From 8da8c97d4f89613ea04de3d01ad56ec794ed3be5 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Fri, 6 Jun 2025 23:54:17 +0200 Subject: [PATCH] ESP32 LVGL library from v9.2.2 to v9.3.0 (#23518) --- CHANGELOG.md | 1 + .../LVGL_assets/src/lv_theme_haspmota.c | 42 +- lib/libesp32_lvgl/freetype/library.json | 1 + .../generate/LVGL_API_Reference.md | 148 +- .../generate/be_lv_c_mapping.h | 136 +- .../generate/be_lvgl_module.c | 100 +- .../lv_binding_berry/mapping/lv_enum.h | 1088 +- .../lv_binding_berry/mapping/lv_funcs.h | 193 +- .../src/be_lvgl_ctypes_definitions.c | 210 +- .../src/embedded/lvgl_ctypes.py | 466 +- .../lv_binding_berry/tools/convert.py | 11 +- .../lv_binding_berry/tools/preprocessor.py | 559 +- .../src/embedded/lv_1_constants.be | 325 +- .../src/solidify/solidified_lv_haspmota.h | 12 +- lib/libesp32_lvgl/lvgl/LICENCE.txt | 2 +- lib/libesp32_lvgl/lvgl/README.md | 56 +- lib/libesp32_lvgl/lvgl/library.json | 2 +- lib/libesp32_lvgl/lvgl/library.properties | 2 +- lib/libesp32_lvgl/lvgl/lv_conf_template.h | 1089 +- lib/libesp32_lvgl/lvgl/lv_version.h | 4 +- lib/libesp32_lvgl/lvgl/lvgl.h | 16 +- lib/libesp32_lvgl/lvgl/lvgl_private.h | 127 + lib/libesp32_lvgl/lvgl/src/core/lv_global.h | 34 +- lib/libesp32_lvgl/lvgl/src/core/lv_group.h | 79 +- .../lvgl/src/core/lv_group_private.h | 2 +- lib/libesp32_lvgl/lvgl/src/core/lv_obj.c | 45 +- lib/libesp32_lvgl/lvgl/src/core/lv_obj.h | 9 +- .../lvgl/src/core/lv_obj_class_private.h | 2 +- lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.c | 190 +- lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.h | 15 + .../lvgl/src/core/lv_obj_event.c | 42 +- .../lvgl/src/core/lv_obj_event.h | 10 +- .../lvgl/src/core/lv_obj_event_private.h | 4 +- lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.c | 135 +- lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.h | 26 +- .../lvgl/src/core/lv_obj_private.h | 12 +- .../lvgl/src/core/lv_obj_property.c | 113 +- .../lvgl/src/core/lv_obj_property.h | 87 +- .../lvgl/src/core/lv_obj_scroll.c | 42 +- .../lvgl/src/core/lv_obj_scroll.h | 177 +- .../lvgl/src/core/lv_obj_style.c | 81 +- .../lvgl/src/core/lv_obj_style.h | 19 + .../lvgl/src/core/lv_obj_style_gen.c | 64 + .../lvgl/src/core/lv_obj_style_gen.h | 80 +- .../lvgl/src/core/lv_obj_style_private.h | 4 +- lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.c | 185 +- lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.h | 84 + lib/libesp32_lvgl/lvgl/src/core/lv_refr.c | 490 +- lib/libesp32_lvgl/lvgl/src/core/lv_refr.h | 6 + .../lvgl/src/core/lv_refr_private.h | 6 - .../lvgl/src/display/lv_display.c | 230 +- .../lvgl/src/display/lv_display.h | 163 +- .../lvgl/src/display/lv_display_private.h | 9 +- .../lvgl/src/draw/dma2d/lv_draw_dma2d.c | 472 + .../lvgl/src/draw/dma2d/lv_draw_dma2d.h | 49 + .../lvgl/src/draw/dma2d/lv_draw_dma2d_fill.c | 127 + .../lvgl/src/draw/dma2d/lv_draw_dma2d_img.c | 210 + .../src/draw/dma2d/lv_draw_dma2d_private.h | 156 + lib/libesp32_lvgl/lvgl/src/draw/lv_draw.c | 422 +- lib/libesp32_lvgl/lvgl/src/draw/lv_draw.h | 74 +- lib/libesp32_lvgl/lvgl/src/draw/lv_draw_3d.c | 69 + lib/libesp32_lvgl/lvgl/src/draw/lv_draw_3d.h | 70 + lib/libesp32_lvgl/lvgl/src/draw/lv_draw_arc.c | 8 +- lib/libesp32_lvgl/lvgl/src/draw/lv_draw_arc.h | 19 + lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.c | 74 +- lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.h | 6 +- .../lvgl/src/draw/lv_draw_buf_private.h | 2 +- .../lvgl/src/draw/lv_draw_image.c | 116 +- .../lvgl/src/draw/lv_draw_image.h | 52 +- .../lvgl/src/draw/lv_draw_image_private.h | 10 +- .../lvgl/src/draw/lv_draw_label.c | 304 +- .../lvgl/src/draw/lv_draw_label.h | 146 +- .../lvgl/src/draw/lv_draw_label_private.h | 14 +- .../lvgl/src/draw/lv_draw_line.c | 9 +- .../lvgl/src/draw/lv_draw_line.h | 23 +- .../lvgl/src/draw/lv_draw_mask.c | 8 +- .../lvgl/src/draw/lv_draw_mask_private.h | 9 +- .../lvgl/src/draw/lv_draw_private.h | 23 +- .../lvgl/src/draw/lv_draw_rect.c | 93 +- .../lvgl/src/draw/lv_draw_rect.h | 61 +- .../lvgl/src/draw/lv_draw_triangle.c | 27 +- .../lvgl/src/draw/lv_draw_triangle.h | 16 +- .../lvgl/src/draw/lv_draw_vector.c | 39 +- .../lvgl/src/draw/lv_draw_vector.h | 24 +- .../lvgl/src/draw/lv_draw_vector_private.h | 20 +- .../lvgl/src/draw/lv_image_decoder.c | 32 +- .../lvgl/src/draw/lv_image_decoder.h | 11 +- .../lvgl/src/draw/lv_image_decoder_private.h | 14 +- .../lvgl/src/draw/lv_image_dsc.h | 8 +- .../lvgl/src/draw/nema_gfx/lv_draw_nema_gfx.c | 405 + .../lvgl/src/draw/nema_gfx/lv_draw_nema_gfx.h | 124 + .../src/draw/nema_gfx/lv_draw_nema_gfx_arc.c | 105 + .../draw/nema_gfx/lv_draw_nema_gfx_border.c | 226 + .../src/draw/nema_gfx/lv_draw_nema_gfx_fill.c | 149 + .../src/draw/nema_gfx/lv_draw_nema_gfx_img.c | 283 + .../draw/nema_gfx/lv_draw_nema_gfx_label.c | 850 + .../draw/nema_gfx/lv_draw_nema_gfx_layer.c | 57 + .../src/draw/nema_gfx/lv_draw_nema_gfx_line.c | 96 + .../nema_gfx/lv_draw_nema_gfx_stm32_hal.c | 254 + .../draw/nema_gfx/lv_draw_nema_gfx_triangle.c | 171 + .../draw/nema_gfx/lv_draw_nema_gfx_utils.c | 143 + .../draw/nema_gfx/lv_draw_nema_gfx_utils.h | 132 + .../lvgl/src/draw/nema_gfx/lv_nema_gfx_path.c | 159 + .../lvgl/src/draw/nema_gfx/lv_nema_gfx_path.h | 97 + .../lvgl/src/draw/nxp/g2d/lv_draw_buf_g2d.c | 92 + .../lvgl/src/draw/nxp/g2d/lv_draw_g2d.c | 336 + .../lvgl/src/draw/nxp/g2d/lv_draw_g2d.h | 71 + .../lvgl/src/draw/nxp/g2d/lv_draw_g2d_fill.c | 178 + .../lvgl/src/draw/nxp/g2d/lv_draw_g2d_img.c | 214 + .../lvgl/src/draw/nxp/g2d/lv_g2d_buf_map.c | 247 + .../lvgl/src/draw/nxp/g2d/lv_g2d_buf_map.h | 81 + .../lvgl/src/draw/nxp/g2d/lv_g2d_utils.c | 97 + .../lvgl/src/draw/nxp/g2d/lv_g2d_utils.h | 72 + .../lvgl/src/draw/nxp/pxp/lv_draw_pxp.c | 39 +- .../lvgl/src/draw/nxp/pxp/lv_draw_pxp.h | 23 +- .../lvgl/src/draw/nxp/pxp/lv_draw_pxp_fill.c | 10 +- .../lvgl/src/draw/nxp/pxp/lv_draw_pxp_img.c | 14 +- .../lvgl/src/draw/nxp/pxp/lv_draw_pxp_layer.c | 31 +- .../src/draw/nxp/vglite/lv_draw_buf_vglite.c | 4 +- .../lvgl/src/draw/nxp/vglite/lv_draw_vglite.c | 148 +- .../lvgl/src/draw/nxp/vglite/lv_draw_vglite.h | 47 +- .../src/draw/nxp/vglite/lv_draw_vglite_arc.c | 70 +- .../draw/nxp/vglite/lv_draw_vglite_border.c | 187 +- .../src/draw/nxp/vglite/lv_draw_vglite_fill.c | 136 +- .../src/draw/nxp/vglite/lv_draw_vglite_img.c | 74 +- .../draw/nxp/vglite/lv_draw_vglite_label.c | 134 +- .../draw/nxp/vglite/lv_draw_vglite_layer.c | 31 +- .../src/draw/nxp/vglite/lv_draw_vglite_line.c | 74 +- .../draw/nxp/vglite/lv_draw_vglite_triangle.c | 126 +- .../lvgl/src/draw/nxp/vglite/lv_vglite_buf.c | 16 +- .../lvgl/src/draw/nxp/vglite/lv_vglite_buf.h | 2 +- .../src/draw/nxp/vglite/lv_vglite_matrix.c | 16 +- .../src/draw/nxp/vglite/lv_vglite_matrix.h | 4 +- .../lvgl/src/draw/nxp/vglite/lv_vglite_path.h | 3 +- .../src/draw/nxp/vglite/lv_vglite_utils.c | 10 +- .../src/draw/nxp/vglite/lv_vglite_utils.h | 6 +- .../lvgl/src/draw/opengles/lv_draw_opengles.c | 634 + .../lvgl/src/draw/opengles/lv_draw_opengles.h | 45 + .../src/draw/renesas/dave2d/lv_draw_dave2d.c | 60 +- .../src/draw/renesas/dave2d/lv_draw_dave2d.h | 32 +- .../draw/renesas/dave2d/lv_draw_dave2d_arc.c | 15 +- .../renesas/dave2d/lv_draw_dave2d_border.c | 35 +- .../draw/renesas/dave2d/lv_draw_dave2d_fill.c | 13 +- .../renesas/dave2d/lv_draw_dave2d_image.c | 23 +- .../renesas/dave2d/lv_draw_dave2d_label.c | 30 +- .../draw/renesas/dave2d/lv_draw_dave2d_line.c | 15 +- .../dave2d/lv_draw_dave2d_mask_rectangle.c | 15 +- .../renesas/dave2d/lv_draw_dave2d_triangle.c | 41 +- .../renesas/dave2d/lv_draw_dave2d_utils.c | 48 +- .../renesas/dave2d/lv_draw_dave2d_utils.h | 2 + .../lvgl/src/draw/sdl/lv_draw_sdl.c | 126 +- .../lvgl/src/draw/sdl/lv_draw_sdl.h | 7 - .../lvgl/src/draw/sw/arm2d/lv_draw_sw_arm2d.h | 206 +- .../draw/sw/blend/helium/lv_blend_helium.S | 7 + .../lvgl/src/draw/sw/blend/lv_draw_sw_blend.c | 233 +- .../lvgl/src/draw/sw/blend/lv_draw_sw_blend.h | 14 +- .../draw/sw/blend/lv_draw_sw_blend_private.h | 6 +- .../draw/sw/blend/lv_draw_sw_blend_to_al88.c | 10 +- .../draw/sw/blend/lv_draw_sw_blend_to_al88.h | 2 +- .../sw/blend/lv_draw_sw_blend_to_argb8888.c | 336 +- ..._draw_sw_blend_to_argb8888_premultiplied.c | 835 + ..._draw_sw_blend_to_argb8888_premultiplied.h | 45 + .../draw/sw/blend/lv_draw_sw_blend_to_i1.c | 174 +- .../draw/sw/blend/lv_draw_sw_blend_to_l8.c | 130 +- .../draw/sw/blend/lv_draw_sw_blend_to_l8.h | 2 +- .../sw/blend/lv_draw_sw_blend_to_rgb565.c | 381 +- .../lv_draw_sw_blend_to_rgb565_swapped.c | 1560 + .../lv_draw_sw_blend_to_rgb565_swapped.h | 45 + .../sw/blend/lv_draw_sw_blend_to_rgb888.c | 175 +- .../src/draw/sw/blend/neon/lv_blend_neon.S | 590 +- .../lvgl/src/draw/sw/lv_draw_sw.c | 769 +- .../lvgl/src/draw/sw/lv_draw_sw.h | 96 +- .../lvgl/src/draw/sw/lv_draw_sw_arc.c | 15 +- .../lvgl/src/draw/sw/lv_draw_sw_border.c | 54 +- .../lvgl/src/draw/sw/lv_draw_sw_box_shadow.c | 51 +- .../lvgl/src/draw/sw/lv_draw_sw_fill.c | 60 +- ...v_draw_sw_gradient.c => lv_draw_sw_grad.c} | 132 +- .../lvgl/src/draw/sw/lv_draw_sw_grad.h | 147 + .../lvgl/src/draw/sw/lv_draw_sw_gradient.h | 203 - .../lvgl/src/draw/sw/lv_draw_sw_img.c | 882 +- .../lvgl/src/draw/sw/lv_draw_sw_letter.c | 383 +- .../lvgl/src/draw/sw/lv_draw_sw_line.c | 50 +- .../lvgl/src/draw/sw/lv_draw_sw_mask.c | 1 + .../lvgl/src/draw/sw/lv_draw_sw_mask.h | 4 - .../src/draw/sw/lv_draw_sw_mask_private.h | 14 +- .../lvgl/src/draw/sw/lv_draw_sw_mask_rect.c | 46 +- .../lvgl/src/draw/sw/lv_draw_sw_private.h | 17 +- .../lvgl/src/draw/sw/lv_draw_sw_transform.c | 401 +- .../lvgl/src/draw/sw/lv_draw_sw_triangle.c | 25 +- .../lvgl/src/draw/sw/lv_draw_sw_utils.c | 596 + .../lvgl/src/draw/sw/lv_draw_sw_utils.h | 111 + .../lvgl/src/draw/sw/lv_draw_sw_vector.c | 133 +- .../lvgl/src/draw/vg_lite/lv_draw_vg_lite.c | 79 +- .../lvgl/src/draw/vg_lite/lv_draw_vg_lite.h | 33 +- .../src/draw/vg_lite/lv_draw_vg_lite_arc.c | 164 +- .../src/draw/vg_lite/lv_draw_vg_lite_border.c | 337 +- .../draw/vg_lite/lv_draw_vg_lite_box_shadow.c | 31 +- .../src/draw/vg_lite/lv_draw_vg_lite_fill.c | 43 +- .../src/draw/vg_lite/lv_draw_vg_lite_img.c | 118 +- .../src/draw/vg_lite/lv_draw_vg_lite_label.c | 354 +- .../src/draw/vg_lite/lv_draw_vg_lite_layer.c | 14 +- .../src/draw/vg_lite/lv_draw_vg_lite_line.c | 40 +- .../draw/vg_lite/lv_draw_vg_lite_mask_rect.c | 85 +- .../draw/vg_lite/lv_draw_vg_lite_triangle.c | 44 +- .../src/draw/vg_lite/lv_draw_vg_lite_type.h | 15 +- .../src/draw/vg_lite/lv_draw_vg_lite_vector.c | 468 +- .../src/draw/vg_lite/lv_vg_lite_decoder.c | 5 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_grad.c | 495 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_grad.h | 47 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_math.c | 22 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_math.h | 1 + .../lvgl/src/draw/vg_lite/lv_vg_lite_path.c | 207 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_path.h | 42 +- .../src/draw/vg_lite/lv_vg_lite_pending.c | 52 +- .../src/draw/vg_lite/lv_vg_lite_pending.h | 10 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_stroke.c | 265 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_stroke.h | 16 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_utils.c | 246 +- .../lvgl/src/draw/vg_lite/lv_vg_lite_utils.h | 148 +- .../src/drivers/display/drm/lv_linux_drm.c | 236 +- .../src/drivers/display/fb/lv_linux_fbdev.c | 25 +- .../lvgl/src/drivers/display/ft81x/lv_ft81x.c | 399 + .../lvgl/src/drivers/display/ft81x/lv_ft81x.h | 93 + .../drivers/display/ft81x/lv_ft81x_defines.h | 846 + .../src/drivers/display/ili9341/lv_ili9341.h | 7 +- .../drivers/display/lcd/lv_lcd_generic_mipi.c | 1 + .../drivers/display/lcd/lv_lcd_generic_mipi.h | 10 +- .../display/renesas_glcdc/lv_renesas_glcdc.c | 7 +- .../display/renesas_glcdc/lv_renesas_glcdc.h | 4 +- .../src/drivers/display/st7735/lv_st7735.h | 2 +- .../src/drivers/display/st7789/lv_st7789.h | 7 +- .../src/drivers/display/st7796/lv_st7796.h | 6 +- .../src/drivers/display/st_ltdc/lv_st_ltdc.c | 290 + .../src/drivers/display/st_ltdc/lv_st_ltdc.h | 65 + .../lvgl/src/drivers/evdev/lv_evdev.c | 323 +- .../lvgl/src/drivers/evdev/lv_evdev.h | 34 + .../lvgl/src/drivers/evdev/lv_evdev_private.h | 45 + .../lvgl/src/drivers/glfw/lv_glfw_window.c | 16 +- .../lvgl/src/drivers/glfw/lv_glfw_window.h | 7 + .../src/drivers/glfw/lv_glfw_window_private.h | 4 +- .../lvgl/src/drivers/glfw/lv_opengles_debug.c | 4 +- .../lvgl/src/drivers/glfw/lv_opengles_debug.h | 10 +- .../src/drivers/glfw/lv_opengles_driver.c | 172 +- .../src/drivers/glfw/lv_opengles_driver.h | 16 +- .../src/drivers/glfw/lv_opengles_texture.c | 32 +- .../lvgl/src/drivers/libinput/lv_libinput.c | 9 +- .../drivers/libinput/lv_libinput_private.h | 4 +- .../src/drivers/libinput/lv_xkb_private.h | 2 +- .../lvgl/src/drivers/lv_drivers.h | 14 + .../lvgl/src/drivers/nuttx/lv_nuttx_cache.c | 19 + .../lvgl/src/drivers/nuttx/lv_nuttx_entry.c | 17 +- .../lvgl/src/drivers/nuttx/lv_nuttx_entry.h | 2 +- .../lvgl/src/drivers/nuttx/lv_nuttx_fbdev.c | 124 +- .../src/drivers/nuttx/lv_nuttx_image_cache.c | 75 +- .../src/drivers/nuttx/lv_nuttx_image_cache.h | 3 +- .../lvgl/src/drivers/nuttx/lv_nuttx_lcd.c | 28 +- .../lvgl/src/drivers/nuttx/lv_nuttx_libuv.c | 39 +- .../src/drivers/nuttx/lv_nuttx_profiler.c | 16 +- .../src/drivers/nuttx/lv_nuttx_touchscreen.c | 31 +- .../lvgl/src/drivers/sdl/lv_sdl_keyboard.c | 4 +- .../lvgl/src/drivers/sdl/lv_sdl_mouse.c | 12 +- .../lvgl/src/drivers/sdl/lv_sdl_mousewheel.c | 2 +- .../lvgl/src/drivers/sdl/lv_sdl_window.c | 173 +- .../lvgl/src/drivers/sdl/lv_sdl_window.h | 11 +- .../lvgl/src/drivers/uefi/lv_uefi.h | 106 + .../lvgl/src/drivers/uefi/lv_uefi_context.c | 91 + .../lvgl/src/drivers/uefi/lv_uefi_context.h | 71 + .../lvgl/src/drivers/uefi/lv_uefi_display.c | 284 + .../lvgl/src/drivers/uefi/lv_uefi_display.h | 65 + .../lvgl/src/drivers/uefi/lv_uefi_edk2.h | 28 + .../lvgl/src/drivers/uefi/lv_uefi_gnu_efi.h | 17 + .../lvgl/src/drivers/uefi/lv_uefi_indev.h | 108 + .../src/drivers/uefi/lv_uefi_indev_keyboard.c | 346 + .../src/drivers/uefi/lv_uefi_indev_pointer.c | 285 + .../src/drivers/uefi/lv_uefi_indev_touch.c | 290 + .../lvgl/src/drivers/uefi/lv_uefi_private.c | 225 + .../lvgl/src/drivers/uefi/lv_uefi_private.h | 107 + .../src/drivers/uefi/lv_uefi_std_wrapper.h | 155 + .../lvgl/src/drivers/wayland/lv_wayland.c | 2994 +- .../lvgl/src/drivers/wayland/lv_wayland.h | 117 +- .../src/drivers/wayland/lv_wayland_private.h | 374 + .../lvgl/src/drivers/wayland/lv_wayland_smm.c | 9 +- .../lvgl/src/drivers/wayland/lv_wayland_smm.h | 2 +- .../lvgl/src/drivers/wayland/lv_wl_cache.c | 133 + .../lvgl/src/drivers/wayland/lv_wl_dmabuf.c | 360 + .../lvgl/src/drivers/wayland/lv_wl_keyboard.c | 301 + .../lvgl/src/drivers/wayland/lv_wl_keyboard.h | 52 + .../lvgl/src/drivers/wayland/lv_wl_pointer.c | 245 + .../lvgl/src/drivers/wayland/lv_wl_pointer.h | 54 + .../src/drivers/wayland/lv_wl_pointer_axis.c | 79 + .../src/drivers/wayland/lv_wl_pointer_axis.h | 54 + .../lvgl/src/drivers/wayland/lv_wl_seat.c | 100 + .../lvgl/src/drivers/wayland/lv_wl_shell.c | 184 + .../lvgl/src/drivers/wayland/lv_wl_shm.c | 468 + .../lvgl/src/drivers/wayland/lv_wl_touch.c | 275 + .../lvgl/src/drivers/wayland/lv_wl_touch.h | 54 + .../lvgl/src/drivers/wayland/lv_wl_window.c | 489 + .../lvgl/src/drivers/wayland/lv_wl_window.h | 84 + .../wayland/lv_wl_window_decorations.c | 361 + .../src/drivers/wayland/lv_wl_xdg_shell.c | 467 + .../src/drivers/windows/lv_windows_context.c | 3 +- .../src/drivers/windows/lv_windows_context.h | 14 +- .../src/drivers/windows/lv_windows_input.c | 2 +- .../lvgl/src/drivers/x11/lv_x11.h | 1 + .../lvgl/src/drivers/x11/lv_x11_display.c | 1 + .../lvgl/src/font/lv_binfont_loader.c | 66 + .../lvgl/src/font/lv_binfont_loader.h | 10 + lib/libesp32_lvgl/lvgl/src/font/lv_font.c | 61 +- lib/libesp32_lvgl/lvgl/src/font/lv_font.h | 94 +- .../lvgl/src/font/lv_font_fmt_txt.c | 135 +- .../lvgl/src/font/lv_font_fmt_txt.h | 17 +- .../lvgl/src/font/lv_font_montserrat_14.c | 1 - .../src/font/lv_font_montserrat_14_aligned.c | 4179 +++ .../lvgl/src/font/lv_font_simsun_14_cjk.c | 6 + .../lvgl/src/font/lv_font_simsun_16_cjk.c | 6 + .../font/lv_font_source_han_sans_sc_14_cjk.c | 23898 +++++++++++++ .../font/lv_font_source_han_sans_sc_16_cjk.c | 27593 ++++++++++++++++ lib/libesp32_lvgl/lvgl/src/indev/lv_indev.c | 233 +- lib/libesp32_lvgl/lvgl/src/indev/lv_indev.h | 41 +- .../lvgl/src/indev/lv_indev_gesture.c | 964 + .../lvgl/src/indev/lv_indev_gesture.h | 244 + .../lvgl/src/indev/lv_indev_gesture_private.h | 97 + .../lvgl/src/indev/lv_indev_private.h | 20 +- .../lvgl/src/indev/lv_indev_scroll.c | 233 +- .../lvgl/src/layouts/flex/lv_flex.c | 38 +- .../lvgl/src/layouts/grid/lv_grid.c | 6 +- .../lvgl/src/libs/barcode/LICENSE.txt | 22 + .../lvgl/src/libs/barcode/lv_barcode.c | 32 +- .../lvgl/src/libs/barcode/lv_barcode.h | 25 + .../src/libs/barcode/lv_barcode_private.h | 3 +- .../src/libs/bin_decoder/lv_bin_decoder.c | 135 +- .../lvgl/src/libs/expat/LICENSE.txt | 21 + .../lvgl/src/libs/expat/add_lvgl_if.sh | 13 + lib/libesp32_lvgl/lvgl/src/libs/expat/ascii.h | 129 + .../lvgl/src/libs/expat/asciitab.h | 72 + lib/libesp32_lvgl/lvgl/src/libs/expat/expat.h | 1081 + .../lvgl/src/libs/expat/expat_config.h | 151 + .../lvgl/src/libs/expat/expat_external.h | 171 + .../lvgl/src/libs/expat/iasciitab.h | 73 + .../lvgl/src/libs/expat/internal.h | 182 + .../lvgl/src/libs/expat/latin1tab.h | 72 + .../lvgl/src/libs/expat/nametab.h | 142 + .../lvgl/src/libs/expat/siphash.h | 398 + .../lvgl/src/libs/expat/utf8tab.h | 72 + .../lvgl/src/libs/expat/winconfig.h | 54 + .../lvgl/src/libs/expat/xmlparse.c | 8565 +++++ .../lvgl/src/libs/expat/xmlrole.c | 1261 + .../lvgl/src/libs/expat/xmlrole.h | 148 + .../lvgl/src/libs/expat/xmltok.c | 1678 + .../lvgl/src/libs/expat/xmltok.h | 327 + .../lvgl/src/libs/expat/xmltok_impl.c | 1825 + .../lvgl/src/libs/expat/xmltok_impl.h | 80 + .../lvgl/src/libs/expat/xmltok_ns.c | 128 + .../lvgl/src/libs/ffmpeg/lv_ffmpeg.c | 191 +- .../lvgl/src/libs/ffmpeg/lv_ffmpeg.h | 7 +- .../lvgl/src/libs/ffmpeg/lv_ffmpeg_private.h | 2 +- .../lvgl/src/libs/freetype/LICENSE.txt | 170 + .../lvgl/src/libs/freetype/ftoption.h | 2 +- .../lvgl/src/libs/freetype/lv_freetype.c | 108 +- .../lvgl/src/libs/freetype/lv_freetype.h | 32 +- .../src/libs/freetype/lv_freetype_glyph.c | 55 +- .../src/libs/freetype/lv_freetype_image.c | 56 +- .../src/libs/freetype/lv_freetype_outline.c | 162 +- .../src/libs/freetype/lv_freetype_private.h | 28 +- .../libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp | 19 +- .../lvgl/src/libs/fsdrv/lv_fs_arduino_sd.cpp | 18 +- .../lvgl/src/libs/fsdrv/lv_fs_fatfs.c | 23 +- .../lvgl/src/libs/fsdrv/lv_fs_littlefs.c | 23 +- .../lvgl/src/libs/fsdrv/lv_fs_memfs.c | 14 +- .../lvgl/src/libs/fsdrv/lv_fs_posix.c | 80 +- .../lvgl/src/libs/fsdrv/lv_fs_stdio.c | 26 +- .../lvgl/src/libs/fsdrv/lv_fs_uefi.c | 607 + .../lvgl/src/libs/fsdrv/lv_fs_win32.c | 51 +- .../lvgl/src/libs/fsdrv/lv_fsdrv.h | 6 + .../lvgl/src/libs/gif/LICENSE.txt | 2 + lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.c | 3 +- lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.c | 7 +- .../lvgl/src/libs/gif/lv_gif_private.h | 2 +- .../lvgl/src/libs/libpng/lv_libpng.c | 22 +- .../lvgl/src/libs/lodepng/LICENSE.txt | 21 + .../lvgl/src/libs/lodepng/lodepng.h | 6 +- .../lvgl/src/libs/lodepng/lv_lodepng.c | 34 +- .../src/libs/lz4/{LICENSE => LICENSE.txt} | 0 lib/libesp32_lvgl/lvgl/src/libs/lz4/lz4.c | 130 +- lib/libesp32_lvgl/lvgl/src/libs/lz4/lz4.h | 140 +- .../lvgl/src/libs/qrcode/LICENSE.txt | 8 + .../lvgl/src/libs/qrcode/lv_qrcode.c | 2 +- .../lvgl/src/libs/qrcode/lv_qrcode_private.h | 2 +- .../lvgl/src/libs/qrcode/qrcodegen.h | 6 +- .../lvgl/src/libs/rlottie/lv_rlottie.c | 2 +- .../src/libs/rlottie/lv_rlottie_private.h | 2 +- lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg.c | 124 + lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg.h | 334 + .../lvgl/src/libs/svg/lv_svg_decoder.c | 379 + .../lvgl/src/libs/svg/lv_svg_decoder.h | 51 + .../lvgl/src/libs/svg/lv_svg_parser.c | 2344 ++ .../lvgl/src/libs/svg/lv_svg_parser.h | 84 + .../lvgl/src/libs/svg/lv_svg_render.c | 2486 ++ .../lvgl/src/libs/svg/lv_svg_render.h | 125 + .../lvgl/src/libs/svg/lv_svg_token.c | 483 + .../lvgl/src/libs/svg/lv_svg_token.h | 70 + .../lvgl/src/libs/thorvg/LICENSE.txt | 7 + .../lvgl/src/libs/thorvg/config.h | 13 +- .../src/libs/thorvg/rapidjson/allocators.h | 15 +- .../src/libs/thorvg/rapidjson/rapidjson.h | 8 +- .../lvgl/src/libs/thorvg/thorvg.h | 660 +- .../lvgl/src/libs/thorvg/thorvg_capi.h | 602 +- .../lvgl/src/libs/thorvg/thorvg_lottie.h | 6 +- .../lvgl/src/libs/thorvg/tvgAccessor.cpp | 43 +- .../lvgl/src/libs/thorvg/tvgAnimation.cpp | 2 +- .../lvgl/src/libs/thorvg/tvgArray.h | 14 +- .../lvgl/src/libs/thorvg/tvgBinaryDesc.h | 2 +- .../lvgl/src/libs/thorvg/tvgCanvas.h | 31 +- .../lvgl/src/libs/thorvg/tvgCapi.cpp | 130 +- .../lvgl/src/libs/thorvg/tvgCommon.h | 29 +- .../lvgl/src/libs/thorvg/tvgCompressor.cpp | 31 +- .../lvgl/src/libs/thorvg/tvgCompressor.h | 1 + .../lvgl/src/libs/thorvg/tvgFill.cpp | 31 +- .../lvgl/src/libs/thorvg/tvgFill.h | 11 +- .../lvgl/src/libs/thorvg/tvgGlCanvas.cpp | 11 +- .../lvgl/src/libs/thorvg/tvgInitializer.cpp | 42 +- .../lvgl/src/libs/thorvg/tvgInlist.h | 2 +- .../lvgl/src/libs/thorvg/tvgLines.cpp | 249 - .../lvgl/src/libs/thorvg/tvgLoadModule.h | 9 +- .../lvgl/src/libs/thorvg/tvgLoader.cpp | 32 +- .../lvgl/src/libs/thorvg/tvgLoader.h | 1 + .../lvgl/src/libs/thorvg/tvgLock.h | 11 +- .../src/libs/thorvg/tvgLottieAnimation.cpp | 14 +- .../lvgl/src/libs/thorvg/tvgLottieBuilder.cpp | 1641 +- .../lvgl/src/libs/thorvg/tvgLottieBuilder.h | 90 +- .../lvgl/src/libs/thorvg/tvgLottieCommon.h | 104 + .../src/libs/thorvg/tvgLottieExpressions.cpp | 555 +- .../src/libs/thorvg/tvgLottieExpressions.h | 71 +- .../src/libs/thorvg/tvgLottieInterpolator.cpp | 2 +- .../lvgl/src/libs/thorvg/tvgLottieLoader.cpp | 83 +- .../lvgl/src/libs/thorvg/tvgLottieLoader.h | 4 + .../lvgl/src/libs/thorvg/tvgLottieModel.cpp | 228 +- .../lvgl/src/libs/thorvg/tvgLottieModel.h | 372 +- .../src/libs/thorvg/tvgLottieModifier.cpp | 401 + .../lvgl/src/libs/thorvg/tvgLottieModifier.h | 77 + .../lvgl/src/libs/thorvg/tvgLottieParser.cpp | 500 +- .../lvgl/src/libs/thorvg/tvgLottieParser.h | 19 +- .../libs/thorvg/tvgLottieParserHandler.cpp | 4 +- .../lvgl/src/libs/thorvg/tvgLottieProperty.h | 336 +- .../{tvgLines.h => tvgLottieRenderPooler.h} | 64 +- .../lvgl/src/libs/thorvg/tvgMath.cpp | 334 +- .../lvgl/src/libs/thorvg/tvgMath.h | 188 +- .../lvgl/src/libs/thorvg/tvgPaint.cpp | 325 +- .../lvgl/src/libs/thorvg/tvgPaint.h | 84 +- .../lvgl/src/libs/thorvg/tvgPicture.cpp | 59 +- .../lvgl/src/libs/thorvg/tvgPicture.h | 84 +- .../lvgl/src/libs/thorvg/tvgRawLoader.cpp | 5 +- .../lvgl/src/libs/thorvg/tvgRender.cpp | 28 +- .../lvgl/src/libs/thorvg/tvgRender.h | 174 +- .../lvgl/src/libs/thorvg/tvgSaver.cpp | 2 +- .../lvgl/src/libs/thorvg/tvgScene.cpp | 56 +- .../lvgl/src/libs/thorvg/tvgScene.h | 85 +- .../lvgl/src/libs/thorvg/tvgShape.cpp | 57 +- .../lvgl/src/libs/thorvg/tvgShape.h | 147 +- .../lvgl/src/libs/thorvg/tvgStr.cpp | 24 +- .../lvgl/src/libs/thorvg/tvgStr.h | 2 +- .../lvgl/src/libs/thorvg/tvgSvgCssStyle.cpp | 19 +- .../lvgl/src/libs/thorvg/tvgSvgLoader.cpp | 388 +- .../lvgl/src/libs/thorvg/tvgSvgLoader.h | 2 + .../lvgl/src/libs/thorvg/tvgSvgLoaderCommon.h | 31 +- .../lvgl/src/libs/thorvg/tvgSvgPath.cpp | 26 +- .../src/libs/thorvg/tvgSvgSceneBuilder.cpp | 154 +- .../lvgl/src/libs/thorvg/tvgSvgUtil.cpp | 4 +- .../lvgl/src/libs/thorvg/tvgSwCanvas.cpp | 14 +- .../lvgl/src/libs/thorvg/tvgSwCommon.h | 93 +- .../lvgl/src/libs/thorvg/tvgSwFill.cpp | 183 +- .../lvgl/src/libs/thorvg/tvgSwImage.cpp | 68 +- .../lvgl/src/libs/thorvg/tvgSwMath.cpp | 59 +- .../lvgl/src/libs/thorvg/tvgSwMemPool.cpp | 20 +- .../lvgl/src/libs/thorvg/tvgSwPostEffect.cpp | 215 + .../lvgl/src/libs/thorvg/tvgSwRaster.cpp | 630 +- .../lvgl/src/libs/thorvg/tvgSwRasterAvx.h | 174 +- .../lvgl/src/libs/thorvg/tvgSwRasterC.h | 6 +- .../lvgl/src/libs/thorvg/tvgSwRasterNeon.h | 146 +- .../lvgl/src/libs/thorvg/tvgSwRasterTexmap.h | 173 +- .../lvgl/src/libs/thorvg/tvgSwRenderer.cpp | 348 +- .../lvgl/src/libs/thorvg/tvgSwRenderer.h | 19 +- .../lvgl/src/libs/thorvg/tvgSwRle.cpp | 460 +- .../lvgl/src/libs/thorvg/tvgSwShape.cpp | 258 +- .../lvgl/src/libs/thorvg/tvgSwStroke.cpp | 65 +- .../lvgl/src/libs/thorvg/tvgTaskScheduler.h | 9 + .../lvgl/src/libs/thorvg/tvgText.cpp | 33 +- .../lvgl/src/libs/thorvg/tvgText.h | 85 +- .../lvgl/src/libs/thorvg/tvgWgCanvas.cpp | 23 +- .../lvgl/src/libs/thorvg/tvgXmlParser.cpp | 16 +- .../lvgl/src/libs/tiny_ttf/LICENSE.txt | 63 + .../lvgl/src/libs/tiny_ttf/lv_tiny_ttf.c | 71 +- .../lvgl/src/libs/tiny_ttf/lv_tiny_ttf.h | 9 + .../src/libs/tiny_ttf/stb_truetype_htcw.h | 4 +- .../lvgl/src/libs/tjpgd/LICENSE.txt | 15 + lib/libesp32_lvgl/lvgl/src/lv_api_map_v9_1.h | 53 +- lib/libesp32_lvgl/lvgl/src/lv_conf_internal.h | 2090 +- lib/libesp32_lvgl/lvgl/src/lv_conf_kconfig.h | 53 +- lib/libesp32_lvgl/lvgl/src/lv_init.c | 100 +- lib/libesp32_lvgl/lvgl/src/lvgl_private.h | 97 +- .../src/misc/cache/class/lv_cache_class.h | 17 + .../src/misc/cache/class/lv_cache_lru_ll.c | 443 + .../src/misc/cache/class/lv_cache_lru_ll.h | 44 + .../misc/cache/{ => class}/lv_cache_lru_rb.c | 51 +- .../misc/cache/{ => class}/lv_cache_lru_rb.h | 4 +- .../misc/cache/instance/lv_cache_instance.h | 16 + .../cache/{ => instance}/lv_image_cache.c | 53 +- .../cache/{ => instance}/lv_image_cache.h | 14 +- .../{ => instance}/lv_image_header_cache.c | 52 +- .../{ => instance}/lv_image_header_cache.h | 14 +- .../lvgl/src/misc/cache/lv_cache.c | 52 +- .../lvgl/src/misc/cache/lv_cache.h | 17 +- .../lvgl/src/misc/cache/lv_cache_entry.c | 20 +- .../lvgl/src/misc/cache/lv_cache_entry.h | 3 +- .../src/misc/cache/lv_cache_entry_private.h | 2 + .../lvgl/src/misc/cache/lv_cache_private.h | 36 +- lib/libesp32_lvgl/lvgl/src/misc/lv_anim.c | 180 +- lib/libesp32_lvgl/lvgl/src/misc/lv_anim.h | 125 +- .../lvgl/src/misc/lv_anim_timeline.c | 8 +- .../lvgl/src/misc/lv_anim_timeline.h | 2 +- lib/libesp32_lvgl/lvgl/src/misc/lv_area.c | 12 +- lib/libesp32_lvgl/lvgl/src/misc/lv_array.c | 75 +- lib/libesp32_lvgl/lvgl/src/misc/lv_array.h | 57 +- lib/libesp32_lvgl/lvgl/src/misc/lv_async.c | 2 +- .../lvgl/src/misc/lv_circle_buf.c | 295 + .../lvgl/src/misc/lv_circle_buf.h | 191 + lib/libesp32_lvgl/lvgl/src/misc/lv_color.c | 22 +- lib/libesp32_lvgl/lvgl/src/misc/lv_color.h | 49 +- lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.c | 46 +- lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.h | 29 +- lib/libesp32_lvgl/lvgl/src/misc/lv_event.c | 246 +- lib/libesp32_lvgl/lvgl/src/misc/lv_event.h | 167 +- .../lvgl/src/misc/lv_event_private.h | 4 +- lib/libesp32_lvgl/lvgl/src/misc/lv_fs.c | 59 +- lib/libesp32_lvgl/lvgl/src/misc/lv_fs.h | 10 +- .../lvgl/src/misc/lv_fs_private.h | 4 +- lib/libesp32_lvgl/lvgl/src/misc/lv_grad.c | 120 + lib/libesp32_lvgl/lvgl/src/misc/lv_grad.h | 182 + lib/libesp32_lvgl/lvgl/src/misc/lv_iter.c | 213 + lib/libesp32_lvgl/lvgl/src/misc/lv_iter.h | 120 + lib/libesp32_lvgl/lvgl/src/misc/lv_ll.c | 4 +- lib/libesp32_lvgl/lvgl/src/misc/lv_log.c | 23 +- lib/libesp32_lvgl/lvgl/src/misc/lv_log.h | 2 +- lib/libesp32_lvgl/lvgl/src/misc/lv_lru.c | 4 +- lib/libesp32_lvgl/lvgl/src/misc/lv_lru.h | 4 +- lib/libesp32_lvgl/lvgl/src/misc/lv_math.c | 2 +- lib/libesp32_lvgl/lvgl/src/misc/lv_math.h | 9 +- lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.c | 20 +- lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.h | 9 +- lib/libesp32_lvgl/lvgl/src/misc/lv_profiler.h | 132 + .../lvgl/src/misc/lv_profiler_builtin.c | 28 +- .../src/misc/lv_profiler_builtin_private.h | 4 +- .../lvgl/src/misc/lv_rb_private.h | 10 +- lib/libesp32_lvgl/lvgl/src/misc/lv_style.c | 53 +- lib/libesp32_lvgl/lvgl/src/misc/lv_style.h | 198 +- .../lvgl/src/misc/lv_style_gen.c | 64 + .../lvgl/src/misc/lv_style_gen.h | 48 + lib/libesp32_lvgl/lvgl/src/misc/lv_text.c | 113 +- lib/libesp32_lvgl/lvgl/src/misc/lv_text.h | 33 + lib/libesp32_lvgl/lvgl/src/misc/lv_text_ap.c | 1 + .../lvgl/src/misc/lv_text_private.h | 3 +- lib/libesp32_lvgl/lvgl/src/misc/lv_timer.c | 11 +- lib/libesp32_lvgl/lvgl/src/misc/lv_timer.h | 4 - .../lvgl/src/misc/lv_timer_private.h | 2 +- lib/libesp32_lvgl/lvgl/src/misc/lv_tree.c | 189 + lib/libesp32_lvgl/lvgl/src/misc/lv_tree.h | 105 + lib/libesp32_lvgl/lvgl/src/misc/lv_types.h | 281 +- lib/libesp32_lvgl/lvgl/src/misc/lv_utils.c | 2 +- lib/libesp32_lvgl/lvgl/src/misc/lv_utils.h | 23 + .../lvgl/src/osal/lv_cmsis_rtos2.c | 10 +- lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.c | 18 +- lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.h | 9 +- lib/libesp32_lvgl/lvgl/src/osal/lv_linux.c | 122 + .../lvgl/src/osal/lv_linux_private.h | 56 + lib/libesp32_lvgl/lvgl/src/osal/lv_mqx.c | 11 +- lib/libesp32_lvgl/lvgl/src/osal/lv_os.c | 12 +- lib/libesp32_lvgl/lvgl/src/osal/lv_os.h | 117 +- lib/libesp32_lvgl/lvgl/src/osal/lv_os_none.c | 93 +- lib/libesp32_lvgl/lvgl/src/osal/lv_pthread.c | 22 +- lib/libesp32_lvgl/lvgl/src/osal/lv_rtthread.c | 11 +- lib/libesp32_lvgl/lvgl/src/osal/lv_sdl2.c | 194 + lib/libesp32_lvgl/lvgl/src/osal/lv_sdl2.h | 55 + lib/libesp32_lvgl/lvgl/src/osal/lv_windows.c | 10 +- lib/libesp32_lvgl/lvgl/src/osal/lv_windows.h | 2 +- .../others/file_explorer/lv_file_explorer.c | 172 +- .../others/file_explorer/lv_file_explorer.h | 28 +- .../file_explorer/lv_file_explorer_private.h | 14 +- .../src/others/font_manager/lv_font_manager.c | 619 + .../src/others/font_manager/lv_font_manager.h | 115 + .../font_manager/lv_font_manager_recycle.c | 172 + .../font_manager/lv_font_manager_recycle.h | 78 + .../lvgl/src/others/fragment/lv_fragment.h | 6 +- .../src/others/fragment/lv_fragment_manager.c | 4 +- .../src/others/fragment/lv_fragment_private.h | 2 +- .../lvgl/src/others/ime/lv_ime_pinyin.c | 3 +- .../src/others/ime/lv_ime_pinyin_private.h | 2 +- .../lvgl/src/others/monkey/lv_monkey.c | 2 +- .../lvgl/src/others/monkey/lv_monkey.h | 12 +- .../lvgl/src/others/observer/lv_observer.c | 261 +- .../lvgl/src/others/observer/lv_observer.h | 437 +- .../src/others/observer/lv_observer_private.h | 16 +- .../lvgl/src/others/snapshot/lv_snapshot.c | 10 +- .../lvgl/src/others/sysmon/lv_sysmon.c | 36 +- .../src/others/sysmon/lv_sysmon_private.h | 4 +- .../lvgl/src/others/test/lv_test.h | 46 + .../lvgl/src/others/test/lv_test_display.c | 108 + .../lvgl/src/others/test/lv_test_display.h | 55 + .../lvgl/src/others/test/lv_test_helpers.c | 60 + .../lvgl/src/others/test/lv_test_helpers.h | 80 + .../lvgl/src/others/test/lv_test_indev.c | 194 + .../lvgl/src/others/test/lv_test_indev.h | 166 + .../src/others/test/lv_test_indev_gesture.c | 117 + .../src/others/test/lv_test_indev_gesture.h | 88 + .../lvgl/src/others/test/lv_test_private.h | 67 + .../others/test/lv_test_screenshot_compare.c | 328 + .../others/test/lv_test_screenshot_compare.h | 53 + .../lvgl/src/others/vg_lite_tvg/vg_lite.h | 4 +- .../src/others/vg_lite_tvg/vg_lite_tvg.cpp | 265 +- .../lvgl/src/others/xml/lv_xml.c | 642 + .../lvgl/src/others/xml/lv_xml.h | 86 + .../lvgl/src/others/xml/lv_xml_base_types.c | 226 + .../lvgl/src/others/xml/lv_xml_base_types.h | 138 + .../lvgl/src/others/xml/lv_xml_component.c | 740 + .../lvgl/src/others/xml/lv_xml_component.h | 78 + .../src/others/xml/lv_xml_component_private.h | 92 + .../lvgl/src/others/xml/lv_xml_parser.c | 123 + .../lvgl/src/others/xml/lv_xml_parser.h | 79 + .../lvgl/src/others/xml/lv_xml_private.h | 64 + .../lvgl/src/others/xml/lv_xml_style.c | 541 + .../lvgl/src/others/xml/lv_xml_style.h | 99 + .../lvgl/src/others/xml/lv_xml_update.c | 124 + .../lvgl/src/others/xml/lv_xml_update.h | 46 + .../lvgl/src/others/xml/lv_xml_utils.c | 239 + .../lvgl/src/others/xml/lv_xml_utils.h | 67 + .../lvgl/src/others/xml/lv_xml_widget.c | 102 + .../lvgl/src/others/xml/lv_xml_widget.h | 58 + .../others/xml/parsers/lv_xml_arc_parser.c | 113 + .../others/xml/parsers/lv_xml_arc_parser.h | 40 + .../others/xml/parsers/lv_xml_bar_parser.c | 111 + .../others/xml/parsers/lv_xml_bar_parser.h | 40 + .../others/xml/parsers/lv_xml_button_parser.c | 59 + .../others/xml/parsers/lv_xml_button_parser.h | 41 + .../xml/parsers/lv_xml_buttonmatrix_parser.c | 171 + .../xml/parsers/lv_xml_buttonmatrix_parser.h | 41 + .../xml/parsers/lv_xml_calendar_parser.c | 104 + .../xml/parsers/lv_xml_calendar_parser.h | 43 + .../others/xml/parsers/lv_xml_canvas_parser.c | 59 + .../others/xml/parsers/lv_xml_canvas_parser.h | 41 + .../others/xml/parsers/lv_xml_chart_parser.c | 206 + .../others/xml/parsers/lv_xml_chart_parser.h | 45 + .../xml/parsers/lv_xml_checkbox_parser.c | 65 + .../xml/parsers/lv_xml_checkbox_parser.h | 40 + .../xml/parsers/lv_xml_dropdown_parser.c | 93 + .../xml/parsers/lv_xml_dropdown_parser.h | 41 + .../others/xml/parsers/lv_xml_event_parser.c | 170 + .../others/xml/parsers/lv_xml_event_parser.h | 40 + .../others/xml/parsers/lv_xml_image_parser.c | 99 + .../others/xml/parsers/lv_xml_image_parser.h | 43 + .../xml/parsers/lv_xml_keyboard_parser.c | 85 + .../xml/parsers/lv_xml_keyboard_parser.h | 41 + .../others/xml/parsers/lv_xml_label_parser.c | 110 + .../others/xml/parsers/lv_xml_label_parser.h | 41 + .../others/xml/parsers/lv_xml_obj_parser.c | 399 + .../others/xml/parsers/lv_xml_obj_parser.h | 40 + .../others/xml/parsers/lv_xml_roller_parser.c | 117 + .../others/xml/parsers/lv_xml_roller_parser.h | 40 + .../others/xml/parsers/lv_xml_scale_parser.c | 135 + .../others/xml/parsers/lv_xml_scale_parser.h | 41 + .../others/xml/parsers/lv_xml_slider_parser.c | 122 + .../others/xml/parsers/lv_xml_slider_parser.h | 40 + .../xml/parsers/lv_xml_spangroup_parser.c | 106 + .../xml/parsers/lv_xml_spangroup_parser.h | 41 + .../others/xml/parsers/lv_xml_table_parser.c | 149 + .../others/xml/parsers/lv_xml_table_parser.h | 43 + .../xml/parsers/lv_xml_tabview_parser.c | 94 + .../xml/parsers/lv_xml_tabview_parser.h | 44 + .../xml/parsers/lv_xml_textarea_parser.c | 72 + .../xml/parsers/lv_xml_textarea_parser.h | 41 + .../src/stdlib/builtin/LICENSE_SPRINTF.txt | 23 + .../lvgl/src/stdlib/builtin/LICENSE_TLSF.txt | 1 + .../src/stdlib/builtin/lv_sprintf_builtin.c | 12 +- .../src/stdlib/builtin/lv_string_builtin.c | 52 +- .../lvgl/src/stdlib/builtin/lv_tlsf.h | 3 +- .../lvgl/src/stdlib/builtin/lv_tlsf_private.h | 1 + .../lvgl/src/stdlib/clib/lv_string_clib.c | 26 + lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.c | 20 + lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.h | 27 +- .../lvgl/src/stdlib/lv_sprintf.h | 15 + lib/libesp32_lvgl/lvgl/src/stdlib/lv_string.h | 48 +- .../src/stdlib/rtthread/lv_string_rtthread.c | 39 + .../lvgl/src/stdlib/uefi/lv_mem_core_uefi.c | 116 + .../src/themes/default/lv_theme_default.c | 43 +- .../lvgl/src/themes/lv_theme_private.h | 2 +- .../lvgl/src/themes/mono/lv_theme_mono.c | 8 + .../lvgl/src/themes/mono/lv_theme_mono.h | 6 + .../lvgl/src/widgets/3dtexture/lv_3dtexture.c | 144 + .../lvgl/src/widgets/3dtexture/lv_3dtexture.h | 78 + .../3dtexture/lv_3dtexture_private.h} | 24 +- .../lvgl/src/widgets/animimage/lv_animimage.c | 105 +- .../lvgl/src/widgets/animimage/lv_animimage.h | 94 +- .../widgets/animimage/lv_animimage_private.h | 2 +- .../lvgl/src/widgets/arc/lv_arc.c | 15 +- .../lvgl/src/widgets/arc/lv_arc_private.h | 2 +- .../lvgl/src/widgets/bar/lv_bar.c | 11 +- .../lvgl/src/widgets/bar/lv_bar.h | 6 +- .../lvgl/src/widgets/bar/lv_bar_private.h | 4 +- .../lvgl/src/widgets/button/lv_button.c | 2 +- .../src/widgets/button/lv_button_private.h | 2 +- .../widgets/buttonmatrix/lv_buttonmatrix.c | 223 +- .../widgets/buttonmatrix/lv_buttonmatrix.h | 44 +- .../buttonmatrix/lv_buttonmatrix_private.h | 5 +- .../lvgl/src/widgets/calendar/lv_calendar.c | 6 +- .../lvgl/src/widgets/calendar/lv_calendar.h | 2 +- .../widgets/calendar/lv_calendar_chinese.c | 2 +- .../calendar/lv_calendar_chinese_private.h | 53 - .../calendar/lv_calendar_header_arrow.c | 16 +- .../calendar/lv_calendar_header_arrow.h | 2 +- .../calendar/lv_calendar_header_dropdown.c | 43 +- .../calendar/lv_calendar_header_dropdown.h | 2 +- .../widgets/calendar/lv_calendar_private.h | 2 +- .../lvgl/src/widgets/canvas/lv_canvas.c | 10 +- .../src/widgets/canvas/lv_canvas_private.h | 2 +- .../lvgl/src/widgets/chart/lv_chart.c | 160 +- .../lvgl/src/widgets/chart/lv_chart.h | 54 +- .../lvgl/src/widgets/chart/lv_chart_private.h | 22 +- .../lvgl/src/widgets/checkbox/lv_checkbox.c | 4 +- .../widgets/checkbox/lv_checkbox_private.h | 2 +- .../lvgl/src/widgets/dropdown/lv_dropdown.c | 25 +- .../widgets/dropdown/lv_dropdown_private.h | 4 +- .../lvgl/src/widgets/image/lv_image.c | 139 +- .../lvgl/src/widgets/image/lv_image.h | 34 +- .../lvgl/src/widgets/image/lv_image_private.h | 3 +- .../src/widgets/imagebutton/lv_imagebutton.c | 7 +- .../imagebutton/lv_imagebutton_private.h | 4 +- .../lvgl/src/widgets/keyboard/lv_keyboard.c | 2 +- .../widgets/keyboard/lv_keyboard_private.h | 2 +- .../lvgl/src/widgets/label/lv_label.c | 377 +- .../lvgl/src/widgets/label/lv_label.h | 25 +- .../lvgl/src/widgets/label/lv_label_private.h | 17 +- .../lvgl/src/widgets/led/lv_led.c | 6 +- .../lvgl/src/widgets/led/lv_led_private.h | 2 +- .../lvgl/src/widgets/line/lv_line.c | 3 +- .../lvgl/src/widgets/line/lv_line_private.h | 2 +- .../lvgl/src/widgets/list/lv_list.c | 8 +- .../lvgl/src/widgets/list/lv_list.h | 4 + .../lvgl/src/widgets/lottie/lv_lottie.c | 21 +- .../lvgl/src/widgets/menu/lv_menu.c | 27 +- .../lvgl/src/widgets/menu/lv_menu.h | 18 +- .../lvgl/src/widgets/menu/lv_menu_private.h | 10 +- .../lvgl/src/widgets/msgbox/lv_msgbox.c | 14 +- .../src/widgets/msgbox/lv_msgbox_private.h | 2 +- .../src/widgets/objx_templ/lv_objx_templ.c | 4 +- .../property/lv_animimage_properties.c | 26 + .../widgets/property/lv_obj_property_names.h | 4 +- .../widgets/property/lv_slider_properties.c | 30 + .../widgets/property/lv_style_properties.c | 10 +- .../widgets/property/lv_style_properties.h | 8 + .../lvgl/src/widgets/roller/lv_roller.c | 57 +- .../lvgl/src/widgets/roller/lv_roller.h | 17 +- .../src/widgets/roller/lv_roller_private.h | 2 +- .../lvgl/src/widgets/scale/lv_scale.c | 370 +- .../lvgl/src/widgets/scale/lv_scale.h | 195 +- .../lvgl/src/widgets/scale/lv_scale_private.h | 77 +- .../lvgl/src/widgets/slider/lv_slider.c | 86 +- .../lvgl/src/widgets/slider/lv_slider.h | 39 +- .../src/widgets/slider/lv_slider_private.h | 2 +- .../lvgl/src/widgets/span/lv_span.c | 567 +- .../lvgl/src/widgets/span/lv_span.h | 97 +- .../lvgl/src/widgets/span/lv_span_private.h | 9 +- .../lvgl/src/widgets/spinbox/lv_spinbox.c | 2 +- .../src/widgets/spinbox/lv_spinbox_private.h | 2 +- .../lvgl/src/widgets/spinner/lv_spinner.c | 2 +- .../lvgl/src/widgets/switch/lv_switch.c | 110 +- .../lvgl/src/widgets/switch/lv_switch.h | 32 + .../src/widgets/switch/lv_switch_private.h | 3 +- .../lvgl/src/widgets/table/lv_table.c | 60 +- .../lvgl/src/widgets/table/lv_table.h | 3 +- .../lvgl/src/widgets/table/lv_table_private.h | 4 +- .../lvgl/src/widgets/tabview/lv_tabview.c | 24 +- .../src/widgets/tabview/lv_tabview_private.h | 2 +- .../lvgl/src/widgets/textarea/lv_textarea.c | 10 +- .../widgets/textarea/lv_textarea_private.h | 2 +- .../lvgl/src/widgets/tileview/lv_tileview.c | 7 +- .../lvgl/src/widgets/tileview/lv_tileview.h | 33 +- .../widgets/tileview/lv_tileview_private.h | 4 +- .../lvgl/src/widgets/win/lv_win.c | 4 +- .../lvgl/src/widgets/win/lv_win.h | 30 + .../lvgl/src/widgets/win/lv_win_private.h | 2 +- tasmota/lvgl_berry/tasmota_lv_conf.h | 1101 +- 789 files changed, 142829 insertions(+), 18101 deletions(-) create mode 100644 lib/libesp32_lvgl/lvgl/lvgl_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d_fill.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d_img.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/lv_draw_3d.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/lv_draw_3d.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_arc.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_border.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_fill.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_img.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_label.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_layer.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_line.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_stm32_hal.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_triangle.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_utils.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_utils.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_nema_gfx_path.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_nema_gfx_path.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_buf_g2d.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d_fill.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d_img.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_buf_map.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_buf_map.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_utils.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_utils.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/opengles/lv_draw_opengles.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/opengles/lv_draw_opengles.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888_premultiplied.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888_premultiplied.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565_swapped.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565_swapped.h rename lib/libesp32_lvgl/lvgl/src/draw/sw/{lv_draw_sw_gradient.c => lv_draw_sw_grad.c} (78%) create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_grad.h delete mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient.h create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_utils.c create mode 100644 lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_utils.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/display/ft81x/lv_ft81x.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/display/ft81x/lv_ft81x.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/display/ft81x/lv_ft81x_defines.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/display/st_ltdc/lv_st_ltdc.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/display/st_ltdc/lv_st_ltdc.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/evdev/lv_evdev_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_context.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_context.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_display.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_display.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_edk2.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_gnu_efi.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev_keyboard.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev_pointer.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev_touch.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_private.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_std_wrapper.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_cache.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_dmabuf.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_keyboard.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_keyboard.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer_axis.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer_axis.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_seat.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_shell.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_shm.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_touch.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_touch.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_window.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_window.h create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_window_decorations.c create mode 100644 lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_xdg_shell.c create mode 100644 lib/libesp32_lvgl/lvgl/src/font/lv_font_montserrat_14_aligned.c create mode 100644 lib/libesp32_lvgl/lvgl/src/font/lv_font_source_han_sans_sc_14_cjk.c create mode 100644 lib/libesp32_lvgl/lvgl/src/font/lv_font_source_han_sans_sc_16_cjk.c create mode 100644 lib/libesp32_lvgl/lvgl/src/indev/lv_indev_gesture.c create mode 100644 lib/libesp32_lvgl/lvgl/src/indev/lv_indev_gesture.h create mode 100644 lib/libesp32_lvgl/lvgl/src/indev/lv_indev_gesture_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/barcode/LICENSE.txt create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/LICENSE.txt create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/add_lvgl_if.sh create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/ascii.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/asciitab.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/expat.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/expat_config.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/expat_external.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/iasciitab.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/internal.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/latin1tab.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/nametab.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/siphash.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/utf8tab.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/winconfig.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/xmlparse.c create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/xmlrole.c create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/xmlrole.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok.c create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok_impl.c create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok_impl.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok_ns.c create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/freetype/LICENSE.txt create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_uefi.c create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/gif/LICENSE.txt create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/lodepng/LICENSE.txt rename lib/libesp32_lvgl/lvgl/src/libs/lz4/{LICENSE => LICENSE.txt} (100%) create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/qrcode/LICENSE.txt create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg.c create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_decoder.c create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_decoder.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_render.c create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_render.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_token.c create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_token.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/LICENSE.txt delete mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLines.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieCommon.h create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieModifier.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgLottieModifier.h rename lib/libesp32_lvgl/lvgl/src/libs/thorvg/{tvgLines.h => tvgLottieRenderPooler.h} (57%) create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwPostEffect.cpp create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/LICENSE.txt create mode 100644 lib/libesp32_lvgl/lvgl/src/libs/tjpgd/LICENSE.txt create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_class.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_lru_ll.c create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_lru_ll.h rename lib/libesp32_lvgl/lvgl/src/misc/cache/{ => class}/lv_cache_lru_rb.c (91%) rename lib/libesp32_lvgl/lvgl/src/misc/cache/{ => class}/lv_cache_lru_rb.h (93%) create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/cache/instance/lv_cache_instance.h rename lib/libesp32_lvgl/lvgl/src/misc/cache/{ => instance}/lv_image_cache.c (66%) rename lib/libesp32_lvgl/lvgl/src/misc/cache/{ => instance}/lv_image_cache.h (81%) rename lib/libesp32_lvgl/lvgl/src/misc/cache/{ => instance}/lv_image_header_cache.c (64%) rename lib/libesp32_lvgl/lvgl/src/misc/cache/{ => instance}/lv_image_header_cache.h (81%) create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_circle_buf.c create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_circle_buf.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_grad.c create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_grad.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_iter.c create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_iter.h create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_tree.c create mode 100644 lib/libesp32_lvgl/lvgl/src/misc/lv_tree.h create mode 100644 lib/libesp32_lvgl/lvgl/src/osal/lv_linux.c create mode 100644 lib/libesp32_lvgl/lvgl/src/osal/lv_linux_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/osal/lv_sdl2.c create mode 100644 lib/libesp32_lvgl/lvgl/src/osal/lv_sdl2.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager_recycle.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager_recycle.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/test/lv_test.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/test/lv_test_display.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/test/lv_test_display.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/test/lv_test_helpers.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/test/lv_test_helpers.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev_gesture.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev_gesture.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/test/lv_test_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/test/lv_test_screenshot_compare.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/test/lv_test_screenshot_compare.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_base_types.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_base_types.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_component.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_component.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_component_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_style.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_style.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_update.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_update.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_utils.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_utils.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_widget.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_widget.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_arc_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_arc_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_bar_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_bar_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_button_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_button_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_buttonmatrix_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_buttonmatrix_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_calendar_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_calendar_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_canvas_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_canvas_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_chart_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_chart_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_checkbox_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_checkbox_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_dropdown_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_dropdown_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_event_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_event_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_image_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_image_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_keyboard_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_keyboard_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_label_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_label_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_obj_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_obj_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_roller_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_roller_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_scale_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_scale_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_slider_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_slider_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_spangroup_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_spangroup_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_table_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_table_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_tabview_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_tabview_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_textarea_parser.c create mode 100644 lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_textarea_parser.h create mode 100644 lib/libesp32_lvgl/lvgl/src/stdlib/builtin/LICENSE_SPRINTF.txt create mode 100644 lib/libesp32_lvgl/lvgl/src/stdlib/builtin/LICENSE_TLSF.txt create mode 100644 lib/libesp32_lvgl/lvgl/src/stdlib/uefi/lv_mem_core_uefi.c create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/3dtexture/lv_3dtexture.c create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/3dtexture/lv_3dtexture.h rename lib/libesp32_lvgl/lvgl/src/{draw/sw/lv_draw_sw_gradient_private.h => widgets/3dtexture/lv_3dtexture_private.h} (56%) delete mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese_private.h create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/property/lv_animimage_properties.c create mode 100644 lib/libesp32_lvgl/lvgl/src/widgets/property/lv_slider_properties.c diff --git a/CHANGELOG.md b/CHANGELOG.md index 2552d70a7..22fc10903 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ All notable changes to this project will be documented in this file. - Increase number of supported LoRaWan nodes from 4 to 16 - Berry change number parser for json to reuse same parser as lexer (#23505) - Berry increase web hooks from 16 to 32 (#23507) +- ESP32 LVGL library from v9.2.2 to v9.3.0 ### Fixed - Haspmota `haspmota.parse()` page parsing (#23403) 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 fefbf6fe8..a7029093a 100644 --- a/lib/libesp32_lvgl/LVGL_assets/src/lv_theme_haspmota.c +++ b/lib/libesp32_lvgl/LVGL_assets/src/lv_theme_haspmota.c @@ -176,9 +176,6 @@ struct _haspmota_theme_t { bool inited; haspmota_theme_styles_t styles; - lv_color_filter_dsc_t dark_filter; - lv_color_filter_dsc_t grey_filter; - #if LV_THEME_DEFAULT_TRANSITION_TIME lv_style_transition_dsc_t trans_delayed; lv_style_transition_dsc_t trans_normal; @@ -226,7 +223,8 @@ static void style_init(haspmota_theme_t * theme) LV_STYLE_TRANSLATE_Y, LV_STYLE_TRANSLATE_X, LV_STYLE_TRANSFORM_ROTATION, LV_STYLE_TRANSFORM_SCALE_X, LV_STYLE_TRANSFORM_SCALE_Y, - LV_STYLE_COLOR_FILTER_OPA, LV_STYLE_COLOR_FILTER_DSC, + LV_STYLE_RECOLOR_OPA, LV_STYLE_RECOLOR, + // LV_STYLE_COLOR_FILTER_OPA, LV_STYLE_COLOR_FILTER_DSC, 0 }; #endif @@ -301,30 +299,28 @@ static void style_init(haspmota_theme_t * theme) LV_DPX_CALC(theme->disp_dpi, theme->disp_size == DISP_LARGE ? 16 : theme->disp_size == DISP_MEDIUM ? 12 : 10)); // Tasmota min 10 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_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)); - style_init_reset(&theme->styles.btn_border_color); - lv_style_set_border_color(&theme->styles.btn_border_color, lv_color_mix(theme->color_text, theme->color_grey, LV_OPA_80)); - - style_init_reset(&theme->styles.btn_border); - lv_style_set_border_width(&theme->styles.btn_border, BORDER_WIDTH); - lv_style_set_border_side(&theme->styles.btn_border, LV_BORDER_SIDE_FULL); - lv_style_set_border_opa(&theme->styles.btn_border, LV_OPA_COVER); - - lv_color_filter_dsc_init(&theme->dark_filter, dark_color_filter_cb); - lv_color_filter_dsc_init(&theme->grey_filter, grey_filter_cb); - style_init_reset(&theme->styles.pressed); - lv_style_set_color_filter_dsc(&theme->styles.pressed, &theme->dark_filter); - lv_style_set_color_filter_opa(&theme->styles.pressed, LV_OPA_60); // Tasmota from 35 ot LV_OPA_60 (153) + lv_style_set_recolor(&theme->styles.pressed, lv_color_black()); + lv_style_set_recolor_opa(&theme->styles.pressed, 70); style_init_reset(&theme->styles.disabled); - lv_style_set_color_filter_dsc(&theme->styles.disabled, &theme->grey_filter); - lv_style_set_color_filter_opa(&theme->styles.disabled, LV_OPA_50); + if(theme_def->base.flags & MODE_DARK) + lv_style_set_recolor(&theme->styles.disabled, lv_palette_darken(LV_PALETTE_GREY, 2)); + else + lv_style_set_recolor(&theme->styles.disabled, lv_palette_lighten(LV_PALETTE_GREY, 2)); + lv_style_set_recolor_opa(&theme->styles.disabled, LV_OPA_50); style_init_reset(&theme->styles.clip_corner); lv_style_set_clip_corner(&theme->styles.clip_corner, true); @@ -430,7 +426,6 @@ static void style_init(haspmota_theme_t * theme) style_init_reset(&theme->styles.dropdown_list); lv_style_set_max_height(&theme->styles.dropdown_list, LV_DPI_DEF * 2); #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)); @@ -1083,6 +1078,13 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) lv_obj_add_style(obj, &theme->styles.bg_color_secondary_muted, LV_PART_ITEMS | LV_STATE_EDITED); } #endif + +#if LV_USE_LABEL && LV_USE_TEXTAREA + else if(lv_obj_check_type(obj, &lv_label_class) && lv_obj_check_type(parent, &lv_textarea_class)) { + lv_obj_add_style(obj, &theme->styles.bg_color_primary, LV_PART_SELECTED); + } +#endif + #if LV_USE_LIST else if(lv_obj_check_type(obj, &lv_list_class)) { lv_obj_add_style(obj, &theme->styles.card, 0); diff --git a/lib/libesp32_lvgl/freetype/library.json b/lib/libesp32_lvgl/freetype/library.json index 93d86e7b1..2785a3e47 100644 --- a/lib/libesp32_lvgl/freetype/library.json +++ b/lib/libesp32_lvgl/freetype/library.json @@ -18,6 +18,7 @@ "+", "+", + "+", "+", "+", 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 1a274905c..63c114692 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 @@ -15,6 +15,7 @@ anim_delete_all|||[lv_anim_delete_all](https://docs.lvgl.io/9.0/search.html?q=lv anim_get|\, comptr|lv.anim|[lv_anim_get](https://docs.lvgl.io/9.0/search.html?q=lv_anim_get) anim_get_timer||lv.timer|[lv_anim_get_timer](https://docs.lvgl.io/9.0/search.html?q=lv_anim_get_timer) anim_refr_now|||[lv_anim_refr_now](https://docs.lvgl.io/9.0/search.html?q=lv_anim_refr_now) +anim_resolve_speed|int, int, int|int|[lv_anim_resolve_speed](https://docs.lvgl.io/9.0/search.html?q=lv_anim_resolve_speed) 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) @@ -50,7 +51,10 @@ color_luminance|lv.color|int|[lv_color_luminance](https://docs.lvgl.io/9.0/searc 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) +color_mix32_premultiplied|int, int|int|[lv_color_mix32_premultiplied](https://docs.lvgl.io/9.0/search.html?q=lv_color_mix32_premultiplied) +color_over32|int, int|int|[lv_color_over32](https://docs.lvgl.io/9.0/search.html?q=lv_color_over32) color_rgb_to_hsv|int, int, int|int|[lv_color_rgb_to_hsv](https://docs.lvgl.io/9.0/search.html?q=lv_color_rgb_to_hsv) +color_swap_16|int|int|[lv_color_swap_16](https://docs.lvgl.io/9.0/search.html?q=lv_color_swap_16) color_to_32|lv.color, int|int|[lv_color_to_32](https://docs.lvgl.io/9.0/search.html?q=lv_color_to_32) color_to_hsv|lv.color|int|[lv_color_to_hsv](https://docs.lvgl.io/9.0/search.html?q=lv_color_to_hsv) color_to_int|lv.color|int|[lv_color_to_int](https://docs.lvgl.io/9.0/search.html?q=lv_color_to_int) @@ -59,6 +63,7 @@ color_to_u32|lv.color|int|[lv_color_to_u32](https://docs.lvgl.io/9.0/search.html color_white||lv.color|[lv_color_white](https://docs.lvgl.io/9.0/search.html?q=lv_color_white) display_create|int, int|lv.display|[lv_display_create](https://docs.lvgl.io/9.0/search.html?q=lv_display_create) display_get_default||lv.display|[lv_display_get_default](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_default) +display_refr_timer|lv.timer||[lv_display_refr_timer](https://docs.lvgl.io/9.0/search.html?q=lv_display_refr_timer) dpx|int|int|[lv_dpx](https://docs.lvgl.io/9.0/search.html?q=lv_dpx) draw_arc|lv.layer, lv.draw_arc_dsc||[lv_draw_arc](https://docs.lvgl.io/9.0/search.html?q=lv_draw_arc) draw_arc_dsc_init|lv.draw_arc_dsc||[lv_draw_arc_dsc_init](https://docs.lvgl.io/9.0/search.html?q=lv_draw_arc_dsc_init) @@ -77,17 +82,24 @@ draw_label_dsc_init|lv.draw_label_dsc||[lv_draw_label_dsc_init](https://docs.lvg draw_layer_alloc_buf|lv.layer|comptr|[lv_draw_layer_alloc_buf](https://docs.lvgl.io/9.0/search.html?q=lv_draw_layer_alloc_buf) draw_layer_create|lv.layer, int, lv.area|lv.layer|[lv_draw_layer_create](https://docs.lvgl.io/9.0/search.html?q=lv_draw_layer_create) draw_layer_go_to_xy|lv.layer, int, int|comptr|[lv_draw_layer_go_to_xy](https://docs.lvgl.io/9.0/search.html?q=lv_draw_layer_go_to_xy) +draw_layer_init|lv.layer, lv.layer, int, lv.area||[lv_draw_layer_init](https://docs.lvgl.io/9.0/search.html?q=lv_draw_layer_init) +draw_letter|lv.layer, lv.draw_letter_dsc, comptr||[lv_draw_letter](https://docs.lvgl.io/9.0/search.html?q=lv_draw_letter) +draw_letter_dsc_init|lv.draw_letter_dsc||[lv_draw_letter_dsc_init](https://docs.lvgl.io/9.0/search.html?q=lv_draw_letter_dsc_init) draw_line|lv.layer, lv.draw_line_dsc||[lv_draw_line](https://docs.lvgl.io/9.0/search.html?q=lv_draw_line) 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_code_get_name|int|string|[lv_event_code_get_name](https://docs.lvgl.io/9.0/search.html?q=lv_event_code_get_name) 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) flex_init|||[lv_flex_init](https://docs.lvgl.io/9.0/search.html?q=lv_flex_init) +font_get_default||lv.font|[lv_font_get_default](https://docs.lvgl.io/9.0/search.html?q=lv_font_get_default) font_get_glyph_width|lv.font, int, int|int|[lv_font_get_glyph_width](https://docs.lvgl.io/9.0/search.html?q=lv_font_get_glyph_width) font_get_line_height|lv.font|int|[lv_font_get_line_height](https://docs.lvgl.io/9.0/search.html?q=lv_font_get_line_height) +font_has_static_bitmap|lv.font|bool|[lv_font_has_static_bitmap](https://docs.lvgl.io/9.0/search.html?q=lv_font_has_static_bitmap) +font_info_is_equal|lv.font_info, lv.font_info|bool|[lv_font_info_is_equal](https://docs.lvgl.io/9.0/search.html?q=lv_font_info_is_equal) font_set_kerning|lv.font, int||[lv_font_set_kerning](https://docs.lvgl.io/9.0/search.html?q=lv_font_set_kerning) get_hor_res||int|[lv_get_hor_res](https://docs.lvgl.io/9.0/search.html?q=lv_get_hor_res) get_ts_calibration||lv.ts_calibration|[lv_get_ts_calibration](https://docs.lvgl.io/9.0/search.html?q=lv_get_ts_calibration) @@ -102,6 +114,8 @@ indev_create||lv.indev|[lv_indev_create](https://docs.lvgl.io/9.0/search.html?q= indev_get_active_obj||lv.obj|[lv_indev_get_active_obj](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_active_obj) indev_read_timer_cb|lv.timer||[lv_indev_read_timer_cb](https://docs.lvgl.io/9.0/search.html?q=lv_indev_read_timer_cb) layer_bottom||lv.obj|[lv_layer_bottom](https://docs.lvgl.io/9.0/search.html?q=lv_layer_bottom) +layer_init|lv.layer||[lv_layer_init](https://docs.lvgl.io/9.0/search.html?q=lv_layer_init) +layer_reset|lv.layer||[lv_layer_reset](https://docs.lvgl.io/9.0/search.html?q=lv_layer_reset) layer_sys||lv.obj|[lv_layer_sys](https://docs.lvgl.io/9.0/search.html?q=lv_layer_sys) layer_top||lv.obj|[lv_layer_top](https://docs.lvgl.io/9.0/search.html?q=lv_layer_top) obj_assign_id|lv.obj_class, lv.obj||[lv_obj_assign_id](https://docs.lvgl.io/9.0/search.html?q=lv_obj_assign_id) @@ -145,6 +159,8 @@ style_register_prop|int|int|[lv_style_register_prop](https://docs.lvgl.io/9.0/se 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) text_get_width|string, int, lv.font, int|int|[lv_text_get_width](https://docs.lvgl.io/9.0/search.html?q=lv_text_get_width) +text_get_width_with_flags|string, int, lv.font, int, int|int|[lv_text_get_width_with_flags](https://docs.lvgl.io/9.0/search.html?q=lv_text_get_width_with_flags) +text_is_cmd|comptr, int|bool|[lv_text_is_cmd](https://docs.lvgl.io/9.0/search.html?q=lv_text_is_cmd) theme_apply|lv.obj||[lv_theme_apply](https://docs.lvgl.io/9.0/search.html?q=lv_theme_apply) theme_get_color_primary|lv.obj|lv.color|[lv_theme_get_color_primary](https://docs.lvgl.io/9.0/search.html?q=lv_theme_get_color_primary) theme_get_color_secondary|lv.obj|lv.color|[lv_theme_get_color_secondary](https://docs.lvgl.io/9.0/search.html?q=lv_theme_get_color_secondary) @@ -182,6 +198,10 @@ get_repeat_count||int|[lv_anim_get_repeat_count](https://docs.lvgl.io/9.0/search get_time||int|[lv_anim_get_time](https://docs.lvgl.io/9.0/search.html?q=lv_anim_get_time) get_user_data||comptr|[lv_anim_get_user_data](https://docs.lvgl.io/9.0/search.html?q=lv_anim_get_user_data) init|||[lv_anim_init](https://docs.lvgl.io/9.0/search.html?q=lv_anim_init) +is_paused||bool|[lv_anim_is_paused](https://docs.lvgl.io/9.0/search.html?q=lv_anim_is_paused) +pause|||[lv_anim_pause](https://docs.lvgl.io/9.0/search.html?q=lv_anim_pause) +pause_for|int||[lv_anim_pause_for](https://docs.lvgl.io/9.0/search.html?q=lv_anim_pause_for) +resume|||[lv_anim_resume](https://docs.lvgl.io/9.0/search.html?q=lv_anim_resume) set_bezier3_param|int, int, int, int||[lv_anim_set_bezier3_param](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_bezier3_param) set_completed_cb|comptr||[lv_anim_set_completed_cb](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_completed_cb) set_custom_exec_cb|comptr||[lv_anim_set_custom_exec_cb](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_custom_exec_cb) @@ -191,14 +211,13 @@ set_early_apply|bool||[lv_anim_set_early_apply](https://docs.lvgl.io/9.0/search. set_exec_cb|comptr||[lv_anim_set_exec_cb](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_exec_cb) set_get_value_cb|comptr||[lv_anim_set_get_value_cb](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_get_value_cb) set_path_cb|comptr||[lv_anim_set_path_cb](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_path_cb) -set_playback_delay|int||[lv_anim_set_playback_delay](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_playback_delay) -set_playback_duration|int||[lv_anim_set_playback_duration](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_playback_duration) -set_playback_time|int||[lv_anim_set_playback_time](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_playback_time) set_ready_cb|comptr||[lv_anim_set_completed_cb](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_completed_cb) set_repeat_count|int||[lv_anim_set_repeat_count](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_repeat_count) set_repeat_delay|int||[lv_anim_set_repeat_delay](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_repeat_delay) +set_reverse_delay|int||[lv_anim_set_reverse_delay](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_reverse_delay) +set_reverse_duration|int||[lv_anim_set_reverse_duration](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_reverse_duration) +set_reverse_time|int||[lv_anim_set_reverse_time](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_reverse_time) set_start_cb|comptr||[lv_anim_set_start_cb](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_start_cb) -set_time|int||[lv_anim_set_time](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_time) set_user_data|\||[lv_anim_set_user_data](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_user_data) set_values|int, int||[lv_anim_set_values](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_values) set_var|\||[lv_anim_set_var](https://docs.lvgl.io/9.0/search.html?q=lv_anim_set_var) @@ -222,6 +241,7 @@ get_antialiasing||bool|[lv_display_get_antialiasing](https://docs.lvgl.io/9.0/se get_color_format||int|[lv_display_get_color_format](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_color_format) get_dpi||int|[lv_display_get_dpi](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_dpi) get_dpi||int|[lv_display_get_dpi](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_dpi) +get_draw_buf_size||int|[lv_display_get_draw_buf_size](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_draw_buf_size) get_driver_data||comptr|[lv_display_get_driver_data](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_driver_data) get_event_count||int|[lv_display_get_event_count](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_event_count) get_event_dsc|int|lv.event_dsc|[lv_display_get_event_dsc](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_event_dsc) @@ -229,17 +249,21 @@ get_hor_res||int|[lv_display_get_horizontal_resolution](https://docs.lvgl.io/9.0 get_horizontal_resolution||int|[lv_display_get_horizontal_resolution](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_horizontal_resolution) get_inactive_time||int|[lv_display_get_inactive_time](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_inactive_time) get_inactive_time||int|[lv_display_get_inactive_time](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_inactive_time) +get_invalidated_draw_buf_size|int, int|int|[lv_display_get_invalidated_draw_buf_size](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_invalidated_draw_buf_size) get_layer_bottom||lv.obj|[lv_display_get_layer_bottom](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_layer_bottom) get_layer_sys||lv.obj|[lv_display_get_layer_sys](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_layer_sys) get_layer_sys||lv.obj|[lv_display_get_layer_sys](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_layer_sys) get_layer_top||lv.obj|[lv_display_get_layer_top](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_layer_top) get_layer_top||lv.obj|[lv_display_get_layer_top](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_layer_top) +get_matrix_rotation||bool|[lv_display_get_matrix_rotation](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_matrix_rotation) get_next||lv.display|[lv_display_get_next](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_next) get_next||lv.display|[lv_display_get_next](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_next) get_offset_x||int|[lv_display_get_offset_x](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_offset_x) get_offset_x||int|[lv_display_get_offset_x](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_offset_x) get_offset_y||int|[lv_display_get_offset_y](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_offset_y) get_offset_y||int|[lv_display_get_offset_y](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_offset_y) +get_original_horizontal_resolution||int|[lv_display_get_original_horizontal_resolution](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_original_horizontal_resolution) +get_original_vertical_resolution||int|[lv_display_get_original_vertical_resolution](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_original_vertical_resolution) get_physical_hor_res||int|[lv_display_get_physical_horizontal_resolution](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_physical_horizontal_resolution) get_physical_horizontal_resolution||int|[lv_display_get_physical_horizontal_resolution](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_physical_horizontal_resolution) get_physical_ver_res||int|[lv_display_get_physical_vertical_resolution](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_physical_vertical_resolution) @@ -253,25 +277,30 @@ get_screen_active||lv.obj|[lv_display_get_screen_active](https://docs.lvgl.io/9. get_screen_prev||lv.obj|[lv_display_get_screen_prev](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_screen_prev) get_theme||lv.theme|[lv_display_get_theme](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_theme) get_theme||lv.theme|[lv_display_get_theme](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_theme) +get_tile_cnt||int|[lv_display_get_tile_cnt](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_tile_cnt) get_user_data||comptr|[lv_display_get_user_data](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_user_data) get_ver_res||int|[lv_display_get_vertical_resolution](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_vertical_resolution) get_vertical_resolution||int|[lv_display_get_vertical_resolution](https://docs.lvgl.io/9.0/search.html?q=lv_display_get_vertical_resolution) is_double_buffered||bool|[lv_display_is_double_buffered](https://docs.lvgl.io/9.0/search.html?q=lv_display_is_double_buffered) is_invalidation_enabled||bool|[lv_display_is_invalidation_enabled](https://docs.lvgl.io/9.0/search.html?q=lv_display_is_invalidation_enabled) is_invalidation_enabled||bool|[lv_display_is_invalidation_enabled](https://docs.lvgl.io/9.0/search.html?q=lv_display_is_invalidation_enabled) +register_vsync_event|\, \|bool|[lv_display_register_vsync_event](https://docs.lvgl.io/9.0/search.html?q=lv_display_register_vsync_event) 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) +send_vsync_event|\|int|[lv_display_send_vsync_event](https://docs.lvgl.io/9.0/search.html?q=lv_display_send_vsync_event) set_angle|int||[lv_display_set_rotation](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_rotation) set_antialiasing|bool||[lv_display_set_antialiasing](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_antialiasing) set_buffers|\, \, int, int||[lv_display_set_buffers](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_buffers) +set_buffers_with_stride|\, \, int, int, int||[lv_display_set_buffers_with_stride](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_buffers_with_stride) set_color_format|int||[lv_display_set_color_format](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_color_format) set_default|||[lv_display_set_default](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_default) set_default|||[lv_display_set_default](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_default) set_dpi|int||[lv_display_set_dpi](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_dpi) set_driver_data|\||[lv_display_set_driver_data](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_driver_data) +set_matrix_rotation|bool||[lv_display_set_matrix_rotation](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_matrix_rotation) set_offset|int, int||[lv_display_set_offset](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_offset) set_physical_resolution|int, int||[lv_display_set_physical_resolution](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_physical_resolution) set_render_mode|int||[lv_display_set_render_mode](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_render_mode) @@ -280,9 +309,11 @@ set_rotation|int||[lv_display_set_rotation](https://docs.lvgl.io/9.0/search.html set_rotation|int||[lv_display_set_rotation](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_rotation) set_theme|lv.theme||[lv_display_set_theme](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_theme) set_theme|lv.theme||[lv_display_set_theme](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_theme) +set_tile_cnt|int||[lv_display_set_tile_cnt](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_tile_cnt) set_user_data|\||[lv_display_set_user_data](https://docs.lvgl.io/9.0/search.html?q=lv_display_set_user_data) trig_activity|||[lv_display_trigger_activity](https://docs.lvgl.io/9.0/search.html?q=lv_display_trigger_activity) trigger_activity|||[lv_display_trigger_activity](https://docs.lvgl.io/9.0/search.html?q=lv_display_trigger_activity) +unregister_vsync_event|\, \|bool|[lv_display_unregister_vsync_event](https://docs.lvgl.io/9.0/search.html?q=lv_display_unregister_vsync_event) ### class `lv.event` @@ -294,6 +325,7 @@ get_current_target||comptr|[lv_event_get_current_target](https://docs.lvgl.io/9. get_current_target_obj||lv.obj|[lv_event_get_current_target_obj](https://docs.lvgl.io/9.0/search.html?q=lv_event_get_current_target_obj) get_hit_test_info||comptr|[lv_event_get_hit_test_info](https://docs.lvgl.io/9.0/search.html?q=lv_event_get_hit_test_info) get_indev||lv.indev|[lv_event_get_indev](https://docs.lvgl.io/9.0/search.html?q=lv_event_get_indev) +get_invalidated_area||lv.area|[lv_event_get_invalidated_area](https://docs.lvgl.io/9.0/search.html?q=lv_event_get_invalidated_area) get_key||int|[lv_event_get_key](https://docs.lvgl.io/9.0/search.html?q=lv_event_get_key) get_layer||lv.layer|[lv_event_get_layer](https://docs.lvgl.io/9.0/search.html?q=lv_event_get_layer) get_old_size||lv.area|[lv_event_get_old_size](https://docs.lvgl.io/9.0/search.html?q=lv_event_get_old_size) @@ -347,6 +379,7 @@ add_event_cb|\, int, \||[lv_indev_add_event_cb](https://docs.lvg del|||[lv_indev_delete](https://docs.lvgl.io/9.0/search.html?q=lv_indev_delete) delete|||[lv_indev_delete](https://docs.lvgl.io/9.0/search.html?q=lv_indev_delete) enable|bool||[lv_indev_enable](https://docs.lvgl.io/9.0/search.html?q=lv_indev_enable) +get_cursor||lv.obj|[lv_indev_get_cursor](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_cursor) get_disp||lv.display|[lv_indev_get_display](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_display) get_display||lv.display|[lv_indev_get_display](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_display) get_driver_data||comptr|[lv_indev_get_driver_data](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_driver_data) @@ -363,6 +396,7 @@ get_press_moved||bool|[lv_indev_get_press_moved](https://docs.lvgl.io/9.0/search 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) +get_short_click_streak||int|[lv_indev_get_short_click_streak](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_short_click_streak) get_state||int|[lv_indev_get_state](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_state) get_type||int|[lv_indev_get_type](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_type) get_user_data||comptr|[lv_indev_get_user_data](https://docs.lvgl.io/9.0/search.html?q=lv_indev_get_user_data) @@ -382,6 +416,7 @@ 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_repeat_time|int||[lv_indev_set_long_press_repeat_time](https://docs.lvgl.io/9.0/search.html?q=lv_indev_set_long_press_repeat_time) 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) @@ -395,6 +430,7 @@ wait_release|||[lv_indev_wait_release](https://docs.lvgl.io/9.0/search.html?q=lv Method|Arguments|Return type|LVGL equivalent :---|:---|:---|:--- +copy|lv.style||[lv_style_copy](https://docs.lvgl.io/9.0/search.html?q=lv_style_copy) is_const||bool|[lv_style_is_const](https://docs.lvgl.io/9.0/search.html?q=lv_style_is_const) is_empty||bool|[lv_style_is_empty](https://docs.lvgl.io/9.0/search.html?q=lv_style_is_empty) remove_prop|int|bool|[lv_style_remove_prop](https://docs.lvgl.io/9.0/search.html?q=lv_style_remove_prop) @@ -468,10 +504,13 @@ set_line_dash_width|int||[lv_style_set_line_dash_width](https://docs.lvgl.io/9.0 set_line_opa|int||[lv_style_set_line_opa](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_line_opa) set_line_rounded|bool||[lv_style_set_line_rounded](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_line_rounded) set_line_width|int||[lv_style_set_line_width](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_line_width) +set_margin_all|int||[lv_style_set_margin_all](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_margin_all) set_margin_bottom|int||[lv_style_set_margin_bottom](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_margin_bottom) +set_margin_hor|int||[lv_style_set_margin_hor](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_margin_hor) set_margin_left|int||[lv_style_set_margin_left](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_margin_left) set_margin_right|int||[lv_style_set_margin_right](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_margin_right) set_margin_top|int||[lv_style_set_margin_top](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_margin_top) +set_margin_ver|int||[lv_style_set_margin_ver](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_margin_ver) set_max_height|int||[lv_style_set_max_height](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_max_height) set_max_width|int||[lv_style_set_max_width](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_max_width) set_min_height|int||[lv_style_set_min_height](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_min_height) @@ -488,12 +527,16 @@ set_pad_column|int||[lv_style_set_pad_column](https://docs.lvgl.io/9.0/search.ht set_pad_gap|int||[lv_style_set_pad_gap](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_pad_gap) set_pad_hor|int||[lv_style_set_pad_hor](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_pad_hor) set_pad_left|int||[lv_style_set_pad_left](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_pad_left) +set_pad_radial|int||[lv_style_set_pad_radial](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_pad_radial) set_pad_right|int||[lv_style_set_pad_right](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_pad_right) set_pad_row|int||[lv_style_set_pad_row](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_pad_row) set_pad_top|int||[lv_style_set_pad_top](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_pad_top) set_pad_ver|int||[lv_style_set_pad_ver](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_pad_ver) set_prop|int, int||[lv_style_set_prop](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_prop) +set_radial_offset|int||[lv_style_set_radial_offset](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_radial_offset) set_radius|int||[lv_style_set_radius](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_radius) +set_recolor|lv.color||[lv_style_set_recolor](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_recolor) +set_recolor_opa|int||[lv_style_set_recolor_opa](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_recolor_opa) set_rotary_sensitivity|int||[lv_style_set_rotary_sensitivity](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_rotary_sensitivity) set_shadow_color|lv.color||[lv_style_set_shadow_color](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_shadow_color) set_shadow_offset_x|int||[lv_style_set_shadow_offset_x](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_shadow_offset_x) @@ -511,6 +554,9 @@ set_text_font|lv.font||[lv_style_set_text_font](https://docs.lvgl.io/9.0/search. set_text_letter_space|int||[lv_style_set_text_letter_space](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_text_letter_space) set_text_line_space|int||[lv_style_set_text_line_space](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_text_line_space) set_text_opa|int||[lv_style_set_text_opa](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_text_opa) +set_text_outline_stroke_color|lv.color||[lv_style_set_text_outline_stroke_color](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_text_outline_stroke_color) +set_text_outline_stroke_opa|int||[lv_style_set_text_outline_stroke_opa](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_text_outline_stroke_opa) +set_text_outline_stroke_width|int||[lv_style_set_text_outline_stroke_width](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_text_outline_stroke_width) set_transform_angle|int||[lv_style_set_transform_rotation](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_transform_rotation) set_transform_height|int||[lv_style_set_transform_height](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_transform_height) set_transform_pivot_x|int||[lv_style_set_transform_pivot_x](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_transform_pivot_x) @@ -524,6 +570,7 @@ set_transform_skew_y|int||[lv_style_set_transform_skew_y](https://docs.lvgl.io/9 set_transform_width|int||[lv_style_set_transform_width](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_transform_width) set_transform_zoom|int||[lv_style_set_transform_scale](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_transform_scale) set_transition|lv.style_transition_dsc||[lv_style_set_transition](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_transition) +set_translate_radial|int||[lv_style_set_translate_radial](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_translate_radial) set_translate_x|int||[lv_style_set_translate_x](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_translate_x) set_translate_y|int||[lv_style_set_translate_y](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_translate_y) set_width|int||[lv_style_set_width](https://docs.lvgl.io/9.0/search.html?q=lv_style_set_width) @@ -581,9 +628,9 @@ delete_delayed|int||[lv_obj_delete_delayed](https://docs.lvgl.io/9.0/search.html dump_tree|||[lv_obj_dump_tree](https://docs.lvgl.io/9.0/search.html?q=lv_obj_dump_tree) fade_in|int, int||[lv_obj_fade_in](https://docs.lvgl.io/9.0/search.html?q=lv_obj_fade_in) fade_out|int, int||[lv_obj_fade_out](https://docs.lvgl.io/9.0/search.html?q=lv_obj_fade_out) +find_by_id|\|lv.obj|[lv_obj_find_by_id](https://docs.lvgl.io/9.0/search.html?q=lv_obj_find_by_id) 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) @@ -713,11 +760,16 @@ get_style_outline_width|int|int|[lv_obj_get_style_outline_width](https://docs.lv get_style_pad_bottom|int|int|[lv_obj_get_style_pad_bottom](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_pad_bottom) get_style_pad_column|int|int|[lv_obj_get_style_pad_column](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_pad_column) get_style_pad_left|int|int|[lv_obj_get_style_pad_left](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_pad_left) +get_style_pad_radial|int|int|[lv_obj_get_style_pad_radial](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_pad_radial) get_style_pad_right|int|int|[lv_obj_get_style_pad_right](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_pad_right) get_style_pad_row|int|int|[lv_obj_get_style_pad_row](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_pad_row) get_style_pad_top|int|int|[lv_obj_get_style_pad_top](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_pad_top) get_style_prop|int, int|int|[lv_obj_get_style_prop](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_prop) +get_style_radial_offset|int|int|[lv_obj_get_style_radial_offset](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_radial_offset) get_style_radius|int|int|[lv_obj_get_style_radius](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_radius) +get_style_recolor|int|lv.color|[lv_obj_get_style_recolor](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_recolor) +get_style_recolor_opa|int|int|[lv_obj_get_style_recolor_opa](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_recolor_opa) +get_style_recolor_recursive|int|int|[lv_obj_get_style_recolor_recursive](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_recolor_recursive) get_style_rotary_sensitivity|int|int|[lv_obj_get_style_rotary_sensitivity](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_rotary_sensitivity) get_style_shadow_color|int|lv.color|[lv_obj_get_style_shadow_color](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_shadow_color) get_style_shadow_color_filtered|int|lv.color|[lv_obj_get_style_shadow_color_filtered](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_shadow_color_filtered) @@ -740,6 +792,10 @@ get_style_text_font|int|lv.font|[lv_obj_get_style_text_font](https://docs.lvgl.i get_style_text_letter_space|int|int|[lv_obj_get_style_text_letter_space](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_text_letter_space) get_style_text_line_space|int|int|[lv_obj_get_style_text_line_space](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_text_line_space) get_style_text_opa|int|int|[lv_obj_get_style_text_opa](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_text_opa) +get_style_text_outline_stroke_color|int|lv.color|[lv_obj_get_style_text_outline_stroke_color](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_text_outline_stroke_color) +get_style_text_outline_stroke_color_filtered|int|lv.color|[lv_obj_get_style_text_outline_stroke_color_filtered](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_text_outline_stroke_color_filtered) +get_style_text_outline_stroke_opa|int|int|[lv_obj_get_style_text_outline_stroke_opa](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_text_outline_stroke_opa) +get_style_text_outline_stroke_width|int|int|[lv_obj_get_style_text_outline_stroke_width](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_text_outline_stroke_width) get_style_transform_angle|int|int|[lv_obj_get_style_transform_rotation](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_transform_rotation) get_style_transform_height|int|int|[lv_obj_get_style_transform_height](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_transform_height) get_style_transform_pivot_x|int|int|[lv_obj_get_style_transform_pivot_x](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_transform_pivot_x) @@ -753,6 +809,7 @@ get_style_transform_skew_x|int|int|[lv_obj_get_style_transform_skew_x](https://d get_style_transform_skew_y|int|int|[lv_obj_get_style_transform_skew_y](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_transform_skew_y) get_style_transform_width|int|int|[lv_obj_get_style_transform_width](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_transform_width) get_style_transition|int|lv.style_transition_dsc|[lv_obj_get_style_transition](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_transition) +get_style_translate_radial|int|int|[lv_obj_get_style_translate_radial](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_translate_radial) get_style_translate_x|int|int|[lv_obj_get_style_translate_x](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_translate_x) get_style_translate_y|int|int|[lv_obj_get_style_translate_y](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_translate_y) get_style_width|int|int|[lv_obj_get_style_width](https://docs.lvgl.io/9.0/search.html?q=lv_obj_get_style_width) @@ -801,7 +858,7 @@ refresh_self_size||bool|[lv_obj_refresh_self_size](https://docs.lvgl.io/9.0/sear refresh_style|int, int||[lv_obj_refresh_style](https://docs.lvgl.io/9.0/search.html?q=lv_obj_refresh_style) remove|||[lv_obj_delete](https://docs.lvgl.io/9.0/search.html?q=lv_obj_delete) remove_event|int|bool|[lv_obj_remove_event](https://docs.lvgl.io/9.0/search.html?q=lv_obj_remove_event) -remove_event_cb|\|bool|[lv_obj_remove_event_cb](https://docs.lvgl.io/9.0/search.html?q=lv_obj_remove_event_cb) +remove_event_cb|\|int|[lv_obj_remove_event_cb](https://docs.lvgl.io/9.0/search.html?q=lv_obj_remove_event_cb) remove_event_cb_with_user_data|\, \|int|[lv_obj_remove_event_cb_with_user_data](https://docs.lvgl.io/9.0/search.html?q=lv_obj_remove_event_cb_with_user_data) remove_event_dsc|lv.event_dsc|bool|[lv_obj_remove_event_dsc](https://docs.lvgl.io/9.0/search.html?q=lv_obj_remove_event_dsc) remove_flag|int||[lv_obj_remove_flag](https://docs.lvgl.io/9.0/search.html?q=lv_obj_remove_flag) @@ -810,6 +867,7 @@ remove_state|int||[lv_obj_remove_state](https://docs.lvgl.io/9.0/search.html?q=l remove_style|lv.style, int||[lv_obj_remove_style](https://docs.lvgl.io/9.0/search.html?q=lv_obj_remove_style) remove_style_all|||[lv_obj_remove_style_all](https://docs.lvgl.io/9.0/search.html?q=lv_obj_remove_style_all) replace_style|lv.style, lv.style, int|bool|[lv_obj_replace_style](https://docs.lvgl.io/9.0/search.html?q=lv_obj_replace_style) +reset_transform|||[lv_obj_reset_transform](https://docs.lvgl.io/9.0/search.html?q=lv_obj_reset_transform) scroll_by|int, int, int||[lv_obj_scroll_by](https://docs.lvgl.io/9.0/search.html?q=lv_obj_scroll_by) scroll_by_bounded|int, int, int||[lv_obj_scroll_by_bounded](https://docs.lvgl.io/9.0/search.html?q=lv_obj_scroll_by_bounded) scroll_to|int, int, int||[lv_obj_scroll_to](https://docs.lvgl.io/9.0/search.html?q=lv_obj_scroll_to) @@ -824,6 +882,7 @@ set_align|int||[lv_obj_set_align](https://docs.lvgl.io/9.0/search.html?q=lv_obj_ set_content_height|int||[lv_obj_set_content_height](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_content_height) set_content_width|int||[lv_obj_set_content_width](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_content_width) set_ext_click_area|int||[lv_obj_set_ext_click_area](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_ext_click_area) +set_flag|int, bool||[lv_obj_set_flag](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_flag) set_flex_align|int, int, int||[lv_obj_set_flex_align](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_flex_align) set_flex_flow|int||[lv_obj_set_flex_flow](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_flex_flow) set_flex_grow|int||[lv_obj_set_flex_grow](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_flex_grow) @@ -929,11 +988,15 @@ set_style_pad_column|int, int||[lv_obj_set_style_pad_column](https://docs.lvgl.i set_style_pad_gap|int, int||[lv_obj_set_style_pad_gap](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_pad_gap) set_style_pad_hor|int, int||[lv_obj_set_style_pad_hor](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_pad_hor) set_style_pad_left|int, int||[lv_obj_set_style_pad_left](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_pad_left) +set_style_pad_radial|int, int||[lv_obj_set_style_pad_radial](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_pad_radial) set_style_pad_right|int, int||[lv_obj_set_style_pad_right](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_pad_right) set_style_pad_row|int, int||[lv_obj_set_style_pad_row](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_pad_row) set_style_pad_top|int, int||[lv_obj_set_style_pad_top](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_pad_top) set_style_pad_ver|int, int||[lv_obj_set_style_pad_ver](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_pad_ver) +set_style_radial_offset|int, int||[lv_obj_set_style_radial_offset](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_radial_offset) set_style_radius|int, int||[lv_obj_set_style_radius](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_radius) +set_style_recolor|lv.color, int||[lv_obj_set_style_recolor](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_recolor) +set_style_recolor_opa|int, int||[lv_obj_set_style_recolor_opa](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_recolor_opa) set_style_rotary_sensitivity|int, int||[lv_obj_set_style_rotary_sensitivity](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_rotary_sensitivity) set_style_shadow_color|lv.color, int||[lv_obj_set_style_shadow_color](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_shadow_color) set_style_shadow_offset_x|int, int||[lv_obj_set_style_shadow_offset_x](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_shadow_offset_x) @@ -951,6 +1014,9 @@ set_style_text_font|lv.font, int||[lv_obj_set_style_text_font](https://docs.lvgl set_style_text_letter_space|int, int||[lv_obj_set_style_text_letter_space](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_text_letter_space) set_style_text_line_space|int, int||[lv_obj_set_style_text_line_space](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_text_line_space) set_style_text_opa|int, int||[lv_obj_set_style_text_opa](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_text_opa) +set_style_text_outline_stroke_color|lv.color, int||[lv_obj_set_style_text_outline_stroke_color](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_text_outline_stroke_color) +set_style_text_outline_stroke_opa|int, int||[lv_obj_set_style_text_outline_stroke_opa](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_text_outline_stroke_opa) +set_style_text_outline_stroke_width|int, int||[lv_obj_set_style_text_outline_stroke_width](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_text_outline_stroke_width) set_style_transform_angle|int, int||[lv_obj_set_style_transform_rotation](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_transform_rotation) set_style_transform_height|int, int||[lv_obj_set_style_transform_height](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_transform_height) set_style_transform_pivot_x|int, int||[lv_obj_set_style_transform_pivot_x](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_transform_pivot_x) @@ -964,6 +1030,7 @@ set_style_transform_skew_y|int, int||[lv_obj_set_style_transform_skew_y](https:/ set_style_transform_width|int, int||[lv_obj_set_style_transform_width](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_transform_width) set_style_transform_zoom|int, int||[lv_obj_set_style_transform_scale](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_transform_scale) set_style_transition|lv.style_transition_dsc, int||[lv_obj_set_style_transition](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_transition) +set_style_translate_radial|int, int||[lv_obj_set_style_translate_radial](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_translate_radial) set_style_translate_x|int, int||[lv_obj_set_style_translate_x](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_translate_x) set_style_translate_y|int, int||[lv_obj_set_style_translate_y](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_translate_y) set_style_width|int, int||[lv_obj_set_style_width](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_style_width) @@ -973,12 +1040,13 @@ set_user_data|\||[lv_obj_set_user_data](https://docs.lvgl.io/9.0/search.ht set_width|int||[lv_obj_set_width](https://docs.lvgl.io/9.0/search.html?q=lv_obj_set_width) 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) +stop_scroll_anim|||[lv_obj_stop_scroll_anim](https://docs.lvgl.io/9.0/search.html?q=lv_obj_stop_scroll_anim) 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) +style_apply_recolor|int, int|int|[lv_obj_style_apply_recolor](https://docs.lvgl.io/9.0/search.html?q=lv_obj_style_apply_recolor) 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) -update_flag|int, bool||[lv_obj_update_flag](https://docs.lvgl.io/9.0/search.html?q=lv_obj_update_flag) update_layout|||[lv_obj_update_layout](https://docs.lvgl.io/9.0/search.html?q=lv_obj_update_layout) update_snap|int||[lv_obj_update_snap](https://docs.lvgl.io/9.0/search.html?q=lv_obj_update_snap) @@ -1127,6 +1195,10 @@ get_scale||int|[lv_image_get_scale](https://docs.lvgl.io/9.0/search.html?q=lv_im get_scale_x||int|[lv_image_get_scale_x](https://docs.lvgl.io/9.0/search.html?q=lv_image_get_scale_x) get_scale_y||int|[lv_image_get_scale_y](https://docs.lvgl.io/9.0/search.html?q=lv_image_get_scale_y) get_src||comptr|[lv_image_get_src](https://docs.lvgl.io/9.0/search.html?q=lv_image_get_src) +get_src_height||int|[lv_image_get_src_height](https://docs.lvgl.io/9.0/search.html?q=lv_image_get_src_height) +get_src_width||int|[lv_image_get_src_width](https://docs.lvgl.io/9.0/search.html?q=lv_image_get_src_width) +get_transformed_height||int|[lv_image_get_transformed_height](https://docs.lvgl.io/9.0/search.html?q=lv_image_get_transformed_height) +get_transformed_width||int|[lv_image_get_transformed_width](https://docs.lvgl.io/9.0/search.html?q=lv_image_get_transformed_width) get_zoom||int|[lv_image_get_scale](https://docs.lvgl.io/9.0/search.html?q=lv_image_get_scale) set_angle|int||[lv_image_set_rotation](https://docs.lvgl.io/9.0/search.html?q=lv_image_set_rotation) set_antialias|bool||[lv_image_set_antialias](https://docs.lvgl.io/9.0/search.html?q=lv_image_set_antialias) @@ -1153,12 +1225,14 @@ cut_text|int, int||[lv_label_cut_text](https://docs.lvgl.io/9.0/search.html?q=lv get_letter_on|comptr, bool|int|[lv_label_get_letter_on](https://docs.lvgl.io/9.0/search.html?q=lv_label_get_letter_on) get_letter_pos|int, comptr||[lv_label_get_letter_pos](https://docs.lvgl.io/9.0/search.html?q=lv_label_get_letter_pos) get_long_mode||int|[lv_label_get_long_mode](https://docs.lvgl.io/9.0/search.html?q=lv_label_get_long_mode) +get_recolor||bool|[lv_label_get_recolor](https://docs.lvgl.io/9.0/search.html?q=lv_label_get_recolor) get_text||string|[lv_label_get_text](https://docs.lvgl.io/9.0/search.html?q=lv_label_get_text) get_text_selection_end||int|[lv_label_get_text_selection_end](https://docs.lvgl.io/9.0/search.html?q=lv_label_get_text_selection_end) get_text_selection_start||int|[lv_label_get_text_selection_start](https://docs.lvgl.io/9.0/search.html?q=lv_label_get_text_selection_start) ins_text|int, string||[lv_label_ins_text](https://docs.lvgl.io/9.0/search.html?q=lv_label_ins_text) is_char_under_pos|comptr|bool|[lv_label_is_char_under_pos](https://docs.lvgl.io/9.0/search.html?q=lv_label_is_char_under_pos) set_long_mode|int||[lv_label_set_long_mode](https://docs.lvgl.io/9.0/search.html?q=lv_label_set_long_mode) +set_recolor|bool||[lv_label_set_recolor](https://docs.lvgl.io/9.0/search.html?q=lv_label_set_recolor) set_text|string||[lv_label_set_text](https://docs.lvgl.io/9.0/search.html?q=lv_label_set_text) set_text_fmt|string, [\]||[lv_label_set_text_fmt](https://docs.lvgl.io/9.0/search.html?q=lv_label_set_text_fmt) set_text_selection_end|int||[lv_label_set_text_selection_end](https://docs.lvgl.io/9.0/search.html?q=lv_label_set_text_selection_end) @@ -1189,6 +1263,7 @@ get_selected||int|[lv_roller_get_selected](https://docs.lvgl.io/9.0/search.html? get_selected_str|comptr, int||[lv_roller_get_selected_str](https://docs.lvgl.io/9.0/search.html?q=lv_roller_get_selected_str) set_options|string, int||[lv_roller_set_options](https://docs.lvgl.io/9.0/search.html?q=lv_roller_set_options) set_selected|int, int||[lv_roller_set_selected](https://docs.lvgl.io/9.0/search.html?q=lv_roller_set_selected) +set_selected_str|string, int|bool|[lv_roller_set_selected_str](https://docs.lvgl.io/9.0/search.html?q=lv_roller_set_selected_str) set_visible_row_cnt|int||[lv_roller_set_visible_row_count](https://docs.lvgl.io/9.0/search.html?q=lv_roller_set_visible_row_count) set_visible_row_count|int||[lv_roller_set_visible_row_count](https://docs.lvgl.io/9.0/search.html?q=lv_roller_set_visible_row_count) @@ -1200,24 +1275,27 @@ get_left_value||int|[lv_slider_get_left_value](https://docs.lvgl.io/9.0/search.h get_max_value||int|[lv_slider_get_max_value](https://docs.lvgl.io/9.0/search.html?q=lv_slider_get_max_value) get_min_value||int|[lv_slider_get_min_value](https://docs.lvgl.io/9.0/search.html?q=lv_slider_get_min_value) get_mode||int|[lv_slider_get_mode](https://docs.lvgl.io/9.0/search.html?q=lv_slider_get_mode) +get_orientation||int|[lv_slider_get_orientation](https://docs.lvgl.io/9.0/search.html?q=lv_slider_get_orientation) get_value||int|[lv_slider_get_value](https://docs.lvgl.io/9.0/search.html?q=lv_slider_get_value) is_dragged||bool|[lv_slider_is_dragged](https://docs.lvgl.io/9.0/search.html?q=lv_slider_is_dragged) is_symmetrical||bool|[lv_slider_is_symmetrical](https://docs.lvgl.io/9.0/search.html?q=lv_slider_is_symmetrical) -set_left_value|int, int||[lv_slider_set_left_value](https://docs.lvgl.io/9.0/search.html?q=lv_slider_set_left_value) set_mode|int||[lv_slider_set_mode](https://docs.lvgl.io/9.0/search.html?q=lv_slider_set_mode) +set_orientation|int||[lv_slider_set_orientation](https://docs.lvgl.io/9.0/search.html?q=lv_slider_set_orientation) set_range|int, int||[lv_slider_set_range](https://docs.lvgl.io/9.0/search.html?q=lv_slider_set_range) +set_start_value|int, int||[lv_slider_set_start_value](https://docs.lvgl.io/9.0/search.html?q=lv_slider_set_start_value) set_value|int, int||[lv_slider_set_value](https://docs.lvgl.io/9.0/search.html?q=lv_slider_set_value) ### widget `lv.switch` Method|Arguments|Return type|LVGL equivalent :---|:---|:---|:--- +get_orientation||int|[lv_switch_get_orientation](https://docs.lvgl.io/9.0/search.html?q=lv_switch_get_orientation) +set_orientation|int||[lv_switch_set_orientation](https://docs.lvgl.io/9.0/search.html?q=lv_switch_set_orientation) ### widget `lv.table` Method|Arguments|Return type|LVGL equivalent :---|:---|:---|:--- -add_cell_ctrl|int, int, int||[lv_table_add_cell_ctrl](https://docs.lvgl.io/9.0/search.html?q=lv_table_add_cell_ctrl) clear_cell_ctrl|int, int, int||[lv_table_clear_cell_ctrl](https://docs.lvgl.io/9.0/search.html?q=lv_table_clear_cell_ctrl) get_cell_user_data|int, int|comptr|[lv_table_get_cell_user_data](https://docs.lvgl.io/9.0/search.html?q=lv_table_get_cell_user_data) get_cell_value|int, int|string|[lv_table_get_cell_value](https://docs.lvgl.io/9.0/search.html?q=lv_table_get_cell_value) @@ -1229,6 +1307,7 @@ get_row_cnt||int|[lv_table_get_row_count](https://docs.lvgl.io/9.0/search.html?q get_row_count||int|[lv_table_get_row_count](https://docs.lvgl.io/9.0/search.html?q=lv_table_get_row_count) get_selected_cell|lv.int_arr, lv.int_arr||[lv_table_get_selected_cell](https://docs.lvgl.io/9.0/search.html?q=lv_table_get_selected_cell) has_cell_ctrl|int, int, int|bool|[lv_table_has_cell_ctrl](https://docs.lvgl.io/9.0/search.html?q=lv_table_has_cell_ctrl) +set_cell_ctrl|int, int, int||[lv_table_set_cell_ctrl](https://docs.lvgl.io/9.0/search.html?q=lv_table_set_cell_ctrl) set_cell_user_data|int, int, \||[lv_table_set_cell_user_data](https://docs.lvgl.io/9.0/search.html?q=lv_table_set_cell_user_data) set_cell_value|int, int, string||[lv_table_set_cell_value](https://docs.lvgl.io/9.0/search.html?q=lv_table_set_cell_value) set_cell_value_fmt|int, int, string, [\]||[lv_table_set_cell_value_fmt](https://docs.lvgl.io/9.0/search.html?q=lv_table_set_cell_value_fmt) @@ -1285,6 +1364,7 @@ text_is_selected||bool|[lv_textarea_text_is_selected](https://docs.lvgl.io/9.0/s Method|Arguments|Return type|LVGL equivalent :---|:---|:---|:--- +add_span||lv.span|[lv_spangroup_add_span](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_add_span) delete_span|lv.span||[lv_spangroup_delete_span](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_delete_span) get_align||int|[lv_spangroup_get_align](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_get_align) get_child|int|lv.span|[lv_spangroup_get_child](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_get_child) @@ -1295,22 +1375,28 @@ get_max_line_height||int|[lv_spangroup_get_max_line_height](https://docs.lvgl.io get_max_lines||int|[lv_spangroup_get_max_lines](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_get_max_lines) get_mode||int|[lv_spangroup_get_mode](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_get_mode) get_overflow||int|[lv_spangroup_get_overflow](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_get_overflow) +get_span_by_point|comptr|lv.span|[lv_spangroup_get_span_by_point](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_get_span_by_point) +get_span_coords|lv.span|lv.span_coords|[lv_spangroup_get_span_coords](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_get_span_coords) get_span_count||int|[lv_spangroup_get_span_count](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_get_span_count) -new_span||lv.span|[lv_spangroup_new_span](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_new_span) -refr_mode|||[lv_spangroup_refr_mode](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_refr_mode) +refresh|||[lv_spangroup_refresh](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_refresh) set_align|int||[lv_spangroup_set_align](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_set_align) set_indent|int||[lv_spangroup_set_indent](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_set_indent) set_max_lines|int||[lv_spangroup_set_max_lines](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_set_max_lines) set_mode|int||[lv_spangroup_set_mode](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_set_mode) set_overflow|int||[lv_spangroup_set_overflow](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_set_overflow) +set_span_style|lv.span, lv.style||[lv_spangroup_set_span_style](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_set_span_style) +set_span_text|lv.span, string||[lv_spangroup_set_span_text](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_set_span_text) +set_span_text_static|lv.span, string||[lv_spangroup_set_span_text_static](https://docs.lvgl.io/9.0/search.html?q=lv_spangroup_set_span_text_static) ### widget `lv.span` Method|Arguments|Return type|LVGL equivalent :---|:---|:---|:--- get_style||lv.style|[lv_span_get_style](https://docs.lvgl.io/9.0/search.html?q=lv_span_get_style) +get_text||string|[lv_span_get_text](https://docs.lvgl.io/9.0/search.html?q=lv_span_get_text) set_text|string||[lv_span_set_text](https://docs.lvgl.io/9.0/search.html?q=lv_span_set_text) set_text_static|string||[lv_span_set_text_static](https://docs.lvgl.io/9.0/search.html?q=lv_span_set_text_static) +set_text_static|string||[lv_span_set_text_static](https://docs.lvgl.io/9.0/search.html?q=lv_span_set_text_static) ### widget `lv.scale_section` @@ -1324,12 +1410,15 @@ set_style|int, lv.style||[lv_scale_section_set_style](https://docs.lvgl.io/9.0/s Method|Arguments|Return type|LVGL equivalent :---|:---|:---|:--- add_section||lv.scale_section|[lv_scale_add_section](https://docs.lvgl.io/9.0/search.html?q=lv_scale_add_section) +get_angle||int|[lv_scale_get_rotation](https://docs.lvgl.io/9.0/search.html?q=lv_scale_get_rotation) get_angle_range||int|[lv_scale_get_angle_range](https://docs.lvgl.io/9.0/search.html?q=lv_scale_get_angle_range) get_label_show||bool|[lv_scale_get_label_show](https://docs.lvgl.io/9.0/search.html?q=lv_scale_get_label_show) get_major_tick_every||int|[lv_scale_get_major_tick_every](https://docs.lvgl.io/9.0/search.html?q=lv_scale_get_major_tick_every) get_mode||int|[lv_scale_get_mode](https://docs.lvgl.io/9.0/search.html?q=lv_scale_get_mode) get_range_max_value||int|[lv_scale_get_range_max_value](https://docs.lvgl.io/9.0/search.html?q=lv_scale_get_range_max_value) get_range_min_value||int|[lv_scale_get_range_min_value](https://docs.lvgl.io/9.0/search.html?q=lv_scale_get_range_min_value) +get_rotation||int|[lv_scale_get_rotation](https://docs.lvgl.io/9.0/search.html?q=lv_scale_get_rotation) +get_rotation||int|[lv_scale_get_rotation](https://docs.lvgl.io/9.0/search.html?q=lv_scale_get_rotation) 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) @@ -1343,6 +1432,10 @@ set_post_draw|bool||[lv_scale_set_post_draw](https://docs.lvgl.io/9.0/search.htm set_range|int, int||[lv_scale_set_range](https://docs.lvgl.io/9.0/search.html?q=lv_scale_set_range) set_rotation|int||[lv_scale_set_rotation](https://docs.lvgl.io/9.0/search.html?q=lv_scale_set_rotation) set_rotation|int||[lv_scale_set_rotation](https://docs.lvgl.io/9.0/search.html?q=lv_scale_set_rotation) +set_section_range|lv.scale_section, int, int||[lv_scale_set_section_range](https://docs.lvgl.io/9.0/search.html?q=lv_scale_set_section_range) +set_section_style_indicator|lv.scale_section, lv.style||[lv_scale_set_section_style_indicator](https://docs.lvgl.io/9.0/search.html?q=lv_scale_set_section_style_indicator) +set_section_style_items|lv.scale_section, lv.style||[lv_scale_set_section_style_items](https://docs.lvgl.io/9.0/search.html?q=lv_scale_set_section_style_items) +set_section_style_main|lv.scale_section, lv.style||[lv_scale_set_section_style_main](https://docs.lvgl.io/9.0/search.html?q=lv_scale_set_section_style_main) set_text_src|lv.str_arr||[lv_scale_set_text_src](https://docs.lvgl.io/9.0/search.html?q=lv_scale_set_text_src) set_total_tick_count|int||[lv_scale_set_total_tick_count](https://docs.lvgl.io/9.0/search.html?q=lv_scale_set_total_tick_count) @@ -1359,28 +1452,32 @@ get_point_pos_by_id|lv.chart_series, int, comptr||[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_series_x_array|lv.chart_series|lv.int_arr|[lv_chart_get_series_x_array](https://docs.lvgl.io/9.0/search.html?q=lv_chart_get_series_x_array) +get_series_y_array|lv.chart_series|lv.int_arr|[lv_chart_get_series_y_array](https://docs.lvgl.io/9.0/search.html?q=lv_chart_get_series_y_array) 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) get_x_start_point|lv.chart_series|int|[lv_chart_get_x_start_point](https://docs.lvgl.io/9.0/search.html?q=lv_chart_get_x_start_point) -get_y_array|lv.chart_series|lv.int_arr|[lv_chart_get_y_array](https://docs.lvgl.io/9.0/search.html?q=lv_chart_get_y_array) hide_series|lv.chart_series, bool||[lv_chart_hide_series](https://docs.lvgl.io/9.0/search.html?q=lv_chart_hide_series) refresh|||[lv_chart_refresh](https://docs.lvgl.io/9.0/search.html?q=lv_chart_refresh) remove_series|lv.chart_series||[lv_chart_remove_series](https://docs.lvgl.io/9.0/search.html?q=lv_chart_remove_series) -set_all_value|lv.chart_series, int||[lv_chart_set_all_value](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_all_value) +set_all_values|lv.chart_series, int||[lv_chart_set_all_values](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_all_values) +set_axis_range|int, int, int||[lv_chart_set_axis_range](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_axis_range) set_cursor_point|lv.chart_cursor, lv.chart_series, int||[lv_chart_set_cursor_point](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_cursor_point) set_cursor_pos|lv.chart_cursor, comptr||[lv_chart_set_cursor_pos](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_cursor_pos) +set_cursor_pos_x|lv.chart_cursor, int||[lv_chart_set_cursor_pos_x](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_cursor_pos_x) +set_cursor_pos_y|lv.chart_cursor, int||[lv_chart_set_cursor_pos_y](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_cursor_pos_y) set_div_line_count|int, int||[lv_chart_set_div_line_count](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_div_line_count) -set_ext_x_array|lv.chart_series, lv.int_arr||[lv_chart_set_ext_x_array](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_ext_x_array) -set_ext_y_array|lv.chart_series, lv.int_arr||[lv_chart_set_ext_y_array](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_ext_y_array) set_next_value|lv.chart_series, int||[lv_chart_set_next_value](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_next_value) set_next_value2|lv.chart_series, int, int||[lv_chart_set_next_value2](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_next_value2) set_point_count|int||[lv_chart_set_point_count](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_point_count) -set_range|int, int, int||[lv_chart_set_range](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_range) set_series_color|lv.chart_series, lv.color||[lv_chart_set_series_color](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_series_color) +set_series_ext_x_array|lv.chart_series, lv.int_arr||[lv_chart_set_series_ext_x_array](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_series_ext_x_array) +set_series_ext_y_array|lv.chart_series, lv.int_arr||[lv_chart_set_series_ext_y_array](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_series_ext_y_array) +set_series_value_by_id|lv.chart_series, int, int||[lv_chart_set_series_value_by_id](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_series_value_by_id) +set_series_value_by_id2|lv.chart_series, int, int, int||[lv_chart_set_series_value_by_id2](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_series_value_by_id2) +set_series_values|lv.chart_series, lv.int_arr, int||[lv_chart_set_series_values](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_series_values) +set_series_values2|lv.chart_series, lv.int_arr, lv.int_arr, int||[lv_chart_set_series_values2](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_series_values2) set_type|int||[lv_chart_set_type](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_type) set_update_mode|int||[lv_chart_set_update_mode](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_update_mode) -set_value_by_id|lv.chart_series, int, int||[lv_chart_set_value_by_id](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_value_by_id) -set_value_by_id2|lv.chart_series, int, int, int||[lv_chart_set_value_by_id2](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_value_by_id2) set_x_start_point|lv.chart_series, int||[lv_chart_set_x_start_point](https://docs.lvgl.io/9.0/search.html?q=lv_chart_set_x_start_point) ### widget `lv.imagebutton` @@ -1501,25 +1598,36 @@ set_button_text|lv.obj, string||[lv_list_set_button_text](https://docs.lvgl.io/9 Method|Arguments|Return type|LVGL equivalent :---|:---|:---|:--- +del||bool|[lv_animimg_delete](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_delete) +delete||bool|[lv_animimg_delete](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_delete) get_anim||lv.anim|[lv_animimg_get_anim](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_get_anim) get_duration||int|[lv_animimg_get_duration](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_get_duration) get_repeat_count||int|[lv_animimg_get_repeat_count](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_get_repeat_count) get_src_count||int|[lv_animimg_get_src_count](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_get_src_count) +remove||bool|[lv_animimg_delete](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_delete) +set_completed_cb|comptr||[lv_animimg_set_completed_cb](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_set_completed_cb) set_duration|int||[lv_animimg_set_duration](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_set_duration) +set_ready_cb|comptr||[lv_animimg_set_completed_cb](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_set_completed_cb) set_repeat_count|int||[lv_animimg_set_repeat_count](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_set_repeat_count) +set_reverse_delay|int||[lv_animimg_set_reverse_delay](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_set_reverse_delay) +set_reverse_duration|int||[lv_animimg_set_reverse_duration](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_set_reverse_duration) set_src|comptr, int||[lv_animimg_set_src](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_set_src) +set_src_reverse|comptr, int||[lv_animimg_set_src_reverse](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_set_src_reverse) +set_start_cb|comptr||[lv_animimg_set_start_cb](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_set_start_cb) start|||[lv_animimg_start](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_start) ### widget `lv.calendar` Method|Arguments|Return type|LVGL equivalent :---|:---|:---|:--- +add_header_arrow||lv.obj|[lv_calendar_add_header_arrow](https://docs.lvgl.io/9.0/search.html?q=lv_calendar_add_header_arrow) +add_header_dropdown||lv.obj|[lv_calendar_add_header_dropdown](https://docs.lvgl.io/9.0/search.html?q=lv_calendar_add_header_dropdown) 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_month_shown|int, int||[lv_calendar_set_month_shown](https://docs.lvgl.io/9.0/search.html?q=lv_calendar_set_month_shown) 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) ### widget `lv.menu_page` 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 f12c88315..afa7c212f 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 @@ -13,6 +13,7 @@ extern "C" { /* `lv_style` methods */ const be_ntv_func_def_t lv_style_func[] = { + { "copy", { (const void*) &lv_style_copy, "", "(lv.style)(lv.style)" } }, { "is_const", { (const void*) &lv_style_is_const, "b", "(lv.style)" } }, { "is_empty", { (const void*) &lv_style_is_empty, "b", "(lv.style)" } }, { "remove_prop", { (const void*) &lv_style_remove_prop, "b", "(lv.style)i" } }, @@ -86,10 +87,13 @@ const be_ntv_func_def_t lv_style_func[] = { { "set_line_opa", { (const void*) &lv_style_set_line_opa, "", "(lv.style)i" } }, { "set_line_rounded", { (const void*) &lv_style_set_line_rounded, "", "(lv.style)b" } }, { "set_line_width", { (const void*) &lv_style_set_line_width, "", "(lv.style)i" } }, + { "set_margin_all", { (const void*) &lv_style_set_margin_all, "", "(lv.style)i" } }, { "set_margin_bottom", { (const void*) &lv_style_set_margin_bottom, "", "(lv.style)i" } }, + { "set_margin_hor", { (const void*) &lv_style_set_margin_hor, "", "(lv.style)i" } }, { "set_margin_left", { (const void*) &lv_style_set_margin_left, "", "(lv.style)i" } }, { "set_margin_right", { (const void*) &lv_style_set_margin_right, "", "(lv.style)i" } }, { "set_margin_top", { (const void*) &lv_style_set_margin_top, "", "(lv.style)i" } }, + { "set_margin_ver", { (const void*) &lv_style_set_margin_ver, "", "(lv.style)i" } }, { "set_max_height", { (const void*) &lv_style_set_max_height, "", "(lv.style)i" } }, { "set_max_width", { (const void*) &lv_style_set_max_width, "", "(lv.style)i" } }, { "set_min_height", { (const void*) &lv_style_set_min_height, "", "(lv.style)i" } }, @@ -106,12 +110,16 @@ const be_ntv_func_def_t lv_style_func[] = { { "set_pad_gap", { (const void*) &lv_style_set_pad_gap, "", "(lv.style)i" } }, { "set_pad_hor", { (const void*) &lv_style_set_pad_hor, "", "(lv.style)i" } }, { "set_pad_left", { (const void*) &lv_style_set_pad_left, "", "(lv.style)i" } }, + { "set_pad_radial", { (const void*) &lv_style_set_pad_radial, "", "(lv.style)i" } }, { "set_pad_right", { (const void*) &lv_style_set_pad_right, "", "(lv.style)i" } }, { "set_pad_row", { (const void*) &lv_style_set_pad_row, "", "(lv.style)i" } }, { "set_pad_top", { (const void*) &lv_style_set_pad_top, "", "(lv.style)i" } }, { "set_pad_ver", { (const void*) &lv_style_set_pad_ver, "", "(lv.style)i" } }, { "set_prop", { (const void*) &lv_style_set_prop, "", "(lv.style)ii" } }, + { "set_radial_offset", { (const void*) &lv_style_set_radial_offset, "", "(lv.style)i" } }, { "set_radius", { (const void*) &lv_style_set_radius, "", "(lv.style)i" } }, + { "set_recolor", { (const void*) &lv_style_set_recolor, "", "(lv.style)(lv.color)" } }, + { "set_recolor_opa", { (const void*) &lv_style_set_recolor_opa, "", "(lv.style)i" } }, { "set_rotary_sensitivity", { (const void*) &lv_style_set_rotary_sensitivity, "", "(lv.style)i" } }, { "set_shadow_color", { (const void*) &lv_style_set_shadow_color, "", "(lv.style)(lv.color)" } }, { "set_shadow_offset_x", { (const void*) &lv_style_set_shadow_offset_x, "", "(lv.style)i" } }, @@ -129,6 +137,9 @@ const be_ntv_func_def_t lv_style_func[] = { { "set_text_letter_space", { (const void*) &lv_style_set_text_letter_space, "", "(lv.style)i" } }, { "set_text_line_space", { (const void*) &lv_style_set_text_line_space, "", "(lv.style)i" } }, { "set_text_opa", { (const void*) &lv_style_set_text_opa, "", "(lv.style)i" } }, + { "set_text_outline_stroke_color", { (const void*) &lv_style_set_text_outline_stroke_color, "", "(lv.style)(lv.color)" } }, + { "set_text_outline_stroke_opa", { (const void*) &lv_style_set_text_outline_stroke_opa, "", "(lv.style)i" } }, + { "set_text_outline_stroke_width", { (const void*) &lv_style_set_text_outline_stroke_width, "", "(lv.style)i" } }, { "set_transform_angle", { (const void*) &lv_style_set_transform_rotation, "", "(lv.style)i" } }, { "set_transform_height", { (const void*) &lv_style_set_transform_height, "", "(lv.style)i" } }, { "set_transform_pivot_x", { (const void*) &lv_style_set_transform_pivot_x, "", "(lv.style)i" } }, @@ -142,6 +153,7 @@ const be_ntv_func_def_t lv_style_func[] = { { "set_transform_width", { (const void*) &lv_style_set_transform_width, "", "(lv.style)i" } }, { "set_transform_zoom", { (const void*) &lv_style_set_transform_scale, "", "(lv.style)i" } }, { "set_transition", { (const void*) &lv_style_set_transition, "", "(lv.style)(lv.style_transition_dsc)" } }, + { "set_translate_radial", { (const void*) &lv_style_set_translate_radial, "", "(lv.style)i" } }, { "set_translate_x", { (const void*) &lv_style_set_translate_x, "", "(lv.style)i" } }, { "set_translate_y", { (const void*) &lv_style_set_translate_y, "", "(lv.style)i" } }, { "set_width", { (const void*) &lv_style_set_width, "", "(lv.style)i" } }, @@ -216,9 +228,9 @@ const be_ntv_func_def_t lv_obj_func[] = { { "dump_tree", { (const void*) &lv_obj_dump_tree, "", "(lv.obj)" } }, { "fade_in", { (const void*) &lv_obj_fade_in, "", "(lv.obj)ii" } }, { "fade_out", { (const void*) &lv_obj_fade_out, "", "(lv.obj)ii" } }, + { "find_by_id", { (const void*) &lv_obj_find_by_id, "lv.obj", "(lv.obj)." } }, { "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)" } }, @@ -348,11 +360,16 @@ const be_ntv_func_def_t lv_obj_func[] = { { "get_style_pad_bottom", { (const void*) &lv_obj_get_style_pad_bottom, "i", "(lv.obj)i" } }, { "get_style_pad_column", { (const void*) &lv_obj_get_style_pad_column, "i", "(lv.obj)i" } }, { "get_style_pad_left", { (const void*) &lv_obj_get_style_pad_left, "i", "(lv.obj)i" } }, + { "get_style_pad_radial", { (const void*) &lv_obj_get_style_pad_radial, "i", "(lv.obj)i" } }, { "get_style_pad_right", { (const void*) &lv_obj_get_style_pad_right, "i", "(lv.obj)i" } }, { "get_style_pad_row", { (const void*) &lv_obj_get_style_pad_row, "i", "(lv.obj)i" } }, { "get_style_pad_top", { (const void*) &lv_obj_get_style_pad_top, "i", "(lv.obj)i" } }, { "get_style_prop", { (const void*) &lv_obj_get_style_prop, "i", "(lv.obj)ii" } }, + { "get_style_radial_offset", { (const void*) &lv_obj_get_style_radial_offset, "i", "(lv.obj)i" } }, { "get_style_radius", { (const void*) &lv_obj_get_style_radius, "i", "(lv.obj)i" } }, + { "get_style_recolor", { (const void*) &lv_obj_get_style_recolor, "lv.color", "(lv.obj)i" } }, + { "get_style_recolor_opa", { (const void*) &lv_obj_get_style_recolor_opa, "i", "(lv.obj)i" } }, + { "get_style_recolor_recursive", { (const void*) &lv_obj_get_style_recolor_recursive, "i", "(lv.obj)i" } }, { "get_style_rotary_sensitivity", { (const void*) &lv_obj_get_style_rotary_sensitivity, "i", "(lv.obj)i" } }, { "get_style_shadow_color", { (const void*) &lv_obj_get_style_shadow_color, "lv.color", "(lv.obj)i" } }, { "get_style_shadow_color_filtered", { (const void*) &lv_obj_get_style_shadow_color_filtered, "lv.color", "(lv.obj)i" } }, @@ -375,6 +392,10 @@ const be_ntv_func_def_t lv_obj_func[] = { { "get_style_text_letter_space", { (const void*) &lv_obj_get_style_text_letter_space, "i", "(lv.obj)i" } }, { "get_style_text_line_space", { (const void*) &lv_obj_get_style_text_line_space, "i", "(lv.obj)i" } }, { "get_style_text_opa", { (const void*) &lv_obj_get_style_text_opa, "i", "(lv.obj)i" } }, + { "get_style_text_outline_stroke_color", { (const void*) &lv_obj_get_style_text_outline_stroke_color, "lv.color", "(lv.obj)i" } }, + { "get_style_text_outline_stroke_color_filtered", { (const void*) &lv_obj_get_style_text_outline_stroke_color_filtered, "lv.color", "(lv.obj)i" } }, + { "get_style_text_outline_stroke_opa", { (const void*) &lv_obj_get_style_text_outline_stroke_opa, "i", "(lv.obj)i" } }, + { "get_style_text_outline_stroke_width", { (const void*) &lv_obj_get_style_text_outline_stroke_width, "i", "(lv.obj)i" } }, { "get_style_transform_angle", { (const void*) &lv_obj_get_style_transform_rotation, "i", "(lv.obj)i" } }, { "get_style_transform_height", { (const void*) &lv_obj_get_style_transform_height, "i", "(lv.obj)i" } }, { "get_style_transform_pivot_x", { (const void*) &lv_obj_get_style_transform_pivot_x, "i", "(lv.obj)i" } }, @@ -388,6 +409,7 @@ const be_ntv_func_def_t lv_obj_func[] = { { "get_style_transform_skew_y", { (const void*) &lv_obj_get_style_transform_skew_y, "i", "(lv.obj)i" } }, { "get_style_transform_width", { (const void*) &lv_obj_get_style_transform_width, "i", "(lv.obj)i" } }, { "get_style_transition", { (const void*) &lv_obj_get_style_transition, "lv.style_transition_dsc", "(lv.obj)i" } }, + { "get_style_translate_radial", { (const void*) &lv_obj_get_style_translate_radial, "i", "(lv.obj)i" } }, { "get_style_translate_x", { (const void*) &lv_obj_get_style_translate_x, "i", "(lv.obj)i" } }, { "get_style_translate_y", { (const void*) &lv_obj_get_style_translate_y, "i", "(lv.obj)i" } }, { "get_style_width", { (const void*) &lv_obj_get_style_width, "i", "(lv.obj)i" } }, @@ -435,7 +457,7 @@ const be_ntv_func_def_t lv_obj_func[] = { { "refresh_style", { (const void*) &lv_obj_refresh_style, "", "(lv.obj)ii" } }, { "remove", { (const void*) &lv_obj_delete, "", "(lv.obj)" } }, { "remove_event", { (const void*) &lv_obj_remove_event, "b", "(lv.obj)i" } }, - { "remove_event_cb", { (const void*) &lv_obj_remove_event_cb, "b", "(lv.obj)." } }, + { "remove_event_cb", { (const void*) &lv_obj_remove_event_cb, "i", "(lv.obj)." } }, { "remove_event_cb_with_user_data", { (const void*) &lv_obj_remove_event_cb_with_user_data, "i", "(lv.obj).." } }, { "remove_event_dsc", { (const void*) &lv_obj_remove_event_dsc, "b", "(lv.obj)(lv.event_dsc)" } }, { "remove_flag", { (const void*) &lv_obj_remove_flag, "", "(lv.obj)i" } }, @@ -444,6 +466,7 @@ const be_ntv_func_def_t lv_obj_func[] = { { "remove_style", { (const void*) &lv_obj_remove_style, "", "(lv.obj)(lv.style)i" } }, { "remove_style_all", { (const void*) &lv_obj_remove_style_all, "", "(lv.obj)" } }, { "replace_style", { (const void*) &lv_obj_replace_style, "b", "(lv.obj)(lv.style)(lv.style)i" } }, + { "reset_transform", { (const void*) &lv_obj_reset_transform, "", "(lv.obj)" } }, { "scroll_by", { (const void*) &lv_obj_scroll_by, "", "(lv.obj)iii" } }, { "scroll_by_bounded", { (const void*) &lv_obj_scroll_by_bounded, "", "(lv.obj)iii" } }, { "scroll_to", { (const void*) &lv_obj_scroll_to, "", "(lv.obj)iii" } }, @@ -457,6 +480,7 @@ const be_ntv_func_def_t lv_obj_func[] = { { "set_content_height", { (const void*) &lv_obj_set_content_height, "", "(lv.obj)i" } }, { "set_content_width", { (const void*) &lv_obj_set_content_width, "", "(lv.obj)i" } }, { "set_ext_click_area", { (const void*) &lv_obj_set_ext_click_area, "", "(lv.obj)i" } }, + { "set_flag", { (const void*) &lv_obj_set_flag, "", "(lv.obj)ib" } }, { "set_flex_align", { (const void*) &lv_obj_set_flex_align, "", "(lv.obj)iii" } }, { "set_flex_flow", { (const void*) &lv_obj_set_flex_flow, "", "(lv.obj)i" } }, { "set_flex_grow", { (const void*) &lv_obj_set_flex_grow, "", "(lv.obj)i" } }, @@ -562,11 +586,15 @@ const be_ntv_func_def_t lv_obj_func[] = { { "set_style_pad_gap", { (const void*) &lv_obj_set_style_pad_gap, "", "(lv.obj)ii" } }, { "set_style_pad_hor", { (const void*) &lv_obj_set_style_pad_hor, "", "(lv.obj)ii" } }, { "set_style_pad_left", { (const void*) &lv_obj_set_style_pad_left, "", "(lv.obj)ii" } }, + { "set_style_pad_radial", { (const void*) &lv_obj_set_style_pad_radial, "", "(lv.obj)ii" } }, { "set_style_pad_right", { (const void*) &lv_obj_set_style_pad_right, "", "(lv.obj)ii" } }, { "set_style_pad_row", { (const void*) &lv_obj_set_style_pad_row, "", "(lv.obj)ii" } }, { "set_style_pad_top", { (const void*) &lv_obj_set_style_pad_top, "", "(lv.obj)ii" } }, { "set_style_pad_ver", { (const void*) &lv_obj_set_style_pad_ver, "", "(lv.obj)ii" } }, + { "set_style_radial_offset", { (const void*) &lv_obj_set_style_radial_offset, "", "(lv.obj)ii" } }, { "set_style_radius", { (const void*) &lv_obj_set_style_radius, "", "(lv.obj)ii" } }, + { "set_style_recolor", { (const void*) &lv_obj_set_style_recolor, "", "(lv.obj)(lv.color)i" } }, + { "set_style_recolor_opa", { (const void*) &lv_obj_set_style_recolor_opa, "", "(lv.obj)ii" } }, { "set_style_rotary_sensitivity", { (const void*) &lv_obj_set_style_rotary_sensitivity, "", "(lv.obj)ii" } }, { "set_style_shadow_color", { (const void*) &lv_obj_set_style_shadow_color, "", "(lv.obj)(lv.color)i" } }, { "set_style_shadow_offset_x", { (const void*) &lv_obj_set_style_shadow_offset_x, "", "(lv.obj)ii" } }, @@ -584,6 +612,9 @@ const be_ntv_func_def_t lv_obj_func[] = { { "set_style_text_letter_space", { (const void*) &lv_obj_set_style_text_letter_space, "", "(lv.obj)ii" } }, { "set_style_text_line_space", { (const void*) &lv_obj_set_style_text_line_space, "", "(lv.obj)ii" } }, { "set_style_text_opa", { (const void*) &lv_obj_set_style_text_opa, "", "(lv.obj)ii" } }, + { "set_style_text_outline_stroke_color", { (const void*) &lv_obj_set_style_text_outline_stroke_color, "", "(lv.obj)(lv.color)i" } }, + { "set_style_text_outline_stroke_opa", { (const void*) &lv_obj_set_style_text_outline_stroke_opa, "", "(lv.obj)ii" } }, + { "set_style_text_outline_stroke_width", { (const void*) &lv_obj_set_style_text_outline_stroke_width, "", "(lv.obj)ii" } }, { "set_style_transform_angle", { (const void*) &lv_obj_set_style_transform_rotation, "", "(lv.obj)ii" } }, { "set_style_transform_height", { (const void*) &lv_obj_set_style_transform_height, "", "(lv.obj)ii" } }, { "set_style_transform_pivot_x", { (const void*) &lv_obj_set_style_transform_pivot_x, "", "(lv.obj)ii" } }, @@ -597,6 +628,7 @@ const be_ntv_func_def_t lv_obj_func[] = { { "set_style_transform_width", { (const void*) &lv_obj_set_style_transform_width, "", "(lv.obj)ii" } }, { "set_style_transform_zoom", { (const void*) &lv_obj_set_style_transform_scale, "", "(lv.obj)ii" } }, { "set_style_transition", { (const void*) &lv_obj_set_style_transition, "", "(lv.obj)(lv.style_transition_dsc)i" } }, + { "set_style_translate_radial", { (const void*) &lv_obj_set_style_translate_radial, "", "(lv.obj)ii" } }, { "set_style_translate_x", { (const void*) &lv_obj_set_style_translate_x, "", "(lv.obj)ii" } }, { "set_style_translate_y", { (const void*) &lv_obj_set_style_translate_y, "", "(lv.obj)ii" } }, { "set_style_width", { (const void*) &lv_obj_set_style_width, "", "(lv.obj)ii" } }, @@ -606,12 +638,13 @@ const be_ntv_func_def_t lv_obj_func[] = { { "set_width", { (const void*) &lv_obj_set_width, "", "(lv.obj)i" } }, { "set_x", { (const void*) &lv_obj_set_x, "", "(lv.obj)i" } }, { "set_y", { (const void*) &lv_obj_set_y, "", "(lv.obj)i" } }, + { "stop_scroll_anim", { (const void*) &lv_obj_stop_scroll_anim, "", "(lv.obj)" } }, { "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" } }, + { "style_apply_recolor", { (const void*) &lv_obj_style_apply_recolor, "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" } }, - { "update_flag", { (const void*) &lv_obj_update_flag, "", "(lv.obj)ib" } }, { "update_layout", { (const void*) &lv_obj_update_layout, "", "(lv.obj)" } }, { "update_snap", { (const void*) &lv_obj_update_snap, "", "(lv.obj)i" } }, }; @@ -625,6 +658,7 @@ const be_ntv_func_def_t lv_event_func[] = { { "get_current_target_obj", { (const void*) &lv_event_get_current_target_obj, "lv.obj", "(lv.event)" } }, { "get_hit_test_info", { (const void*) &lv_event_get_hit_test_info, "c", "(lv.event)" } }, { "get_indev", { (const void*) &lv_event_get_indev, "lv.indev", "(lv.event)" } }, + { "get_invalidated_area", { (const void*) &lv_event_get_invalidated_area, "lv.area", "(lv.event)" } }, { "get_key", { (const void*) &lv_event_get_key, "i", "(lv.event)" } }, { "get_layer", { (const void*) &lv_event_get_layer, "lv.layer", "(lv.event)" } }, { "get_old_size", { (const void*) &lv_event_get_old_size, "lv.area", "(lv.event)" } }, @@ -654,18 +688,23 @@ const be_ntv_func_def_t lv_display_func[] = { { "get_antialiasing", { (const void*) &lv_display_get_antialiasing, "b", "(lv.display)" } }, { "get_color_format", { (const void*) &lv_display_get_color_format, "i", "(lv.display)" } }, { "get_dpi", { (const void*) &lv_display_get_dpi, "i", "(lv.display)" } }, + { "get_draw_buf_size", { (const void*) &lv_display_get_draw_buf_size, "i", "(lv.display)" } }, { "get_driver_data", { (const void*) &lv_display_get_driver_data, "c", "(lv.display)" } }, { "get_event_count", { (const void*) &lv_display_get_event_count, "i", "(lv.display)" } }, { "get_event_dsc", { (const void*) &lv_display_get_event_dsc, "lv.event_dsc", "(lv.display)i" } }, { "get_hor_res", { (const void*) &lv_display_get_horizontal_resolution, "i", "(lv.display)" } }, { "get_horizontal_resolution", { (const void*) &lv_display_get_horizontal_resolution, "i", "(lv.display)" } }, { "get_inactive_time", { (const void*) &lv_display_get_inactive_time, "i", "(lv.display)" } }, + { "get_invalidated_draw_buf_size", { (const void*) &lv_display_get_invalidated_draw_buf_size, "i", "(lv.display)ii" } }, { "get_layer_bottom", { (const void*) &lv_display_get_layer_bottom, "lv.obj", "(lv.display)" } }, { "get_layer_sys", { (const void*) &lv_display_get_layer_sys, "lv.obj", "(lv.display)" } }, { "get_layer_top", { (const void*) &lv_display_get_layer_top, "lv.obj", "(lv.display)" } }, + { "get_matrix_rotation", { (const void*) &lv_display_get_matrix_rotation, "b", "(lv.display)" } }, { "get_next", { (const void*) &lv_display_get_next, "lv.display", "(lv.display)" } }, { "get_offset_x", { (const void*) &lv_display_get_offset_x, "i", "(lv.display)" } }, { "get_offset_y", { (const void*) &lv_display_get_offset_y, "i", "(lv.display)" } }, + { "get_original_horizontal_resolution", { (const void*) &lv_display_get_original_horizontal_resolution, "i", "(lv.display)" } }, + { "get_original_vertical_resolution", { (const void*) &lv_display_get_original_vertical_resolution, "i", "(lv.display)" } }, { "get_physical_hor_res", { (const void*) &lv_display_get_physical_horizontal_resolution, "i", "(lv.display)" } }, { "get_physical_horizontal_resolution", { (const void*) &lv_display_get_physical_horizontal_resolution, "i", "(lv.display)" } }, { "get_physical_ver_res", { (const void*) &lv_display_get_physical_vertical_resolution, "i", "(lv.display)" } }, @@ -677,31 +716,38 @@ const be_ntv_func_def_t lv_display_func[] = { { "get_screen_active", { (const void*) &lv_display_get_screen_active, "lv.obj", "(lv.display)" } }, { "get_screen_prev", { (const void*) &lv_display_get_screen_prev, "lv.obj", "(lv.display)" } }, { "get_theme", { (const void*) &lv_display_get_theme, "lv.theme", "(lv.display)" } }, + { "get_tile_cnt", { (const void*) &lv_display_get_tile_cnt, "i", "(lv.display)" } }, { "get_user_data", { (const void*) &lv_display_get_user_data, "c", "(lv.display)" } }, { "get_ver_res", { (const void*) &lv_display_get_vertical_resolution, "i", "(lv.display)" } }, { "get_vertical_resolution", { (const void*) &lv_display_get_vertical_resolution, "i", "(lv.display)" } }, { "is_double_buffered", { (const void*) &lv_display_is_double_buffered, "b", "(lv.display)" } }, { "is_invalidation_enabled", { (const void*) &lv_display_is_invalidation_enabled, "b", "(lv.display)" } }, + { "register_vsync_event", { (const void*) &lv_display_register_vsync_event, "b", "(lv.display)^lv_event_cb^." } }, { "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." } }, + { "send_vsync_event", { (const void*) &lv_display_send_vsync_event, "i", "(lv.display)." } }, { "set_angle", { (const void*) &lv_display_set_rotation, "", "(lv.display)i" } }, { "set_antialiasing", { (const void*) &lv_display_set_antialiasing, "", "(lv.display)b" } }, { "set_buffers", { (const void*) &lv_display_set_buffers, "", "(lv.display)..ii" } }, + { "set_buffers_with_stride", { (const void*) &lv_display_set_buffers_with_stride, "", "(lv.display)..iii" } }, { "set_color_format", { (const void*) &lv_display_set_color_format, "", "(lv.display)i" } }, { "set_default", { (const void*) &lv_display_set_default, "", "(lv.display)" } }, { "set_dpi", { (const void*) &lv_display_set_dpi, "", "(lv.display)i" } }, { "set_driver_data", { (const void*) &lv_display_set_driver_data, "", "(lv.display)." } }, + { "set_matrix_rotation", { (const void*) &lv_display_set_matrix_rotation, "", "(lv.display)b" } }, { "set_offset", { (const void*) &lv_display_set_offset, "", "(lv.display)ii" } }, { "set_physical_resolution", { (const void*) &lv_display_set_physical_resolution, "", "(lv.display)ii" } }, { "set_render_mode", { (const void*) &lv_display_set_render_mode, "", "(lv.display)i" } }, { "set_resolution", { (const void*) &lv_display_set_resolution, "", "(lv.display)ii" } }, { "set_rotation", { (const void*) &lv_display_set_rotation, "", "(lv.display)i" } }, { "set_theme", { (const void*) &lv_display_set_theme, "", "(lv.display)(lv.theme)" } }, + { "set_tile_cnt", { (const void*) &lv_display_set_tile_cnt, "", "(lv.display)i" } }, { "set_user_data", { (const void*) &lv_display_set_user_data, "", "(lv.display)." } }, { "trig_activity", { (const void*) &lv_display_trigger_activity, "", "(lv.display)" } }, { "trigger_activity", { (const void*) &lv_display_trigger_activity, "", "(lv.display)" } }, + { "unregister_vsync_event", { (const void*) &lv_display_unregister_vsync_event, "b", "(lv.display)^lv_event_cb^." } }, }; /* `lv_indev` methods */ @@ -710,6 +756,7 @@ const be_ntv_func_def_t lv_indev_func[] = { { "del", { (const void*) &lv_indev_delete, "", "(lv.indev)" } }, { "delete", { (const void*) &lv_indev_delete, "", "(lv.indev)" } }, { "enable", { (const void*) &lv_indev_enable, "", "(lv.indev)b" } }, + { "get_cursor", { (const void*) &lv_indev_get_cursor, "lv.obj", "(lv.indev)" } }, { "get_disp", { (const void*) &lv_indev_get_display, "lv.display", "(lv.indev)" } }, { "get_display", { (const void*) &lv_indev_get_display, "lv.display", "(lv.indev)" } }, { "get_driver_data", { (const void*) &lv_indev_get_driver_data, "c", "(lv.indev)" } }, @@ -725,6 +772,7 @@ const be_ntv_func_def_t lv_indev_func[] = { { "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)" } }, + { "get_short_click_streak", { (const void*) &lv_indev_get_short_click_streak, "i", "(lv.indev)" } }, { "get_state", { (const void*) &lv_indev_get_state, "i", "(lv.indev)" } }, { "get_type", { (const void*) &lv_indev_get_type, "i", "(lv.indev)" } }, { "get_user_data", { (const void*) &lv_indev_get_user_data, "c", "(lv.indev)" } }, @@ -743,6 +791,7 @@ 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_repeat_time", { (const void*) &lv_indev_set_long_press_repeat_time, "", "(lv.indev)i" } }, { "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" } }, @@ -773,6 +822,10 @@ const be_ntv_func_def_t lv_anim_func[] = { { "get_time", { (const void*) &lv_anim_get_time, "i", "(lv.anim)" } }, { "get_user_data", { (const void*) &lv_anim_get_user_data, "c", "(lv.anim)" } }, { "init", { (const void*) &lv_anim_init, "", "(lv.anim)" } }, + { "is_paused", { (const void*) &lv_anim_is_paused, "b", "(lv.anim)" } }, + { "pause", { (const void*) &lv_anim_pause, "", "(lv.anim)" } }, + { "pause_for", { (const void*) &lv_anim_pause_for, "", "(lv.anim)i" } }, + { "resume", { (const void*) &lv_anim_resume, "", "(lv.anim)" } }, { "set_bezier3_param", { (const void*) &lv_anim_set_bezier3_param, "", "(lv.anim)iiii" } }, { "set_completed_cb", { (const void*) &lv_anim_set_completed_cb, "", "(lv.anim)c" } }, { "set_custom_exec_cb", { (const void*) &lv_anim_set_custom_exec_cb, "", "(lv.anim)c" } }, @@ -782,14 +835,13 @@ const be_ntv_func_def_t lv_anim_func[] = { { "set_exec_cb", { (const void*) &lv_anim_set_exec_cb, "", "(lv.anim)c" } }, { "set_get_value_cb", { (const void*) &lv_anim_set_get_value_cb, "", "(lv.anim)c" } }, { "set_path_cb", { (const void*) &lv_anim_set_path_cb, "", "(lv.anim)c" } }, - { "set_playback_delay", { (const void*) &lv_anim_set_playback_delay, "", "(lv.anim)i" } }, - { "set_playback_duration", { (const void*) &lv_anim_set_playback_duration, "", "(lv.anim)i" } }, - { "set_playback_time", { (const void*) &lv_anim_set_playback_time, "", "(lv.anim)i" } }, { "set_ready_cb", { (const void*) &lv_anim_set_completed_cb, "", "(lv.anim)c" } }, { "set_repeat_count", { (const void*) &lv_anim_set_repeat_count, "", "(lv.anim)i" } }, { "set_repeat_delay", { (const void*) &lv_anim_set_repeat_delay, "", "(lv.anim)i" } }, + { "set_reverse_delay", { (const void*) &lv_anim_set_reverse_delay, "", "(lv.anim)i" } }, + { "set_reverse_duration", { (const void*) &lv_anim_set_reverse_duration, "", "(lv.anim)i" } }, + { "set_reverse_time", { (const void*) &lv_anim_set_reverse_time, "", "(lv.anim)i" } }, { "set_start_cb", { (const void*) &lv_anim_set_start_cb, "", "(lv.anim)c" } }, - { "set_time", { (const void*) &lv_anim_set_time, "", "(lv.anim)i" } }, { "set_user_data", { (const void*) &lv_anim_set_user_data, "", "(lv.anim)." } }, { "set_values", { (const void*) &lv_anim_set_values, "", "(lv.anim)ii" } }, { "set_var", { (const void*) &lv_anim_set_var, "", "(lv.anim)." } }, @@ -818,13 +870,22 @@ const be_ntv_func_def_t lv_timer_func[] = { /* `lv_animimg` methods */ #ifdef BE_LV_WIDGET_ANIMIMG const be_ntv_func_def_t lv_animimg_func[] = { + { "del", { (const void*) &lv_animimg_delete, "b", "(lv.obj)" } }, + { "delete", { (const void*) &lv_animimg_delete, "b", "(lv.obj)" } }, { "get_anim", { (const void*) &lv_animimg_get_anim, "lv.anim", "(lv.obj)" } }, { "get_duration", { (const void*) &lv_animimg_get_duration, "i", "(lv.obj)" } }, { "get_repeat_count", { (const void*) &lv_animimg_get_repeat_count, "i", "(lv.obj)" } }, { "get_src_count", { (const void*) &lv_animimg_get_src_count, "i", "(lv.obj)" } }, + { "remove", { (const void*) &lv_animimg_delete, "b", "(lv.obj)" } }, + { "set_completed_cb", { (const void*) &lv_animimg_set_completed_cb, "", "(lv.obj)c" } }, { "set_duration", { (const void*) &lv_animimg_set_duration, "", "(lv.obj)i" } }, + { "set_ready_cb", { (const void*) &lv_animimg_set_completed_cb, "", "(lv.obj)c" } }, { "set_repeat_count", { (const void*) &lv_animimg_set_repeat_count, "", "(lv.obj)i" } }, + { "set_reverse_delay", { (const void*) &lv_animimg_set_reverse_delay, "", "(lv.obj)i" } }, + { "set_reverse_duration", { (const void*) &lv_animimg_set_reverse_duration, "", "(lv.obj)i" } }, { "set_src", { (const void*) &lv_animimg_set_src, "", "(lv.obj)ci" } }, + { "set_src_reverse", { (const void*) &lv_animimg_set_src_reverse, "", "(lv.obj)ci" } }, + { "set_start_cb", { (const void*) &lv_animimg_set_start_cb, "", "(lv.obj)c" } }, { "start", { (const void*) &lv_animimg_start, "", "(lv.obj)" } }, }; #endif // BE_LV_WIDGET_ANIMIMG @@ -909,12 +970,14 @@ const be_ntv_func_def_t lv_buttonmatrix_func[] = { /* `lv_calendar` methods */ #ifdef BE_LV_WIDGET_CALENDAR const be_ntv_func_def_t lv_calendar_func[] = { + { "add_header_arrow", { (const void*) &lv_calendar_add_header_arrow, "lv.obj", "(lv.obj)" } }, + { "add_header_dropdown", { (const void*) &lv_calendar_add_header_dropdown, "lv.obj", "(lv.obj)" } }, { "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_month_shown", { (const void*) &lv_calendar_set_month_shown, "", "(lv.obj)ii" } }, { "set_today_date", { (const void*) &lv_calendar_set_today_date, "", "(lv.obj)iii" } }, }; #endif // BE_LV_WIDGET_CALENDAR @@ -946,28 +1009,32 @@ const be_ntv_func_def_t lv_chart_func[] = { { "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_series_x_array", { (const void*) &lv_chart_get_series_x_array, "lv.int_arr", "(lv.obj)(lv.chart_series)" } }, + { "get_series_y_array", { (const void*) &lv_chart_get_series_y_array, "lv.int_arr", "(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)" } }, { "get_x_start_point", { (const void*) &lv_chart_get_x_start_point, "i", "(lv.obj)(lv.chart_series)" } }, - { "get_y_array", { (const void*) &lv_chart_get_y_array, "lv.int_arr", "(lv.obj)(lv.chart_series)" } }, { "hide_series", { (const void*) &lv_chart_hide_series, "", "(lv.obj)(lv.chart_series)b" } }, { "refresh", { (const void*) &lv_chart_refresh, "", "(lv.obj)" } }, { "remove_series", { (const void*) &lv_chart_remove_series, "", "(lv.obj)(lv.chart_series)" } }, - { "set_all_value", { (const void*) &lv_chart_set_all_value, "", "(lv.obj)(lv.chart_series)i" } }, + { "set_all_values", { (const void*) &lv_chart_set_all_values, "", "(lv.obj)(lv.chart_series)i" } }, + { "set_axis_range", { (const void*) &lv_chart_set_axis_range, "", "(lv.obj)iii" } }, { "set_cursor_point", { (const void*) &lv_chart_set_cursor_point, "", "(lv.obj)(lv.chart_cursor)(lv.chart_series)i" } }, { "set_cursor_pos", { (const void*) &lv_chart_set_cursor_pos, "", "(lv.obj)(lv.chart_cursor)c" } }, + { "set_cursor_pos_x", { (const void*) &lv_chart_set_cursor_pos_x, "", "(lv.obj)(lv.chart_cursor)i" } }, + { "set_cursor_pos_y", { (const void*) &lv_chart_set_cursor_pos_y, "", "(lv.obj)(lv.chart_cursor)i" } }, { "set_div_line_count", { (const void*) &lv_chart_set_div_line_count, "", "(lv.obj)ii" } }, - { "set_ext_x_array", { (const void*) &lv_chart_set_ext_x_array, "", "(lv.obj)(lv.chart_series)(lv.int_arr)" } }, - { "set_ext_y_array", { (const void*) &lv_chart_set_ext_y_array, "", "(lv.obj)(lv.chart_series)(lv.int_arr)" } }, { "set_next_value", { (const void*) &lv_chart_set_next_value, "", "(lv.obj)(lv.chart_series)i" } }, { "set_next_value2", { (const void*) &lv_chart_set_next_value2, "", "(lv.obj)(lv.chart_series)ii" } }, { "set_point_count", { (const void*) &lv_chart_set_point_count, "", "(lv.obj)i" } }, - { "set_range", { (const void*) &lv_chart_set_range, "", "(lv.obj)iii" } }, { "set_series_color", { (const void*) &lv_chart_set_series_color, "", "(lv.obj)(lv.chart_series)(lv.color)" } }, + { "set_series_ext_x_array", { (const void*) &lv_chart_set_series_ext_x_array, "", "(lv.obj)(lv.chart_series)(lv.int_arr)" } }, + { "set_series_ext_y_array", { (const void*) &lv_chart_set_series_ext_y_array, "", "(lv.obj)(lv.chart_series)(lv.int_arr)" } }, + { "set_series_value_by_id", { (const void*) &lv_chart_set_series_value_by_id, "", "(lv.obj)(lv.chart_series)ii" } }, + { "set_series_value_by_id2", { (const void*) &lv_chart_set_series_value_by_id2, "", "(lv.obj)(lv.chart_series)iii" } }, + { "set_series_values", { (const void*) &lv_chart_set_series_values, "", "(lv.obj)(lv.chart_series)(lv.int_arr)i" } }, + { "set_series_values2", { (const void*) &lv_chart_set_series_values2, "", "(lv.obj)(lv.chart_series)(lv.int_arr)(lv.int_arr)i" } }, { "set_type", { (const void*) &lv_chart_set_type, "", "(lv.obj)i" } }, { "set_update_mode", { (const void*) &lv_chart_set_update_mode, "", "(lv.obj)i" } }, - { "set_value_by_id", { (const void*) &lv_chart_set_value_by_id, "", "(lv.obj)(lv.chart_series)ii" } }, - { "set_value_by_id2", { (const void*) &lv_chart_set_value_by_id2, "", "(lv.obj)(lv.chart_series)iii" } }, { "set_x_start_point", { (const void*) &lv_chart_set_x_start_point, "", "(lv.obj)(lv.chart_series)i" } }, }; #endif // BE_LV_WIDGET_CHART @@ -1026,6 +1093,10 @@ const be_ntv_func_def_t lv_image_func[] = { { "get_scale_x", { (const void*) &lv_image_get_scale_x, "i", "(lv.obj)" } }, { "get_scale_y", { (const void*) &lv_image_get_scale_y, "i", "(lv.obj)" } }, { "get_src", { (const void*) &lv_image_get_src, "c", "(lv.obj)" } }, + { "get_src_height", { (const void*) &lv_image_get_src_height, "i", "(lv.obj)" } }, + { "get_src_width", { (const void*) &lv_image_get_src_width, "i", "(lv.obj)" } }, + { "get_transformed_height", { (const void*) &lv_image_get_transformed_height, "i", "(lv.obj)" } }, + { "get_transformed_width", { (const void*) &lv_image_get_transformed_width, "i", "(lv.obj)" } }, { "get_zoom", { (const void*) &lv_image_get_scale, "i", "(lv.obj)" } }, { "set_angle", { (const void*) &lv_image_set_rotation, "", "(lv.obj)i" } }, { "set_antialias", { (const void*) &lv_image_set_antialias, "", "(lv.obj)b" } }, @@ -1076,12 +1147,14 @@ const be_ntv_func_def_t lv_label_func[] = { { "get_letter_on", { (const void*) &lv_label_get_letter_on, "i", "(lv.obj)cb" } }, { "get_letter_pos", { (const void*) &lv_label_get_letter_pos, "", "(lv.obj)ic" } }, { "get_long_mode", { (const void*) &lv_label_get_long_mode, "i", "(lv.obj)" } }, + { "get_recolor", { (const void*) &lv_label_get_recolor, "b", "(lv.obj)" } }, { "get_text", { (const void*) &lv_label_get_text, "s", "(lv.obj)" } }, { "get_text_selection_end", { (const void*) &lv_label_get_text_selection_end, "i", "(lv.obj)" } }, { "get_text_selection_start", { (const void*) &lv_label_get_text_selection_start, "i", "(lv.obj)" } }, { "ins_text", { (const void*) &lv_label_ins_text, "", "(lv.obj)is" } }, { "is_char_under_pos", { (const void*) &lv_label_is_char_under_pos, "b", "(lv.obj)c" } }, { "set_long_mode", { (const void*) &lv_label_set_long_mode, "", "(lv.obj)i" } }, + { "set_recolor", { (const void*) &lv_label_set_recolor, "", "(lv.obj)b" } }, { "set_text", { (const void*) &lv_label_set_text, "", "(lv.obj)s" } }, { "set_text_fmt", { (const void*) &lv_label_set_text_fmt, "", "(lv.obj)s[......]" } }, { "set_text_selection_end", { (const void*) &lv_label_set_text_selection_end, "", "(lv.obj)i" } }, @@ -1201,6 +1274,7 @@ const be_ntv_func_def_t lv_roller_func[] = { { "get_selected_str", { (const void*) &lv_roller_get_selected_str, "", "(lv.obj)ci" } }, { "set_options", { (const void*) &lv_roller_set_options, "", "(lv.obj)si" } }, { "set_selected", { (const void*) &lv_roller_set_selected, "", "(lv.obj)ii" } }, + { "set_selected_str", { (const void*) &lv_roller_set_selected_str, "b", "(lv.obj)si" } }, { "set_visible_row_cnt", { (const void*) &lv_roller_set_visible_row_count, "", "(lv.obj)i" } }, { "set_visible_row_count", { (const void*) &lv_roller_set_visible_row_count, "", "(lv.obj)i" } }, }; @@ -1210,12 +1284,14 @@ const be_ntv_func_def_t lv_roller_func[] = { #ifdef BE_LV_WIDGET_SCALE const be_ntv_func_def_t lv_scale_func[] = { { "add_section", { (const void*) &lv_scale_add_section, "lv.scale_section", "(lv.obj)" } }, + { "get_angle", { (const void*) &lv_scale_get_rotation, "i", "(lv.obj)" } }, { "get_angle_range", { (const void*) &lv_scale_get_angle_range, "i", "(lv.obj)" } }, { "get_label_show", { (const void*) &lv_scale_get_label_show, "b", "(lv.obj)" } }, { "get_major_tick_every", { (const void*) &lv_scale_get_major_tick_every, "i", "(lv.obj)" } }, { "get_mode", { (const void*) &lv_scale_get_mode, "i", "(lv.obj)" } }, { "get_range_max_value", { (const void*) &lv_scale_get_range_max_value, "i", "(lv.obj)" } }, { "get_range_min_value", { (const void*) &lv_scale_get_range_min_value, "i", "(lv.obj)" } }, + { "get_rotation", { (const void*) &lv_scale_get_rotation, "i", "(lv.obj)" } }, { "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" } }, @@ -1228,6 +1304,10 @@ const be_ntv_func_def_t lv_scale_func[] = { { "set_post_draw", { (const void*) &lv_scale_set_post_draw, "", "(lv.obj)b" } }, { "set_range", { (const void*) &lv_scale_set_range, "", "(lv.obj)ii" } }, { "set_rotation", { (const void*) &lv_scale_set_rotation, "", "(lv.obj)i" } }, + { "set_section_range", { (const void*) &lv_scale_set_section_range, "", "(lv.obj)(lv.scale_section)ii" } }, + { "set_section_style_indicator", { (const void*) &lv_scale_set_section_style_indicator, "", "(lv.obj)(lv.scale_section)(lv.style)" } }, + { "set_section_style_items", { (const void*) &lv_scale_set_section_style_items, "", "(lv.obj)(lv.scale_section)(lv.style)" } }, + { "set_section_style_main", { (const void*) &lv_scale_set_section_style_main, "", "(lv.obj)(lv.scale_section)(lv.style)" } }, { "set_text_src", { (const void*) &lv_scale_set_text_src, "", "(lv.obj)(lv.str_arr)" } }, { "set_total_tick_count", { (const void*) &lv_scale_set_total_tick_count, "", "(lv.obj)i" } }, }; @@ -1248,12 +1328,14 @@ const be_ntv_func_def_t lv_slider_func[] = { { "get_max_value", { (const void*) &lv_slider_get_max_value, "i", "(lv.obj)" } }, { "get_min_value", { (const void*) &lv_slider_get_min_value, "i", "(lv.obj)" } }, { "get_mode", { (const void*) &lv_slider_get_mode, "i", "(lv.obj)" } }, + { "get_orientation", { (const void*) &lv_slider_get_orientation, "i", "(lv.obj)" } }, { "get_value", { (const void*) &lv_slider_get_value, "i", "(lv.obj)" } }, { "is_dragged", { (const void*) &lv_slider_is_dragged, "b", "(lv.obj)" } }, { "is_symmetrical", { (const void*) &lv_slider_is_symmetrical, "b", "(lv.obj)" } }, - { "set_left_value", { (const void*) &lv_slider_set_left_value, "", "(lv.obj)ii" } }, { "set_mode", { (const void*) &lv_slider_set_mode, "", "(lv.obj)i" } }, + { "set_orientation", { (const void*) &lv_slider_set_orientation, "", "(lv.obj)i" } }, { "set_range", { (const void*) &lv_slider_set_range, "", "(lv.obj)ii" } }, + { "set_start_value", { (const void*) &lv_slider_set_start_value, "", "(lv.obj)ii" } }, { "set_value", { (const void*) &lv_slider_set_value, "", "(lv.obj)ii" } }, }; #endif // BE_LV_WIDGET_SLIDER @@ -1262,6 +1344,7 @@ const be_ntv_func_def_t lv_slider_func[] = { #ifdef BE_LV_WIDGET_SPAN const be_ntv_func_def_t lv_span_func[] = { { "get_style", { (const void*) &lv_span_get_style, "lv.style", "(lv.span)" } }, + { "get_text", { (const void*) &lv_span_get_text, "s", "(lv.span)" } }, { "set_text", { (const void*) &lv_span_set_text, "", "(lv.span)s" } }, { "set_text_static", { (const void*) &lv_span_set_text_static, "", "(lv.span)s" } }, }; @@ -1270,6 +1353,7 @@ const be_ntv_func_def_t lv_span_func[] = { /* `lv_spangroup` methods */ #ifdef BE_LV_WIDGET_SPANGROUP const be_ntv_func_def_t lv_spangroup_func[] = { + { "add_span", { (const void*) &lv_spangroup_add_span, "lv.span", "(lv.obj)" } }, { "delete_span", { (const void*) &lv_spangroup_delete_span, "", "(lv.obj)(lv.span)" } }, { "get_align", { (const void*) &lv_spangroup_get_align, "i", "(lv.obj)" } }, { "get_child", { (const void*) &lv_spangroup_get_child, "lv.span", "(lv.obj)i" } }, @@ -1280,14 +1364,18 @@ const be_ntv_func_def_t lv_spangroup_func[] = { { "get_max_lines", { (const void*) &lv_spangroup_get_max_lines, "i", "(lv.obj)" } }, { "get_mode", { (const void*) &lv_spangroup_get_mode, "i", "(lv.obj)" } }, { "get_overflow", { (const void*) &lv_spangroup_get_overflow, "i", "(lv.obj)" } }, + { "get_span_by_point", { (const void*) &lv_spangroup_get_span_by_point, "lv.span", "(lv.obj)c" } }, + { "get_span_coords", { (const void*) &lv_spangroup_get_span_coords, "lv.span_coords", "(lv.obj)(lv.span)" } }, { "get_span_count", { (const void*) &lv_spangroup_get_span_count, "i", "(lv.obj)" } }, - { "new_span", { (const void*) &lv_spangroup_new_span, "lv.span", "(lv.obj)" } }, - { "refr_mode", { (const void*) &lv_spangroup_refr_mode, "", "(lv.obj)" } }, + { "refresh", { (const void*) &lv_spangroup_refresh, "", "(lv.obj)" } }, { "set_align", { (const void*) &lv_spangroup_set_align, "", "(lv.obj)i" } }, { "set_indent", { (const void*) &lv_spangroup_set_indent, "", "(lv.obj)i" } }, { "set_max_lines", { (const void*) &lv_spangroup_set_max_lines, "", "(lv.obj)i" } }, { "set_mode", { (const void*) &lv_spangroup_set_mode, "", "(lv.obj)i" } }, { "set_overflow", { (const void*) &lv_spangroup_set_overflow, "", "(lv.obj)i" } }, + { "set_span_style", { (const void*) &lv_spangroup_set_span_style, "", "(lv.obj)(lv.span)(lv.style)" } }, + { "set_span_text", { (const void*) &lv_spangroup_set_span_text, "", "(lv.obj)(lv.span)s" } }, + { "set_span_text_static", { (const void*) &lv_spangroup_set_span_text_static, "", "(lv.obj)(lv.span)s" } }, }; #endif // BE_LV_WIDGET_SPANGROUP @@ -1321,13 +1409,14 @@ const be_ntv_func_def_t lv_spinner_func[] = { /* `lv_switch` methods */ #ifdef BE_LV_WIDGET_SWITCH const be_ntv_func_def_t lv_switch_func[] = { + { "get_orientation", { (const void*) &lv_switch_get_orientation, "i", "(lv.obj)" } }, + { "set_orientation", { (const void*) &lv_switch_set_orientation, "", "(lv.obj)i" } }, }; #endif // BE_LV_WIDGET_SWITCH /* `lv_table` methods */ #ifdef BE_LV_WIDGET_TABLE const be_ntv_func_def_t lv_table_func[] = { - { "add_cell_ctrl", { (const void*) &lv_table_add_cell_ctrl, "", "(lv.obj)iii" } }, { "clear_cell_ctrl", { (const void*) &lv_table_clear_cell_ctrl, "", "(lv.obj)iii" } }, { "get_cell_user_data", { (const void*) &lv_table_get_cell_user_data, "c", "(lv.obj)ii" } }, { "get_cell_value", { (const void*) &lv_table_get_cell_value, "s", "(lv.obj)ii" } }, @@ -1339,6 +1428,7 @@ const be_ntv_func_def_t lv_table_func[] = { { "get_row_count", { (const void*) &lv_table_get_row_count, "i", "(lv.obj)" } }, { "get_selected_cell", { (const void*) &lv_table_get_selected_cell, "", "(lv.obj)(lv.int_arr)(lv.int_arr)" } }, { "has_cell_ctrl", { (const void*) &lv_table_has_cell_ctrl, "b", "(lv.obj)iii" } }, + { "set_cell_ctrl", { (const void*) &lv_table_set_cell_ctrl, "", "(lv.obj)iii" } }, { "set_cell_user_data", { (const void*) &lv_table_set_cell_user_data, "", "(lv.obj)ii." } }, { "set_cell_value", { (const void*) &lv_table_set_cell_value, "", "(lv.obj)iis" } }, { "set_cell_value_fmt", { (const void*) &lv_table_set_cell_value_fmt, "", "(lv.obj)iis[......]" } }, @@ -1663,12 +1753,6 @@ const size_t lv_classes_size = sizeof(lv_classes) / sizeof(lv_classes[0]); /* `lv_calendar` methods */ #ifdef BE_LV_WIDGET_CALENDAR int be_ntv_lv_calendar_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_calendar_create, "+_p", "(lv.obj)"); } -#endif // BE_LV_WIDGET_CALENDAR -#ifdef BE_LV_WIDGET_CALENDAR - int be_ntv_lv_calendar_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_calendar_header_arrow_create, "+_p", "(lv.obj)"); } -#endif // BE_LV_WIDGET_CALENDAR -#ifdef BE_LV_WIDGET_CALENDAR - int be_ntv_lv_calendar_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_calendar_header_dropdown_create, "+_p", "(lv.obj)"); } #endif // BE_LV_WIDGET_CALENDAR /* `lv_canvas` methods */ #ifdef BE_LV_WIDGET_CANVAS 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 de171d45e..c59e115a3 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 @@ -37,6 +37,7 @@ const be_ntv_func_def_t lv_func[] = { { "anim_get", { (const void*) &lv_anim_get, "lv.anim", ".c" } }, { "anim_get_timer", { (const void*) &lv_anim_get_timer, "lv.timer", "" } }, { "anim_refr_now", { (const void*) &lv_anim_refr_now, "", "" } }, + { "anim_resolve_speed", { (const void*) &lv_anim_resolve_speed, "i", "iii" } }, { "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" } }, @@ -72,7 +73,10 @@ const be_ntv_func_def_t lv_func[] = { { "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" } }, + { "color_mix32_premultiplied", { (const void*) &lv_color_mix32_premultiplied, "i", "ii" } }, + { "color_over32", { (const void*) &lv_color_over32, "i", "ii" } }, { "color_rgb_to_hsv", { (const void*) &lv_color_rgb_to_hsv, "i", "iii" } }, + { "color_swap_16", { (const void*) &lv_color_swap_16, "i", "i" } }, { "color_to_32", { (const void*) &lv_color_to_32, "i", "(lv.color)i" } }, { "color_to_hsv", { (const void*) &lv_color_to_hsv, "i", "(lv.color)" } }, { "color_to_int", { (const void*) &lv_color_to_int, "i", "(lv.color)" } }, @@ -81,6 +85,7 @@ const be_ntv_func_def_t lv_func[] = { { "color_white", { (const void*) &lv_color_white, "lv.color", "" } }, { "display_create", { (const void*) &lv_display_create, "lv.display", "ii" } }, { "display_get_default", { (const void*) &lv_display_get_default, "lv.display", "" } }, + { "display_refr_timer", { (const void*) &lv_display_refr_timer, "", "(lv.timer)" } }, { "dpx", { (const void*) &lv_dpx, "i", "i" } }, { "draw_arc", { (const void*) &lv_draw_arc, "", "(lv.layer)(lv.draw_arc_dsc)" } }, { "draw_arc_dsc_init", { (const void*) &lv_draw_arc_dsc_init, "", "(lv.draw_arc_dsc)" } }, @@ -99,17 +104,24 @@ const be_ntv_func_def_t lv_func[] = { { "draw_layer_alloc_buf", { (const void*) &lv_draw_layer_alloc_buf, "c", "(lv.layer)" } }, { "draw_layer_create", { (const void*) &lv_draw_layer_create, "lv.layer", "(lv.layer)i(lv.area)" } }, { "draw_layer_go_to_xy", { (const void*) &lv_draw_layer_go_to_xy, "c", "(lv.layer)ii" } }, + { "draw_layer_init", { (const void*) &lv_draw_layer_init, "", "(lv.layer)(lv.layer)i(lv.area)" } }, + { "draw_letter", { (const void*) &lv_draw_letter, "", "(lv.layer)(lv.draw_letter_dsc)c" } }, + { "draw_letter_dsc_init", { (const void*) &lv_draw_letter_dsc_init, "", "(lv.draw_letter_dsc)" } }, { "draw_line", { (const void*) &lv_draw_line, "", "(lv.layer)(lv.draw_line_dsc)" } }, { "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_code_get_name", { (const void*) &lv_event_code_get_name, "s", "i" } }, { "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", "" } }, { "flex_init", { (const void*) &lv_flex_init, "", "" } }, + { "font_get_default", { (const void*) &lv_font_get_default, "lv.font", "" } }, { "font_get_glyph_width", { (const void*) &lv_font_get_glyph_width, "i", "(lv.font)ii" } }, { "font_get_line_height", { (const void*) &lv_font_get_line_height, "i", "(lv.font)" } }, + { "font_has_static_bitmap", { (const void*) &lv_font_has_static_bitmap, "b", "(lv.font)" } }, + { "font_info_is_equal", { (const void*) &lv_font_info_is_equal, "b", "(lv.font_info)(lv.font_info)" } }, { "font_set_kerning", { (const void*) &lv_font_set_kerning, "", "(lv.font)i" } }, { "get_hor_res", { (const void*) &lv_get_hor_res, "i", "" } }, { "get_ts_calibration", { (const void*) &lv_get_ts_calibration, "lv.ts_calibration", "" } }, @@ -124,6 +136,8 @@ const be_ntv_func_def_t lv_func[] = { { "indev_get_active_obj", { (const void*) &lv_indev_get_active_obj, "lv.obj", "" } }, { "indev_read_timer_cb", { (const void*) &lv_indev_read_timer_cb, "", "(lv.timer)" } }, { "layer_bottom", { (const void*) &lv_layer_bottom, "lv.obj", "" } }, + { "layer_init", { (const void*) &lv_layer_init, "", "(lv.layer)" } }, + { "layer_reset", { (const void*) &lv_layer_reset, "", "(lv.layer)" } }, { "layer_sys", { (const void*) &lv_layer_sys, "lv.obj", "" } }, { "layer_top", { (const void*) &lv_layer_top, "lv.obj", "" } }, { "obj_assign_id", { (const void*) &lv_obj_assign_id, "", "(lv.obj_class)(lv.obj)" } }, @@ -167,6 +181,8 @@ const be_ntv_func_def_t lv_func[] = { { "task_handler", { (const void*) &lv_task_handler, "i", "" } }, { "text_get_size", { (const void*) &lv_text_get_size, "", "cs(lv.font)iiii" } }, { "text_get_width", { (const void*) &lv_text_get_width, "i", "si(lv.font)i" } }, + { "text_get_width_with_flags", { (const void*) &lv_text_get_width_with_flags, "i", "si(lv.font)ii" } }, + { "text_is_cmd", { (const void*) &lv_text_is_cmd, "b", "ci" } }, { "theme_apply", { (const void*) &lv_theme_apply, "", "(lv.obj)" } }, { "theme_get_color_primary", { (const void*) &lv_theme_get_color_primary, "lv.color", "(lv.obj)" } }, { "theme_get_color_secondary", { (const void*) &lv_theme_get_color_secondary, "lv.color", "(lv.obj)" } }, @@ -221,8 +237,6 @@ const be_const_member_t lv0_constants[] = { { "ALIGN_TOP_MID", be_cconst_int(LV_ALIGN_TOP_MID) }, { "ALIGN_TOP_RIGHT", be_cconst_int(LV_ALIGN_TOP_RIGHT) }, { "ANIM_IMAGE_PART_MAIN", be_cconst_int(LV_ANIM_IMAGE_PART_MAIN) }, - { "ANIM_OFF", be_cconst_int(LV_ANIM_OFF) }, - { "ANIM_ON", be_cconst_int(LV_ANIM_ON) }, { "ANIM_PLAYTIME_INFINITE", be_cconst_int(LV_ANIM_PLAYTIME_INFINITE) }, { "ANIM_REPEAT_INFINITE", be_cconst_int(LV_ANIM_REPEAT_INFINITE) }, { "ARC_MODE_NORMAL", be_cconst_int(LV_ARC_MODE_NORMAL) }, @@ -240,6 +254,7 @@ const be_const_member_t lv0_constants[] = { { "BASE_DIR_RTL", be_cconst_int(LV_BASE_DIR_RTL) }, { "BASE_DIR_WEAK", be_cconst_int(LV_BASE_DIR_WEAK) }, { "BLEND_MODE_ADDITIVE", be_cconst_int(LV_BLEND_MODE_ADDITIVE) }, + { "BLEND_MODE_DIFFERENCE", be_cconst_int(LV_BLEND_MODE_DIFFERENCE) }, { "BLEND_MODE_MULTIPLY", be_cconst_int(LV_BLEND_MODE_MULTIPLY) }, { "BLEND_MODE_NORMAL", be_cconst_int(LV_BLEND_MODE_NORMAL) }, { "BLEND_MODE_SUBTRACTIVE", be_cconst_int(LV_BLEND_MODE_SUBTRACTIVE) }, @@ -268,11 +283,27 @@ const be_const_member_t lv0_constants[] = { { "BUTTONMATRIX_CTRL_CUSTOM_2", be_cconst_int(LV_BUTTONMATRIX_CTRL_CUSTOM_2) }, { "BUTTONMATRIX_CTRL_DISABLED", be_cconst_int(LV_BUTTONMATRIX_CTRL_DISABLED) }, { "BUTTONMATRIX_CTRL_HIDDEN", be_cconst_int(LV_BUTTONMATRIX_CTRL_HIDDEN) }, + { "BUTTONMATRIX_CTRL_NONE", be_cconst_int(LV_BUTTONMATRIX_CTRL_NONE) }, { "BUTTONMATRIX_CTRL_NO_REPEAT", be_cconst_int(LV_BUTTONMATRIX_CTRL_NO_REPEAT) }, { "BUTTONMATRIX_CTRL_POPOVER", be_cconst_int(LV_BUTTONMATRIX_CTRL_POPOVER) }, + { "BUTTONMATRIX_CTRL_RECOLOR", be_cconst_int(LV_BUTTONMATRIX_CTRL_RECOLOR) }, { "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) }, + { "BUTTONMATRIX_CTRL_WIDTH_1", be_cconst_int(LV_BUTTONMATRIX_CTRL_WIDTH_1) }, + { "BUTTONMATRIX_CTRL_WIDTH_10", be_cconst_int(LV_BUTTONMATRIX_CTRL_WIDTH_10) }, + { "BUTTONMATRIX_CTRL_WIDTH_11", be_cconst_int(LV_BUTTONMATRIX_CTRL_WIDTH_11) }, + { "BUTTONMATRIX_CTRL_WIDTH_12", be_cconst_int(LV_BUTTONMATRIX_CTRL_WIDTH_12) }, + { "BUTTONMATRIX_CTRL_WIDTH_13", be_cconst_int(LV_BUTTONMATRIX_CTRL_WIDTH_13) }, + { "BUTTONMATRIX_CTRL_WIDTH_14", be_cconst_int(LV_BUTTONMATRIX_CTRL_WIDTH_14) }, + { "BUTTONMATRIX_CTRL_WIDTH_15", be_cconst_int(LV_BUTTONMATRIX_CTRL_WIDTH_15) }, + { "BUTTONMATRIX_CTRL_WIDTH_2", be_cconst_int(LV_BUTTONMATRIX_CTRL_WIDTH_2) }, + { "BUTTONMATRIX_CTRL_WIDTH_3", be_cconst_int(LV_BUTTONMATRIX_CTRL_WIDTH_3) }, + { "BUTTONMATRIX_CTRL_WIDTH_4", be_cconst_int(LV_BUTTONMATRIX_CTRL_WIDTH_4) }, + { "BUTTONMATRIX_CTRL_WIDTH_5", be_cconst_int(LV_BUTTONMATRIX_CTRL_WIDTH_5) }, + { "BUTTONMATRIX_CTRL_WIDTH_6", be_cconst_int(LV_BUTTONMATRIX_CTRL_WIDTH_6) }, + { "BUTTONMATRIX_CTRL_WIDTH_7", be_cconst_int(LV_BUTTONMATRIX_CTRL_WIDTH_7) }, + { "BUTTONMATRIX_CTRL_WIDTH_8", be_cconst_int(LV_BUTTONMATRIX_CTRL_WIDTH_8) }, + { "BUTTONMATRIX_CTRL_WIDTH_9", be_cconst_int(LV_BUTTONMATRIX_CTRL_WIDTH_9) }, { "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) }, @@ -301,8 +332,12 @@ const be_const_member_t lv0_constants[] = { { "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_ARGB1555", be_cconst_int(LV_COLOR_FORMAT_ARGB1555) }, + { "COLOR_FORMAT_ARGB2222", be_cconst_int(LV_COLOR_FORMAT_ARGB2222) }, + { "COLOR_FORMAT_ARGB4444", be_cconst_int(LV_COLOR_FORMAT_ARGB4444) }, { "COLOR_FORMAT_ARGB8565", be_cconst_int(LV_COLOR_FORMAT_ARGB8565) }, { "COLOR_FORMAT_ARGB8888", be_cconst_int(LV_COLOR_FORMAT_ARGB8888) }, + { "COLOR_FORMAT_ARGB8888_PREMULTIPLIED", be_cconst_int(LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED) }, { "COLOR_FORMAT_I1", be_cconst_int(LV_COLOR_FORMAT_I1) }, { "COLOR_FORMAT_I2", be_cconst_int(LV_COLOR_FORMAT_I2) }, { "COLOR_FORMAT_I4", be_cconst_int(LV_COLOR_FORMAT_I4) }, @@ -314,12 +349,22 @@ const be_const_member_t lv0_constants[] = { { "COLOR_FORMAT_L8", be_cconst_int(LV_COLOR_FORMAT_L8) }, { "COLOR_FORMAT_NATIVE", be_cconst_int(LV_COLOR_FORMAT_NATIVE) }, { "COLOR_FORMAT_NATIVE_WITH_ALPHA", be_cconst_int(LV_COLOR_FORMAT_NATIVE_WITH_ALPHA) }, + { "COLOR_FORMAT_NEMA_TSC12", be_cconst_int(LV_COLOR_FORMAT_NEMA_TSC12) }, + { "COLOR_FORMAT_NEMA_TSC12A", be_cconst_int(LV_COLOR_FORMAT_NEMA_TSC12A) }, + { "COLOR_FORMAT_NEMA_TSC4", be_cconst_int(LV_COLOR_FORMAT_NEMA_TSC4) }, + { "COLOR_FORMAT_NEMA_TSC6", be_cconst_int(LV_COLOR_FORMAT_NEMA_TSC6) }, + { "COLOR_FORMAT_NEMA_TSC6A", be_cconst_int(LV_COLOR_FORMAT_NEMA_TSC6A) }, + { "COLOR_FORMAT_NEMA_TSC6AP", be_cconst_int(LV_COLOR_FORMAT_NEMA_TSC6AP) }, + { "COLOR_FORMAT_NEMA_TSC_END", be_cconst_int(LV_COLOR_FORMAT_NEMA_TSC_END) }, + { "COLOR_FORMAT_NEMA_TSC_START", be_cconst_int(LV_COLOR_FORMAT_NEMA_TSC_START) }, { "COLOR_FORMAT_NV12", be_cconst_int(LV_COLOR_FORMAT_NV12) }, { "COLOR_FORMAT_NV21", be_cconst_int(LV_COLOR_FORMAT_NV21) }, + { "COLOR_FORMAT_PROPRIETARY_START", be_cconst_int(LV_COLOR_FORMAT_PROPRIETARY_START) }, { "COLOR_FORMAT_RAW", be_cconst_int(LV_COLOR_FORMAT_RAW) }, { "COLOR_FORMAT_RAW_ALPHA", be_cconst_int(LV_COLOR_FORMAT_RAW_ALPHA) }, { "COLOR_FORMAT_RGB565", be_cconst_int(LV_COLOR_FORMAT_RGB565) }, { "COLOR_FORMAT_RGB565A8", be_cconst_int(LV_COLOR_FORMAT_RGB565A8) }, + { "COLOR_FORMAT_RGB565_SWAPPED", be_cconst_int(LV_COLOR_FORMAT_RGB565_SWAPPED) }, { "COLOR_FORMAT_RGB888", be_cconst_int(LV_COLOR_FORMAT_RGB888) }, { "COLOR_FORMAT_UNKNOWN", be_cconst_int(LV_COLOR_FORMAT_UNKNOWN) }, { "COLOR_FORMAT_UYVY", be_cconst_int(LV_COLOR_FORMAT_UYVY) }, @@ -397,12 +442,12 @@ const be_const_member_t lv0_constants[] = { { "DRAW_TASK_TYPE_IMAGE", be_cconst_int(LV_DRAW_TASK_TYPE_IMAGE) }, { "DRAW_TASK_TYPE_LABEL", be_cconst_int(LV_DRAW_TASK_TYPE_LABEL) }, { "DRAW_TASK_TYPE_LAYER", be_cconst_int(LV_DRAW_TASK_TYPE_LAYER) }, + { "DRAW_TASK_TYPE_LETTER", be_cconst_int(LV_DRAW_TASK_TYPE_LETTER) }, { "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) }, { "EVENT_ALL", be_cconst_int(LV_EVENT_ALL) }, { "EVENT_CANCEL", be_cconst_int(LV_EVENT_CANCEL) }, @@ -415,6 +460,7 @@ const be_const_member_t lv0_constants[] = { { "EVENT_CREATE", be_cconst_int(LV_EVENT_CREATE) }, { "EVENT_DEFOCUSED", be_cconst_int(LV_EVENT_DEFOCUSED) }, { "EVENT_DELETE", be_cconst_int(LV_EVENT_DELETE) }, + { "EVENT_DOUBLE_CLICKED", be_cconst_int(LV_EVENT_DOUBLE_CLICKED) }, { "EVENT_DRAW_MAIN", be_cconst_int(LV_EVENT_DRAW_MAIN) }, { "EVENT_DRAW_MAIN_BEGIN", be_cconst_int(LV_EVENT_DRAW_MAIN_BEGIN) }, { "EVENT_DRAW_MAIN_END", be_cconst_int(LV_EVENT_DRAW_MAIN_END) }, @@ -441,6 +487,7 @@ const be_const_member_t lv0_constants[] = { { "EVENT_LEAVE", be_cconst_int(LV_EVENT_LEAVE) }, { "EVENT_LONG_PRESSED", be_cconst_int(LV_EVENT_LONG_PRESSED) }, { "EVENT_LONG_PRESSED_REPEAT", be_cconst_int(LV_EVENT_LONG_PRESSED_REPEAT) }, + { "EVENT_MARKED_DELETING", be_cconst_int(LV_EVENT_MARKED_DELETING) }, { "EVENT_PREPROCESS", be_cconst_int(LV_EVENT_PREPROCESS) }, { "EVENT_PRESSED", be_cconst_int(LV_EVENT_PRESSED) }, { "EVENT_PRESSING", be_cconst_int(LV_EVENT_PRESSING) }, @@ -465,10 +512,13 @@ const be_const_member_t lv0_constants[] = { { "EVENT_SCROLL_END", be_cconst_int(LV_EVENT_SCROLL_END) }, { "EVENT_SCROLL_THROW_BEGIN", be_cconst_int(LV_EVENT_SCROLL_THROW_BEGIN) }, { "EVENT_SHORT_CLICKED", be_cconst_int(LV_EVENT_SHORT_CLICKED) }, + { "EVENT_SINGLE_CLICKED", be_cconst_int(LV_EVENT_SINGLE_CLICKED) }, { "EVENT_SIZE_CHANGED", be_cconst_int(LV_EVENT_SIZE_CHANGED) }, { "EVENT_STYLE_CHANGED", be_cconst_int(LV_EVENT_STYLE_CHANGED) }, + { "EVENT_TRIPLE_CLICKED", be_cconst_int(LV_EVENT_TRIPLE_CLICKED) }, { "EVENT_VALUE_CHANGED", be_cconst_int(LV_EVENT_VALUE_CHANGED) }, { "EVENT_VSYNC", be_cconst_int(LV_EVENT_VSYNC) }, + { "EVENT_VSYNC_REQUEST", be_cconst_int(LV_EVENT_VSYNC_REQUEST) }, { "FLEX_ALIGN_CENTER", be_cconst_int(LV_FLEX_ALIGN_CENTER) }, { "FLEX_ALIGN_END", be_cconst_int(LV_FLEX_ALIGN_END) }, { "FLEX_ALIGN_SPACE_AROUND", be_cconst_int(LV_FLEX_ALIGN_SPACE_AROUND) }, @@ -537,6 +587,8 @@ const be_const_member_t lv0_constants[] = { { "IMAGE_ALIGN_BOTTOM_MID", be_cconst_int(LV_IMAGE_ALIGN_BOTTOM_MID) }, { "IMAGE_ALIGN_BOTTOM_RIGHT", be_cconst_int(LV_IMAGE_ALIGN_BOTTOM_RIGHT) }, { "IMAGE_ALIGN_CENTER", be_cconst_int(LV_IMAGE_ALIGN_CENTER) }, + { "IMAGE_ALIGN_CONTAIN", be_cconst_int(LV_IMAGE_ALIGN_CONTAIN) }, + { "IMAGE_ALIGN_COVER", be_cconst_int(LV_IMAGE_ALIGN_COVER) }, { "IMAGE_ALIGN_DEFAULT", be_cconst_int(LV_IMAGE_ALIGN_DEFAULT) }, { "IMAGE_ALIGN_LEFT_MID", be_cconst_int(LV_IMAGE_ALIGN_LEFT_MID) }, { "IMAGE_ALIGN_RIGHT_MID", be_cconst_int(LV_IMAGE_ALIGN_RIGHT_MID) }, @@ -550,6 +602,7 @@ const be_const_member_t lv0_constants[] = { { "IMAGE_COMPRESS_RLE", be_cconst_int(LV_IMAGE_COMPRESS_RLE) }, { "IMAGE_FLAGS_ALLOCATED", be_cconst_int(LV_IMAGE_FLAGS_ALLOCATED) }, { "IMAGE_FLAGS_COMPRESSED", be_cconst_int(LV_IMAGE_FLAGS_COMPRESSED) }, + { "IMAGE_FLAGS_CUSTOM_DRAW", be_cconst_int(LV_IMAGE_FLAGS_CUSTOM_DRAW) }, { "IMAGE_FLAGS_MODIFIABLE", be_cconst_int(LV_IMAGE_FLAGS_MODIFIABLE) }, { "IMAGE_FLAGS_PREMULTIPLIED", be_cconst_int(LV_IMAGE_FLAGS_PREMULTIPLIED) }, { "IMAGE_FLAGS_USER1", be_cconst_int(LV_IMAGE_FLAGS_USER1) }, @@ -588,11 +641,16 @@ const be_const_member_t lv0_constants[] = { { "KEY_RIGHT", be_cconst_int(LV_KEY_RIGHT) }, { "KEY_UP", be_cconst_int(LV_KEY_UP) }, { "LABEL_DOT_NUM", be_cconst_int(LV_LABEL_DOT_NUM) }, - { "LABEL_LONG_CLIP", be_cconst_int(LV_LABEL_LONG_CLIP) }, - { "LABEL_LONG_DOT", be_cconst_int(LV_LABEL_LONG_DOT) }, - { "LABEL_LONG_SCROLL", be_cconst_int(LV_LABEL_LONG_SCROLL) }, - { "LABEL_LONG_SCROLL_CIRCULAR", be_cconst_int(LV_LABEL_LONG_SCROLL_CIRCULAR) }, - { "LABEL_LONG_WRAP", be_cconst_int(LV_LABEL_LONG_WRAP) }, + { "LABEL_LONG_CLIP", be_cconst_int(LV_LABEL_LONG_MODE_CLIP) }, + { "LABEL_LONG_DOT", be_cconst_int(LV_LABEL_LONG_MODE_DOTS) }, + { "LABEL_LONG_MODE_CLIP", be_cconst_int(LV_LABEL_LONG_MODE_CLIP) }, + { "LABEL_LONG_MODE_DOTS", be_cconst_int(LV_LABEL_LONG_MODE_DOTS) }, + { "LABEL_LONG_MODE_SCROLL", be_cconst_int(LV_LABEL_LONG_MODE_SCROLL) }, + { "LABEL_LONG_MODE_SCROLL_CIRCULAR", be_cconst_int(LV_LABEL_LONG_MODE_SCROLL_CIRCULAR) }, + { "LABEL_LONG_MODE_WRAP", be_cconst_int(LV_LABEL_LONG_MODE_WRAP) }, + { "LABEL_LONG_SCROLL", be_cconst_int(LV_LABEL_LONG_MODE_SCROLL) }, + { "LABEL_LONG_SCROLL_CIRCULAR", be_cconst_int(LV_LABEL_LONG_MODE_SCROLL_CIRCULAR) }, + { "LABEL_LONG_WRAP", be_cconst_int(LV_LABEL_LONG_MODE_WRAP) }, { "LABEL_POS_LAST", be_cconst_int(LV_LABEL_POS_LAST) }, { "LABEL_TEXT_SELECTION_OFF", be_cconst_int(LV_LABEL_TEXT_SELECTION_OFF) }, { "LAYER_TYPE_NONE", be_cconst_int(LV_LAYER_TYPE_NONE) }, @@ -713,6 +771,8 @@ const be_const_member_t lv0_constants[] = { { "ROLLER_MODE_INFINITE", be_cconst_int(LV_ROLLER_MODE_INFINITE) }, { "ROLLER_MODE_NORMAL", be_cconst_int(LV_ROLLER_MODE_NORMAL) }, { "SCALE_LABEL_ENABLED_DEFAULT", be_cconst_int(LV_SCALE_LABEL_ENABLED_DEFAULT) }, + { "SCALE_LABEL_ROTATE_KEEP_UPRIGHT", be_cconst_int(LV_SCALE_LABEL_ROTATE_KEEP_UPRIGHT) }, + { "SCALE_LABEL_ROTATE_MATCH_TICKS", be_cconst_int(LV_SCALE_LABEL_ROTATE_MATCH_TICKS) }, { "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) }, @@ -722,6 +782,7 @@ const be_const_member_t lv0_constants[] = { { "SCALE_MODE_VERTICAL_LEFT", be_cconst_int(LV_SCALE_MODE_VERTICAL_LEFT) }, { "SCALE_MODE_VERTICAL_RIGHT", be_cconst_int(LV_SCALE_MODE_VERTICAL_RIGHT) }, { "SCALE_NONE", be_cconst_int(LV_SCALE_NONE) }, + { "SCALE_ROTATION_ANGLE_MASK", be_cconst_int(LV_SCALE_ROTATION_ANGLE_MASK) }, { "SCALE_TOTAL_TICK_COUNT_DEFAULT", be_cconst_int(LV_SCALE_TOTAL_TICK_COUNT_DEFAULT) }, { "SCROLLBAR_MODE_ACTIVE", be_cconst_int(LV_SCROLLBAR_MODE_ACTIVE) }, { "SCROLLBAR_MODE_AUTO", be_cconst_int(LV_SCROLLBAR_MODE_AUTO) }, @@ -751,6 +812,9 @@ const be_const_member_t lv0_constants[] = { { "SLIDER_MODE_NORMAL", be_cconst_int(LV_SLIDER_MODE_NORMAL) }, { "SLIDER_MODE_RANGE", be_cconst_int(LV_SLIDER_MODE_RANGE) }, { "SLIDER_MODE_SYMMETRICAL", be_cconst_int(LV_SLIDER_MODE_SYMMETRICAL) }, + { "SLIDER_ORIENTATION_AUTO", be_cconst_int(LV_SLIDER_ORIENTATION_AUTO) }, + { "SLIDER_ORIENTATION_HORIZONTAL", be_cconst_int(LV_SLIDER_ORIENTATION_HORIZONTAL) }, + { "SLIDER_ORIENTATION_VERTICAL", be_cconst_int(LV_SLIDER_ORIENTATION_VERTICAL) }, { "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) }, @@ -856,13 +920,17 @@ const be_const_member_t lv0_constants[] = { { "STYLE_PAD_BOTTOM", be_cconst_int(LV_STYLE_PAD_BOTTOM) }, { "STYLE_PAD_COLUMN", be_cconst_int(LV_STYLE_PAD_COLUMN) }, { "STYLE_PAD_LEFT", be_cconst_int(LV_STYLE_PAD_LEFT) }, + { "STYLE_PAD_RADIAL", be_cconst_int(LV_STYLE_PAD_RADIAL) }, { "STYLE_PAD_RIGHT", be_cconst_int(LV_STYLE_PAD_RIGHT) }, { "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_RADIAL_OFFSET", be_cconst_int(LV_STYLE_RADIAL_OFFSET) }, { "STYLE_RADIUS", be_cconst_int(LV_STYLE_RADIUS) }, + { "STYLE_RECOLOR", be_cconst_int(LV_STYLE_RECOLOR) }, + { "STYLE_RECOLOR_OPA", be_cconst_int(LV_STYLE_RECOLOR_OPA) }, { "STYLE_RES_FOUND", be_cconst_int(LV_STYLE_RES_FOUND) }, { "STYLE_RES_NOT_FOUND", be_cconst_int(LV_STYLE_RES_NOT_FOUND) }, { "STYLE_ROTARY_SENSITIVITY", be_cconst_int(LV_STYLE_ROTARY_SENSITIVITY) }, @@ -885,6 +953,9 @@ const be_const_member_t lv0_constants[] = { { "STYLE_TEXT_LETTER_SPACE", be_cconst_int(LV_STYLE_TEXT_LETTER_SPACE) }, { "STYLE_TEXT_LINE_SPACE", be_cconst_int(LV_STYLE_TEXT_LINE_SPACE) }, { "STYLE_TEXT_OPA", be_cconst_int(LV_STYLE_TEXT_OPA) }, + { "STYLE_TEXT_OUTLINE_STROKE_COLOR", be_cconst_int(LV_STYLE_TEXT_OUTLINE_STROKE_COLOR) }, + { "STYLE_TEXT_OUTLINE_STROKE_OPA", be_cconst_int(LV_STYLE_TEXT_OUTLINE_STROKE_OPA) }, + { "STYLE_TEXT_OUTLINE_STROKE_WIDTH", be_cconst_int(LV_STYLE_TEXT_OUTLINE_STROKE_WIDTH) }, { "STYLE_TRANSFORM_ANGLE", be_cconst_int(LV_STYLE_TRANSFORM_ROTATION) }, { "STYLE_TRANSFORM_HEIGHT", be_cconst_int(LV_STYLE_TRANSFORM_HEIGHT) }, { "STYLE_TRANSFORM_PIVOT_X", be_cconst_int(LV_STYLE_TRANSFORM_PIVOT_X) }, @@ -896,11 +967,15 @@ const be_const_member_t lv0_constants[] = { { "STYLE_TRANSFORM_SKEW_Y", be_cconst_int(LV_STYLE_TRANSFORM_SKEW_Y) }, { "STYLE_TRANSFORM_WIDTH", be_cconst_int(LV_STYLE_TRANSFORM_WIDTH) }, { "STYLE_TRANSITION", be_cconst_int(LV_STYLE_TRANSITION) }, + { "STYLE_TRANSLATE_RADIAL", be_cconst_int(LV_STYLE_TRANSLATE_RADIAL) }, { "STYLE_TRANSLATE_X", be_cconst_int(LV_STYLE_TRANSLATE_X) }, { "STYLE_TRANSLATE_Y", be_cconst_int(LV_STYLE_TRANSLATE_Y) }, { "STYLE_WIDTH", be_cconst_int(LV_STYLE_WIDTH) }, { "STYLE_X", be_cconst_int(LV_STYLE_X) }, { "STYLE_Y", be_cconst_int(LV_STYLE_Y) }, + { "SWITCH_ORIENTATION_AUTO", be_cconst_int(LV_SWITCH_ORIENTATION_AUTO) }, + { "SWITCH_ORIENTATION_HORIZONTAL", be_cconst_int(LV_SWITCH_ORIENTATION_HORIZONTAL) }, + { "SWITCH_ORIENTATION_VERTICAL", be_cconst_int(LV_SWITCH_ORIENTATION_VERTICAL) }, { "$SYMBOL_AUDIO", be_cconst_string("\xef\x80\x81") }, { "$SYMBOL_BACKSPACE", be_cconst_string("\xef\x95\x9A") }, { "$SYMBOL_BATTERY_1", be_cconst_string("\xef\x89\x83") }, @@ -965,6 +1040,7 @@ const be_const_member_t lv0_constants[] = { { "TABLE_CELL_CTRL_CUSTOM_3", be_cconst_int(LV_TABLE_CELL_CTRL_CUSTOM_3) }, { "TABLE_CELL_CTRL_CUSTOM_4", be_cconst_int(LV_TABLE_CELL_CTRL_CUSTOM_4) }, { "TABLE_CELL_CTRL_MERGE_RIGHT", be_cconst_int(LV_TABLE_CELL_CTRL_MERGE_RIGHT) }, + { "TABLE_CELL_CTRL_NONE", be_cconst_int(LV_TABLE_CELL_CTRL_NONE) }, { "TABLE_CELL_CTRL_TEXT_CROP", be_cconst_int(LV_TABLE_CELL_CTRL_TEXT_CROP) }, { "TABLE_CELL_NONE", be_cconst_int(LV_TABLE_CELL_NONE) }, { "TEXTAREA_CURSOR_LAST", be_cconst_int(LV_TEXTAREA_CURSOR_LAST) }, @@ -972,6 +1048,9 @@ const be_const_member_t lv0_constants[] = { { "TEXT_ALIGN_CENTER", be_cconst_int(LV_TEXT_ALIGN_CENTER) }, { "TEXT_ALIGN_LEFT", be_cconst_int(LV_TEXT_ALIGN_LEFT) }, { "TEXT_ALIGN_RIGHT", be_cconst_int(LV_TEXT_ALIGN_RIGHT) }, + { "TEXT_CMD_STATE_IN", be_cconst_int(LV_TEXT_CMD_STATE_IN) }, + { "TEXT_CMD_STATE_PAR", be_cconst_int(LV_TEXT_CMD_STATE_PAR) }, + { "TEXT_CMD_STATE_WAIT", be_cconst_int(LV_TEXT_CMD_STATE_WAIT) }, { "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) }, @@ -979,6 +1058,9 @@ const be_const_member_t lv0_constants[] = { { "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) }, + { "TEXT_FLAG_RECOLOR", be_cconst_int(LV_TEXT_FLAG_RECOLOR) }, + { "TREE_WALK_POST_ORDER", be_cconst_int(LV_TREE_WALK_POST_ORDER) }, + { "TREE_WALK_PRE_ORDER", be_cconst_int(LV_TREE_WALK_PRE_ORDER) }, { "ZOOM_NONE", be_cconst_int(LV_SCALE_NONE) }, { "&anim_path_bounce", be_cconst_ptr(&lv_anim_path_bounce) }, { "&anim_path_ease_in", be_cconst_ptr(&lv_anim_path_ease_in) }, 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 90b6f4062..d69266d23 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_enum.h +++ b/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_enum.h @@ -49,7 +49,6 @@ COLOR_IVORY=0xFFFFF0 COLOR_LINEN=0xFAF0E6 COLOR_BEIGE=0xF5F5DC COLOR_AZURE=0xF0FFFF -COLOR_SILVER=0xC0C0C0 COLOR_PINK=0xFFC0CB COLOR_PLUM=0xDDA0DD COLOR_ORCHID=0xDA70D6 @@ -178,94 +177,97 @@ LV_STYLE_TRANSFORM_ANGLE=LV_STYLE_TRANSFORM_ROTATION LV_ZOOM_NONE=LV_SCALE_NONE +// LVGL 9.3 +LV_LABEL_LONG_WRAP=LV_LABEL_LONG_MODE_WRAP +LV_LABEL_LONG_DOT=LV_LABEL_LONG_MODE_DOTS +LV_LABEL_LONG_SCROLL=LV_LABEL_LONG_MODE_SCROLL +LV_LABEL_LONG_SCROLL_CIRCULAR=LV_LABEL_LONG_MODE_SCROLL_CIRCULAR +LV_LABEL_LONG_CLIP=LV_LABEL_LONG_MODE_CLIP + // ====================================================================== // Generated from headers // ====================================================================== - // File: ../../lvgl/src/core/lv_global.h -// File: ../../lvgl/src/core/lv_group.h -LV_KEY_UP -LV_KEY_DOWN -LV_KEY_RIGHT -LV_KEY_LEFT -LV_KEY_ESC -LV_KEY_DEL -LV_KEY_BACKSPACE -LV_KEY_ENTER -LV_KEY_NEXT -LV_KEY_PREV -LV_KEY_HOME -LV_KEY_END +// File: ../../lvgl/src/core/lv_group.h LV_GROUP_REFOCUS_POLICY_NEXT LV_GROUP_REFOCUS_POLICY_PREV +LV_KEY_BACKSPACE +LV_KEY_DEL +LV_KEY_DOWN +LV_KEY_END +LV_KEY_ENTER +LV_KEY_ESC +LV_KEY_HOME +LV_KEY_LEFT +LV_KEY_NEXT +LV_KEY_PREV +LV_KEY_RIGHT +LV_KEY_UP + // File: ../../lvgl/src/core/lv_obj.h -LV_STATE_DEFAULT -LV_STATE_CHECKED -LV_STATE_FOCUSED -LV_STATE_FOCUS_KEY -LV_STATE_EDITED -LV_STATE_HOVERED -LV_STATE_PRESSED -LV_STATE_SCROLLED -LV_STATE_DISABLED -LV_STATE_USER_1 -LV_STATE_USER_2 -LV_STATE_USER_3 -LV_STATE_USER_4 -LV_STATE_ANY - -LV_PART_MAIN -LV_PART_SCROLLBAR -LV_PART_INDICATOR -LV_PART_KNOB -LV_PART_SELECTED -LV_PART_ITEMS -LV_PART_CURSOR -LV_PART_CUSTOM_FIRST -LV_PART_ANY - -LV_OBJ_FLAG_HIDDEN +LV_OBJ_FLAG_ADV_HITTEST +LV_OBJ_FLAG_CHECKABLE LV_OBJ_FLAG_CLICKABLE LV_OBJ_FLAG_CLICK_FOCUSABLE -LV_OBJ_FLAG_CHECKABLE +LV_OBJ_FLAG_EVENT_BUBBLE +LV_OBJ_FLAG_FLEX_IN_NEW_TRACK +LV_OBJ_FLAG_FLOATING +LV_OBJ_FLAG_GESTURE_BUBBLE +LV_OBJ_FLAG_HIDDEN +LV_OBJ_FLAG_IGNORE_LAYOUT +LV_OBJ_FLAG_LAYOUT_1 +LV_OBJ_FLAG_LAYOUT_2 +LV_OBJ_FLAG_OVERFLOW_VISIBLE +LV_OBJ_FLAG_PRESS_LOCK LV_OBJ_FLAG_SCROLLABLE +LV_OBJ_FLAG_SCROLL_CHAIN +LV_OBJ_FLAG_SCROLL_CHAIN_HOR +LV_OBJ_FLAG_SCROLL_CHAIN_VER LV_OBJ_FLAG_SCROLL_ELASTIC LV_OBJ_FLAG_SCROLL_MOMENTUM LV_OBJ_FLAG_SCROLL_ONE -LV_OBJ_FLAG_SCROLL_CHAIN_HOR -LV_OBJ_FLAG_SCROLL_CHAIN_VER -LV_OBJ_FLAG_SCROLL_CHAIN LV_OBJ_FLAG_SCROLL_ON_FOCUS LV_OBJ_FLAG_SCROLL_WITH_ARROW -LV_OBJ_FLAG_SNAPPABLE -LV_OBJ_FLAG_PRESS_LOCK -LV_OBJ_FLAG_EVENT_BUBBLE -LV_OBJ_FLAG_GESTURE_BUBBLE -LV_OBJ_FLAG_ADV_HITTEST -LV_OBJ_FLAG_IGNORE_LAYOUT -LV_OBJ_FLAG_FLOATING LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS -LV_OBJ_FLAG_OVERFLOW_VISIBLE -LV_OBJ_FLAG_FLEX_IN_NEW_TRACK -LV_OBJ_FLAG_LAYOUT_1 -LV_OBJ_FLAG_LAYOUT_2 -LV_OBJ_FLAG_WIDGET_1 -LV_OBJ_FLAG_WIDGET_2 +LV_OBJ_FLAG_SNAPPABLE LV_OBJ_FLAG_USER_1 LV_OBJ_FLAG_USER_2 LV_OBJ_FLAG_USER_3 LV_OBJ_FLAG_USER_4 +LV_OBJ_FLAG_WIDGET_1 +LV_OBJ_FLAG_WIDGET_2 +LV_PART_ANY +LV_PART_CURSOR +LV_PART_CUSTOM_FIRST +LV_PART_INDICATOR +LV_PART_ITEMS +LV_PART_KNOB +LV_PART_MAIN +LV_PART_SCROLLBAR +LV_PART_SELECTED +LV_STATE_ANY +LV_STATE_CHECKED +LV_STATE_DEFAULT +LV_STATE_DISABLED +LV_STATE_EDITED +LV_STATE_FOCUSED +LV_STATE_FOCUS_KEY +LV_STATE_HOVERED +LV_STATE_PRESSED +LV_STATE_SCROLLED +LV_STATE_USER_1 +LV_STATE_USER_2 +LV_STATE_USER_3 +LV_STATE_USER_4 // File: ../../lvgl/src/core/lv_obj_class.h +LV_OBJ_CLASS_EDITABLE_FALSE LV_OBJ_CLASS_EDITABLE_INHERIT LV_OBJ_CLASS_EDITABLE_TRUE -LV_OBJ_CLASS_EDITABLE_FALSE - +LV_OBJ_CLASS_GROUP_DEF_FALSE LV_OBJ_CLASS_GROUP_DEF_INHERIT LV_OBJ_CLASS_GROUP_DEF_TRUE -LV_OBJ_CLASS_GROUP_DEF_FALSE - LV_OBJ_CLASS_THEME_INHERITABLE_FALSE LV_OBJ_CLASS_THEME_INHERITABLE_TRUE @@ -276,115 +278,121 @@ LV_LAYER_TYPE_TRANSFORM // File: ../../lvgl/src/core/lv_obj_event.h LV_COVER_RES_COVER -LV_COVER_RES_NOT_COVER LV_COVER_RES_MASKED +LV_COVER_RES_NOT_COVER // File: ../../lvgl/src/core/lv_obj_pos.h -LV_OBJ_POINT_TRANSFORM_FLAG_NONE -LV_OBJ_POINT_TRANSFORM_FLAG_RECURSIVE LV_OBJ_POINT_TRANSFORM_FLAG_INVERSE LV_OBJ_POINT_TRANSFORM_FLAG_INVERSE_RECURSIVE +LV_OBJ_POINT_TRANSFORM_FLAG_NONE +LV_OBJ_POINT_TRANSFORM_FLAG_RECURSIVE // File: ../../lvgl/src/core/lv_obj_scroll.h -LV_SCROLLBAR_MODE_OFF -LV_SCROLLBAR_MODE_ON LV_SCROLLBAR_MODE_ACTIVE LV_SCROLLBAR_MODE_AUTO - +LV_SCROLLBAR_MODE_OFF +LV_SCROLLBAR_MODE_ON +LV_SCROLL_SNAP_CENTER +LV_SCROLL_SNAP_END LV_SCROLL_SNAP_NONE 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 +LV_STYLE_STATE_CMP_DIFF_REDRAW +LV_STYLE_STATE_CMP_SAME // File: ../../lvgl/src/core/lv_obj_style_gen.h + // File: ../../lvgl/src/core/lv_obj_tree.h +LV_OBJ_TREE_WALK_END LV_OBJ_TREE_WALK_NEXT LV_OBJ_TREE_WALK_SKIP_CHILDREN -LV_OBJ_TREE_WALK_END // File: ../../lvgl/src/core/lv_refr.h + // File: ../../lvgl/src/display/lv_display.h -LV_DISPLAY_ROTATION_0 -LV_DISPLAY_ROTATION_90 -LV_DISPLAY_ROTATION_180 -LV_DISPLAY_ROTATION_270 -LV_DISPLAY_RENDER_MODE_PARTIAL LV_DISPLAY_RENDER_MODE_DIRECT LV_DISPLAY_RENDER_MODE_FULL - -LV_SCR_LOAD_ANIM_NONE -LV_SCR_LOAD_ANIM_OVER_LEFT -LV_SCR_LOAD_ANIM_OVER_RIGHT -LV_SCR_LOAD_ANIM_OVER_TOP -LV_SCR_LOAD_ANIM_OVER_BOTTOM -LV_SCR_LOAD_ANIM_MOVE_LEFT -LV_SCR_LOAD_ANIM_MOVE_RIGHT -LV_SCR_LOAD_ANIM_MOVE_TOP -LV_SCR_LOAD_ANIM_MOVE_BOTTOM +LV_DISPLAY_RENDER_MODE_PARTIAL +LV_DISPLAY_ROTATION_0 +LV_DISPLAY_ROTATION_180 +LV_DISPLAY_ROTATION_270 +LV_DISPLAY_ROTATION_90 LV_SCR_LOAD_ANIM_FADE_IN LV_SCR_LOAD_ANIM_FADE_ON LV_SCR_LOAD_ANIM_FADE_OUT +LV_SCR_LOAD_ANIM_MOVE_BOTTOM +LV_SCR_LOAD_ANIM_MOVE_LEFT +LV_SCR_LOAD_ANIM_MOVE_RIGHT +LV_SCR_LOAD_ANIM_MOVE_TOP +LV_SCR_LOAD_ANIM_NONE +LV_SCR_LOAD_ANIM_OUT_BOTTOM LV_SCR_LOAD_ANIM_OUT_LEFT LV_SCR_LOAD_ANIM_OUT_RIGHT LV_SCR_LOAD_ANIM_OUT_TOP -LV_SCR_LOAD_ANIM_OUT_BOTTOM +LV_SCR_LOAD_ANIM_OVER_BOTTOM +LV_SCR_LOAD_ANIM_OVER_LEFT +LV_SCR_LOAD_ANIM_OVER_RIGHT +LV_SCR_LOAD_ANIM_OVER_TOP // File: ../../lvgl/src/draw/lv_draw.h -LV_DRAW_TASK_TYPE_NONE -LV_DRAW_TASK_TYPE_FILL +LV_DRAW_TASK_STATE_IN_PROGRESS +LV_DRAW_TASK_STATE_QUEUED +LV_DRAW_TASK_STATE_READY +LV_DRAW_TASK_STATE_WAITING +LV_DRAW_TASK_TYPE_ARC LV_DRAW_TASK_TYPE_BORDER LV_DRAW_TASK_TYPE_BOX_SHADOW -LV_DRAW_TASK_TYPE_LABEL +LV_DRAW_TASK_TYPE_FILL LV_DRAW_TASK_TYPE_IMAGE +LV_DRAW_TASK_TYPE_LABEL LV_DRAW_TASK_TYPE_LAYER +LV_DRAW_TASK_TYPE_LETTER LV_DRAW_TASK_TYPE_LINE -LV_DRAW_TASK_TYPE_ARC -LV_DRAW_TASK_TYPE_TRIANGLE -LV_DRAW_TASK_TYPE_MASK_RECTANGLE LV_DRAW_TASK_TYPE_MASK_BITMAP -LV_DRAW_TASK_TYPE_VECTOR +LV_DRAW_TASK_TYPE_MASK_RECTANGLE +LV_DRAW_TASK_TYPE_NONE +LV_DRAW_TASK_TYPE_TRIANGLE -LV_DRAW_TASK_STATE_WAITING -LV_DRAW_TASK_STATE_QUEUED -LV_DRAW_TASK_STATE_IN_PROGRESS -LV_DRAW_TASK_STATE_READY +// File: ../../lvgl/src/draw/lv_draw_3d.h // File: ../../lvgl/src/draw/lv_draw_arc.h + // File: ../../lvgl/src/draw/lv_draw_buf.h LV_STRIDE_AUTO + // File: ../../lvgl/src/draw/lv_draw_image.h + // File: ../../lvgl/src/draw/lv_draw_label.h + // File: ../../lvgl/src/draw/lv_draw_line.h + // File: ../../lvgl/src/draw/lv_draw_mask.h + // File: ../../lvgl/src/draw/lv_draw_rect.h LV_RADIUS_CIRCLE + // File: ../../lvgl/src/draw/lv_draw_triangle.h + // File: ../../lvgl/src/draw/lv_draw_vector.h - - - - - - - - // File: ../../lvgl/src/draw/lv_image_decoder.h -LV_IMAGE_SRC_VARIABLE LV_IMAGE_SRC_FILE LV_IMAGE_SRC_SYMBOL LV_IMAGE_SRC_UNKNOWN +LV_IMAGE_SRC_VARIABLE // File: ../../lvgl/src/draw/lv_image_dsc.h -LV_IMAGE_FLAGS_PREMULTIPLIED -LV_IMAGE_FLAGS_COMPRESSED +LV_IMAGE_COMPRESS_LZ4 +LV_IMAGE_COMPRESS_NONE +LV_IMAGE_COMPRESS_RLE LV_IMAGE_FLAGS_ALLOCATED +LV_IMAGE_FLAGS_COMPRESSED +LV_IMAGE_FLAGS_CUSTOM_DRAW LV_IMAGE_FLAGS_MODIFIABLE +LV_IMAGE_FLAGS_PREMULTIPLIED LV_IMAGE_FLAGS_USER1 LV_IMAGE_FLAGS_USER2 LV_IMAGE_FLAGS_USER3 @@ -393,102 +401,147 @@ LV_IMAGE_FLAGS_USER5 LV_IMAGE_FLAGS_USER6 LV_IMAGE_FLAGS_USER7 LV_IMAGE_FLAGS_USER8 - -LV_IMAGE_COMPRESS_NONE -LV_IMAGE_COMPRESS_RLE -LV_IMAGE_COMPRESS_LZ4 - LV_IMAGE_HEADER_MAGIC + // File: ../../lvgl/src/layouts/flex/lv_flex.h -LV_FLEX_ALIGN_START -LV_FLEX_ALIGN_END LV_FLEX_ALIGN_CENTER -LV_FLEX_ALIGN_SPACE_EVENLY +LV_FLEX_ALIGN_END LV_FLEX_ALIGN_SPACE_AROUND LV_FLEX_ALIGN_SPACE_BETWEEN - -LV_FLEX_FLOW_ROW +LV_FLEX_ALIGN_SPACE_EVENLY +LV_FLEX_ALIGN_START LV_FLEX_FLOW_COLUMN -LV_FLEX_FLOW_ROW_WRAP -LV_FLEX_FLOW_ROW_REVERSE -LV_FLEX_FLOW_ROW_WRAP_REVERSE -LV_FLEX_FLOW_COLUMN_WRAP LV_FLEX_FLOW_COLUMN_REVERSE +LV_FLEX_FLOW_COLUMN_WRAP LV_FLEX_FLOW_COLUMN_WRAP_REVERSE +LV_FLEX_FLOW_ROW +LV_FLEX_FLOW_ROW_REVERSE +LV_FLEX_FLOW_ROW_WRAP +LV_FLEX_FLOW_ROW_WRAP_REVERSE // File: ../../lvgl/src/layouts/grid/lv_grid.h -LV_GRID_ALIGN_START LV_GRID_ALIGN_CENTER LV_GRID_ALIGN_END -LV_GRID_ALIGN_STRETCH -LV_GRID_ALIGN_SPACE_EVENLY LV_GRID_ALIGN_SPACE_AROUND LV_GRID_ALIGN_SPACE_BETWEEN - +LV_GRID_ALIGN_SPACE_EVENLY +LV_GRID_ALIGN_START +LV_GRID_ALIGN_STRETCH LV_GRID_CONTENT LV_GRID_TEMPLATE_LAST + // File: ../../lvgl/src/layouts/lv_layout.h -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 +LV_LAYOUT_NONE -LV_ANIM_REPEAT_INFINITE +// File: ../../lvgl/src/misc/lv_anim.h LV_ANIM_PLAYTIME_INFINITE +LV_ANIM_REPEAT_INFINITE + // File: ../../lvgl/src/misc/lv_anim_timeline.h + // File: ../../lvgl/src/misc/lv_area.h -LV_ALIGN_DEFAULT -LV_ALIGN_TOP_LEFT -LV_ALIGN_TOP_MID -LV_ALIGN_TOP_RIGHT LV_ALIGN_BOTTOM_LEFT LV_ALIGN_BOTTOM_MID LV_ALIGN_BOTTOM_RIGHT -LV_ALIGN_LEFT_MID -LV_ALIGN_RIGHT_MID LV_ALIGN_CENTER -LV_ALIGN_OUT_TOP_LEFT -LV_ALIGN_OUT_TOP_MID -LV_ALIGN_OUT_TOP_RIGHT +LV_ALIGN_DEFAULT +LV_ALIGN_LEFT_MID LV_ALIGN_OUT_BOTTOM_LEFT LV_ALIGN_OUT_BOTTOM_MID LV_ALIGN_OUT_BOTTOM_RIGHT -LV_ALIGN_OUT_LEFT_TOP -LV_ALIGN_OUT_LEFT_MID LV_ALIGN_OUT_LEFT_BOTTOM -LV_ALIGN_OUT_RIGHT_TOP -LV_ALIGN_OUT_RIGHT_MID +LV_ALIGN_OUT_LEFT_MID +LV_ALIGN_OUT_LEFT_TOP LV_ALIGN_OUT_RIGHT_BOTTOM - -LV_DIR_NONE -LV_DIR_LEFT -LV_DIR_RIGHT -LV_DIR_TOP -LV_DIR_BOTTOM -LV_DIR_HOR -LV_DIR_VER -LV_DIR_ALL - +LV_ALIGN_OUT_RIGHT_MID +LV_ALIGN_OUT_RIGHT_TOP +LV_ALIGN_OUT_TOP_LEFT +LV_ALIGN_OUT_TOP_MID +LV_ALIGN_OUT_TOP_RIGHT +LV_ALIGN_RIGHT_MID +LV_ALIGN_TOP_LEFT +LV_ALIGN_TOP_MID +LV_ALIGN_TOP_RIGHT LV_COORD_MAX LV_COORD_MIN +LV_DIR_ALL +LV_DIR_BOTTOM +LV_DIR_HOR +LV_DIR_LEFT +LV_DIR_NONE +LV_DIR_RIGHT +LV_DIR_TOP +LV_DIR_VER LV_SIZE_CONTENT + // File: ../../lvgl/src/misc/lv_array.h + // File: ../../lvgl/src/misc/lv_assert.h + // File: ../../lvgl/src/misc/lv_async.h + // File: ../../lvgl/src/misc/lv_bidi.h -LV_BASE_DIR_LTR -LV_BASE_DIR_RTL LV_BASE_DIR_AUTO +LV_BASE_DIR_LTR LV_BASE_DIR_NEUTRAL +LV_BASE_DIR_RTL LV_BASE_DIR_WEAK +// File: ../../lvgl/src/misc/lv_circle_buf.h + // File: ../../lvgl/src/misc/lv_color.h -LV_OPA_TRANSP +LV_COLOR_DEPTH +LV_COLOR_FORMAT_A1 +LV_COLOR_FORMAT_A2 +LV_COLOR_FORMAT_A4 +LV_COLOR_FORMAT_A8 +LV_COLOR_FORMAT_AL88 +LV_COLOR_FORMAT_ARGB1555 +LV_COLOR_FORMAT_ARGB2222 +LV_COLOR_FORMAT_ARGB4444 +LV_COLOR_FORMAT_ARGB8565 +LV_COLOR_FORMAT_ARGB8888 +LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED +LV_COLOR_FORMAT_I1 +LV_COLOR_FORMAT_I2 +LV_COLOR_FORMAT_I4 +LV_COLOR_FORMAT_I400 +LV_COLOR_FORMAT_I420 +LV_COLOR_FORMAT_I422 +LV_COLOR_FORMAT_I444 +LV_COLOR_FORMAT_I8 +LV_COLOR_FORMAT_L8 +LV_COLOR_FORMAT_NATIVE +LV_COLOR_FORMAT_NATIVE_WITH_ALPHA +LV_COLOR_FORMAT_NEMA_TSC12 +LV_COLOR_FORMAT_NEMA_TSC12A +LV_COLOR_FORMAT_NEMA_TSC4 +LV_COLOR_FORMAT_NEMA_TSC6 +LV_COLOR_FORMAT_NEMA_TSC6A +LV_COLOR_FORMAT_NEMA_TSC6AP +LV_COLOR_FORMAT_NEMA_TSC_END +LV_COLOR_FORMAT_NEMA_TSC_START +LV_COLOR_FORMAT_NV12 +LV_COLOR_FORMAT_NV21 +LV_COLOR_FORMAT_PROPRIETARY_START +LV_COLOR_FORMAT_RAW +LV_COLOR_FORMAT_RAW_ALPHA +LV_COLOR_FORMAT_RGB565 +LV_COLOR_FORMAT_RGB565A8 +LV_COLOR_FORMAT_RGB565_SWAPPED +LV_COLOR_FORMAT_RGB888 +LV_COLOR_FORMAT_UNKNOWN +LV_COLOR_FORMAT_UYVY +LV_COLOR_FORMAT_XRGB8888 +LV_COLOR_FORMAT_YUV_END +LV_COLOR_FORMAT_YUV_START +LV_COLOR_FORMAT_YUY2 LV_OPA_0 LV_OPA_10 +LV_OPA_100 LV_OPA_20 LV_OPA_30 LV_OPA_40 @@ -497,498 +550,541 @@ LV_OPA_60 LV_OPA_70 LV_OPA_80 LV_OPA_90 -LV_OPA_100 LV_OPA_COVER +LV_OPA_TRANSP -LV_COLOR_FORMAT_UNKNOWN -LV_COLOR_FORMAT_RAW -LV_COLOR_FORMAT_RAW_ALPHA -LV_COLOR_FORMAT_L8 -LV_COLOR_FORMAT_I1 -LV_COLOR_FORMAT_I2 -LV_COLOR_FORMAT_I4 -LV_COLOR_FORMAT_I8 -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 -LV_COLOR_FORMAT_A1 -LV_COLOR_FORMAT_A2 -LV_COLOR_FORMAT_A4 -LV_COLOR_FORMAT_YUV_START -LV_COLOR_FORMAT_I420 -LV_COLOR_FORMAT_I422 -LV_COLOR_FORMAT_I444 -LV_COLOR_FORMAT_I400 -LV_COLOR_FORMAT_NV21 -LV_COLOR_FORMAT_NV12 -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 -LV_COLOR_FORMAT_NATIVE_WITH_ALPHA -LV_COLOR_FORMAT_NATIVE -LV_COLOR_FORMAT_NATIVE_WITH_ALPHA - -LV_COLOR_DEPTH // File: ../../lvgl/src/misc/lv_color_op.h + // File: ../../lvgl/src/misc/lv_event.h LV_EVENT_ALL -LV_EVENT_PRESSED -LV_EVENT_PRESSING -LV_EVENT_PRESS_LOST -LV_EVENT_SHORT_CLICKED -LV_EVENT_LONG_PRESSED -LV_EVENT_LONG_PRESSED_REPEAT -LV_EVENT_CLICKED -LV_EVENT_RELEASED -LV_EVENT_SCROLL_BEGIN -LV_EVENT_SCROLL_THROW_BEGIN -LV_EVENT_SCROLL_END -LV_EVENT_SCROLL -LV_EVENT_GESTURE -LV_EVENT_KEY -LV_EVENT_ROTARY -LV_EVENT_FOCUSED -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 -LV_EVENT_DRAW_MAIN -LV_EVENT_DRAW_MAIN_END -LV_EVENT_DRAW_POST_BEGIN -LV_EVENT_DRAW_POST -LV_EVENT_DRAW_POST_END -LV_EVENT_DRAW_TASK_ADDED -LV_EVENT_VALUE_CHANGED -LV_EVENT_INSERT -LV_EVENT_REFRESH -LV_EVENT_READY LV_EVENT_CANCEL -LV_EVENT_CREATE -LV_EVENT_DELETE LV_EVENT_CHILD_CHANGED LV_EVENT_CHILD_CREATED LV_EVENT_CHILD_DELETED -LV_EVENT_SCREEN_UNLOAD_START -LV_EVENT_SCREEN_LOAD_START -LV_EVENT_SCREEN_LOADED -LV_EVENT_SCREEN_UNLOADED -LV_EVENT_SIZE_CHANGED -LV_EVENT_STYLE_CHANGED -LV_EVENT_LAYOUT_CHANGED -LV_EVENT_GET_SELF_SIZE -LV_EVENT_INVALIDATE_AREA -LV_EVENT_RESOLUTION_CHANGED +LV_EVENT_CLICKED LV_EVENT_COLOR_FORMAT_CHANGED +LV_EVENT_COVER_CHECK +LV_EVENT_CREATE +LV_EVENT_DEFOCUSED +LV_EVENT_DELETE +LV_EVENT_DOUBLE_CLICKED +LV_EVENT_DRAW_MAIN +LV_EVENT_DRAW_MAIN_BEGIN +LV_EVENT_DRAW_MAIN_END +LV_EVENT_DRAW_POST +LV_EVENT_DRAW_POST_BEGIN +LV_EVENT_DRAW_POST_END +LV_EVENT_DRAW_TASK_ADDED +LV_EVENT_FLUSH_FINISH +LV_EVENT_FLUSH_START +LV_EVENT_FLUSH_WAIT_FINISH +LV_EVENT_FLUSH_WAIT_START +LV_EVENT_FOCUSED +LV_EVENT_GESTURE +LV_EVENT_GET_SELF_SIZE +LV_EVENT_HIT_TEST +LV_EVENT_HOVER_LEAVE +LV_EVENT_HOVER_OVER +LV_EVENT_INDEV_RESET +LV_EVENT_INSERT +LV_EVENT_INVALIDATE_AREA +LV_EVENT_KEY +LV_EVENT_LAST +LV_EVENT_LAYOUT_CHANGED +LV_EVENT_LEAVE +LV_EVENT_LONG_PRESSED +LV_EVENT_LONG_PRESSED_REPEAT +LV_EVENT_MARKED_DELETING +LV_EVENT_PREPROCESS +LV_EVENT_PRESSED +LV_EVENT_PRESSING +LV_EVENT_PRESS_LOST +LV_EVENT_READY +LV_EVENT_REFRESH +LV_EVENT_REFR_EXT_DRAW_SIZE +LV_EVENT_REFR_READY LV_EVENT_REFR_REQUEST LV_EVENT_REFR_START -LV_EVENT_REFR_READY -LV_EVENT_RENDER_START +LV_EVENT_RELEASED LV_EVENT_RENDER_READY -LV_EVENT_FLUSH_START -LV_EVENT_FLUSH_FINISH -LV_EVENT_FLUSH_WAIT_START -LV_EVENT_FLUSH_WAIT_FINISH +LV_EVENT_RENDER_START +LV_EVENT_RESOLUTION_CHANGED +LV_EVENT_ROTARY +LV_EVENT_SCREEN_LOADED +LV_EVENT_SCREEN_LOAD_START +LV_EVENT_SCREEN_UNLOADED +LV_EVENT_SCREEN_UNLOAD_START +LV_EVENT_SCROLL +LV_EVENT_SCROLL_BEGIN +LV_EVENT_SCROLL_END +LV_EVENT_SCROLL_THROW_BEGIN +LV_EVENT_SHORT_CLICKED +LV_EVENT_SINGLE_CLICKED +LV_EVENT_SIZE_CHANGED +LV_EVENT_STYLE_CHANGED +LV_EVENT_TRIPLE_CLICKED +LV_EVENT_VALUE_CHANGED LV_EVENT_VSYNC -LV_EVENT_LAST -LV_EVENT_PREPROCESS +LV_EVENT_VSYNC_REQUEST // File: ../../lvgl/src/misc/lv_fs.h -LV_FS_RES_OK -LV_FS_RES_HW_ERR -LV_FS_RES_FS_ERR -LV_FS_RES_NOT_EX -LV_FS_RES_FULL -LV_FS_RES_LOCKED -LV_FS_RES_DENIED -LV_FS_RES_BUSY -LV_FS_RES_TOUT -LV_FS_RES_NOT_IMP -LV_FS_RES_OUT_OF_MEM -LV_FS_RES_INV_PARAM -LV_FS_RES_UNKNOWN - -LV_FS_MODE_WR LV_FS_MODE_RD - -LV_FS_SEEK_SET +LV_FS_MODE_WR +LV_FS_RES_BUSY +LV_FS_RES_DENIED +LV_FS_RES_FS_ERR +LV_FS_RES_FULL +LV_FS_RES_HW_ERR +LV_FS_RES_INV_PARAM +LV_FS_RES_LOCKED +LV_FS_RES_NOT_EX +LV_FS_RES_NOT_IMP +LV_FS_RES_OK +LV_FS_RES_OUT_OF_MEM +LV_FS_RES_TOUT +LV_FS_RES_UNKNOWN LV_FS_SEEK_CUR LV_FS_SEEK_END +LV_FS_SEEK_SET -// File: ../../lvgl/src/misc/lv_ll.h -// File: ../../lvgl/src/misc/lv_log.h -LV_LOG_LEVEL_TRACE -LV_LOG_LEVEL_INFO -LV_LOG_LEVEL_WARN -LV_LOG_LEVEL_ERROR -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 -LV_PALETTE_PURPLE -LV_PALETTE_DEEP_PURPLE -LV_PALETTE_INDIGO -LV_PALETTE_BLUE -LV_PALETTE_LIGHT_BLUE -LV_PALETTE_CYAN -LV_PALETTE_TEAL -LV_PALETTE_GREEN -LV_PALETTE_LIGHT_GREEN -LV_PALETTE_LIME -LV_PALETTE_YELLOW -LV_PALETTE_AMBER -LV_PALETTE_ORANGE -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 -// File: ../../lvgl/src/misc/lv_profiler_builtin.h -// File: ../../lvgl/src/misc/lv_rb.h -LV_RB_COLOR_RED -LV_RB_COLOR_BLACK -// File: ../../lvgl/src/misc/lv_style.h -LV_BLEND_MODE_NORMAL -LV_BLEND_MODE_ADDITIVE -LV_BLEND_MODE_SUBTRACTIVE -LV_BLEND_MODE_MULTIPLY - -LV_TEXT_DECOR_NONE -LV_TEXT_DECOR_UNDERLINE -LV_TEXT_DECOR_STRIKETHROUGH - -LV_BORDER_SIDE_NONE -LV_BORDER_SIDE_BOTTOM -LV_BORDER_SIDE_TOP -LV_BORDER_SIDE_LEFT -LV_BORDER_SIDE_RIGHT -LV_BORDER_SIDE_FULL -LV_BORDER_SIDE_INTERNAL - -LV_GRAD_DIR_NONE -LV_GRAD_DIR_VER +// File: ../../lvgl/src/misc/lv_grad.h +LV_GRAD_DIR_CONICAL LV_GRAD_DIR_HOR LV_GRAD_DIR_LINEAR +LV_GRAD_DIR_NONE LV_GRAD_DIR_RADIAL -LV_GRAD_DIR_CONICAL - +LV_GRAD_DIR_VER LV_GRAD_EXTEND_PAD -LV_GRAD_EXTEND_REPEAT LV_GRAD_EXTEND_REFLECT +LV_GRAD_EXTEND_REPEAT -LV_STYLE_PROP_INV -LV_STYLE_WIDTH -LV_STYLE_HEIGHT -LV_STYLE_LENGTH -LV_STYLE_MIN_WIDTH -LV_STYLE_MAX_WIDTH -LV_STYLE_MIN_HEIGHT -LV_STYLE_MAX_HEIGHT -LV_STYLE_X -LV_STYLE_Y +// File: ../../lvgl/src/misc/lv_iter.h + +// File: ../../lvgl/src/misc/lv_ll.h + +// File: ../../lvgl/src/misc/lv_log.h +LV_LOG_LEVEL_ERROR +LV_LOG_LEVEL_INFO +LV_LOG_LEVEL_NONE +LV_LOG_LEVEL_TRACE +LV_LOG_LEVEL_USER +LV_LOG_LEVEL_WARN + +// 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_AMBER +LV_PALETTE_BLUE +LV_PALETTE_BLUE_GREY +LV_PALETTE_BROWN +LV_PALETTE_CYAN +LV_PALETTE_DEEP_ORANGE +LV_PALETTE_DEEP_PURPLE +LV_PALETTE_GREEN +LV_PALETTE_GREY +LV_PALETTE_INDIGO +LV_PALETTE_LAST +LV_PALETTE_LIGHT_BLUE +LV_PALETTE_LIGHT_GREEN +LV_PALETTE_LIME +LV_PALETTE_NONE +LV_PALETTE_ORANGE +LV_PALETTE_PINK +LV_PALETTE_PURPLE +LV_PALETTE_RED +LV_PALETTE_TEAL +LV_PALETTE_YELLOW + +// File: ../../lvgl/src/misc/lv_profiler.h + +// File: ../../lvgl/src/misc/lv_profiler_builtin.h + +// File: ../../lvgl/src/misc/lv_rb.h +LV_RB_COLOR_BLACK +LV_RB_COLOR_RED + +// File: ../../lvgl/src/misc/lv_style.h +LV_BLEND_MODE_ADDITIVE +LV_BLEND_MODE_DIFFERENCE +LV_BLEND_MODE_MULTIPLY +LV_BLEND_MODE_NORMAL +LV_BLEND_MODE_SUBTRACTIVE +LV_BORDER_SIDE_BOTTOM +LV_BORDER_SIDE_FULL +LV_BORDER_SIDE_INTERNAL +LV_BORDER_SIDE_LEFT +LV_BORDER_SIDE_NONE +LV_BORDER_SIDE_RIGHT +LV_BORDER_SIDE_TOP +LV_SCALE_NONE LV_STYLE_ALIGN -LV_STYLE_RADIUS -LV_STYLE_PAD_TOP -LV_STYLE_PAD_BOTTOM -LV_STYLE_PAD_LEFT -LV_STYLE_PAD_RIGHT -LV_STYLE_PAD_ROW -LV_STYLE_PAD_COLUMN -LV_STYLE_LAYOUT -LV_STYLE_MARGIN_TOP -LV_STYLE_MARGIN_BOTTOM -LV_STYLE_MARGIN_LEFT -LV_STYLE_MARGIN_RIGHT -LV_STYLE_BG_COLOR -LV_STYLE_BG_OPA -LV_STYLE_BG_GRAD_DIR -LV_STYLE_BG_MAIN_STOP -LV_STYLE_BG_GRAD_STOP -LV_STYLE_BG_GRAD_COLOR -LV_STYLE_BG_MAIN_OPA -LV_STYLE_BG_GRAD_OPA -LV_STYLE_BG_GRAD +LV_STYLE_ANIM +LV_STYLE_ANIM_DURATION +LV_STYLE_ARC_COLOR +LV_STYLE_ARC_IMAGE_SRC +LV_STYLE_ARC_OPA +LV_STYLE_ARC_ROUNDED +LV_STYLE_ARC_WIDTH LV_STYLE_BASE_DIR -LV_STYLE_BG_IMAGE_SRC +LV_STYLE_BG_COLOR +LV_STYLE_BG_GRAD +LV_STYLE_BG_GRAD_COLOR +LV_STYLE_BG_GRAD_DIR +LV_STYLE_BG_GRAD_OPA +LV_STYLE_BG_GRAD_STOP LV_STYLE_BG_IMAGE_OPA LV_STYLE_BG_IMAGE_RECOLOR LV_STYLE_BG_IMAGE_RECOLOR_OPA +LV_STYLE_BG_IMAGE_SRC LV_STYLE_BG_IMAGE_TILED -LV_STYLE_CLIP_CORNER -LV_STYLE_BORDER_WIDTH +LV_STYLE_BG_MAIN_OPA +LV_STYLE_BG_MAIN_STOP +LV_STYLE_BG_OPA +LV_STYLE_BITMAP_MASK_SRC +LV_STYLE_BLEND_MODE LV_STYLE_BORDER_COLOR LV_STYLE_BORDER_OPA -LV_STYLE_BORDER_SIDE LV_STYLE_BORDER_POST -LV_STYLE_OUTLINE_WIDTH -LV_STYLE_OUTLINE_COLOR -LV_STYLE_OUTLINE_OPA -LV_STYLE_OUTLINE_PAD -LV_STYLE_SHADOW_WIDTH -LV_STYLE_SHADOW_COLOR -LV_STYLE_SHADOW_OPA -LV_STYLE_SHADOW_OFFSET_X -LV_STYLE_SHADOW_OFFSET_Y -LV_STYLE_SHADOW_SPREAD +LV_STYLE_BORDER_SIDE +LV_STYLE_BORDER_WIDTH +LV_STYLE_CLIP_CORNER +LV_STYLE_COLOR_FILTER_DSC +LV_STYLE_COLOR_FILTER_OPA +LV_STYLE_FLEX_CROSS_PLACE +LV_STYLE_FLEX_FLOW +LV_STYLE_FLEX_GROW +LV_STYLE_FLEX_MAIN_PLACE +LV_STYLE_FLEX_TRACK_PLACE +LV_STYLE_GRID_CELL_COLUMN_POS +LV_STYLE_GRID_CELL_COLUMN_SPAN +LV_STYLE_GRID_CELL_ROW_POS +LV_STYLE_GRID_CELL_ROW_SPAN +LV_STYLE_GRID_CELL_X_ALIGN +LV_STYLE_GRID_CELL_Y_ALIGN +LV_STYLE_GRID_COLUMN_ALIGN +LV_STYLE_GRID_COLUMN_DSC_ARRAY +LV_STYLE_GRID_ROW_ALIGN +LV_STYLE_GRID_ROW_DSC_ARRAY +LV_STYLE_HEIGHT LV_STYLE_IMAGE_OPA LV_STYLE_IMAGE_RECOLOR LV_STYLE_IMAGE_RECOLOR_OPA -LV_STYLE_LINE_WIDTH -LV_STYLE_LINE_DASH_WIDTH -LV_STYLE_LINE_DASH_GAP -LV_STYLE_LINE_ROUNDED +LV_STYLE_LAST_BUILT_IN_PROP +LV_STYLE_LAYOUT +LV_STYLE_LENGTH LV_STYLE_LINE_COLOR +LV_STYLE_LINE_DASH_GAP +LV_STYLE_LINE_DASH_WIDTH LV_STYLE_LINE_OPA -LV_STYLE_ARC_WIDTH -LV_STYLE_ARC_ROUNDED -LV_STYLE_ARC_COLOR -LV_STYLE_ARC_OPA -LV_STYLE_ARC_IMAGE_SRC +LV_STYLE_LINE_ROUNDED +LV_STYLE_LINE_WIDTH +LV_STYLE_MARGIN_BOTTOM +LV_STYLE_MARGIN_LEFT +LV_STYLE_MARGIN_RIGHT +LV_STYLE_MARGIN_TOP +LV_STYLE_MAX_HEIGHT +LV_STYLE_MAX_WIDTH +LV_STYLE_MIN_HEIGHT +LV_STYLE_MIN_WIDTH +LV_STYLE_NUM_BUILT_IN_PROPS +LV_STYLE_OPA +LV_STYLE_OPA_LAYERED +LV_STYLE_OUTLINE_COLOR +LV_STYLE_OUTLINE_OPA +LV_STYLE_OUTLINE_PAD +LV_STYLE_OUTLINE_WIDTH +LV_STYLE_PAD_BOTTOM +LV_STYLE_PAD_COLUMN +LV_STYLE_PAD_LEFT +LV_STYLE_PAD_RADIAL +LV_STYLE_PAD_RIGHT +LV_STYLE_PAD_ROW +LV_STYLE_PAD_TOP +LV_STYLE_PROP_ANY +LV_STYLE_PROP_CONST +LV_STYLE_PROP_INV +LV_STYLE_RADIAL_OFFSET +LV_STYLE_RADIUS +LV_STYLE_RECOLOR +LV_STYLE_RECOLOR_OPA +LV_STYLE_RES_FOUND +LV_STYLE_RES_NOT_FOUND +LV_STYLE_ROTARY_SENSITIVITY +LV_STYLE_SHADOW_COLOR +LV_STYLE_SHADOW_OFFSET_X +LV_STYLE_SHADOW_OFFSET_Y +LV_STYLE_SHADOW_OPA +LV_STYLE_SHADOW_SPREAD +LV_STYLE_SHADOW_WIDTH +LV_STYLE_TEXT_ALIGN LV_STYLE_TEXT_COLOR -LV_STYLE_TEXT_OPA +LV_STYLE_TEXT_DECOR LV_STYLE_TEXT_FONT LV_STYLE_TEXT_LETTER_SPACE LV_STYLE_TEXT_LINE_SPACE -LV_STYLE_TEXT_DECOR -LV_STYLE_TEXT_ALIGN -LV_STYLE_OPA -LV_STYLE_OPA_LAYERED -LV_STYLE_COLOR_FILTER_DSC -LV_STYLE_COLOR_FILTER_OPA -LV_STYLE_ANIM -LV_STYLE_ANIM_DURATION -LV_STYLE_TRANSITION -LV_STYLE_BLEND_MODE -LV_STYLE_TRANSFORM_WIDTH +LV_STYLE_TEXT_OPA +LV_STYLE_TEXT_OUTLINE_STROKE_COLOR +LV_STYLE_TEXT_OUTLINE_STROKE_OPA +LV_STYLE_TEXT_OUTLINE_STROKE_WIDTH LV_STYLE_TRANSFORM_HEIGHT -LV_STYLE_TRANSLATE_X -LV_STYLE_TRANSLATE_Y -LV_STYLE_TRANSFORM_SCALE_X -LV_STYLE_TRANSFORM_SCALE_Y -LV_STYLE_TRANSFORM_ROTATION LV_STYLE_TRANSFORM_PIVOT_X LV_STYLE_TRANSFORM_PIVOT_Y +LV_STYLE_TRANSFORM_ROTATION +LV_STYLE_TRANSFORM_SCALE_X +LV_STYLE_TRANSFORM_SCALE_Y LV_STYLE_TRANSFORM_SKEW_X LV_STYLE_TRANSFORM_SKEW_Y -LV_STYLE_BITMAP_MASK_SRC -LV_STYLE_ROTARY_SENSITIVITY -LV_STYLE_FLEX_FLOW -LV_STYLE_FLEX_MAIN_PLACE -LV_STYLE_FLEX_CROSS_PLACE -LV_STYLE_FLEX_TRACK_PLACE -LV_STYLE_FLEX_GROW -LV_STYLE_GRID_COLUMN_ALIGN -LV_STYLE_GRID_ROW_ALIGN -LV_STYLE_GRID_ROW_DSC_ARRAY -LV_STYLE_GRID_COLUMN_DSC_ARRAY -LV_STYLE_GRID_CELL_COLUMN_POS -LV_STYLE_GRID_CELL_COLUMN_SPAN -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 +LV_STYLE_TRANSFORM_WIDTH +LV_STYLE_TRANSITION +LV_STYLE_TRANSLATE_RADIAL +LV_STYLE_TRANSLATE_X +LV_STYLE_TRANSLATE_Y +LV_STYLE_WIDTH +LV_STYLE_X +LV_STYLE_Y +LV_TEXT_DECOR_NONE +LV_TEXT_DECOR_STRIKETHROUGH +LV_TEXT_DECOR_UNDERLINE -LV_SCALE_NONE // File: ../../lvgl/src/misc/lv_style_gen.h + // File: ../../lvgl/src/misc/lv_templ.h + // File: ../../lvgl/src/misc/lv_text.h -LV_TEXT_FLAG_NONE +LV_TEXT_ALIGN_AUTO +LV_TEXT_ALIGN_CENTER +LV_TEXT_ALIGN_LEFT +LV_TEXT_ALIGN_RIGHT +LV_TEXT_CMD_STATE_IN +LV_TEXT_CMD_STATE_PAR +LV_TEXT_CMD_STATE_WAIT +LV_TEXT_FLAG_BREAK_ALL LV_TEXT_FLAG_EXPAND LV_TEXT_FLAG_FIT -LV_TEXT_FLAG_BREAK_ALL - -LV_TEXT_ALIGN_AUTO -LV_TEXT_ALIGN_LEFT -LV_TEXT_ALIGN_CENTER -LV_TEXT_ALIGN_RIGHT +LV_TEXT_FLAG_NONE +LV_TEXT_FLAG_RECOLOR // File: ../../lvgl/src/misc/lv_text_ap.h + // File: ../../lvgl/src/misc/lv_timer.h + +// File: ../../lvgl/src/misc/lv_tree.h +LV_TREE_WALK_POST_ORDER +LV_TREE_WALK_PRE_ORDER + // File: ../../lvgl/src/misc/lv_types.h LV_RESULT_INVALID LV_RESULT_OK // File: ../../lvgl/src/misc/lv_utils.h + // File: ../../lvgl/src/widgets/animimage/lv_animimage.h LV_ANIM_IMAGE_PART_MAIN // File: ../../lvgl/src/widgets/arc/lv_arc.h LV_ARC_MODE_NORMAL -LV_ARC_MODE_SYMMETRICAL LV_ARC_MODE_REVERSE +LV_ARC_MODE_SYMMETRICAL + // File: ../../lvgl/src/widgets/bar/lv_bar.h LV_BAR_MODE_NORMAL -LV_BAR_MODE_SYMMETRICAL LV_BAR_MODE_RANGE +LV_BAR_MODE_SYMMETRICAL 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 -LV_BUTTONMATRIX_CTRL_NO_REPEAT -LV_BUTTONMATRIX_CTRL_DISABLED +LV_BUTTONMATRIX_BUTTON_NONE 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_CTRL_DISABLED +LV_BUTTONMATRIX_CTRL_HIDDEN +LV_BUTTONMATRIX_CTRL_NONE +LV_BUTTONMATRIX_CTRL_NO_REPEAT +LV_BUTTONMATRIX_CTRL_POPOVER +LV_BUTTONMATRIX_CTRL_RECOLOR +LV_BUTTONMATRIX_CTRL_RESERVED_1 +LV_BUTTONMATRIX_CTRL_RESERVED_2 +LV_BUTTONMATRIX_CTRL_WIDTH_1 +LV_BUTTONMATRIX_CTRL_WIDTH_10 +LV_BUTTONMATRIX_CTRL_WIDTH_11 +LV_BUTTONMATRIX_CTRL_WIDTH_12 +LV_BUTTONMATRIX_CTRL_WIDTH_13 +LV_BUTTONMATRIX_CTRL_WIDTH_14 +LV_BUTTONMATRIX_CTRL_WIDTH_15 +LV_BUTTONMATRIX_CTRL_WIDTH_2 +LV_BUTTONMATRIX_CTRL_WIDTH_3 +LV_BUTTONMATRIX_CTRL_WIDTH_4 +LV_BUTTONMATRIX_CTRL_WIDTH_5 +LV_BUTTONMATRIX_CTRL_WIDTH_6 +LV_BUTTONMATRIX_CTRL_WIDTH_7 +LV_BUTTONMATRIX_CTRL_WIDTH_8 +LV_BUTTONMATRIX_CTRL_WIDTH_9 -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 + // File: ../../lvgl/src/widgets/chart/lv_chart.h -LV_CHART_TYPE_NONE -LV_CHART_TYPE_LINE -LV_CHART_TYPE_BAR -LV_CHART_TYPE_SCATTER - -LV_CHART_UPDATE_MODE_SHIFT -LV_CHART_UPDATE_MODE_CIRCULAR - -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_AXIS_PRIMARY_X +LV_CHART_AXIS_PRIMARY_Y +LV_CHART_AXIS_SECONDARY_X +LV_CHART_AXIS_SECONDARY_Y LV_CHART_POINT_NONE +LV_CHART_TYPE_BAR +LV_CHART_TYPE_LINE +LV_CHART_TYPE_NONE +LV_CHART_TYPE_SCATTER +LV_CHART_UPDATE_MODE_CIRCULAR +LV_CHART_UPDATE_MODE_SHIFT + // File: ../../lvgl/src/widgets/checkbox/lv_checkbox.h + // File: ../../lvgl/src/widgets/dropdown/lv_dropdown.h LV_DROPDOWN_POS_LAST + // File: ../../lvgl/src/widgets/image/lv_image.h -LV_IMAGE_ALIGN_DEFAULT -LV_IMAGE_ALIGN_TOP_LEFT -LV_IMAGE_ALIGN_TOP_MID -LV_IMAGE_ALIGN_TOP_RIGHT +LV_IMAGE_ALIGN_AUTO_TRANSFORM LV_IMAGE_ALIGN_BOTTOM_LEFT LV_IMAGE_ALIGN_BOTTOM_MID LV_IMAGE_ALIGN_BOTTOM_RIGHT +LV_IMAGE_ALIGN_CENTER +LV_IMAGE_ALIGN_CONTAIN +LV_IMAGE_ALIGN_COVER +LV_IMAGE_ALIGN_DEFAULT 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 +LV_IMAGE_ALIGN_TOP_LEFT +LV_IMAGE_ALIGN_TOP_MID +LV_IMAGE_ALIGN_TOP_RIGHT // File: ../../lvgl/src/widgets/imagebutton/lv_imagebutton.h -LV_IMAGEBUTTON_STATE_RELEASED -LV_IMAGEBUTTON_STATE_PRESSED -LV_IMAGEBUTTON_STATE_DISABLED -LV_IMAGEBUTTON_STATE_CHECKED_RELEASED -LV_IMAGEBUTTON_STATE_CHECKED_PRESSED LV_IMAGEBUTTON_STATE_CHECKED_DISABLED +LV_IMAGEBUTTON_STATE_CHECKED_PRESSED +LV_IMAGEBUTTON_STATE_CHECKED_RELEASED +LV_IMAGEBUTTON_STATE_DISABLED LV_IMAGEBUTTON_STATE_NUM +LV_IMAGEBUTTON_STATE_PRESSED +LV_IMAGEBUTTON_STATE_RELEASED // File: ../../lvgl/src/widgets/keyboard/lv_keyboard.h +LV_KEYBOARD_MODE_NUMBER +LV_KEYBOARD_MODE_SPECIAL LV_KEYBOARD_MODE_TEXT_LOWER LV_KEYBOARD_MODE_TEXT_UPPER -LV_KEYBOARD_MODE_SPECIAL -LV_KEYBOARD_MODE_NUMBER LV_KEYBOARD_MODE_USER_1 LV_KEYBOARD_MODE_USER_2 LV_KEYBOARD_MODE_USER_3 LV_KEYBOARD_MODE_USER_4 -// File: ../../lvgl/src/widgets/label/lv_label.h -LV_LABEL_LONG_WRAP -LV_LABEL_LONG_DOT -LV_LABEL_LONG_SCROLL -LV_LABEL_LONG_SCROLL_CIRCULAR -LV_LABEL_LONG_CLIP +// File: ../../lvgl/src/widgets/label/lv_label.h LV_LABEL_DOT_NUM +LV_LABEL_LONG_MODE_CLIP +LV_LABEL_LONG_MODE_DOTS +LV_LABEL_LONG_MODE_SCROLL +LV_LABEL_LONG_MODE_SCROLL_CIRCULAR +LV_LABEL_LONG_MODE_WRAP LV_LABEL_POS_LAST LV_LABEL_TEXT_SELECTION_OFF + // File: ../../lvgl/src/widgets/led/lv_led.h + // File: ../../lvgl/src/widgets/line/lv_line.h + // File: ../../lvgl/src/widgets/list/lv_list.h + // File: ../../lvgl/src/widgets/menu/lv_menu.h +LV_MENU_HEADER_BOTTOM_FIXED LV_MENU_HEADER_TOP_FIXED LV_MENU_HEADER_TOP_UNFIXED -LV_MENU_HEADER_BOTTOM_FIXED LV_MENU_ROOT_BACK_BUTTON_DISABLED LV_MENU_ROOT_BACK_BUTTON_ENABLED + // File: ../../lvgl/src/widgets/msgbox/lv_msgbox.h + // File: ../../lvgl/src/widgets/objx_templ/lv_objx_templ.h + // File: ../../lvgl/src/widgets/roller/lv_roller.h -LV_ROLLER_MODE_NORMAL LV_ROLLER_MODE_INFINITE +LV_ROLLER_MODE_NORMAL // File: ../../lvgl/src/widgets/scale/lv_scale.h -LV_SCALE_MODE_HORIZONTAL_TOP +LV_SCALE_LABEL_ENABLED_DEFAULT +LV_SCALE_LABEL_ROTATE_KEEP_UPRIGHT +LV_SCALE_LABEL_ROTATE_MATCH_TICKS +LV_SCALE_MAJOR_TICK_EVERY_DEFAULT LV_SCALE_MODE_HORIZONTAL_BOTTOM -LV_SCALE_MODE_VERTICAL_LEFT -LV_SCALE_MODE_VERTICAL_RIGHT +LV_SCALE_MODE_HORIZONTAL_TOP +LV_SCALE_MODE_LAST LV_SCALE_MODE_ROUND_INNER LV_SCALE_MODE_ROUND_OUTER -LV_SCALE_MODE_LAST +LV_SCALE_MODE_VERTICAL_LEFT +LV_SCALE_MODE_VERTICAL_RIGHT +LV_SCALE_ROTATION_ANGLE_MASK LV_SCALE_TOTAL_TICK_COUNT_DEFAULT -LV_SCALE_MAJOR_TICK_EVERY_DEFAULT -LV_SCALE_LABEL_ENABLED_DEFAULT + // File: ../../lvgl/src/widgets/slider/lv_slider.h LV_SLIDER_MODE_NORMAL -LV_SLIDER_MODE_SYMMETRICAL LV_SLIDER_MODE_RANGE +LV_SLIDER_MODE_SYMMETRICAL +LV_SLIDER_ORIENTATION_AUTO +LV_SLIDER_ORIENTATION_HORIZONTAL +LV_SLIDER_ORIENTATION_VERTICAL + // File: ../../lvgl/src/widgets/span/lv_span.h +LV_SPAN_MODE_BREAK +LV_SPAN_MODE_EXPAND +LV_SPAN_MODE_FIXED +LV_SPAN_MODE_LAST 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 +LV_SWITCH_ORIENTATION_AUTO +LV_SWITCH_ORIENTATION_HORIZONTAL +LV_SWITCH_ORIENTATION_VERTICAL + // File: ../../lvgl/src/widgets/table/lv_table.h -LV_TABLE_CELL_CTRL_MERGE_RIGHT -LV_TABLE_CELL_CTRL_TEXT_CROP LV_TABLE_CELL_CTRL_CUSTOM_1 LV_TABLE_CELL_CTRL_CUSTOM_2 LV_TABLE_CELL_CTRL_CUSTOM_3 LV_TABLE_CELL_CTRL_CUSTOM_4 - +LV_TABLE_CELL_CTRL_MERGE_RIGHT +LV_TABLE_CELL_CTRL_NONE +LV_TABLE_CELL_CTRL_TEXT_CROP LV_TABLE_CELL_NONE + // File: ../../lvgl/src/widgets/tabview/lv_tabview.h + // File: ../../lvgl/src/widgets/textarea/lv_textarea.h LV_PART_TEXTAREA_PLACEHOLDER - LV_TEXTAREA_CURSOR_LAST + // File: ../../lvgl/src/widgets/tileview/lv_tileview.h + // File: ../../lvgl/src/widgets/win/lv_win.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 425c50633..f958ae4ea 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_funcs.h +++ b/lib/libesp32_lvgl/lv_binding_berry/mapping/lv_funcs.h @@ -17,7 +17,6 @@ lv_coord_t lv_get_ver_res(void); // Generated from headers // ====================================================================== - // ../../lvgl/src/../lvgl.h static inline int lv_version_major(void) static inline int lv_version_minor(void) @@ -60,7 +59,7 @@ lv_group_t * lv_group_by_index(uint32_t index) lv_obj_t * lv_obj_create(lv_obj_t * parent) void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f) void lv_obj_remove_flag(lv_obj_t * obj, lv_obj_flag_t f) -void lv_obj_update_flag(lv_obj_t * obj, lv_obj_flag_t f, bool v) +void lv_obj_set_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) @@ -79,7 +78,7 @@ 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) +lv_obj_t * lv_obj_find_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) @@ -110,8 +109,8 @@ lv_event_dsc_t * lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb, lv_ uint32_t lv_obj_get_event_count(lv_obj_t * obj) lv_event_dsc_t * lv_obj_get_event_dsc(lv_obj_t * obj, uint32_t index) bool lv_obj_remove_event(lv_obj_t * obj, uint32_t index) -bool lv_obj_remove_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb) bool lv_obj_remove_event_dsc(lv_obj_t * obj, lv_event_dsc_t * dsc) +uint32_t lv_obj_remove_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb) uint32_t lv_obj_remove_event_cb_with_user_data(lv_obj_t * obj, lv_event_cb_t event_cb, void * user_data) lv_indev_t * lv_event_get_indev(lv_event_t * e) lv_layer_t * lv_event_get_layer(lv_event_t * e) @@ -144,6 +143,8 @@ 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) void lv_obj_center(lv_obj_t * obj) +void lv_obj_set_transform(lv_obj_t * obj, const lv_matrix_t * matrix) +void lv_obj_reset_transform(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) @@ -162,6 +163,7 @@ bool lv_obj_refresh_self_size(lv_obj_t * obj) void lv_obj_refr_pos(lv_obj_t * obj) void lv_obj_move_to(lv_obj_t * obj, int32_t x, int32_t y) void lv_obj_move_children_by(lv_obj_t * obj, int32_t x_diff, int32_t y_diff, bool ignore_floating) +const lv_matrix_t * lv_obj_get_transform(const lv_obj_t * obj) void lv_obj_transform_point(const lv_obj_t * obj, lv_point_t * p, lv_obj_point_transform_flag_t flags) void lv_obj_transform_point_array(const lv_obj_t * obj, lv_point_t points[], size_t count, lv_obj_point_transform_flag_t flags) void lv_obj_get_transformed_area(const lv_obj_t * obj, lv_area_t * area, lv_obj_point_transform_flag_t flags) @@ -186,12 +188,12 @@ lv_scroll_snap_t lv_obj_get_scroll_snap_x(const lv_obj_t * obj) lv_scroll_snap_t lv_obj_get_scroll_snap_y(const lv_obj_t * obj) int32_t lv_obj_get_scroll_x(const lv_obj_t * obj) int32_t lv_obj_get_scroll_y(const lv_obj_t * obj) -int32_t lv_obj_get_scroll_top(lv_obj_t * obj) -int32_t lv_obj_get_scroll_bottom(lv_obj_t * obj) -int32_t lv_obj_get_scroll_left(lv_obj_t * obj) -int32_t lv_obj_get_scroll_right(lv_obj_t * obj) +int32_t lv_obj_get_scroll_top(const lv_obj_t * obj) +int32_t lv_obj_get_scroll_bottom(const lv_obj_t * obj) +int32_t lv_obj_get_scroll_left(const lv_obj_t * obj) +int32_t lv_obj_get_scroll_right(const lv_obj_t * obj) void lv_obj_get_scroll_end(lv_obj_t * obj, lv_point_t * end) -void lv_obj_scroll_by(lv_obj_t * obj, int32_t x, int32_t y, lv_anim_enable_t anim_en) +void lv_obj_scroll_by(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_enable_t anim_en) void lv_obj_scroll_by_bounded(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_enable_t anim_en) void lv_obj_scroll_to(lv_obj_t * obj, int32_t x, int32_t y, lv_anim_enable_t anim_en) void lv_obj_scroll_to_x(lv_obj_t * obj, int32_t x, lv_anim_enable_t anim_en) @@ -199,6 +201,7 @@ void lv_obj_scroll_to_y(lv_obj_t * obj, int32_t y, lv_anim_enable_t anim_en) 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) bool lv_obj_is_scrolling(const lv_obj_t * obj) +void lv_obj_stop_scroll_anim(const lv_obj_t * obj) void lv_obj_update_snap(lv_obj_t * obj, lv_anim_enable_t anim_en) void lv_obj_get_scrollbar_area(lv_obj_t * obj, lv_area_t * hor, lv_area_t * ver) void lv_obj_scrollbar_invalidate(lv_obj_t * obj) @@ -239,6 +242,8 @@ lv_text_align_t lv_obj_calculate_style_text_align(const lv_obj_t * obj, lv_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) +lv_color32_t lv_obj_style_apply_recolor(const lv_obj_t * obj, lv_part_t part, lv_color32_t color) +lv_color32_t lv_obj_get_style_recolor_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, lv_part_t part) @@ -255,6 +260,7 @@ static inline int32_t lv_obj_get_style_transform_width(const lv_obj_t * obj, lv_ 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_translate_radial(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) @@ -268,6 +274,7 @@ static inline int32_t lv_obj_get_style_pad_left(const lv_obj_t * obj, lv_part_t 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_pad_radial(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) @@ -332,12 +339,19 @@ static inline int32_t lv_obj_get_style_text_letter_space(const lv_obj_t * obj, l 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 lv_color_t lv_obj_get_style_text_outline_stroke_color(const lv_obj_t * obj, lv_part_t part) +static inline lv_color_t lv_obj_get_style_text_outline_stroke_color_filtered(const lv_obj_t * obj, lv_part_t part) +static inline int32_t lv_obj_get_style_text_outline_stroke_width(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_text_outline_stroke_opa(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 int32_t lv_obj_get_style_radial_offset(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 lv_color_t lv_obj_get_style_recolor(const lv_obj_t * obj, lv_part_t part) +static inline lv_opa_t lv_obj_get_style_recolor_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) @@ -375,6 +389,7 @@ void lv_obj_set_style_transform_width(lv_obj_t * obj, int32_t value, lv_style_se void lv_obj_set_style_transform_height(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) void lv_obj_set_style_translate_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) void lv_obj_set_style_translate_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) +void lv_obj_set_style_translate_radial(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) void lv_obj_set_style_transform_scale_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) void lv_obj_set_style_transform_scale_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) void lv_obj_set_style_transform_rotation(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) @@ -388,6 +403,7 @@ void lv_obj_set_style_pad_left(lv_obj_t * obj, int32_t value, lv_style_selector_ void lv_obj_set_style_pad_right(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) void lv_obj_set_style_pad_row(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) void lv_obj_set_style_pad_column(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) +void lv_obj_set_style_pad_radial(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) void lv_obj_set_style_margin_top(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) void lv_obj_set_style_margin_bottom(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) void lv_obj_set_style_margin_left(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) @@ -442,12 +458,18 @@ void lv_obj_set_style_text_letter_space(lv_obj_t * obj, int32_t value, lv_style_ void lv_obj_set_style_text_line_space(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) void lv_obj_set_style_text_decor(lv_obj_t * obj, lv_text_decor_t value, lv_style_selector_t selector) void lv_obj_set_style_text_align(lv_obj_t * obj, lv_text_align_t value, lv_style_selector_t selector) +void lv_obj_set_style_text_outline_stroke_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector) +void lv_obj_set_style_text_outline_stroke_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) +void lv_obj_set_style_text_outline_stroke_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector) void lv_obj_set_style_radius(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) +void lv_obj_set_style_radial_offset(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) void lv_obj_set_style_clip_corner(lv_obj_t * obj, bool value, lv_style_selector_t selector) void lv_obj_set_style_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector) void lv_obj_set_style_opa_layered(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector) void lv_obj_set_style_color_filter_dsc(lv_obj_t * obj, const lv_color_filter_dsc_t * value, lv_style_selector_t selector) void lv_obj_set_style_color_filter_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector) +void lv_obj_set_style_recolor(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector) +void lv_obj_set_style_recolor_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector) void lv_obj_set_style_anim(lv_obj_t * obj, const lv_anim_t * value, lv_style_selector_t selector) void lv_obj_set_style_anim_duration(lv_obj_t * obj, uint32_t value, lv_style_selector_t selector) void lv_obj_set_style_transition(lv_obj_t * obj, const lv_style_transition_dsc_t * value, lv_style_selector_t selector) @@ -498,6 +520,7 @@ void lv_obj_dump_tree(lv_obj_t * start_obj) // ../../lvgl/src/core/lv_refr.h void lv_refr_now(lv_display_t * disp) void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) +void lv_display_refr_timer(lv_timer_t * timer) // ../../lvgl/src/display/lv_display.h lv_display_t * lv_display_create(int32_t hor_res, int32_t ver_res) @@ -509,22 +532,30 @@ void lv_display_set_resolution(lv_display_t * disp, int32_t hor_res, int32_t ver void lv_display_set_physical_resolution(lv_display_t * disp, int32_t hor_res, int32_t ver_res) void lv_display_set_offset(lv_display_t * disp, int32_t x, int32_t y) void lv_display_set_rotation(lv_display_t * disp, lv_display_rotation_t rotation) +void lv_display_set_matrix_rotation(lv_display_t * disp, bool enable) void lv_display_set_dpi(lv_display_t * disp, int32_t dpi) int32_t lv_display_get_horizontal_resolution(const lv_display_t * disp) int32_t lv_display_get_vertical_resolution(const lv_display_t * disp) +int32_t lv_display_get_original_horizontal_resolution(const lv_display_t * disp) +int32_t lv_display_get_original_vertical_resolution(const lv_display_t * disp) int32_t lv_display_get_physical_horizontal_resolution(const lv_display_t * disp) int32_t lv_display_get_physical_vertical_resolution(const lv_display_t * disp) int32_t lv_display_get_offset_x(const lv_display_t * disp) int32_t lv_display_get_offset_y(const lv_display_t * disp) lv_display_rotation_t lv_display_get_rotation(lv_display_t * disp) +bool lv_display_get_matrix_rotation(lv_display_t * disp) int32_t lv_display_get_dpi(const lv_display_t * disp) void lv_display_set_buffers(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size, lv_display_render_mode_t render_mode) +void lv_display_set_buffers_with_stride(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size, uint32_t stride, lv_display_render_mode_t render_mode) void lv_display_set_draw_buffers(lv_display_t * disp, lv_draw_buf_t * buf1, lv_draw_buf_t * buf2) +void lv_display_set_3rd_draw_buffer(lv_display_t * disp, lv_draw_buf_t * buf3) void lv_display_set_render_mode(lv_display_t * disp, lv_display_render_mode_t render_mode) void lv_display_set_flush_cb(lv_display_t * disp, lv_display_flush_cb_t flush_cb) void lv_display_set_flush_wait_cb(lv_display_t * disp, lv_display_flush_wait_cb_t wait_cb) void lv_display_set_color_format(lv_display_t * disp, lv_color_format_t color_format) lv_color_format_t lv_display_get_color_format(lv_display_t * disp) +void lv_display_set_tile_cnt(lv_display_t * disp, uint32_t tile_cnt) +uint32_t lv_display_get_tile_cnt(lv_display_t * disp) void lv_display_set_antialiasing(lv_display_t * disp, bool en) bool lv_display_get_antialiasing(lv_display_t * disp) bool lv_display_is_double_buffered(lv_display_t * disp) @@ -533,7 +564,7 @@ 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) lv_obj_t * lv_screen_active(void) lv_obj_t * lv_layer_top(void) @@ -545,6 +576,7 @@ lv_event_dsc_t * lv_display_get_event_dsc(lv_display_t * disp, uint32_t index) bool lv_display_delete_event(lv_display_t * disp, uint32_t index) uint32_t lv_display_remove_event_cb_with_user_data(lv_display_t * disp, lv_event_cb_t event_cb, void * user_data) lv_result_t lv_display_send_event(lv_display_t * disp, lv_event_code_t code, void * param) +lv_area_t * lv_event_get_invalidated_area(lv_event_t * e) void lv_display_set_theme(lv_display_t * disp, lv_theme_t * th) lv_theme_t * lv_display_get_theme(lv_display_t * disp) uint32_t lv_display_get_inactive_time(const lv_display_t * disp) @@ -553,12 +585,17 @@ void lv_display_enable_invalidation(lv_display_t * disp, bool en) bool lv_display_is_invalidation_enabled(lv_display_t * disp) lv_timer_t * lv_display_get_refr_timer(lv_display_t * disp) void lv_display_delete_refr_timer(lv_display_t * disp) +bool lv_display_register_vsync_event(lv_display_t * disp, lv_event_cb_t event_cb, void * user_data) +bool lv_display_unregister_vsync_event(lv_display_t * disp, lv_event_cb_t event_cb, void * user_data) +lv_result_t lv_display_send_vsync_event(lv_display_t * disp, void * param) void lv_display_set_user_data(lv_display_t * disp, void * user_data) 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) void lv_display_rotate_area(lv_display_t * disp, lv_area_t * area) +uint32_t lv_display_get_draw_buf_size(lv_display_t * disp) +uint32_t lv_display_get_invalidated_draw_buf_size(lv_display_t * disp, uint32_t width, uint32_t height) int32_t lv_dpx(int32_t n) int32_t lv_display_dpx(const lv_display_t * disp, int32_t n) @@ -566,7 +603,7 @@ int32_t lv_display_dpx(const lv_display_t * disp, int32_t n) void lv_draw_init(void) void lv_draw_deinit(void) void * lv_draw_create_unit(size_t size) -lv_draw_task_t * lv_draw_add_task(lv_layer_t * layer, const lv_area_t * coords) +lv_draw_task_t * lv_draw_add_task(lv_layer_t * layer, const lv_area_t * coords, lv_draw_task_type_t type) 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) @@ -574,9 +611,13 @@ 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_available_task(lv_layer_t * layer, lv_draw_task_t * t_prev, uint8_t draw_unit_id) 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) +void lv_layer_init(lv_layer_t * layer) +void lv_layer_reset(lv_layer_t * layer) 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_init(lv_layer_t * layer, 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) @@ -590,12 +631,15 @@ void lv_draw_arc(lv_layer_t * layer, const lv_draw_arc_dsc_t * dsc) void lv_draw_arc_get_area(int32_t x, int32_t y, uint16_t radius, lv_value_precise_t start_angle, lv_value_precise_t end_angle, int32_t w, bool rounded, lv_area_t * area) // ../../lvgl/src/draw/lv_draw_label.h +void lv_draw_letter_dsc_init(lv_draw_letter_dsc_t * dsc) void lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc) lv_draw_label_dsc_t * lv_draw_task_get_label_dsc(lv_draw_task_t * task) void lv_draw_glyph_dsc_init(lv_draw_glyph_dsc_t * dsc) void lv_draw_label(lv_layer_t * layer, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords) void lv_draw_character(lv_layer_t * layer, lv_draw_label_dsc_t * dsc, const lv_point_t * point, uint32_t unicode_letter) -void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords, lv_draw_glyph_cb_t cb) +void lv_draw_letter(lv_layer_t * layer, lv_draw_letter_dsc_t * dsc, const lv_point_t * point) +void lv_draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords, lv_draw_glyph_cb_t cb) +void lv_draw_unit_draw_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * dsc, const lv_point_t * pos, const lv_font_t * font, uint32_t letter, lv_draw_glyph_cb_t cb) // ../../lvgl/src/draw/lv_draw_line.h void lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc) @@ -611,10 +655,13 @@ void lv_draw_mask_rect(lv_layer_t * layer, const lv_draw_mask_rect_dsc_t * dsc) void lv_draw_rect_dsc_init(lv_draw_rect_dsc_t * dsc) void lv_draw_fill_dsc_init(lv_draw_fill_dsc_t * dsc) lv_draw_fill_dsc_t * lv_draw_task_get_fill_dsc(lv_draw_task_t * task) +void lv_draw_fill(lv_layer_t * layer, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords) void lv_draw_border_dsc_init(lv_draw_border_dsc_t * dsc) lv_draw_border_dsc_t * lv_draw_task_get_border_dsc(lv_draw_task_t * task) +void lv_draw_border(lv_layer_t * layer, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords) void lv_draw_box_shadow_dsc_init(lv_draw_box_shadow_dsc_t * dsc) lv_draw_box_shadow_dsc_t * lv_draw_task_get_box_shadow_dsc(lv_draw_task_t * task) +void lv_draw_box_shadow(lv_layer_t * layer, const lv_draw_box_shadow_dsc_t * dsc, const lv_area_t * coords) void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords) // ../../lvgl/src/draw/lv_draw_triangle.h @@ -624,11 +671,15 @@ void lv_draw_triangle(lv_layer_t * layer, const lv_draw_triangle_dsc_t * draw_ds // ../../lvgl/src/font/lv_font.h const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf) +const void * lv_font_get_glyph_static_bitmap(lv_font_glyph_dsc_t * g_dsc) 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) 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) +const lv_font_t * lv_font_get_default(void) +bool lv_font_info_is_equal(const lv_font_info_t * ft_info_1, const lv_font_info_t * ft_info_2) +bool lv_font_has_static_bitmap(const lv_font_t * font) // ../../lvgl/src/indev/lv_indev.h lv_indev_t * lv_indev_create(void) @@ -642,8 +693,9 @@ 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_long_press_repeat_time(lv_indev_t * indev, uint16_t long_press_repeat_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) @@ -663,9 +715,11 @@ void lv_indev_set_button_points(lv_indev_t * indev, const lv_point_t points[]) void lv_indev_get_point(const lv_indev_t * indev, lv_point_t * point) lv_dir_t lv_indev_get_gesture_dir(const lv_indev_t * indev) uint32_t lv_indev_get_key(const lv_indev_t * indev) +uint8_t lv_indev_get_short_click_streak(const lv_indev_t * indev) lv_dir_t lv_indev_get_scroll_dir(const lv_indev_t * indev) lv_obj_t * lv_indev_get_scroll_obj(const lv_indev_t * indev) void lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point) +lv_obj_t * lv_indev_get_cursor(lv_indev_t * indev) void lv_indev_wait_release(lv_indev_t * indev) lv_obj_t * lv_indev_get_active_obj(void) lv_timer_t * lv_indev_get_read_timer(lv_indev_t * indev) @@ -713,8 +767,11 @@ void lv_anim_init(lv_anim_t * a) 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_resume(lv_anim_t * a) +void lv_anim_pause(lv_anim_t * a) +void lv_anim_pause_for(lv_anim_t * a, uint32_t ms) +bool lv_anim_is_paused(lv_anim_t * a) 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) @@ -722,9 +779,9 @@ 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_reverse_duration(lv_anim_t * a, uint32_t duration) +void lv_anim_set_reverse_time(lv_anim_t * a, uint32_t duration) +void lv_anim_set_reverse_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) @@ -745,6 +802,7 @@ 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_resolve_speed(uint32_t speed, int32_t start, int32_t end) uint32_t lv_anim_speed_to_time(uint32_t speed, int32_t start, int32_t end) void lv_anim_refr_now(void) @@ -798,12 +856,15 @@ 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) +static inline uint16_t lv_color_swap_16(uint16_t c) // ../../lvgl/src/misc/lv_color_op.h 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) +lv_color32_t lv_color_mix32_premultiplied(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) +lv_color32_t lv_color_over32(lv_color32_t fg, lv_color32_t bg) // ../../lvgl/src/misc/lv_event.h lv_result_t lv_event_send(lv_event_list_t * list, lv_event_t * e, bool preprocess) @@ -823,6 +884,7 @@ void * lv_event_get_user_data(lv_event_t * e) void lv_event_stop_bubbling(lv_event_t * e) void lv_event_stop_processing(lv_event_t * e) uint32_t lv_event_register_id(void) +const char * lv_event_code_get_name(lv_event_code_t code) // ../../lvgl/src/misc/lv_palette.h lv_color_t lv_palette_main(lv_palette_t p) @@ -832,6 +894,7 @@ lv_color_t lv_palette_darken(lv_palette_t p, uint8_t lvl) // ../../lvgl/src/misc/lv_style.h void lv_style_init(lv_style_t * style) void lv_style_reset(lv_style_t * style) +void lv_style_copy(lv_style_t * dst, const lv_style_t * src) static inline bool lv_style_is_const(const lv_style_t * style) lv_style_prop_t lv_style_register_prop(uint8_t flag) lv_style_prop_t lv_style_get_num_custom_props(void) @@ -849,6 +912,9 @@ 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) static inline void lv_style_set_pad_ver(lv_style_t * style, int32_t value) static inline void lv_style_set_pad_gap(lv_style_t * style, int32_t value) +static inline void lv_style_set_margin_hor(lv_style_t * style, int32_t value) +static inline void lv_style_set_margin_ver(lv_style_t * style, int32_t value) +static inline void lv_style_set_margin_all(lv_style_t * style, int32_t value) static inline void lv_style_set_transform_scale(lv_style_t * style, int32_t value) static inline bool lv_style_prop_has_flag(lv_style_prop_t prop, uint8_t flag) @@ -867,6 +933,7 @@ void lv_style_set_transform_width(lv_style_t * style, int32_t value) void lv_style_set_transform_height(lv_style_t * style, int32_t value) void lv_style_set_translate_x(lv_style_t * style, int32_t value) void lv_style_set_translate_y(lv_style_t * style, int32_t value) +void lv_style_set_translate_radial(lv_style_t * style, int32_t value) void lv_style_set_transform_scale_x(lv_style_t * style, int32_t value) void lv_style_set_transform_scale_y(lv_style_t * style, int32_t value) void lv_style_set_transform_rotation(lv_style_t * style, int32_t value) @@ -880,6 +947,7 @@ void lv_style_set_pad_left(lv_style_t * style, int32_t value) void lv_style_set_pad_right(lv_style_t * style, int32_t value) void lv_style_set_pad_row(lv_style_t * style, int32_t value) void lv_style_set_pad_column(lv_style_t * style, int32_t value) +void lv_style_set_pad_radial(lv_style_t * style, int32_t value) void lv_style_set_margin_top(lv_style_t * style, int32_t value) void lv_style_set_margin_bottom(lv_style_t * style, int32_t value) void lv_style_set_margin_left(lv_style_t * style, int32_t value) @@ -934,12 +1002,18 @@ void lv_style_set_text_letter_space(lv_style_t * style, int32_t value) void lv_style_set_text_line_space(lv_style_t * style, int32_t value) void lv_style_set_text_decor(lv_style_t * style, lv_text_decor_t value) void lv_style_set_text_align(lv_style_t * style, lv_text_align_t value) +void lv_style_set_text_outline_stroke_color(lv_style_t * style, lv_color_t value) +void lv_style_set_text_outline_stroke_width(lv_style_t * style, int32_t value) +void lv_style_set_text_outline_stroke_opa(lv_style_t * style, lv_opa_t value) void lv_style_set_radius(lv_style_t * style, int32_t value) +void lv_style_set_radial_offset(lv_style_t * style, int32_t value) void lv_style_set_clip_corner(lv_style_t * style, bool value) void lv_style_set_opa(lv_style_t * style, lv_opa_t value) void lv_style_set_opa_layered(lv_style_t * style, lv_opa_t value) void lv_style_set_color_filter_dsc(lv_style_t * style, const lv_color_filter_dsc_t * value) void lv_style_set_color_filter_opa(lv_style_t * style, lv_opa_t value) +void lv_style_set_recolor(lv_style_t * style, lv_color_t value) +void lv_style_set_recolor_opa(lv_style_t * style, lv_opa_t value) void lv_style_set_anim(lv_style_t * style, const lv_anim_t * value) void lv_style_set_anim_duration(lv_style_t * style, uint32_t value) void lv_style_set_transition(lv_style_t * style, const lv_style_transition_dsc_t * value) @@ -967,6 +1041,8 @@ 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) +int32_t lv_text_get_width_with_flags(const char * txt, uint32_t length, const lv_font_t * font, int32_t letter_space, lv_text_flag_t flags) +bool lv_text_is_cmd(lv_text_cmd_state_t * state, uint32_t c) // ../../lvgl/src/misc/lv_timer.h uint32_t lv_timer_handler(void) @@ -1005,15 +1081,21 @@ lv_color_t lv_theme_get_color_secondary(lv_obj_t * obj) // ../../lvgl/src/widgets/animimage/lv_animimage.h lv_obj_t * lv_animimg_create(lv_obj_t * parent) -void lv_animimg_set_src(lv_obj_t * img, const void * dsc[], size_t num) +void lv_animimg_set_src(lv_obj_t * obj, const void * dsc[], size_t num) +void lv_animimg_set_src_reverse(lv_obj_t * obj, const void * dsc[], size_t num) void lv_animimg_start(lv_obj_t * obj) -void lv_animimg_set_duration(lv_obj_t * img, uint32_t duration) -void lv_animimg_set_repeat_count(lv_obj_t * img, uint32_t count) -const void ** lv_animimg_get_src(lv_obj_t * img) -uint8_t lv_animimg_get_src_count(lv_obj_t * img) -uint32_t lv_animimg_get_duration(lv_obj_t * img) -uint32_t lv_animimg_get_repeat_count(lv_obj_t * img) -lv_anim_t * lv_animimg_get_anim(lv_obj_t * img) +bool lv_animimg_delete(lv_obj_t * obj) +void lv_animimg_set_duration(lv_obj_t * obj, uint32_t duration) +void lv_animimg_set_repeat_count(lv_obj_t * obj, uint32_t count) +void lv_animimg_set_reverse_duration(lv_obj_t * obj, uint32_t duration) +void lv_animimg_set_reverse_delay(lv_obj_t * obj, uint32_t duration) +void lv_animimg_set_start_cb(lv_obj_t * obj, lv_anim_start_cb_t start_cb) +void lv_animimg_set_completed_cb(lv_obj_t * obj, lv_anim_completed_cb_t completed_cb) +const void ** lv_animimg_get_src(lv_obj_t * obj) +uint8_t lv_animimg_get_src_count(lv_obj_t * obj) +uint32_t lv_animimg_get_duration(lv_obj_t * obj) +uint32_t lv_animimg_get_repeat_count(lv_obj_t * obj) +lv_anim_t * lv_animimg_get_anim(lv_obj_t * obj) // ../../lvgl/src/widgets/arc/lv_arc.h lv_obj_t * lv_arc_create(lv_obj_t * parent) @@ -1080,7 +1162,7 @@ bool lv_buttonmatrix_get_one_checked(const lv_obj_t * obj) // ../../lvgl/src/widgets/calendar/lv_calendar.h lv_obj_t * lv_calendar_create(lv_obj_t * parent) void lv_calendar_set_today_date(lv_obj_t * obj, uint32_t year, uint32_t month, uint32_t day) -void lv_calendar_set_showed_date(lv_obj_t * obj, uint32_t year, uint32_t month) +void lv_calendar_set_month_shown(lv_obj_t * obj, uint32_t year, uint32_t month) void lv_calendar_set_highlighted_dates(lv_obj_t * obj, lv_calendar_date_t highlighted[], size_t date_num) void lv_calendar_set_day_names(lv_obj_t * obj, const char ** day_names) lv_obj_t * lv_calendar_get_btnmatrix(const lv_obj_t * obj) @@ -1096,10 +1178,10 @@ const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian) void lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian_time, lv_calendar_chinese_t * chinese_time) // ../../lvgl/src/widgets/calendar/lv_calendar_header_arrow.h -lv_obj_t * lv_calendar_header_arrow_create(lv_obj_t * parent) +lv_obj_t * lv_calendar_add_header_arrow(lv_obj_t * parent) // ../../lvgl/src/widgets/calendar/lv_calendar_header_dropdown.h -lv_obj_t * lv_calendar_header_dropdown_create(lv_obj_t * parent) +lv_obj_t * lv_calendar_add_header_dropdown(lv_obj_t * parent) void lv_calendar_header_dropdown_set_year_list(lv_obj_t * parent, const char * years_list) // ../../lvgl/src/widgets/canvas/lv_canvas.h @@ -1122,7 +1204,7 @@ uint32_t lv_canvas_buf_size(int32_t w, int32_t h, uint8_t bpp, uint8_t stride) lv_obj_t * lv_chart_create(lv_obj_t * parent) void lv_chart_set_type(lv_obj_t * obj, lv_chart_type_t type) void lv_chart_set_point_count(lv_obj_t * obj, uint32_t cnt) -void lv_chart_set_range(lv_obj_t * obj, lv_chart_axis_t axis, int32_t min, int32_t max) +void lv_chart_set_axis_range(lv_obj_t * obj, lv_chart_axis_t axis, int32_t min, int32_t max) void lv_chart_set_update_mode(lv_obj_t * obj, lv_chart_update_mode_t update_mode) void lv_chart_set_div_line_count(lv_obj_t * obj, uint8_t hdiv, uint8_t vdiv) lv_chart_type_t lv_chart_get_type(const lv_obj_t * obj) @@ -1139,17 +1221,21 @@ void lv_chart_set_x_start_point(lv_obj_t * obj, lv_chart_series_t * ser, uint32_ 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) void lv_chart_set_cursor_pos(lv_obj_t * chart, lv_chart_cursor_t * cursor, lv_point_t * pos) +void lv_chart_set_cursor_pos_x(lv_obj_t * chart, lv_chart_cursor_t * cursor, int32_t x) +void lv_chart_set_cursor_pos_y(lv_obj_t * chart, lv_chart_cursor_t * cursor, int32_t y) void lv_chart_set_cursor_point(lv_obj_t * chart, lv_chart_cursor_t * cursor, lv_chart_series_t * ser, uint32_t point_id) lv_point_t lv_chart_get_cursor_point(lv_obj_t * chart, lv_chart_cursor_t * cursor) -void lv_chart_set_all_value(lv_obj_t * obj, lv_chart_series_t * ser, int32_t value) +void lv_chart_set_all_values(lv_obj_t * obj, lv_chart_series_t * ser, int32_t value) void lv_chart_set_next_value(lv_obj_t * obj, lv_chart_series_t * ser, int32_t value) void lv_chart_set_next_value2(lv_obj_t * obj, lv_chart_series_t * ser, int32_t x_value, int32_t y_value) -void lv_chart_set_value_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id, int32_t value) -void lv_chart_set_value_by_id2(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id, int32_t x_value, int32_t y_value) -void lv_chart_set_ext_y_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t array[]) -void lv_chart_set_ext_x_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t array[]) -int32_t * lv_chart_get_y_array(const lv_obj_t * obj, lv_chart_series_t * ser) -int32_t * lv_chart_get_x_array(const lv_obj_t * obj, lv_chart_series_t * ser) +void lv_chart_set_series_values(lv_obj_t * obj, lv_chart_series_t * ser, const int32_t values[], size_t values_cnt) +void lv_chart_set_series_values2(lv_obj_t * obj, lv_chart_series_t * ser, const int32_t x_values[], const int32_t y_values[], size_t values_cnt) +void lv_chart_set_series_value_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id, int32_t value) +void lv_chart_set_series_value_by_id2(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id, int32_t x_value, int32_t y_value) +void lv_chart_set_series_ext_y_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t array[]) +void lv_chart_set_series_ext_x_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t array[]) +int32_t * lv_chart_get_series_y_array(const lv_obj_t * obj, lv_chart_series_t * ser) +int32_t * lv_chart_get_series_x_array(const lv_obj_t * obj, lv_chart_series_t * ser) uint32_t lv_chart_get_pressed_point(const lv_obj_t * obj) int32_t lv_chart_get_first_point_center_offset(lv_obj_t * obj) @@ -1206,6 +1292,10 @@ void lv_image_get_pivot(lv_obj_t * obj, lv_point_t * pivot) int32_t lv_image_get_scale(lv_obj_t * obj) int32_t lv_image_get_scale_x(lv_obj_t * obj) int32_t lv_image_get_scale_y(lv_obj_t * obj) +int32_t lv_image_get_src_width(lv_obj_t * obj) +int32_t lv_image_get_src_height(lv_obj_t * obj) +int32_t lv_image_get_transformed_width(lv_obj_t * obj) +int32_t lv_image_get_transformed_height(lv_obj_t * obj) lv_blend_mode_t lv_image_get_blend_mode(lv_obj_t * obj) bool lv_image_get_antialias(lv_obj_t * obj) lv_image_align_t lv_image_get_inner_align(lv_obj_t * obj) @@ -1237,6 +1327,7 @@ void lv_label_set_text_static(lv_obj_t * obj, const char * text) void lv_label_set_long_mode(lv_obj_t * obj, lv_label_long_mode_t long_mode) void lv_label_set_text_selection_start(lv_obj_t * obj, uint32_t index) void lv_label_set_text_selection_end(lv_obj_t * obj, uint32_t index) +void lv_label_set_recolor(lv_obj_t * obj, bool en) char * lv_label_get_text(const lv_obj_t * obj) lv_label_long_mode_t lv_label_get_long_mode(const lv_obj_t * obj) void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t * pos) @@ -1244,6 +1335,7 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) uint32_t lv_label_get_text_selection_start(const lv_obj_t * obj) uint32_t lv_label_get_text_selection_end(const lv_obj_t * obj) +bool lv_label_get_recolor(const lv_obj_t * obj) void lv_label_ins_text(lv_obj_t * obj, uint32_t pos, const char * txt) void lv_label_cut_text(lv_obj_t * obj, uint32_t pos, uint32_t cnt) @@ -1276,7 +1368,7 @@ void lv_list_set_button_text(lv_obj_t * list, lv_obj_t * btn, const char * txt) // ../../lvgl/src/widgets/menu/lv_menu.h lv_obj_t * lv_menu_create(lv_obj_t * parent) -lv_obj_t * lv_menu_page_create(lv_obj_t * parent, char const * const title) +lv_obj_t * lv_menu_page_create(lv_obj_t * menu, char const * const title) lv_obj_t * lv_menu_cont_create(lv_obj_t * parent) lv_obj_t * lv_menu_section_create(lv_obj_t * parent) lv_obj_t * lv_menu_separator_create(lv_obj_t * parent) @@ -1316,6 +1408,7 @@ void lv_msgbox_close_async(lv_obj_t * mbox) lv_obj_t * lv_roller_create(lv_obj_t * parent) void lv_roller_set_options(lv_obj_t * obj, const char * options, lv_roller_mode_t mode) void lv_roller_set_selected(lv_obj_t * obj, uint32_t sel_opt, lv_anim_enable_t anim) +bool lv_roller_set_selected_str(lv_obj_t * obj, const char * sel_opt, lv_anim_enable_t anim) void lv_roller_set_visible_row_count(lv_obj_t * obj, uint32_t row_cnt) uint32_t lv_roller_get_selected(const lv_obj_t * obj) void lv_roller_get_selected_str(const lv_obj_t * obj, char * buf, uint32_t buf_size) @@ -1337,11 +1430,16 @@ 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_range(lv_scale_section_t * section, int32_t min, int32_t max) +void lv_scale_set_section_range(lv_obj_t * scale, lv_scale_section_t * section, int32_t min, int32_t max) void lv_scale_section_set_style(lv_scale_section_t * section, lv_part_t part, lv_style_t * section_part_style) +void lv_scale_set_section_style_main(lv_obj_t * scale, lv_scale_section_t * section, const lv_style_t * style) +void lv_scale_set_section_style_indicator(lv_obj_t * scale, lv_scale_section_t * section, const lv_style_t * style) +void lv_scale_set_section_style_items(lv_obj_t * scale, lv_scale_section_t * section, const lv_style_t * 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) +int32_t lv_scale_get_rotation(lv_obj_t * obj) bool lv_scale_get_label_show(lv_obj_t * obj) uint32_t lv_scale_get_angle_range(lv_obj_t * obj) int32_t lv_scale_get_range_min_value(lv_obj_t * obj) @@ -1350,31 +1448,38 @@ 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) 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_start_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) +void lv_slider_set_orientation(lv_obj_t * obj, lv_slider_orientation_t orientation) 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) lv_slider_mode_t lv_slider_get_mode(lv_obj_t * slider) +lv_slider_orientation_t lv_slider_get_orientation(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) void lv_span_stack_deinit(void) lv_obj_t * lv_spangroup_create(lv_obj_t * parent) -lv_span_t * lv_spangroup_new_span(lv_obj_t * obj) +lv_span_t * lv_spangroup_add_span(lv_obj_t * obj) void lv_spangroup_delete_span(lv_obj_t * obj, lv_span_t * span) void lv_span_set_text(lv_span_t * span, const char * text) void lv_span_set_text_static(lv_span_t * span, const char * text) +void lv_spangroup_set_span_text(lv_obj_t * obj, lv_span_t * span, const char * text) +void lv_spangroup_set_span_text_static(lv_obj_t * obj, lv_span_t * span, const char * text) +void lv_span_set_text_static(lv_span_t * span, const char * text) +void lv_spangroup_set_span_style(lv_obj_t * obj, lv_span_t * span, const lv_style_t * style) void lv_spangroup_set_align(lv_obj_t * obj, lv_text_align_t align) 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) +const char * lv_span_get_text(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) @@ -1385,7 +1490,9 @@ int32_t lv_spangroup_get_max_lines(lv_obj_t * obj) int32_t lv_spangroup_get_max_line_height(lv_obj_t * obj) uint32_t lv_spangroup_get_expand_width(lv_obj_t * obj, uint32_t max_width) int32_t lv_spangroup_get_expand_height(lv_obj_t * obj, int32_t width) -void lv_spangroup_refr_mode(lv_obj_t * obj) +lv_span_coords_t lv_spangroup_get_span_coords(lv_obj_t * obj, const lv_span_t * span) +lv_span_t * lv_spangroup_get_span_by_point(lv_obj_t * obj, const lv_point_t * point) +void lv_spangroup_refresh(lv_obj_t * obj) // ../../lvgl/src/widgets/spinbox/lv_spinbox.h lv_obj_t * lv_spinbox_create(lv_obj_t * parent) @@ -1410,6 +1517,8 @@ void lv_spinner_set_anim_params(lv_obj_t * obj, uint32_t t, uint32_t angle) // ../../lvgl/src/widgets/switch/lv_switch.h lv_obj_t * lv_switch_create(lv_obj_t * parent) +void lv_switch_set_orientation(lv_obj_t * obj, lv_switch_orientation_t orientation) +lv_switch_orientation_t lv_switch_get_orientation(lv_obj_t * obj) // ../../lvgl/src/widgets/table/lv_table.h lv_obj_t * lv_table_create(lv_obj_t * parent) @@ -1418,7 +1527,7 @@ void lv_table_set_cell_value_fmt(lv_obj_t * obj, uint32_t row, uint32_t col, con void lv_table_set_row_count(lv_obj_t * obj, uint32_t row_cnt) void lv_table_set_column_count(lv_obj_t * obj, uint32_t col_cnt) 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_set_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) 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 5f7a712de..c4fdb10fb 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 @@ -41,6 +41,16 @@ const be_ctypes_structure_t be_lv_area = { { "y2", 12, 0, 0, ctypes_i32, 0 }, }}; +const be_ctypes_structure_t be_lv_grad_stop = { + 8, /* size in bytes */ + 3, /* number of elements */ + be_ctypes_instance_mappings, + (const be_ctypes_structure_item_t[3]) { + { "color", 0, 0, 0, ctypes_u24, 1 }, + { "frac", 4, 0, 0, ctypes_u8, 0 }, + { "opa", 3, 0, 0, ctypes_u8, 0 }, +}}; + const be_ctypes_structure_t be_lv_gradient_stop = { 8, /* size in bytes */ 3, /* number of elements */ @@ -56,8 +66,8 @@ const be_ctypes_structure_t be_lv_grad_dsc = { 9, /* number of elements */ be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[9]) { - { "dir", 11, 0, 3, ctypes_bf, 0 }, - { "extend", 11, 3, 2, ctypes_bf, 0 }, + { "dir", 11, 0, 4, ctypes_bf, 0 }, + { "extend", 11, 4, 3, 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 }, @@ -94,8 +104,8 @@ const be_ctypes_structure_t be_lv_draw_rect_dsc = { { "base_part", 4, 0, 0, ctypes_u32, 0 }, { "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_dir", 47, 0, 4, ctypes_bf, 0 }, + { "bg_grad_extend", 47, 4, 3, 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 }, @@ -130,9 +140,9 @@ const be_ctypes_structure_t be_lv_draw_rect_dsc = { const be_ctypes_structure_t be_lv_draw_line_dsc = { 64, /* size in bytes */ - 20, /* number of elements */ + 19, /* number of elements */ be_ctypes_instance_mappings, - (const be_ctypes_structure_item_t[20]) { + (const be_ctypes_structure_item_t[19]) { { "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 }, @@ -140,7 +150,6 @@ const be_ctypes_structure_t be_lv_draw_line_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 }, - { "blend_mode", 61, 0, 2, ctypes_bf, 0 }, { "color", 44, 0, 0, ctypes_u24, 1 }, { "dash_gap", 56, 0, 0, ctypes_i32, 0 }, { "dash_width", 52, 0, 0, ctypes_i32, 0 }, @@ -149,9 +158,9 @@ const be_ctypes_structure_t be_lv_draw_line_dsc = { { "p1_y", 32, 0, 0, ctypes_i32, 0 }, { "p2_x", 36, 0, 0, ctypes_i32, 0 }, { "p2_y", 40, 0, 0, ctypes_i32, 0 }, - { "raw_end", 61, 4, 1, ctypes_bf, 0 }, - { "round_end", 61, 3, 1, ctypes_bf, 0 }, - { "round_start", 61, 2, 1, ctypes_bf, 0 }, + { "raw_end", 61, 2, 1, ctypes_bf, 0 }, + { "round_end", 61, 1, 1, ctypes_bf, 0 }, + { "round_start", 61, 0, 1, ctypes_bf, 0 }, { "width", 48, 0, 0, ctypes_i32, 0 }, }}; @@ -198,7 +207,7 @@ const be_ctypes_structure_t be_lv_draw_image_dsc = { 35, /* number of elements */ be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[35]) { - { "antialias", 77, 4, 1, ctypes_bf, 0 }, + { "antialias", 81, 4, 1, ctypes_bf, 0 }, { "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 }, @@ -207,8 +216,8 @@ const be_ctypes_structure_t be_lv_draw_image_dsc = { { "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 }, + { "blend_mode", 81, 0, 4, ctypes_bf, 0 }, + { "clip_radius", 44, 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 }, @@ -216,31 +225,31 @@ 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 }, - { "pivot_x", 64, 0, 0, ctypes_i32, 0 }, - { "pivot_y", 68, 0, 0, ctypes_i32, 0 }, - { "recolor", 72, 0, 0, ctypes_u24, 1 }, - { "recolor_opa", 75, 0, 0, ctypes_u8, 0 }, - { "rotation", 44, 0, 0, ctypes_i32, 0 }, - { "scale_x", 48, 0, 0, ctypes_i32, 0 }, - { "scale_y", 52, 0, 0, ctypes_i32, 0 }, - { "skew_x", 56, 0, 0, ctypes_i32, 0 }, - { "skew_y", 60, 0, 0, ctypes_i32, 0 }, + { "image_area_x1", 88, 0, 0, ctypes_i32, 0 }, + { "image_area_x2", 96, 0, 0, ctypes_i32, 0 }, + { "image_area_y1", 92, 0, 0, ctypes_i32, 0 }, + { "image_area_y2", 100, 0, 0, ctypes_i32, 0 }, + { "opa", 80, 0, 0, ctypes_u8, 0 }, + { "pivot_x", 68, 0, 0, ctypes_i32, 0 }, + { "pivot_y", 72, 0, 0, ctypes_i32, 0 }, + { "recolor", 76, 0, 0, ctypes_u24, 1 }, + { "recolor_opa", 79, 0, 0, ctypes_u8, 0 }, + { "rotation", 48, 0, 0, ctypes_i32, 0 }, + { "scale_x", 52, 0, 0, ctypes_i32, 0 }, + { "scale_y", 56, 0, 0, ctypes_i32, 0 }, + { "skew_x", 60, 0, 0, ctypes_i32, 0 }, + { "skew_y", 64, 0, 0, ctypes_i32, 0 }, { "src", 28, 0, 0, ctypes_ptr32, 0 }, - { "sup", 80, 0, 0, ctypes_ptr32, 0 }, - { "tile", 77, 5, 1, ctypes_bf, 0 }, + { "sup", 84, 0, 0, ctypes_ptr32, 0 }, + { "tile", 81, 5, 1, ctypes_bf, 0 }, }}; const be_ctypes_structure_t be_lv_draw_label_dsc = { - 84, /* size in bytes */ - 26, /* number of elements */ + 108, /* size in bytes */ + 35, /* number of elements */ be_ctypes_instance_mappings, - (const be_ctypes_structure_item_t[26]) { - { "align", 74, 0, 0, ctypes_u8, 0 }, + (const be_ctypes_structure_item_t[35]) { + { "align", 89, 0, 0, ctypes_u8, 0 }, { "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 }, @@ -248,24 +257,33 @@ const be_ctypes_structure_t be_lv_draw_label_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 }, - { "bidi_dir", 73, 0, 0, ctypes_u8, 0 }, - { "blend_mode", 76, 3, 3, ctypes_bf, 0 }, + { "bidi_dir", 90, 0, 0, ctypes_u8, 0 }, + { "blend_mode", 93, 0, 3, ctypes_bf, 0 }, { "color", 44, 0, 0, ctypes_u24, 1 }, - { "decor", 76, 0, 3, ctypes_bf, 0 }, - { "flag", 75, 0, 0, ctypes_u8, 0 }, - { "font", 32, 0, 0, ctypes_ptr32, 0 }, - { "hint", 80, 0, 0, ctypes_ptr32, 0 }, - { "letter_space", 60, 0, 0, ctypes_i32, 0 }, - { "line_space", 56, 0, 0, ctypes_i32, 0 }, - { "ofs_x", 64, 0, 0, ctypes_i32, 0 }, - { "ofs_y", 68, 0, 0, ctypes_i32, 0 }, - { "opa", 72, 0, 0, ctypes_u8, 0 }, - { "sel_bg_color", 50, 0, 0, ctypes_u24, 1 }, - { "sel_color", 47, 0, 0, ctypes_u24, 1 }, - { "sel_end", 40, 0, 0, ctypes_u32, 0 }, - { "sel_start", 36, 0, 0, ctypes_u32, 0 }, + { "decor", 92, 0, 3, ctypes_bf, 0 }, + { "flag", 92, 3, 5, ctypes_bf, 0 }, + { "font", 40, 0, 0, ctypes_ptr32, 0 }, + { "has_bided", 93, 5, 1, ctypes_bf, 0 }, + { "hint", 96, 0, 0, ctypes_ptr32, 0 }, + { "letter_space", 52, 0, 0, ctypes_i32, 0 }, + { "line_space", 48, 0, 0, ctypes_i32, 0 }, + { "ofs_x", 56, 0, 0, ctypes_i32, 0 }, + { "ofs_y", 60, 0, 0, ctypes_i32, 0 }, + { "opa", 88, 0, 0, ctypes_u8, 0 }, + { "outline_stroke_color", 101, 0, 0, ctypes_u24, 1 }, + { "outline_stroke_opa", 100, 0, 0, ctypes_u8, 0 }, + { "outline_stroke_width", 104, 0, 0, ctypes_i32, 0 }, + { "rotation", 64, 0, 0, ctypes_i32, 0 }, + { "sel_bg_color", 79, 0, 0, ctypes_u24, 1 }, + { "sel_color", 76, 0, 0, ctypes_u24, 1 }, + { "sel_end", 72, 0, 0, ctypes_u32, 0 }, + { "sel_start", 68, 0, 0, ctypes_u32, 0 }, { "text", 28, 0, 0, ctypes_ptr32, 0 }, - { "text_local", 76, 6, 1, ctypes_bf, 0 }, + { "text_length", 84, 0, 0, ctypes_u32, 0 }, + { "text_local", 93, 3, 1, ctypes_bf, 0 }, + { "text_size_x", 32, 0, 0, ctypes_i32, 0 }, + { "text_size_y", 36, 0, 0, ctypes_i32, 0 }, + { "text_static", 93, 4, 1, ctypes_bf, 0 }, }}; const be_ctypes_structure_t be_lv_chart_series = { @@ -334,10 +352,10 @@ const be_ctypes_structure_t be_lv_event = { }}; const be_ctypes_structure_t be_lv_image_dsc = { - 24, /* size in bytes */ - 10, /* number of elements */ + 28, /* size in bytes */ + 11, /* number of elements */ be_ctypes_instance_mappings, - (const be_ctypes_structure_item_t[10]) { + (const be_ctypes_structure_item_t[11]) { { "data", 16, 0, 0, ctypes_ptr32, 0 }, { "data_size", 12, 0, 0, ctypes_u32, 0 }, { "header_cf", 1, 0, 0, ctypes_u8, 0 }, @@ -348,6 +366,7 @@ const be_ctypes_structure_t be_lv_image_dsc = { { "header_stride", 8, 0, 0, ctypes_u16, 0 }, { "header_w", 4, 0, 0, ctypes_u16, 0 }, { "reserved", 20, 0, 0, ctypes_ptr32, 0 }, + { "reserved_2", 24, 0, 0, ctypes_ptr32, 0 }, }}; const be_ctypes_structure_t be_lv_style_transition_dsc = { @@ -363,10 +382,10 @@ const be_ctypes_structure_t be_lv_style_transition_dsc = { }}; const be_ctypes_structure_t be_lv_layer = { - 72, /* size in bytes */ - 18, /* number of elements */ + 84, /* size in bytes */ + 21, /* number of elements */ be_ctypes_instance_mappings, - (const be_ctypes_structure_item_t[18]) { + (const be_ctypes_structure_item_t[21]) { { "_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 }, @@ -377,14 +396,17 @@ const be_ctypes_structure_t be_lv_layer = { { "buf_area_y2", 16, 0, 0, ctypes_i32, 0 }, { "color_format", 20, 0, 0, ctypes_u32, 0 }, { "draw_buf", 0, 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 }, + { "draw_task_head", 68, 0, 0, ctypes_ptr32, 0 }, + { "next", 76, 0, 0, ctypes_ptr32, 0 }, + { "opa", 56, 0, 0, ctypes_u8, 0 }, + { "parent", 72, 0, 0, ctypes_ptr32, 0 }, + { "partial_y_offset", 64, 0, 0, ctypes_i32, 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 }, + { "recolor", 60, 0, 0, ctypes_u32, 0 }, + { "user_data", 80, 0, 0, ctypes_ptr32, 0 }, }}; const be_ctypes_structure_t be_lv_color_filter_dsc = { @@ -432,6 +454,68 @@ const be_ctypes_structure_t be_lv_ts_calibration = { { "y", 12, 0, 0, ctypes_i32, 0 }, }}; +const be_ctypes_structure_t be_lv_span_coords = { + 48, /* size in bytes */ + 12, /* number of elements */ + be_ctypes_instance_mappings, + (const be_ctypes_structure_item_t[12]) { + { "heading_x1", 0, 0, 0, ctypes_i32, 0 }, + { "heading_x2", 8, 0, 0, ctypes_i32, 0 }, + { "heading_y1", 4, 0, 0, ctypes_i32, 0 }, + { "heading_y2", 12, 0, 0, ctypes_i32, 0 }, + { "middle_x1", 16, 0, 0, ctypes_i32, 0 }, + { "middle_x2", 24, 0, 0, ctypes_i32, 0 }, + { "middle_y1", 20, 0, 0, ctypes_i32, 0 }, + { "middle_y2", 28, 0, 0, ctypes_i32, 0 }, + { "trailing_x1", 32, 0, 0, ctypes_i32, 0 }, + { "trailing_x2", 40, 0, 0, ctypes_i32, 0 }, + { "trailing_y1", 36, 0, 0, ctypes_i32, 0 }, + { "trailing_y2", 44, 0, 0, ctypes_i32, 0 }, +}}; + +const be_ctypes_structure_t be_lv_font_info = { + 24, /* size in bytes */ + 6, /* number of elements */ + be_ctypes_instance_mappings, + (const be_ctypes_structure_item_t[6]) { + { "class_p", 4, 0, 0, ctypes_ptr32, 0 }, + { "kerning", 20, 0, 0, ctypes_u32, 0 }, + { "name", 0, 0, 0, ctypes_ptr32, 0 }, + { "render_mode", 12, 0, 0, ctypes_u32, 0 }, + { "size", 8, 0, 0, ctypes_u32, 0 }, + { "style", 16, 0, 0, ctypes_u32, 0 }, +}}; + +const be_ctypes_structure_t be_lv_draw_letter_dsc = { + 80, /* size in bytes */ + 23, /* number of elements */ + be_ctypes_instance_mappings, + (const be_ctypes_structure_item_t[23]) { + { "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 }, + { "base_layer", 16, 0, 0, ctypes_ptr32, 0 }, + { "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 }, + { "blend_mode", 69, 3, 3, ctypes_bf, 0 }, + { "color", 36, 0, 0, ctypes_u24, 1 }, + { "decor", 69, 0, 3, ctypes_bf, 0 }, + { "font", 32, 0, 0, ctypes_ptr32, 0 }, + { "opa", 68, 0, 0, ctypes_u8, 0 }, + { "outline_stroke_color", 76, 0, 0, ctypes_u24, 1 }, + { "outline_stroke_opa", 70, 0, 0, ctypes_u8, 0 }, + { "outline_stroke_width", 72, 0, 0, ctypes_i32, 0 }, + { "pivot_x", 60, 0, 0, ctypes_i32, 0 }, + { "pivot_y", 64, 0, 0, ctypes_i32, 0 }, + { "rotation", 40, 0, 0, ctypes_i32, 0 }, + { "scale_x", 44, 0, 0, ctypes_i32, 0 }, + { "scale_y", 48, 0, 0, ctypes_i32, 0 }, + { "skew_x", 52, 0, 0, ctypes_i32, 0 }, + { "skew_y", 56, 0, 0, ctypes_i32, 0 }, + { "unicode", 28, 0, 0, ctypes_u32, 0 }, +}}; + static const char * be_ctypes_instance_mappings[] = { "lv.color", NULL @@ -445,11 +529,14 @@ static be_define_ctypes_class(lv_draw_arc_dsc, &be_lv_draw_arc_dsc, &be_class_ct static be_define_ctypes_class(lv_draw_dsc_base, &be_lv_draw_dsc_base, &be_class_ctypes_bytes, "lv_draw_dsc_base"); static be_define_ctypes_class(lv_draw_image_dsc, &be_lv_draw_image_dsc, &be_class_ctypes_bytes, "lv_draw_image_dsc"); static be_define_ctypes_class(lv_draw_label_dsc, &be_lv_draw_label_dsc, &be_class_ctypes_bytes, "lv_draw_label_dsc"); +static be_define_ctypes_class(lv_draw_letter_dsc, &be_lv_draw_letter_dsc, &be_class_ctypes_bytes, "lv_draw_letter_dsc"); static be_define_ctypes_class(lv_draw_line_dsc, &be_lv_draw_line_dsc, &be_class_ctypes_bytes, "lv_draw_line_dsc"); static be_define_ctypes_class(lv_draw_rect_dsc, &be_lv_draw_rect_dsc, &be_class_ctypes_bytes, "lv_draw_rect_dsc"); static be_define_ctypes_class(lv_event, &be_lv_event, &be_class_ctypes_bytes, "lv_event"); static be_define_ctypes_class(lv_event_dsc, &be_lv_event_dsc, &be_class_ctypes_bytes, "lv_event_dsc"); +static be_define_ctypes_class(lv_font_info, &be_lv_font_info, &be_class_ctypes_bytes, "lv_font_info"); static be_define_ctypes_class(lv_grad_dsc, &be_lv_grad_dsc, &be_class_ctypes_bytes, "lv_grad_dsc"); +static be_define_ctypes_class(lv_grad_stop, &be_lv_grad_stop, &be_class_ctypes_bytes, "lv_grad_stop"); static be_define_ctypes_class(lv_gradient_stop, &be_lv_gradient_stop, &be_class_ctypes_bytes, "lv_gradient_stop"); static be_define_ctypes_class(lv_image_dsc, &be_lv_image_dsc, &be_class_ctypes_bytes, "lv_image_dsc"); static be_define_ctypes_class(lv_image_header, &be_lv_image_header, &be_class_ctypes_bytes, "lv_image_header"); @@ -457,6 +544,7 @@ static be_define_ctypes_class(lv_layer, &be_lv_layer, &be_class_ctypes_bytes, "l static be_define_ctypes_class(lv_obj_class, &be_lv_obj_class, &be_class_ctypes_bytes, "lv_obj_class"); static be_define_ctypes_class(lv_point, &be_lv_point, &be_class_ctypes_bytes, "lv_point"); static be_define_ctypes_class(lv_point_precise, &be_lv_point_precise, &be_class_ctypes_bytes, "lv_point_precise"); +static be_define_ctypes_class(lv_span_coords, &be_lv_span_coords, &be_class_ctypes_bytes, "lv_span_coords"); static be_define_ctypes_class(lv_style_transition_dsc, &be_lv_style_transition_dsc, &be_class_ctypes_bytes, "lv_style_transition_dsc"); static be_define_ctypes_class(lv_timer_ntv, &be_lv_timer_ntv, &be_class_ctypes_bytes, "lv_timer_ntv"); static be_define_ctypes_class(lv_ts_calibration, &be_lv_ts_calibration, &be_class_ctypes_bytes, "lv_ts_calibration"); @@ -470,11 +558,14 @@ be_ctypes_class_by_name_t be_ctypes_lvgl_classes[] = { { "lv_draw_dsc_base", &be_class_lv_draw_dsc_base }, { "lv_draw_image_dsc", &be_class_lv_draw_image_dsc }, { "lv_draw_label_dsc", &be_class_lv_draw_label_dsc }, + { "lv_draw_letter_dsc", &be_class_lv_draw_letter_dsc }, { "lv_draw_line_dsc", &be_class_lv_draw_line_dsc }, { "lv_draw_rect_dsc", &be_class_lv_draw_rect_dsc }, { "lv_event", &be_class_lv_event }, { "lv_event_dsc", &be_class_lv_event_dsc }, + { "lv_font_info", &be_class_lv_font_info }, { "lv_grad_dsc", &be_class_lv_grad_dsc }, + { "lv_grad_stop", &be_class_lv_grad_stop }, { "lv_gradient_stop", &be_class_lv_gradient_stop }, { "lv_image_dsc", &be_class_lv_image_dsc }, { "lv_image_header", &be_class_lv_image_header }, @@ -482,6 +573,7 @@ be_ctypes_class_by_name_t be_ctypes_lvgl_classes[] = { { "lv_obj_class", &be_class_lv_obj_class }, { "lv_point", &be_class_lv_point }, { "lv_point_precise", &be_class_lv_point_precise }, + { "lv_span_coords", &be_class_lv_span_coords }, { "lv_style_transition_dsc", &be_class_lv_style_transition_dsc }, { "lv_timer_ntv", &be_class_lv_timer_ntv }, { "lv_ts_calibration", &be_class_lv_ts_calibration }, 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 820d5e8cb..148ab33d5 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 @@ -18,6 +18,7 @@ ct.print_types() lv_style_int = ct.i16 lv_color = [ct.u24, "lv.color"] # cast to the class instance, constructor is called with 2 args: (nil, value) +lv_color32 = ct.u32 lv_grad_dir = ct.u8 lv_meter_indicator_type_t = ct.u8 lv_opa = ct.u8 @@ -51,7 +52,7 @@ int32_t = ct.i32 size_t = ct.u32 ptr = ct.ptr32 -lv_point = [ # valid LVGL92 +lv_point = [ # valid LVGL93 [int32_t, "x"], [int32_t, "y"], ] @@ -61,13 +62,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 LVGL92 +lv_point_precise = [ # valid LVGL93 [lv_value_precise, "x"], [lv_value_precise, "y"], ] lv_point_precise = ct.structure(lv_point_precise, "lv_point_precise") -lv_area = [ # valid LVGL92 +lv_area = [ # valid LVGL93 [int32_t, "x1"], [int32_t, "y1"], [int32_t, "x2"], @@ -81,24 +82,49 @@ lv_area = ct.structure(lv_area, "lv_area") # lv_color_t color; /**< The stop color */ # 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 LVGL92 +# } lv_grad_stop_t; +lv_gradient_stop = [ # valid LVGL93 [lv_color, "color"], [lv_opa, "opa"], [uint8_t, "frac"], ] +lv_grad_stop = ct.structure(lv_gradient_stop, "lv_grad_stop") 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_grad_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 : 4; /**< 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_extend_t extend : 3; /**< 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; -lv_grad_dsc = [ # valid LVGL92 +lv_grad_dsc = [ # valid LVGL93 # 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"], @@ -110,22 +136,35 @@ lv_grad_dsc = [ # valid LVGL92 [uint8_t, "stops_1_frac"], [uint8_t, "stops_count"], - [uint8_t_3, "dir"], - [uint8_t_2, "extend"], + [uint8_t_4, "dir"], + [uint8_t_3, "extend"], ] lv_grad_dsc = ct.structure(lv_grad_dsc, "lv_grad_dsc") # typedef struct { +# /**The widget for which draw descriptor was created */ # lv_obj_t * obj; -# uint32_t part; + +# /**The widget part for which draw descriptor was created */ +# lv_part_t part; + +# /**A widget type specific ID (e.g. table row index). See the docs of the given widget.*/ # uint32_t id1; + +# /**A widget type specific ID (e.g. table column index). See the docs of the given widget.*/ # uint32_t id2; + +# /**The target layer */ # lv_layer_t * layer; + +# /**Size of the specific draw descriptor into which this base descriptor is embedded*/ # size_t dsc_size; + +# /**Any custom user data*/ # void * user_data; # } lv_draw_dsc_base_t; -lv_draw_dsc_base = [ # valid LVGL92 +lv_draw_dsc_base = [ # valid LVGL93 [ptr, "obj"], [uint32_t, "part"], [uint32_t, "id1"], @@ -175,7 +214,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 LVGL92 +lv_draw_rect_dsc = [ # valid LVGL93 [lv_draw_dsc_base, "base"], [int32_t, "radius"], @@ -219,19 +258,38 @@ lv_draw_rect_dsc = ct.structure(lv_draw_rect_dsc, "lv_draw_rect_dsc") # typedef struct { # lv_draw_dsc_base_t base; +# /**The first point of the line. If `LV_USE_FLOAT` is enabled float number can be also used*/ # lv_point_precise_t p1; + +# /**The second point of the line. If `LV_USE_FLOAT` is enabled float number can be also used*/ # lv_point_precise_t p2; + +# /**The color of the line*/ # lv_color_t color; + +# /**The width (thickness) of the line*/ # int32_t width; + +# /** The length of a dash (0: don't dash)*/ # int32_t dash_width; + +# /** The length of the gaps between dashes (0: don't dash)*/ # int32_t dash_gap; + +# /**Opacity of the line in 0...255 range. +# * LV_OPA_TRANSP, LV_OPA_10, LV_OPA_20, .. LV_OPA_COVER can be used as well*/ # lv_opa_t opa; -# lv_blend_mode_t blend_mode : 2; + +# /**Make the line start rounded*/ # uint8_t round_start : 1; + +# /**Make the line end rounded*/ # 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*/ + +# /**1: Do not bother with line ending (if it's not visible for any reason) */ +# uint8_t raw_end : 1; # } lv_draw_line_dsc_t; -lv_draw_line_dsc = [ # valid LVGL92 +lv_draw_line_dsc = [ # valid LVGL93 [lv_draw_dsc_base, "base"], [lv_point_precise, "p1"], @@ -241,7 +299,6 @@ lv_draw_line_dsc = [ # valid LVGL92 [int32_t, "dash_width"], [int32_t, "dash_gap"], [lv_opa, "opa"], - [uint8_t_2, "blend_mode"], [uint8_t_1, "round_start"], [uint8_t_1, "round_end"], [uint8_t_1, "raw_end"], @@ -251,17 +308,36 @@ lv_draw_line_dsc = ct.structure(lv_draw_line_dsc, "lv_draw_line_dsc") # typedef struct { # lv_draw_dsc_base_t base; +# /**The color of the arc*/ # lv_color_t color; + +# /**The width (thickness) of the arc */ # int32_t width; + +# /**The start angle in 1 degree units (if `LV_USE_FLOAT` is enabled a float number can be also used) +# * 0° is the 3 o'clock position, 90° is the 6 o'clock, etc. */ # lv_value_precise_t start_angle; + +# /**The end angle, similarly to start_angle. */ # lv_value_precise_t end_angle; + +# /**The center point of the arc. */ # lv_point_t center; + +# /**The outer radius of the arc*/ # uint16_t radius; + +# /**An image source to be used instead of `color`. `NULL` if unused*/ # const void * img_src; + +# /**Opacity of the arc in 0...255 range. +# * LV_OPA_TRANSP, LV_OPA_10, LV_OPA_20, .. LV_OPA_COVER can be used as well*/ # lv_opa_t opa; + +# /**1: Make the arc ends rounded*/ # uint8_t rounded : 1; # } lv_draw_arc_dsc_t; -lv_draw_arc_dsc = [ # valid LVGL92 +lv_draw_arc_dsc = [ # valid LVGL93 [lv_draw_dsc_base, "base"], [lv_color, "color"], @@ -278,16 +354,16 @@ lv_draw_arc_dsc = ct.structure(lv_draw_arc_dsc, "lv_draw_arc_dsc") # 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; -lv_image_header = [ # valid LVGL92 +lv_image_header = [ # valid LVGL93 [uint8_t, "magic"], [uint8_t, "cf"], [uint16_t, "flags"], @@ -299,40 +375,83 @@ lv_image_header = [ # valid LVGL92 ] lv_image_header = ct.structure(lv_image_header, "lv_image_header") -# typedef struct _lv_draw_image_dsc_t { +# struct _lv_draw_image_dsc_t { # lv_draw_dsc_base_t base; +# /**The image source: pointer to `lv_image_dsc_t` or a path to a file*/ # const void * src; + +# /**The header of the image. Initialized internally in `lv_draw_image` */ # lv_image_header_t header; +# /**Clip the corner of the image with this radius. Use `LV_RADIUS_CIRCLE` for max. radius */ +# int32_t clip_radius; + +# /**The rotation of the image in 0.1 degree unit. E.g. 234 means 23.4° */ # int32_t rotation; + +# /**Horizontal scale (zoom) of the image. +# * 256 (LV_SCALE_NONE): means no zoom, 512 double size, 128 half size.*/ # int32_t scale_x; + +# /**Same as `scale_y` but vertically*/ # int32_t scale_y; + +# /**Parallelogram like transformation of the image horizontally in 0.1 degree unit. E.g. 456 means 45.6°.*/ # int32_t skew_x; + +# /**Same as `skew_x` but vertically*/ # int32_t skew_y; + +# /**The pivot point of transformation (scale and rotation). +# * 0;0 is the top left corner of the image. Can be outside of the image too.*/ # lv_point_t pivot; +# /**Mix this color to the images. In case of `LV_COLOR_FORMAT_A8` it will be the color of the visible pixels*/ # lv_color_t recolor; + +# /**The intensity of recoloring. 0 means, no recolor, 255 means full cover (transparent pixels remain transparent)*/ # lv_opa_t recolor_opa; +# /**Opacity in 0...255 range. +# * LV_OPA_TRANSP, LV_OPA_10, LV_OPA_20, .. LV_OPA_COVER can be used as well*/ # lv_opa_t opa; + +# /**Describes how to blend the pixels of the image to the background. +# * See `lv_blend_mode_t` for more details. +# */ # lv_blend_mode_t blend_mode : 4; +# /**1: perform the transformation with anti-alaising */ # uint16_t antialias : 1; + +# /**If the image is smaller than the `image_area` field of `lv_draw_image_dsc_t` +# * tile the image (repeat is both horizontally and vertically) to fill the +# * `image_area` area*/ # uint16_t tile : 1; + +# /**Used internally to store some information about the palette or the color of A8 images*/ # 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 and e.g. +# * `clip_radius` needs to know what the original image was. +# * 2. Tiled images, where the target draw area is larger than the image to be tiled. +# */ +# lv_area_t image_area; + +# /**Pointer to an A8 or L8 image descriptor to mask the image with. +# * The mask is always center aligned. */ # const lv_image_dsc_t * bitmap_mask_src; -# } lv_draw_image_dsc_t; -lv_draw_image_dsc = [ # valid LVGL92 +# }; +lv_draw_image_dsc = [ # valid LVGL93 [lv_draw_dsc_base, "base"], [ptr, "src"], [lv_image_header, "header"], + [int32_t, "clip_radius"], [int32_t, "rotation"], [int32_t, "scale_x"], [int32_t, "scale_y"], @@ -350,62 +469,126 @@ lv_draw_image_dsc = [ # valid LVGL92 [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") + # typedef struct { # lv_draw_dsc_base_t base; +# /**The text to draw*/ # const char * text; + +# /**The size of the text*/ +# lv_point_t text_size; + +# /**The font to use. Fallback fonts are also handled.*/ # const lv_font_t * font; -# uint32_t sel_start; -# uint32_t sel_end; + +# /**Color of the text*/ # lv_color_t color; -# lv_color_t sel_color; -# lv_color_t sel_bg_color; + +# /**Extra space between the lines*/ # int32_t line_space; + +# /**Extra space between the characters*/ # int32_t letter_space; + +# /**Offset the text with this value horizontally*/ # int32_t ofs_x; + +# /**Offset the text with this value vertically*/ # int32_t ofs_y; + +# /**Rotation of the letters in 0.1 degree unit*/ +# int32_t rotation; + +# /**The first characters index for selection (not byte index). `LV_DRAW_LABEL_NO_TXT_SEL` for no selection*/ +# uint32_t sel_start; + +# /**The last characters's index for selection (not byte index). `LV_DRAW_LABEL_NO_TXT_SEL` for no selection*/ +# uint32_t sel_end; + +# /**Color of the selected characters*/ +# lv_color_t sel_color; + +# /**Background color of the selected characters*/ +# lv_color_t sel_bg_color; + +# /**The number of characters to render. 0: means render until reaching the `\0` termination.*/ +# uint32_t text_length; + +# /**Opacity of the text in 0...255 range. +# * LV_OPA_TRANSP, LV_OPA_10, LV_OPA_20, .. LV_OPA_COVER can be used as well*/ # lv_opa_t opa; -# lv_base_dir_t bidi_dir; + +# /**The alignment of the text `LV_TEXT_ALIGN_LEFT/RIGHT/CENTER`*/ # lv_text_align_t align; -# lv_text_flag_t flag; + +# /**The base direction. Used when type setting Right-to-left (e.g. Arabic) texts*/ +# lv_base_dir_t bidi_dir; + +# /**Text decoration, e.g. underline*/ # lv_text_decor_t decor : 3; -# lv_blend_mode_t blend_mode : 3; -# /** -# * < 1: malloc buffer and copy `text` there. -# * 0: `text` is const and it's pointer will be valid during rendering.*/ + +# /**Some flags to control type setting*/ +# lv_text_flag_t flag : 5; + +# /**1: malloc a buffer and copy `text` there. +# * 0: `text` will be valid during rendering.*/ # uint8_t text_local : 1; + +# /**Indicate that the text is constant and its pointer can be safely saved e.g. in a cache.*/ +# uint8_t text_static : 1; + +# /**1: already executed lv_bidi_process_paragraph. +# * 0: has not been executed lv_bidi_process_paragraph.*/ +# uint8_t has_bided : 1; + +# /**Pointer to an externally stored struct where some data can be cached to speed up rendering*/ # lv_draw_label_hint_t * hint; + +# /* Properties of the letter outlines */ +# lv_opa_t outline_stroke_opa; +# lv_color_t outline_stroke_color; +# int32_t outline_stroke_width; + # } lv_draw_label_dsc_t; -lv_draw_label_dsc = [ # valid LVGL92 +lv_draw_label_dsc = [ # valid LVGL93 [lv_draw_dsc_base, "base"], [ptr, "text"], + [lv_point, "text_size"], [ptr, "font"], - [uint32_t, "sel_start"], - [uint32_t, "sel_end"], [lv_color, "color"], - [lv_color, "sel_color"], - [lv_color, "sel_bg_color"], [int32_t, "line_space"], [int32_t, "letter_space"], [int32_t, "ofs_x"], [int32_t, "ofs_y"], + [int32_t, "rotation"], + [uint32_t, "sel_start"], + [uint32_t, "sel_end"], + [lv_color, "sel_color"], + [lv_color, "sel_bg_color"], + [uint32_t, "text_length"], [lv_opa, "opa"], - [lv_base_dir, "bidi_dir"], [lv_text_align, "align"], + [lv_base_dir, "bidi_dir"], [lv_text_flag, "flag"], [uint8_t_3, "decor"], + [uint8_t_5, "flag"], [uint8_t_3, "blend_mode"], [uint8_t_1, "text_local"], + [uint8_t_1, "text_static"], + [uint8_t_1, "has_bided"], [ptr, "hint"], + [lv_opa, "outline_stroke_opa"], + [lv_color, "outline_stroke_color"], + [int32_t, "outline_stroke_width"], ] lv_draw_label_dsc = ct.structure(lv_draw_label_dsc, "lv_draw_label_dsc") -# typedef struct { +# struct _lv_chart_series_t { # int32_t * x_points; # int32_t * y_points; # lv_color_t color; @@ -415,8 +598,8 @@ lv_draw_label_dsc = ct.structure(lv_draw_label_dsc, "lv_draw_label_dsc") # uint32_t y_ext_buf_assigned : 1; # uint32_t x_axis_sec : 1; # uint32_t y_axis_sec : 1; -# } lv_chart_series_t; -lv_chart_series = [ # valid LVGL92 +# }; +lv_chart_series = [ # valid LVGL93 [ptr, "x_points"], [ptr, "y_points"], [lv_color, "color"], @@ -429,15 +612,15 @@ lv_chart_series = [ # valid LVGL92 ] lv_chart_series = ct.structure(lv_chart_series, "lv_chart_series") -# typedef struct { +# 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*/ -# } lv_chart_cursor_t; -lv_chart_cursor = [ # valid LVGL92 +# uint32_t pos_set: 1; /**< 1: pos is set; 0: point_id is set */ +# }; +lv_chart_cursor = [ # valid LVGL93 [lv_point, "pos"], [int32_t, "point_id"], [lv_color, "color"], @@ -457,15 +640,28 @@ 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. */ # 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; @@ -475,7 +671,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 LVGL92 +lv_obj_class = [ # valid LVGL93 [lv_obj_class_ptr, "base_class"], [constructor_cb, "constructor_cb"], [destructor_cb, "destructor_cb"], @@ -491,7 +687,7 @@ lv_obj_class = [ # valid LVGL92 ] 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; @@ -502,7 +698,7 @@ lv_obj_class = ct.structure(lv_obj_class, "lv_obj_class") # uint8_t stop_processing : 1; # uint8_t stop_bubbling : 1; # }; -lv_event = [ # valid LVGL92 +lv_event = [ # valid LVGL93 [lv_obj_ptr, "current_target"], [lv_obj_ptr, "original_target"], [lv_event_code, "code"], @@ -523,12 +719,14 @@ lv_event = ct.structure(lv_event, "lv_event") # uint32_t data_size; /**< Size of the image in bytes*/ # 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*/ +# const void * reserved_2; /**< A reserved field to make it has same size as lv_draw_buf_t*/ # } lv_image_dsc_t; -lv_image_dsc = [ # valid LVGL92 +lv_image_dsc = [ # valid LVGL93 [lv_image_header, "header"], [uint32_t, "data_size"], [ptr, "data"], [ptr, "reserved"], + [ptr, "reserved_2"], ] lv_image_dsc = ct.structure(lv_image_dsc, "lv_image_dsc") @@ -538,11 +736,11 @@ lv_image_dsc = ct.structure(lv_image_dsc, "lv_image_dsc") # 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; -lv_style_transition_dsc = [ # valid LVGL92 +lv_style_transition_dsc = [ # valid LVGL93 [ptr, "props"], [ptr, "user_data"], [ptr, "path_xcb"], @@ -552,17 +750,17 @@ lv_style_transition_dsc = [ # valid LVGL92 lv_style_transition_dsc = ct.structure(lv_style_transition_dsc, "lv_style_transition_dsc") -# struct lv_layer_t { -# +# 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` @@ -572,31 +770,43 @@ lv_style_transition_dsc = ct.structure(lv_style_transition_dsc, "lv_style_transi # * 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 -# + +# /** Opacity of the layer */ +# lv_opa_t opa; + +# /*Recolor of the layer*/ +# lv_color32_t recolor; + +# /** Partial y offset */ +# int32_t partial_y_offset; + # /** 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 = [ # valid LVGL92 +lv_layer = [ # valid LVGL93 [ptr, "draw_buf"], [lv_area, "buf_area"], [uint32_t, "color_format"], [lv_area, "_clip_area"], [lv_area, "phy_clip_area"], + [lv_opa, "opa"], + [lv_color32, "recolor"], + [int32_t, "partial_y_offset"], [ptr, "draw_task_head"], [ptr, "parent"], [ptr, "next"], @@ -608,11 +818,11 @@ lv_layer = ct.structure(lv_layer, "lv_layer") ####################################################################### # lv_color -# 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; -lv_color_filter_dsc = [ # valid LVGL92 +# }; +lv_color_filter_dsc = [ # valid LVGL93 [ptr, "filter_cb"], [ptr, "user_data"], ] @@ -621,7 +831,7 @@ 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 { +# 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 */ @@ -630,7 +840,7 @@ lv_color_filter_dsc = ct.structure(lv_color_filter_dsc, "lv_color_filter_dsc") # uint32_t paused : 1; # uint32_t auto_delete : 1; # }; -lv_timer_ntv = [ # valid LVGL92 +lv_timer_ntv = [ # valid LVGL93 [uint32_t, "period"], [uint32_t, "last_run"], [ptr, "timer_cb"], @@ -644,12 +854,12 @@ lv_timer_ntv = ct.structure(lv_timer_ntv, "lv_timer_ntv") ####################################################################### # lv_event_dsc -# typedef struct { +# struct _lv_event_dsc_t { # lv_event_cb_t cb; # void * user_data; # uint32_t filter; -# } lv_event_dsc_t; -lv_event_dsc = [ # valid LVGL92 +# }; +lv_event_dsc = [ # valid LVGL93 [ptr, "cb"], [ptr, "user_data"], [uint32_t, "filter"], @@ -659,7 +869,7 @@ lv_event_dsc = ct.structure(lv_event_dsc, "lv_event_dsc") ####################################################################### # Special structure used to calibrate resistive touchscreens ####################################################################### -lv_ts_calibration = [ # valid LVGL91 +lv_ts_calibration = [ # valid LVGL93 [lv_coord_t, "raw_x"], [lv_coord_t, "raw_y"], [lv_coord_t, "x"], @@ -668,5 +878,91 @@ lv_ts_calibration = [ # valid LVGL91 ] lv_ts_calibration = ct.structure(lv_ts_calibration, "lv_ts_calibration") +####################################################################### +# New in LVGL 9.3.0 +####################################################################### +# /** Coords of a span */ +# typedef struct _lv_span_coords_t { +# lv_area_t heading; +# lv_area_t middle; +# lv_area_t trailing; +# } lv_span_coords_t; +lv_span_coords = [ + [lv_area, "heading"], + [lv_area, "middle"], + [lv_area, "trailing"], +] +lv_span_coords = ct.structure(lv_span_coords, "lv_span_coords") + + +####################################################################### +# lv_font_info + +# struct _lv_font_info_t { +# const char * name; /**< Font name, used to distinguish different font resources*/ +# const lv_font_class_t * class_p; /**< Font backend implementation*/ +# uint32_t size; /**< Font size in pixel*/ +# uint32_t render_mode; /**< Font rendering mode, see `lv_freetype_font_render_mode_t`*/ +# uint32_t style; /**< Font style, see `lv_freetype_font_style_t`*/ +# lv_font_kerning_t kerning; /**< Font kerning, see `lv_font_kerning_t`*/ +# }; +lv_font_info = [ # valid LVGL92 + [ptr, "name"], + [ptr, "class_p"], + [uint32_t, "size"], + [uint32_t, "render_mode"], + [uint32_t, "style"], + [uint32_t, "kerning"], +] +lv_font_info = ct.structure(lv_font_info, "lv_font_info") + + +####################################################################### +# lv_draw_letter + +# typedef struct { +# lv_draw_dsc_base_t base; + +# uint32_t unicode; +# const lv_font_t * font; +# lv_color_t color; + +# int32_t rotation; +# int32_t scale_x; +# int32_t scale_y; +# int32_t skew_x; +# int32_t skew_y; +# lv_point_t pivot; + +# lv_opa_t opa; +# lv_text_decor_t decor : 3; +# lv_blend_mode_t blend_mode : 3; + +# /* Properties of the letter outlines */ +# lv_opa_t outline_stroke_opa; +# int32_t outline_stroke_width; +# lv_color_t outline_stroke_color; + +# } lv_draw_letter_dsc_t; +lv_draw_letter_dsc = [ # valid LVGL93 + [lv_draw_dsc_base, "base"], + [uint32_t, "unicode"], + [ptr, "font"], + [lv_color, "color"], + [int32_t, "rotation"], + [int32_t, "scale_x"], + [int32_t, "scale_y"], + [int32_t, "skew_x"], + [int32_t, "skew_y"], + [lv_point, "pivot"], + [lv_opa, "opa"], + [uint8_t_3, "decor"], + [uint8_t_3, "blend_mode"], + [lv_opa, "outline_stroke_opa"], + [int32_t, "outline_stroke_width"], + [lv_color, "outline_stroke_color"], +] +lv_draw_letter_dsc = ct.structure(lv_draw_letter_dsc, "lv_draw_letter_dsc") + # ct.print_classes("lvgl") diff --git a/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py b/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py index 9e89498d5..ebe4c3080 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py +++ b/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py @@ -431,8 +431,9 @@ class type_mapper_class: "lv_point_precise_t *": "lv_point_precise", "lv_draw_image_dsc_t *": "lv_draw_image_dsc", "lv_event_dsc_t *": "lv_event_dsc", + "lv_span_coords_t": "lv_span_coords", - # "_lv_obj_t *": "lv_obj", // no more used in LVGL 9.2 + "_lv_obj_t *": "lv_obj", "lv_obj_t *": "lv_obj", "lv_event_t *": "lv_event", "lv_color_t": "lv_color", @@ -441,7 +442,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", // no more used in LVGL 9.2 + '_lv_display_t *': "lv_display", "lv_indev_t *": "lv_indev", "lv_point_t []": "lv_point_arr", "lv_span_t *": "lv_span", @@ -461,6 +462,12 @@ class type_mapper_class: "constchar **": "c", # treat as a simple pointer, decoding needs to be done at Berry level "void * []": "c", # treat as a simple pointer, decoding needs to be done at Berry level "constchar * *": "c", + # new in 9.3.0 + "lv_text_cmd_state_t *": "c", + "lv_font_info_t *": "lv_font_info", + "lv_switch_orientation_t": "i", + "lv_slider_orientation_t": "i", + "lv_draw_letter_dsc_t *": "lv_draw_letter_dsc", # callbacks "lv_group_focus_cb_t": "lv_group_focus_cb", diff --git a/lib/libesp32_lvgl/lv_binding_berry/tools/preprocessor.py b/lib/libesp32_lvgl/lv_binding_berry/tools/preprocessor.py index 48b39fa2b..4db9489c1 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/tools/preprocessor.py +++ b/lib/libesp32_lvgl/lv_binding_berry/tools/preprocessor.py @@ -1,105 +1,265 @@ +#!/usr/bin/env python3 +""" +LVGL Header Preprocessor + +Extracts function signatures and enums from LVGL header files. +Generates mapping files for Berry scripting integration. +""" + import re import sys import glob +import argparse +from pathlib import Path +from typing import List, Set, Tuple, Optional +import logging -# https://stackoverflow.com/a/241506 -def comment_remover(text): - def replacer(match): - s = match.group(0) - if s.startswith('/'): - return " " # note: a space and not an empty string - else: - return s - pattern = re.compile( - r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', - re.DOTALL | re.MULTILINE - ) - return re.sub(pattern, replacer, text) +# Configure logging +logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s') +logger = logging.getLogger(__name__) -# compute a sorted list of files from a prefix and a list of glob patterns -def list_files(prefix, glob_list): - r = [] - for g in glob_list: - r += glob.glob(prefix + g, recursive=True) - return sorted(r) -def clean_source(raw): - raw = comment_remover(raw) # remove comments - # convert cr/lf or cr to lf - raw = re.sub(r'\r\n ', '\n', raw) - raw = re.sub(r'\r', '\n', raw) - # group multilines into a single line, i.e. if line ends with '\', put in a single line - raw = re.sub(r'\\\n', ' ', raw) - # remove preprocessor directives - raw = re.sub(r'\n[ \t]*#[^\n]*(?=\n)', '', raw) - raw = re.sub(r'^[ \t]*#[^\n]*\n', '', raw) - raw = re.sub(r'\n[ \t]*#[^\n]*$', '', raw) +class LVGLPreprocessor: + """Main preprocessor class for LVGL headers.""" + + def __init__(self, lv_src_prefix: str = "../../lvgl/src/"): + self.lv_src_prefix = Path(lv_src_prefix) + self.headers_exclude_suffix = { + "_private.h", + "lv_lottie.h", + "lv_obj_property.h", + "lv_obj_property_names.h", + "lv_style_properties.h", + "lv_3dtexture.h", + } + + # Function exclusion patterns + self.function_exclude_patterns = [ + r"^_", # skip if function name starts with '_' + r"^lv_debug", # all debug functions + r"^lv_init", r"^lv_deinit", + r"^lv_templ_", + r"^lv_imagebutton_get_src_", # LV_IMGBTN_TILED == 0 + r"^lv_imagebitton_set_src_tiled", # !LV_IMGBTN_TILED + r"^lv_refr_get_fps_", # no LV_USE_PERF_MONITOR + r"^lv_image_cache_", + r"^lv_image_decoder_", + r"^lv_image_cf_", + r"^lv_image_buf_", + r"^lv_indev_scroll_", + r"^lv_pow", + r"^lv_keyboard_def_event_cb", # need to fix conditional include + r"^lv_refr_reset_fps_counter", + r"^lv_refr_get_fps_avg", + r"^lv_anim_path_", # callbacks for animation are moved to constants + r"^lv_obj_set_property", # LV_USE_OBJ_PROPERTY 0 + r"^lv_obj_set_properties", + r"^lv_obj_get_property", + r"^lv_win_", + r"^lv_obj.*name", # we don't enable #if LV_USE_OBJ_NAME + ] + + # Enum exclusion patterns + self.enum_exclude_prefixes = { + "_", "LV_BIDI_DIR_", "LV_FONT_", "LV_SIGNAL_", "LV_TEMPL_", + "LV_TASK_PRIO_", "LV_THEME_", "LV_LRU_", "LV_VECTOR_", + "LV_KEYBOARD_MODE_TEXT_ARABIC", "LV_DRAW_TASK_TYPE_3D", + "LV_DRAW_TASK_TYPE_VECTOR", + } - # remove extern "C" {} - raw = re.sub(r'extern\s+"C"\s+{(.*)}', '\\1', raw, flags=re.DOTALL) + def comment_remover(self, text: str) -> str: + """Remove C/C++ style comments from source code.""" + def replacer(match): + s = match.group(0) + return " " if s.startswith('/') else s + + pattern = re.compile( + r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', + re.DOTALL | re.MULTILINE + ) + return re.sub(pattern, replacer, text) - # remove empty lines - raw = re.sub(r'\n[ \t]*(?=\n)', '', raw) - raw = re.sub(r'^[ \t]*\n', '', raw) # remove first empty line - raw = re.sub(r'\n[ \t]*$', '', raw) # remove last empty line - return raw + def list_files(self, prefix: Path, glob_patterns: List[str]) -> List[Path]: + """Compute a sorted list of files from a prefix and glob patterns.""" + files = [] + for pattern in glob_patterns: + files.extend(Path(prefix).glob(pattern)) + return sorted(files) -# ################################################################################ -# Parse function signatures -# ################################################################################ + def clean_source(self, raw: str) -> str: + """Clean source code by removing comments, preprocessor directives, etc.""" + raw = self.comment_remover(raw) + + # Normalize line endings + raw = re.sub(r'\r\n', '\n', raw) + raw = re.sub(r'\r', '\n', raw) + + # Handle line continuations + raw = re.sub(r'\\\n', ' ', raw) + + # Remove preprocessor directives + raw = re.sub(r'\n[ \t]*#[^\n]*(?=\n)', '', raw) + raw = re.sub(r'^[ \t]*#[^\n]*\n', '', raw) + raw = re.sub(r'\n[ \t]*#[^\n]*$', '', raw) -lv_src_prefix = "../../lvgl/src/" -lv_fun_globs = [ - "lv_api*.h", - "widgets/*/*.h", # all widgets - "libs/qrcode/lv_qrcode.h", - "core/*.h", - "indev/lv_indev.h", - "layouts/*/*.h", - # "draw/*.h", - "themes/lv_theme.h", - "draw/lv_draw_arc.h", - "draw/lv_draw_label.h", - "draw/lv_draw_line.h", - "draw/lv_draw_mask.h", - "draw/lv_draw_rect.h", - "draw/lv_draw_triangle.h", - # "draw/lv_draw_vector.h", - "draw/lv_draw.h", - "display/*.h", - "misc/lv_anim.h", - "misc/lv_area.h", - "misc/lv_color.h", - "misc/lv_color_op.h", - "misc/lv_palette.h", - "misc/lv_event.h", - "misc/lv_style_gen.h", - "misc/lv_style.h", - "misc/lv_timer.h", - "misc/lv_text.h", - "font/lv_font.h", - # 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", -] + # Remove extern "C" blocks + raw = re.sub(r'extern\s+"C"\s+{(.*)}', r'\1', raw, flags=re.DOTALL) -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", "lv_colorwheel.h"]) + # Remove empty lines + raw = re.sub(r'\n[ \t]*(?=\n)', '', raw) + raw = re.sub(r'^[ \t]*\n', '', raw) + raw = re.sub(r'\n[ \t]*$', '', raw) + + return raw -# 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)] + def extract_functions(self, source: str) -> List[str]: + """Extract function signatures from cleaned source code.""" + # Remove content within braces + while True: + source, repl_count = re.subn(r'\{[^{]*?\}', ';', source, flags=re.DOTALL) + if repl_count == 0: + break -output_filename = "../mapping/lv_funcs.h" -sys.stdout = open(output_filename, 'w', encoding='utf-8') + # Find function signatures + pattern = r'(^|;|})\s*([^;{}]+\(.*?\))\s*(?=(;|{))' + matches = re.findall(pattern, source, flags=re.DOTALL) + + functions = [] + for match in matches: + func_def = match[1] + # Clean up whitespace + func_def = re.sub(r'[ \t\r\n]+', ' ', func_def) + + # Remove LVGL-specific attributes + func_def = re.sub(r'LV_ATTRIBUTE_FAST_MEM ', '', func_def) + func_def = re.sub(r'LV_ATTRIBUTE_TIMER_HANDLER ', '', func_def) + func_def = re.sub(r'extern ', '', func_def) + + # Skip excluded function types + if any(func_def.startswith(prefix) for prefix in ["typedef", "_LV_", "LV_"]): + continue + + # Extract function name + name_match = re.search(r'\s(\w+)\([^\(]*$', func_def) + if not name_match: + continue + + func_name = name_match.group(1) + + # Check exclusion patterns + if any(re.search(pattern, func_name) for pattern in self.function_exclude_patterns): + continue + + functions.append(func_def) + + return functions -print(""" + def extract_enums(self, source: str) -> Set[str]: + """Extract enum values from cleaned source code.""" + enum_values = set() + + # Find enum definitions + enum_matches = re.findall(r'enum\s+\w*\s*{(.*?)}', source, flags=re.DOTALL) + + for enum_content in enum_matches: + # Skip LV_PROPERTY_ID enums (disabled feature) + if 'LV_PROPERTY_ID' in enum_content: + continue + + # Remove macro-defined enums + enum_content = re.sub(r'\S+\((.*?),.*?\),', r'\1,', enum_content) + + # Split by commas and clean up + for item in enum_content.split(','): + item = re.sub(r'[ \t\n]', '', item) # Remove whitespace + item = re.sub(r'=.*$', '', item) # Remove assignment + + if not item: # Skip empty items + continue + + # Check exclusion patterns + if any(item.startswith(prefix) for prefix in self.enum_exclude_prefixes): + continue + + enum_values.add(item) + + # Extract LV_EXPORT_CONST_INT constants + const_ints = re.findall(r'LV_EXPORT_CONST_INT\((\w+)\)', source, flags=re.DOTALL) + enum_values.update(const_ints) + + return enum_values + + def get_function_headers(self) -> List[Path]: + """Get list of header files for function extraction.""" + patterns = [ + "lv_api*.h", + "widgets/*/*.h", + "libs/qrcode/lv_qrcode.h", + "core/*.h", + "indev/lv_indev.h", + "layouts/*/*.h", + "themes/lv_theme.h", + "draw/lv_draw_arc.h", + "draw/lv_draw_label.h", + "draw/lv_draw_line.h", + "draw/lv_draw_mask.h", + "draw/lv_draw_rect.h", + "draw/lv_draw_triangle.h", + "draw/lv_draw.h", + "display/*.h", + "misc/lv_anim.h", + "misc/lv_area.h", + "misc/lv_color.h", + "misc/lv_color_op.h", + "misc/lv_palette.h", + "misc/lv_event.h", + "misc/lv_style_gen.h", + "misc/lv_style.h", + "misc/lv_timer.h", + "misc/lv_text.h", + "font/lv_font.h", + "../lvgl.h", + ] + + headers = self.list_files(self.lv_src_prefix, patterns) + + # Add additional headers + additional_paths = [ + Path("../../LVGL_assets/src/lv_theme_haspmota.h"), + Path("../src/lv_berry.h"), + Path("../src/lv_colorwheel.h"), + ] + + for path in additional_paths: + if path.exists(): + headers.append(path) + + # Filter out excluded files + return [h for h in headers if not any(str(h).endswith(suffix) for suffix in self.headers_exclude_suffix)] + + def get_enum_headers(self) -> List[Path]: + """Get list of header files for enum extraction.""" + patterns = [ + "core/*.h", + "draw/*.h", + "hal/*.h", + "misc/*.h", + "widgets/*/*.h", + "display/lv_display.h", + "layouts/**/*.h", + ] + + headers = self.list_files(self.lv_src_prefix, patterns) + return [h for h in headers if not any(str(h).endswith(suffix) for suffix in self.headers_exclude_suffix)] + + def generate_functions_header(self, output_path: Path): + """Generate the functions header file.""" + logger.info(f"Generating functions header: {output_path}") + + headers = self.get_function_headers() + + with open(output_path, 'w', encoding='utf-8') as f: + f.write(""" // Automatically generated from LVGL source with `python3 preprocessor.py` // Extract function signatures from LVGL APIs in headers @@ -119,105 +279,51 @@ lv_coord_t lv_get_ver_res(void); // ====================================================================== """) + + for header_path in headers: + try: + with open(header_path, encoding='utf-8-sig') as header_file: + f.write(f"// {header_path}\n") + + raw_content = self.clean_source(header_file.read()) + functions = self.extract_functions(raw_content) + + for func in functions: + f.write(f"{func}\n") + f.write("\n") + + except Exception as e: + logger.error(f"Error processing {header_path}: {e}") -for header_name in headers_names: - with open(header_name, encoding='utf-8-sig') as f: - print("// " + header_name) - raw = clean_source(f.read()) - - # remove anything in '{' '}' - while True: - (raw, repl) = re.subn(r'\{[^{]*?\}', ';', raw, flags=re.DOTALL) # replace with ';' to make pattern matching still work - if (repl == 0): break # no more replace, stop - - raw_f = re.findall(r'(^|;|})\s*([^;{}]+\(.*?\))\s*(?=(;|{))', raw, flags=re.DOTALL) - fun_defs = [ x[1] for x in raw_f] - # remove any CRLF or multi-space - fun_defs = [ re.sub(r'[ \t\r\n]+', ' ', x) for x in fun_defs] - - # parse individual - for fun in fun_defs: - # remove LV_ATTRIBUTE_FAST_MEM - fun = re.sub(r'LV_ATTRIBUTE_FAST_MEM ', '', fun) - # remove LV_ATTRIBUTE_TIMER_HANDLER - fun = re.sub(r'LV_ATTRIBUTE_TIMER_HANDLER ', '', fun) - # remove extern - fun = re.sub(r'extern ', '', fun) - exclude = False - for exclude_prefix in ["typedef", "_LV_", "LV_"]: - if fun.startswith(exclude_prefix): exclude = True - if exclude: continue - - # extrac the function name - fun_name = re.search(r'\s(\w+)\([^\(]*$', fun) - if fun_name != None: - fun_name = fun_name.group(1) # we now have the function name + def generate_enums_header(self, output_path: Path): + """Generate the enums header file.""" + logger.info(f"Generating enums header: {output_path}") - # exclude specific names - for exclude_pattern in [ - "^_", # skip if function name starts with '_' - "^lv_debug", # all debug functions - "^lv_init", "^lv_deinit", - "^lv_templ_", - "^lv_imagebutton_get_src_", # LV_IMGBTN_TILED == 0 - "^lv_imagebitton_set_src_tiled",# !LV_IMGBTN_TILED - #"^lv_disp_", - "^lv_refr_get_fps_", # no LV_USE_PERF_MONITOR - "^lv_image_cache_", - "^lv_image_decoder_", - "^lv_image_cf_", - "^lv_image_buf_", - "^lv_indev_scroll_", - "^lv_pow", - "^lv_keyboard_def_event_cb", # need to fix conditional include - # "^lv_event_get_", # event_getters not needed - "^lv_refr_reset_fps_counter", - "^lv_refr_get_fps_avg", - "^lv_anim_path_", # callbacks for animation are moved to constants - # LV_USE_OBJ_PROPERTY 0 - "^lv_obj_set_property", - "^lv_obj_set_properties", - "^lv_obj_get_property", - "^lv_win_", - ]: - if re.search(exclude_pattern, fun_name): exclude = True - if exclude: continue - - print(fun) - print() + headers = self.get_enum_headers() + + with open(output_path, 'w', encoding='utf-8') as f: + # Write the static content first + f.write(self._get_static_enum_content()) + + # Process headers for dynamic enums + for header_path in headers: + try: + with open(header_path, encoding='utf-8-sig') as header_file: + f.write(f"// File: {header_path}\n") + + raw_content = self.clean_source(header_file.read()) + enum_values = self.extract_enums(raw_content) + + for enum_value in sorted(enum_values): + f.write(f"{enum_value}\n") + f.write("\n") + + except Exception as e: + logger.error(f"Error processing {header_path}: {e}") -sys.stdout.close() - -# ################################################################################ -# Parse 'enum' -# ################################################################################ - -lv_src_prefix = "../../lvgl/src/" -lv_fun_globs = [ - "core/*.h", - "draw/*.h", - "hal/*.h", - "misc/*.h", - "widgets/*/*.h", - "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("""// ====================================================================== + def _get_static_enum_content(self) -> str: + """Get the static content for enum header.""" + return """// ====================================================================== // Functions // ====================================================================== @@ -268,7 +374,6 @@ COLOR_IVORY=0xFFFFF0 COLOR_LINEN=0xFAF0E6 COLOR_BEIGE=0xF5F5DC COLOR_AZURE=0xF0FFFF -COLOR_SILVER=0xC0C0C0 COLOR_PINK=0xFFC0CB COLOR_PLUM=0xDDA0DD COLOR_ORCHID=0xDA70D6 @@ -397,47 +502,59 @@ LV_STYLE_TRANSFORM_ANGLE=LV_STYLE_TRANSFORM_ROTATION LV_ZOOM_NONE=LV_SCALE_NONE +// LVGL 9.3 +LV_LABEL_LONG_WRAP=LV_LABEL_LONG_MODE_WRAP +LV_LABEL_LONG_DOT=LV_LABEL_LONG_MODE_DOTS +LV_LABEL_LONG_SCROLL=LV_LABEL_LONG_MODE_SCROLL +LV_LABEL_LONG_SCROLL_CIRCULAR=LV_LABEL_LONG_MODE_SCROLL_CIRCULAR +LV_LABEL_LONG_CLIP=LV_LABEL_LONG_MODE_CLIP + // ====================================================================== // Generated from headers // ====================================================================== -""") +""" -for header_name in headers_names: - with open(header_name) as f: - raw = clean_source(f.read()) + def run(self, functions_output: str = "../mapping/lv_funcs.h", + enums_output: str = "../mapping/lv_enum.h"): + """Run the complete preprocessing pipeline.""" + functions_path = Path(functions_output) + enums_path = Path(enums_output) + + # Create output directories if they don't exist + functions_path.parent.mkdir(parents=True, exist_ok=True) + enums_path.parent.mkdir(parents=True, exist_ok=True) + + # Generate both files + self.generate_functions_header(functions_path) + self.generate_enums_header(enums_path) + + logger.info("Preprocessing complete!") - print(f"// File: {header_name}") - # extract enums - enums = re.findall(r'enum\s+\w*\s*{(.*?)}', raw, flags=re.DOTALL) - for enum in enums: # iterate on all matches - # exclude LV_PROPERTY_ID - # we compile with `#define LV_USE_OBJ_PROPERTY 0` - # and remove all instances of `LV_PROPERTY_ID(OBJ, FLAG_START, LV_PROPERTY_TYPE_INT, 0),` - if re.search('LV_PROPERTY_ID', enum): continue - # remove enums defined via a macro - enum = re.sub(r'\S+\((.*?),.*?\),', '\\1,', enum) # turn 'LV_STYLE_PROP_INIT(LV_STYLE_SIZE, 0x0, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),' into 'LV_STYLE_SIZE' - # - enum_elt = enum.split(",") - for enum_item in enum_elt: - # remove any space - enum_item = re.sub(r'[ \t\n]', '', enum_item) - # remove anything after '=' - enum_item = re.sub(r'=.*$', '', enum_item) - # item is ready - exclude = False - for exclude_prefix in ["_", "LV_BIDI_DIR_", "LV_FONT_", - "LV_SIGNAL_", "LV_TEMPL_", "LV_TASK_PRIO_", "LV_THEME_", - "LV_LRU_", - "LV_VECTOR_", - "LV_KEYBOARD_MODE_TEXT_ARABIC"]: - if enum_item.startswith(exclude_prefix): exclude = True - if exclude: continue +def main(): + """Main entry point with command line argument parsing.""" + parser = argparse.ArgumentParser(description="LVGL Header Preprocessor") + parser.add_argument("--lv-src", default="../../lvgl/src/", + help="Path to LVGL source directory") + parser.add_argument("--functions-output", default="../mapping/lv_funcs.h", + help="Output path for functions header") + parser.add_argument("--enums-output", default="../mapping/lv_enum.h", + help="Output path for enums header") + parser.add_argument("--verbose", "-v", action="store_true", + help="Enable verbose logging") + + args = parser.parse_args() + + if args.verbose: + logging.getLogger().setLevel(logging.DEBUG) + + try: + preprocessor = LVGLPreprocessor(args.lv_src) + preprocessor.run(args.functions_output, args.enums_output) + except Exception as e: + logger.error(f"Preprocessing failed: {e}") + sys.exit(1) - print(enum_item) - # extract `LV_EXPORT_CONST_INT()` int constants - constints = re.findall(r'LV_EXPORT_CONST_INT\((\w+)\)', raw, flags=re.DOTALL) - for constint in constints: - print(constint) -sys.stdout.close() +if __name__ == "__main__": + main() diff --git a/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_1_constants.be b/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_1_constants.be index 1924b6aed..51d69e8f5 100644 --- a/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_1_constants.be +++ b/lib/libesp32_lvgl/lv_haspmota/src/embedded/lv_1_constants.be @@ -1,5 +1,5 @@ # LVGL integer constants -# LVGL version 9 +# LVGL version 9.3.0 lv.ALIGN_BOTTOM_LEFT = 4 lv.ALIGN_BOTTOM_MID = 5 @@ -24,8 +24,6 @@ lv.ALIGN_TOP_LEFT = 1 lv.ALIGN_TOP_MID = 2 lv.ALIGN_TOP_RIGHT = 3 lv.ANIM_IMAGE_PART_MAIN = 0 -lv.ANIM_OFF = 0 -lv.ANIM_ON = 1 lv.ANIM_PLAYTIME_INFINITE = -1 lv.ANIM_REPEAT_INFINITE = -1 lv.ARC_MODE_NORMAL = 0 @@ -43,6 +41,7 @@ lv.BASE_DIR_NEUTRAL = 32 lv.BASE_DIR_RTL = 1 lv.BASE_DIR_WEAK = 33 lv.BLEND_MODE_ADDITIVE = 1 +lv.BLEND_MODE_DIFFERENCE = 4 lv.BLEND_MODE_MULTIPLY = 3 lv.BLEND_MODE_NORMAL = 0 lv.BLEND_MODE_SUBTRACTIVE = 2 @@ -71,11 +70,27 @@ lv.BUTTONMATRIX_CTRL_CUSTOM_1 = 16384 lv.BUTTONMATRIX_CTRL_CUSTOM_2 = 32768 lv.BUTTONMATRIX_CTRL_DISABLED = 64 lv.BUTTONMATRIX_CTRL_HIDDEN = 16 +lv.BUTTONMATRIX_CTRL_NONE = 0 lv.BUTTONMATRIX_CTRL_NO_REPEAT = 32 lv.BUTTONMATRIX_CTRL_POPOVER = 1024 -lv.BUTTONMATRIX_CTRL_RESERVED_1 = 2048 -lv.BUTTONMATRIX_CTRL_RESERVED_2 = 4096 -lv.BUTTONMATRIX_CTRL_RESERVED_3 = 8192 +lv.BUTTONMATRIX_CTRL_RECOLOR = 2048 +lv.BUTTONMATRIX_CTRL_RESERVED_1 = 4096 +lv.BUTTONMATRIX_CTRL_RESERVED_2 = 8192 +lv.BUTTONMATRIX_CTRL_WIDTH_1 = 1 +lv.BUTTONMATRIX_CTRL_WIDTH_10 = 10 +lv.BUTTONMATRIX_CTRL_WIDTH_11 = 11 +lv.BUTTONMATRIX_CTRL_WIDTH_12 = 12 +lv.BUTTONMATRIX_CTRL_WIDTH_13 = 13 +lv.BUTTONMATRIX_CTRL_WIDTH_14 = 14 +lv.BUTTONMATRIX_CTRL_WIDTH_15 = 15 +lv.BUTTONMATRIX_CTRL_WIDTH_2 = 2 +lv.BUTTONMATRIX_CTRL_WIDTH_3 = 3 +lv.BUTTONMATRIX_CTRL_WIDTH_4 = 4 +lv.BUTTONMATRIX_CTRL_WIDTH_5 = 5 +lv.BUTTONMATRIX_CTRL_WIDTH_6 = 6 +lv.BUTTONMATRIX_CTRL_WIDTH_7 = 7 +lv.BUTTONMATRIX_CTRL_WIDTH_8 = 8 +lv.BUTTONMATRIX_CTRL_WIDTH_9 = 9 lv.CHART_AXIS_LAST = 5 lv.CHART_AXIS_PRIMARY_X = 2 lv.CHART_AXIS_PRIMARY_Y = 0 @@ -89,8 +104,14 @@ lv.CHART_TYPE_SCATTER = 3 lv.CHART_UPDATE_MODE_CIRCULAR = 1 lv.CHART_UPDATE_MODE_SHIFT = 0 lv.COLOR_AQUA = 65535 +lv.COLOR_AZURE = 15794175 +lv.COLOR_BEIGE = 16119260 +lv.COLOR_BISQUE = 16770244 lv.COLOR_BLACK = 0 lv.COLOR_BLUE = 255 +lv.COLOR_BLUSH = 11534336 +lv.COLOR_BROWN = 10824234 +lv.COLOR_CORAL = 16744272 lv.COLOR_CYAN = 65535 lv.COLOR_DEPTH = 16 lv.COLOR_FORMAT_A1 = 11 @@ -98,8 +119,12 @@ lv.COLOR_FORMAT_A2 = 12 lv.COLOR_FORMAT_A4 = 13 lv.COLOR_FORMAT_A8 = 14 lv.COLOR_FORMAT_AL88 = 21 +lv.COLOR_FORMAT_ARGB1555 = 22 +lv.COLOR_FORMAT_ARGB2222 = 24 +lv.COLOR_FORMAT_ARGB4444 = 23 lv.COLOR_FORMAT_ARGB8565 = 19 lv.COLOR_FORMAT_ARGB8888 = 16 +lv.COLOR_FORMAT_ARGB8888_PREMULTIPLIED = 26 lv.COLOR_FORMAT_I1 = 7 lv.COLOR_FORMAT_I2 = 8 lv.COLOR_FORMAT_I4 = 9 @@ -111,12 +136,22 @@ lv.COLOR_FORMAT_I8 = 10 lv.COLOR_FORMAT_L8 = 6 lv.COLOR_FORMAT_NATIVE = 18 lv.COLOR_FORMAT_NATIVE_WITH_ALPHA = 20 +lv.COLOR_FORMAT_NEMA_TSC12 = 52 +lv.COLOR_FORMAT_NEMA_TSC12A = 53 +lv.COLOR_FORMAT_NEMA_TSC4 = 48 +lv.COLOR_FORMAT_NEMA_TSC6 = 49 +lv.COLOR_FORMAT_NEMA_TSC6A = 50 +lv.COLOR_FORMAT_NEMA_TSC6AP = 51 +lv.COLOR_FORMAT_NEMA_TSC_END = 53 +lv.COLOR_FORMAT_NEMA_TSC_START = 48 lv.COLOR_FORMAT_NV12 = 37 lv.COLOR_FORMAT_NV21 = 36 +lv.COLOR_FORMAT_PROPRIETARY_START = 48 lv.COLOR_FORMAT_RAW = 1 lv.COLOR_FORMAT_RAW_ALPHA = 2 lv.COLOR_FORMAT_RGB565 = 18 lv.COLOR_FORMAT_RGB565A8 = 20 +lv.COLOR_FORMAT_RGB565_SWAPPED = 27 lv.COLOR_FORMAT_RGB888 = 15 lv.COLOR_FORMAT_UNKNOWN = 0 lv.COLOR_FORMAT_UYVY = 39 @@ -124,18 +159,36 @@ lv.COLOR_FORMAT_XRGB8888 = 17 lv.COLOR_FORMAT_YUV_END = 39 lv.COLOR_FORMAT_YUV_START = 32 lv.COLOR_FORMAT_YUY2 = 38 +lv.COLOR_FUCHSIA = 16711935 +lv.COLOR_GOLD = 16766720 lv.COLOR_GRAY = 8421504 lv.COLOR_GREEN = 32768 +lv.COLOR_GREY = 8421504 +lv.COLOR_INDIGO = 4915330 +lv.COLOR_IVORY = 16777200 +lv.COLOR_KHAKI = 15787660 lv.COLOR_LIME = 65280 +lv.COLOR_LINEN = 16445670 lv.COLOR_MAGENTA = 16711935 lv.COLOR_MAROON = 8388608 lv.COLOR_NAVY = 128 lv.COLOR_OLIVE = 8421376 -lv.COLOR_ORANGE = 16744192 +lv.COLOR_ORANGE = 16753920 +lv.COLOR_ORCHID = 14315734 +lv.COLOR_PERU = 13468991 +lv.COLOR_PINK = 16761035 +lv.COLOR_PLUM = 14524637 lv.COLOR_PURPLE = 8388736 lv.COLOR_RED = 16711680 +lv.COLOR_SALMON = 16416882 +lv.COLOR_SIENNA = 10506797 lv.COLOR_SILVER = 12632256 +lv.COLOR_SNOW = 16775930 +lv.COLOR_TAN = 13808780 lv.COLOR_TEAL = 32896 +lv.COLOR_TOMATO = 16737095 +lv.COLOR_VIOLET = 15631086 +lv.COLOR_WHEAT = 16113331 lv.COLOR_WHITE = 16777215 lv.COLOR_YELLOW = 16776960 lv.COORD_MAX = 536870911 @@ -169,85 +222,90 @@ lv.DRAW_TASK_STATE_IN_PROGRESS = 2 lv.DRAW_TASK_STATE_QUEUED = 1 lv.DRAW_TASK_STATE_READY = 3 lv.DRAW_TASK_STATE_WAITING = 0 -lv.DRAW_TASK_TYPE_ARC = 8 +lv.DRAW_TASK_TYPE_ARC = 9 lv.DRAW_TASK_TYPE_BORDER = 2 lv.DRAW_TASK_TYPE_BOX_SHADOW = 3 lv.DRAW_TASK_TYPE_FILL = 1 -lv.DRAW_TASK_TYPE_IMAGE = 5 -lv.DRAW_TASK_TYPE_LABEL = 4 -lv.DRAW_TASK_TYPE_LAYER = 6 -lv.DRAW_TASK_TYPE_LINE = 7 -lv.DRAW_TASK_TYPE_MASK_BITMAP = 11 -lv.DRAW_TASK_TYPE_MASK_RECTANGLE = 10 +lv.DRAW_TASK_TYPE_IMAGE = 6 +lv.DRAW_TASK_TYPE_LABEL = 5 +lv.DRAW_TASK_TYPE_LAYER = 7 +lv.DRAW_TASK_TYPE_LETTER = 4 +lv.DRAW_TASK_TYPE_LINE = 8 +lv.DRAW_TASK_TYPE_MASK_BITMAP = 12 +lv.DRAW_TASK_TYPE_MASK_RECTANGLE = 11 lv.DRAW_TASK_TYPE_NONE = 0 -lv.DRAW_TASK_TYPE_TRIANGLE = 9 -lv.DRAW_TASK_TYPE_VECTOR = 12 +lv.DRAW_TASK_TYPE_TRIANGLE = 10 lv.DROPDOWN_POS_LAST = 65535 lv.EVENT_ALL = 0 -lv.EVENT_CANCEL = 36 -lv.EVENT_CHILD_CHANGED = 39 -lv.EVENT_CHILD_CREATED = 40 -lv.EVENT_CHILD_DELETED = 41 -lv.EVENT_CLICKED = 7 -lv.EVENT_COLOR_FORMAT_CHANGED = 52 -lv.EVENT_COVER_CHECK = 23 -lv.EVENT_CREATE = 37 -lv.EVENT_DEFOCUSED = 17 -lv.EVENT_DELETE = 38 -lv.EVENT_DRAW_MAIN = 26 -lv.EVENT_DRAW_MAIN_BEGIN = 25 -lv.EVENT_DRAW_MAIN_END = 27 -lv.EVENT_DRAW_POST = 29 -lv.EVENT_DRAW_POST_BEGIN = 28 -lv.EVENT_DRAW_POST_END = 30 -lv.EVENT_DRAW_TASK_ADDED = 31 -lv.EVENT_FLUSH_FINISH = 59 -lv.EVENT_FLUSH_START = 58 -lv.EVENT_FLUSH_WAIT_FINISH = 61 -lv.EVENT_FLUSH_WAIT_START = 60 -lv.EVENT_FOCUSED = 16 -lv.EVENT_GESTURE = 13 -lv.EVENT_GET_SELF_SIZE = 49 -lv.EVENT_HIT_TEST = 19 -lv.EVENT_HOVER_LEAVE = 22 -lv.EVENT_HOVER_OVER = 21 -lv.EVENT_INDEV_RESET = 20 -lv.EVENT_INSERT = 33 -lv.EVENT_INVALIDATE_AREA = 50 -lv.EVENT_KEY = 14 -lv.EVENT_LAST = 63 -lv.EVENT_LAYOUT_CHANGED = 48 -lv.EVENT_LEAVE = 18 -lv.EVENT_LONG_PRESSED = 5 -lv.EVENT_LONG_PRESSED_REPEAT = 6 +lv.EVENT_CANCEL = 39 +lv.EVENT_CHILD_CHANGED = 42 +lv.EVENT_CHILD_CREATED = 43 +lv.EVENT_CHILD_DELETED = 44 +lv.EVENT_CLICKED = 10 +lv.EVENT_COLOR_FORMAT_CHANGED = 55 +lv.EVENT_COVER_CHECK = 26 +lv.EVENT_CREATE = 40 +lv.EVENT_DEFOCUSED = 20 +lv.EVENT_DELETE = 41 +lv.EVENT_DOUBLE_CLICKED = 6 +lv.EVENT_DRAW_MAIN = 29 +lv.EVENT_DRAW_MAIN_BEGIN = 28 +lv.EVENT_DRAW_MAIN_END = 30 +lv.EVENT_DRAW_POST = 32 +lv.EVENT_DRAW_POST_BEGIN = 31 +lv.EVENT_DRAW_POST_END = 33 +lv.EVENT_DRAW_TASK_ADDED = 34 +lv.EVENT_FLUSH_FINISH = 62 +lv.EVENT_FLUSH_START = 61 +lv.EVENT_FLUSH_WAIT_FINISH = 64 +lv.EVENT_FLUSH_WAIT_START = 63 +lv.EVENT_FOCUSED = 19 +lv.EVENT_GESTURE = 16 +lv.EVENT_GET_SELF_SIZE = 52 +lv.EVENT_HIT_TEST = 22 +lv.EVENT_HOVER_LEAVE = 25 +lv.EVENT_HOVER_OVER = 24 +lv.EVENT_INDEV_RESET = 23 +lv.EVENT_INSERT = 36 +lv.EVENT_INVALIDATE_AREA = 53 +lv.EVENT_KEY = 17 +lv.EVENT_LAST = 67 +lv.EVENT_LAYOUT_CHANGED = 51 +lv.EVENT_LEAVE = 21 +lv.EVENT_LONG_PRESSED = 8 +lv.EVENT_LONG_PRESSED_REPEAT = 9 +lv.EVENT_MARKED_DELETING = 65536 lv.EVENT_PREPROCESS = 32768 lv.EVENT_PRESSED = 1 lv.EVENT_PRESSING = 2 lv.EVENT_PRESS_LOST = 3 -lv.EVENT_READY = 35 -lv.EVENT_REFRESH = 34 -lv.EVENT_REFR_EXT_DRAW_SIZE = 24 -lv.EVENT_REFR_READY = 55 -lv.EVENT_REFR_REQUEST = 53 -lv.EVENT_REFR_START = 54 -lv.EVENT_RELEASED = 8 -lv.EVENT_RENDER_READY = 57 -lv.EVENT_RENDER_START = 56 -lv.EVENT_RESOLUTION_CHANGED = 51 -lv.EVENT_ROTARY = 15 -lv.EVENT_SCREEN_LOADED = 44 -lv.EVENT_SCREEN_LOAD_START = 43 -lv.EVENT_SCREEN_UNLOADED = 45 -lv.EVENT_SCREEN_UNLOAD_START = 42 -lv.EVENT_SCROLL = 12 -lv.EVENT_SCROLL_BEGIN = 9 -lv.EVENT_SCROLL_END = 11 -lv.EVENT_SCROLL_THROW_BEGIN = 10 +lv.EVENT_READY = 38 +lv.EVENT_REFRESH = 37 +lv.EVENT_REFR_EXT_DRAW_SIZE = 27 +lv.EVENT_REFR_READY = 58 +lv.EVENT_REFR_REQUEST = 56 +lv.EVENT_REFR_START = 57 +lv.EVENT_RELEASED = 11 +lv.EVENT_RENDER_READY = 60 +lv.EVENT_RENDER_START = 59 +lv.EVENT_RESOLUTION_CHANGED = 54 +lv.EVENT_ROTARY = 18 +lv.EVENT_SCREEN_LOADED = 47 +lv.EVENT_SCREEN_LOAD_START = 46 +lv.EVENT_SCREEN_UNLOADED = 48 +lv.EVENT_SCREEN_UNLOAD_START = 45 +lv.EVENT_SCROLL = 15 +lv.EVENT_SCROLL_BEGIN = 12 +lv.EVENT_SCROLL_END = 14 +lv.EVENT_SCROLL_THROW_BEGIN = 13 lv.EVENT_SHORT_CLICKED = 4 -lv.EVENT_SIZE_CHANGED = 46 -lv.EVENT_STYLE_CHANGED = 47 -lv.EVENT_VALUE_CHANGED = 32 -lv.EVENT_VSYNC = 62 +lv.EVENT_SINGLE_CLICKED = 5 +lv.EVENT_SIZE_CHANGED = 49 +lv.EVENT_STYLE_CHANGED = 50 +lv.EVENT_TRIPLE_CLICKED = 7 +lv.EVENT_VALUE_CHANGED = 35 +lv.EVENT_VSYNC = 65 +lv.EVENT_VSYNC_REQUEST = 66 lv.FLEX_ALIGN_CENTER = 2 lv.FLEX_ALIGN_END = 1 lv.FLEX_ALIGN_SPACE_AROUND = 4 @@ -316,6 +374,8 @@ lv.IMAGE_ALIGN_BOTTOM_LEFT = 4 lv.IMAGE_ALIGN_BOTTOM_MID = 5 lv.IMAGE_ALIGN_BOTTOM_RIGHT = 6 lv.IMAGE_ALIGN_CENTER = 9 +lv.IMAGE_ALIGN_CONTAIN = 13 +lv.IMAGE_ALIGN_COVER = 14 lv.IMAGE_ALIGN_DEFAULT = 0 lv.IMAGE_ALIGN_LEFT_MID = 7 lv.IMAGE_ALIGN_RIGHT_MID = 8 @@ -329,6 +389,7 @@ lv.IMAGE_COMPRESS_NONE = 0 lv.IMAGE_COMPRESS_RLE = 1 lv.IMAGE_FLAGS_ALLOCATED = 16 lv.IMAGE_FLAGS_COMPRESSED = 8 +lv.IMAGE_FLAGS_CUSTOM_DRAW = 64 lv.IMAGE_FLAGS_MODIFIABLE = 32 lv.IMAGE_FLAGS_PREMULTIPLIED = 1 lv.IMAGE_FLAGS_USER1 = 256 @@ -367,11 +428,11 @@ lv.KEY_PREV = 11 lv.KEY_RIGHT = 19 lv.KEY_UP = 17 lv.LABEL_DOT_NUM = 3 -lv.LABEL_LONG_CLIP = 4 -lv.LABEL_LONG_DOT = 1 -lv.LABEL_LONG_SCROLL = 2 -lv.LABEL_LONG_SCROLL_CIRCULAR = 3 -lv.LABEL_LONG_WRAP = 0 +lv.LABEL_LONG_MODE_CLIP = 4 +lv.LABEL_LONG_MODE_DOTS = 1 +lv.LABEL_LONG_MODE_SCROLL = 2 +lv.LABEL_LONG_MODE_SCROLL_CIRCULAR = 3 +lv.LABEL_LONG_MODE_WRAP = 0 lv.LABEL_POS_LAST = 65535 lv.LABEL_TEXT_SELECTION_OFF = 65535 lv.LAYER_TYPE_NONE = 0 @@ -492,6 +553,8 @@ lv.RES_OK = 1 lv.ROLLER_MODE_INFINITE = 1 lv.ROLLER_MODE_NORMAL = 0 lv.SCALE_LABEL_ENABLED_DEFAULT = 1 +lv.SCALE_LABEL_ROTATE_KEEP_UPRIGHT = 524288 +lv.SCALE_LABEL_ROTATE_MATCH_TICKS = 1048576 lv.SCALE_MAJOR_TICK_EVERY_DEFAULT = 5 lv.SCALE_MODE_HORIZONTAL_BOTTOM = 1 lv.SCALE_MODE_HORIZONTAL_TOP = 0 @@ -501,6 +564,7 @@ lv.SCALE_MODE_ROUND_OUTER = 16 lv.SCALE_MODE_VERTICAL_LEFT = 2 lv.SCALE_MODE_VERTICAL_RIGHT = 4 lv.SCALE_NONE = 256 +lv.SCALE_ROTATION_ANGLE_MASK = 524287 lv.SCALE_TOTAL_TICK_COUNT_DEFAULT = 11 lv.SCROLLBAR_MODE_ACTIVE = 2 lv.SCROLLBAR_MODE_AUTO = 3 @@ -530,6 +594,9 @@ lv.SIZE_CONTENT = 1073741823 lv.SLIDER_MODE_NORMAL = 0 lv.SLIDER_MODE_RANGE = 2 lv.SLIDER_MODE_SYMMETRICAL = 1 +lv.SLIDER_ORIENTATION_AUTO = 0 +lv.SLIDER_ORIENTATION_HORIZONTAL = 1 +lv.SLIDER_ORIENTATION_VERTICAL = 2 lv.SPAN_MODE_BREAK = 2 lv.SPAN_MODE_EXPAND = 1 lv.SPAN_MODE_FIXED = 0 @@ -553,9 +620,9 @@ lv.STATE_USER_3 = 16384 lv.STATE_USER_4 = 32768 lv.STRIDE_AUTO = 0 lv.STYLE_ALIGN = 10 -lv.STYLE_ANIM = 99 -lv.STYLE_ANIM_DURATION = 100 -lv.STYLE_ANIM_TIME = 100 +lv.STYLE_ANIM = 102 +lv.STYLE_ANIM_DURATION = 103 +lv.STYLE_ANIM_TIME = 103 lv.STYLE_ARC_COLOR = 82 lv.STYLE_ARC_IMAGE_SRC = 84 lv.STYLE_ARC_OPA = 83 @@ -576,31 +643,31 @@ lv.STYLE_BG_IMAGE_TILED = 44 lv.STYLE_BG_MAIN_OPA = 36 lv.STYLE_BG_MAIN_STOP = 33 lv.STYLE_BG_OPA = 29 -lv.STYLE_BITMAP_MASK_SRC = 115 -lv.STYLE_BLEND_MODE = 103 +lv.STYLE_BITMAP_MASK_SRC = 117 +lv.STYLE_BLEND_MODE = 105 lv.STYLE_BORDER_COLOR = 49 lv.STYLE_BORDER_OPA = 50 lv.STYLE_BORDER_POST = 53 lv.STYLE_BORDER_SIDE = 52 lv.STYLE_BORDER_WIDTH = 48 lv.STYLE_CLIP_CORNER = 45 -lv.STYLE_COLOR_FILTER_DSC = 97 -lv.STYLE_COLOR_FILTER_OPA = 98 -lv.STYLE_FLEX_CROSS_PLACE = 127 -lv.STYLE_FLEX_FLOW = 125 -lv.STYLE_FLEX_GROW = 129 -lv.STYLE_FLEX_MAIN_PLACE = 126 -lv.STYLE_FLEX_TRACK_PLACE = 128 -lv.STYLE_GRID_CELL_COLUMN_POS = 134 -lv.STYLE_GRID_CELL_COLUMN_SPAN = 135 -lv.STYLE_GRID_CELL_ROW_POS = 137 -lv.STYLE_GRID_CELL_ROW_SPAN = 138 -lv.STYLE_GRID_CELL_X_ALIGN = 136 -lv.STYLE_GRID_CELL_Y_ALIGN = 139 -lv.STYLE_GRID_COLUMN_ALIGN = 130 -lv.STYLE_GRID_COLUMN_DSC_ARRAY = 133 -lv.STYLE_GRID_ROW_ALIGN = 131 -lv.STYLE_GRID_ROW_DSC_ARRAY = 132 +lv.STYLE_COLOR_FILTER_DSC = 100 +lv.STYLE_COLOR_FILTER_OPA = 101 +lv.STYLE_FLEX_CROSS_PLACE = 124 +lv.STYLE_FLEX_FLOW = 122 +lv.STYLE_FLEX_GROW = 126 +lv.STYLE_FLEX_MAIN_PLACE = 123 +lv.STYLE_FLEX_TRACK_PLACE = 125 +lv.STYLE_GRID_CELL_COLUMN_POS = 131 +lv.STYLE_GRID_CELL_COLUMN_SPAN = 132 +lv.STYLE_GRID_CELL_ROW_POS = 134 +lv.STYLE_GRID_CELL_ROW_SPAN = 135 +lv.STYLE_GRID_CELL_X_ALIGN = 133 +lv.STYLE_GRID_CELL_Y_ALIGN = 136 +lv.STYLE_GRID_COLUMN_ALIGN = 127 +lv.STYLE_GRID_COLUMN_DSC_ARRAY = 130 +lv.STYLE_GRID_ROW_ALIGN = 128 +lv.STYLE_GRID_ROW_DSC_ARRAY = 129 lv.STYLE_HEIGHT = 2 lv.STYLE_IMAGE_OPA = 68 lv.STYLE_IMAGE_RECOLOR = 69 @@ -608,7 +675,7 @@ lv.STYLE_IMAGE_RECOLOR_OPA = 70 lv.STYLE_IMG_OPA = 68 lv.STYLE_IMG_RECOLOR = 69 lv.STYLE_IMG_RECOLOR_OPA = 70 -lv.STYLE_LAST_BUILT_IN_PROP = 140 +lv.STYLE_LAST_BUILT_IN_PROP = 137 lv.STYLE_LAYOUT = 22 lv.STYLE_LENGTH = 3 lv.STYLE_LINE_COLOR = 76 @@ -625,9 +692,9 @@ lv.STYLE_MAX_HEIGHT = 7 lv.STYLE_MAX_WIDTH = 5 lv.STYLE_MIN_HEIGHT = 6 lv.STYLE_MIN_WIDTH = 4 -lv.STYLE_NUM_BUILT_IN_PROPS = 141 -lv.STYLE_OPA = 95 -lv.STYLE_OPA_LAYERED = 96 +lv.STYLE_NUM_BUILT_IN_PROPS = 138 +lv.STYLE_OPA = 98 +lv.STYLE_OPA_LAYERED = 99 lv.STYLE_OUTLINE_COLOR = 57 lv.STYLE_OUTLINE_OPA = 58 lv.STYLE_OUTLINE_PAD = 59 @@ -635,16 +702,20 @@ lv.STYLE_OUTLINE_WIDTH = 56 lv.STYLE_PAD_BOTTOM = 17 lv.STYLE_PAD_COLUMN = 21 lv.STYLE_PAD_LEFT = 18 +lv.STYLE_PAD_RADIAL = 14 lv.STYLE_PAD_RIGHT = 19 lv.STYLE_PAD_ROW = 20 lv.STYLE_PAD_TOP = 16 lv.STYLE_PROP_ANY = 255 lv.STYLE_PROP_CONST = 255 lv.STYLE_PROP_INV = 0 +lv.STYLE_RADIAL_OFFSET = 13 lv.STYLE_RADIUS = 12 +lv.STYLE_RECOLOR = 120 +lv.STYLE_RECOLOR_OPA = 121 lv.STYLE_RES_FOUND = 1 lv.STYLE_RES_NOT_FOUND = 0 -lv.STYLE_ROTARY_SENSITIVITY = 116 +lv.STYLE_ROTARY_SENSITIVITY = 118 lv.STYLE_SHADOW_COLOR = 61 lv.STYLE_SHADOW_OFFSET_X = 64 lv.STYLE_SHADOW_OFFSET_Y = 65 @@ -664,27 +735,35 @@ lv.STYLE_TEXT_FONT = 90 lv.STYLE_TEXT_LETTER_SPACE = 91 lv.STYLE_TEXT_LINE_SPACE = 92 lv.STYLE_TEXT_OPA = 89 -lv.STYLE_TRANSFORM_ANGLE = 110 -lv.STYLE_TRANSFORM_HEIGHT = 105 -lv.STYLE_TRANSFORM_PIVOT_X = 111 -lv.STYLE_TRANSFORM_PIVOT_Y = 112 -lv.STYLE_TRANSFORM_ROTATION = 110 -lv.STYLE_TRANSFORM_SCALE_X = 108 -lv.STYLE_TRANSFORM_SCALE_Y = 109 -lv.STYLE_TRANSFORM_SKEW_X = 113 -lv.STYLE_TRANSFORM_SKEW_Y = 114 -lv.STYLE_TRANSFORM_WIDTH = 104 -lv.STYLE_TRANSITION = 102 -lv.STYLE_TRANSLATE_X = 106 -lv.STYLE_TRANSLATE_Y = 107 +lv.STYLE_TEXT_OUTLINE_STROKE_COLOR = 97 +lv.STYLE_TEXT_OUTLINE_STROKE_OPA = 96 +lv.STYLE_TEXT_OUTLINE_STROKE_WIDTH = 95 +lv.STYLE_TRANSFORM_ANGLE = 112 +lv.STYLE_TRANSFORM_HEIGHT = 107 +lv.STYLE_TRANSFORM_PIVOT_X = 113 +lv.STYLE_TRANSFORM_PIVOT_Y = 114 +lv.STYLE_TRANSFORM_ROTATION = 112 +lv.STYLE_TRANSFORM_SCALE_X = 110 +lv.STYLE_TRANSFORM_SCALE_Y = 111 +lv.STYLE_TRANSFORM_SKEW_X = 115 +lv.STYLE_TRANSFORM_SKEW_Y = 116 +lv.STYLE_TRANSFORM_WIDTH = 106 +lv.STYLE_TRANSITION = 104 +lv.STYLE_TRANSLATE_RADIAL = 119 +lv.STYLE_TRANSLATE_X = 108 +lv.STYLE_TRANSLATE_Y = 109 lv.STYLE_WIDTH = 1 lv.STYLE_X = 8 lv.STYLE_Y = 9 +lv.SWITCH_ORIENTATION_AUTO = 0 +lv.SWITCH_ORIENTATION_HORIZONTAL = 1 +lv.SWITCH_ORIENTATION_VERTICAL = 2 lv.TABLE_CELL_CTRL_CUSTOM_1 = 16 lv.TABLE_CELL_CTRL_CUSTOM_2 = 32 lv.TABLE_CELL_CTRL_CUSTOM_3 = 64 lv.TABLE_CELL_CTRL_CUSTOM_4 = 128 lv.TABLE_CELL_CTRL_MERGE_RIGHT = 1 +lv.TABLE_CELL_CTRL_NONE = 0 lv.TABLE_CELL_CTRL_TEXT_CROP = 2 lv.TABLE_CELL_NONE = 65535 lv.TEXTAREA_CURSOR_LAST = 32767 @@ -692,6 +771,9 @@ lv.TEXT_ALIGN_AUTO = 0 lv.TEXT_ALIGN_CENTER = 2 lv.TEXT_ALIGN_LEFT = 1 lv.TEXT_ALIGN_RIGHT = 3 +lv.TEXT_CMD_STATE_IN = 2 +lv.TEXT_CMD_STATE_PAR = 1 +lv.TEXT_CMD_STATE_WAIT = 0 lv.TEXT_DECOR_NONE = 0 lv.TEXT_DECOR_STRIKETHROUGH = 2 lv.TEXT_DECOR_UNDERLINE = 1 @@ -699,4 +781,7 @@ lv.TEXT_FLAG_BREAK_ALL = 4 lv.TEXT_FLAG_EXPAND = 1 lv.TEXT_FLAG_FIT = 2 lv.TEXT_FLAG_NONE = 0 +lv.TEXT_FLAG_RECOLOR = 8 +lv.TREE_WALK_POST_ORDER = 1 +lv.TREE_WALK_PRE_ORDER = 0 lv.ZOOM_NONE = 256 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 4907c2e24..ead74239f 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 @@ -4705,13 +4705,13 @@ be_local_class(lvh_obj, { be_const_key_weak(_event_map, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { be_const_map( * be_nested_map(7, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_int(7, -1), be_nested_str_weak(up) }, - { be_const_key_int(8, 2), be_nested_str_weak(release) }, + { be_const_key_int(35, -1), be_nested_str_weak(changed) }, + { be_const_key_int(8, 5), be_nested_str_weak(long) }, + { be_const_key_int(9, -1), be_nested_str_weak(hold) }, + { be_const_key_int(10, 6), be_nested_str_weak(up) }, + { be_const_key_int(11, -1), be_nested_str_weak(release) }, { be_const_key_int(1, -1), be_nested_str_weak(down) }, { be_const_key_int(3, -1), be_nested_str_weak(lost) }, - { be_const_key_int(32, -1), be_nested_str_weak(changed) }, - { be_const_key_int(5, -1), be_nested_str_weak(long) }, - { be_const_key_int(6, -1), be_nested_str_weak(hold) }, })) ) } )) }, { be_const_key_weak(register_event_cb, -1), be_const_closure(class_lvh_obj_register_event_cb_closure) }, { be_const_key_weak(get_pad_left, 11), be_const_closure(class_lvh_obj_get_pad_left_closure) }, @@ -4745,7 +4745,7 @@ be_local_class(lvh_obj, { be_const_key_weak(_lv_label, -1), be_const_var(0) }, { be_const_key_weak(get_pad_right, 9), be_const_closure(class_lvh_obj_get_pad_right_closure) }, { be_const_key_weak(set_value_font, -1), be_const_closure(class_lvh_obj_set_value_font_closure) }, - { be_const_key_weak(_EVENTS, 16), be_const_bytes_instance(010703080520) }, + { be_const_key_weak(_EVENTS, 16), be_const_bytes_instance(010A030B0823) }, { be_const_key_weak(get_pad_bottom, 50), be_const_closure(class_lvh_obj_get_pad_bottom_closure) }, { be_const_key_weak(set_text_font, -1), be_const_closure(class_lvh_obj_set_text_font_closure) }, { be_const_key_weak(set_pad_right2, -1), be_const_closure(class_lvh_obj_set_pad_right2_closure) }, diff --git a/lib/libesp32_lvgl/lvgl/LICENCE.txt b/lib/libesp32_lvgl/lvgl/LICENCE.txt index f877abb18..690d2dfd7 100644 --- a/lib/libesp32_lvgl/lvgl/LICENCE.txt +++ b/lib/libesp32_lvgl/lvgl/LICENCE.txt @@ -1,5 +1,5 @@ MIT licence -Copyright (c) 2021 LVGL Kft +Copyright (c) 2025 LVGL Kft 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: diff --git a/lib/libesp32_lvgl/lvgl/README.md b/lib/libesp32_lvgl/lvgl/README.md index aa42b9145..cc3c1a903 100644 --- a/lib/libesp32_lvgl/lvgl/README.md +++ b/lib/libesp32_lvgl/lvgl/README.md @@ -2,7 +2,7 @@

- English | 中文 | Português do Brasil | 日本語 + English | 中文 | Português do Brasil | 日本語


@@ -44,31 +44,31 @@ Our team is ready to help you with graphics design, UI implementation and consul **Free and Portable** - A fully portable C (C++ compatible) library with no external dependencies. - Can be compiled to any MCU or MPU, with any (RT)OS. - - Supports monochrome, ePaper, OLED or TFT displays, or even monitors. [Porting Guide](https://docs.lvgl.io/master/porting/project.html) + - Supports monochrome, ePaper, OLED or TFT displays, or even monitors. [Displays](https://docs.lvgl.io/master/details/main-modules/display/index.html) - Distributed under the MIT license, so you can easily use it in commercial projects too. - Needs only 32kB RAM and 128 kB Flash, a frame buffer, and at least an 1/10 screen sized buffer for rendering. - OS, External memory and GPU are supported but not required. **Widgets, Styles, Layouts and more** - - 30+ built-in [Widgets](https://docs.lvgl.io/master/widgets/index.html):  Button, Label, Slider, Chart, Keyboard, Meter, Arc, Table and many more. - - Flexible [Style system](https://docs.lvgl.io/master/overview/style.html) with  ~100 style properties to customize any part of the widgets in any state. - - [Flexbox](https://docs.lvgl.io/master/layouts/flex.html) and [Grid](https://docs.lvgl.io/master/layouts/grid.html)-like layouts engines to automatically size and position the widgets in a responsive way. + - 30+ built-in [Widgets](https://docs.lvgl.io/master/details/widgets/index.html):  Button, Label, Slider, Chart, Keyboard, Meter, Arc, Table and many more. + - Flexible [Style system](https://docs.lvgl.io/master/details/common-widget-features/styles/style.html) with  ~100 style properties to customize any part of the widgets in any state. + - [Flexbox](https://docs.lvgl.io/master/details/common-widget-features/layouts/flex.html) and [Grid](https://docs.lvgl.io/master/details/common-widget-features/layouts/grid.html)-like layouts engines to automatically size and position the widgets in a responsive way. - Texts are rendered with UTF-8 encoding supporting CJK, Thai, Hindi, Arabic, Persian writing systems. - 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/display.html#multiple-display-support) support. + - Supports Mouse, Touchpad, Keypad, Keyboard, External buttons, Encoder [Input devices](https://docs.lvgl.io/master/details/main-modules/indev.html). + - [Multiple display](https://docs.lvgl.io/master/details/main-modules/display/overview.html#how-many-displays-can-lvgl-use) support. **Binding and Build Support** - [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/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. + - Support for Make and [CMake](https://docs.lvgl.io/master/details/integration/building/cmake.html) is included out of the box. + - [Develop on PC](https://docs.lvgl.io/master/details/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** - - Detailed [Documentation](https://docs.lvgl.io/) with [100+ simple examples](https://docs.lvgl.io/master/index.html) + - Detailed [Documentation](https://docs.lvgl.io/) with [100+ simple examples](https://docs.lvgl.io/master/examples.html) - [Services](https://lvgl.io/services) such as User interface design, Implementation and Consulting to make UI development simpler and faster. ## :heart: Sponsor @@ -88,17 +88,17 @@ If someone implements or fixes an issue labeled as [Sponsored](https://github.co [![Sponsors of LVGL](https://opencollective.com/lvgl/organizations.svg?width=600)](https://opencollective.com/lvgl) **Individuals supporting LVGL**
-[![Backers of LVGL](https://opencollective.com/lvgl/individuals.svg?width=600)](https://opencollective.com/lvgl) +[![Backers of LVGL](https://contrib.rocks/image?repo=lvgl/lvgl&max=48)](https://opencollective.com/lvgl) ## :package: Packages LVGL is available as: -- [Arduino library](https://docs.lvgl.io/master/integration/framework/arduino.html) +- [Arduino library](https://docs.lvgl.io/master/details/integration/framework/arduino.html) - [PlatformIO package](https://registry.platformio.org/libraries/lvgl/lvgl) -- [Zephyr library](https://docs.lvgl.io/master/integration/os/zephyr.html) +- [Zephyr library](https://docs.lvgl.io/master/details/integration/os/zephyr.html) - [ESP-IDF(ESP32) component](https://components.espressif.com/components/lvgl/lvgl) - [NXP MCUXpresso component](https://www.nxp.com/design/software/embedded-software/lvgl-open-source-graphics-library:LITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY) -- [NuttX library](https://docs.lvgl.io/master/integration/os/nuttx.html) -- [RT-Thread RTOS](https://docs.lvgl.io/master/integration/os/rt-thread.html) +- [NuttX library](https://docs.lvgl.io/master/details/integration/os/nuttx.html) +- [RT-Thread RTOS](https://docs.lvgl.io/master/details/integration/os/rt-thread.html) - CMSIS-Pack - [RIOT OS package](https://doc.riot-os.org/group__pkg__lvgl.html#details) @@ -378,7 +378,7 @@ lv_obj_align(rtl_label, LV_ALIGN_LEFT_MID, 5, 0); lv_obj_t * cz_label = lv_label_create(lv_screen_active()); lv_label_set_text(cz_label, "嵌入式系统(Embedded System),\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。"); -lv_obj_set_style_text_font(cz_label, &lv_font_simsun_16_cjk, 0); +lv_obj_set_style_text_font(cz_label, &lv_font_source_han_sans_sc_16_cjk, 0); lv_obj_set_width(cz_label, 310); lv_obj_align(cz_label, LV_ALIGN_BOTTOM_LEFT, 5, -5); ``` @@ -403,10 +403,10 @@ rtl_label.set_style_text_font(lv.font_dejavu_16_persian_hebrew, 0) rtl_label.set_width(310) rtl_label.align(lv.ALIGN.LEFT_MID, 5, 0) -font_simsun_16_cjk = lv.font_load("S:../../assets/font/lv_font_simsun_16_cjk.fnt") +font_hans_sans_16_cjk = lv.font_load("S:../../assets/font/lv_font_source_han_sans_sc_16_cjk.fnt") cz_label = lv.label(lv.screen_active()) -cz_label.set_style_text_font(font_simsun_16_cjk, 0) +cz_label.set_style_text_font(font_hans_sans_16_cjk, 0) cz_label.set_text("嵌入式系统(Embedded System),\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。") cz_label.set_width(310) cz_label.align(lv.ALIGN.BOTTOM_LEFT, 5, -5) @@ -419,25 +419,25 @@ This list will guide you to get started with LVGL step-by-step. **Get Familiar with LVGL** - 1. Check the [Online demos](https://lvgl.io/demos) to see LVGL in action (3 minutes) - 2. Read the [Introduction](https://docs.lvgl.io/master/intro/index.html) page of the documentation (5 minutes) - 3. Get familiar with the basics on the [Quick overview](https://docs.lvgl.io/master/get-started/quick-overview.html) page (15 minutes) + 1. Check the [Online demos](https://lvgl.io/demos) to see LVGL in action (3 minutes). + 2. Read the [Introduction](https://docs.lvgl.io/master/intro/index.html) page of the documentation (5 minutes). + 3. Get familiar with the basics on the [Quick overview](https://docs.lvgl.io/master/intro/getting_started.html#lvgl-basics) page (15 minutes). **Start to Use LVGL** - 4. Set up a [Simulator](https://docs.lvgl.io/master/integration/ide/pc-simulator.html#simulator) (10 minutes) - 5. Try out some [Examples](https://github.com/lvgl/lvgl/tree/master/examples) - 6. Port LVGL to a board. See the [Porting](https://docs.lvgl.io/master/porting/index.html) guide or check the ready to use [Projects](https://github.com/lvgl?q=lv_port_) + 4. Set up a [Simulator](https://docs.lvgl.io/master/details/integration/ide/pc-simulator.html#simulator) (10 minutes). + 5. Try out some [Examples](https://github.com/lvgl/lvgl/tree/master/examples). + 6. Port LVGL to a board. See the [Porting](https://docs.lvgl.io/master/details/integration/adding-lvgl-to-your-project/index.html) guide or check out the ready-to-use [Projects](https://github.com/lvgl?q=lv_port_). **Become a Pro** - 7. Read the [Overview](https://docs.lvgl.io/master/overview/index.html) page to get a better understanding of the library (2-3 hours) - 8. Check the documentation of the [Widgets](https://docs.lvgl.io/master/widgets/index.html) to see their features and usage + 7. Read the [Main-Modules](https://docs.lvgl.io/master/details/main-modules/index.html) page to get a better understanding of the library (2-3 hours) + 8. Check the documentation of the [Widgets](https://docs.lvgl.io/master/details/widgets/index.html) to see their features and usage **Get Help and Help Others** 9. If you have questions go to the [Forum](http://forum.lvgl.io/) - 10. Read the [Contributing](https://docs.lvgl.io/master/CONTRIBUTING.html) guide to see how you can help to improve LVGL (15 minutes) + 10. Read the [Contributing](https://docs.lvgl.io/master/contributing/index.html) guide to see how you can help to improve LVGL (15 minutes) ## :handshake: Services @@ -457,7 +457,7 @@ Check out our [Demos](https://lvgl.io/demos) as reference. For more information ## :star2: Contributing LVGL is an open project and contribution is very welcome. There are many ways to contribute from simply speaking about your project, through writing examples, improving the documentation, fixing bugs or even hosting your own project under the LVGL organization. -For a detailed description of contribution opportunities visit the [Contributing](https://docs.lvgl.io/master/CONTRIBUTING.html) section of the documentation. +For a detailed description of contribution opportunities visit the [Contributing](https://docs.lvgl.io/master/contributing/index.html) section of the documentation. More than 300 people already left their fingerprint in LVGL. Be one them! See you here! :slightly_smiling_face: diff --git a/lib/libesp32_lvgl/lvgl/library.json b/lib/libesp32_lvgl/lvgl/library.json index ccdc959dc..3b386e5a0 100644 --- a/lib/libesp32_lvgl/lvgl/library.json +++ b/lib/libesp32_lvgl/lvgl/library.json @@ -1,6 +1,6 @@ { "name": "lvgl", - "version": "9.2.2", + "version": "9.3.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 79a170e8f..911743009 100644 --- a/lib/libesp32_lvgl/lvgl/library.properties +++ b/lib/libesp32_lvgl/lvgl/library.properties @@ -1,5 +1,5 @@ name=lvgl -version=9.2.2 +version=9.3.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 99e4aee66..9afdf2341 100644 --- a/lib/libesp32_lvgl/lvgl/lv_conf_template.h +++ b/lib/libesp32_lvgl/lvgl/lv_conf_template.h @@ -1,23 +1,23 @@ -/** +/** * @file lv_conf.h - * Configuration file for v9.2.2 + * Configuration file for v9.3.0 */ /* * Copy this file as `lv_conf.h` - * 1. simply next to the `lvgl` folder - * 2. or any other places and - * - define `LV_CONF_INCLUDE_SIMPLE` - * - add the path as include path + * 1. simply next to `lvgl` folder + * 2. or to any other place and + * - define `LV_CONF_INCLUDE_SIMPLE`; + * - add the path as an include path. */ /* clang-format off */ -#if 0 /*Set it to "1" to enable content*/ +#if 0 /* Set this to "1" to enable content */ #ifndef LV_CONF_H #define LV_CONF_H -/*If you need to include anything here, do it inside the `__ASSEMBLY__` guard */ +/* If you need to include anything here, do it inside the `__ASSEMBLY__` guard */ #if 0 && defined(__ASSEMBLY__) #include "my_include.h" #endif @@ -26,14 +26,14 @@ COLOR SETTINGS *====================*/ -/*Color depth: 1 (I1), 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ +/** Color depth: 1 (I1), 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888) */ #define LV_COLOR_DEPTH 16 /*========================= STDLIB WRAPPER SETTINGS *=========================*/ -/* Possible values +/** Possible values * - LV_STDLIB_BUILTIN: LVGL's built in implementation * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc * - LV_STDLIB_MICROPYTHON: MicroPython implementation @@ -41,7 +41,23 @@ * - LV_STDLIB_CUSTOM: Implement the functions externally */ #define LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN + +/** Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ #define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN + +/** Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ #define LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN #define LV_STDINT_INCLUDE @@ -52,15 +68,15 @@ #define LV_STDARG_INCLUDE #if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN - /*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/ - #define LV_MEM_SIZE (64 * 1024U) /*[bytes]*/ + /** Size of memory available for `lv_malloc()` in bytes (>= 2kB) */ + #define LV_MEM_SIZE (64 * 1024U) /**< [bytes] */ - /*Size of the memory expand for `lv_malloc()` in bytes*/ + /** Size of the memory expand for `lv_malloc()` in bytes */ #define LV_MEM_POOL_EXPAND_SIZE 0 - /*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/ - #define LV_MEM_ADR 0 /*0: unused*/ - /*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/ + /** Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too. */ + #define LV_MEM_ADR 0 /**< 0: unused*/ + /* Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc */ #if LV_MEM_ADR == 0 #undef LV_MEM_POOL_INCLUDE #undef LV_MEM_POOL_ALLOC @@ -71,17 +87,17 @@ HAL SETTINGS *====================*/ -/*Default display refresh, input device read and animation step period.*/ -#define LV_DEF_REFR_PERIOD 33 /*[ms]*/ +/** Default display refresh, input device read and animation step period. */ +#define LV_DEF_REFR_PERIOD 33 /**< [ms] */ -/*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings. - *(Not so important, you can adjust it to modify default sizes and spaces)*/ -#define LV_DPI_DEF 130 /*[px/inch]*/ +/** Default Dots Per Inch. Used to initialize default sizes such as widgets sized, style paddings. + * (Not so important, you can adjust it to modify default sizes and spaces.) */ +#define LV_DPI_DEF 130 /**< [px/inch] */ /*================= * OPERATING SYSTEM *=================*/ -/*Select an operating system to use. Possible options: +/** Select operating system to use. Possible options: * - LV_OS_NONE * - LV_OS_PTHREAD * - LV_OS_FREERTOS @@ -89,6 +105,7 @@ * - LV_OS_RTTHREAD * - LV_OS_WINDOWS * - LV_OS_MQX + * - LV_OS_SDL2 * - LV_OS_CUSTOM */ #define LV_USE_OS LV_OS_NONE @@ -96,28 +113,28 @@ #define LV_OS_CUSTOM_INCLUDE #endif #if LV_USE_OS == LV_OS_FREERTOS - /* - * Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM - * than unblocking a task using an intermediary object such as a binary semaphore. - * RTOS task notifications can only be used when there is only one task that can be the recipient of the event. - */ - #define LV_USE_FREERTOS_TASK_NOTIFY 1 + /* + * Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM + * than unblocking a task using an intermediary object such as a binary semaphore. + * RTOS task notifications can only be used when there is only one task that can be the recipient of the event. + */ + #define LV_USE_FREERTOS_TASK_NOTIFY 1 #endif /*======================== * RENDERING CONFIGURATION *========================*/ -/*Align the stride of all layers and images to this bytes*/ +/** Align stride of all layers and images to this bytes */ #define LV_DRAW_BUF_STRIDE_ALIGN 1 -/*Align the start address of draw_buf addresses to this bytes*/ +/** Align 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.*/ +/** Using matrix for transformations. + * Requirements: + * - `LV_USE_MATRIX = 1`. + * - 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 @@ -125,59 +142,79 @@ * "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers * and can't be drawn in chunks. */ -/*The target buffer size for simple layer chunks.*/ -#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /*[bytes]*/ +/** 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. +/* Limit the max allocated memory for simple and transformed layers. + * It should be at least `LV_DRAW_LAYER_SIMPLE_BUF_SIZE` sized but if transformed layers are also used + * it should be enough to store the largest widget too (width x height x 4 area). + * Set it to 0 to have no limit. */ +#define LV_DRAW_LAYER_MAX_MEMORY 0 /**< No limit by default [bytes]*/ + +/** Stack size of 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_DRAW_THREAD_STACK_SIZE (8 * 1024) /**< [bytes]*/ + +/** Thread priority of the drawing task. + * Higher values mean higher priority. + * Can use values from lv_thread_prio_t enum in lv_os.h: LV_THREAD_PRIO_LOWEST, + * LV_THREAD_PRIO_LOW, LV_THREAD_PRIO_MID, LV_THREAD_PRIO_HIGH, LV_THREAD_PRIO_HIGHEST + * Make sure the priority value aligns with the OS-specific priority levels. + * On systems with limited priority levels (e.g., FreeRTOS), a higher value can improve + * rendering performance but might cause other tasks to starve. */ +#define LV_DRAW_THREAD_PRIO LV_THREAD_PRIO_HIGH #define LV_USE_DRAW_SW 1 #if LV_USE_DRAW_SW == 1 + /* + * 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_RGB565_SWAPPED 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_ARGB8888_PREMULTIPLIED 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 - /* - * 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 - */ + /* The threshold of the luminance to consider a pixel as + * active in indexed color format */ + #define LV_DRAW_SW_I1_LUM_THRESHOLD 127 - #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 multiple threads will render the screen in parallel */ + /** Set number of draw units. + * - > 1 requires operating system to be enabled in `LV_USE_OS`. + * - > 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 */ + /** Use Arm-2D to accelerate software (sw) rendering. */ #define LV_USE_DRAW_ARM2D_SYNC 0 - /* Enable native helium assembly to be compiled */ + /** 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 */ + /** + * - 0: Use a simple renderer capable of drawing only simple rectangles with gradient, images, text, 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 #if LV_DRAW_SW_COMPLEX == 1 - /*Allow buffering some shadow calculation. - *LV_DRAW_SW_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius` - *Caching has LV_DRAW_SW_SHADOW_CACHE_SIZE^2 RAM cost*/ + /** Allow buffering some shadow calculation. + * LV_DRAW_SW_SHADOW_CACHE_SIZE is the maximum shadow size to buffer, where shadow size is + * `shadow_width + radius`. Caching has LV_DRAW_SW_SHADOW_CACHE_SIZE^2 RAM cost. */ #define LV_DRAW_SW_SHADOW_CACHE_SIZE 0 - /* Set number of maximally cached circle data. - * The circumference of 1/4 circle are saved for anti-aliasing - * radius * 4 bytes are used per circle (the most often used radiuses are saved) - * 0: to disable caching */ + /** Set number of maximally-cached circle data. + * The circumference of 1/4 circle are saved for anti-aliasing. + * `radius * 4` bytes are used per circle (the most often used radiuses are saved). + * - 0: disables caching */ #define LV_DRAW_SW_CIRCLE_CACHE_SIZE 4 #endif @@ -187,85 +224,139 @@ #define LV_DRAW_SW_ASM_CUSTOM_INCLUDE "" #endif - /* Enable drawing complex gradients in software: linear at an angle, radial or conical */ + /** 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. */ +/*Use TSi's aka (Think Silicon) NemaGFX */ +#define LV_USE_NEMA_GFX 0 + +#if LV_USE_NEMA_GFX + /** Select which NemaGFX HAL to use. Possible options: + * - LV_NEMA_HAL_CUSTOM + * - LV_NEMA_HAL_STM32 */ + #define LV_USE_NEMA_HAL LV_NEMA_HAL_CUSTOM + #if LV_USE_NEMA_HAL == LV_NEMA_HAL_STM32 + #define LV_NEMA_STM32_HAL_INCLUDE + #endif + + /*Enable Vector Graphics Operations. Available only if NemaVG library is present*/ + #define LV_USE_NEMA_VG 0 + #if LV_USE_NEMA_VG + /*Define application's resolution used for VG related buffer allocation */ + #define LV_NEMA_GFX_MAX_RESX 800 + #define LV_NEMA_GFX_MAX_RESY 600 + #endif +#endif + +/** Use NXP's VG-Lite GPU on iMX RTxxx platforms. */ #define LV_USE_DRAW_VGLITE 0 #if LV_USE_DRAW_VGLITE - /* Enable blit quality degradation workaround recommended for screen's dimension > 352 pixels. */ + /** Enable blit quality degradation workaround recommended for screen's dimension > 352 pixels. */ #define LV_USE_VGLITE_BLIT_SPLIT 0 #if LV_USE_OS - /* Use additional draw thread for VG-Lite processing.*/ + /** 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. */ + /** 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. */ + /** Enable VGLite asserts. */ #define LV_USE_VGLITE_ASSERT 0 + + /** Enable VGLite error checks. */ + #define LV_USE_VGLITE_CHECK_ERROR 0 #endif -/* Use NXP's PXP on iMX RTxxx platforms. */ +/** Use NXP's PXP on iMX RTxxx platforms. */ #define LV_USE_PXP 0 #if LV_USE_PXP - /* Use PXP for drawing.*/ + /** Use PXP for drawing.*/ #define LV_USE_DRAW_PXP 1 - /* Use PXP to rotate display.*/ + /** Use PXP to rotate display.*/ #define LV_USE_ROTATE_PXP 0 #if LV_USE_DRAW_PXP && LV_USE_OS - /* Use additional draw thread for PXP processing.*/ + /** Use additional draw thread for PXP processing.*/ #define LV_USE_PXP_DRAW_THREAD 1 #endif - /* Enable PXP asserts. */ + /** Enable PXP asserts. */ #define LV_USE_PXP_ASSERT 0 #endif -/* Use Renesas Dave2D on RA platforms. */ +/** Use NXP's G2D on MPU platforms. */ +#define LV_USE_DRAW_G2D 0 + +#if LV_USE_DRAW_G2D + /** Maximum number of buffers that can be stored for G2D draw unit. + * Includes the frame buffers and assets. */ + #define LV_G2D_HASH_TABLE_SIZE 50 + + #if LV_USE_OS + /** Use additional draw thread for G2D processing.*/ + #define LV_USE_G2D_DRAW_THREAD 1 + #endif + + /** Enable G2D asserts. */ + #define LV_USE_G2D_ASSERT 0 +#endif + +/** Use Renesas Dave2D on RA platforms. */ #define LV_USE_DRAW_DAVE2D 0 -/* Draw using cached SDL textures*/ +/** Draw using cached SDL textures*/ #define LV_USE_DRAW_SDL 0 -/* Use VG-Lite GPU. */ +/** Use VG-Lite GPU. */ #define LV_USE_DRAW_VG_LITE 0 #if LV_USE_DRAW_VG_LITE - /* Enable VG-Lite custom external 'gpu_init()' function */ + /** Enable VG-Lite custom external 'gpu_init()' function */ #define LV_VG_LITE_USE_GPU_INIT 0 - /* Enable VG-Lite assert. */ + /** 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. */ + /** 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 1 - /* VG-Lite gradient maximum cache number. - * NOTE: The memory usage of a single gradient image is 4K bytes. - */ + /** 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. - */ + /** VG-Lite stroke maximum cache number. */ #define LV_VG_LITE_STROKE_CACHE_CNT 32 - #endif +/** Accelerate blends, fills, etc. with STM32 DMA2D */ +#define LV_USE_DRAW_DMA2D 0 + +#if LV_USE_DRAW_DMA2D + #define LV_DRAW_DMA2D_HAL_INCLUDE "stm32h7xx_hal.h" + + /* if enabled, the user is required to call `lv_draw_dma2d_transfer_complete_interrupt_handler` + * upon receiving the DMA2D global interrupt + */ + #define LV_USE_DRAW_DMA2D_INTERRUPT 0 +#endif + +/** Draw using cached OpenGLES textures */ +#define LV_USE_DRAW_OPENGLES 0 + /*======================= * FEATURE CONFIGURATION *=======================*/ @@ -274,79 +365,77 @@ * Logging *-----------*/ -/*Enable the log module*/ +/** Enable log module */ #define LV_USE_LOG 0 #if LV_USE_LOG - - /*How important log should be added: - *LV_LOG_LEVEL_TRACE A lot of logs to give detailed information - *LV_LOG_LEVEL_INFO Log important events - *LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem - *LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail - *LV_LOG_LEVEL_USER Only logs added by the user - *LV_LOG_LEVEL_NONE Do not log anything*/ + /** Set value to one of the following levels of logging detail: + * - LV_LOG_LEVEL_TRACE Log detailed information. + * - LV_LOG_LEVEL_INFO Log important events. + * - LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem. + * - LV_LOG_LEVEL_ERROR Log only critical issues, when system may fail. + * - LV_LOG_LEVEL_USER Log only custom log messages added by the user. + * - LV_LOG_LEVEL_NONE Do not log anything. */ #define LV_LOG_LEVEL LV_LOG_LEVEL_WARN - /*1: Print the log with 'printf'; - *0: User need to register a callback with `lv_log_register_print_cb()`*/ + /** - 1: Print log with 'printf'; + * - 0: User needs 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`*/ + /** Set callback to print 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*/ + /** - 1: Enable printing timestamp; + * - 0: Disable printing timestamp. */ #define LV_LOG_USE_TIMESTAMP 1 - /*1: Print file and line number of the log; - *0: Do not print file and line number of the log*/ + /** - 1: Print file and line number of the log; + * - 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 - #define LV_LOG_TRACE_INDEV 1 - #define LV_LOG_TRACE_DISP_REFR 1 - #define LV_LOG_TRACE_EVENT 1 - #define LV_LOG_TRACE_OBJ_CREATE 1 - #define LV_LOG_TRACE_LAYOUT 1 - #define LV_LOG_TRACE_ANIM 1 - #define LV_LOG_TRACE_CACHE 1 - + /* Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs. */ + #define LV_LOG_TRACE_MEM 1 /**< Enable/disable trace logs in memory operations. */ + #define LV_LOG_TRACE_TIMER 1 /**< Enable/disable trace logs in timer operations. */ + #define LV_LOG_TRACE_INDEV 1 /**< Enable/disable trace logs in input device operations. */ + #define LV_LOG_TRACE_DISP_REFR 1 /**< Enable/disable trace logs in display re-draw operations. */ + #define LV_LOG_TRACE_EVENT 1 /**< Enable/disable trace logs in event dispatch logic. */ + #define LV_LOG_TRACE_OBJ_CREATE 1 /**< Enable/disable trace logs in object creation (core `obj` creation plus every widget). */ + #define LV_LOG_TRACE_LAYOUT 1 /**< Enable/disable trace logs in flex- and grid-layout operations. */ + #define LV_LOG_TRACE_ANIM 1 /**< Enable/disable trace logs in animation logic. */ + #define LV_LOG_TRACE_CACHE 1 /**< Enable/disable trace logs in cache operations. */ #endif /*LV_USE_LOG*/ /*------------- * Asserts *-----------*/ -/*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*/ -#define LV_USE_ASSERT_NULL 1 /*Check if the parameter is NULL. (Very fast, recommended)*/ -#define LV_USE_ASSERT_MALLOC 1 /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/ -#define LV_USE_ASSERT_STYLE 0 /*Check if the styles are properly initialized. (Very fast, recommended)*/ -#define LV_USE_ASSERT_MEM_INTEGRITY 0 /*Check the integrity of `lv_mem` after critical operations. (Slow)*/ -#define LV_USE_ASSERT_OBJ 0 /*Check the object's type and existence (e.g. not deleted). (Slow)*/ +/* Enable assertion failures if an operation fails or invalid data is found. + * If LV_USE_LOG is enabled, an error message will be printed on failure. */ +#define LV_USE_ASSERT_NULL 1 /**< Check if the parameter is NULL. (Very fast, recommended) */ +#define LV_USE_ASSERT_MALLOC 1 /**< Checks is the memory is successfully allocated or no. (Very fast, recommended) */ +#define LV_USE_ASSERT_STYLE 0 /**< Check if the styles are properly initialized. (Very fast, recommended) */ +#define LV_USE_ASSERT_MEM_INTEGRITY 0 /**< Check the integrity of `lv_mem` after critical operations. (Slow) */ +#define LV_USE_ASSERT_OBJ 0 /**< Check the object's type and existence (e.g. not deleted). (Slow) */ -/*Add a custom handler when assert happens e.g. to restart the MCU*/ +/** Add a custom handler when assert happens e.g. to restart MCU. */ #define LV_ASSERT_HANDLER_INCLUDE -#define LV_ASSERT_HANDLER while(1); /*Halt by default*/ +#define LV_ASSERT_HANDLER while(1); /**< Halt by default */ /*------------- * Debug *-----------*/ -/*1: Draw random colored rectangles over the redrawn areas*/ +/** 1: Draw random colored rectangles over the redrawn areas. */ #define LV_USE_REFR_DEBUG 0 -/*1: Draw a red overlay for ARGB layers and a green overlay for RGB layers*/ +/** 1: Draw a red overlay for ARGB layers and a green overlay for RGB layers*/ #define LV_USE_LAYER_DEBUG 0 -/*1: Draw overlays with different colors for each draw_unit's tasks. - *Also add the index number of the draw unit on white background. - *For layers add the index number of the draw unit on black background.*/ +/** 1: Adds the following behaviors for debugging: + * - Draw overlays with different colors for each draw_unit's tasks. + * - Draw index number of draw unit on white background. + * - For layers, draws index number of draw unit on black background. */ #define LV_USE_PARALLEL_DRAW_DEBUG 0 /*------------- @@ -355,132 +444,145 @@ #define LV_ENABLE_GLOBAL_CUSTOM 0 #if LV_ENABLE_GLOBAL_CUSTOM - /*Header to include for the custom 'lv_global' function"*/ + /** Header to include for custom 'lv_global' function" */ #define LV_GLOBAL_CUSTOM_INCLUDE #endif -/*Default cache size in bytes. - *Used by image decoders such as `lv_lodepng` to keep the decoded image in the memory. - *If size is not set to 0, the decoder will fail to decode when the cache is full. - *If size is 0, the cache function is not enabled and the decoded mem will be released immediately after use.*/ +/** Default cache size in bytes. + * Used by image decoders such as `lv_lodepng` to keep the decoded image in memory. + * If size is not set to 0, the decoder will fail to decode when the cache is full. + * If size is 0, the cache function is not enabled and the decoded memory will be + * released immediately after use. */ #define LV_CACHE_DEF_SIZE 0 -/*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.*/ +/** 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 0 -/*Number of stops allowed per gradient. Increase this to allow more stops. - *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/ +/** Number of stops allowed per gradient. Increase this to allow more stops. + * This adds (sizeof(lv_color_t) + 1) bytes per additional stop. */ #define LV_GRADIENT_MAX_STOPS 2 -/* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. - * 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */ +/** Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. + * - 0: round down, + * - 64: round up from x.75, + * - 128: round up from half, + * - 192: round up from x.25, + * - 254: round up */ #define LV_COLOR_MIX_ROUND_OFS 0 -/* Add 2 x 32 bit variables to each lv_obj_t to speed up getting style properties */ +/** Add 2 x 32-bit variables to each `lv_obj_t` to speed up getting style properties */ #define LV_OBJ_STYLE_CACHE 0 -/* Add `id` field to `lv_obj_t` */ +/** Add `id` field to `lv_obj_t` */ #define LV_USE_OBJ_ID 0 -/* Automatically assign an ID when obj is created */ +/** Enable support widget names*/ +#define LV_USE_OBJ_NAME 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: +/** Use 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. +* - lv_obj_stringify_id: Return string-ified identifier, 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*/ +/** Use obj property set/get API. */ #define LV_USE_OBJ_PROPERTY 0 -/*Enable property name support*/ +/** Enable property name support. */ #define LV_USE_OBJ_PROPERTY_NAME 1 -/* VG-Lite Simulator */ -/*Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ +/* Use VG-Lite Simulator. + * - Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ #define LV_USE_VG_LITE_THORVG 0 #if LV_USE_VG_LITE_THORVG - - /*Enable LVGL's blend mode support*/ + /** Enable LVGL's blend mode support */ #define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT 0 - /*Enable YUV color format support*/ + /** Enable YUV color format support */ #define LV_VG_LITE_THORVG_YUV_SUPPORT 0 - /*Enable Linear gradient extension support*/ + /** Enable Linear gradient extension support */ #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT 0 - /*Enable 16 pixels alignment*/ + /** Enable alignment on 16 pixels */ #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1 - /*Buffer address alignment*/ + /** Buffer address alignment */ #define LV_VG_LITE_THORVG_BUF_ADDR_ALIGN 64 - /*Enable multi-thread render*/ + /** Enable multi-thread render */ #define LV_VG_LITE_THORVG_THREAD_RENDER 0 - #endif +/* Enable the multi-touch gesture recognition feature */ +/* Gesture recognition requires the use of floats */ +#define LV_USE_GESTURE_RECOGNITION 0 + /*===================== * COMPILER SETTINGS *====================*/ -/*For big endian systems set to 1*/ +/** For big endian systems set to 1 */ #define LV_BIG_ENDIAN_SYSTEM 0 -/*Define a custom attribute to `lv_tick_inc` function*/ +/** Define a custom attribute for `lv_tick_inc` function */ #define LV_ATTRIBUTE_TICK_INC -/*Define a custom attribute to `lv_timer_handler` function*/ +/** Define a custom attribute for `lv_timer_handler` function */ #define LV_ATTRIBUTE_TIMER_HANDLER -/*Define a custom attribute to `lv_display_flush_ready` function*/ +/** Define a custom attribute for `lv_display_flush_ready` function */ #define LV_ATTRIBUTE_FLUSH_READY -/*Required alignment size for buffers*/ +/** Align VG_LITE buffers on this number of bytes. + * @note vglite_src_buf_aligned() uses this value to validate alignment of passed buffer pointers. */ #define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1 -/*Will be added where memories needs to be aligned (with -Os data might not be aligned to boundary by default). - * E.g. __attribute__((aligned(4)))*/ +/** Will be added where memory needs to be aligned (with -Os data might not be aligned to boundary by default). + * E.g. __attribute__((aligned(4)))*/ #define LV_ATTRIBUTE_MEM_ALIGN -/*Attribute to mark large constant arrays for example font's bitmaps*/ +/** Attribute to mark large constant arrays, for example for font bitmaps */ #define LV_ATTRIBUTE_LARGE_CONST -/*Compiler prefix for a big array declaration in RAM*/ +/** Compiler prefix for a large array declaration in RAM */ #define LV_ATTRIBUTE_LARGE_RAM_ARRAY -/*Place performance critical functions into a faster memory (e.g RAM)*/ +/** Place performance critical functions into a faster memory (e.g RAM) */ #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.*/ -#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/ +/** 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. */ +#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*/ +/** Prefix all global extern data with this */ #define LV_ATTRIBUTE_EXTERN_DATA -/* Use `float` as `lv_value_precise_t` */ +/** Use `float` as `lv_value_precise_t` */ #define LV_USE_FLOAT 0 -/*Enable matrix support - *Requires `LV_USE_FLOAT = 1`*/ +/** 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 +/** Include `lvgl_private.h` in `lvgl.h` to access internal data and functions by default */ +#ifndef LV_USE_PRIVATE_API + #define LV_USE_PRIVATE_API 0 +#endif /*================== * FONT USAGE *===================*/ -/*Montserrat fonts with ASCII range and some symbols using bpp = 4 - *https://fonts.google.com/specimen/Montserrat*/ +/* Montserrat fonts with ASCII range and some symbols using bpp = 4 + * https://fonts.google.com/specimen/Montserrat */ #define LV_FONT_MONTSERRAT_8 0 #define LV_FONT_MONTSERRAT_10 0 #define LV_FONT_MONTSERRAT_12 0 @@ -503,33 +605,41 @@ #define LV_FONT_MONTSERRAT_46 0 #define LV_FONT_MONTSERRAT_48 0 -/*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*/ +/* 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 */ +#define LV_FONT_SOURCE_HAN_SANS_SC_14_CJK 0 /**< 1338 most common CJK radicals */ +#define LV_FONT_SOURCE_HAN_SANS_SC_16_CJK 0 /**< 1338 most common CJK radicals */ -/*Pixel perfect monospace fonts*/ +/** Pixel perfect monospaced fonts */ #define LV_FONT_UNSCII_8 0 #define LV_FONT_UNSCII_16 0 -/*Optionally declare custom fonts here. - *You can use these fonts as default font too and they will be available globally. - *E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/ +/** Optionally declare custom fonts here. + * + * You can use any of these fonts as the default font too and they will be available + * globally. Example: + * + * @code + * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2) + * @endcode + */ #define LV_FONT_CUSTOM_DECLARE -/*Always set a default font*/ +/** Always set a default font */ #define LV_FONT_DEFAULT &lv_font_montserrat_14 -/*Enable handling large font and/or fonts with a lot of characters. - *The limit depends on the font size, font face and bpp. - *Compiler error will be triggered if a font needs it.*/ +/** Enable handling large font and/or fonts with a lot of characters. + * The limit depends on the font size, font face and bpp. + * A compiler error will be triggered if a font needs it. */ #define LV_FONT_FMT_TXT_LARGE 0 -/*Enables/disables support for compressed fonts.*/ +/** Enables/disables support for compressed fonts. */ #define LV_USE_FONT_COMPRESSED 0 -/*Enable drawing placeholders when glyph dsc is not found*/ +/** Enable drawing placeholders when glyph dsc is not found. */ #define LV_USE_FONT_PLACEHOLDER 1 /*================= @@ -538,49 +648,58 @@ /** * Select a character encoding for strings. - * Your IDE or editor should have the same character encoding + * Your IDE or editor should have the same character encoding. * - LV_TXT_ENC_UTF8 * - LV_TXT_ENC_ASCII */ #define LV_TXT_ENC LV_TXT_ENC_UTF8 -/*Can break (wrap) texts on these chars*/ +/** While rendering text strings, break (wrap) text on these chars. */ #define LV_TXT_BREAK_CHARS " ,.;:-_)]}" -/*If a word is at least this long, will break wherever "prettiest" - *To disable, set to a value <= 0*/ +/** If a word is at least this long, will break wherever "prettiest". + * To disable, set to a value <= 0. */ #define LV_TXT_LINE_BREAK_LONG_LEN 0 -/*Minimum number of characters in a long word to put on a line before a break. - *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ +/** Minimum number of characters in a long word to put on a line before a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ #define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 -/*Minimum number of characters in a long word to put on a line after a break. - *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ +/** Minimum number of characters in a long word to put on a line after a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ #define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 -/*Support bidirectional texts. Allows mixing Left-to-Right and Right-to-Left texts. - *The direction will be processed according to the Unicode Bidirectional Algorithm: - *https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/ +/** Support bidirectional text. Allows mixing Left-to-Right and Right-to-Left text. + * The direction will be processed according to the Unicode Bidirectional Algorithm: + * https://www.w3.org/International/articles/inline-bidi-markup/uba-basics */ #define LV_USE_BIDI 0 #if LV_USE_BIDI /*Set the default direction. Supported values: *`LV_BASE_DIR_LTR` Left-to-Right *`LV_BASE_DIR_RTL` Right-to-Left - *`LV_BASE_DIR_AUTO` detect texts base direction*/ + *`LV_BASE_DIR_AUTO` detect text base direction*/ #define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO #endif -/*Enable Arabic/Persian processing - *In these languages characters should be replaced with another form based on their position in the text*/ +/** Enable Arabic/Persian processing + * In these languages characters should be replaced with another form based on their position in the text */ #define LV_USE_ARABIC_PERSIAN_CHARS 0 +/*The control character to use for signaling text recoloring*/ +#define LV_TXT_COLOR_CMD "#" + /*================== * WIDGETS *================*/ +/* Documentation for widgets can be found here: https://docs.lvgl.io/master/details/widgets/index.html . */ -/*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/ - +/** 1: Causes these widgets to be given default values at creation time. + * - lv_buttonmatrix_t: Get default maps: {"Btn1", "Btn2", "Btn3", "\n", "Btn4", "Btn5", ""}, else map not set. + * - lv_checkbox_t : String label set to "Check box", else set to empty string. + * - lv_dropdown_t : Options set to "Option 1", "Option 2", "Option 3", else no values are set. + * - lv_roller_t : Options set to "Option 1", "Option 2", "Option 3", "Option 4", "Option 5", else no values are set. + * - lv_label_t : Text set to "Text", else empty string. + * */ #define LV_WIDGETS_HAS_DEFAULT_VALUE 1 #define LV_USE_ANIMIMG 1 @@ -614,9 +733,9 @@ #define LV_USE_CHECKBOX 1 -#define LV_USE_DROPDOWN 1 /*Requires: lv_label*/ +#define LV_USE_DROPDOWN 1 /**< Requires: lv_label */ -#define LV_USE_IMAGE 1 /*Requires: lv_label*/ +#define LV_USE_IMAGE 1 /**< Requires: lv_label */ #define LV_USE_IMAGEBUTTON 1 @@ -624,9 +743,9 @@ #define LV_USE_LABEL 1 #if LV_USE_LABEL - #define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/ - #define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/ - #define LV_LABEL_WAIT_CHAR_COUNT 3 /*The count of wait chart*/ + #define LV_LABEL_TEXT_SELECTION 1 /**< Enable selecting text of the label */ + #define LV_LABEL_LONG_TXT_HINT 1 /**< Store some extra info in labels to speed up drawing of very long text */ + #define LV_LABEL_WAIT_CHAR_COUNT 3 /**< The count of wait chart */ #endif #define LV_USE_LED 1 @@ -635,21 +754,21 @@ #define LV_USE_LIST 1 -#define LV_USE_LOTTIE 0 /*Requires: lv_canvas, thorvg */ +#define LV_USE_LOTTIE 0 /**< Requires: lv_canvas, thorvg */ #define LV_USE_MENU 1 #define LV_USE_MSGBOX 1 -#define LV_USE_ROLLER 1 /*Requires: lv_label*/ +#define LV_USE_ROLLER 1 /**< Requires: lv_label */ #define LV_USE_SCALE 1 -#define LV_USE_SLIDER 1 /*Requires: lv_bar*/ +#define LV_USE_SLIDER 1 /**< Requires: lv_bar */ #define LV_USE_SPAN 1 #if LV_USE_SPAN - /*A line text can contain maximum num of span descriptor */ + /** A line of text can contain this maximum number of span descriptors. */ #define LV_SPAN_SNIPPET_STACK_SIZE 64 #endif @@ -659,166 +778,182 @@ #define LV_USE_SWITCH 1 -#define LV_USE_TEXTAREA 1 /*Requires: lv_label*/ -#if LV_USE_TEXTAREA != 0 - #define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/ -#endif - #define LV_USE_TABLE 1 #define LV_USE_TABVIEW 1 +#define LV_USE_TEXTAREA 1 /**< Requires: lv_label */ +#if LV_USE_TEXTAREA != 0 + #define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /**< [ms] */ +#endif + #define LV_USE_TILEVIEW 1 #define LV_USE_WIN 1 +#define LV_USE_3DTEXTURE 0 + /*================== * THEMES *==================*/ +/* Documentation for themes can be found here: https://docs.lvgl.io/master/details/common-widget-features/styles/style.html#themes . */ -/*A simple, impressive and very complete theme*/ +/** A simple, impressive and very complete theme */ #define LV_USE_THEME_DEFAULT 1 #if LV_USE_THEME_DEFAULT - - /*0: Light mode; 1: Dark mode*/ + /** 0: Light mode; 1: Dark mode */ #define LV_THEME_DEFAULT_DARK 0 - /*1: Enable grow on press*/ + /** 1: Enable grow on press */ #define LV_THEME_DEFAULT_GROW 1 - /*Default transition time in [ms]*/ + /** Default transition time in ms. */ #define LV_THEME_DEFAULT_TRANSITION_TIME 80 #endif /*LV_USE_THEME_DEFAULT*/ -/*A very simple theme that is a good starting point for a custom theme*/ +/** A very simple theme that is a good starting point for a custom theme */ #define LV_USE_THEME_SIMPLE 1 -/*A theme designed for monochrome displays*/ +/** A theme designed for monochrome displays */ #define LV_USE_THEME_MONO 1 /*================== * LAYOUTS *==================*/ +/* Documentation for layouts can be found here: https://docs.lvgl.io/master/details/common-widget-features/layouts/index.html . */ -/*A layout similar to Flexbox in CSS.*/ +/** A layout similar to Flexbox in CSS. */ #define LV_USE_FLEX 1 -/*A layout similar to Grid in CSS.*/ +/** A layout similar to Grid in CSS. */ #define LV_USE_GRID 1 /*==================== * 3RD PARTS LIBRARIES *====================*/ +/* Documentation for libraries can be found here: https://docs.lvgl.io/master/details/libs/index.html . */ -/*File system interfaces for common APIs */ +/* 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' +/** Setting a default driver letter allows skipping the driver prefix in filepaths. + * Documentation about how to use the below driver-identifier letters can be found at + * https://docs.lvgl.io/master/details/main-modules/fs.html#lv-fs-identifier-letters . */ +#define LV_FS_DEFAULT_DRIVER_LETTER '\0' -/*API for fopen, fread, etc*/ +/** API for fopen, fread, etc. */ #define LV_USE_FS_STDIO 0 #if LV_USE_FS_STDIO - #define LV_FS_STDIO_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ - #define LV_FS_STDIO_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ - #define LV_FS_STDIO_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ + #define LV_FS_STDIO_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_STDIO_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ + #define LV_FS_STDIO_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ #endif -/*API for open, read, etc*/ +/** API for open, read, etc. */ #define LV_USE_FS_POSIX 0 #if LV_USE_FS_POSIX - #define LV_FS_POSIX_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ - #define LV_FS_POSIX_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ - #define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ + #define LV_FS_POSIX_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_POSIX_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ + #define LV_FS_POSIX_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ #endif -/*API for CreateFile, ReadFile, etc*/ +/** API for CreateFile, ReadFile, etc. */ #define LV_USE_FS_WIN32 0 #if LV_USE_FS_WIN32 - #define LV_FS_WIN32_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ - #define LV_FS_WIN32_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ - #define LV_FS_WIN32_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ + #define LV_FS_WIN32_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_WIN32_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ + #define LV_FS_WIN32_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ #endif -/*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/ +/** API for FATFS (needs to be added separately). Uses f_open, f_read, etc. */ #define LV_USE_FS_FATFS 0 #if LV_USE_FS_FATFS - #define LV_FS_FATFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ - #define LV_FS_FATFS_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ + #define LV_FS_FATFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_FATFS_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ + #define LV_FS_FATFS_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ #endif -/*API for memory-mapped file access. */ +/** API for memory-mapped file access. */ #define LV_USE_FS_MEMFS 0 #if LV_USE_FS_MEMFS - #define LV_FS_MEMFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_MEMFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ #endif -/*API for LittleFs. */ +/** API for LittleFs. */ #define LV_USE_FS_LITTLEFS 0 #if LV_USE_FS_LITTLEFS - #define LV_FS_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_LITTLEFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_LITTLEFS_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ #endif -/*API for Arduino LittleFs. */ +/** 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')*/ + #define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_ARDUINO_ESP_LITTLEFS_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ #endif -/*API for Arduino Sd. */ +/** 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')*/ + #define LV_FS_ARDUINO_SD_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_ARDUINO_SD_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ #endif -/*LODEPNG decoder library*/ +/** API for UEFI */ +#define LV_USE_FS_UEFI 0 +#if LV_USE_FS_UEFI + #define LV_FS_UEFI_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ +#endif + +/** LODEPNG decoder library */ #define LV_USE_LODEPNG 0 -/*PNG decoder(libpng) library*/ +/** PNG decoder(libpng) library */ #define LV_USE_LIBPNG 0 -/*BMP decoder library*/ +/** BMP decoder library */ #define LV_USE_BMP 0 -/* JPG + split JPG decoder library. - * Split JPG is a custom format optimized for embedded systems. */ +/** JPG + split JPG decoder library. + * Split JPG is a custom format optimized for embedded systems. */ #define LV_USE_TJPGD 0 -/* libjpeg-turbo decoder library. - * Supports complete JPEG specifications and high-performance JPEG decoding. */ +/** libjpeg-turbo decoder library. + * - Supports complete JPEG specifications and high-performance JPEG decoding. */ #define LV_USE_LIBJPEG_TURBO 0 -/*GIF decoder library*/ +/** GIF decoder library */ #define LV_USE_GIF 0 #if LV_USE_GIF - /*GIF decoder accelerate*/ + /** GIF decoder accelerate */ #define LV_GIF_CACHE_DECODE_DATA 0 #endif -/*Decode bin images to RAM*/ +/** Decode bin images to RAM */ #define LV_BIN_DECODER_RAM_LOAD 0 -/*RLE decompress library*/ +/** RLE decompress library */ #define LV_USE_RLE 0 -/*QR code library*/ +/** QR code library */ #define LV_USE_QRCODE 0 -/*Barcode code library*/ +/** Barcode code library */ #define LV_USE_BARCODE 0 -/*FreeType library*/ +/** FreeType library */ #define LV_USE_FREETYPE 0 #if LV_USE_FREETYPE - /*Let FreeType to use LVGL memory and file porting*/ + /** Let FreeType use LVGL memory and file porting */ #define LV_FREETYPE_USE_LVGL_PORT 0 - /*Cache count of the glyphs in FreeType. It means the number of glyphs that can be cached. - *The higher the value, the more memory will be used.*/ + /** Cache count of glyphs in FreeType, i.e. number of glyphs that can be cached. + * The higher the value, the more memory will be used. */ #define LV_FREETYPE_CACHE_FT_GLYPH_CNT 256 #endif -/* Built-in TTF decoder */ +/** Built-in TTF decoder */ #define LV_USE_TINY_TTF 0 #if LV_USE_TINY_TTF /* Enable loading TTF data from files */ @@ -826,299 +961,433 @@ #define LV_TINY_TTF_CACHE_GLYPH_CNT 256 #endif -/*Rlottie library*/ +/** Rlottie library */ #define LV_USE_RLOTTIE 0 -/*Enable Vector Graphic APIs - *Requires `LV_USE_MATRIX = 1`*/ +/** 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 */ +/** Enable ThorVG (vector graphics library) from the src/libs folder */ #define LV_USE_THORVG_INTERNAL 0 -/* Enable ThorVG by assuming that its installed and linked to the project */ +/** Enable ThorVG by assuming that its installed and linked to the project */ #define LV_USE_THORVG_EXTERNAL 0 -/*Use lvgl built-in LZ4 lib*/ +/** Use lvgl built-in LZ4 lib */ #define LV_USE_LZ4_INTERNAL 0 -/*Use external LZ4 library*/ +/** Use external LZ4 library */ #define LV_USE_LZ4_EXTERNAL 0 -/*FFmpeg library for image decoding and playing videos - *Supports all major image formats so do not enable other image decoder with it*/ +/*SVG library + * - Requires `LV_USE_VECTOR_GRAPHIC = 1` */ +#define LV_USE_SVG 0 +#define LV_USE_SVG_ANIMATION 0 +#define LV_USE_SVG_DEBUG 0 + +/** FFmpeg library for image decoding and playing videos. + * Supports all major image formats so do not enable other image decoder with it. */ #define LV_USE_FFMPEG 0 #if LV_USE_FFMPEG - /*Dump input information to stderr*/ + /** Dump input information to stderr */ #define LV_FFMPEG_DUMP_FORMAT 0 + /** Use lvgl file path in FFmpeg Player widget + * You won't be able to open URLs after enabling this feature. + * Note that FFmpeg image decoder will always use lvgl file system. */ + #define LV_FFMPEG_PLAYER_USE_LV_FS 0 #endif /*================== * OTHERS *==================*/ +/* Documentation for several of the below items can be found here: https://docs.lvgl.io/master/details/auxiliary-modules/index.html . */ -/*1: Enable API to take snapshot for object*/ +/** 1: Enable API to take snapshot for object */ #define LV_USE_SNAPSHOT 0 -/*1: Enable system monitor component*/ +/** 1: Enable system monitor component */ #define LV_USE_SYSMON 0 #if LV_USE_SYSMON - /*Get the idle percentage. E.g. uint32_t my_get_idle(void);*/ - #define LV_SYSMON_GET_IDLE lv_timer_get_idle + /** Get the idle percentage. E.g. uint32_t my_get_idle(void); */ + #define LV_SYSMON_GET_IDLE lv_os_get_idle_percent - /*1: Show CPU usage and FPS count - * Requires `LV_USE_SYSMON = 1`*/ + /** 1: Show CPU usage and FPS count. + * - Requires `LV_USE_SYSMON = 1` */ #define LV_USE_PERF_MONITOR 0 #if LV_USE_PERF_MONITOR #define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT - /*0: Displays performance data on the screen, 1: Prints performance data using log.*/ + /** 0: Displays performance data on the screen; 1: Prints performance data using log. */ #define LV_USE_PERF_MONITOR_LOG_MODE 0 #endif - /*1: Show the used memory and the memory fragmentation - * Requires `LV_USE_STDLIB_MALLOC = LV_STDLIB_BUILTIN` - * Requires `LV_USE_SYSMON = 1`*/ + /** 1: Show used memory and memory fragmentation. + * - Requires `LV_USE_STDLIB_MALLOC = LV_STDLIB_BUILTIN` + * - Requires `LV_USE_SYSMON = 1`*/ #define LV_USE_MEM_MONITOR 0 #if LV_USE_MEM_MONITOR #define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT #endif - #endif /*LV_USE_SYSMON*/ -/*1: Enable the runtime performance profiler*/ +/** 1: Enable runtime performance profiler */ #define LV_USE_PROFILER 0 #if LV_USE_PROFILER - /*1: Enable the built-in profiler*/ + /** 1: Enable the built-in profiler */ #define LV_USE_PROFILER_BUILTIN 1 #if LV_USE_PROFILER_BUILTIN - /*Default profiler trace buffer size*/ - #define LV_PROFILER_BUILTIN_BUF_SIZE (16 * 1024) /*[bytes]*/ + /** Default profiler trace buffer size */ + #define LV_PROFILER_BUILTIN_BUF_SIZE (16 * 1024) /**< [bytes] */ + #define LV_PROFILER_BUILTIN_DEFAULT_ENABLE 1 #endif - /*Header to include for the profiler*/ + /** Header to include for profiler */ #define LV_PROFILER_INCLUDE "lvgl/src/misc/lv_profiler_builtin.h" - /*Profiler start point function*/ + /** Profiler start point function */ #define LV_PROFILER_BEGIN LV_PROFILER_BUILTIN_BEGIN - /*Profiler end point function*/ + /** Profiler end point function */ #define LV_PROFILER_END LV_PROFILER_BUILTIN_END - /*Profiler start point function with custom tag*/ + /** Profiler start point function with custom tag */ #define LV_PROFILER_BEGIN_TAG LV_PROFILER_BUILTIN_BEGIN_TAG - /*Profiler end point function with custom tag*/ + /** Profiler end point function with custom tag */ #define LV_PROFILER_END_TAG LV_PROFILER_BUILTIN_END_TAG + + /*Enable layout profiler*/ + #define LV_PROFILER_LAYOUT 1 + + /*Enable disp refr profiler*/ + #define LV_PROFILER_REFR 1 + + /*Enable draw profiler*/ + #define LV_PROFILER_DRAW 1 + + /*Enable indev profiler*/ + #define LV_PROFILER_INDEV 1 + + /*Enable decoder profiler*/ + #define LV_PROFILER_DECODER 1 + + /*Enable font profiler*/ + #define LV_PROFILER_FONT 1 + + /*Enable fs profiler*/ + #define LV_PROFILER_FS 1 + + /*Enable style profiler*/ + #define LV_PROFILER_STYLE 0 + + /*Enable timer profiler*/ + #define LV_PROFILER_TIMER 1 + + /*Enable cache profiler*/ + #define LV_PROFILER_CACHE 1 + + /*Enable event profiler*/ + #define LV_PROFILER_EVENT 1 #endif -/*1: Enable Monkey test*/ +/** 1: Enable Monkey test */ #define LV_USE_MONKEY 0 -/*1: Enable grid navigation*/ +/** 1: Enable grid navigation */ #define LV_USE_GRIDNAV 0 -/*1: Enable lv_obj fragment*/ +/** 1: Enable `lv_obj` fragment logic */ #define LV_USE_FRAGMENT 0 -/*1: Support using images as font in label or span widgets */ +/** 1: Support using images as font in label or span widgets */ #define LV_USE_IMGFONT 0 -/*1: Enable an observer pattern implementation*/ +/** 1: Enable an observer pattern implementation */ #define LV_USE_OBSERVER 1 -/*1: Enable Pinyin input method*/ -/*Requires: lv_keyboard*/ +/** 1: Enable Pinyin input method + * - Requires: lv_keyboard */ #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 thesaurus*/ + /** 1: Use default thesaurus. + * @note 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*/ + /** Set maximum number of candidate panels that can be displayed. + * @note This needs to be adjusted according to size of screen. */ #define LV_IME_PINYIN_CAND_TEXT_NUM 6 - /*Use 9 key input(k9)*/ + /** Use 9-key input (k9). */ #define LV_IME_PINYIN_USE_K9_MODE 1 #if LV_IME_PINYIN_USE_K9_MODE == 1 #define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3 #endif /*LV_IME_PINYIN_USE_K9_MODE*/ #endif -/*1: Enable file explorer*/ -/*Requires: lv_table*/ +/** 1: Enable file explorer. + * - Requires: lv_table */ #define LV_USE_FILE_EXPLORER 0 #if LV_USE_FILE_EXPLORER - /*Maximum length of path*/ + /** Maximum length of path */ #define LV_FILE_EXPLORER_PATH_MAX_LEN (128) - /*Quick access bar, 1:use, 0:not use*/ - /*Requires: lv_list*/ + /** Quick access bar, 1:use, 0:do not use. + * - Requires: lv_list */ #define LV_FILE_EXPLORER_QUICK_ACCESS 1 #endif +/** 1: Enable Font manager */ +#define LV_USE_FONT_MANAGER 0 +#if LV_USE_FONT_MANAGER + +/**Font manager name max length*/ +#define LV_FONT_MANAGER_NAME_MAX_LEN 32 + +#endif + +/** Enable emulated input devices, time emulation, and screenshot compares. */ +#define LV_USE_TEST 0 +#if LV_USE_TEST + +/** Enable `lv_test_screenshot_compare`. + * Requires libpng and a few MB of extra RAM. */ +#define LV_USE_TEST_SCREENSHOT_COMPARE 0 +#endif /*LV_USE_TEST*/ + +/** Enable loading XML UIs runtime */ +#define LV_USE_XML 0 + +/*1: Enable color filter style*/ +#define LV_USE_COLOR_FILTER 0 /*================== * DEVICES *==================*/ -/*Use SDL to open window on PC and handle mouse and keyboard*/ +/** Use SDL to open window on PC and handle mouse and keyboard. */ #define LV_USE_SDL 0 #if LV_USE_SDL #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_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*/ #endif -/*Use X11 to open window on Linux desktop and handle mouse and keyboard*/ +/** Use X11 to open window on Linux desktop and handle mouse and keyboard */ #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 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*/ + #define LV_X11_DIRECT_EXIT 1 /**< Exit application when all X11 windows have been closed */ + #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 */ +/** 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*/ + #define LV_WAYLAND_BUF_COUNT 1 /**< Use 1 for single buffer with partial render mode or 2 for double buffer with full render mode*/ + #define LV_WAYLAND_USE_DMABUF 0 /**< Use DMA buffers for frame buffers. Requires LV_DRAW_USE_G2D */ + #define LV_WAYLAND_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL /**< DMABUF supports LV_DISPLAY_RENDER_MODE_FULL and LV_DISPLAY_RENDER_MODE_DIRECT*/ + /**< When LV_WAYLAND_USE_DMABUF is disabled, only LV_DISPLAY_RENDER_MODE_PARTIAL is supported*/ + #define LV_WAYLAND_WINDOW_DECORATIONS 0 /**< Draw client side window decorations only necessary on Mutter/GNOME. Not supported using DMABUF*/ + #define LV_WAYLAND_WL_SHELL 0 /**< Use the legacy wl_shell protocol instead of the default XDG shell*/ #endif -/*Driver for /dev/fb*/ +/** Driver for /dev/fb */ #define LV_USE_LINUX_FBDEV 0 #if LV_USE_LINUX_FBDEV #define LV_LINUX_FBDEV_BSD 0 #define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL #define LV_LINUX_FBDEV_BUFFER_COUNT 0 #define LV_LINUX_FBDEV_BUFFER_SIZE 60 + #define LV_LINUX_FBDEV_MMAP 1 #endif -/*Use Nuttx to open window and handle touchscreen*/ +/** Use Nuttx to open window and handle touchscreen */ #define LV_USE_NUTTX 0 #if LV_USE_NUTTX + #define LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP 0 + + /** Use independent image heap for default draw buffer */ + #define LV_NUTTX_DEFAULT_DRAW_BUF_USE_INDEPENDENT_IMAGE_HEAP 0 + #define LV_USE_NUTTX_LIBUV 0 - /*Use Nuttx custom init API to open window and handle touchscreen*/ + /** Use Nuttx custom init API to open window and handle touchscreen */ #define LV_USE_NUTTX_CUSTOM_INIT 0 - /*Driver for /dev/lcd*/ + /** Driver for /dev/lcd */ #define LV_USE_NUTTX_LCD 0 #if LV_USE_NUTTX_LCD #define LV_NUTTX_LCD_BUFFER_COUNT 0 #define LV_NUTTX_LCD_BUFFER_SIZE 60 #endif - /*Driver for /dev/input*/ + /** Driver for /dev/input */ #define LV_USE_NUTTX_TOUCHSCREEN 0 + /*Touchscreen cursor size in pixels(<=0: disable cursor)*/ + #define LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE 0 #endif -/*Driver for /dev/dri/card*/ +/** Driver for /dev/dri/card */ #define LV_USE_LINUX_DRM 0 -/*Interface for TFT_eSPI*/ +#if LV_USE_LINUX_DRM + + /* Use the MESA GBM library to allocate DMA buffers that can be + * shared across sub-systems and libraries using the Linux DMA-BUF API. + * The GBM library aims to provide a platform independent memory management system + * it supports the major GPU vendors - This option requires linking with libgbm */ + #define LV_LINUX_DRM_GBM_BUFFERS 0 +#endif + +/** Interface for TFT_eSPI */ #define LV_USE_TFT_ESPI 0 -/*Driver for evdev input devices*/ +/** Driver for evdev input devices */ #define LV_USE_EVDEV 0 -/*Driver for libinput input devices*/ +/** Driver for libinput input devices */ #define LV_USE_LIBINPUT 0 #if LV_USE_LIBINPUT #define LV_LIBINPUT_BSD 0 - /*Full keyboard support*/ + /** Full keyboard support */ #define LV_LIBINPUT_XKB 0 #if LV_LIBINPUT_XKB - /*"setxkbmap -query" can help find the right values for your keyboard*/ + /** "setxkbmap -query" can help find the right values for your keyboard */ #define LV_LIBINPUT_XKB_KEY_MAP { .rules = NULL, .model = "pc101", .layout = "us", .variant = NULL, .options = NULL } #endif #endif -/*Drivers for LCD devices connected via SPI/parallel port*/ +/* 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_FT81X 0 -#define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) +#if (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) + #define LV_USE_GENERIC_MIPI 1 +#else + #define LV_USE_GENERIC_MIPI 0 +#endif -/*Driver for Renesas GLCD*/ +/** Driver for Renesas GLCD */ #define LV_USE_RENESAS_GLCDC 0 -/* LVGL Windows backend */ +/** Driver for ST LTDC */ +#define LV_USE_ST_LTDC 0 +#if LV_USE_ST_LTDC + /* Only used for partial. */ + #define LV_ST_LTDC_USE_DMA2D_FLUSH 0 +#endif + +/** LVGL Windows backend */ #define LV_USE_WINDOWS 0 -/* Use OpenGL to open window on PC and handle mouse and keyboard */ +/** LVGL UEFI backend */ +#define LV_USE_UEFI 0 +#if LV_USE_UEFI + #define LV_USE_UEFI_INCLUDE "myefi.h" /**< Header that hides the actual framework (EDK2, gnu-efi, ...) */ + #define LV_UEFI_USE_MEMORY_SERVICES 0 /**< Use the memory functions from the boot services table */ +#endif + +/** 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 */ + #define LV_USE_OPENGLES_DEBUG 1 /**< Enable or disable debug for opengles */ #endif -/* QNX Screen display and input drivers */ +/** QNX Screen display and input drivers */ #define LV_USE_QNX 0 #if LV_USE_QNX - #define LV_QNX_BUF_COUNT 1 /*1 or 2*/ + #define LV_QNX_BUF_COUNT 1 /**< 1 or 2 */ #endif -/*================== -* EXAMPLES -*==================*/ +/*===================== +* BUILD OPTIONS +*======================*/ -/*Enable the examples to be built with the library*/ +/** Enable examples to be built with the library. */ #define LV_BUILD_EXAMPLES 1 +/** Build the demos */ +#define LV_BUILD_DEMOS 1 + /*=================== * DEMO USAGE ====================*/ -/*Show some widget. It might be required to increase `LV_MEM_SIZE` */ -#define LV_USE_DEMO_WIDGETS 0 +#if LV_BUILD_DEMOS + /** Show some widgets. This might be required to increase `LV_MEM_SIZE`. */ + #define LV_USE_DEMO_WIDGETS 0 + + /** Demonstrate usage of encoder and keyboard. */ + #define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 + + /** Benchmark your system */ + #define LV_USE_DEMO_BENCHMARK 0 -/*Demonstrate the usage of encoder and keyboard*/ -#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 + #if LV_USE_DEMO_BENCHMARK + /** Use fonts where bitmaps are aligned 16 byte and has Nx16 byte stride */ + #define LV_DEMO_BENCHMARK_ALIGNED_FONTS 0 + #endif -/*Benchmark your system*/ -#define LV_USE_DEMO_BENCHMARK 0 - -/*Render test for each primitives. Requires at least 480x272 display*/ -#define LV_USE_DEMO_RENDER 0 - -/*Stress test for LVGL*/ -#define LV_USE_DEMO_STRESS 0 - -/*Music player demo*/ -#define LV_USE_DEMO_MUSIC 0 -#if LV_USE_DEMO_MUSIC - #define LV_DEMO_MUSIC_SQUARE 0 - #define LV_DEMO_MUSIC_LANDSCAPE 0 - #define LV_DEMO_MUSIC_ROUND 0 - #define LV_DEMO_MUSIC_LARGE 0 - #define LV_DEMO_MUSIC_AUTO_PLAY 0 -#endif - -/*Flex layout demo*/ -#define LV_USE_DEMO_FLEX_LAYOUT 0 - -/*Smart-phone like multi-language demo*/ -#define LV_USE_DEMO_MULTILANG 0 - -/*Widget transformation demo*/ -#define LV_USE_DEMO_TRANSFORM 0 - -/*Demonstrate scroll settings*/ -#define LV_USE_DEMO_SCROLL 0 - -/*Vector graphic demo*/ -#define LV_USE_DEMO_VECTOR_GRAPHIC 0 + /** Render test for each primitive. + * - Requires at least 480x272 display. */ + #define LV_USE_DEMO_RENDER 0 + + /** Stress test for LVGL */ + #define LV_USE_DEMO_STRESS 0 + + /** Music player demo */ + #define LV_USE_DEMO_MUSIC 0 + #if LV_USE_DEMO_MUSIC + #define LV_DEMO_MUSIC_SQUARE 0 + #define LV_DEMO_MUSIC_LANDSCAPE 0 + #define LV_DEMO_MUSIC_ROUND 0 + #define LV_DEMO_MUSIC_LARGE 0 + #define LV_DEMO_MUSIC_AUTO_PLAY 0 + #endif + + /** Vector graphic demo */ + #define LV_USE_DEMO_VECTOR_GRAPHIC 0 + + /*--------------------------- + * Demos from lvgl/lv_demos + ---------------------------*/ + + /** Flex layout demo */ + #define LV_USE_DEMO_FLEX_LAYOUT 0 + + /** Smart-phone like multi-language demo */ + #define LV_USE_DEMO_MULTILANG 0 + + /** Widget transformation demo */ + #define LV_USE_DEMO_TRANSFORM 0 + + /** Demonstrate scroll settings */ + #define LV_USE_DEMO_SCROLL 0 + + /*E-bike demo with Lottie animations (if LV_USE_LOTTIE is enabled)*/ + #define LV_USE_DEMO_EBIKE 0 + #if LV_USE_DEMO_EBIKE + #define LV_DEMO_EBIKE_PORTRAIT 0 /*0: for 480x270..480x320, 1: for 480x800..720x1280*/ + #endif + + /** High-resolution demo */ + #define LV_USE_DEMO_HIGH_RES 0 + + /* Smart watch demo */ + #define LV_USE_DEMO_SMARTWATCH 0 +#endif /* LV_BUILD_DEMOS */ /*--END OF LV_CONF_H--*/ diff --git a/lib/libesp32_lvgl/lvgl/lv_version.h b/lib/libesp32_lvgl/lvgl/lv_version.h index 5767c66c5..8bbd5506e 100644 --- a/lib/libesp32_lvgl/lvgl/lv_version.h +++ b/lib/libesp32_lvgl/lvgl/lv_version.h @@ -7,8 +7,8 @@ #define LVGL_VERSION_H #define LVGL_VERSION_MAJOR 9 -#define LVGL_VERSION_MINOR 2 -#define LVGL_VERSION_PATCH 2 +#define LVGL_VERSION_MINOR 3 +#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 df6140e29..42f958539 100644 --- a/lib/libesp32_lvgl/lvgl/lvgl.h +++ b/lib/libesp32_lvgl/lvgl/lvgl.h @@ -33,12 +33,17 @@ extern "C" { #include "src/misc/lv_profiler_builtin.h" #include "src/misc/lv_rb.h" #include "src/misc/lv_utils.h" +#include "src/misc/lv_iter.h" +#include "src/misc/lv_circle_buf.h" +#include "src/misc/lv_tree.h" +#include "src/misc/cache/lv_cache.h" #include "src/tick/lv_tick.h" #include "src/core/lv_obj.h" #include "src/core/lv_group.h" #include "src/indev/lv_indev.h" +#include "src/indev/lv_indev_gesture.h" #include "src/core/lv_refr.h" #include "src/display/lv_display.h" @@ -78,6 +83,7 @@ extern "C" { #include "src/widgets/textarea/lv_textarea.h" #include "src/widgets/tileview/lv_tileview.h" #include "src/widgets/win/lv_win.h" +#include "src/widgets/3dtexture/lv_3dtexture.h" #include "src/others/snapshot/lv_snapshot.h" #include "src/others/sysmon/lv_sysmon.h" @@ -88,6 +94,10 @@ extern "C" { #include "src/others/observer/lv_observer.h" #include "src/others/ime/lv_ime_pinyin.h" #include "src/others/file_explorer/lv_file_explorer.h" +#include "src/others/font_manager/lv_font_manager.h" +#include "src/others/xml/lv_xml.h" +#include "src/others/xml/lv_xml_component.h" +#include "src/others/test/lv_test.h" #include "src/libs/barcode/lv_barcode.h" #include "src/libs/bin_decoder/lv_bin_decoder.h" @@ -104,13 +114,14 @@ extern "C" { #include "src/libs/rlottie/lv_rlottie.h" #include "src/libs/ffmpeg/lv_ffmpeg.h" #include "src/libs/tiny_ttf/lv_tiny_ttf.h" +#include "src/libs/svg/lv_svg.h" +#include "src/libs/svg/lv_svg_render.h" #include "src/layouts/lv_layout.h" -#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/draw/sw/lv_draw_sw_utils.h" #include "src/themes/lv_theme.h" @@ -124,6 +135,7 @@ extern "C" { #include "src/lvgl_private.h" #endif + /********************* * DEFINES *********************/ diff --git a/lib/libesp32_lvgl/lvgl/lvgl_private.h b/lib/libesp32_lvgl/lvgl/lvgl_private.h new file mode 100644 index 000000000..426a4ca41 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/lvgl_private.h @@ -0,0 +1,127 @@ +/** + * @file lvgl_private.h + * + */ + +#ifndef LVGL_PRIVATE_H +#define LVGL_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "src/core/lv_global.h" + +#include "src/display/lv_display_private.h" +#include "src/indev/lv_indev_private.h" +#include "src/misc/lv_text_private.h" +#include "src/misc/cache/lv_cache_entry_private.h" +#include "src/misc/cache/lv_cache_private.h" +#include "src/layouts/lv_layout_private.h" +#include "src/stdlib/lv_mem_private.h" +#include "src/others/file_explorer/lv_file_explorer_private.h" +#include "src/others/sysmon/lv_sysmon_private.h" +#include "src/others/monkey/lv_monkey_private.h" +#include "src/others/ime/lv_ime_pinyin_private.h" +#include "src/others/fragment/lv_fragment_private.h" +#include "src/others/observer/lv_observer_private.h" +#include "src/others/xml/lv_xml_private.h" +#include "src/libs/qrcode/lv_qrcode_private.h" +#include "src/libs/barcode/lv_barcode_private.h" +#include "src/libs/gif/lv_gif_private.h" +#include "src/draw/lv_draw_triangle_private.h" +#include "src/draw/lv_draw_private.h" +#include "src/draw/lv_draw_rect_private.h" +#include "src/draw/lv_draw_image_private.h" +#include "src/draw/lv_image_decoder_private.h" +#include "src/draw/lv_draw_label_private.h" +#include "src/draw/lv_draw_vector_private.h" +#include "src/draw/lv_draw_buf_private.h" +#include "src/draw/lv_draw_mask_private.h" +#include "src/draw/sw/lv_draw_sw_private.h" +#include "src/draw/sw/lv_draw_sw_mask_private.h" +#include "src/draw/sw/blend/lv_draw_sw_blend_private.h" +#include "src/drivers/libinput/lv_xkb_private.h" +#include "src/drivers/libinput/lv_libinput_private.h" +#include "src/drivers/evdev/lv_evdev_private.h" +#include "src/font/lv_font_fmt_txt_private.h" +#include "src/themes/lv_theme_private.h" +#include "src/core/lv_refr_private.h" +#include "src/core/lv_obj_style_private.h" +#include "src/core/lv_obj_private.h" +#include "src/core/lv_obj_scroll_private.h" +#include "src/core/lv_obj_draw_private.h" +#include "src/core/lv_obj_class_private.h" +#include "src/core/lv_group_private.h" +#include "src/core/lv_obj_event_private.h" +#include "src/misc/lv_timer_private.h" +#include "src/misc/lv_area_private.h" +#include "src/misc/lv_fs_private.h" +#include "src/misc/lv_profiler_builtin_private.h" +#include "src/misc/lv_event_private.h" +#include "src/misc/lv_bidi_private.h" +#include "src/misc/lv_rb_private.h" +#include "src/misc/lv_style_private.h" +#include "src/misc/lv_color_op_private.h" +#include "src/misc/lv_anim_private.h" +#include "src/widgets/msgbox/lv_msgbox_private.h" +#include "src/widgets/buttonmatrix/lv_buttonmatrix_private.h" +#include "src/widgets/slider/lv_slider_private.h" +#include "src/widgets/switch/lv_switch_private.h" +#include "src/widgets/calendar/lv_calendar_private.h" +#include "src/widgets/imagebutton/lv_imagebutton_private.h" +#include "src/widgets/bar/lv_bar_private.h" +#include "src/widgets/image/lv_image_private.h" +#include "src/widgets/textarea/lv_textarea_private.h" +#include "src/widgets/table/lv_table_private.h" +#include "src/widgets/checkbox/lv_checkbox_private.h" +#include "src/widgets/roller/lv_roller_private.h" +#include "src/widgets/win/lv_win_private.h" +#include "src/widgets/keyboard/lv_keyboard_private.h" +#include "src/widgets/line/lv_line_private.h" +#include "src/widgets/animimage/lv_animimage_private.h" +#include "src/widgets/dropdown/lv_dropdown_private.h" +#include "src/widgets/menu/lv_menu_private.h" +#include "src/widgets/chart/lv_chart_private.h" +#include "src/widgets/button/lv_button_private.h" +#include "src/widgets/scale/lv_scale_private.h" +#include "src/widgets/led/lv_led_private.h" +#include "src/widgets/arc/lv_arc_private.h" +#include "src/widgets/tileview/lv_tileview_private.h" +#include "src/widgets/spinbox/lv_spinbox_private.h" +#include "src/widgets/span/lv_span_private.h" +#include "src/widgets/label/lv_label_private.h" +#include "src/widgets/canvas/lv_canvas_private.h" +#include "src/widgets/tabview/lv_tabview_private.h" +#include "src/widgets/3dtexture/lv_3dtexture_private.h" +#include "src/tick/lv_tick_private.h" +#include "src/stdlib/builtin/lv_tlsf_private.h" +#include "src/libs/rlottie/lv_rlottie_private.h" +#include "src/libs/ffmpeg/lv_ffmpeg_private.h" +#include "src/widgets/lottie/lv_lottie_private.h" +#include "src/osal/lv_os_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LVGL_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_global.h b/lib/libesp32_lvgl/lvgl/src/core/lv_global.h index c106e4f50..4515c01c9 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_global.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_global.h @@ -35,6 +35,10 @@ extern "C" { #include "../font/lv_font_fmt_txt_private.h" #endif +#if LV_USE_OS != LV_OS_NONE && defined(__linux__) +#include "../osal/lv_linux_private.h" +#endif + #include "../tick/lv_tick.h" #include "../layouts/lv_layout.h" @@ -49,6 +53,7 @@ extern "C" { #include "../draw/sw/lv_draw_sw_mask_private.h" #include "../stdlib/builtin/lv_tlsf_private.h" #include "../others/sysmon/lv_sysmon_private.h" +#include "../others/test/lv_test_private.h" #include "../layouts/lv_layout_private.h" /********************* @@ -65,18 +70,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 */ @@ -122,6 +127,7 @@ typedef struct lv_global_t { lv_cache_t * img_header_cache; lv_draw_global_info_t draw_info; + lv_ll_t draw_sw_blend_handler_ll; #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 @@ -169,6 +175,10 @@ typedef struct lv_global_t { lv_fs_drv_t win32_fs_drv; #endif +#if LV_USE_FS_UEFI + lv_fs_drv_t uefi_fs_drv; +#endif + #if LV_USE_FS_LITTLEFS lv_fs_drv_t littlefs_fs_drv; #endif @@ -182,7 +192,7 @@ typedef struct lv_global_t { #endif #if LV_USE_FREETYPE - struct lv_freetype_context_t * ft_context; + struct _lv_freetype_context_t * ft_context; #endif #if LV_USE_FONT_COMPRESSED @@ -194,7 +204,7 @@ 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 @@ -214,12 +224,19 @@ typedef struct lv_global_t { uint32_t objid_count; #endif +#if LV_USE_TEST + lv_test_state_t test_state; +#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; +#if defined(__linux__) + lv_proc_stat_t linux_last_proc_stat; +#endif #endif #if LV_USE_OS == LV_OS_FREERTOS @@ -229,6 +246,9 @@ typedef struct lv_global_t { bool freertos_idle_task_running; #endif +#if LV_USE_EVDEV + lv_evdev_discovery_t * evdev_discovery; +#endif void * user_data; } lv_global_t; diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_group.h b/lib/libesp32_lvgl/lvgl/src/core/lv_group.h index e5f267d00..f092848e3 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_group.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_group.h @@ -21,7 +21,7 @@ extern "C" { /********************* * DEFINES *********************/ -/** Predefined keys to control focused object via lv_group_send(group, c) */ +/** Predefined keys to control which Widget has focus via lv_group_send(group, c) */ typedef enum { LV_KEY_UP = 17, /*0x11*/ LV_KEY_DOWN = 18, /*0x12*/ @@ -54,90 +54,91 @@ typedef enum { **********************/ /** - * Create a new object group - * @return pointer to the new object group + * Create new Widget group. + * @return pointer to the new Widget group */ lv_group_t * lv_group_create(void); /** - * Delete a group object + * Delete group object. * @param group pointer to a group */ void lv_group_delete(lv_group_t * group); /** - * Set a default group. New object are added to this group if it's enabled in their class with `add_to_def_group = true` + * Set default group. New Widgets will be added to this group if it's enabled in + * their class with `add_to_def_group = true`. * @param group pointer to a group (can be `NULL`) */ void lv_group_set_default(lv_group_t * group); /** - * Get the default group + * Get default group. * @return pointer to the default group */ lv_group_t * lv_group_get_default(void); /** - * Add an object to a group + * Add an Widget to group. * @param group pointer to a group - * @param obj pointer to an object to add + * @param obj pointer to a Widget to add */ 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 another object + * Swap 2 Widgets in group. Widgets must be in the same group. + * @param obj1 pointer to a Widget + * @param obj2 pointer to another Widget */ void lv_group_swap_obj(lv_obj_t * obj1, lv_obj_t * obj2); /** - * Remove an object from its group - * @param obj pointer to an object to remove + * Remove a Widget from its group. + * @param obj pointer to Widget to remove */ void lv_group_remove_obj(lv_obj_t * obj); /** - * Remove all objects from a group + * Remove all Widgets from a group. * @param group pointer to a group */ void lv_group_remove_all_objs(lv_group_t * group); /** - * Focus on an object (defocus the current) - * @param obj pointer to an object to focus on + * Focus on a Widget (defocus the current). + * @param obj pointer to Widget to focus on */ void lv_group_focus_obj(lv_obj_t * obj); /** - * Focus the next object in a group (defocus the current) + * Focus on next Widget in a group (defocus the current). * @param group pointer to a group */ void lv_group_focus_next(lv_group_t * group); /** - * Focus the previous object in a group (defocus the current) + * Focus on previous Widget in a group (defocus the current). * @param group pointer to a group */ void lv_group_focus_prev(lv_group_t * group); /** - * Do not let to change the focus from the current object + * Do not allow changing focus from current Widget. * @param group pointer to a group * @param en true: freeze, false: release freezing (normal mode) */ void lv_group_focus_freeze(lv_group_t * group, bool en); /** - * Send a control character to the focuses object of a group + * Send a control character to Widget that has focus in a group. * @param group pointer to a group * @param c a character (use LV_KEY_.. to navigate) - * @return result of focused object in group. + * @return result of Widget with focus in group. */ lv_result_t lv_group_send_data(lv_group_t * group, uint32_t c); /** - * Set a function for a group which will be called when a new object is focused + * Set a function for a group which will be called when a new Widget has focus. * @param group pointer to a group * @param focus_cb the call back function or NULL if unused */ @@ -151,8 +152,8 @@ void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb); void lv_group_set_edge_cb(lv_group_t * group, lv_group_edge_cb_t edge_cb); /** - * Set whether the next or previous item in a group is focused if the currently focused obj is - * deleted. + * Set whether the next or previous Widget in a group gets focus when Widget that has + * focus is deleted. * @param group pointer to a group * @param policy new refocus policy enum */ @@ -166,69 +167,71 @@ void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t p void lv_group_set_editing(lv_group_t * group, bool edit); /** - * Set whether focus next/prev will allow wrapping from first->last or last->first object. + * Set whether moving focus to next/previous Widget will allow wrapping from + * first->last or last->first Widget. * @param group pointer to group * @param en true: wrapping enabled; false: wrapping disabled */ void lv_group_set_wrap(lv_group_t * group, bool en); /** - * Get the focused object or NULL if there isn't one + * Get Widget that has focus, or NULL if there isn't one. * @param group pointer to a group - * @return pointer to the focused object + * @return pointer to Widget with focus */ lv_obj_t * lv_group_get_focused(const lv_group_t * group); /** - * Get the focus callback function of a group + * Get focus callback function of a group. * @param group pointer to a group * @return the call back function or NULL if not set */ lv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group); /** - * Get the edge callback function of a group + * Get edge callback function of a group. * @param group pointer to a group * @return the call back function or NULL if not set */ lv_group_edge_cb_t lv_group_get_edge_cb(const lv_group_t * group); /** - * Get the current mode (edit or navigate). + * Get current mode (edit or navigate). * @param group pointer to group * @return true: edit mode; false: navigate mode */ 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. + * Get whether moving focus to next/previous Widget will allow wrapping from + * first->last or last->first Widget. * @param group pointer to group */ bool lv_group_get_wrap(lv_group_t * group); /** - * Get the number of object in the group + * Get number of Widgets in group. * @param group pointer to a group - * @return number of objects in the group + * @return number of Widgets in the group */ uint32_t lv_group_get_obj_count(lv_group_t * group); /** - * Get the nth object within a group + * Get nth Widget within group. * @param group pointer to a group - * @param index index of object within the group - * @return pointer to the object + * @param index index of Widget within the group + * @return pointer to Widget */ lv_obj_t * lv_group_get_obj_by_index(lv_group_t * group, uint32_t index); /** - * Get the number of groups + * Get the number of groups. * @return number of groups */ uint32_t lv_group_get_count(void); /** - * Get a group by its index + * Get a group by its index. * @param index index of the group * @return pointer to the group */ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_group_private.h b/lib/libesp32_lvgl/lvgl/src/core/lv_group_private.h index 33b7640c7..fe5f22b0e 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_group_private.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_group_private.h @@ -28,7 +28,7 @@ extern "C" { * 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 { +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*/ diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj.c b/lib/libesp32_lvgl/lvgl/src/core/lv_obj.c index c58e95502..fa19d4a98 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj.c @@ -187,7 +187,7 @@ const lv_obj_class_t lv_obj_class = { .group_def = LV_OBJ_CLASS_GROUP_DEF_FALSE, .instance_size = (sizeof(lv_obj_t)), .base_class = NULL, - .name = "obj", + .name = "lv_obj", #if LV_USE_OBJ_PROPERTY .prop_index_start = LV_PROPERTY_OBJ_START, .prop_index_end = LV_PROPERTY_OBJ_END, @@ -231,6 +231,8 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent) void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f) { LV_ASSERT_OBJ(obj, MY_CLASS); + if(lv_obj_has_flag(obj, f)) /*Check if all flags are set*/ + return; bool was_on_layout = lv_obj_is_layout_positioned(obj); @@ -268,6 +270,8 @@ void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f) void lv_obj_remove_flag(lv_obj_t * obj, lv_obj_flag_t f) { LV_ASSERT_OBJ(obj, MY_CLASS); + if(!lv_obj_has_flag_any(obj, f)) + return; bool was_on_layout = lv_obj_is_layout_positioned(obj); if(f & LV_OBJ_FLAG_SCROLLABLE) { @@ -281,10 +285,8 @@ void lv_obj_remove_flag(lv_obj_t * obj, lv_obj_flag_t f) if(f & LV_OBJ_FLAG_HIDDEN) { lv_obj_invalidate(obj); - if(lv_obj_is_layout_positioned(obj)) { - lv_obj_mark_layout_as_dirty(lv_obj_get_parent(obj)); - lv_obj_mark_layout_as_dirty(obj); - } + lv_obj_mark_layout_as_dirty(lv_obj_get_parent(obj)); + lv_obj_mark_layout_as_dirty(obj); } if((was_on_layout != lv_obj_is_layout_positioned(obj)) || (f & (LV_OBJ_FLAG_LAYOUT_1 | LV_OBJ_FLAG_LAYOUT_2))) { @@ -293,7 +295,7 @@ void lv_obj_remove_flag(lv_obj_t * obj, lv_obj_flag_t f) } -void lv_obj_update_flag(lv_obj_t * obj, lv_obj_flag_t f, bool v) +void lv_obj_set_flag(lv_obj_t * obj, lv_obj_flag_t f, bool v) { if(v) lv_obj_add_flag(obj, f); else lv_obj_remove_flag(obj, f); @@ -305,11 +307,6 @@ void lv_obj_add_state(lv_obj_t * obj, lv_state_t state) lv_state_t new_state = obj->state | state; if(obj->state != new_state) { - - if(new_state & ~obj->state & LV_STATE_DISABLED) { - lv_indev_reset(NULL, obj); - } - update_obj_state(obj, new_state); } } @@ -439,8 +436,10 @@ void * lv_obj_get_id(const lv_obj_t * obj) return obj->id; } -lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, const void * id) +lv_obj_t * lv_obj_find_by_id(const lv_obj_t * obj, const void * id) { + LV_LOG_WARN("DEPRECATED: IDs are used only to print the widget trees. To find a widget use obj_name"); + if(obj == NULL) obj = lv_display_get_screen_active(NULL); if(obj == NULL) return NULL; @@ -454,7 +453,7 @@ lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, const void * id) /*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); + lv_obj_t * found = lv_obj_find_by_id(child, id); if(found != NULL) return found; } @@ -536,6 +535,18 @@ static void lv_obj_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) } lv_event_remove_all(&obj->spec_attr->event_list); +#if LV_USE_OBJ_NAME + if(obj->spec_attr->name && !obj->spec_attr->name_static) { + lv_free((void *)obj->spec_attr->name); + } +#endif + +#if LV_DRAW_TRANSFORM_USE_MATRIX + if(obj->spec_attr->matrix) { + lv_free(obj->spec_attr->matrix); + obj->spec_attr->matrix = NULL; + } +#endif lv_free(obj->spec_attr); obj->spec_attr = NULL; @@ -582,7 +593,8 @@ static void lv_obj_draw(lv_event_t * e) } if(lv_obj_get_style_bg_grad_dir(obj, 0) != LV_GRAD_DIR_NONE) { - if(lv_obj_get_style_bg_grad_opa(obj, 0) < LV_OPA_MAX) { + if(lv_obj_get_style_bg_grad_opa(obj, 0) < LV_OPA_MAX || + lv_obj_get_style_bg_main_opa(obj, 0) < LV_OPA_MAX) { info->res = LV_COVER_RES_NOT_COVER; return; } @@ -603,6 +615,7 @@ static void lv_obj_draw(lv_event_t * e) lv_layer_t * layer = lv_event_get_layer(e); lv_draw_rect_dsc_t draw_dsc; lv_draw_rect_dsc_init(&draw_dsc); + draw_dsc.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_MAIN, &draw_dsc); /*If the border is drawn later disable loading its properties*/ @@ -623,13 +636,15 @@ static void lv_obj_draw(lv_event_t * e) draw_scrollbar(obj, layer); /*If the border is drawn later disable loading other properties*/ - if(lv_obj_get_style_border_post(obj, LV_PART_MAIN)) { + if(lv_obj_get_style_border_width(obj, LV_PART_MAIN) && + lv_obj_get_style_border_post(obj, LV_PART_MAIN)) { lv_draw_rect_dsc_t draw_dsc; lv_draw_rect_dsc_init(&draw_dsc); draw_dsc.bg_opa = LV_OPA_TRANSP; draw_dsc.bg_image_opa = LV_OPA_TRANSP; draw_dsc.outline_opa = LV_OPA_TRANSP; draw_dsc.shadow_opa = LV_OPA_TRANSP; + draw_dsc.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_MAIN, &draw_dsc); int32_t w = lv_obj_get_style_transform_width(obj, LV_PART_MAIN); diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj.h index 4ae648ffc..49c71aac3 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj.h @@ -252,7 +252,7 @@ void lv_obj_remove_flag(lv_obj_t * obj, lv_obj_flag_t f); * @param f OR-ed values from `lv_obj_flag_t` to update. * @param v true: add the flags; false: remove the flags */ -void lv_obj_update_flag(lv_obj_t * obj, lv_obj_flag_t f, bool v); +void lv_obj_set_flag(lv_obj_t * obj, lv_obj_flag_t f, bool v); /** * Add one or more states to the object. The other state bits will remain unchanged. @@ -399,6 +399,9 @@ void lv_obj_set_id(lv_obj_t * obj, void * id); void * lv_obj_get_id(const lv_obj_t * obj); /** + * DEPRECATED IDs are used only to print the widget trees. + * To find a widget use `lv_obj_find_by_name` + * * 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. @@ -407,7 +410,7 @@ void * lv_obj_get_id(const lv_obj_t * obj); * @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); +lv_obj_t * lv_obj_find_by_id(const lv_obj_t * obj, const void * id); /** * Assign id to object if not previously assigned. @@ -470,7 +473,7 @@ void lv_objid_builtin_destroy(void); LV_ASSERT_MSG(lv_obj_is_valid(obj_p) == true, "The object is invalid, deleted or corrupted?"); \ } while(0) # else -# define LV_ASSERT_OBJ(obj_p, obj_class) do{}while(0) +# define LV_ASSERT_OBJ(obj_p, obj_class) LV_ASSERT_NULL(obj_p) #endif #if LV_USE_LOG && LV_LOG_TRACE_OBJ_CREATE 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 index 1279b9caf..de2b1738e 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_class_private.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_class_private.h @@ -28,7 +28,7 @@ extern "C" { * Describe the common methods of every object. * Similar to a C++ class. */ -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. */ void (*constructor_cb)(const lv_obj_class_t * class_p, lv_obj_t * obj); 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 b3694b9e5..56fa3f95e 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.c @@ -27,6 +27,12 @@ * STATIC PROTOTYPES **********************/ +static inline lv_opa_t get_layer_opa(const lv_obj_t * obj, lv_part_t part, const lv_draw_dsc_base_t * base_dsc); +static lv_color_t normal_apply_layer_recolor(const lv_obj_t * obj, lv_part_t part, const lv_draw_dsc_base_t * base_dsc, + lv_color_t color); +static lv_color32_t image_apply_layer_recolor(const lv_obj_t * obj, lv_part_t part, + const lv_draw_dsc_base_t * base_dsc, lv_color_t color, lv_opa_t opa); + /********************** * STATIC VARIABLES **********************/ @@ -41,10 +47,11 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_t * draw_dsc) { + LV_PROFILER_DRAW_BEGIN; draw_dsc->base.obj = obj; draw_dsc->base.part = part; - lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, part); + lv_opa_t opa = get_layer_opa(obj, part, &draw_dsc->base); if(part != LV_PART_MAIN) { if(opa <= LV_OPA_MIN) { draw_dsc->bg_opa = LV_OPA_TRANSP; @@ -52,6 +59,7 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_ draw_dsc->border_opa = LV_OPA_TRANSP; draw_dsc->outline_opa = LV_OPA_TRANSP; draw_dsc->shadow_opa = LV_OPA_TRANSP; + LV_PROFILER_DRAW_END; return; } } @@ -61,7 +69,8 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_ if(draw_dsc->bg_opa != LV_OPA_TRANSP) { draw_dsc->bg_opa = lv_obj_get_style_bg_opa(obj, part); if(draw_dsc->bg_opa > LV_OPA_MIN) { - draw_dsc->bg_color = lv_obj_get_style_bg_color_filtered(obj, part); + lv_color_t bg_color = lv_obj_get_style_bg_color_filtered(obj, part); + draw_dsc->bg_color = normal_apply_layer_recolor(obj, part, &draw_dsc->base, bg_color); const lv_grad_dsc_t * grad = lv_obj_get_style_bg_grad(obj, part); if(grad && grad->dir != LV_GRAD_DIR_NONE) { lv_memcpy(&draw_dsc->bg_grad, grad, sizeof(*grad)); @@ -69,8 +78,9 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_ else { draw_dsc->bg_grad.dir = lv_obj_get_style_bg_grad_dir(obj, part); if(draw_dsc->bg_grad.dir != LV_GRAD_DIR_NONE) { - draw_dsc->bg_grad.stops[0].color = lv_obj_get_style_bg_color_filtered(obj, part); - draw_dsc->bg_grad.stops[1].color = lv_obj_get_style_bg_grad_color_filtered(obj, part); + draw_dsc->bg_grad.stops[0].color = draw_dsc->bg_color; + lv_color_t bg_grad_color = lv_obj_get_style_bg_grad_color_filtered(obj, part); + draw_dsc->bg_grad.stops[1].color = normal_apply_layer_recolor(obj, part, &draw_dsc->base, bg_grad_color); draw_dsc->bg_grad.stops[0].frac = lv_obj_get_style_bg_main_stop(obj, part); draw_dsc->bg_grad.stops[1].frac = lv_obj_get_style_bg_grad_stop(obj, part); draw_dsc->bg_grad.stops[0].opa = lv_obj_get_style_bg_main_opa(obj, part); @@ -86,7 +96,8 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_ draw_dsc->border_opa = lv_obj_get_style_border_opa(obj, part); if(draw_dsc->border_opa > LV_OPA_MIN) { draw_dsc->border_side = lv_obj_get_style_border_side(obj, part); - draw_dsc->border_color = lv_obj_get_style_border_color_filtered(obj, part); + lv_color_t border_color = lv_obj_get_style_border_color_filtered(obj, part); + draw_dsc->border_color = normal_apply_layer_recolor(obj, part, &draw_dsc->base, border_color); } } } @@ -97,7 +108,8 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_ draw_dsc->outline_opa = lv_obj_get_style_outline_opa(obj, part); if(draw_dsc->outline_opa > LV_OPA_MIN) { draw_dsc->outline_pad = lv_obj_get_style_outline_pad(obj, part); - draw_dsc->outline_color = lv_obj_get_style_outline_color_filtered(obj, part); + lv_color_t outline_color = lv_obj_get_style_outline_color_filtered(obj, part); + draw_dsc->outline_color = normal_apply_layer_recolor(obj, part, &draw_dsc->base, outline_color); } } } @@ -109,11 +121,15 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_ if(draw_dsc->bg_image_opa > LV_OPA_MIN) { if(lv_image_src_get_type(draw_dsc->bg_image_src) == LV_IMAGE_SRC_SYMBOL) { draw_dsc->bg_image_symbol_font = lv_obj_get_style_text_font(obj, part); - draw_dsc->bg_image_recolor = lv_obj_get_style_text_color_filtered(obj, part); + lv_color_t text_color = lv_obj_get_style_text_color_filtered(obj, part); + draw_dsc->bg_image_recolor = normal_apply_layer_recolor(obj, part, &draw_dsc->base, text_color); } else { - draw_dsc->bg_image_recolor = lv_obj_get_style_bg_image_recolor_filtered(obj, part); - draw_dsc->bg_image_recolor_opa = lv_obj_get_style_bg_image_recolor_opa(obj, part); + lv_color_t bg_image_recolor = lv_obj_get_style_bg_image_recolor_filtered(obj, part); + lv_opa_t bg_image_recolor_opa = lv_obj_get_style_bg_image_recolor_opa(obj, part); + lv_color32_t result = image_apply_layer_recolor(obj, part, &draw_dsc->base, bg_image_recolor, bg_image_recolor_opa); + draw_dsc->bg_image_recolor_opa = result.alpha; + draw_dsc->bg_image_recolor = lv_color_make(result.red, result.green, result.blue); draw_dsc->bg_image_tiled = lv_obj_get_style_bg_image_tiled(obj, part); } } @@ -129,7 +145,8 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_ draw_dsc->shadow_offset_x = lv_obj_get_style_shadow_offset_x(obj, part); draw_dsc->shadow_offset_y = lv_obj_get_style_shadow_offset_y(obj, part); draw_dsc->shadow_spread = lv_obj_get_style_shadow_spread(obj, part); - draw_dsc->shadow_color = lv_obj_get_style_shadow_color_filtered(obj, part); + lv_color_t shadow_color = lv_obj_get_style_shadow_color_filtered(obj, part); + draw_dsc->shadow_color = normal_apply_layer_recolor(obj, part, &draw_dsc->base, shadow_color); } } } @@ -142,27 +159,36 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_ draw_dsc->shadow_opa = LV_OPA_MIX2(draw_dsc->shadow_opa, opa); draw_dsc->outline_opa = LV_OPA_MIX2(draw_dsc->outline_opa, opa); } + + LV_PROFILER_DRAW_END; } void lv_obj_init_draw_label_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_label_dsc_t * draw_dsc) { + LV_PROFILER_DRAW_BEGIN; draw_dsc->base.obj = obj; draw_dsc->base.part = part; draw_dsc->opa = lv_obj_get_style_text_opa(obj, part); - if(draw_dsc->opa <= LV_OPA_MIN) return; + if(draw_dsc->opa <= LV_OPA_MIN) { + LV_PROFILER_DRAW_END; + return; + } - lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, part); + lv_opa_t opa = get_layer_opa(obj, part, &draw_dsc->base); if(opa < LV_OPA_MAX) { draw_dsc->opa = LV_OPA_MIX2(draw_dsc->opa, opa); } - if(draw_dsc->opa <= LV_OPA_MIN) return; + if(draw_dsc->opa <= LV_OPA_MIN) { + LV_PROFILER_DRAW_END; + return; + } - draw_dsc->color = lv_obj_get_style_text_color_filtered(obj, part); + lv_color_t text_color = lv_obj_get_style_text_color_filtered(obj, part); + draw_dsc->color = normal_apply_layer_recolor(obj, part, &draw_dsc->base, text_color); draw_dsc->letter_space = lv_obj_get_style_text_letter_space(obj, part); draw_dsc->line_space = lv_obj_get_style_text_line_space(obj, part); draw_dsc->decor = lv_obj_get_style_text_decor(obj, part); - if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); draw_dsc->font = lv_obj_get_style_text_font(obj, part); @@ -171,21 +197,30 @@ void lv_obj_init_draw_label_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_label_ds #endif draw_dsc->align = lv_obj_get_style_text_align(obj, part); + + LV_PROFILER_DRAW_END; } void lv_obj_init_draw_image_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_image_dsc_t * draw_dsc) { + LV_PROFILER_DRAW_BEGIN; draw_dsc->base.obj = obj; draw_dsc->base.part = part; draw_dsc->opa = lv_obj_get_style_image_opa(obj, part); - if(draw_dsc->opa <= LV_OPA_MIN) return; + if(draw_dsc->opa <= LV_OPA_MIN) { + LV_PROFILER_DRAW_END; + return; + } - lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, part); + lv_opa_t opa = get_layer_opa(obj, part, &draw_dsc->base); if(opa < LV_OPA_MAX) { draw_dsc->opa = LV_OPA_MIX2(draw_dsc->opa, opa); } - if(draw_dsc->opa <= LV_OPA_MIN) return; + if(draw_dsc->opa <= LV_OPA_MIN) { + LV_PROFILER_DRAW_END; + return; + } draw_dsc->rotation = 0; draw_dsc->scale_x = LV_SCALE_NONE; @@ -193,30 +228,46 @@ void lv_obj_init_draw_image_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_image_ds draw_dsc->pivot.x = lv_area_get_width(&obj->coords) / 2; draw_dsc->pivot.y = lv_area_get_height(&obj->coords) / 2; - draw_dsc->recolor_opa = lv_obj_get_style_image_recolor_opa(obj, part); - draw_dsc->recolor = lv_obj_get_style_image_recolor_filtered(obj, part); + lv_color_t recolor = lv_obj_get_style_image_recolor_filtered(obj, part); + lv_opa_t recolor_opa = lv_obj_get_style_image_recolor_opa(obj, part); + lv_color32_t result = image_apply_layer_recolor(obj, part, &draw_dsc->base, recolor, recolor_opa); + draw_dsc->recolor_opa = result.alpha; + draw_dsc->recolor = lv_color_make(result.red, result.green, result.blue); if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); + + LV_PROFILER_DRAW_END; } void lv_obj_init_draw_line_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_line_dsc_t * draw_dsc) { + LV_PROFILER_DRAW_BEGIN; draw_dsc->base.obj = obj; draw_dsc->base.part = part; draw_dsc->opa = lv_obj_get_style_line_opa(obj, part); - if(draw_dsc->opa <= LV_OPA_MIN) return; + if(draw_dsc->opa <= LV_OPA_MIN) { + LV_PROFILER_DRAW_END; + return; + } - lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, part); + lv_opa_t opa = get_layer_opa(obj, part, &draw_dsc->base); if(opa < LV_OPA_MAX) { draw_dsc->opa = LV_OPA_MIX2(draw_dsc->opa, opa); } - if(draw_dsc->opa <= LV_OPA_MIN) return; + if(draw_dsc->opa <= LV_OPA_MIN) { + LV_PROFILER_DRAW_END; + return; + } draw_dsc->width = lv_obj_get_style_line_width(obj, part); - if(draw_dsc->width == 0) return; + if(draw_dsc->width == 0) { + LV_PROFILER_DRAW_END; + return; + } - draw_dsc->color = lv_obj_get_style_line_color_filtered(obj, part); + lv_color_t line_color = lv_obj_get_style_line_color_filtered(obj, part); + draw_dsc->color = normal_apply_layer_recolor(obj, part, &draw_dsc->base, line_color); draw_dsc->dash_width = lv_obj_get_style_line_dash_width(obj, part); if(draw_dsc->dash_width) { @@ -226,34 +277,47 @@ void lv_obj_init_draw_line_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_line_dsc_ draw_dsc->round_start = lv_obj_get_style_line_rounded(obj, part); draw_dsc->round_end = draw_dsc->round_start; - if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part); + LV_PROFILER_DRAW_END; } void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_arc_dsc_t * draw_dsc) { + LV_PROFILER_DRAW_BEGIN; draw_dsc->base.obj = obj; draw_dsc->base.part = part; draw_dsc->width = lv_obj_get_style_arc_width(obj, part); - if(draw_dsc->width == 0) return; + if(draw_dsc->width == 0) { + LV_PROFILER_DRAW_END; + return; + } draw_dsc->opa = lv_obj_get_style_arc_opa(obj, part); - if(draw_dsc->opa <= LV_OPA_MIN) return; + if(draw_dsc->opa <= LV_OPA_MIN) { + LV_PROFILER_DRAW_END; + return; + } - lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, part); + lv_opa_t opa = get_layer_opa(obj, part, &draw_dsc->base); if(opa < LV_OPA_MAX) { draw_dsc->opa = LV_OPA_MIX2(draw_dsc->opa, opa); } - if(draw_dsc->opa <= LV_OPA_MIN) return; + if(draw_dsc->opa <= LV_OPA_MIN) { + LV_PROFILER_DRAW_END; + return; + } - draw_dsc->color = lv_obj_get_style_arc_color_filtered(obj, part); + lv_color_t arc_color = lv_obj_get_style_arc_color_filtered(obj, part); + draw_dsc->color = normal_apply_layer_recolor(obj, part, &draw_dsc->base, arc_color); draw_dsc->img_src = lv_obj_get_style_arc_image_src(obj, part); draw_dsc->rounded = lv_obj_get_style_arc_rounded(obj, part); + LV_PROFILER_DRAW_END; } int32_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, lv_part_t part) { + LV_PROFILER_DRAW_BEGIN; int32_t s = 0; int32_t sh_width = lv_obj_get_style_shadow_width(obj, part); @@ -283,11 +347,13 @@ int32_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, lv_part_t part) int32_t wh = LV_MAX(w, h); if(wh > 0) s += wh; + LV_PROFILER_DRAW_END; return s; } void lv_obj_refresh_ext_draw_size(lv_obj_t * obj) { + LV_PROFILER_DRAW_BEGIN; LV_ASSERT_OBJ(obj, MY_CLASS); int32_t s_old = lv_obj_get_ext_draw_size(obj); @@ -306,6 +372,7 @@ void lv_obj_refresh_ext_draw_size(lv_obj_t * obj) } if(s_new != s_old) lv_obj_invalidate(obj); + LV_PROFILER_DRAW_END; } int32_t lv_obj_get_ext_draw_size(const lv_obj_t * obj) @@ -324,3 +391,64 @@ lv_layer_type_t lv_obj_get_layer_type(const lv_obj_t * obj) /********************** * STATIC FUNCTIONS **********************/ + +static inline lv_opa_t get_layer_opa(const lv_obj_t * obj, lv_part_t part, const lv_draw_dsc_base_t * base_dsc) +{ + if(base_dsc->layer) { + /* Accessing the layer opa directly is faster than using get style opa recursive */ + if(part == LV_PART_MAIN) { + return base_dsc->layer->opa; + } + + return LV_OPA_MIX2(base_dsc->layer->opa, lv_obj_get_style_opa(obj, part)); + } + + /* fallback to old recursive style opa */ + return lv_obj_get_style_opa_recursive(obj, part); +} + + +static lv_color_t normal_apply_layer_recolor(const lv_obj_t * obj, lv_part_t part, const lv_draw_dsc_base_t * base_dsc, + lv_color_t color) +{ + lv_color32_t recolor; + + if(base_dsc->layer) { + recolor = base_dsc->layer->recolor; + if(part != LV_PART_MAIN) { + recolor = lv_obj_style_apply_recolor(obj, part, recolor); + } + } + else { + recolor = lv_obj_get_style_recolor_recursive(obj, part); + } + + return lv_color_mix(lv_color_make(recolor.red, recolor.green, recolor.blue), color, recolor.alpha); +} + + +static lv_color32_t image_apply_layer_recolor(const lv_obj_t * obj, lv_part_t part, + const lv_draw_dsc_base_t * base_dsc, lv_color_t color, lv_opa_t opa) +{ + lv_color32_t recolor; + + if(base_dsc->layer) { + recolor = base_dsc->layer->recolor; + if(part != LV_PART_MAIN) { + recolor = lv_obj_style_apply_recolor(obj, part, recolor); + } + } + else { + recolor = lv_obj_get_style_recolor_recursive(obj, part); + } + + if(opa > LV_OPA_TRANSP && recolor.alpha > LV_OPA_TRANSP) { + return lv_color_over32(recolor, lv_color_to_32(color, opa)); + } + else if(recolor.alpha > LV_OPA_TRANSP) { + return recolor; + } + else { + return lv_color_to_32(color, opa); + } +} 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 c0dbee431..9df48c5eb 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_draw.h @@ -19,6 +19,7 @@ extern "C" { #include "../draw/lv_draw_image.h" #include "../draw/lv_draw_line.h" #include "../draw/lv_draw_arc.h" +#include "../draw/lv_draw_triangle.h" /********************* * DEFINES @@ -28,9 +29,23 @@ extern "C" { * TYPEDEFS **********************/ +/** Store the type of layer required to render a widget.*/ typedef enum { + /**No layer is needed. */ LV_LAYER_TYPE_NONE, + + /**Simple layer means that the layer can be rendered in chunks. + * For example with opa_layered = 140 it's possible to render only 10 lines + * from the layer. When it's ready go the the next 10 lines. + * It avoids large memory allocations for the layer buffer. + * The buffer size for a chunk can be set by `LV_DRAW_LAYER_SIMPLE_BUF_SIZE` in lv_conf.h.*/ LV_LAYER_TYPE_SIMPLE, + + /**The widget is transformed and cannot be rendered in chunks. + * It's because - due to the transformations - pixel outside of + * a given area will also contribute to the final image. + * In this case there is no limitation on the buffer size. + * LVGL will allocate as large buffer as needed to render the transformed area.*/ LV_LAYER_TYPE_TRANSFORM, } lv_layer_type_t; 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 3831feeb5..05e01525e 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event.c @@ -86,7 +86,9 @@ lv_result_t lv_obj_event_base(const lv_obj_class_t * class_p, lv_event_t * e) /*Call the actual event callback*/ e->user_data = NULL; + LV_PROFILER_EVENT_BEGIN_TAG(lv_event_code_get_name(e->code)); base->event_cb(base, e); + LV_PROFILER_EVENT_END_TAG(lv_event_code_get_name(e->code)); lv_result_t res = LV_RESULT_OK; /*Stop if the object is deleted*/ @@ -124,23 +126,6 @@ bool lv_obj_remove_event(lv_obj_t * obj, uint32_t index) return lv_event_remove(&obj->spec_attr->event_list, index); } -bool lv_obj_remove_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb) -{ - LV_ASSERT_NULL(obj); - - uint32_t event_cnt = lv_obj_get_event_count(obj); - uint32_t i; - for(i = 0; i < event_cnt; i++) { - lv_event_dsc_t * dsc = lv_obj_get_event_dsc(obj, i); - if(dsc->cb == event_cb) { - lv_obj_remove_event(obj, i); - return true; - } - } - - return false; -} - bool lv_obj_remove_event_dsc(lv_obj_t * obj, lv_event_dsc_t * dsc) { LV_ASSERT_NULL(obj); @@ -149,6 +134,24 @@ bool lv_obj_remove_event_dsc(lv_obj_t * obj, lv_event_dsc_t * dsc) return lv_event_remove_dsc(&obj->spec_attr->event_list, dsc); } +uint32_t lv_obj_remove_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb) +{ + LV_ASSERT_NULL(obj); + + uint32_t event_cnt = lv_obj_get_event_count(obj); + uint32_t removed_count = 0; + uint32_t i; + for(i = 0; i < event_cnt; i++) { + lv_event_dsc_t * dsc = lv_obj_get_event_dsc(obj, i); + if(dsc && dsc->cb == event_cb) { + lv_obj_remove_event(obj, i); + removed_count++; + } + } + + return removed_count; +} + uint32_t lv_obj_remove_event_cb_with_user_data(lv_obj_t * obj, lv_event_cb_t event_cb, void * user_data) { LV_ASSERT_NULL(obj); @@ -157,9 +160,11 @@ uint32_t lv_obj_remove_event_cb_with_user_data(lv_obj_t * obj, lv_event_cb_t eve uint32_t removed_count = 0; int32_t i; + if(event_cnt == 0) return 0; + for(i = event_cnt - 1; i >= 0; i--) { lv_event_dsc_t * dsc = lv_obj_get_event_dsc(obj, i); - if(dsc && dsc->cb == event_cb && dsc->user_data == user_data) { + if(dsc && (event_cb == NULL || dsc->cb == event_cb) && dsc->user_data == user_data) { lv_obj_remove_event(obj, i); removed_count ++; } @@ -371,7 +376,6 @@ static lv_result_t event_send_core(lv_event_t * e) if(parent && event_is_bubbled(e)) { e->current_target = parent; res = event_send_core(e); - 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 2035f1765..53e5d684a 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event.h @@ -86,10 +86,16 @@ lv_event_dsc_t * lv_obj_get_event_dsc(lv_obj_t * obj, uint32_t index); bool lv_obj_remove_event(lv_obj_t * obj, uint32_t index); -bool lv_obj_remove_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb); - bool lv_obj_remove_event_dsc(lv_obj_t * obj, lv_event_dsc_t * dsc); +/** + * Remove an event_cb from an object + * @param obj pointer to a obj + * @param event_cb the event_cb of the event to remove + * @return the count of the event removed + */ +uint32_t lv_obj_remove_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb); + /** * Remove an event_cb with user_data * @param obj pointer to a obj 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 index 731d33248..2199717c4 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event_private.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_event_private.h @@ -31,7 +31,7 @@ extern "C" { * - 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 { +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*/ }; @@ -41,7 +41,7 @@ struct lv_hit_test_info_t { * 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 { +struct _lv_cover_check_info_t { lv_cover_res_t res; const lv_area_t * area; }; 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 0f10d7dcc..708e3f4c6 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.c @@ -10,6 +10,7 @@ #include "../layouts/lv_layout_private.h" #include "lv_obj_event_private.h" #include "lv_obj_draw_private.h" +#include "lv_obj_style_private.h" #include "lv_obj_private.h" #include "../display/lv_display.h" #include "../display/lv_display_private.h" @@ -33,6 +34,7 @@ static int32_t calc_content_width(lv_obj_t * obj); static int32_t calc_content_height(lv_obj_t * obj); static void layout_update_core(lv_obj_t * obj); static void transform_point_array(const lv_obj_t * obj, lv_point_t * p, size_t p_count, bool inv); +static bool is_transformed(const lv_obj_t * obj); /********************** * STATIC VARIABLES @@ -296,7 +298,7 @@ void lv_obj_update_layout(const lv_obj_t * obj) LV_LOG_TRACE("Already running, returning"); return; } - LV_PROFILER_BEGIN; + LV_PROFILER_LAYOUT_BEGIN; update_layout_mutex = true; lv_obj_t * scr = lv_obj_get_screen(obj); @@ -309,7 +311,7 @@ void lv_obj_update_layout(const lv_obj_t * obj) } update_layout_mutex = false; - LV_PROFILER_END; + LV_PROFILER_LAYOUT_END; } void lv_obj_set_align(lv_obj_t * obj, lv_align_t align) @@ -624,8 +626,15 @@ void lv_obj_refr_pos(lv_obj_t * obj) /*Handle percentage value*/ int32_t pw = lv_obj_get_content_width(parent); int32_t ph = lv_obj_get_content_height(parent); - if(LV_COORD_IS_PCT(x)) x = (pw * LV_COORD_GET_PCT(x)) / 100; - if(LV_COORD_IS_PCT(y)) y = (ph * LV_COORD_GET_PCT(y)) / 100; + if(LV_COORD_IS_PCT(x)) { + if(lv_obj_get_style_width(parent, 0) == LV_SIZE_CONTENT) x = 0; /*Avoid circular dependency*/ + else x = (pw * LV_COORD_GET_PCT(x)) / 100; + } + + if(LV_COORD_IS_PCT(y)) { + if(lv_obj_get_style_height(parent, 0) == LV_SIZE_CONTENT) y = 0; /*Avoid circular dependency*/ + y = (ph * LV_COORD_GET_PCT(y)) / 100; + } /*Handle percentage value of translate*/ int32_t tr_x = lv_obj_get_style_translate_x(obj, LV_PART_MAIN); @@ -878,7 +887,9 @@ bool lv_obj_area_is_visible(const lv_obj_t * obj, lv_area_t * area) /*The area is not on the object*/ if(!lv_area_intersect(area, area, &obj_coords)) return false; - lv_obj_get_transformed_area(obj, area, LV_OBJ_POINT_TRANSFORM_FLAG_RECURSIVE); + if(is_transformed(obj)) { + lv_obj_get_transformed_area(obj, area, LV_OBJ_POINT_TRANSFORM_FLAG_RECURSIVE); + } /*Truncate recursively to the parents*/ lv_obj_t * parent = lv_obj_get_parent(obj); @@ -893,7 +904,9 @@ bool lv_obj_area_is_visible(const lv_obj_t * obj, lv_area_t * area) 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(is_transformed(parent)) { + lv_obj_get_transformed_area(parent, &parent_coords, LV_OBJ_POINT_TRANSFORM_FLAG_RECURSIVE); + } if(!lv_area_intersect(area, area, &parent_coords)) return false; parent = lv_obj_get_parent(parent); @@ -972,10 +985,95 @@ void lv_obj_center(lv_obj_t * obj) lv_obj_align(obj, LV_ALIGN_CENTER, 0, 0); } +void lv_obj_set_transform(lv_obj_t * obj, const lv_matrix_t * matrix) +{ +#if LV_DRAW_TRANSFORM_USE_MATRIX + LV_ASSERT_OBJ(obj, MY_CLASS); + + if(!matrix) { + lv_obj_reset_transform(obj); + return; + } + + lv_obj_allocate_spec_attr(obj); + if(!obj->spec_attr->matrix) { + obj->spec_attr->matrix = lv_malloc(sizeof(lv_matrix_t));; + LV_ASSERT_MALLOC(obj->spec_attr->matrix); + } + + /* Invalidate the old area */ + lv_obj_invalidate(obj); + + /* Copy the matrix */ + *obj->spec_attr->matrix = *matrix; + + /* Matrix is set. Update the layer type */ + lv_obj_update_layer_type(obj); + + /* Invalidate the new area */ + lv_obj_invalidate(obj); +#else + LV_UNUSED(obj); + LV_UNUSED(matrix); + LV_LOG_WARN("Transform matrix is not used because LV_DRAW_TRANSFORM_USE_MATRIX is disabled"); +#endif +} + +void lv_obj_reset_transform(lv_obj_t * obj) +{ +#if LV_DRAW_TRANSFORM_USE_MATRIX + LV_ASSERT_OBJ(obj, MY_CLASS); + if(!obj->spec_attr) { + return; + } + + if(!obj->spec_attr->matrix) { + return; + } + + /* Invalidate the old area */ + lv_obj_invalidate(obj); + + /* Free the matrix */ + lv_free(obj->spec_attr->matrix); + obj->spec_attr->matrix = NULL; + + /* Matrix is cleared. Update the layer type */ + lv_obj_update_layer_type(obj); + + /* Invalidate the new area */ + lv_obj_invalidate(obj); +#else + LV_UNUSED(obj); +#endif +} + +const lv_matrix_t * lv_obj_get_transform(const lv_obj_t * obj) +{ +#if LV_DRAW_TRANSFORM_USE_MATRIX + LV_ASSERT_OBJ(obj, MY_CLASS); + if(obj->spec_attr) { + return obj->spec_attr->matrix; + } +#else + LV_UNUSED(obj); +#endif + return NULL; +} + /********************** * STATIC FUNCTIONS **********************/ +static bool is_transformed(const lv_obj_t * obj) +{ + while(obj) { + if(obj->spec_attr && obj->spec_attr->layer_type == LV_LAYER_TYPE_TRANSFORM) return true; + obj = obj->parent; + } + return false; +} + static int32_t calc_content_width(lv_obj_t * obj) { int32_t scroll_x_tmp = lv_obj_get_scroll_x(obj); @@ -1150,6 +1248,31 @@ static void layout_update_core(lv_obj_t * obj) static void transform_point_array(const lv_obj_t * obj, lv_point_t * p, size_t p_count, bool inv) { +#if LV_DRAW_TRANSFORM_USE_MATRIX + const lv_matrix_t * obj_matrix = lv_obj_get_transform(obj); + if(obj_matrix) { + lv_matrix_t m; + lv_matrix_identity(&m); + lv_matrix_translate(&m, obj->coords.x1, obj->coords.y1); + lv_matrix_multiply(&m, obj_matrix); + lv_matrix_translate(&m, -obj->coords.x1, -obj->coords.y1); + + if(inv) { + lv_matrix_t inv_m; + lv_matrix_inverse(&inv_m, &m); + m = inv_m; + } + + for(size_t i = 0; i < p_count; i++) { + lv_point_precise_t p_precise = lv_point_to_precise(&p[i]); + lv_point_precise_t res = lv_matrix_transform_precise_point(&m, &p_precise); + p[i] = lv_point_from_precise(&res); + } + + return; + } +#endif /* LV_DRAW_TRANSFORM_USE_MATRIX */ + int32_t angle = lv_obj_get_style_transform_rotation(obj, 0); int32_t scale_x = lv_obj_get_style_transform_scale_x_safe(obj, 0); int32_t scale_y = lv_obj_get_style_transform_scale_y_safe(obj, 0); 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 584f0b7e8..eab91b2a2 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_pos.h @@ -149,13 +149,13 @@ bool lv_obj_is_layout_positioned(const lv_obj_t * obj); /** * Mark the object for layout update. - * @param obj pointer to an object whose children needs to be updated + * @param obj pointer to an object whose children need to be updated */ void lv_obj_mark_layout_as_dirty(lv_obj_t * obj); /** * Update the layout of an object. - * @param obj pointer to an object whose children needs to be updated + * @param obj pointer to an object whose position and size needs to be updated */ void lv_obj_update_layout(const lv_obj_t * obj); @@ -197,6 +197,21 @@ void lv_obj_align_to(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, in */ void lv_obj_center(lv_obj_t * obj); +/** + * Set the transform matrix of an object + * @param obj pointer to an object + * @param matrix pointer to a matrix to set + * @note `LV_DRAW_TRANSFORM_USE_MATRIX` needs to be enabled. + */ +void lv_obj_set_transform(lv_obj_t * obj, const lv_matrix_t * matrix); + +/** + * Reset the transform matrix of an object to identity matrix + * @param obj pointer to an object + * @note `LV_DRAW_TRANSFORM_USE_MATRIX` needs to be enabled. + */ +void lv_obj_reset_transform(lv_obj_t * obj); + /** * Copy the coordinates of an object to an area * @param obj pointer to an object @@ -342,6 +357,13 @@ void lv_obj_move_to(lv_obj_t * obj, int32_t x, int32_t y); void lv_obj_move_children_by(lv_obj_t * obj, int32_t x_diff, int32_t y_diff, bool ignore_floating); +/** + * Get the transform matrix of an object + * @param obj pointer to an object + * @return pointer to the transform matrix or NULL if not set + */ +const lv_matrix_t * lv_obj_get_transform(const lv_obj_t * obj); + /** * Transform a point using the angle and zoom style properties of an object * @param obj pointer to an object whose style properties should be used diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_private.h b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_private.h index d9eee4939..5b1100fb8 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_private.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_private.h @@ -28,11 +28,16 @@ extern "C" { * Special, rarely used attributes. * They are allocated automatically if any elements is set. */ -struct lv_obj_spec_attr_t { +struct _lv_obj_spec_attr_t { lv_obj_t ** children; /**< Store the pointer of the children in an array.*/ lv_group_t * group_p; +#if LV_DRAW_TRANSFORM_USE_MATRIX + lv_matrix_t * matrix; /**< The transform matrix*/ +#endif lv_event_list_t event_list; - +#if LV_USE_OBJ_NAME + const char * name; /**< Pointer to the name */ +#endif lv_point_t scroll; /**< The current X/Y scroll offset*/ int32_t ext_click_pad; /**< Extra click padding in all direction*/ @@ -44,9 +49,10 @@ struct lv_obj_spec_attr_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 */ + uint16_t name_static : 1; /**< 1: `name` was not dynamically allocated */ }; -struct lv_obj_t { +struct _lv_obj_t { const lv_obj_class_t * class_p; lv_obj_t * parent; lv_obj_spec_attr_t * spec_attr; 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 405b00674..7f45e6c7f 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.c @@ -19,24 +19,72 @@ * DEFINES *********************/ +#define HANDLE_PROPERTY_TYPE(type, field) \ + if(!set) { \ + value->field = ((lv_property_get_##type##_t)(prop->getter))(obj); \ + } else { \ + switch(LV_PROPERTY_ID_TYPE2(prop->id)) { \ + case LV_PROPERTY_ID_INVALID: \ + ((lv_property_set_##type##_t)(prop->setter))(obj, value->field); \ + break; \ + case LV_PROPERTY_TYPE_INT: \ + ((lv_property_set_##type##_integer_t)(prop->setter))(obj, value->arg1.field, value->arg2.num); \ + break; \ + case LV_PROPERTY_TYPE_BOOL: \ + ((lv_property_set_##type##_boolean_t)(prop->setter))(obj, value->arg1.field, value->arg2.enable); \ + break; \ + case LV_PROPERTY_TYPE_PRECISE: \ + ((lv_property_set_##type##_precise_t)(prop->setter))(obj, value->arg1.field, value->arg2.precise); \ + break; \ + case LV_PROPERTY_TYPE_COLOR: \ + ((lv_property_set_##type##_color_t)(prop->setter))(obj, value->arg1.field, value->arg2.color); \ + break; \ + case LV_PROPERTY_TYPE_POINTER: \ + case LV_PROPERTY_TYPE_IMGSRC: \ + case LV_PROPERTY_TYPE_TEXT: \ + case LV_PROPERTY_TYPE_OBJ: \ + case LV_PROPERTY_TYPE_DISPLAY: \ + case LV_PROPERTY_TYPE_FONT: \ + ((lv_property_set_##type##_pointer_t)(prop->setter))(obj, value->arg1.field, value->arg2.ptr); \ + break; \ + } \ + } + + /********************** * TYPEDEFS **********************/ -typedef void (*lv_property_set_int_t)(lv_obj_t *, int32_t); -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 int32_t integer; +typedef bool boolean; +typedef lv_value_precise_t precise; +typedef lv_color_t color; +typedef const void * pointer; + +#define DEFINE_PROPERTY_SETTER_TYPES(type) \ + typedef void (*lv_property_set_##type##_t)(lv_obj_t *, type); \ + typedef void (*lv_property_set_##type##_integer_t)(lv_obj_t *, type, int32_t); \ + typedef void (*lv_property_set_##type##_boolean_t)(lv_obj_t *, type, bool); \ + typedef void (*lv_property_set_##type##_precise_t)(lv_obj_t *, type, lv_value_precise_t); \ + typedef void (*lv_property_set_##type##_color_t)(lv_obj_t *, type, lv_color_t); \ + typedef void (*lv_property_set_##type##_pointer_t)(lv_obj_t *, type, const void *) + +DEFINE_PROPERTY_SETTER_TYPES(integer); +DEFINE_PROPERTY_SETTER_TYPES(boolean); +DEFINE_PROPERTY_SETTER_TYPES(precise); +DEFINE_PROPERTY_SETTER_TYPES(color); +DEFINE_PROPERTY_SETTER_TYPES(pointer); + 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 bool (*lv_property_get_bool_t)(const lv_obj_t *); +typedef integer(*lv_property_get_integer_t)(const lv_obj_t *); +typedef bool (*lv_property_get_boolean_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_point_t (*lv_property_get_point_t)(lv_obj_t *); + typedef lv_result_t (*lv_property_getter_t)(const lv_obj_t *, lv_prop_id_t, lv_property_t *); /********************** @@ -240,41 +288,30 @@ 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_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_INT: + HANDLE_PROPERTY_TYPE(integer, num); + break; + case LV_PROPERTY_TYPE_BOOL: + HANDLE_PROPERTY_TYPE(boolean, enable); + break; + case LV_PROPERTY_TYPE_PRECISE: + HANDLE_PROPERTY_TYPE(precise, precise); + break; + case LV_PROPERTY_TYPE_COLOR: + HANDLE_PROPERTY_TYPE(color, color); + break; case LV_PROPERTY_TYPE_POINTER: case LV_PROPERTY_TYPE_IMGSRC: 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); + case LV_PROPERTY_TYPE_FONT: + HANDLE_PROPERTY_TYPE(pointer, ptr); + 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; } default: { 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 4c8c142f4..5cd16aa2d 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_property.h @@ -37,9 +37,12 @@ extern "C" { #define LV_PROPERTY_TYPE_BOOL 11 /*int32_t type*/ #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_TYPE2_SHIFT 24 +#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_ID2(clz, name, type, type2, index) LV_PROPERTY_ID(clz, name, type, index) | ((type2) << LV_PROPERTY_TYPE2_SHIFT) #define LV_PROPERTY_ID_TYPE(id) ((id) >> LV_PROPERTY_TYPE_SHIFT) +#define LV_PROPERTY_ID_TYPE2(id) ((id) >> LV_PROPERTY_TYPE_SHIFT) #define LV_PROPERTY_ID_INDEX(id) ((id) & 0xfffffff) /*Set properties from an array of lv_property_t*/ @@ -68,6 +71,8 @@ enum { 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_PROPERTY_SLIDER_START = 0x0800, /* lv_slider.c */ + LV_PROPERTY_ANIMIMAGE_START = 0x0900, /* lv_animimage.c */ /*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*/ @@ -75,7 +80,7 @@ enum { LV_PROPERTY_ID_ANY = 0x7ffffffe, /*Special ID used by lvgl to intercept all setter/getter call.*/ }; -struct lv_property_name_t { +struct _lv_property_name_t { const char * name; lv_prop_id_t id; }; @@ -83,12 +88,14 @@ struct lv_property_name_t { 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_point_t point; /**< Point*/ + int32_t num; /**< Signed integer number (enums or "normal" numbers)*/ + uint32_t num_u; /**< Unsigned integer number (opacity, Booleans) */ + 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_point_t point; /**< Point, contains two int32_t */ + struct { /** * Note that place struct member `style` at first place is intended. @@ -113,6 +120,21 @@ typedef struct { 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 */ }; + + /** + * For some properties like slider range, it contains two simple (4-byte) values + * so we can use `arg1.num` and `arg2.num` to set the argument. + */ + struct { + union { + int32_t num; + uint32_t num_u; + bool enable; + const void * ptr; + lv_color_t color; + lv_value_precise_t precise; + } arg1, arg2; + }; }; } lv_property_t; @@ -132,19 +154,19 @@ typedef struct { *====================*/ /** - * Set widget property. - * @param obj pointer to an object - * @param value The property value to set - * @return return LV_RESULT_OK if success + * Set Widget property. + * @param obj pointer to Widget + * @param value property value to set + * @return return LV_RESULT_OK if call succeeded */ 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 + * Set multiple Widget properties. Helper `LV_OBJ_SET_PROPERTY_ARRAY` can be used for constant property array. + * @param obj pointer to Widget + * @param value property value array to set + * @param count number of array elements + * @return return LV_RESULT_OK if call succeeded */ lv_result_t lv_obj_set_properties(lv_obj_t * obj, const lv_property_t * value, uint32_t count); @@ -153,41 +175,44 @@ lv_result_t lv_obj_set_properties(lv_obj_t * obj, const lv_property_t * value, u *====================*/ /** - * 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 to read - * @return return the property value read. The returned property ID is set to `LV_PROPERTY_ID_INVALID` if failed. + * Read property value from Widget. + * If id is a style property. Style selector is 0 by default. + * @param obj pointer to Widget + * @param id ID of property to read + * @return return property value read. The returned property ID is set to `LV_PROPERTY_ID_INVALID` if read 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 + * Read style property value from Widget + * @param obj pointer to Widget * @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. + * @param selector selector for style property + * @return return property value read. The returned property ID is set to `LV_PROPERTY_ID_INVALID` if read 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. + * Get property ID by recursively searching for name in Widget's class hierarchy, and + * if still not found, then search style properties. + * Requires to enabling `LV_USE_OBJ_PROPERTY_NAME`. + * @param obj pointer to Widget whose class and base-class hierarchy are to be searched. * @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. + * Get property ID by doing a non-recursive search for name directly in Widget class properties. + * Requires enabling `LV_USE_OBJ_PROPERTY_NAME`. + * @param clz pointer to Widget class that has specified property. * @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`. + * Get style property ID by name. Requires enabling `LV_USE_OBJ_PROPERTY_NAME`. * @param name property name * @return property ID found or `LV_PROPERTY_ID_INVALID` if not found. */ 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 fa5e16fc9..f8c7d7902 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll.c @@ -127,13 +127,13 @@ int32_t lv_obj_get_scroll_y(const lv_obj_t * obj) return -obj->spec_attr->scroll.y; } -int32_t lv_obj_get_scroll_top(lv_obj_t * obj) +int32_t lv_obj_get_scroll_top(const lv_obj_t * obj) { if(obj->spec_attr == NULL) return 0; return -obj->spec_attr->scroll.y; } -int32_t lv_obj_get_scroll_bottom(lv_obj_t * obj) +int32_t lv_obj_get_scroll_bottom(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -141,7 +141,7 @@ int32_t lv_obj_get_scroll_bottom(lv_obj_t * obj) 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]; + const lv_obj_t * child = obj->spec_attr->children[i]; if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue; int32_t tmp_y = child->coords.y2 + lv_obj_get_style_margin_bottom(child, LV_PART_MAIN); @@ -161,7 +161,7 @@ int32_t lv_obj_get_scroll_bottom(lv_obj_t * obj) return LV_MAX(child_res, self_h); } -int32_t lv_obj_get_scroll_left(lv_obj_t * obj) +int32_t lv_obj_get_scroll_left(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -182,7 +182,7 @@ int32_t lv_obj_get_scroll_left(lv_obj_t * obj) int32_t x1 = LV_COORD_MAX; 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]; + const lv_obj_t * child = obj->spec_attr->children[i]; if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue; int32_t tmp_x = child->coords.x1 - lv_obj_get_style_margin_left(child, LV_PART_MAIN); @@ -204,7 +204,7 @@ int32_t lv_obj_get_scroll_left(lv_obj_t * obj) return LV_MAX(child_res, self_w); } -int32_t lv_obj_get_scroll_right(lv_obj_t * obj) +int32_t lv_obj_get_scroll_right(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -220,7 +220,7 @@ int32_t lv_obj_get_scroll_right(lv_obj_t * obj) 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]; + const lv_obj_t * child = obj->spec_attr->children[i]; if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue; int32_t tmp_x = child->coords.x2 + lv_obj_get_style_margin_right(child, LV_PART_MAIN); @@ -306,7 +306,7 @@ void lv_obj_scroll_by_bounded(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_en void lv_obj_scroll_by(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_enable_t anim_en) { if(dx == 0 && dy == 0) return; - if(anim_en == LV_ANIM_ON) { + if(anim_en) { lv_display_t * d = lv_obj_get_display(obj); lv_anim_t a; lv_anim_init(&a); @@ -434,9 +434,20 @@ bool lv_obj_is_scrolling(const lv_obj_t * obj) indev = lv_indev_get_next(indev); } + if(lv_anim_get((lv_obj_t *)obj, scroll_x_anim) != NULL || + lv_anim_get((lv_obj_t *)obj, scroll_y_anim) != NULL) { + return true; + } + return false; } +void lv_obj_stop_scroll_anim(const lv_obj_t * obj) +{ + lv_anim_delete((lv_obj_t *)obj, scroll_y_anim); + lv_anim_delete((lv_obj_t *)obj, scroll_x_anim); +} + void lv_obj_update_snap(lv_obj_t * obj, lv_anim_enable_t anim_en) { lv_obj_update_layout(obj); @@ -499,6 +510,7 @@ void lv_obj_get_scrollbar_area(lv_obj_t * obj, lv_area_t * hor_area, lv_area_t * int32_t left_space = lv_obj_get_style_pad_left(obj, LV_PART_SCROLLBAR); int32_t right_space = lv_obj_get_style_pad_right(obj, LV_PART_SCROLLBAR); int32_t thickness = lv_obj_get_style_width(obj, LV_PART_SCROLLBAR); + int32_t length = lv_obj_get_style_length(obj, LV_PART_SCROLLBAR); int32_t obj_h = lv_obj_get_height(obj); int32_t obj_w = lv_obj_get_width(obj); @@ -508,8 +520,8 @@ void lv_obj_get_scrollbar_area(lv_obj_t * obj, lv_area_t * hor_area, lv_area_t * int32_t hor_req_space = hor_draw ? thickness : 0; int32_t rem; - if(lv_obj_get_style_bg_opa(obj, LV_PART_SCROLLBAR) < LV_OPA_MIN && - lv_obj_get_style_border_opa(obj, LV_PART_SCROLLBAR) < LV_OPA_MIN) { + if(lv_obj_get_style_bg_opa(obj, LV_PART_SCROLLBAR) <= LV_OPA_MIN && + lv_obj_get_style_border_opa(obj, LV_PART_SCROLLBAR) <= LV_OPA_MIN) { return; } @@ -528,7 +540,8 @@ void lv_obj_get_scrollbar_area(lv_obj_t * obj, lv_area_t * hor_area, lv_area_t * } int32_t sb_h = ((obj_h - top_space - bottom_space - hor_req_space) * obj_h) / content_h; - sb_h = LV_MAX(sb_h, SCROLLBAR_MIN_SIZE); + sb_h = LV_MAX(length > 0 ? length : sb_h, SCROLLBAR_MIN_SIZE); /*Style-defined size, calculated size, or minimum size*/ + sb_h = LV_MIN(sb_h, obj_h); /*Limit scrollbar length to parent height*/ rem = (obj_h - top_space - bottom_space - hor_req_space) - sb_h; /*Remaining size from the scrollbar track that is not the scrollbar itself*/ int32_t scroll_h = content_h - obj_h; /*The size of the content which can be really scrolled*/ @@ -566,7 +579,8 @@ void lv_obj_get_scrollbar_area(lv_obj_t * obj, lv_area_t * hor_area, lv_area_t * hor_area->x2 = obj->coords.x2; int32_t sb_w = ((obj_w - left_space - right_space - ver_reg_space) * obj_w) / content_w; - sb_w = LV_MAX(sb_w, SCROLLBAR_MIN_SIZE); + sb_w = LV_MAX(length > 0 ? length : sb_w, SCROLLBAR_MIN_SIZE); /*Style-defined size, calculated size, or minimum size*/ + sb_w = LV_MIN(sb_w, obj_w); /*Limit scrollbar length to parent width*/ rem = (obj_w - left_space - right_space - ver_reg_space) - sb_w; /*Remaining size from the scrollbar track that is not the scrollbar itself*/ int32_t scroll_w = content_w - obj_w; /*The size of the content which can be really scrolled*/ @@ -793,7 +807,7 @@ static void scroll_area_into_view(const lv_area_t * area, lv_obj_t * child, lv_p if((scroll_dir & LV_DIR_TOP) == 0 && y_scroll < 0) y_scroll = 0; if((scroll_dir & LV_DIR_BOTTOM) == 0 && y_scroll > 0) y_scroll = 0; - scroll_value->x += anim_en == LV_ANIM_OFF ? 0 : x_scroll; - scroll_value->y += anim_en == LV_ANIM_OFF ? 0 : y_scroll; + scroll_value->x += anim_en ? x_scroll : 0; + scroll_value->y += anim_en ? y_scroll : 0; lv_obj_scroll_by(parent, x_scroll, y_scroll, anim_en); } 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 f2cb2f103..ee6221d8a 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_scroll.h @@ -31,7 +31,7 @@ extern "C" { 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_ACTIVE, /**< Show scroll bars when Widget is being scrolled*/ LV_SCROLLBAR_MODE_AUTO, /**< Show scroll bars when the content is large enough to be scrolled*/ } lv_scrollbar_mode_t; @@ -53,29 +53,29 @@ typedef enum { /** * Set how the scrollbars should behave. - * @param obj pointer to an object + * @param obj pointer to Widget * @param mode LV_SCROLL_MODE_ON/OFF/AUTO/ACTIVE */ void lv_obj_set_scrollbar_mode(lv_obj_t * obj, lv_scrollbar_mode_t mode); /** - * Set 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` + * Set direction Widget can be scrolled + * @param obj pointer to Widget + * @param dir one or more bit-wise OR-ed values of `lv_dir_t` enumeration */ void lv_obj_set_scroll_dir(lv_obj_t * obj, lv_dir_t dir); /** * Set where to snap the children when scrolling ends horizontally - * @param obj pointer to an object - * @param align the snap align to set from `lv_scroll_snap_t` + * @param obj pointer to Widget + * @param align value from `lv_scroll_snap_t` enumeration */ void lv_obj_set_scroll_snap_x(lv_obj_t * obj, lv_scroll_snap_t align); /** * Set where to snap the children when scrolling ends vertically - * @param obj pointer to an object - * @param align the snap align to set from `lv_scroll_snap_t` + * @param obj pointer to Widget + * @param align value from `lv_scroll_snap_t` enumeration */ void lv_obj_set_scroll_snap_y(lv_obj_t * obj, lv_scroll_snap_t align); @@ -85,92 +85,97 @@ void lv_obj_set_scroll_snap_y(lv_obj_t * obj, lv_scroll_snap_t align); /** * Get the current scroll mode (when to hide the scrollbars) - * @param obj pointer to an object + * @param obj pointer to Widget * @return the current scroll mode from `lv_scrollbar_mode_t` */ 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 + * Get directions Widget can be scrolled (set with `lv_obj_set_scroll_dir()`) + * @param obj pointer to Widget + * @return current scroll direction bit(s) */ lv_dir_t lv_obj_get_scroll_dir(const lv_obj_t * obj); /** - * Get where to snap the children when scrolling ends horizontally - * @param obj pointer to an object - * @return the current snap align from `lv_scroll_snap_t` + * Get where to snap child Widgets when horizontal scrolling ends. + * @param obj pointer to Widget + * @return current snap value from `lv_scroll_snap_t` */ lv_scroll_snap_t lv_obj_get_scroll_snap_x(const lv_obj_t * obj); /** - * Get where to snap the children when scrolling ends vertically - * @param obj pointer to an object - * @return the current snap align from `lv_scroll_snap_t` + * Get where to snap child Widgets when vertical scrolling ends. + * @param obj pointer to Widget + * @return current snap value from `lv_scroll_snap_t` */ lv_scroll_snap_t lv_obj_get_scroll_snap_y(const lv_obj_t * obj); /** - * Get current X scroll position. - * @param obj pointer to an object - * @return the current scroll position from the left edge. - * If the object is not scrolled return 0 - * If scrolled return > 0 - * If scrolled in (elastic scroll) return < 0 + * Get current X scroll position. Identical to `lv_obj_get_scroll_left()`. + * @param obj pointer to scrollable container Widget + * @return current scroll position from left edge + * - If Widget is not scrolled return 0. + * - If scrolled return > 0. + * - If scrolled inside (elastic scroll) return < 0. */ int32_t lv_obj_get_scroll_x(const lv_obj_t * obj); /** - * Get current Y scroll position. - * @param obj pointer to an object - * @return the current scroll position from the top edge. - * If the object is not scrolled return 0 - * If scrolled return > 0 - * If scrolled inside return < 0 + * Get current Y scroll position. Identical to `lv_obj_get_scroll_top()`. + * @param obj pointer to scrollable container Widget + * @return current scroll position from top edge + * - If Widget is not scrolled return 0. + * - If scrolled return > 0. + * - If scrolled inside (elastic scroll) return < 0. */ int32_t lv_obj_get_scroll_y(const lv_obj_t * obj); /** - * Return the height of the area above the object. - * That is the number of pixels the object can be scrolled down. - * Normally positive but can be negative when scrolled inside. - * @param obj pointer to an object - * @return the scrollable area above the object in pixels + * Number of pixels a scrollable container Widget can be scrolled down + * before its top edge appears. When LV_OBJ_FLAG_SCROLL_ELASTIC flag + * is set in Widget, this value can go negative while Widget is being + * dragged below its normal top-edge boundary. + * @param obj pointer to scrollable container Widget + * @return pixels Widget can be scrolled down before its top edge appears */ -int32_t lv_obj_get_scroll_top(lv_obj_t * obj); +int32_t lv_obj_get_scroll_top(const lv_obj_t * obj); /** - * Return the height of the area below the object. - * That is the number of pixels the object can be scrolled down. - * Normally positive but can be negative when scrolled inside. - * @param obj pointer to an object - * @return the scrollable area below the object in pixels + * Number of pixels a scrollable container Widget can be scrolled up + * before its bottom edge appears. When LV_OBJ_FLAG_SCROLL_ELASTIC flag + * is set in Widget, this value can go negative while Widget is being + * dragged above its normal bottom-edge boundary. + * @param obj pointer to scrollable container Widget + * @return pixels Widget can be scrolled up before its bottom edge appears */ -int32_t lv_obj_get_scroll_bottom(lv_obj_t * obj); +int32_t lv_obj_get_scroll_bottom(const lv_obj_t * obj); /** - * Return the width of the area on the left the object. - * That is the number of pixels the object can be scrolled down. - * Normally positive but can be negative when scrolled inside. - * @param obj pointer to an object - * @return the scrollable area on the left the object in pixels + * Number of pixels a scrollable container Widget can be scrolled right + * before its left edge appears. When LV_OBJ_FLAG_SCROLL_ELASTIC flag + * is set in Widget, this value can go negative while Widget is being + * dragged farther right than its normal left-edge boundary. + * @param obj pointer to scrollable container Widget + * @return pixels Widget can be scrolled right before its left edge appears */ -int32_t lv_obj_get_scroll_left(lv_obj_t * obj); +int32_t lv_obj_get_scroll_left(const lv_obj_t * obj); /** - * Return the width of the area on the right the object. - * That is the number of pixels the object can be scrolled down. - * Normally positive but can be negative when scrolled inside. - * @param obj pointer to an object - * @return the scrollable area on the right the object in pixels + * Number of pixels a scrollable container Widget can be scrolled left + * before its right edge appears. When LV_OBJ_FLAG_SCROLL_ELASTIC flag + * is set in Widget, this value can go negative while Widget is being + * dragged farther left than its normal right-edge boundary. + * @param obj pointer to scrollable container Widget + * @return pixels Widget can be scrolled left before its right edge appears */ -int32_t lv_obj_get_scroll_right(lv_obj_t * obj); +int32_t lv_obj_get_scroll_right(const lv_obj_t * obj); /** - * Get the X and Y coordinates where the scrolling will end for this object if a scrolling animation is in progress. + * Get the X and Y coordinates where the scrolling will end for Widget if a scrolling animation is in progress. * If no scrolling animation, give the current `x` or `y` scroll position. - * @param obj pointer to an object - * @param end pointer to store the result + * @param obj pointer to scrollable Widget + * @param end pointer to `lv_point_t` object in which to store result */ void lv_obj_get_scroll_end(lv_obj_t * obj, lv_point_t * end); @@ -179,20 +184,20 @@ void lv_obj_get_scroll_end(lv_obj_t * obj, lv_point_t * end); *====================*/ /** - * Scroll by a given amount of pixels - * @param obj pointer to an object to scroll - * @param x pixels to scroll horizontally - * @param y pixels to scroll vertically + * Scroll by given amount of pixels. + * @param obj pointer to scrollable Widget to scroll + * @param dx pixels to scroll horizontally + * @param dy pixels to scroll vertically * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately * @note > 0 value means scroll right/bottom (show the more content on the right/bottom) * @note e.g. dy = -20 means scroll down 20 px */ -void lv_obj_scroll_by(lv_obj_t * obj, int32_t x, int32_t y, lv_anim_enable_t anim_en); +void lv_obj_scroll_by(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_enable_t anim_en); /** - * Scroll by a given amount of pixels. + * Scroll by given amount of pixels. * `dx` and `dy` will be limited internally to allow scrolling only on the content area. - * @param obj pointer to an object to scroll + * @param obj pointer to scrollable Widget to scroll * @param dx pixels to scroll horizontally * @param dy pixels to scroll vertically * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately @@ -201,9 +206,9 @@ void lv_obj_scroll_by(lv_obj_t * obj, int32_t x, int32_t y, lv_anim_enable_t ani void lv_obj_scroll_by_bounded(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_enable_t anim_en); /** - * Scroll to a given coordinate on an object. + * Scroll to given coordinate on Widget. * `x` and `y` will be limited internally to allow scrolling only on the content area. - * @param obj pointer to an object to scroll + * @param obj pointer to scrollable Widget to scroll * @param x pixels to scroll horizontally * @param y pixels to scroll vertically * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately @@ -211,56 +216,62 @@ void lv_obj_scroll_by_bounded(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_en void lv_obj_scroll_to(lv_obj_t * obj, int32_t x, int32_t y, lv_anim_enable_t anim_en); /** - * Scroll to a given X coordinate on an object. + * Scroll to X coordinate on Widget. * `x` will be limited internally to allow scrolling only on the content area. - * @param obj pointer to an object to scroll + * @param obj pointer to scrollable Widget to scroll * @param x pixels to scroll horizontally * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately */ void lv_obj_scroll_to_x(lv_obj_t * obj, int32_t x, lv_anim_enable_t anim_en); /** - * Scroll to a given Y coordinate on an object + * Scroll to Y coordinate on Widget. * `y` will be limited internally to allow scrolling only on the content area. - * @param obj pointer to an object to scroll + * @param obj pointer to scrollable Widget to scroll * @param y pixels to scroll vertically * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately */ void lv_obj_scroll_to_y(lv_obj_t * obj, int32_t y, lv_anim_enable_t anim_en); /** - * Scroll to an object until it becomes visible on its parent - * @param obj pointer to an object to scroll into view + * Scroll `obj`'s parent Widget until `obj` becomes visible. + * @param obj pointer to Widget to scroll into view * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately */ void lv_obj_scroll_to_view(lv_obj_t * obj, lv_anim_enable_t anim_en); /** - * Scroll to an object until it becomes visible on its parent. - * Do the same on the parent's parent, and so on. - * Therefore the object will be scrolled into view even it has nested scrollable parents - * @param obj pointer to an object to scroll into view + * Scroll `obj`'s parent Widgets recursively until `obj` becomes visible. + * Widget will be scrolled into view even it has nested scrollable parents. + * @param obj pointer to Widget to scroll into view * @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately */ void lv_obj_scroll_to_view_recursive(lv_obj_t * obj, lv_anim_enable_t anim_en); /** - * Tell whether an object is being scrolled or not at this moment - * @param obj pointer to an object + * Tell whether Widget is being scrolled or not at this moment + * @param obj pointer to Widget * @return true: `obj` is being scrolled */ bool lv_obj_is_scrolling(const lv_obj_t * obj); /** - * Check the children of `obj` and scroll `obj` to fulfill the scroll_snap settings - * @param obj an object whose children needs to checked and snapped + * Stop scrolling the current object + * + * @param obj The object being scrolled + */ +void lv_obj_stop_scroll_anim(const lv_obj_t * obj); + +/** + * Check children of `obj` and scroll `obj` to fulfill scroll_snap settings. + * @param obj Widget whose children need to be checked and snapped * @param anim_en LV_ANIM_ON/OFF */ void lv_obj_update_snap(lv_obj_t * obj, lv_anim_enable_t anim_en); /** * Get the area of the scrollbars - * @param obj pointer to an object + * @param obj pointer to Widget * @param hor pointer to store the area of the horizontal scrollbar * @param ver pointer to store the area of the vertical scrollbar */ @@ -268,13 +279,13 @@ void lv_obj_get_scrollbar_area(lv_obj_t * obj, lv_area_t * hor, lv_area_t * ver) /** * Invalidate the area of the scrollbars - * @param obj pointer to an object + * @param obj pointer to Widget */ void lv_obj_scrollbar_invalidate(lv_obj_t * obj); /** * Checks if the content is scrolled "in" and adjusts it to a normal position. - * @param obj pointer to an object + * @param obj pointer to Widget * @param anim_en LV_ANIM_ON/OFF */ void lv_obj_readjust_scroll(lv_obj_t * obj, lv_anim_enable_t anim_en); 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 06e3ffec3..afffffa15 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.c @@ -278,6 +278,8 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_selector_t selector, lv_style if(!style_refr) return; + LV_PROFILER_STYLE_BEGIN; + lv_obj_invalidate(obj); lv_part_t part = lv_obj_style_get_selector_part(selector); @@ -316,6 +318,8 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_selector_t selector, lv_style refresh_children_style(obj); } } + + LV_PROFILER_STYLE_END; } void lv_obj_enable_style_refresh(bool en) @@ -353,7 +357,9 @@ 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) { - /*Stop running transitions wit this property */ + LV_PROFILER_STYLE_BEGIN; + + /*Stop running transitions with this property */ trans_delete(obj, lv_obj_style_get_selector_part(selector), prop, NULL); lv_style_t * style = get_local_style(obj, selector); @@ -374,6 +380,7 @@ void lv_obj_set_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_ #endif lv_obj_refresh_style(obj, selector, prop); + LV_PROFILER_STYLE_END; } lv_style_res_t lv_obj_get_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t * value, @@ -472,12 +479,18 @@ void lv_obj_style_create_transition(lv_obj_t * obj, lv_part_t part, lv_state_t p 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 LV_USE_COLOR_FILTER if(obj == NULL) return v; const lv_color_filter_dsc_t * f = lv_obj_get_style_color_filter_dsc(obj, part); if(f && f->filter_cb) { lv_opa_t f_opa = lv_obj_get_style_color_filter_opa(obj, part); if(f_opa != 0) v.color = f->filter_cb(f, v.color, f_opa); } +#else + LV_UNUSED(obj); + LV_UNUSED(part); + LV_UNUSED(v); +#endif return v; } @@ -577,9 +590,12 @@ lv_text_align_t lv_obj_calculate_style_text_align(const lv_obj_t * obj, lv_part_ lv_opa_t lv_obj_get_style_opa_recursive(const lv_obj_t * obj, lv_part_t part) { - + LV_PROFILER_STYLE_BEGIN; lv_opa_t opa_obj = lv_obj_get_style_opa(obj, part); - if(opa_obj <= LV_OPA_MIN) return LV_OPA_TRANSP; + if(opa_obj <= LV_OPA_MIN) { + LV_PROFILER_STYLE_END; + return LV_OPA_TRANSP; + } lv_opa_t opa_final = LV_OPA_COVER; if(opa_obj < LV_OPA_MAX) { @@ -595,7 +611,10 @@ lv_opa_t lv_obj_get_style_opa_recursive(const lv_obj_t * obj, lv_part_t part) while(obj) { opa_obj = lv_obj_get_style_opa(obj, part); - if(opa_obj <= LV_OPA_MIN) return LV_OPA_TRANSP; + if(opa_obj <= LV_OPA_MIN) { + LV_PROFILER_STYLE_END; + return LV_OPA_TRANSP; + } if(opa_obj < LV_OPA_MAX) { opa_final = LV_OPA_MIX2(opa_final, opa_obj); } @@ -603,8 +622,17 @@ lv_opa_t lv_obj_get_style_opa_recursive(const lv_obj_t * obj, lv_part_t part) obj = lv_obj_get_parent(obj); } - if(opa_final <= LV_OPA_MIN) return LV_OPA_TRANSP; - if(opa_final >= LV_OPA_MAX) return LV_OPA_COVER; + if(opa_final <= LV_OPA_MIN) { + LV_PROFILER_STYLE_END; + return LV_OPA_TRANSP; + } + + if(opa_final >= LV_OPA_MAX) { + LV_PROFILER_STYLE_END; + return LV_OPA_COVER; + } + + LV_PROFILER_STYLE_END; return opa_final; } @@ -618,6 +646,41 @@ void lv_obj_update_layer_type(lv_obj_t * obj) } } +lv_color32_t lv_obj_style_apply_recolor(const lv_obj_t * obj, lv_part_t part, lv_color32_t color) +{ + lv_opa_t opa = lv_obj_get_style_recolor_opa(obj, part); + if(opa > LV_OPA_TRANSP) { + lv_color_t recolor = lv_obj_get_style_recolor(obj, part); + color = lv_color_over32(color, lv_color_to_32(recolor, opa)); + } + + return color; +} + +lv_color32_t lv_obj_get_style_recolor_recursive(const lv_obj_t * obj, lv_part_t part) +{ + lv_color32_t result; + + lv_color_t color = lv_obj_get_style_recolor(obj, part); + lv_opa_t opa = lv_obj_get_style_recolor_opa(obj, part); + + result = lv_color_to_32(color, opa); + + if(part != LV_PART_MAIN) { + part = LV_PART_MAIN; + } + else { + obj = lv_obj_get_parent(obj); + } + + while(obj) { + result = lv_obj_style_apply_recolor(obj, part, result); + obj = lv_obj_get_parent(obj); + } + + return result; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -652,7 +715,7 @@ static lv_style_t * get_local_style(lv_obj_t * obj, lv_style_selector_t selector } lv_memzero(&obj->styles[i], sizeof(lv_obj_style_t)); - obj->styles[i].style = lv_malloc(sizeof(lv_style_t)); + obj->styles[i].style = lv_malloc_zeroed(sizeof(lv_style_t)); lv_style_init((lv_style_t *)obj->styles[i].style); obj->styles[i].is_local = 1; @@ -861,6 +924,7 @@ static void trans_anim_cb(void * _tr, int32_t v) else if(v < 128) value_final.ptr = tr->start_value.ptr; else value_final.ptr = tr->end_value.ptr; break; + case LV_STYLE_RECOLOR: case LV_STYLE_BG_COLOR: case LV_STYLE_BG_GRAD_COLOR: case LV_STYLE_BORDER_COLOR: @@ -959,6 +1023,9 @@ static void trans_anim_completed_cb(lv_anim_t * a) static lv_layer_type_t calculate_layer_type(lv_obj_t * obj) { +#if LV_DRAW_TRANSFORM_USE_MATRIX + if(lv_obj_get_transform(obj) != NULL) return LV_LAYER_TYPE_TRANSFORM; +#endif if(lv_obj_get_style_transform_rotation(obj, 0) != 0) return LV_LAYER_TYPE_TRANSFORM; if(lv_obj_get_style_transform_scale_x(obj, 0) != 256) return LV_LAYER_TYPE_TRANSFORM; if(lv_obj_get_style_transform_scale_y(obj, 0) != 256) return LV_LAYER_TYPE_TRANSFORM; 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 ff4e365d8..f94a63a49 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style.h @@ -307,6 +307,25 @@ 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); + +/** + * Apply recolor effect to the input color based on the object's style properties. + * @param obj the target object containing recolor style properties + * @param part the part to retrieve recolor styles. + * @param color the original color to be modified + * @return the blended color after applying recolor and opacity + */ +lv_color32_t lv_obj_style_apply_recolor(const lv_obj_t * obj, lv_part_t part, lv_color32_t color); + +/** + * Get the `recolor` style property from all parents and blend them recursively. + * @param obj the object whose recolor value should be retrieved + * @param part the target part to check. Non-MAIN parts will also consider + * the `recolor` value from the MAIN part during calculation + * @return the final blended recolor value combining all parent's recolor values + */ +lv_color32_t lv_obj_get_style_recolor_recursive(const lv_obj_t * obj, lv_part_t part); + /********************** * 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 ad97db594..8910d9a0e 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 @@ -122,6 +122,14 @@ void lv_obj_set_style_translate_y(lv_obj_t * obj, int32_t value, lv_style_select lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSLATE_Y, v, selector); } +void lv_obj_set_style_translate_radial(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) +{ + lv_style_value_t v = { + .num = (int32_t)value + }; + lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSLATE_RADIAL, v, selector); +} + void lv_obj_set_style_transform_scale_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) { lv_style_value_t v = { @@ -226,6 +234,14 @@ void lv_obj_set_style_pad_column(lv_obj_t * obj, int32_t value, lv_style_selecto lv_obj_set_local_style_prop(obj, LV_STYLE_PAD_COLUMN, v, selector); } +void lv_obj_set_style_pad_radial(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) +{ + lv_style_value_t v = { + .num = (int32_t)value + }; + lv_obj_set_local_style_prop(obj, LV_STYLE_PAD_RADIAL, v, selector); +} + void lv_obj_set_style_margin_top(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) { lv_style_value_t v = { @@ -658,6 +674,30 @@ void lv_obj_set_style_text_align(lv_obj_t * obj, lv_text_align_t value, lv_style lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_ALIGN, v, selector); } +void lv_obj_set_style_text_outline_stroke_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector) +{ + lv_style_value_t v = { + .color = value + }; + lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_OUTLINE_STROKE_COLOR, v, selector); +} + +void lv_obj_set_style_text_outline_stroke_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) +{ + lv_style_value_t v = { + .num = (int32_t)value + }; + lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_OUTLINE_STROKE_WIDTH, v, selector); +} + +void lv_obj_set_style_text_outline_stroke_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector) +{ + lv_style_value_t v = { + .num = (int32_t)value + }; + lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_OUTLINE_STROKE_OPA, v, selector); +} + void lv_obj_set_style_radius(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) { lv_style_value_t v = { @@ -666,6 +706,14 @@ void lv_obj_set_style_radius(lv_obj_t * obj, int32_t value, lv_style_selector_t lv_obj_set_local_style_prop(obj, LV_STYLE_RADIUS, v, selector); } +void lv_obj_set_style_radial_offset(lv_obj_t * obj, int32_t value, lv_style_selector_t selector) +{ + lv_style_value_t v = { + .num = (int32_t)value + }; + lv_obj_set_local_style_prop(obj, LV_STYLE_RADIAL_OFFSET, v, selector); +} + void lv_obj_set_style_clip_corner(lv_obj_t * obj, bool value, lv_style_selector_t selector) { lv_style_value_t v = { @@ -706,6 +754,22 @@ void lv_obj_set_style_color_filter_opa(lv_obj_t * obj, lv_opa_t value, lv_style_ lv_obj_set_local_style_prop(obj, LV_STYLE_COLOR_FILTER_OPA, v, selector); } +void lv_obj_set_style_recolor(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector) +{ + lv_style_value_t v = { + .color = value + }; + lv_obj_set_local_style_prop(obj, LV_STYLE_RECOLOR, v, selector); +} + +void lv_obj_set_style_recolor_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector) +{ + lv_style_value_t v = { + .num = (int32_t)value + }; + lv_obj_set_local_style_prop(obj, LV_STYLE_RECOLOR_OPA, v, selector); +} + void lv_obj_set_style_anim(lv_obj_t * obj, const lv_anim_t * value, lv_style_selector_t selector) { lv_style_value_t v = { 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 77cf53785..ff85e38b9 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 @@ -103,6 +103,12 @@ static inline int32_t lv_obj_get_style_translate_y(const lv_obj_t * obj, lv_part return (int32_t)v.num; } +static inline int32_t lv_obj_get_style_translate_radial(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSLATE_RADIAL); + return (int32_t)v.num; +} + 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); @@ -181,6 +187,12 @@ static inline int32_t lv_obj_get_style_pad_column(const lv_obj_t * obj, lv_part_ return (int32_t)v.num; } +static inline int32_t lv_obj_get_style_pad_radial(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_RADIAL); + return (int32_t)v.num; +} + 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); @@ -231,8 +243,7 @@ static inline lv_color_t lv_obj_get_style_bg_grad_color(const lv_obj_t * obj, lv 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; } @@ -292,8 +303,7 @@ static inline lv_color_t lv_obj_get_style_bg_image_recolor(const lv_obj_t * obj, 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; } @@ -317,8 +327,7 @@ static inline lv_color_t lv_obj_get_style_border_color(const lv_obj_t * obj, lv_ 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; } @@ -360,8 +369,7 @@ static inline lv_color_t lv_obj_get_style_outline_color(const lv_obj_t * obj, lv 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; } @@ -409,8 +417,7 @@ static inline lv_color_t lv_obj_get_style_shadow_color(const lv_obj_t * obj, lv_ 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; } @@ -434,8 +441,7 @@ static inline lv_color_t lv_obj_get_style_image_recolor(const lv_obj_t * obj, lv 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; } @@ -571,12 +577,42 @@ static inline lv_text_align_t lv_obj_get_style_text_align(const lv_obj_t * obj, return (lv_text_align_t)v.num; } +static inline lv_color_t lv_obj_get_style_text_outline_stroke_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_OUTLINE_STROKE_COLOR); + return v.color; +} + +static inline lv_color_t lv_obj_get_style_text_outline_stroke_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_OUTLINE_STROKE_COLOR)); + return v.color; +} + +static inline int32_t lv_obj_get_style_text_outline_stroke_width(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_OUTLINE_STROKE_WIDTH); + return (int32_t)v.num; +} + +static inline lv_opa_t lv_obj_get_style_text_outline_stroke_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_OUTLINE_STROKE_OPA); + return (lv_opa_t)v.num; +} + 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 int32_t lv_obj_get_style_radial_offset(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_RADIAL_OFFSET); + return (int32_t)v.num; +} + 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); @@ -607,6 +643,18 @@ static inline lv_opa_t lv_obj_get_style_color_filter_opa(const lv_obj_t * obj, l return (lv_opa_t)v.num; } +static inline lv_color_t lv_obj_get_style_recolor(const lv_obj_t * obj, lv_part_t part) +{ + lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_RECOLOR); + return v.color; +} + +static inline lv_opa_t lv_obj_get_style_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_RECOLOR_OPA); + return (lv_opa_t)v.num; +} + 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); @@ -765,6 +813,7 @@ void lv_obj_set_style_transform_width(lv_obj_t * obj, int32_t value, lv_style_se void lv_obj_set_style_transform_height(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); void lv_obj_set_style_translate_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); void lv_obj_set_style_translate_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_translate_radial(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); void lv_obj_set_style_transform_scale_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); void lv_obj_set_style_transform_scale_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); void lv_obj_set_style_transform_rotation(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); @@ -778,6 +827,7 @@ void lv_obj_set_style_pad_left(lv_obj_t * obj, int32_t value, lv_style_selector_ void lv_obj_set_style_pad_right(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); void lv_obj_set_style_pad_row(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); void lv_obj_set_style_pad_column(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_pad_radial(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); void lv_obj_set_style_margin_top(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); void lv_obj_set_style_margin_bottom(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); void lv_obj_set_style_margin_left(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); @@ -832,12 +882,18 @@ void lv_obj_set_style_text_letter_space(lv_obj_t * obj, int32_t value, lv_style_ void lv_obj_set_style_text_line_space(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); void lv_obj_set_style_text_decor(lv_obj_t * obj, lv_text_decor_t value, lv_style_selector_t selector); void lv_obj_set_style_text_align(lv_obj_t * obj, lv_text_align_t value, lv_style_selector_t selector); +void lv_obj_set_style_text_outline_stroke_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector); +void lv_obj_set_style_text_outline_stroke_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_text_outline_stroke_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); void lv_obj_set_style_radius(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); +void lv_obj_set_style_radial_offset(lv_obj_t * obj, int32_t value, lv_style_selector_t selector); void lv_obj_set_style_clip_corner(lv_obj_t * obj, bool value, lv_style_selector_t selector); void lv_obj_set_style_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); void lv_obj_set_style_opa_layered(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); void lv_obj_set_style_color_filter_dsc(lv_obj_t * obj, const lv_color_filter_dsc_t * value, lv_style_selector_t selector); void lv_obj_set_style_color_filter_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); +void lv_obj_set_style_recolor(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector); +void lv_obj_set_style_recolor_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector); void lv_obj_set_style_anim(lv_obj_t * obj, const lv_anim_t * value, lv_style_selector_t selector); void lv_obj_set_style_anim_duration(lv_obj_t * obj, uint32_t value, lv_style_selector_t selector); void lv_obj_set_style_transition(lv_obj_t * obj, const lv_style_transition_dsc_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 index 7fafc58b1..e6be1279e 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style_private.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_style_private.h @@ -24,14 +24,14 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_obj_style_t { +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 { +struct _lv_obj_style_transition_dsc_t { uint16_t time; uint16_t delay; lv_style_selector_t selector; 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 15c069e90..95396c496 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.c @@ -23,6 +23,7 @@ #define disp_ll_p &(LV_GLOBAL_DEFAULT()->disp_ll) #define OBJ_DUMP_STRING_LEN 128 +#define LV_OBJ_NAME_MAX_LEN 128 /********************** * TYPEDEFS @@ -36,6 +37,9 @@ 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 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); +#if LV_USE_OBJ_NAME + static lv_obj_t * find_by_name_direct(const lv_obj_t * parent, const char * name, size_t len); +#endif /*LV_USE_OBJ_NAME*/ /********************** * STATIC VARIABLES @@ -416,6 +420,166 @@ uint32_t lv_obj_get_child_count_by_type(const lv_obj_t * obj, const lv_obj_class return cnt; } +#if LV_USE_OBJ_NAME + +void lv_obj_set_name(lv_obj_t * obj, const char * name) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_obj_allocate_spec_attr(obj); + + if(!obj->spec_attr->name_static && obj->spec_attr->name) lv_free((void *)obj->spec_attr->name); + + if(name == NULL) { + obj->spec_attr->name = NULL; + obj->spec_attr->name_static = 1; + } + else { + obj->spec_attr->name = lv_strdup(name); + obj->spec_attr->name_static = 0; + } +} + +void lv_obj_set_name_static(lv_obj_t * obj, const char * name) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_obj_allocate_spec_attr(obj); + + if(!obj->spec_attr->name_static && obj->spec_attr->name) lv_free((void *)obj->spec_attr->name); + + obj->spec_attr->name = name; + obj->spec_attr->name_static = 1; +} + +const char * lv_obj_get_name(const lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + if(obj->spec_attr == NULL) return NULL; + else return obj->spec_attr->name; +} + +void lv_obj_get_name_resolved(const lv_obj_t * obj, char buf[], size_t buf_size) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + const char * name = lv_obj_get_name(obj); + /*Use a default name which auto-indexing*/ + char name_buf[LV_OBJ_NAME_MAX_LEN]; + if(name == NULL) { + lv_snprintf(name_buf, sizeof(name_buf), "%s_#", obj->class_p->name); + name = name_buf; + } + + size_t name_len = lv_strlen(name); + lv_obj_t * parent = lv_obj_get_parent(obj); + + /*If the last character is # automatically index the children with the same name start*/ + if(parent && name_len > 0 && name[name_len - 1] == '#') { + uint32_t child_cnt = lv_obj_get_child_count(parent); + uint32_t cnt = 0; + uint32_t i; + for(i = 0; i < child_cnt; i++) { + lv_obj_t * child = lv_obj_get_child(parent, i); + /*All siblings older siblings are checked, craft the name of this widget*/ + if(child == obj) { + char num_buf[8]; + size_t num_len; + num_len = lv_snprintf(num_buf, sizeof(num_buf), "%d", cnt); + /*Is there enough space for the name and the index?*/ + if(buf_size > name_len + num_len) { + /*E.g. buf = "some_name_", so trim the # from the end*/ + lv_strncpy(buf, name, name_len - 1); + lv_strcpy(&buf[name_len - 1], num_buf); + } + else { + /*Use the name as it is as a fallback*/ + lv_strlcpy(buf, obj->spec_attr->name, buf_size); + } + break; + } + /*Check the older siblings. IF they start with the same name count them*/ + else { + const char * child_name = lv_obj_get_name(child); + if(child_name == NULL) { + /*If the name we are looking for start with the child's class name + *increment the index. E.g. _#*/ + size_t class_name_len = lv_strlen(child->class_p->name); + if(name_len > 3 && class_name_len == name_len - 2 && + lv_strncmp(child->class_p->name, name, class_name_len) == 0) { + cnt++; + } + } + /*The name is set, check if it's e.g. #*/ + else { + if(lv_strcmp(child->spec_attr->name, name) == 0) { + cnt++; + } + } + } + } + } + else { + /*Just use the set name*/ + lv_strlcpy(buf, obj->spec_attr->name, buf_size); + } +} + +lv_obj_t * lv_obj_get_child_by_name(const lv_obj_t * parent, const char * path) +{ + LV_ASSERT_OBJ(parent, MY_CLASS); + + if(parent == NULL || parent->spec_attr == NULL || path == NULL) return NULL; + + while(*path) { + const char * segment = path; + uint32_t len = 0; + + /* Calculate the length of the current segment */ + while(path[len] && path[len] != '/') + len++; + + /* Look for a child whose resolved name exactly matches the segment */ + lv_obj_t * child = find_by_name_direct(parent, segment, len); + if(!child) return NULL; /*Segment not found*/ + + /* Advance to the next segment */ + path += len; + if(*path == '/') path++; /* Skip the '/' */ + + /* If there is no further segment, we've found the target child */ + if(*path == '\0') return child; + + parent = child; + } + + return NULL; + +} + +lv_obj_t * lv_obj_find_by_name(const lv_obj_t * parent, const char * name) +{ + if(parent == NULL) parent = lv_display_get_screen_active(NULL); + if(parent == NULL) return NULL; + + lv_obj_t * child = find_by_name_direct(parent, name, UINT16_MAX); + if(child) return child; + + /*Search children recursively*/ + uint32_t child_cnt = lv_obj_get_child_count(parent); + uint32_t i; + for(i = 0; i < child_cnt; i++) { + child = parent->spec_attr->children[i]; + lv_obj_t * found = lv_obj_find_by_name(child, name); + if(found != NULL) return found; + } + + return NULL; +} + +#endif /*LV_USE_OBJ_NAME*/ + int32_t lv_obj_get_index(const lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -634,7 +798,7 @@ static void dump_tree_core(lv_obj_t * obj, int32_t depth) #endif /*id of `obj0` is an invalid id for builtin id*/ - LV_LOG_USER("parent:%p, obj:%p, id:%s;", (void *)(obj ? obj->parent : NULL), (void *)obj, id); + LV_LOG_USER("%*sobj:%p, id:%s;", (int)(2 * depth), "", (void *)obj, id); #endif /*LV_USE_LOG*/ if(obj && obj->spec_attr && obj->spec_attr->child_cnt) { @@ -660,3 +824,22 @@ static lv_obj_t * lv_obj_get_first_not_deleting_child(lv_obj_t * obj) return NULL; } + +#if LV_USE_OBJ_NAME + +static lv_obj_t * find_by_name_direct(const lv_obj_t * parent, const char * name, size_t len) +{ + uint32_t i; + uint32_t child_cnt = lv_obj_get_child_count(parent); + for(i = 0; i < child_cnt; i++) { + lv_obj_t * child = parent->spec_attr->children[i]; + + char child_name_resolved[LV_OBJ_NAME_MAX_LEN]; + lv_obj_get_name_resolved(child, child_name_resolved, sizeof(child_name_resolved)); + if(lv_strncmp(child_name_resolved, name, len) == 0) return child; + } + + return NULL; +} + +#endif /*LV_USE_OBJ_NAME*/ 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 9f679dd40..e86957634 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_obj_tree.h @@ -193,6 +193,90 @@ uint32_t lv_obj_get_child_count(const lv_obj_t * obj); uint32_t lv_obj_get_child_count_by_type(const lv_obj_t * obj, const lv_obj_class_t * class_p); +#if LV_USE_OBJ_NAME + +/** + * Set a name for a widget. The name will be allocated and freed when the + * widget is deleted or a new name is set. + * @param obj pointer to an object + * @param name the name to set. If set to `NULL` the default "_#" + * name will be used. + * @note If the name ends with a `#`, older siblings with the same name + * will be counted, and the `#` will be replaced by the index of the + * given widget. For example, creating multiple widgets with the name + * "mybtn_#" will result in resolved names like "mybtn_0", "mybtn_1", + * "mybtn_2", etc. The name is resolved when `lv_obj_get_name_resolved` + * is called, so the result reflects the currently existing widgets at + * that time. + */ +void lv_obj_set_name(lv_obj_t * obj, const char * name); + +/** + * Set a name for a widget. Only a pointer will be saved. + * @param obj pointer to an object + * @param name the name to set. If set to `NULL` the default "_#" + * name will be used. + * @note If the name ends with a `#`, older siblings with the same name + * will be counted, and the `#` will be replaced by the index of the + * given widget. For example, creating multiple widgets with the name + * "mybtn_#" will result in resolved names like "mybtn_0", "mybtn_1", + * "mybtn_2", etc. The name is resolved when `lv_obj_get_name_resolved` + * is called, so the result reflects the currently existing widgets at + * that time. + */ +void lv_obj_set_name_static(lv_obj_t * obj, const char * name); + +/** + * Get the set name as it was set. + * @param obj pointer to an object + * @return get the set name or NULL if it wasn't set yet + */ +const char * lv_obj_get_name(const lv_obj_t * obj); + +/** + * Get the set name or craft a name automatically. + * @param obj pointer to an object + * @param buf buffer to store the name + * @param buf_size the size of the buffer in bytes + * @note If the name ends with a `#`, older siblings with the same name + * will be counted, and the `#` will be replaced by the index of the + * given widget. For example, creating multiple widgets with the name + * "mybtn_#" will result in resolved names like "mybtn_0", "mybtn_1", + * "mybtn_2", etc. The name is resolved when `lv_obj_get_name_resolved` + * is called, so the result reflects the currently existing widgets at + * that time. + */ +void lv_obj_get_name_resolved(const lv_obj_t * obj, char buf[], size_t buf_size); + +/** + * Find a child with a given name on a parent. This child doesn't have to be the + * direct child of the parent. First direct children of the parent will be checked, + * and the direct children of the first child, etc. (Breadth-first search). + * + * If the name of a widget was not set a name like "lv_button_1" will + * be created for it using `lv_obj_get_name_resolved`. + * + * @param parent the widget where the search should start + * @return the found widget or NULL if not found. + */ +lv_obj_t * lv_obj_find_by_name(const lv_obj_t * parent, const char * name); + +/** + * Get an object by name. The name can be a path too, for example + * "main_container/lv_button_1/label". + * In this case the first part of the name-path should be the direct child of the parent, + * the second part, should the direct child of first one, etc. + * + * If the name of a widget was not set a name like "lv_button_1" will + * be created for it using `lv_obj_get_name_resolved`. + * + * @param parent the widget where the search should start + * @return the found widget or NULL if not found. + */ +lv_obj_t * lv_obj_get_child_by_name(const lv_obj_t * parent, const char * name_path); + +#endif /*LV_USE_OBJ_NAME*/ + /** * Get the index of a child. * @param obj pointer to an object diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_refr.c b/lib/libesp32_lvgl/lvgl/src/core/lv_refr.c index e91fc0059..3d5860473 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_refr.c +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_refr.c @@ -42,8 +42,8 @@ static void lv_refr_join_area(void); static void refr_invalid_areas(void); static void refr_sync_areas(void); -static void refr_area(const lv_area_t * area_p); -static void refr_area_part(lv_layer_t * layer); +static void refr_area(const lv_area_t * area_p, int32_t y_offset); +static void refr_configured_layer(lv_layer_t * layer); static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj); static void refr_obj_and_children(lv_layer_t * layer, lv_obj_t * top_obj); static void refr_obj(lv_layer_t * layer, lv_obj_t * obj); @@ -99,6 +99,7 @@ void lv_refr_now(lv_display_t * disp) void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) { + LV_PROFILER_REFR_BEGIN; lv_area_t clip_area_ori = layer->_clip_area; lv_area_t clip_coords_for_obj; @@ -108,7 +109,10 @@ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * 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)) { + LV_PROFILER_REFR_END; + return; + } /*If the object is visible on the current clip area*/ layer->_clip_area = clip_coords_for_obj; @@ -136,7 +140,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, &layer->_clip_area, obj_coords) || layer->opa <= LV_OPA_MIN) { refr_children = false; } @@ -145,7 +149,6 @@ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) uint32_t child_cnt = lv_obj_get_child_count(obj); if(child_cnt == 0) { /*If the object was visible on the clip area call the post draw events too*/ - layer->_clip_area = clip_coords_for_obj; /*If all the children are redrawn make 'post draw' draw*/ lv_obj_send_event(obj, LV_EVENT_DRAW_POST_BEGIN, layer); lv_obj_send_event(obj, LV_EVENT_DRAW_POST, layer); @@ -168,7 +171,6 @@ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) } /*If the object was visible on the clip area call the post draw events too*/ - layer->_clip_area = clip_coords_for_obj; /*If all the children are redrawn make 'post draw' draw*/ lv_obj_send_event(obj, LV_EVENT_DRAW_POST_BEGIN, layer); lv_obj_send_event(obj, LV_EVENT_DRAW_POST, layer); @@ -189,7 +191,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, &layer->_clip_area)) { layer_children = lv_draw_layer_create(layer, LV_COLOR_FORMAT_ARGB8888, &bottom); for(i = 0; i < child_cnt; i++) { @@ -210,7 +212,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, &layer->_clip_area)) { layer_children = lv_draw_layer_create(layer, LV_COLOR_FORMAT_ARGB8888, &top); for(i = 0; i < child_cnt; i++) { @@ -233,7 +235,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, &layer->_clip_area)) { layer->_clip_area = mid; for(i = 0; i < child_cnt; i++) { lv_obj_t * child = obj->spec_attr->children[i]; @@ -252,6 +254,7 @@ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) } layer->_clip_area = clip_area_ori; + LV_PROFILER_REFR_END; } void lv_inv_area(lv_display_t * disp, const lv_area_t * area_p) @@ -347,7 +350,7 @@ void lv_refr_set_disp_refreshing(lv_display_t * disp) void lv_display_refr_timer(lv_timer_t * tmr) { - LV_PROFILER_BEGIN; + LV_PROFILER_REFR_BEGIN; LV_TRACE_REFR("begin"); if(tmr) { @@ -365,26 +368,28 @@ void lv_display_refr_timer(lv_timer_t * tmr) if(disp_refr == NULL) { LV_LOG_WARN("No display registered"); + LV_PROFILER_REFR_END; return; } lv_draw_buf_t * buf_act = disp_refr->buf_act; if(!(buf_act && buf_act->data && buf_act->data_size)) { LV_LOG_WARN("No draw buffer"); + LV_PROFILER_REFR_END; return; } lv_display_send_event(disp_refr, LV_EVENT_REFR_START, NULL); /*Refresh the screen's layout if required*/ - LV_PROFILER_BEGIN_TAG("layout"); + LV_PROFILER_LAYOUT_BEGIN_TAG("layout"); lv_obj_update_layout(disp_refr->act_scr); if(disp_refr->prev_scr) lv_obj_update_layout(disp_refr->prev_scr); lv_obj_update_layout(disp_refr->bottom_layer); lv_obj_update_layout(disp_refr->top_layer); lv_obj_update_layout(disp_refr->sys_layer); - LV_PROFILER_END_TAG("layout"); + LV_PROFILER_LAYOUT_END_TAG("layout"); /*Do nothing if there is no active screen*/ if(disp_refr->act_scr == NULL) { @@ -398,10 +403,6 @@ void lv_display_refr_timer(lv_timer_t * tmr) refr_invalid_areas(); if(disp_refr->inv_p == 0) goto refr_finish; - - /*If refresh happened ...*/ - lv_display_send_event(disp_refr, LV_EVENT_RENDER_READY, NULL); - /*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) { @@ -428,7 +429,7 @@ refr_finish: lv_display_send_event(disp_refr, LV_EVENT_REFR_READY, NULL); LV_TRACE_REFR("finished"); - LV_PROFILER_END; + LV_PROFILER_REFR_END; } /********************** @@ -440,7 +441,7 @@ refr_finish: */ static void lv_refr_join_area(void) { - LV_PROFILER_BEGIN; + LV_PROFILER_REFR_BEGIN; uint32_t join_from; uint32_t join_in; lv_area_t joined_area; @@ -471,7 +472,7 @@ static void lv_refr_join_area(void) } } } - LV_PROFILER_END; + LV_PROFILER_REFR_END; } /** @@ -488,7 +489,7 @@ static void refr_sync_areas(void) /*Do not sync if no sync areas*/ if(lv_ll_is_empty(&disp_refr->sync_areas)) return; - LV_PROFILER_BEGIN; + LV_PROFILER_REFR_BEGIN; /*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); @@ -496,7 +497,22 @@ static void refr_sync_areas(void) /*The buffers are already swapped. *So the active buffer is the off screen buffer where LVGL will render*/ lv_draw_buf_t * off_screen = disp_refr->buf_act; - lv_draw_buf_t * on_screen = disp_refr->buf_act == disp_refr->buf_1 ? disp_refr->buf_2 : disp_refr->buf_1; + /*Triple buffer sync buffer for off-screen2 updates.*/ + lv_draw_buf_t * off_screen2; + lv_draw_buf_t * on_screen; + + if(disp_refr->buf_act == disp_refr->buf_1) { + off_screen2 = disp_refr->buf_2; + on_screen = disp_refr->buf_3 ? disp_refr->buf_3 : disp_refr->buf_2; + } + else if(disp_refr->buf_act == disp_refr->buf_2) { + off_screen2 = disp_refr->buf_3 ? disp_refr->buf_3 : disp_refr->buf_1; + on_screen = disp_refr->buf_1; + } + else { + off_screen2 = disp_refr->buf_1; + on_screen = disp_refr->buf_2; + } uint32_t hor_res = lv_display_get_horizontal_resolution(disp_refr); uint32_t ver_res = lv_display_get_vertical_resolution(disp_refr); @@ -543,13 +559,22 @@ static void refr_sync_areas(void) /** * @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); + if(!lv_area_intersect(sync_area, sync_area, &disp_area)) { + continue; + } +#if LV_DRAW_TRANSFORM_USE_MATRIX + if(lv_display_get_matrix_rotation(disp_refr)) { + lv_display_rotate_area(disp_refr, sync_area); + } +#endif lv_draw_buf_copy(off_screen, sync_area, on_screen, sync_area); + if(off_screen2 != on_screen) + lv_draw_buf_copy(off_screen2, sync_area, on_screen, sync_area); } /*Clear sync areas*/ lv_ll_clear(&disp_refr->sync_areas); - LV_PROFILER_END; + LV_PROFILER_REFR_END; } /** @@ -558,7 +583,7 @@ static void refr_sync_areas(void) static void refr_invalid_areas(void) { if(disp_refr->inv_p == 0) return; - LV_PROFILER_BEGIN; + LV_PROFILER_REFR_BEGIN; /*Find the last area which will be drawn*/ int32_t i; @@ -579,16 +604,59 @@ static void refr_invalid_areas(void) for(i = 0; i < (int32_t)disp_refr->inv_p; i++) { /*Refresh the unjoined areas*/ - if(disp_refr->inv_area_joined[i] == 0) { + if(disp_refr->inv_area_joined[i]) continue; - if(i == last_i) disp_refr->last_area = 1; - disp_refr->last_part = 0; - refr_area(&disp_refr->inv_areas[i]); + if(i == last_i) disp_refr->last_area = 1; + disp_refr->last_part = 0; + + lv_area_t inv_a = disp_refr->inv_areas[i]; + if(disp_refr->render_mode == LV_DISPLAY_RENDER_MODE_PARTIAL) { + /*Calculate the max row num*/ + int32_t w = lv_area_get_width(&inv_a); + int32_t h = lv_area_get_height(&inv_a); + + int32_t max_row = get_max_row(disp_refr, w, h); + + int32_t row; + int32_t row_last = 0; + lv_area_t sub_area; + sub_area.x1 = inv_a.x1; + sub_area.x2 = inv_a.x2; + int32_t y_off = 0; + for(row = inv_a.y1; row + max_row - 1 <= inv_a.y2; row += max_row) { + /*Calc. the next y coordinates of draw_buf*/ + sub_area.y1 = row; + sub_area.y2 = row + max_row - 1; + if(sub_area.y2 > inv_a.y2) sub_area.y2 = inv_a.y2; + row_last = sub_area.y2; + if(inv_a.y2 == row_last) disp_refr->last_part = 1; + refr_area(&sub_area, y_off); + y_off += lv_area_get_height(&sub_area); + draw_buf_flush(disp_refr); + } + + /*If the last y coordinates are not handled yet ...*/ + if(inv_a.y2 != row_last) { + /*Calc. the next y coordinates of draw_buf*/ + sub_area.y1 = row; + sub_area.y2 = inv_a.y2; + disp_refr->last_part = 1; + refr_area(&sub_area, y_off); + y_off += lv_area_get_height(&sub_area); + draw_buf_flush(disp_refr); + } + } + else if(disp_refr->render_mode == LV_DISPLAY_RENDER_MODE_FULL || + disp_refr->render_mode == LV_DISPLAY_RENDER_MODE_DIRECT) { + disp_refr->last_part = 1; + refr_area(&disp_refr->inv_areas[i], 0); + draw_buf_flush(disp_refr); } } + lv_display_send_event(disp_refr, LV_EVENT_RENDER_READY, NULL); disp_refr->rendering_in_progress = false; - LV_PROFILER_END; + LV_PROFILER_REFR_END; } /** @@ -611,96 +679,174 @@ static void layer_reshape_draw_buf(lv_layer_t * layer, uint32_t stride) * Refresh an area if there is Virtual Display Buffer * @param area_p pointer to an area to refresh */ -static void refr_area(const lv_area_t * area_p) +static void refr_area(const lv_area_t * area_p, int32_t y_offset) { - LV_PROFILER_BEGIN; + LV_PROFILER_REFR_BEGIN; lv_layer_t * layer = disp_refr->layer_head; layer->draw_buf = disp_refr->buf_act; + layer->_clip_area = *area_p; + layer->phy_clip_area = *area_p; + layer->partial_y_offset = y_offset; -#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) { + if(disp_refr->render_mode == LV_DISPLAY_RENDER_MODE_PARTIAL) { + /*In partial mode render this area to the buffer*/ + layer->buf_area = *area_p; + layer_reshape_draw_buf(layer, LV_STRIDE_AUTO); + } + else if(disp_refr->render_mode == LV_DISPLAY_RENDER_MODE_DIRECT || + disp_refr->render_mode == LV_DISPLAY_RENDER_MODE_FULL) { + /*In direct mode and full mode the the buffer area is always the whole screen, not considering rotation*/ layer->buf_area.x1 = 0; 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; - 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); + if(lv_display_get_matrix_rotation(disp_refr)) { + layer->buf_area.x2 = lv_display_get_original_horizontal_resolution(disp_refr) - 1; + layer->buf_area.y2 = lv_display_get_original_vertical_resolution(disp_refr) - 1; } - 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); + else { + layer->buf_area.x2 = lv_display_get_horizontal_resolution(disp_refr) - 1; + layer->buf_area.y2 = lv_display_get_vertical_resolution(disp_refr) - 1; } - LV_PROFILER_END; - return; + layer_reshape_draw_buf(layer, disp_refr->stride_is_auto ? LV_STRIDE_AUTO : layer->draw_buf->header.stride); } - /*Normal refresh: draw the area in parts*/ - /*Calculate the max row num*/ - int32_t w = lv_area_get_width(area_p); - int32_t h = lv_area_get_height(area_p); - int32_t y2 = area_p->y2 >= lv_display_get_vertical_resolution(disp_refr) ? - lv_display_get_vertical_resolution(disp_refr) - 1 : area_p->y2; + /*Try to divide the area to smaller tiles*/ + uint32_t tile_cnt = 1; + int32_t tile_h = lv_area_get_height(area_p); + if(LV_COLOR_FORMAT_IS_INDEXED(layer->color_format) == false) { + /* Assume that the the buffer size (can be screen sized or smaller in case of partial mode) + * and max tile size are the optimal scenario. From this calculate the ideal tile size + * and set the tile count and tile height accordingly. + */ + uint32_t max_tile_cnt = disp_refr->tile_cnt; + uint32_t total_buf_size = layer->draw_buf->data_size; + uint32_t ideal_tile_size = total_buf_size / max_tile_cnt; + uint32_t area_buf_size = lv_area_get_size(area_p) * lv_color_format_get_size(layer->color_format); - int32_t max_row = get_max_row(disp_refr, w, h); - - int32_t row; - int32_t row_last = 0; - lv_area_t sub_area; - for(row = area_p->y1; row + max_row - 1 <= y2; row += max_row) { - /*Calc. the next y coordinates of draw_buf*/ - sub_area.x1 = area_p->x1; - sub_area.x2 = area_p->x2; - sub_area.y1 = row; - sub_area.y2 = row + max_row - 1; - layer->draw_buf = disp_refr->buf_act; - layer->buf_area = sub_area; - layer->_clip_area = sub_area; - 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; - refr_area_part(layer); + tile_cnt = (area_buf_size + (ideal_tile_size - 1)) / ideal_tile_size; /*Round up*/ + tile_h = lv_area_get_height(area_p) / tile_cnt; } - /*If the last y coordinates are not handled yet ...*/ - if(y2 != row_last) { - /*Calc. the next y coordinates of draw_buf*/ - sub_area.x1 = area_p->x1; - sub_area.x2 = area_p->x2; - sub_area.y1 = row; - sub_area.y2 = y2; - layer->draw_buf = disp_refr->buf_act; - layer->buf_area = sub_area; - layer->_clip_area = sub_area; - layer->phy_clip_area = sub_area; - layer_reshape_draw_buf(layer, LV_STRIDE_AUTO); - disp_refr->last_part = 1; - refr_area_part(layer); + if(tile_cnt == 1) { + refr_configured_layer(layer); } - LV_PROFILER_END; + else { + /* Don't draw to the layers buffer of the display but create smaller dummy layers which are using the + * display's layer buffer. These will be the tiles. By using tiles it's more likely that there will + * be independent areas for each draw unit. */ + lv_layer_t * tile_layers = lv_malloc(tile_cnt * sizeof(lv_layer_t)); + LV_ASSERT_MALLOC(tile_layers); + if(tile_layers == NULL) { + disp_refr->refreshed_area = *area_p; + LV_PROFILER_REFR_END; + return; + } + uint32_t i; + for(i = 0; i < tile_cnt; i++) { + lv_area_t tile_area; + lv_area_set(&tile_area, area_p->x1, area_p->y1 + i * tile_h, + area_p->x2, area_p->y1 + (i + 1) * tile_h - 1); + + if(i == tile_cnt - 1) { + tile_area.y2 = area_p->y2; + } + + lv_layer_t * tile_layer = &tile_layers[i]; + lv_draw_layer_init(tile_layer, NULL, layer->color_format, &tile_area); + tile_layer->buf_area = layer->buf_area; /*the buffer is still large*/ + tile_layer->draw_buf = layer->draw_buf; + refr_configured_layer(tile_layer); + } + + + /*Wait until all tiles are ready and destroy remove them*/ + for(i = 0; i < tile_cnt; i++) { + lv_layer_t * tile_layer = &tile_layers[i]; + while(tile_layer->draw_task_head) { + lv_draw_dispatch_wait_for_request(); + lv_draw_dispatch(); + } + + lv_layer_t * layer_i = disp_refr->layer_head; + while(layer_i) { + if(layer_i->next == tile_layer) { + layer_i->next = tile_layer->next; + break; + } + layer_i = layer_i->next; + } + + if(disp_refr->layer_deinit) disp_refr->layer_deinit(disp_refr, tile_layer); + } + lv_free(tile_layers); + } + + disp_refr->refreshed_area = *area_p; + LV_PROFILER_REFR_END; } -static void refr_area_part(lv_layer_t * layer) +static void refr_configured_layer(lv_layer_t * layer) { - LV_PROFILER_BEGIN; - disp_refr->refreshed_area = layer->_clip_area; + LV_PROFILER_REFR_BEGIN; + + lv_layer_reset(layer); + +#if LV_DRAW_TRANSFORM_USE_MATRIX + if(lv_display_get_matrix_rotation(disp_refr)) { + const lv_display_rotation_t rotation = lv_display_get_rotation(disp_refr); + if(rotation != LV_DISPLAY_ROTATION_0) { + lv_display_rotate_area(disp_refr, &layer->phy_clip_area); + + /** + * The screen rotation direction defined by LVGL is opposite to the drawing angle. + * Use direct matrix assignment to reduce precision loss and improve efficiency. + */ + switch(rotation) { + case LV_DISPLAY_ROTATION_90: + /** + * lv_matrix_rotate(&layer->matrix, 270); + * lv_matrix_translate(&layer->matrix, -disp_refr->ver_res, 0); + */ + layer->matrix.m[0][0] = 0; + layer->matrix.m[0][1] = 1; + layer->matrix.m[0][2] = 0; + layer->matrix.m[1][0] = -1; + layer->matrix.m[1][1] = 0; + layer->matrix.m[1][2] = disp_refr->ver_res; + break; + + case LV_DISPLAY_ROTATION_180: + /** + * lv_matrix_rotate(&layer->matrix, 180); + * lv_matrix_translate(&layer->matrix, -disp_refr->hor_res, -disp_refr->ver_res); + */ + layer->matrix.m[0][0] = -1; + layer->matrix.m[0][1] = 0; + layer->matrix.m[0][2] = disp_refr->hor_res; + layer->matrix.m[1][0] = 0; + layer->matrix.m[1][1] = -1; + layer->matrix.m[1][2] = disp_refr->ver_res; + break; + + case LV_DISPLAY_ROTATION_270: + /** + * lv_matrix_rotate(&layer->matrix, 90); + * lv_matrix_translate(&layer->matrix, 0, -disp_refr->hor_res); + */ + layer->matrix.m[0][0] = 0; + layer->matrix.m[0][1] = -1; + layer->matrix.m[0][2] = disp_refr->hor_res; + layer->matrix.m[1][0] = 1; + layer->matrix.m[1][1] = 0; + layer->matrix.m[1][2] = 0; + break; + + default: + LV_LOG_WARN("Invalid rotation: %d", rotation); + break; + } + } + } +#endif /* LV_DRAW_TRANSFORM_USE_MATRIX */ /* In single buffered mode wait here until the buffer is freed. * Else we would draw into the buffer while it's still being transferred to the display*/ @@ -709,13 +855,9 @@ static void refr_area_part(lv_layer_t * layer) } /*If the screen is transparent initialize it when the flushing is ready*/ if(lv_color_format_has_alpha(disp_refr->color_format)) { - lv_area_t a = disp_refr->refreshed_area; - if(disp_refr->render_mode == LV_DISPLAY_RENDER_MODE_PARTIAL) { - /*The area always starts at 0;0*/ - lv_area_move(&a, -disp_refr->refreshed_area.x1, -disp_refr->refreshed_area.y1); - } - - lv_draw_buf_clear(layer->draw_buf, &a); + lv_area_t clear_area = layer->_clip_area; + lv_area_move(&clear_area, -layer->buf_area.x1, -layer->buf_area.y1); + lv_draw_buf_clear(layer->draw_buf, &clear_area); } lv_obj_t * top_act_scr = NULL; @@ -757,8 +899,7 @@ static void refr_area_part(lv_layer_t * layer) refr_obj_and_children(layer, lv_display_get_layer_top(disp_refr)); refr_obj_and_children(layer, lv_display_get_layer_sys(disp_refr)); - draw_buf_flush(disp_refr); - LV_PROFILER_END; + LV_PROFILER_REFR_END; } /** @@ -774,6 +915,7 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj) 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_style_opa(obj, LV_PART_MAIN) < LV_OPA_MAX) return NULL; /*If this object is fully cover the draw area then check the children too*/ lv_cover_check_info_t info; @@ -815,16 +957,21 @@ static void refr_obj_and_children(lv_layer_t * layer, lv_obj_t * top_obj) if(top_obj == NULL) top_obj = lv_display_get_screen_active(disp_refr); if(top_obj == NULL) return; /*Shouldn't happen*/ - LV_PROFILER_BEGIN; - /*Refresh the top object and its children*/ - refr_obj(layer, top_obj); - + LV_PROFILER_REFR_BEGIN; /*Draw the 'younger' sibling objects because they can be on top_obj*/ lv_obj_t * parent; lv_obj_t * border_p = top_obj; parent = lv_obj_get_parent(top_obj); + /*Calculate the recolor before the parent*/ + if(parent) { + layer->recolor = lv_obj_get_style_recolor_recursive(parent, LV_PART_MAIN); + } + + /*Refresh the top object and its children*/ + refr_obj(layer, top_obj); + /*Do until not reach the screen*/ while(parent != NULL) { bool go = false; @@ -852,7 +999,7 @@ static void refr_obj_and_children(lv_layer_t * layer, lv_obj_t * top_obj) /*Go a level deeper*/ parent = lv_obj_get_parent(parent); } - LV_PROFILER_END; + LV_PROFILER_REFR_END; } static lv_result_t layer_get_area(lv_layer_t * layer, lv_obj_t * obj, lv_layer_type_t layer_type, @@ -915,11 +1062,17 @@ static bool alpha_test_area_on_obj(lv_obj_t * obj, const lv_area_t * area) #if LV_DRAW_TRANSFORM_USE_MATRIX -static void refr_obj_matrix(lv_layer_t * layer, lv_obj_t * obj) +static bool obj_get_matrix(lv_obj_t * obj, lv_matrix_t * matrix) { - lv_matrix_t ori_matrix = layer->matrix; - lv_matrix_t obj_matrix; - lv_matrix_identity(&obj_matrix); + lv_matrix_identity(matrix); + + const lv_matrix_t * obj_matrix = lv_obj_get_transform(obj); + if(obj_matrix) { + lv_matrix_translate(matrix, obj->coords.x1, obj->coords.y1); + lv_matrix_multiply(matrix, obj_matrix); + lv_matrix_translate(matrix, -obj->coords.x1, -obj->coords.y1); + return true; + } lv_point_t pivot = { .x = lv_obj_get_style_transform_pivot_x(obj, 0), @@ -937,39 +1090,58 @@ static void refr_obj_matrix(lv_layer_t * layer, lv_obj_t * obj) if(scale_x <= 0 || scale_y <= 0) { /* NOT draw if scale is negative or zero */ - return; + return false; } /* generate the obj matrix */ - lv_matrix_translate(&obj_matrix, pivot.x, pivot.y); + lv_matrix_translate(matrix, pivot.x, pivot.y); if(rotation != 0) { - lv_matrix_rotate(&obj_matrix, rotation * 0.1f); + lv_matrix_rotate(matrix, rotation * 0.1f); } if(scale_x != LV_SCALE_NONE || scale_y != LV_SCALE_NONE) { lv_matrix_scale( - &obj_matrix, + 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_skew(matrix, skew_x, skew_y); } - lv_matrix_translate(&obj_matrix, -pivot.x, -pivot.y); + lv_matrix_translate(matrix, -pivot.x, -pivot.y); + return true; +} + +static void refr_obj_matrix(lv_layer_t * layer, lv_obj_t * obj) +{ + LV_PROFILER_REFR_BEGIN; + lv_matrix_t obj_matrix; + if(!obj_get_matrix(obj, &obj_matrix)) { + /* NOT draw if obj matrix is not available */ + LV_PROFILER_REFR_END; + return; + } + + lv_matrix_t matrix_inv; + if(!lv_matrix_inverse(&matrix_inv, &obj_matrix)) { + /* NOT draw if matrix is not invertible */ + LV_PROFILER_REFR_END; + return; + } + + /* save original matrix */ + lv_matrix_t ori_matrix = layer->matrix; /* 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); + clip_area = lv_matrix_transform_area(&matrix_inv, &clip_area); /* increase the clip area by 1 pixel to avoid rounding errors */ if(!lv_matrix_is_identity_or_translation(&obj_matrix)) { @@ -985,6 +1157,7 @@ static void refr_obj_matrix(lv_layer_t * layer, lv_obj_t * obj) layer->matrix = ori_matrix; /* restore clip area */ layer->_clip_area = clip_area_ori; + LV_PROFILER_REFR_END; } static bool refr_check_obj_clip_overflow(lv_layer_t * layer, lv_obj_t * obj) @@ -1016,21 +1189,31 @@ static void refr_obj(lv_layer_t * layer, lv_obj_t * obj) { if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return; - lv_opa_t opa = lv_obj_get_style_opa_layered(obj, 0); - if(opa < LV_OPA_MIN) return; + /*If `opa_layered != LV_OPA_COVER` draw the widget on a new layer and blend that layer with the given opacity.*/ + const lv_opa_t opa_layered = lv_obj_get_style_opa_layered(obj, LV_PART_MAIN); + if(opa_layered <= 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; + const lv_opa_t layer_opa_ori = layer->opa; + const lv_color32_t layer_recolor = layer->recolor; + + /*Normal `opa` (not layered) will just scale down `bg_opa`, `text_opa`, etc, in the upcoming drawings.*/ + const lv_opa_t opa_main = lv_obj_get_style_opa(obj, LV_PART_MAIN); + if(opa_main < LV_OPA_MAX) { + layer->opa = LV_OPA_MIX2(layer_opa_ori, opa_main); } -#endif /* LV_DRAW_TRANSFORM_USE_MATRIX */ + + layer->recolor = lv_obj_style_apply_recolor(obj, LV_PART_MAIN, layer->recolor); lv_layer_type_t layer_type = lv_obj_get_layer_type(obj); if(layer_type == LV_LAYER_TYPE_NONE) { lv_obj_redraw(layer, obj); } +#if LV_DRAW_TRANSFORM_USE_MATRIX + /*If the layer opa is full then use the matrix transform*/ + else if(opa_layered >= LV_OPA_MAX && !refr_check_obj_clip_overflow(layer, obj)) { + refr_obj_matrix(layer, obj); + } +#endif /* LV_DRAW_TRANSFORM_USE_MATRIX */ else { lv_area_t layer_area_full; lv_area_t obj_draw_size; @@ -1058,7 +1241,10 @@ static void refr_obj(lv_layer_t * layer, lv_obj_t * obj) * If it really doesn't need alpha use it. Else switch to the ARGB size*/ layer_area_act.y2 = layer_area_act.y1 + max_rgb_row_height - 1; if(layer_area_act.y2 > layer_area_full.y2) layer_area_act.y2 = layer_area_full.y2; - bool area_need_alpha = alpha_test_area_on_obj(obj, &layer_area_act); + + const void * bitmap_mask_src = lv_obj_get_style_bitmap_mask_src(obj, 0); + bool area_need_alpha = bitmap_mask_src || alpha_test_area_on_obj(obj, &layer_area_act); + if(area_need_alpha) { layer_area_act.y2 = layer_area_act.y1 + max_argb_row_height - 1; if(layer_area_act.y2 > layer_area_full.y2) layer_area_act.y2 = layer_area_full.y2; @@ -1085,7 +1271,7 @@ static void refr_obj(lv_layer_t * layer, lv_obj_t * obj) layer_draw_dsc.pivot.x = obj->coords.x1 + pivot.x - new_layer->buf_area.x1; layer_draw_dsc.pivot.y = obj->coords.y1 + pivot.y - new_layer->buf_area.y1; - layer_draw_dsc.opa = opa; + layer_draw_dsc.opa = opa_layered; layer_draw_dsc.rotation = lv_obj_get_style_transform_rotation(obj, 0); while(layer_draw_dsc.rotation > 3600) layer_draw_dsc.rotation -= 3600; while(layer_draw_dsc.rotation < 0) layer_draw_dsc.rotation += 3600; @@ -1095,7 +1281,7 @@ static void refr_obj(lv_layer_t * layer, lv_obj_t * obj) layer_draw_dsc.skew_y = lv_obj_get_style_transform_skew_y(obj, 0); 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.bitmap_mask_src = bitmap_mask_src; layer_draw_dsc.image_area = obj_draw_size; layer_draw_dsc.src = new_layer; @@ -1104,6 +1290,10 @@ static void refr_obj(lv_layer_t * layer, lv_obj_t * obj) layer_area_act.y1 = layer_area_act.y2 + 1; } } + + /* Restore the original layer opa and recolor */ + layer->opa = layer_opa_ori; + layer->recolor = layer_recolor; } static uint32_t get_max_row(lv_display_t * disp, int32_t area_w, int32_t area_h) @@ -1112,6 +1302,11 @@ static uint32_t get_max_row(lv_display_t * disp, int32_t area_w, int32_t area_h) uint32_t stride = lv_draw_buf_width_to_stride(area_w, cf); uint32_t overhead = LV_COLOR_INDEXED_PALETTE_SIZE(cf) * sizeof(lv_color32_t); + if(stride == 0) { + LV_LOG_WARN("Invalid stride. Value is 0"); + return 0; + } + int32_t max_row = (uint32_t)(disp->buf_act->data_size - overhead) / stride; if(max_row > area_h) max_row = area_h; @@ -1182,6 +1377,9 @@ static void draw_buf_flush(lv_display_t * disp) if(disp->buf_act == disp->buf_1) { disp->buf_act = disp->buf_2; } + else if(disp->buf_act == disp->buf_2) { + disp->buf_act = disp->buf_3 ? disp->buf_3 : disp->buf_1; + } else { disp->buf_act = disp->buf_1; } @@ -1190,7 +1388,7 @@ static void draw_buf_flush(lv_display_t * disp) static void call_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) { - LV_PROFILER_BEGIN; + LV_PROFILER_REFR_BEGIN; LV_TRACE_REFR("Calling flush_cb on (%d;%d)(%d;%d) area with %p image pointer", (int)area->x1, (int)area->y1, (int)area->x2, (int)area->y2, (void *)px_map); @@ -1211,12 +1409,12 @@ static void call_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * disp->flush_cb(disp, &offset_area, px_map); lv_display_send_event(disp, LV_EVENT_FLUSH_FINISH, &offset_area); - LV_PROFILER_END; + LV_PROFILER_REFR_END; } static void wait_for_flushing(lv_display_t * disp) { - LV_PROFILER_BEGIN; + LV_PROFILER_REFR_BEGIN; LV_LOG_TRACE("begin"); lv_display_send_event(disp, LV_EVENT_FLUSH_WAIT_START, NULL); @@ -1224,8 +1422,8 @@ static void wait_for_flushing(lv_display_t * disp) if(disp->flush_wait_cb) { if(disp->flushing) { disp->flush_wait_cb(disp); + disp->flushing = 0; } - disp->flushing = 0; } else { while(disp->flushing); @@ -1235,5 +1433,5 @@ static void wait_for_flushing(lv_display_t * disp) lv_display_send_event(disp, LV_EVENT_FLUSH_WAIT_FINISH, NULL); LV_LOG_TRACE("end"); - LV_PROFILER_END; + LV_PROFILER_REFR_END; } diff --git a/lib/libesp32_lvgl/lvgl/src/core/lv_refr.h b/lib/libesp32_lvgl/lvgl/src/core/lv_refr.h index 6b756edb5..1756e32f0 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_refr.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_refr.h @@ -57,6 +57,12 @@ void lv_refr_now(lv_display_t * disp); */ void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj); +/** + * Called periodically to handle the refreshing + * @param timer pointer to the timer itself, or `NULL` + */ +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 index 8f840780b..3b2985b70 100644 --- a/lib/libesp32_lvgl/lvgl/src/core/lv_refr_private.h +++ b/lib/libesp32_lvgl/lvgl/src/core/lv_refr_private.h @@ -58,12 +58,6 @@ lv_display_t * lv_refr_get_disp_refreshing(void); */ 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 **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/display/lv_display.c b/lib/libesp32_lvgl/lvgl/src/display/lv_display.c index df4bb9b27..c183b392f 100644 --- a/lib/libesp32_lvgl/lvgl/src/display/lv_display.c +++ b/lib/libesp32_lvgl/lvgl/src/display/lv_display.c @@ -77,9 +77,17 @@ lv_display_t * lv_display_create(int32_t hor_res, int32_t ver_res) disp->dpi = LV_DPI_DEF; disp->color_format = LV_COLOR_FORMAT_NATIVE; - disp->layer_head = lv_malloc_zeroed(sizeof(lv_layer_t)); + +#if defined(LV_DRAW_SW_DRAW_UNIT_CNT) && (LV_DRAW_SW_DRAW_UNIT_CNT != 0) + disp->tile_cnt = LV_DRAW_SW_DRAW_UNIT_CNT; +#else + disp->tile_cnt = 1; +#endif + + disp->layer_head = lv_malloc(sizeof(lv_layer_t)); LV_ASSERT_MALLOC(disp->layer_head); if(disp->layer_head == NULL) return NULL; + lv_layer_init(disp->layer_head); if(disp->layer_init) disp->layer_init(disp, disp->layer_head); disp->layer_head->buf_area.x1 = 0; @@ -119,6 +127,13 @@ lv_display_t * lv_display_create(int32_t hor_res, int32_t ver_res) else { disp->theme = lv_theme_simple_get(); } +#elif LV_USE_THEME_MONO + if(lv_theme_mono_is_inited() == false) { + disp->theme = lv_theme_mono_init(disp, false, LV_FONT_DEFAULT); + } + else { + disp->theme = lv_theme_mono_get(); + } #endif disp->bottom_layer = lv_obj_create(NULL); /*Create bottom layer on the display*/ @@ -314,6 +329,26 @@ int32_t lv_display_get_vertical_resolution(const lv_display_t * disp) } } +int32_t lv_display_get_original_horizontal_resolution(const lv_display_t * disp) +{ + if(disp == NULL) disp = lv_display_get_default(); + if(disp == NULL) { + return 0; + } + + return disp->hor_res; +} + +int32_t lv_display_get_original_vertical_resolution(const lv_display_t * disp) +{ + if(disp == NULL) disp = lv_display_get_default(); + if(disp == NULL) { + return 0; + } + + return disp->ver_res; +} + int32_t lv_display_get_physical_horizontal_resolution(const lv_display_t * disp) { if(disp == NULL) disp = lv_display_get_default(); @@ -411,6 +446,19 @@ void lv_display_set_draw_buffers(lv_display_t * disp, lv_draw_buf_t * buf1, lv_d disp->buf_1 = buf1; disp->buf_2 = buf2; disp->buf_act = disp->buf_1; + + disp->stride_is_auto = 0; +} + +void lv_display_set_3rd_draw_buffer(lv_display_t * disp, lv_draw_buf_t * buf3) +{ + if(disp == NULL) disp = lv_display_get_default(); + if(disp == NULL) return; + + LV_ASSERT_MSG(disp->buf_1 != NULL, "buf1 is null"); + LV_ASSERT_MSG(disp->buf_2 != NULL, "buf2 is null"); + + disp->buf_3 = buf3; } void lv_display_set_buffers(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size, @@ -418,9 +466,8 @@ void lv_display_set_buffers(lv_display_t * disp, void * buf1, void * buf2, uint3 { LV_ASSERT_MSG(buf1 != NULL, "Null buffer"); lv_color_format_t cf = lv_display_get_color_format(disp); - uint32_t w = lv_display_get_horizontal_resolution(disp); - uint32_t h = lv_display_get_vertical_resolution(disp); - + uint32_t w = lv_display_get_original_horizontal_resolution(disp); + uint32_t h = lv_display_get_original_vertical_resolution(disp); LV_ASSERT_MSG(w != 0 && h != 0, "display resolution is 0"); /* buf1 or buf2 is not aligned according to LV_DRAW_BUF_ALIGN */ @@ -428,6 +475,40 @@ void lv_display_set_buffers(lv_display_t * disp, void * buf1, void * buf2, uint3 LV_ASSERT_FORMAT_MSG(buf2 == NULL || buf2 == lv_draw_buf_align(buf2, cf), "buf2 is not aligned: %p", buf2); uint32_t stride = lv_draw_buf_width_to_stride(w, cf); + if(render_mode == LV_DISPLAY_RENDER_MODE_PARTIAL) { + LV_ASSERT_FORMAT_MSG(stride != 0, "stride is 0, check your color format %d and width: %" LV_PRIu32, cf, w); + /* for partial mode, we calculate the height based on the buf_size and stride */ + h = buf_size / stride; + LV_ASSERT_MSG(h != 0, "the buffer is too small"); + } + else { + LV_ASSERT_FORMAT_MSG(stride * h <= buf_size, "%s mode requires screen sized buffer(s)", + render_mode == LV_DISPLAY_RENDER_MODE_FULL ? "FULL" : "DIRECT"); + } + + lv_draw_buf_init(&disp->_static_buf1, w, h, cf, stride, buf1, buf_size); + lv_draw_buf_init(&disp->_static_buf2, w, h, cf, stride, buf2, buf_size); + lv_display_set_draw_buffers(disp, &disp->_static_buf1, buf2 ? &disp->_static_buf2 : NULL); + lv_display_set_render_mode(disp, render_mode); + + /* the stride was not set explicitly */ + disp->stride_is_auto = 1; +} + +void lv_display_set_buffers_with_stride(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size, + uint32_t stride, lv_display_render_mode_t render_mode) +{ + if(stride == LV_STRIDE_AUTO) { + lv_display_set_buffers(disp, buf1, buf2, buf_size, render_mode); + return; + } + + LV_ASSERT_MSG(buf1 != NULL, "Null buffer"); + lv_color_format_t cf = lv_display_get_color_format(disp); + uint32_t w = lv_display_get_original_horizontal_resolution(disp); + uint32_t h = lv_display_get_original_vertical_resolution(disp); + LV_ASSERT_MSG(w != 0 && h != 0, "display resolution is 0"); + if(render_mode == LV_DISPLAY_RENDER_MODE_PARTIAL) { /* for partial mode, we calculate the height based on the buf_size and stride */ h = buf_size / stride; @@ -442,6 +523,8 @@ void lv_display_set_buffers(lv_display_t * disp, void * buf1, void * buf2, uint3 lv_draw_buf_init(&disp->_static_buf2, w, h, cf, stride, buf2, buf_size); lv_display_set_draw_buffers(disp, &disp->_static_buf1, buf2 ? &disp->_static_buf2 : NULL); lv_display_set_render_mode(disp, render_mode); + + disp->stride_is_auto = 0; } void lv_display_set_render_mode(lv_display_t * disp, lv_display_render_mode_t render_mode) @@ -476,6 +559,7 @@ void lv_display_set_color_format(lv_display_t * disp, lv_color_format_t color_fo 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; + if(disp->buf_3) disp->buf_3->header.cf = color_format; lv_display_send_event(disp, LV_EVENT_COLOR_FORMAT_CHANGED, NULL); } @@ -488,6 +572,24 @@ lv_color_format_t lv_display_get_color_format(lv_display_t * disp) return disp->color_format; } +void lv_display_set_tile_cnt(lv_display_t * disp, uint32_t tile_cnt) +{ + LV_ASSERT_FORMAT_MSG(tile_cnt < 256, "tile_cnt must be smaller than 256 (%" LV_PRId32 " was used)", tile_cnt); + + if(disp == NULL) disp = lv_display_get_default(); + if(disp == NULL) return; + + disp->tile_cnt = tile_cnt; +} + +uint32_t lv_display_get_tile_cnt(lv_display_t * disp) +{ + if(disp == NULL) disp = lv_display_get_default(); + if(disp == NULL) return 0; + + return disp->tile_cnt; +} + void lv_display_set_antialiasing(lv_display_t * disp, bool en) { if(disp == NULL) disp = lv_display_get_default(); @@ -578,7 +680,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); } @@ -796,6 +898,17 @@ lv_result_t lv_display_send_event(lv_display_t * disp, lv_event_code_t code, voi return res; } +lv_area_t * lv_event_get_invalidated_area(lv_event_t * e) +{ + if(e->code == LV_EVENT_INVALIDATE_AREA) { + return lv_event_get_param(e); + } + else { + LV_LOG_WARN("Not interpreted with this event code"); + return NULL; + } +} + void lv_display_set_rotation(lv_display_t * disp, lv_display_rotation_t rotation) { if(disp == NULL) disp = lv_display_get_default(); @@ -812,6 +925,32 @@ lv_display_rotation_t lv_display_get_rotation(lv_display_t * disp) return disp->rotation; } +void lv_display_set_matrix_rotation(lv_display_t * disp, bool enable) +{ +#if LV_DRAW_TRANSFORM_USE_MATRIX + if(disp == NULL) disp = lv_display_get_default(); + if(disp == NULL) return; + + if(!(disp->render_mode == LV_DISPLAY_RENDER_MODE_DIRECT || disp->render_mode == LV_DISPLAY_RENDER_MODE_FULL)) { + LV_LOG_WARN("Unsupported rendering mode: %d", disp->render_mode); + return; + } + + disp->matrix_rotation = enable; +#else + (void)disp; + (void)enable; + LV_LOG_WARN("LV_DRAW_TRANSFORM_USE_MATRIX was not enabled"); +#endif +} + +bool lv_display_get_matrix_rotation(lv_display_t * disp) +{ + if(disp == NULL) disp = lv_display_get_default(); + if(disp == NULL) return false; + return disp->matrix_rotation; +} + void lv_display_set_theme(lv_display_t * disp, lv_theme_t * th) { if(!disp) disp = lv_display_get_default(); @@ -902,6 +1041,49 @@ void lv_display_delete_refr_timer(lv_display_t * disp) disp->refr_timer = NULL; } +lv_result_t lv_display_send_vsync_event(lv_display_t * disp, void * param) +{ + if(!disp) disp = lv_display_get_default(); + if(!disp) return LV_RESULT_INVALID; + + if(disp->vsync_count > 0) + return lv_display_send_event(disp, LV_EVENT_VSYNC, param); + + return LV_RESULT_INVALID; +} + +bool lv_display_register_vsync_event(lv_display_t * disp, lv_event_cb_t event_cb, void * user_data) +{ + if(!disp) disp = lv_display_get_default(); + if(!disp) return false; + + lv_display_add_event_cb(disp, event_cb, LV_EVENT_VSYNC, user_data); + + /*only send once*/ + if(disp->vsync_count == 0) + lv_display_send_event(disp, LV_EVENT_VSYNC_REQUEST, disp); + + disp->vsync_count++; + return true; +} + +bool lv_display_unregister_vsync_event(lv_display_t * disp, lv_event_cb_t event_cb, void * user_data) +{ + if(!disp) disp = lv_display_get_default(); + if(!disp) return false; + + uint32_t removed_count = lv_display_remove_event_cb_with_user_data(disp, event_cb, user_data); + if(removed_count == 0) + return false; + + disp->vsync_count -= removed_count; + /*only send once*/ + if(disp->vsync_count == 0) + lv_display_send_event(disp, LV_EVENT_VSYNC_REQUEST, NULL); + + return true; +} + void lv_display_set_user_data(lv_display_t * disp, void * user_data) { if(!disp) disp = lv_display_get_default(); @@ -943,12 +1125,12 @@ void lv_display_rotate_area(lv_display_t * disp, lv_area_t * area) { lv_display_rotation_t rotation = lv_display_get_rotation(disp); + if(rotation == LV_DISPLAY_ROTATION_0) return; + 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; @@ -967,9 +1149,43 @@ void lv_display_rotate_area(lv_display_t * disp, lv_area_t * area) area->x2 = area->x1 + h - 1; area->y1 = area->y2 - w + 1; break; + default: + break; } } +uint32_t lv_display_get_draw_buf_size(lv_display_t * disp) +{ + if(!disp) disp = lv_display_get_default(); + if(!disp) return 0; + + if(disp->buf_1) { + return disp->buf_1->data_size; + } + return 0; +} + +uint32_t lv_display_get_invalidated_draw_buf_size(lv_display_t * disp, uint32_t width, uint32_t height) +{ + if(!disp) disp = lv_display_get_default(); + if(!disp) return 0; + + if(disp->render_mode == LV_DISPLAY_RENDER_MODE_FULL) { + width = lv_display_get_horizontal_resolution(disp); + height = lv_display_get_vertical_resolution(disp); + } + + lv_color_format_t cf = lv_display_get_color_format(disp); + uint32_t stride = lv_draw_buf_width_to_stride(width, cf); + uint32_t buf_size = stride * height; + + LV_ASSERT(disp->buf_1 && disp->buf_1->data_size >= buf_size); + if(disp->buf_2) LV_ASSERT(disp->buf_2->data_size >= buf_size); + if(disp->buf_3) LV_ASSERT(disp->buf_3->data_size >= buf_size); + + return buf_size; +} + lv_obj_t * lv_screen_active(void) { return lv_display_get_screen_active(lv_display_get_default()); diff --git a/lib/libesp32_lvgl/lvgl/src/display/lv_display.h b/lib/libesp32_lvgl/lvgl/src/display/lv_display.h index e3e7c49f2..ddcd1ee05 100644 --- a/lib/libesp32_lvgl/lvgl/src/display/lv_display.h +++ b/lib/libesp32_lvgl/lvgl/src/display/lv_display.h @@ -17,7 +17,7 @@ extern "C" { #include "../misc/lv_timer.h" #include "../misc/lv_event.h" #include "../misc/lv_color.h" -#include "../draw/lv_draw.h" +#include "../misc/lv_area.h" /********************* * DEFINES @@ -54,7 +54,7 @@ typedef enum { /** * Always redraw the whole screen even if only one pixel has been changed. - * With 2 buffers in flush_cb only and address change is required. + * With 2 buffers in flush_cb only an address change is required. */ LV_DISPLAY_RENDER_MODE_FULL, } lv_display_render_mode_t; @@ -158,6 +158,13 @@ void lv_display_set_offset(lv_display_t * disp, int32_t x, int32_t y); */ void lv_display_set_rotation(lv_display_t * disp, lv_display_rotation_t rotation); +/** + * Use matrix rotation for the display. This function is depended on `LV_DRAW_TRANSFORM_USE_MATRIX` + * @param disp pointer to a display (NULL to use the default display) + * @param enable true: enable matrix rotation, false: disable + */ +void lv_display_set_matrix_rotation(lv_display_t * disp, bool enable); + /** * Set the DPI (dot per inch) of the display. * dpi = sqrt(hor_res^2 + ver_res^2) / diagonal" @@ -180,6 +187,20 @@ int32_t lv_display_get_horizontal_resolution(const lv_display_t * disp); */ int32_t lv_display_get_vertical_resolution(const lv_display_t * disp); +/** + * Get the original horizontal resolution of a display without considering rotation + * @param disp pointer to a display (NULL to use the default display) + * @return the horizontal resolution of the display. + */ +int32_t lv_display_get_original_horizontal_resolution(const lv_display_t * disp); + +/** + * Get the original vertical resolution of a display without considering rotation + * @param disp pointer to a display (NULL to use the default display) + * @return the vertical resolution of the display + */ +int32_t lv_display_get_original_vertical_resolution(const lv_display_t * disp); + /** * Get the physical horizontal resolution of a display * @param disp pointer to a display (NULL to use the default display) @@ -215,6 +236,13 @@ int32_t lv_display_get_offset_y(const lv_display_t * disp); */ lv_display_rotation_t lv_display_get_rotation(lv_display_t * disp); +/** + * Get if matrix rotation is enabled for a display or not + * @param disp pointer to a display (NULL to use the default display) + * @return true: matrix rotation is enabled; false: disabled + */ +bool lv_display_get_matrix_rotation(lv_display_t * disp); + /** * Get the DPI of the display * @param disp pointer to a display (NULL to use the default display) @@ -239,6 +267,21 @@ int32_t lv_display_get_dpi(const lv_display_t * disp); void lv_display_set_buffers(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size, lv_display_render_mode_t render_mode); +/** + * Set the frame buffers for a display, similarly to `lv_display_set_buffers`, but allow + * for a custom stride as required by a display controller. + * This allows the frame buffers to have a stride alignment different from the rest of + * the buffers` + * @param disp pointer to a display + * @param buf1 first buffer + * @param buf2 second buffer (can be `NULL`) + * @param buf_size buffer size in byte + * @param stride buffer stride in bytes + * @param render_mode LV_DISPLAY_RENDER_MODE_PARTIAL/DIRECT/FULL + */ +void lv_display_set_buffers_with_stride(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size, + uint32_t stride, lv_display_render_mode_t render_mode); + /** * Set the buffers for a display, accept a draw buffer pointer. * Normally use `lv_display_set_buffers` is enough for most cases. @@ -249,6 +292,13 @@ void lv_display_set_buffers(lv_display_t * disp, void * buf1, void * buf2, uint3 */ void lv_display_set_draw_buffers(lv_display_t * disp, lv_draw_buf_t * buf1, lv_draw_buf_t * buf2); +/** + * Set the third draw buffer for a display. + * @param disp pointer to a display + * @param buf3 third buffer + */ +void lv_display_set_3rd_draw_buffer(lv_display_t * disp, lv_draw_buf_t * buf3); + /** * Set display render mode * @param disp pointer to a display @@ -293,6 +343,20 @@ void lv_display_set_color_format(lv_display_t * disp, lv_color_format_t color_fo */ lv_color_format_t lv_display_get_color_format(lv_display_t * disp); +/** + * Set the number of tiles for parallel rendering. + * @param disp pointer to a display + * @param tile_cnt number of tiles (1 =< tile_cnt < 256) + */ +void lv_display_set_tile_cnt(lv_display_t * disp, uint32_t tile_cnt); + +/** + * Get the number of tiles used for parallel rendering + * @param disp pointer to a display + * @return number of tiles + */ +uint32_t lv_display_get_tile_cnt(lv_display_t * disp); + /** * Enable anti-aliasing for the render engine * @param disp pointer to a display @@ -307,8 +371,6 @@ void lv_display_set_antialiasing(lv_display_t * disp, bool en); */ bool lv_display_get_antialiasing(lv_display_t * disp); -//! @cond Doxygen_Suppress - /** * Call from the display driver when the flushing is finished * @param disp pointer to display whose `flush_cb` was called @@ -324,8 +386,6 @@ LV_ATTRIBUTE_FLUSH_READY void lv_display_flush_ready(lv_display_t * disp); */ LV_ATTRIBUTE_FLUSH_READY bool lv_display_flush_is_last(lv_display_t * disp); -//! @endcond - bool lv_display_is_double_buffered(lv_display_t * disp); /*--------------------- @@ -374,7 +434,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 @@ -465,6 +525,13 @@ uint32_t lv_display_remove_event_cb_with_user_data(lv_display_t * disp, lv_event */ lv_result_t lv_display_send_event(lv_display_t * disp, lv_event_code_t code, void * param); +/** + * Get the area to be invalidated. Can be used in `LV_EVENT_INVALIDATE_AREA` + * @param e pointer to an event + * @return the area to invalidated (can be modified as required) + */ +lv_area_t * lv_event_get_invalidated_area(lv_event_t * e); + /** * Set the theme of a display. If there are no user created widgets yet the screens' theme will be updated * @param disp pointer to a display @@ -520,6 +587,33 @@ lv_timer_t * lv_display_get_refr_timer(lv_display_t * disp); */ void lv_display_delete_refr_timer(lv_display_t * disp); +/** + * Register vsync event of a display. `LV_EVENT_VSYNC` event will be sent periodically. + * Please don't use it in display event listeners, as it may cause memory leaks and illegal access issues. + * + * @param disp pointer to a display + * @param event_cb an event callback + * @param user_data optional user_data + */ +bool lv_display_register_vsync_event(lv_display_t * disp, lv_event_cb_t event_cb, void * user_data); + +/** + * Unregister vsync event of a display. `LV_EVENT_VSYNC` event won't be sent periodically. + * Please don't use it in display event listeners, as it may cause memory leaks and illegal access issues. + * @param disp pointer to a display + * @param event_cb an event callback + * @param user_data optional user_data + */ +bool lv_display_unregister_vsync_event(lv_display_t * disp, lv_event_cb_t event_cb, void * user_data); + +/** + * Send an vsync event to a display + * @param disp pointer to a display + * @param param optional param + * @return LV_RESULT_OK: disp wasn't deleted in the event. + */ +lv_result_t lv_display_send_vsync_event(lv_display_t * disp, void * param); + void lv_display_set_user_data(lv_display_t * disp, void * user_data); void lv_display_set_driver_data(lv_display_t * disp, void * driver_data); void * lv_display_get_user_data(lv_display_t * disp); @@ -533,6 +627,24 @@ lv_draw_buf_t * lv_display_get_buf_active(lv_display_t * disp); */ void lv_display_rotate_area(lv_display_t * disp, lv_area_t * area); +/** + * Get the size of the draw buffers + * @param disp pointer to a display + * @return the size of the draw buffer in bytes for valid display, 0 otherwise + */ +uint32_t lv_display_get_draw_buf_size(lv_display_t * disp); + +/** + * Get the size of the invalidated draw buffer. Can be used in the flush callback + * to get the number of bytes used in the current render buffer. + * @param disp pointer to a display + * @param width the width of the invalidated area + * @param height the height of the invalidated area + * @return the size of the invalidated draw buffer in bytes, not accounting for + * any preceding palette information for a valid display, 0 otherwise + */ +uint32_t lv_display_get_invalidated_draw_buf_size(lv_display_t * disp, uint32_t width, uint32_t height); + /********************** * MACROS **********************/ @@ -557,32 +669,37 @@ void lv_display_rotate_area(lv_display_t * disp, lv_area_t * area); #endif /** + * See `lv_dpx()` and `lv_display_dpx()`. * Same as Android's DIP. (Different name is chosen to avoid mistype between LV_DPI and LV_DIP) - * 1 dip is 1 px on a 160 DPI screen - * 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 + * + * - 40 dip is 40 px on a 160 DPI screen (distance = 1/4 inch). + * - 40 dip is 80 px on a 320 DPI screen (distance still = 1/4 inch). + * + * @sa 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) /** - * Scale the given number of pixels (a distance or size) relative to a 160 DPI display - * considering the DPI of the default display. - * It ensures that e.g. `lv_dpx(100)` will have the same physical size regardless to the - * DPI of the display. - * @param n the number of pixels to scale - * @return `n x current_dpi/160` + * For default display, computes the number of pixels (a distance or size) as if the + * display had 160 DPI. This allows you to specify 1/160-th fractions of an inch to + * get real distance on the display that will be consistent regardless of its current + * DPI. It ensures `lv_dpx(100)`, for example, will have the same physical size + * regardless to the DPI of the display. + * @param n number of 1/160-th-inch units to compute with + * @return number of pixels to use to make that distance */ int32_t lv_dpx(int32_t n); /** - * Scale the given number of pixels (a distance or size) relative to a 160 DPI display - * considering the DPI of the given display. - * It ensures that e.g. `lv_dpx(100)` will have the same physical size regardless to the - * DPI of the display. - * @param disp a display whose dpi should be considered - * @param n the number of pixels to scale - * @return `n x current_dpi/160` + * For specified display, computes the number of pixels (a distance or size) as if the + * display had 160 DPI. This allows you to specify 1/160-th fractions of an inch to + * get real distance on the display that will be consistent regardless of its current + * DPI. It ensures `lv_dpx(100)`, for example, will have the same physical size + * regardless to the DPI of the display. + * @param disp pointer to display whose dpi should be considered + * @param n number of 1/160-th-inch units to compute with + * @return number of pixels to use to make that distance */ int32_t lv_display_dpx(const lv_display_t * disp, int32_t n); 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 7dc9f189f..6545b0c16 100644 --- a/lib/libesp32_lvgl/lvgl/src/display/lv_display_private.h +++ b/lib/libesp32_lvgl/lvgl/src/display/lv_display_private.h @@ -33,7 +33,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_display_t { +struct _lv_display_t { /*--------------------- * Resolution @@ -65,6 +65,7 @@ struct lv_display_t { *--------------------*/ lv_draw_buf_t * buf_1; lv_draw_buf_t * buf_2; + lv_draw_buf_t * buf_3; /** Internal, used by the library*/ lv_draw_buf_t * buf_act; @@ -91,6 +92,9 @@ struct lv_display_t { lv_display_render_mode_t render_mode; uint32_t antialiasing : 1; /**< 1: anti-aliasing is enabled on this display.*/ + uint32_t tile_cnt : 8; /**< Divide the display buffer into these number of tiles */ + uint32_t stride_is_auto : 1; /**< 1: The stride of the buffers was not set explicitly. */ + /** 1: The current screen rendering is in progress*/ uint32_t rendering_in_progress : 1; @@ -143,6 +147,8 @@ struct lv_display_t { uint32_t rotation : 3; /**< Element of lv_display_rotation_t*/ + uint32_t matrix_rotation : 1; /**< 1: Use matrix for display rotation*/ + lv_theme_t * theme; /**< The theme assigned to the screen*/ /** A timer which periodically checks the dirty areas and refreshes them*/ @@ -153,6 +159,7 @@ struct lv_display_t { /** The area being refreshed*/ lv_area_t refreshed_area; + uint32_t vsync_count; #if LV_USE_PERF_MONITOR lv_obj_t * perf_label; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d.c b/lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d.c new file mode 100644 index 000000000..465de8c11 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d.c @@ -0,0 +1,472 @@ +/** + * @file lv_draw_dma2d.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_dma2d_private.h" +#if LV_USE_DRAW_DMA2D + +#include "../sw/lv_draw_sw.h" +#include "../../misc/lv_area_private.h" + +#if !LV_DRAW_DMA2D_ASYNC && LV_USE_DRAW_DMA2D_INTERRUPT + #warning LV_USE_DRAW_DMA2D_INTERRUPT is 1 but has no effect because LV_USE_OS is LV_OS_NONE +#endif + +/********************* + * DEFINES + *********************/ + +#define DRAW_UNIT_ID_DMA2D 5 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static int32_t evaluate_cb(lv_draw_unit_t * draw_unit, lv_draw_task_t * task); +static int32_t dispatch_cb(lv_draw_unit_t * draw_unit, lv_layer_t * layer); +static int32_t delete_cb(lv_draw_unit_t * draw_unit); +#if LV_DRAW_DMA2D_ASYNC + static void thread_cb(void * arg); +#endif +#if !LV_DRAW_DMA2D_ASYNC + static bool check_transfer_completion(void); +#endif +static void post_transfer_tasks(lv_draw_dma2d_unit_t * u); + +/********************** + * STATIC VARIABLES + **********************/ + +#if LV_DRAW_DMA2D_ASYNC + static lv_draw_dma2d_unit_t * g_unit; +#endif + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_dma2d_init(void) +{ + lv_draw_dma2d_unit_t * draw_dma2d_unit = lv_draw_create_unit(sizeof(lv_draw_dma2d_unit_t)); + draw_dma2d_unit->base_unit.evaluate_cb = evaluate_cb; + draw_dma2d_unit->base_unit.dispatch_cb = dispatch_cb; + draw_dma2d_unit->base_unit.delete_cb = delete_cb; + draw_dma2d_unit->base_unit.name = "DMA2D"; + +#if LV_DRAW_DMA2D_ASYNC + g_unit = draw_dma2d_unit; + + lv_result_t res = lv_thread_init(&draw_dma2d_unit->thread, "dma2d", LV_DRAW_THREAD_PRIO, thread_cb, 2 * 1024, + draw_dma2d_unit); + LV_ASSERT(res == LV_RESULT_OK); +#endif + + /* enable the DMA2D clock */ +#if defined(STM32F4) || defined(STM32F7) || defined(STM32U5) + RCC->AHB1ENR |= RCC_AHB1ENR_DMA2DEN; +#elif defined(STM32H7) + RCC->AHB3ENR |= RCC_AHB3ENR_DMA2DEN; +#elif defined(STM32H7RS) + RCC->AHB5ENR |= RCC_AHB5ENR_DMA2DEN; +#else +#warning "LVGL can't enable the clock for DMA2D" +#endif + + /* disable dead time */ + DMA2D->AMTCR = 0; + + /* enable the interrupt */ + NVIC_EnableIRQ(DMA2D_IRQn); +} + +void lv_draw_dma2d_deinit(void) +{ + /* disable the interrupt */ + NVIC_DisableIRQ(DMA2D_IRQn); + + /* disable the DMA2D clock */ +#if defined(STM32F4) || defined(STM32F7) || defined(STM32U5) || defined(STM32L4) + RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA2DEN; +#elif defined(STM32H7) + RCC->AHB3ENR &= ~RCC_AHB3ENR_DMA2DEN; +#elif defined(STM32H7RS) + RCC->AHB5ENR &= ~RCC_AHB5ENR_DMA2DEN; +#endif + +#if LV_DRAW_DMA2D_ASYNC + lv_result_t res = lv_thread_delete(&g_unit->thread); + LV_ASSERT(res == LV_RESULT_OK); + + res = lv_thread_sync_delete(&g_unit->interrupt_signal); + LV_ASSERT(res == LV_RESULT_OK); + + g_unit = NULL; +#endif +} + +#if LV_USE_DRAW_DMA2D_INTERRUPT +void lv_draw_dma2d_transfer_complete_interrupt_handler(void) +{ +#if LV_DRAW_DMA2D_ASYNC + lv_thread_sync_signal_isr(&g_unit->interrupt_signal); +#endif +} +#endif + +lv_draw_dma2d_output_cf_t lv_draw_dma2d_cf_to_dma2d_output_cf(lv_color_format_t cf) +{ + switch(cf) { + case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_XRGB8888: + return LV_DRAW_DMA2D_OUTPUT_CF_ARGB8888; + case LV_COLOR_FORMAT_RGB888: + return LV_DRAW_DMA2D_OUTPUT_CF_RGB888; + case LV_COLOR_FORMAT_RGB565: + return LV_DRAW_DMA2D_OUTPUT_CF_RGB565; + case LV_COLOR_FORMAT_ARGB1555: + return LV_DRAW_DMA2D_OUTPUT_CF_ARGB1555; + default: + LV_ASSERT_MSG(false, "unsupported output color format"); + } + return LV_DRAW_DMA2D_OUTPUT_CF_RGB565; +} + +uint32_t lv_draw_dma2d_color_to_dma2d_color(lv_draw_dma2d_output_cf_t cf, lv_color_t color) +{ + switch(cf) { + case LV_DRAW_DMA2D_OUTPUT_CF_ARGB8888: + case LV_DRAW_DMA2D_OUTPUT_CF_RGB888: + return lv_color_to_u32(color); + case LV_DRAW_DMA2D_OUTPUT_CF_RGB565: + return lv_color_to_u16(color); + default: + LV_ASSERT_MSG(false, "unsupported output color format"); + } + return 0; +} + +void lv_draw_dma2d_configure_and_start_transfer(const lv_draw_dma2d_configuration_t * conf) +{ + /* number of lines register */ + DMA2D->NLR = (conf->w << DMA2D_NLR_PL_Pos) | (conf->h << DMA2D_NLR_NL_Pos); + + /* output */ + + /* output memory address register */ + DMA2D->OMAR = (uint32_t)(uintptr_t) conf->output_address; + /* output offset register */ + DMA2D->OOR = conf->output_offset; + /* output pixel format converter control register */ + DMA2D->OPFCCR = ((uint32_t) conf->output_cf) << DMA2D_OPFCCR_CM_Pos; + + /* Fill color. Only for mode LV_DRAW_DMA2D_MODE_REGISTER_TO_MEMORY */ + DMA2D->OCOLR = conf->reg_to_mem_mode_color; + + /* foreground */ + + /* foreground memory address register */ + DMA2D->FGMAR = (uint32_t)(uintptr_t) conf->fg_address; + /* foreground offset register */ + DMA2D->FGOR = conf->fg_offset; + /* foreground color. only for mem-to-mem with blending and fixed-color foreground */ + DMA2D->FGCOLR = conf->fg_color; + /* foreground pixel format converter control register */ + DMA2D->FGPFCCR = (((uint32_t) conf->fg_cf) << DMA2D_FGPFCCR_CM_Pos) + | (conf->fg_alpha << DMA2D_FGPFCCR_ALPHA_Pos) + | (conf->fg_alpha_mode << DMA2D_FGPFCCR_AM_Pos); + + /* background */ + + DMA2D->BGMAR = (uint32_t)(uintptr_t) conf->bg_address; + DMA2D->BGOR = conf->bg_offset; + DMA2D->BGCOLR = conf->bg_color; + DMA2D->BGPFCCR = (((uint32_t) conf->bg_cf) << DMA2D_BGPFCCR_CM_Pos) + | (conf->bg_alpha << DMA2D_BGPFCCR_ALPHA_Pos) + | (conf->bg_alpha_mode << DMA2D_BGPFCCR_AM_Pos); + + /* ensure the DMA2D register values are observed before the start transfer bit is set */ + __DSB(); + + /* start the transfer (also set mode and enable transfer complete interrupt) */ + DMA2D->CR = DMA2D_CR_START | (((uint32_t) conf->mode) << DMA2D_CR_MODE_Pos) +#if LV_USE_DRAW_DMA2D_INTERRUPT + | DMA2D_CR_TCIE +#endif + ; +} + +#if LV_DRAW_DMA2D_CACHE +void lv_draw_dma2d_invalidate_cache(const lv_draw_dma2d_cache_area_t * mem_area) +{ + if((SCB->CCR & SCB_CCR_DC_Msk) == 0) return; /* data cache is disabled */ + + uint32_t rows_remaining = mem_area->height; + uint32_t row_addr = (uint32_t)(uintptr_t) mem_area->first_byte; + uint32_t row_end_addr = 0; + + __DSB(); + + while(rows_remaining) { + uint32_t addr = row_addr & ~(__SCB_DCACHE_LINE_SIZE - 1U); + uint32_t cache_lines = ((((row_addr + mem_area->width_bytes - 1) & ~(__SCB_DCACHE_LINE_SIZE - 1U)) - addr) / + __SCB_DCACHE_LINE_SIZE) + 1; + + if(addr == row_end_addr) { + addr += __SCB_DCACHE_LINE_SIZE; + cache_lines--; + } + + while(cache_lines) { + SCB->DCIMVAC = addr; + addr += __SCB_DCACHE_LINE_SIZE; + cache_lines--; + } + + row_end_addr = addr - __SCB_DCACHE_LINE_SIZE; + row_addr += mem_area->stride; + rows_remaining--; + }; + + __DSB(); + __ISB(); +} + +void lv_draw_dma2d_clean_cache(const lv_draw_dma2d_cache_area_t * mem_area) +{ + if((SCB->CCR & SCB_CCR_DC_Msk) == 0) return; /* data cache is disabled */ + + uint32_t rows_remaining = mem_area->height; + uint32_t row_addr = (uint32_t)(uintptr_t) mem_area->first_byte; + uint32_t row_end_addr = 0; + + __DSB(); + + while(rows_remaining) { + uint32_t addr = row_addr & ~(__SCB_DCACHE_LINE_SIZE - 1U); + uint32_t cache_lines = ((((row_addr + mem_area->width_bytes - 1) & ~(__SCB_DCACHE_LINE_SIZE - 1U)) - addr) / + __SCB_DCACHE_LINE_SIZE) + 1; + + if(addr == row_end_addr) { + addr += __SCB_DCACHE_LINE_SIZE; + cache_lines--; + } + + while(cache_lines) { + SCB->DCCMVAC = addr; + addr += __SCB_DCACHE_LINE_SIZE; + cache_lines--; + } + + row_end_addr = addr - __SCB_DCACHE_LINE_SIZE; + row_addr += mem_area->stride; + rows_remaining--; + }; + + __DSB(); + __ISB(); +} +#endif + +/********************** + * STATIC FUNCTIONS + **********************/ + +static int32_t evaluate_cb(lv_draw_unit_t * draw_unit, lv_draw_task_t * task) +{ + switch(task->type) { + case LV_DRAW_TASK_TYPE_FILL: { + lv_draw_fill_dsc_t * dsc = task->draw_dsc; + if(!(dsc->radius == 0 + && dsc->grad.dir == LV_GRAD_DIR_NONE + && (dsc->base.layer->color_format == LV_COLOR_FORMAT_ARGB8888 + || dsc->base.layer->color_format == LV_COLOR_FORMAT_XRGB8888 + || dsc->base.layer->color_format == LV_COLOR_FORMAT_RGB888 + || dsc->base.layer->color_format == LV_COLOR_FORMAT_RGB565))) { + return 0; + } + } + break; + case LV_DRAW_TASK_TYPE_IMAGE: { + lv_draw_image_dsc_t * dsc = task->draw_dsc; + if(!(dsc->header.cf < LV_COLOR_FORMAT_PROPRIETARY_START + && dsc->clip_radius == 0 + && dsc->bitmap_mask_src == NULL + && dsc->sup == NULL + && dsc->tile == 0 + && dsc->blend_mode == LV_BLEND_MODE_NORMAL + && dsc->recolor_opa <= LV_OPA_MIN + && dsc->skew_y == 0 + && dsc->skew_x == 0 + && dsc->scale_x == 256 + && dsc->scale_y == 256 + && dsc->rotation == 0 + && lv_image_src_get_type(dsc->src) == LV_IMAGE_SRC_VARIABLE + && (dsc->header.cf == LV_COLOR_FORMAT_ARGB8888 + || dsc->header.cf == LV_COLOR_FORMAT_XRGB8888 + || dsc->header.cf == LV_COLOR_FORMAT_RGB888 + || dsc->header.cf == LV_COLOR_FORMAT_RGB565 + || dsc->header.cf == LV_COLOR_FORMAT_ARGB1555) + && (dsc->base.layer->color_format == LV_COLOR_FORMAT_ARGB8888 + || dsc->base.layer->color_format == LV_COLOR_FORMAT_XRGB8888 + || dsc->base.layer->color_format == LV_COLOR_FORMAT_RGB888 + || dsc->base.layer->color_format == LV_COLOR_FORMAT_RGB565))) { + return 0; + } + } + break; + default: + return 0; + } + + task->preferred_draw_unit_id = DRAW_UNIT_ID_DMA2D; + task->preference_score = 0; + + return 0; +} + +static int32_t dispatch_cb(lv_draw_unit_t * draw_unit, lv_layer_t * layer) +{ + lv_draw_dma2d_unit_t * draw_dma2d_unit = (lv_draw_dma2d_unit_t *) draw_unit; + + if(draw_dma2d_unit->task_act) { +#if LV_DRAW_DMA2D_ASYNC + /*Return immediately if it's busy with draw task*/ + return 0; +#else + if(!check_transfer_completion()) { + return LV_DRAW_UNIT_IDLE; + } + post_transfer_tasks(draw_dma2d_unit); +#endif + } + + lv_draw_task_t * t = lv_draw_get_available_task(layer, NULL, DRAW_UNIT_ID_DMA2D); + if(t == NULL) { + return LV_DRAW_UNIT_IDLE; + } + + void * buf = lv_draw_layer_alloc_buf(layer); + if(buf == NULL) { + return LV_DRAW_UNIT_IDLE; + } + + t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; + t->draw_unit = draw_unit; + draw_dma2d_unit->task_act = t; + + if(t->type == LV_DRAW_TASK_TYPE_FILL) { + lv_draw_fill_dsc_t * dsc = t->draw_dsc; + const lv_area_t * coords = &t->area; + lv_area_t clipped_coords; + if(!lv_area_intersect(&clipped_coords, coords, &t->clip_area)) { + return LV_DRAW_UNIT_IDLE; + } + + void * dest = lv_draw_layer_go_to_xy(layer, + clipped_coords.x1 - layer->buf_area.x1, + clipped_coords.y1 - layer->buf_area.y1); + + if(dsc->opa >= LV_OPA_MAX) { + lv_draw_dma2d_opaque_fill(t, + dest, + lv_area_get_width(&clipped_coords), + lv_area_get_height(&clipped_coords), + lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), dsc->base.layer->color_format)); + } + else { + lv_draw_dma2d_fill(t, + dest, + lv_area_get_width(&clipped_coords), + lv_area_get_height(&clipped_coords), + lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), dsc->base.layer->color_format)); + } + } + else if(t->type == LV_DRAW_TASK_TYPE_IMAGE) { + lv_draw_image_dsc_t * dsc = t->draw_dsc; + const lv_area_t * coords = &t->area; + lv_area_t clipped_coords; + if(!lv_area_intersect(&clipped_coords, coords, &t->clip_area)) { + return LV_DRAW_UNIT_IDLE; + } + + void * dest = lv_draw_layer_go_to_xy(layer, + clipped_coords.x1 - layer->buf_area.x1, + clipped_coords.y1 - layer->buf_area.y1); + + if(dsc->opa >= LV_OPA_MAX) { + lv_draw_dma2d_opaque_image( + t, + dest, + &clipped_coords, + lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), dsc->base.layer->color_format)); + } + else { + lv_draw_dma2d_image( + t, + dest, + &clipped_coords, + lv_draw_buf_width_to_stride(lv_area_get_width(&layer->buf_area), dsc->base.layer->color_format)); + } + } + +#if !LV_DRAW_DMA2D_ASYNC + lv_draw_dispatch_request(); +#endif + + return 1; +} + +static int32_t delete_cb(lv_draw_unit_t * draw_unit) +{ + return 0; +} + +#if LV_DRAW_DMA2D_ASYNC +static void thread_cb(void * arg) +{ + lv_draw_dma2d_unit_t * u = arg; + + lv_thread_sync_init(&u->interrupt_signal); + + while(1) { + + do { + lv_thread_sync_wait(&u->interrupt_signal); + } while(u->task_act != NULL); + + post_transfer_tasks(u); + lv_draw_dispatch_request(); + } +} +#endif + +#if !LV_DRAW_DMA2D_ASYNC +static bool check_transfer_completion(void) +{ + return !(DMA2D->CR & DMA2D_CR_START); +} +#endif + +static void post_transfer_tasks(lv_draw_dma2d_unit_t * u) +{ +#if LV_DRAW_DMA2D_CACHE + lv_draw_dma2d_invalidate_cache(&u->writing_area); +#endif + u->task_act->state = LV_DRAW_TASK_STATE_READY; + u->task_act = NULL; +} + +#endif /*LV_USE_DRAW_DMA2D*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d.h b/lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d.h new file mode 100644 index 000000000..af175f1fc --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d.h @@ -0,0 +1,49 @@ +/** + * @file lv_draw_dma2d.h + * + */ + +#ifndef LV_DRAW_DMA2D_H +#define LV_DRAW_DMA2D_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_DRAW_DMA2D + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_dma2d_init(void); +void lv_draw_dma2d_deinit(void); + +#if LV_USE_DRAW_DMA2D_INTERRUPT +void lv_draw_dma2d_transfer_complete_interrupt_handler(void); +#endif + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_DMA2D*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_DMA2D_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d_fill.c b/lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d_fill.c new file mode 100644 index 000000000..1c0b3a0fc --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d_fill.c @@ -0,0 +1,127 @@ +/** + * @file lv_draw_dma2d_fill.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_dma2d_private.h" +#if LV_USE_DRAW_DMA2D + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_dma2d_opaque_fill(lv_draw_task_t * t, void * first_pixel, int32_t w, int32_t h, int32_t stride) +{ + lv_draw_fill_dsc_t * dsc = t->draw_dsc; + lv_color_format_t cf = dsc->base.layer->color_format; + + lv_draw_dma2d_output_cf_t output_cf = lv_draw_dma2d_cf_to_dma2d_output_cf(cf); + uint32_t cf_size = LV_COLOR_FORMAT_GET_SIZE(cf); + uint32_t reg_to_mem_color = lv_draw_dma2d_color_to_dma2d_color(output_cf, dsc->color); + +#if LV_DRAW_DMA2D_CACHE + lv_draw_dma2d_cache_area_t cache_area = { + .first_byte = first_pixel, + .width_bytes = w * cf_size, + .height = h, + .stride = stride + }; + lv_draw_dma2d_unit_t * u = (lv_draw_dma2d_unit_t *) t->draw_unit; + lv_memcpy(&u->writing_area, &cache_area, sizeof(lv_draw_dma2d_cache_area_t)); +#endif + + lv_draw_dma2d_configuration_t conf = { + .mode = LV_DRAW_DMA2D_MODE_REGISTER_TO_MEMORY, + .w = w, + .h = h, + + .output_address = first_pixel, + .output_offset = (stride / cf_size) - w, + .output_cf = output_cf, + + .reg_to_mem_mode_color = reg_to_mem_color + }; + lv_draw_dma2d_configure_and_start_transfer(&conf); +} + +void lv_draw_dma2d_fill(lv_draw_task_t * t, void * first_pixel, int32_t w, int32_t h, int32_t stride) +{ + lv_draw_fill_dsc_t * dsc = t->draw_dsc; + lv_color_t color = dsc->color; + lv_color_format_t cf = dsc->base.layer->color_format; + lv_opa_t opa = dsc->opa; + + lv_draw_dma2d_output_cf_t output_cf = lv_draw_dma2d_cf_to_dma2d_output_cf(cf); + uint32_t cf_size = LV_COLOR_FORMAT_GET_SIZE(cf); + +#if LV_DRAW_DMA2D_CACHE + lv_draw_dma2d_cache_area_t cache_area = { + .first_byte = first_pixel, + .width_bytes = w * cf_size, + .height = h, + .stride = stride + }; + lv_draw_dma2d_unit_t * u = (lv_draw_dma2d_unit_t *) t->draw_unit; + lv_memcpy(&u->writing_area, &cache_area, sizeof(lv_draw_dma2d_cache_area_t)); + + /* make sure the background area DMA2D is blending is up-to-date in main memory */ + lv_draw_dma2d_clean_cache(&cache_area); +#endif + + uint32_t output_offset = (stride / cf_size) - w; + lv_draw_dma2d_configuration_t conf = { + .mode = LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_BLENDING_AND_FIXED_COLOR_FG, + .w = w, + .h = h, + + .output_address = first_pixel, + .output_offset = output_offset, + .output_cf = output_cf, + + .fg_color = lv_color_to_u32(color), + .fg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL, + .fg_alpha = opa, + + .bg_address = first_pixel, + .bg_offset = output_offset, + .bg_cf = (lv_draw_dma2d_fgbg_cf_t) output_cf + }; + + /* Background alpha channel should be treated as 0xFF if the cf is XRGB */ + if(cf == LV_COLOR_FORMAT_XRGB8888) { + conf.bg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL; + conf.bg_alpha = 0xff; + } + + lv_draw_dma2d_configure_and_start_transfer(&conf); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_DRAW_DMA2D*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d_img.c b/lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d_img.c new file mode 100644 index 000000000..e78bc2b9c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d_img.c @@ -0,0 +1,210 @@ +/** + * @file lv_draw_dma2d_image.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_dma2d_private.h" +#if LV_USE_DRAW_DMA2D + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_dma2d_opaque_image(lv_draw_task_t * t, void * dest_first_pixel, lv_area_t * clipped_coords, + int32_t dest_stride) +{ + int32_t w = lv_area_get_width(clipped_coords); + int32_t h = lv_area_get_height(clipped_coords); + + lv_draw_image_dsc_t * dsc = t->draw_dsc; + lv_color_format_t output_cf = dsc->base.layer->color_format; + lv_color_format_t image_cf = dsc->header.cf; + + lv_draw_dma2d_output_cf_t output_cf_dma2d = lv_draw_dma2d_cf_to_dma2d_output_cf(output_cf); + uint32_t output_cf_size = LV_COLOR_FORMAT_GET_SIZE(output_cf); + + lv_draw_dma2d_fgbg_cf_t image_cf_dma2d = (lv_draw_dma2d_fgbg_cf_t) lv_draw_dma2d_cf_to_dma2d_output_cf(image_cf); + uint32_t image_cf_size = LV_COLOR_FORMAT_GET_SIZE(image_cf); + + const lv_image_dsc_t * img_dsc = dsc->src; + uint32_t image_stride = img_dsc->header.stride; + if(image_stride == 0) image_stride = image_cf_size * img_dsc->header.w; + +#if LV_DRAW_DMA2D_CACHE + lv_draw_dma2d_cache_area_t dest_area = { + .first_byte = dest_first_pixel, + .width_bytes = w * output_cf_size, + .height = h, + .stride = dest_stride + }; + lv_draw_dma2d_unit_t * u = (lv_draw_dma2d_unit_t *) t->draw_unit; + lv_memcpy(&u->writing_area, &dest_area, sizeof(lv_draw_dma2d_cache_area_t)); + if(lv_color_format_has_alpha(image_cf)) { + /* make sure the background area DMA2D is blending is up-to-date in main memory */ + lv_draw_dma2d_clean_cache(&dest_area); + } +#endif + + const void * image_first_byte = img_dsc->data + + (image_stride * (clipped_coords->y1 - dsc->image_area.y1)) + + (image_cf_size * (clipped_coords->x1 - dsc->image_area.x1)); + +#if LV_DRAW_DMA2D_CACHE + lv_draw_dma2d_cache_area_t src_area = { + .first_byte = image_first_byte, + .width_bytes = w * image_cf_size, + .height = h, + .stride = image_stride + }; + /* make sure the image area is up-to-date in main memory for DMA2D */ + lv_draw_dma2d_clean_cache(&src_area); +#endif + + uint32_t output_offset = (dest_stride / output_cf_size) - w; + lv_draw_dma2d_configuration_t conf = { + .mode = LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_PFC, + .w = w, + .h = h, + + .output_address = dest_first_pixel, + .output_offset = output_offset, + .output_cf = output_cf_dma2d, + + .fg_address = image_first_byte, + .fg_offset = (image_stride / image_cf_size) - w, + .fg_cf = image_cf_dma2d + }; + + /* only process the background if the image might be transparent */ + if(lv_color_format_has_alpha(image_cf)) { + conf.mode = LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_BLENDING; + + conf.bg_address = dest_first_pixel; + conf.bg_offset = output_offset; + conf.bg_cf = output_cf_dma2d; + } + + /* Alpha channel should be treated as 0xFF if the cf is XRGB */ + if(image_cf == LV_COLOR_FORMAT_XRGB8888) { + conf.fg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL; + conf.fg_alpha = 0xff; + } + if(output_cf == LV_COLOR_FORMAT_XRGB8888) { + conf.bg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL; + conf.bg_alpha = 0xff; + } + + lv_draw_dma2d_configure_and_start_transfer(&conf); +} + +void lv_draw_dma2d_image(lv_draw_task_t * t, void * dest_first_pixel, lv_area_t * clipped_coords, + int32_t dest_stride) +{ + int32_t w = lv_area_get_width(clipped_coords); + int32_t h = lv_area_get_height(clipped_coords); + + lv_draw_image_dsc_t * dsc = t->draw_dsc; + lv_color_format_t output_cf = dsc->base.layer->color_format; + lv_color_format_t image_cf = dsc->header.cf; + lv_opa_t opa = dsc->opa; + + lv_draw_dma2d_output_cf_t output_cf_dma2d = lv_draw_dma2d_cf_to_dma2d_output_cf(output_cf); + uint32_t output_cf_size = LV_COLOR_FORMAT_GET_SIZE(output_cf); + + lv_draw_dma2d_fgbg_cf_t image_cf_dma2d = (lv_draw_dma2d_fgbg_cf_t) lv_draw_dma2d_cf_to_dma2d_output_cf(image_cf); + uint32_t image_cf_size = LV_COLOR_FORMAT_GET_SIZE(image_cf); + + const lv_image_dsc_t * img_dsc = dsc->src; + uint32_t image_stride = img_dsc->header.stride; + if(image_stride == 0) image_stride = image_cf_size * img_dsc->header.w; + +#if LV_DRAW_DMA2D_CACHE + lv_draw_dma2d_cache_area_t dest_area = { + .first_byte = dest_first_pixel, + .width_bytes = w * output_cf_size, + .height = h, + .stride = dest_stride + }; + lv_draw_dma2d_unit_t * u = (lv_draw_dma2d_unit_t *) t->draw_unit; + lv_memcpy(&u->writing_area, &dest_area, sizeof(lv_draw_dma2d_cache_area_t)); + /* make sure the background area DMA2D is blending is up-to-date in main memory */ + lv_draw_dma2d_clean_cache(&dest_area); +#endif + + const void * image_first_byte = img_dsc->data + + (image_stride * (clipped_coords->y1 - dsc->image_area.y1)) + + (image_cf_size * (clipped_coords->x1 - dsc->image_area.x1)); + +#if LV_DRAW_DMA2D_CACHE + lv_draw_dma2d_cache_area_t src_area = { + .first_byte = image_first_byte, + .width_bytes = w * image_cf_size, + .height = h, + .stride = image_stride + }; + /* make sure the image area is up-to-date in main memory for DMA2D */ + lv_draw_dma2d_clean_cache(&src_area); +#endif + + uint32_t output_offset = (dest_stride / output_cf_size) - w; + lv_draw_dma2d_configuration_t conf = { + .mode = LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_BLENDING, + .w = w, + .h = h, + + .output_address = dest_first_pixel, + .output_offset = output_offset, + .output_cf = output_cf_dma2d, + + .fg_address = image_first_byte, + .fg_offset = (image_stride / image_cf_size) - w, + .fg_cf = image_cf_dma2d, + .fg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_MULTIPLY_IMAGE_ALPHA_CHANNEL, + .fg_alpha = opa, + + .bg_address = dest_first_pixel, + .bg_offset = output_offset, + .bg_cf = output_cf_dma2d, + }; + + /* Alpha channel should be treated as 0xFF if the cf is XRGB */ + if(image_cf == LV_COLOR_FORMAT_XRGB8888) { + conf.fg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL; + } + if(output_cf == LV_COLOR_FORMAT_XRGB8888) { + conf.bg_alpha_mode = LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL; + conf.bg_alpha = 0xff; + } + + lv_draw_dma2d_configure_and_start_transfer(&conf); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_DRAW_DMA2D*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d_private.h b/lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d_private.h new file mode 100644 index 000000000..1326351cd --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/dma2d/lv_draw_dma2d_private.h @@ -0,0 +1,156 @@ +/** + * @file lv_draw_dma2d_private.h + * + */ + +#ifndef LV_DRAW_DMA2D_PRIVATE_H +#define LV_DRAW_DMA2D_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_dma2d.h" +#if LV_USE_DRAW_DMA2D + +#include "../lv_draw_private.h" +#include "../sw/lv_draw_sw.h" +#include LV_DRAW_DMA2D_HAL_INCLUDE + +/********************* + * DEFINES + *********************/ + +#if LV_USE_DRAW_DMA2D_INTERRUPT && LV_USE_OS +#define LV_DRAW_DMA2D_ASYNC 1 +#else +#define LV_DRAW_DMA2D_ASYNC 0 +#endif + +#if defined(__CORTEX_M) && (__CORTEX_M == 7) +#define LV_DRAW_DMA2D_CACHE 1 +#else +#define LV_DRAW_DMA2D_CACHE 0 +#endif + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_DRAW_DMA2D_OUTPUT_CF_ARGB8888 = 0, + LV_DRAW_DMA2D_OUTPUT_CF_RGB888, + LV_DRAW_DMA2D_OUTPUT_CF_RGB565, + LV_DRAW_DMA2D_OUTPUT_CF_ARGB1555, + LV_DRAW_DMA2D_OUTPUT_CF_ARGB4444 +} lv_draw_dma2d_output_cf_t; + +typedef enum { + LV_DRAW_DMA2D_FGBG_CF_ARGB8888 = 0, + LV_DRAW_DMA2D_FGBG_CF_RGB888, + LV_DRAW_DMA2D_FGBG_CF_RGB565, + LV_DRAW_DMA2D_FGBG_CF_ARGB1555, + LV_DRAW_DMA2D_FGBG_CF_ARGB4444, + LV_DRAW_DMA2D_FGBG_CF_L8, + LV_DRAW_DMA2D_FGBG_CF_AL44, + LV_DRAW_DMA2D_FGBG_CF_AL88, + LV_DRAW_DMA2D_FGBG_CF_L4, + LV_DRAW_DMA2D_FGBG_CF_A8, + LV_DRAW_DMA2D_FGBG_CF_A4, + LV_DRAW_DMA2D_FGBG_CF_YCBCR +} lv_draw_dma2d_fgbg_cf_t; + +typedef enum { + LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY = 0, + LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_PFC, + LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_BLENDING, + LV_DRAW_DMA2D_MODE_REGISTER_TO_MEMORY, + LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_BLENDING_AND_FIXED_COLOR_FG, + LV_DRAW_DMA2D_MODE_MEMORY_TO_MEMORY_WITH_BLENDING_AND_FIXED_COLOR_BG +} lv_draw_dma2d_mode_t; + +typedef enum { + LV_DRAW_DMA2D_ALPHA_MODE_NO_MODIFY_IMAGE_ALPHA_CHANNEL = 0, + LV_DRAW_DMA2D_ALPHA_MODE_REPLACE_ALPHA_CHANNEL, + LV_DRAW_DMA2D_ALPHA_MODE_MULTIPLY_IMAGE_ALPHA_CHANNEL +} lv_draw_dma2d_alpha_mode_t; + +typedef struct { + lv_draw_dma2d_mode_t mode; + uint32_t w; + uint32_t h; + + void * output_address; + uint32_t output_offset; + lv_draw_dma2d_output_cf_t output_cf; + + uint32_t reg_to_mem_mode_color; + + const void * fg_address; + uint32_t fg_offset; + lv_draw_dma2d_fgbg_cf_t fg_cf; + uint32_t fg_color; + uint32_t fg_alpha_mode; + uint32_t fg_alpha; + + const void * bg_address; + uint32_t bg_offset; + lv_draw_dma2d_fgbg_cf_t bg_cf; + uint32_t bg_color; + uint32_t bg_alpha_mode; + uint32_t bg_alpha; + +} lv_draw_dma2d_configuration_t; + +typedef struct { + const void * first_byte; + uint32_t width_bytes; + uint32_t height; + uint32_t stride; +} lv_draw_dma2d_cache_area_t; + +typedef struct { + lv_draw_unit_t base_unit; + lv_draw_task_t * volatile task_act; +#if LV_DRAW_DMA2D_CACHE + lv_draw_dma2d_cache_area_t writing_area; +#endif +#if LV_DRAW_DMA2D_ASYNC + lv_thread_t thread; + lv_thread_sync_t interrupt_signal; +#endif +} lv_draw_dma2d_unit_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_dma2d_opaque_fill(lv_draw_task_t * t, void * first_pixel, int32_t w, int32_t h, int32_t stride); +void lv_draw_dma2d_fill(lv_draw_task_t * t, void * first_pixel, int32_t w, int32_t h, int32_t stride); +void lv_draw_dma2d_opaque_image(lv_draw_task_t * t, void * dest_first_pixel, lv_area_t * clipped_coords, + int32_t dest_stride); +void lv_draw_dma2d_image(lv_draw_task_t * t, void * dest_first_pixel, lv_area_t * clipped_coords, + int32_t dest_stride); +lv_draw_dma2d_output_cf_t lv_draw_dma2d_cf_to_dma2d_output_cf(lv_color_format_t cf); +uint32_t lv_draw_dma2d_color_to_dma2d_color(lv_draw_dma2d_output_cf_t cf, lv_color_t color); +void lv_draw_dma2d_configure_and_start_transfer(const lv_draw_dma2d_configuration_t * conf); +#if LV_DRAW_DMA2D_CACHE +void lv_draw_dma2d_invalidate_cache(const lv_draw_dma2d_cache_area_t * mem_area); +void lv_draw_dma2d_clean_cache(const lv_draw_dma2d_cache_area_t * mem_area); +#endif + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_DMA2D*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_DMA2D_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.c b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.c index dbaec7028..a80ae196f 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.c @@ -11,7 +11,11 @@ * INCLUDES *********************/ #include "../misc/lv_area_private.h" +#include "../misc/lv_assert.h" #include "lv_draw_private.h" +#include "lv_draw_mask_private.h" +#include "lv_draw_vector_private.h" +#include "lv_draw_3d.h" #include "sw/lv_draw_sw.h" #include "../display/lv_display_private.h" #include "../core/lv_global.h" @@ -31,14 +35,16 @@ * STATIC PROTOTYPES **********************/ static bool is_independent(lv_layer_t * layer, lv_draw_task_t * t_check); +static void cleanup_task(lv_draw_task_t * t, lv_display_t * disp); +static inline size_t get_draw_dsc_size(lv_draw_task_type_t type); +static lv_draw_task_t * get_first_available_task(lv_layer_t * layer); +#if LV_LOG_LEVEL <= LV_LOG_LEVEL_INFO static inline uint32_t get_layer_size_kb(uint32_t size_byte) { - return size_byte < 1024 ? 1 : size_byte >> 10; + return (size_byte + 1023) >> 10; } -/********************** - * STATIC VARIABLES - **********************/ +#endif /********************** * STATIC VARIABLES @@ -79,25 +85,33 @@ void lv_draw_deinit(void) void * lv_draw_create_unit(size_t size) { lv_draw_unit_t * new_unit = lv_malloc_zeroed(size); - + LV_ASSERT_MALLOC(new_unit); new_unit->next = _draw_info.unit_head; + _draw_info.unit_head = new_unit; _draw_info.unit_cnt++; + new_unit->idx = _draw_info.unit_cnt; + return new_unit; } -lv_draw_task_t * lv_draw_add_task(lv_layer_t * layer, const lv_area_t * coords) +lv_draw_task_t * lv_draw_add_task(lv_layer_t * layer, const lv_area_t * coords, lv_draw_task_type_t type) { - LV_PROFILER_BEGIN; - lv_draw_task_t * new_task = lv_malloc_zeroed(sizeof(lv_draw_task_t)); - + LV_PROFILER_DRAW_BEGIN; + size_t dsc_size = get_draw_dsc_size(type); + LV_ASSERT_FORMAT_MSG(dsc_size > 0, "Draw task size is 0 for type %d", type); + lv_draw_task_t * new_task = lv_malloc_zeroed(LV_ALIGN_UP(sizeof(lv_draw_task_t), 8) + dsc_size); + LV_ASSERT_MALLOC(new_task); new_task->area = *coords; new_task->_real_area = *coords; + new_task->target_layer = layer; new_task->clip_area = layer->_clip_area; #if LV_DRAW_TRANSFORM_USE_MATRIX new_task->matrix = layer->matrix; #endif + new_task->type = type; + new_task->draw_dsc = (uint8_t *)new_task + LV_ALIGN_UP(sizeof(lv_draw_task_t), 8); new_task->state = LV_DRAW_TASK_STATE_QUEUED; /*Find the tail*/ @@ -111,13 +125,13 @@ lv_draw_task_t * lv_draw_add_task(lv_layer_t * layer, const lv_area_t * coords) tail->next = new_task; } - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return new_task; } void lv_draw_finalize_task_creation(lv_layer_t * layer, lv_draw_task_t * t) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; lv_draw_dsc_base_t * base_dsc = t->draw_dsc; base_dsc->layer = layer; @@ -140,11 +154,22 @@ void lv_draw_finalize_task_creation(lv_layer_t * layer, lv_draw_task_t * t) t->preferred_draw_unit_id = 0; lv_draw_unit_t * u = info->unit_head; while(u) { - if(u->evaluate_cb) u->evaluate_cb(u, t); + if(u->evaluate_cb) { + LV_PROFILER_DRAW_BEGIN_TAG("evaluate_cb"); + LV_PROFILER_DRAW_BEGIN_TAG(u->name); + u->evaluate_cb(u, t); + LV_PROFILER_DRAW_END_TAG(u->name); + LV_PROFILER_DRAW_END_TAG("evaluate_cb"); + } u = u->next; } - - lv_draw_dispatch(); + if(t->preferred_draw_unit_id == LV_DRAW_UNIT_NONE) { + LV_LOG_WARN("the draw task was not taken by any units"); + t->state = LV_DRAW_TASK_STATE_READY; + } + else { + lv_draw_dispatch(); + } } else { /*Let the draw units set their preference score*/ @@ -152,28 +177,41 @@ void lv_draw_finalize_task_creation(lv_layer_t * layer, lv_draw_task_t * t) t->preferred_draw_unit_id = 0; lv_draw_unit_t * u = info->unit_head; while(u) { - if(u->evaluate_cb) u->evaluate_cb(u, t); + if(u->evaluate_cb) { + LV_PROFILER_DRAW_BEGIN_TAG("evaluate_cb"); + LV_PROFILER_DRAW_BEGIN_TAG(u->name); + u->evaluate_cb(u, t); + LV_PROFILER_DRAW_END_TAG(u->name); + LV_PROFILER_DRAW_END_TAG("evaluate_cb"); + } u = u->next; } } - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } void lv_draw_wait_for_finish(void) { #if LV_USE_OS + LV_PROFILER_DRAW_BEGIN; lv_draw_unit_t * u = _draw_info.unit_head; while(u) { - if(u->wait_for_finish_cb) + if(u->wait_for_finish_cb) { + LV_PROFILER_DRAW_BEGIN_TAG("wait_for_finish_cb"); + LV_PROFILER_DRAW_BEGIN_TAG(u->name); u->wait_for_finish_cb(u); + LV_PROFILER_DRAW_END_TAG(u->name); + LV_PROFILER_DRAW_END_TAG("wait_for_finish_cb"); + } u = u->next; } + LV_PROFILER_DRAW_END; #endif } void lv_draw_dispatch(void) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; bool task_dispatched = false; lv_display_t * disp = lv_display_get_next(NULL); while(disp) { @@ -189,59 +227,26 @@ void lv_draw_dispatch(void) } disp = lv_display_get_next(disp); } - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } bool lv_draw_dispatch_layer(lv_display_t * disp, lv_layer_t * layer) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; /*Remove the finished tasks first*/ lv_draw_task_t * t_prev = NULL; lv_draw_task_t * t = layer->draw_task_head; + lv_draw_task_t * t_next; + bool remove_task = false; while(t) { - lv_draw_task_t * t_next = t->next; + t_next = t->next; if(t->state == LV_DRAW_TASK_STATE_READY) { - 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*/ - if(t->type == LV_DRAW_TASK_TYPE_LAYER) { - lv_draw_image_dsc_t * draw_image_dsc = t->draw_dsc; - lv_layer_t * layer_drawn = (lv_layer_t *)draw_image_dsc->src; - - if(layer_drawn->draw_buf) { - int32_t h = lv_area_get_height(&layer_drawn->buf_area); - 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); - lv_draw_buf_destroy(layer_drawn->draw_buf); - layer_drawn->draw_buf = NULL; - } - - /*Remove the layer from the display's*/ - if(disp) { - lv_layer_t * l2 = disp->layer_head; - while(l2) { - if(l2->next == layer_drawn) { - l2->next = layer_drawn->next; - break; - } - l2 = l2->next; - } - - if(disp->layer_deinit) disp->layer_deinit(disp, layer_drawn); - lv_free(layer_drawn); - } - } - lv_draw_label_dsc_t * draw_label_dsc = lv_draw_task_get_label_dsc(t); - if(draw_label_dsc && draw_label_dsc->text_local) { - lv_free((void *)draw_label_dsc->text); - draw_label_dsc->text = NULL; - } - - lv_free(t->draw_dsc); - lv_free(t); + cleanup_task(t, disp); + remove_task = true; + if(t_prev != NULL) + t_prev->next = t_next; + else + layer->draw_task_head = t_next; } else { t_prev = t; @@ -268,38 +273,46 @@ bool lv_draw_dispatch_layer(lv_display_t * disp, lv_layer_t * layer) } } /*Assign draw tasks to the draw_units*/ - else { + else if(remove_task || layer->draw_task_head) { /*Find a draw unit which is not busy and can take at least one task*/ /*Let all draw units to pick draw tasks*/ lv_draw_unit_t * u = _draw_info.unit_head; while(u) { + LV_PROFILER_DRAW_BEGIN_TAG("dispatch_cb"); + LV_PROFILER_DRAW_BEGIN_TAG(u->name); int32_t taken_cnt = u->dispatch_cb(u, layer); + LV_PROFILER_DRAW_END_TAG(u->name); + LV_PROFILER_DRAW_END_TAG("dispatch_cb"); if(taken_cnt != LV_DRAW_UNIT_IDLE) task_dispatched = true; u = u->next; } } - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return task_dispatched; } void lv_draw_dispatch_wait_for_request(void) { + LV_PROFILER_DRAW_BEGIN; #if LV_USE_OS lv_thread_sync_wait(&_draw_info.sync); #else while(!_draw_info.dispatch_req); _draw_info.dispatch_req = 0; #endif + LV_PROFILER_DRAW_END; } void lv_draw_dispatch_request(void) { + LV_PROFILER_DRAW_BEGIN; #if LV_USE_OS lv_thread_sync_signal(&_draw_info.sync); #else _draw_info.dispatch_req = 1; #endif + LV_PROFILER_DRAW_END; } uint32_t lv_draw_get_unit_count(void) @@ -307,43 +320,19 @@ uint32_t lv_draw_get_unit_count(void) return _draw_info.unit_cnt; } +lv_draw_task_t * lv_draw_get_available_task(lv_layer_t * layer, lv_draw_task_t * t_prev, uint8_t draw_unit_id) +{ + if(_draw_info.unit_cnt == 1) { + return get_first_available_task(layer); + } + else { + return lv_draw_get_next_available_task(layer, t_prev, draw_unit_id); + } +} + 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 there is only 1 draw unit the task can be consumed linearly as - * they are added in the correct order. However, it can happen that - * there is a `LV_DRAW_TASK_TYPE_LAYER` which can be blended only when - * all its tasks are ready. As other areas might be on top of that - * layer-to-blend don't skip it. Instead stop there, so that the - * draw tasks of that layer can be consumed and can be finished. - * After that this layer-to-blenf will have `LV_DRAW_TASK_STATE_QUEUED` - * so it can be blended normally.*/ - if(_draw_info.unit_cnt <= 1) { - lv_draw_task_t * t = layer->draw_task_head; - while(t) { - /*Mark unsupported draw tasks as ready as no one else will consume them*/ - if(t->state == LV_DRAW_TASK_STATE_QUEUED && - t->preferred_draw_unit_id != LV_DRAW_UNIT_NONE && - t->preferred_draw_unit_id != draw_unit_id) { - t->state = LV_DRAW_TASK_STATE_READY; - } - /*Not queued yet, leave this layer while the first task will be queued*/ - else if(t->state != LV_DRAW_TASK_STATE_QUEUED) { - t = NULL; - break; - } - /*It's a supported and queued task, process it*/ - else { - break; - } - t = t->next; - } - LV_PROFILER_END; - return t; - } - - /*Handle the case of multiply draw units*/ + LV_PROFILER_DRAW_BEGIN; /*If the first task is screen sized, there cannot be independent areas*/ if(layer->draw_task_head) { @@ -353,7 +342,7 @@ lv_draw_task_t * lv_draw_get_next_available_task(lv_layer_t * layer, lv_draw_tas if(t->state != LV_DRAW_TASK_STATE_QUEUED && t->area.x1 <= 0 && t->area.x2 >= hor_res - 1 && t->area.y1 <= 0 && t->area.y2 >= ver_res - 1) { - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return NULL; } } @@ -364,13 +353,13 @@ lv_draw_task_t * lv_draw_get_next_available_task(lv_layer_t * layer, lv_draw_tas if(t->state == LV_DRAW_TASK_STATE_QUEUED && (t->preferred_draw_unit_id == LV_DRAW_UNIT_NONE || t->preferred_draw_unit_id == draw_unit_id) && is_independent(layer, t)) { - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return t; } t = t->next; } - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return NULL; } @@ -379,7 +368,7 @@ uint32_t lv_draw_get_dependent_count(lv_draw_task_t * t_check) if(t_check == NULL) return 0; if(t_check->next == NULL) return 0; - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; uint32_t cnt = 0; lv_draw_task_t * t = t_check->next; @@ -391,43 +380,82 @@ uint32_t lv_draw_get_dependent_count(lv_draw_task_t * t_check) t = t->next; } - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return cnt; } +void lv_layer_init(lv_layer_t * layer) +{ + LV_ASSERT_NULL(layer); + lv_memzero(layer, sizeof(lv_layer_t)); + lv_layer_reset(layer); +} + +void lv_layer_reset(lv_layer_t * layer) +{ + LV_ASSERT_NULL(layer); +#if LV_DRAW_TRANSFORM_USE_MATRIX + lv_matrix_identity(&layer->matrix); +#endif + layer->opa = LV_OPA_COVER; + layer->recolor = lv_color32_make(0, 0, 0, 0); +} + 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_PROFILER_DRAW_BEGIN; lv_layer_t * new_layer = lv_malloc_zeroed(sizeof(lv_layer_t)); LV_ASSERT_MALLOC(new_layer); - if(new_layer == NULL) return NULL; + if(new_layer == NULL) { + LV_PROFILER_DRAW_END; + return NULL; + } - 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; + lv_draw_layer_init(new_layer, parent_layer, color_format, area); -#if LV_DRAW_TRANSFORM_USE_MATRIX - lv_matrix_identity(&new_layer->matrix); -#endif + /*Inherits transparency from parent*/ + if(parent_layer) { + new_layer->opa = parent_layer->opa; + new_layer->recolor = parent_layer->recolor; + } + + LV_PROFILER_DRAW_END; + return new_layer; +} + +void lv_draw_layer_init(lv_layer_t * layer, lv_layer_t * parent_layer, lv_color_format_t color_format, + const lv_area_t * area) +{ + LV_PROFILER_DRAW_BEGIN; + lv_layer_init(layer); + lv_display_t * disp = lv_refr_get_disp_refreshing(); + + layer->parent = parent_layer; + layer->_clip_area = *area; + layer->buf_area = *area; + layer->phy_clip_area = *area; + layer->color_format = color_format; + + if(disp->layer_init) disp->layer_init(disp, layer); if(disp->layer_head) { lv_layer_t * tail = disp->layer_head; while(tail->next) tail = tail->next; - tail->next = new_layer; + tail->next = layer; } else { - disp->layer_head = new_layer; + disp->layer_head = layer; } - return new_layer; + LV_PROFILER_DRAW_END; } void * lv_draw_layer_alloc_buf(lv_layer_t * layer) { + LV_PROFILER_DRAW_BEGIN; /*If the buffer of the layer is already allocated return it*/ if(layer->draw_buf != NULL) { + LV_PROFILER_DRAW_END; return layer->draw_buf->data; } @@ -436,20 +464,31 @@ void * lv_draw_layer_alloc_buf(lv_layer_t * layer) int32_t h = lv_area_get_height(&layer->buf_area); uint32_t layer_size_byte = h * lv_draw_buf_width_to_stride(w, layer->color_format); +#if LV_DRAW_LAYER_MAX_MEMORY > 0 + /* Do not allocate the layer if the sum of allocated layer sizes + * will exceed `LV_DRAW_LAYER_MAX_MEMORY` */ + if((_draw_info.used_memory_for_layers + layer_size_byte) > LV_DRAW_LAYER_MAX_MEMORY) { + LV_LOG_WARN("LV_DRAW_LAYER_MAX_MEMORY was reached when allocating the layer."); + return NULL; + } +#endif + layer->draw_buf = lv_draw_buf_create(w, h, layer->color_format, 0); if(layer->draw_buf == NULL) { LV_LOG_WARN("Allocating layer buffer failed. Try later"); + LV_PROFILER_DRAW_END; return NULL; } - _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); + _draw_info.used_memory_for_layers += layer_size_byte; + LV_LOG_INFO("Layer memory used: %" LV_PRIu32 " kB", get_layer_size_kb(_draw_info.used_memory_for_layers)); if(lv_color_format_has_alpha(layer->color_format)) { lv_draw_buf_clear(layer->draw_buf, NULL); } + LV_PROFILER_DRAW_END; return layer->draw_buf->data; } @@ -485,7 +524,7 @@ void lv_draw_task_get_area(const lv_draw_task_t * t, lv_area_t * area) */ static bool is_independent(lv_layer_t * layer, lv_draw_task_t * t_check) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; lv_draw_task_t * t = layer->draw_task_head; /*If t_check is outside of the older tasks then it's independent*/ @@ -493,13 +532,152 @@ static bool is_independent(lv_layer_t * layer, lv_draw_task_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)) { - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return false; } } t = t->next; } - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return true; } + +/** + * Get the size of the draw descriptor of a draw task + * @param type type of the draw task + * @return size of the draw descriptor in bytes + */ +static inline size_t get_draw_dsc_size(lv_draw_task_type_t type) +{ + switch(type) { + case LV_DRAW_TASK_TYPE_NONE: + return 0; + case LV_DRAW_TASK_TYPE_FILL: + return sizeof(lv_draw_fill_dsc_t); + case LV_DRAW_TASK_TYPE_BORDER: + return sizeof(lv_draw_border_dsc_t); + case LV_DRAW_TASK_TYPE_BOX_SHADOW: + return sizeof(lv_draw_box_shadow_dsc_t); + case LV_DRAW_TASK_TYPE_LETTER: + return sizeof(lv_draw_letter_dsc_t); + case LV_DRAW_TASK_TYPE_LABEL: + return sizeof(lv_draw_label_dsc_t); + case LV_DRAW_TASK_TYPE_IMAGE: + return sizeof(lv_draw_image_dsc_t); + case LV_DRAW_TASK_TYPE_LAYER: + return sizeof(lv_draw_image_dsc_t); + case LV_DRAW_TASK_TYPE_LINE: + return sizeof(lv_draw_line_dsc_t); + case LV_DRAW_TASK_TYPE_ARC: + return sizeof(lv_draw_arc_dsc_t); + case LV_DRAW_TASK_TYPE_TRIANGLE: + return sizeof(lv_draw_triangle_dsc_t); + case LV_DRAW_TASK_TYPE_MASK_RECTANGLE: + return sizeof(lv_draw_mask_rect_dsc_t); + + /* no struct match for LV_DRAW_TASK_TYPE_MASK_BITMAP, set it to zero now */ + case LV_DRAW_TASK_TYPE_MASK_BITMAP: + return 0; +#if LV_USE_VECTOR_GRAPHIC + case LV_DRAW_TASK_TYPE_VECTOR: + return sizeof(lv_draw_vector_task_dsc_t); +#endif +#if LV_USE_3DTEXTURE + case LV_DRAW_TASK_TYPE_3D: + return sizeof(lv_draw_3d_dsc_t); +#endif + /* Note that default is not added here because when adding new draw task type, + * if forget to add case, the compiler will automatically report a warning. + */ + } + + return 0; +} + +/** + * Clean-up resources allocated by a finished task + * @param t pointer to a draw task + * @param disp pointer to a display on which the task was drawn + */ +static void cleanup_task(lv_draw_task_t * t, lv_display_t * disp) +{ + LV_PROFILER_DRAW_BEGIN; + /*If it was layer drawing free the layer too*/ + if(t->type == LV_DRAW_TASK_TYPE_LAYER) { + lv_draw_image_dsc_t * draw_image_dsc = t->draw_dsc; + lv_layer_t * layer_drawn = (lv_layer_t *)draw_image_dsc->src; + + if(layer_drawn->draw_buf) { + int32_t h = lv_area_get_height(&layer_drawn->buf_area); + uint32_t layer_size_byte = h * layer_drawn->draw_buf->header.stride; + + if(_draw_info.used_memory_for_layers >= layer_size_byte) { + _draw_info.used_memory_for_layers -= layer_size_byte; + } + else { + _draw_info.used_memory_for_layers = 0; + LV_LOG_WARN("More layers were freed than allocated"); + } + LV_LOG_INFO("Layer memory used: %" LV_PRIu32 " kB", get_layer_size_kb(_draw_info.used_memory_for_layers)); + lv_draw_buf_destroy(layer_drawn->draw_buf); + layer_drawn->draw_buf = NULL; + } + + /*Remove the layer from the display's*/ + if(disp) { + lv_layer_t * l2 = disp->layer_head; + while(l2) { + if(l2->next == layer_drawn) { + l2->next = layer_drawn->next; + break; + } + l2 = l2->next; + } + + if(disp->layer_deinit) { + LV_PROFILER_DRAW_BEGIN_TAG("layer_deinit"); + disp->layer_deinit(disp, layer_drawn); + LV_PROFILER_DRAW_END_TAG("layer_deinit"); + } + lv_free(layer_drawn); + } + } + lv_draw_label_dsc_t * draw_label_dsc = lv_draw_task_get_label_dsc(t); + if(draw_label_dsc && draw_label_dsc->text_local) { + lv_free((void *)draw_label_dsc->text); + draw_label_dsc->text = NULL; + } + + lv_free(t); + LV_PROFILER_DRAW_END; +} + +static lv_draw_task_t * get_first_available_task(lv_layer_t * layer) +{ + LV_PROFILER_DRAW_BEGIN; + /* If there is only 1 draw unit the task can be consumed linearly as + * they are added in the correct order. However, it can happen that + * there is a `LV_DRAW_TASK_TYPE_LAYER` which can be blended only when + * all its tasks are ready. As other areas might be on top of that + * layer-to-blend don't skip it. Instead stop there, so that the + * draw tasks of that layer can be consumed and can be finished. + * After that this layer-to-blenf will have `LV_DRAW_TASK_STATE_QUEUED` + * so it can be blended normally.*/ + lv_draw_task_t * t = layer->draw_task_head; + while(t) { + /*Not queued yet, leave this layer while the first task is queued*/ + if(t->state != LV_DRAW_TASK_STATE_QUEUED) { + t = NULL; + break; + } + /*It's a supported and queued task, process it*/ + else { + break; + } + t = t->next; + } + + LV_PROFILER_DRAW_END; + return t; +} diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.h index 298526776..d394de87c 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw.h @@ -25,7 +25,6 @@ extern "C" { #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" /********************* @@ -49,6 +48,7 @@ typedef enum { LV_DRAW_TASK_TYPE_FILL, LV_DRAW_TASK_TYPE_BORDER, LV_DRAW_TASK_TYPE_BOX_SHADOW, + LV_DRAW_TASK_TYPE_LETTER, LV_DRAW_TASK_TYPE_LABEL, LV_DRAW_TASK_TYPE_IMAGE, LV_DRAW_TASK_TYPE_LAYER, @@ -57,7 +57,12 @@ typedef enum { LV_DRAW_TASK_TYPE_TRIANGLE, LV_DRAW_TASK_TYPE_MASK_RECTANGLE, LV_DRAW_TASK_TYPE_MASK_BITMAP, +#if LV_USE_VECTOR_GRAPHIC LV_DRAW_TASK_TYPE_VECTOR, +#endif +#if LV_USE_3DTEXTURE + LV_DRAW_TASK_TYPE_3D, +#endif } lv_draw_task_type_t; typedef enum { @@ -67,7 +72,7 @@ typedef enum { LV_DRAW_TASK_STATE_READY, } lv_draw_task_state_t; -struct lv_layer_t { +struct _lv_layer_t { /** Target draw buffer of the layer*/ lv_draw_buf_t * draw_buf; @@ -98,6 +103,15 @@ struct lv_layer_t { lv_matrix_t matrix; #endif + /** Opacity of the layer */ + lv_opa_t opa; + + /*Recolor of the layer*/ + lv_color32_t recolor; + + /** Partial y offset */ + int32_t partial_y_offset; + /** Linked list of draw tasks */ lv_draw_task_t * draw_task_head; @@ -108,12 +122,25 @@ struct lv_layer_t { }; typedef struct { + /**The widget for which draw descriptor was created */ lv_obj_t * obj; + + /**The widget part for which draw descriptor was created */ lv_part_t part; + + /**A widget type specific ID (e.g. table row index). See the docs of the given widget.*/ uint32_t id1; + + /**A widget type specific ID (e.g. table column index). See the docs of the given widget.*/ uint32_t id2; + + /**The target layer */ lv_layer_t * layer; + + /**Size of the specific draw descriptor into which this base descriptor is embedded*/ size_t dsc_size; + + /**Any custom user data*/ void * user_data; } lv_draw_dsc_base_t; @@ -145,7 +172,7 @@ void * lv_draw_create_unit(size_t size); * @return the created draw task which needs to be * further configured e.g. by added a draw descriptor */ -lv_draw_task_t * lv_draw_add_task(lv_layer_t * layer, const lv_area_t * coords); +lv_draw_task_t * lv_draw_add_task(lv_layer_t * layer, const lv_area_t * coords, lv_draw_task_type_t type); /** * Needs to be called when a draw task is created and configured. @@ -193,11 +220,21 @@ void lv_draw_dispatch_request(void); uint32_t lv_draw_get_unit_count(void); /** - * Find and available draw task - * @param layer the draw ctx to search in + * If there is only one draw unit check the first draw task if it's available. + * If there are multiple draw units call `lv_draw_get_next_available_task` to find a task. + * @param layer the draw layer 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_NONE` - * @return tan available draw task or NULL if there is no any + * @return an available draw task or NULL if there is not any + */ +lv_draw_task_t * lv_draw_get_available_task(lv_layer_t * layer, lv_draw_task_t * t_prev, uint8_t draw_unit_id); + +/** + * Find and available draw task + * @param layer the draw layer 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_NONE` + * @return an available draw task or NULL if there is not 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); @@ -212,7 +249,19 @@ lv_draw_task_t * lv_draw_get_next_available_task(lv_layer_t * layer, lv_draw_tas uint32_t lv_draw_get_dependent_count(lv_draw_task_t * t_check); /** - * Create a new layer on a parent layer + * Initialize a layer + * @param layer pointer to a layer to initialize + */ +void lv_layer_init(lv_layer_t * layer); + +/** + * Reset the layer to a drawable state + * @param layer pointer to a layer to reset + */ +void lv_layer_reset(lv_layer_t * layer); + +/** + * Create (allocate) a new layer on a parent layer * @param parent_layer the parent layer to which the layer will be merged when it's rendered * @param color_format the color format of the layer * @param area the areas of the layer (absolute coordinates) @@ -220,6 +269,17 @@ 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); +/** + * Initialize a layer which is allocated by the user + * @param layer pointer the layer to initialize (its lifetime needs to be managed by the user) + * @param parent_layer the parent layer to which the layer will be merged when it's rendered + * @param color_format the color format of the layer + * @param area the areas of the layer (absolute coordinates) + * @return the new target_layer or NULL on error + */ +void lv_draw_layer_init(lv_layer_t * layer, lv_layer_t * parent_layer, lv_color_format_t color_format, + const lv_area_t * area); + /** * Try to allocate a buffer for the layer. * @param layer pointer to a layer diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_3d.c b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_3d.c new file mode 100644 index 000000000..0ea6cbc75 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_3d.c @@ -0,0 +1,69 @@ +/** + * @file lv_draw_3d.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_3d.h" +#if LV_USE_3DTEXTURE + +#include "lv_draw_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_3d_dsc_init(lv_draw_3d_dsc_t * dsc) +{ + lv_memzero(dsc, sizeof(lv_draw_3d_dsc_t)); + dsc->base.dsc_size = sizeof(lv_draw_3d_dsc_t); + dsc->tex_id = LV_3DTEXTURE_ID_NULL; + dsc->opa = LV_OPA_COVER; +} + +lv_draw_3d_dsc_t * lv_draw_task_get_3d_dsc(lv_draw_task_t * task) +{ + return task->type == LV_DRAW_TASK_TYPE_3D ? (lv_draw_3d_dsc_t *)task->draw_dsc : NULL; +} + +void lv_draw_3d(lv_layer_t * layer, const lv_draw_3d_dsc_t * dsc, const lv_area_t * coords) +{ + LV_PROFILER_DRAW_BEGIN; + + lv_draw_task_t * t = lv_draw_add_task(layer, coords, LV_DRAW_TASK_TYPE_3D); + + lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc)); + + lv_draw_finalize_task_creation(layer, t); + + LV_PROFILER_DRAW_END; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_3DTEXTURE*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_3d.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_3d.h new file mode 100644 index 000000000..436be9a8f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_3d.h @@ -0,0 +1,70 @@ +/** + * @file lv_draw_3d.h + * + */ + +#ifndef LV_DRAW_3D_H +#define LV_DRAW_3D_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../lv_conf_internal.h" +#if LV_USE_3DTEXTURE + +#include "lv_draw.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_draw_dsc_base_t base; + lv_3dtexture_id_t tex_id; + lv_opa_t opa; +} lv_draw_3d_dsc_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize a 3D draw descriptor + * @param dsc pointer to a draw descriptor + */ +void lv_draw_3d_dsc_init(lv_draw_3d_dsc_t * dsc); + +/** + * Try to get a 3D draw descriptor from a draw task. + * @param task draw task + * @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_3D + */ +lv_draw_3d_dsc_t * lv_draw_task_get_3d_dsc(lv_draw_task_t * task); + +/** + * Create a 3D draw task + * @param layer pointer to a layer + * @param dsc pointer to an initialized `lv_draw_3d_dsc_t` variable + */ +void lv_draw_3d(lv_layer_t * layer, const lv_draw_3d_dsc_t * dsc, const lv_area_t * coords); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_3DTEXTURE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_3D_H*/ 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 f092ea73f..4f3a5473d 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_arc.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_arc.c @@ -56,21 +56,19 @@ void lv_draw_arc(lv_layer_t * layer, const lv_draw_arc_dsc_t * dsc) if(dsc->width == 0) return; if(dsc->start_angle == dsc->end_angle) return; - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; lv_area_t a; a.x1 = dsc->center.x - dsc->radius; a.y1 = dsc->center.y - dsc->radius; a.x2 = dsc->center.x + dsc->radius - 1; a.y2 = dsc->center.y + dsc->radius - 1; - lv_draw_task_t * t = lv_draw_add_task(layer, &a); + lv_draw_task_t * t = lv_draw_add_task(layer, &a, LV_DRAW_TASK_TYPE_ARC); - t->draw_dsc = lv_malloc(sizeof(*dsc)); lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc)); - t->type = LV_DRAW_TASK_TYPE_ARC; lv_draw_finalize_task_creation(layer, t); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } void lv_draw_arc_get_area(int32_t x, int32_t y, uint16_t radius, lv_value_precise_t start_angle, diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_arc.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_arc.h index 726bd68c8..1178ecb3a 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_arc.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_arc.h @@ -29,14 +29,33 @@ extern "C" { typedef struct { lv_draw_dsc_base_t base; + /**The color of the arc*/ lv_color_t color; + + /**The width (thickness) of the arc */ int32_t width; + + /**The start angle in 1 degree units (if `LV_USE_FLOAT` is enabled a float number can be also used) + * 0° is the 3 o'clock position, 90° is the 6 o'clock, etc. */ lv_value_precise_t start_angle; + + /**The end angle, similarly to start_angle. */ lv_value_precise_t end_angle; + + /**The center point of the arc. */ lv_point_t center; + + /**The outer radius of the arc*/ uint16_t radius; + + /**An image source to be used instead of `color`. `NULL` if unused*/ const void * img_src; + + /**Opacity of the arc in 0...255 range. + * LV_OPA_TRANSP, LV_OPA_10, LV_OPA_20, .. LV_OPA_COVER can be used as well*/ lv_opa_t opa; + + /**1: Make the arc ends rounded*/ uint8_t rounded : 1; } lv_draw_arc_dsc_t; 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 a6dc29bb1..58562a86e 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.c @@ -126,6 +126,8 @@ void lv_draw_buf_invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_ return; } + LV_PROFILER_DRAW_BEGIN; + lv_area_t full; if(area == NULL) { draw_buf_get_full_area(draw_buf, &full); @@ -133,6 +135,7 @@ void lv_draw_buf_invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_ } handlers->invalidate_cache_cb(draw_buf, area); + LV_PROFILER_DRAW_END; } void lv_draw_buf_flush_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area) @@ -145,6 +148,8 @@ void lv_draw_buf_flush_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * a return; } + LV_PROFILER_DRAW_BEGIN; + lv_area_t full; if(area == NULL) { draw_buf_get_full_area(draw_buf, &full); @@ -152,11 +157,13 @@ void lv_draw_buf_flush_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * a } handlers->flush_cache_cb(draw_buf, area); + LV_PROFILER_DRAW_END; } void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a) { LV_ASSERT_NULL(draw_buf); + LV_PROFILER_DRAW_BEGIN; const lv_image_header_t * header = &draw_buf->header; uint32_t stride = header->stride; @@ -164,6 +171,8 @@ void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a) if(a == NULL) { uint8_t * buf = lv_draw_buf_goto_xy(draw_buf, 0, 0); lv_memzero(buf, header->h * stride); + lv_draw_buf_flush_cache(draw_buf, a); + LV_PROFILER_DRAW_END; return; } @@ -174,9 +183,20 @@ void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a) 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; + if(!lv_area_intersect(&a_clipped, a, &a_draw_buf)) { + LV_PROFILER_DRAW_END; + return; + } + + if(lv_area_get_width(&a_clipped) <= 0) { + LV_PROFILER_DRAW_END; + return; + } + + if(lv_area_get_height(&a_clipped) <= 0) { + LV_PROFILER_DRAW_END; + 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); @@ -186,11 +206,14 @@ void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a) lv_memzero(buf, line_length); buf += stride; } + lv_draw_buf_flush_cache(draw_buf, a); + LV_PROFILER_DRAW_END; } void lv_draw_buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area, const lv_draw_buf_t * src, const lv_area_t * src_area) { + LV_PROFILER_DRAW_BEGIN; uint8_t * dest_bufc; uint8_t * src_bufc; int32_t line_width; @@ -213,6 +236,7 @@ void lv_draw_buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area, if((src_area == NULL && line_width != src->header.w) || \ (src_area != NULL && line_width != lv_area_get_width(src_area))) { LV_ASSERT_MSG(0, "Source and destination areas have different width"); + LV_PROFILER_DRAW_END; return; } @@ -241,6 +265,7 @@ void lv_draw_buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area, dest_bufc += dest_stride; src_bufc += src_stride; } + LV_PROFILER_DRAW_END; } 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, @@ -283,9 +308,13 @@ lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf, 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_PROFILER_DRAW_BEGIN; lv_draw_buf_t * draw_buf = lv_malloc_zeroed(sizeof(lv_draw_buf_t)); LV_ASSERT_MALLOC(draw_buf); - if(draw_buf == NULL) return NULL; + if(draw_buf == NULL) { + LV_PROFILER_DRAW_END; + return NULL; + } if(stride == 0) stride = lv_draw_buf_width_to_stride(w, cf); uint32_t size = _calculate_draw_buf_size(w, h, cf, stride); @@ -296,6 +325,7 @@ lv_draw_buf_t * lv_draw_buf_create_ex(const lv_draw_buf_handlers_t * handlers, u LV_LOG_WARN("No memory: %"LV_PRIu32"x%"LV_PRIu32", cf: %d, stride: %"LV_PRIu32", %"LV_PRIu32"Byte, ", w, h, cf, stride, size); lv_free(draw_buf); + LV_PROFILER_DRAW_END; return NULL; } @@ -309,6 +339,7 @@ lv_draw_buf_t * lv_draw_buf_create_ex(const lv_draw_buf_handlers_t * handlers, u draw_buf->unaligned_data = buf; draw_buf->data_size = size; draw_buf->handlers = handlers; + LV_PROFILER_DRAW_END; return draw_buf; } @@ -319,9 +350,13 @@ lv_draw_buf_t * lv_draw_buf_dup(const lv_draw_buf_t * 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) { + LV_PROFILER_DRAW_BEGIN; const lv_image_header_t * header = &draw_buf->header; 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; + if(new_buf == NULL) { + LV_PROFILER_DRAW_END; + return NULL; + } new_buf->header.flags = draw_buf->header.flags; new_buf->header.flags |= LV_IMAGE_FLAGS_MODIFIABLE | LV_IMAGE_FLAGS_ALLOCATED; @@ -331,6 +366,7 @@ lv_draw_buf_t * lv_draw_buf_dup_ex(const lv_draw_buf_handlers_t * handlers, cons /*Copy image data*/ lv_memcpy(new_buf->data, draw_buf->data, size); + LV_PROFILER_DRAW_END; return new_buf; } @@ -338,6 +374,7 @@ lv_draw_buf_t * lv_draw_buf_reshape(lv_draw_buf_t * draw_buf, lv_color_format_t uint32_t stride) { if(draw_buf == NULL) return NULL; + LV_PROFILER_DRAW_BEGIN; /*If color format is unknown, keep using the original color format.*/ if(cf == LV_COLOR_FORMAT_UNKNOWN) cf = draw_buf->header.cf; @@ -347,6 +384,7 @@ lv_draw_buf_t * lv_draw_buf_reshape(lv_draw_buf_t * draw_buf, lv_color_format_t if(size > draw_buf->data_size) { LV_LOG_TRACE("Draw buf too small for new shape"); + LV_PROFILER_DRAW_END; return NULL; } @@ -355,6 +393,7 @@ lv_draw_buf_t * lv_draw_buf_reshape(lv_draw_buf_t * draw_buf, lv_color_format_t draw_buf->header.h = h; draw_buf->header.stride = stride; + LV_PROFILER_DRAW_END; return draw_buf; } @@ -362,6 +401,7 @@ void lv_draw_buf_destroy(lv_draw_buf_t * draw_buf) { LV_ASSERT_NULL(draw_buf); if(draw_buf == NULL) return; + LV_PROFILER_DRAW_BEGIN; if(draw_buf->header.flags & LV_IMAGE_FLAGS_ALLOCATED) { LV_ASSERT_NULL(draw_buf->handlers); @@ -373,6 +413,7 @@ void lv_draw_buf_destroy(lv_draw_buf_t * draw_buf) else { LV_LOG_ERROR("draw buffer is not allocated, ignored"); } + LV_PROFILER_DRAW_END; } void * lv_draw_buf_goto_xy(const lv_draw_buf_t * buf, uint32_t x, uint32_t y) @@ -397,12 +438,14 @@ lv_result_t lv_draw_buf_adjust_stride(lv_draw_buf_t * src, uint32_t stride) LV_ASSERT_NULL(src->data); if(src == NULL) return LV_RESULT_INVALID; if(src->data == NULL) return LV_RESULT_INVALID; + LV_PROFILER_DRAW_BEGIN; const lv_image_header_t * header = &src->header; uint32_t w = header->w; uint32_t h = header->h; if(!lv_draw_buf_has_flag(src, LV_IMAGE_FLAGS_MODIFIABLE)) { + LV_PROFILER_DRAW_END; return LV_RESULT_INVALID; } @@ -410,19 +453,24 @@ lv_result_t lv_draw_buf_adjust_stride(lv_draw_buf_t * src, uint32_t stride) if(stride == 0) stride = lv_draw_buf_width_to_stride(w, header->cf); /*Check if stride already match*/ - if(header->stride == stride) return LV_RESULT_OK; + if(header->stride == stride) { + LV_PROFILER_DRAW_END; + return LV_RESULT_OK; + } /*Calculate the minimal stride allowed from bpp*/ uint32_t bpp = lv_color_format_get_bpp(header->cf); uint32_t min_stride = (w * bpp + 7) >> 3; if(stride < min_stride) { LV_LOG_WARN("New stride is too small. min: %" LV_PRId32, min_stride); + LV_PROFILER_DRAW_END; return LV_RESULT_INVALID; } /*Check if buffer has enough space. */ uint32_t new_size = _calculate_draw_buf_size(w, h, header->cf, stride); if(new_size > src->data_size) { + LV_PROFILER_DRAW_END; return LV_RESULT_INVALID; } @@ -451,6 +499,7 @@ lv_result_t lv_draw_buf_adjust_stride(lv_draw_buf_t * src, uint32_t stride) src->header.stride = stride; + LV_PROFILER_DRAW_END; return LV_RESULT_OK; } @@ -464,6 +513,7 @@ lv_result_t lv_draw_buf_premultiply(lv_draw_buf_t * draw_buf) LV_LOG_WARN("draw buf is not modifiable: 0x%04x", draw_buf->header.flags); return LV_RESULT_INVALID; } + LV_PROFILER_DRAW_BEGIN; /*Premultiply color with alpha, do case by case by judging color format*/ lv_color_format_t cf = draw_buf->header.cf; @@ -529,6 +579,7 @@ lv_result_t lv_draw_buf_premultiply(lv_draw_buf_t * draw_buf) draw_buf->header.flags |= LV_IMAGE_FLAGS_PREMULTIPLIED; + LV_PROFILER_DRAW_END; return LV_RESULT_OK; } @@ -561,11 +612,16 @@ 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_result_t 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); + const lv_result_t res = lv_draw_buf_init(buf, img->header.w, img->header.h, img->header.cf, img->header.stride, + (void *)img->data, img->data_size); + if(res != LV_RESULT_OK) { + return res; + } + buf->header.flags = img->header.flags; + return res; } void lv_draw_buf_to_image(const lv_draw_buf_t * buf, lv_image_dsc_t * img) 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 22b09de0a..c36e0a612 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf.h @@ -48,7 +48,7 @@ LV_EXPORT_CONST_INT(LV_STRIDE_AUTO); * For platform that needs special buffer alignment, call LV_DRAW_BUF_INIT_STATIC. */ #define LV_DRAW_BUF_DEFINE_STATIC(name, _w, _h, _cf) \ - static uint8_t buf_##name[LV_DRAW_BUF_SIZE(_w, _h, _cf)]; \ + static LV_ATTRIBUTE_MEM_ALIGN uint8_t buf_##name[LV_DRAW_BUF_SIZE(_w, _h, _cf)]; \ static lv_draw_buf_t name = { \ .header = { \ .magic = LV_IMAGE_HEADER_MAGIC, \ @@ -85,7 +85,7 @@ typedef void (*lv_draw_buf_cache_operation_cb)(const lv_draw_buf_t * draw_buf, c typedef uint32_t (*lv_draw_buf_width_to_stride_cb)(uint32_t w, lv_color_format_t color_format); -struct lv_draw_buf_t { +struct _lv_draw_buf_t { lv_image_header_t header; uint32_t data_size; /**< Total buf size in bytes */ uint8_t * data; @@ -318,7 +318,7 @@ void lv_draw_buf_clear_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag); * And is interchangeable with `lv_image_dsc_t`. */ -void lv_draw_buf_from_image(lv_draw_buf_t * buf, const lv_image_dsc_t * img); +lv_result_t lv_draw_buf_from_image(lv_draw_buf_t * buf, const lv_image_dsc_t * img); void lv_draw_buf_to_image(const lv_draw_buf_t * buf, lv_image_dsc_t * img); 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 index 051f9ba7c..a22640315 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf_private.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_buf_private.h @@ -24,7 +24,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_draw_buf_handlers_t { +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; 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 45804573e..ee29d6b7a 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image.c @@ -14,6 +14,7 @@ #include "../misc/lv_log.h" #include "../misc/lv_math.h" #include "../core/lv_refr.h" +#include "../core/lv_obj_private.h" #include "../stdlib/lv_mem.h" #include "../stdlib/lv_string.h" @@ -29,7 +30,7 @@ * STATIC PROTOTYPES **********************/ -static void img_decode_and_draw(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, +static void img_decode_and_draw(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, lv_image_decoder_dsc_t * decoder_dsc, lv_area_t * relative_decoded_area, const lv_area_t * img_area, const lv_area_t * clipped_img_area, lv_draw_image_core_cb draw_core_cb); @@ -70,24 +71,31 @@ void lv_draw_layer(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv return; } - lv_draw_task_t * t = lv_draw_add_task(layer, coords); + LV_PROFILER_DRAW_BEGIN; - t->draw_dsc = lv_malloc(sizeof(*dsc)); - lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc)); - t->type = LV_DRAW_TASK_TYPE_LAYER; + lv_draw_task_t * t = lv_draw_add_task(layer, coords, LV_DRAW_TASK_TYPE_LAYER); + lv_draw_image_dsc_t * new_image_dsc = t->draw_dsc; + lv_memcpy(new_image_dsc, dsc, sizeof(*dsc)); 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_area_move(&t->_real_area, coords->x1, coords->y1); + /*If the image_area is not set assume that it's the same as the rendering area */ + if(new_image_dsc->image_area.x2 == LV_COORD_MIN) { + new_image_dsc->image_area = *coords; + } + lv_layer_t * layer_to_draw = (lv_layer_t *)dsc->src; layer_to_draw->all_tasks_added = true; lv_draw_finalize_task_creation(layer, t); + + LV_PROFILER_DRAW_END; } -void lv_draw_image(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_image(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv_area_t * image_coords) { if(dsc->src == NULL) { LV_LOG_WARN("Image draw: src is NULL"); @@ -100,27 +108,81 @@ void lv_draw_image(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv return; } - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; - lv_draw_image_dsc_t * new_image_dsc = lv_malloc(sizeof(*dsc)); - lv_memcpy(new_image_dsc, dsc, sizeof(*dsc)); - lv_result_t res = lv_image_decoder_get_info(new_image_dsc->src, &new_image_dsc->header); + lv_draw_image_dsc_t new_image_dsc; + lv_memcpy(&new_image_dsc, dsc, sizeof(*dsc)); + lv_result_t res = lv_image_decoder_get_info(new_image_dsc.src, &new_image_dsc.header); if(res != LV_RESULT_OK) { LV_LOG_WARN("Couldn't get info about the image"); - lv_free(new_image_dsc); + LV_PROFILER_DRAW_END; return; } - lv_draw_task_t * t = lv_draw_add_task(layer, coords); - t->draw_dsc = new_image_dsc; - t->type = LV_DRAW_TASK_TYPE_IMAGE; + /*If the image_area is not set assume that it's the same as the rendering area */ + if(new_image_dsc.image_area.x2 == LV_COORD_MIN) { + new_image_dsc.image_area = *image_coords; + } - 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); + /*Typical case, draw the image as bitmap*/ + if(!(new_image_dsc.header.flags & LV_IMAGE_FLAGS_CUSTOM_DRAW)) { + lv_draw_task_t * t = lv_draw_add_task(layer, image_coords, LV_DRAW_TASK_TYPE_IMAGE); + lv_memcpy(t->draw_dsc, &new_image_dsc, sizeof(lv_draw_image_dsc_t)); - lv_draw_finalize_task_creation(layer, t); - LV_PROFILER_END; + lv_image_buf_get_transformed_area(&t->_real_area, lv_area_get_width(image_coords), lv_area_get_height(image_coords), + dsc->rotation, dsc->scale_x, dsc->scale_y, &dsc->pivot); + lv_area_move(&t->_real_area, image_coords->x1, image_coords->y1); + + lv_draw_finalize_task_creation(layer, t); + } + /*Use a custom draw callback*/ + else { + + lv_image_decoder_dsc_t decoder_dsc; + res = lv_image_decoder_open(&decoder_dsc, new_image_dsc.src, NULL); + if(res != LV_RESULT_OK) { + LV_LOG_ERROR("Failed to open image"); + LV_PROFILER_DRAW_END; + return; + } + + if(decoder_dsc.decoder && decoder_dsc.decoder->custom_draw_cb) { + lv_area_t draw_area = layer->buf_area; + lv_area_t coords_area = *image_coords; + + lv_area_t obj_area = dsc->base.obj->coords; + if(layer->parent) { /* child layer */ + if(lv_area_intersect(&coords_area, &coords_area, &obj_area)) { + int32_t xpos = image_coords->x1 - draw_area.x1; + int32_t ypos = image_coords->y1 - draw_area.y1; + + lv_area_move(&coords_area, -(image_coords->x1 - xpos), -(image_coords->y1 - ypos)); + layer->_clip_area = coords_area; + decoder_dsc.decoder->custom_draw_cb(layer, &decoder_dsc, &coords_area, &new_image_dsc, &coords_area); + } + } + else { + lv_area_t clip_area = draw_area; + if(lv_area_intersect(&clip_area, &clip_area, &coords_area)) { + + lv_image_buf_get_transformed_area(&coords_area, lv_area_get_width(image_coords), lv_area_get_height(image_coords), + dsc->rotation, dsc->scale_x, dsc->scale_y, &dsc->pivot); + lv_area_move(&coords_area, image_coords->x1, image_coords->y1); + + lv_image_buf_get_transformed_area(&clip_area, lv_area_get_width(image_coords), lv_area_get_height(image_coords), + dsc->rotation, dsc->scale_x, dsc->scale_y, &dsc->pivot); + lv_area_move(&clip_area, image_coords->x1, image_coords->y1); + + if(lv_area_intersect(&clip_area, &clip_area, &obj_area)) { + decoder_dsc.decoder->custom_draw_cb(layer, &decoder_dsc, &coords_area, &new_image_dsc, &clip_area); + } + } + } + + } + } + + LV_PROFILER_DRAW_END; } lv_image_src_t lv_image_src_get_type(const void * src) @@ -140,7 +202,7 @@ 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, +void lv_draw_image_normal_helper(lv_draw_task_t * t, 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) { @@ -164,7 +226,7 @@ void lv_draw_image_normal_helper(lv_draw_unit_t * draw_unit, const lv_draw_image } 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, &t->clip_area)) { return; } @@ -175,12 +237,12 @@ void lv_draw_image_normal_helper(lv_draw_unit_t * draw_unit, const lv_draw_image return; } - img_decode_and_draw(draw_unit, draw_dsc, &decoder_dsc, NULL, coords, &clipped_img_area, draw_core_cb); + img_decode_and_draw(t, draw_dsc, &decoder_dsc, NULL, coords, &clipped_img_area, draw_core_cb); 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, +void lv_draw_image_tiled_helper(lv_draw_task_t * t, 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) { @@ -222,7 +284,7 @@ void lv_draw_image_tiled_helper(lv_draw_unit_t * draw_unit, const lv_draw_image_ lv_area_t clipped_img_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, + img_decode_and_draw(t, draw_dsc, &decoder_dsc, &relative_decoded_area, &tile_area, &clipped_img_area, draw_core_cb); } @@ -270,7 +332,7 @@ void lv_image_buf_get_transformed_area(lv_area_t * res, int32_t w, int32_t h, in * STATIC FUNCTIONS **********************/ -static void img_decode_and_draw(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, +static void img_decode_and_draw(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, lv_image_decoder_dsc_t * decoder_dsc, lv_area_t * relative_decoded_area, const lv_area_t * img_area, const lv_area_t * clipped_img_area, lv_draw_image_core_cb draw_core_cb) @@ -282,7 +344,7 @@ static void img_decode_and_draw(lv_draw_unit_t * draw_unit, const lv_draw_image_ /*The whole image is available, just draw it*/ if(decoder_dsc->decoded && (relative_decoded_area == NULL || relative_decoded_area->x1 == LV_COORD_MIN)) { - draw_core_cb(draw_unit, draw_dsc, decoder_dsc, &sup, img_area, clipped_img_area); + draw_core_cb(t, draw_dsc, decoder_dsc, &sup, img_area, clipped_img_area); } /*Draw in smaller pieces*/ else { @@ -305,7 +367,7 @@ static void img_decode_and_draw(lv_draw_unit_t * draw_unit, const lv_draw_image_ /*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)) { - draw_core_cb(draw_unit, draw_dsc, decoder_dsc, &sup, + draw_core_cb(t, 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 a16f6d055..de925e60e 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image.h @@ -26,51 +26,87 @@ extern "C" { * MACROS **********************/ -typedef struct lv_draw_image_dsc_t { +struct _lv_draw_image_dsc_t { lv_draw_dsc_base_t base; + /**The image source: pointer to `lv_image_dsc_t` or a path to a file*/ const void * src; + + /**The header of the image. Initialized internally in `lv_draw_image` */ lv_image_header_t header; + /**Clip the corner of the image with this radius. Use `LV_RADIUS_CIRCLE` for max. radius */ + int32_t clip_radius; + + /**The rotation of the image in 0.1 degree unit. E.g. 234 means 23.4° */ int32_t rotation; + + /**Horizontal scale (zoom) of the image. + * 256 (LV_SCALE_NONE): means no zoom, 512 double size, 128 half size.*/ int32_t scale_x; + + /**Same as `scale_y` but vertically*/ int32_t scale_y; + + /**Parallelogram like transformation of the image horizontally in 0.1 degree unit. E.g. 456 means 45.6°.*/ int32_t skew_x; + + /**Same as `skew_x` but vertically*/ int32_t skew_y; + + /**The pivot point of transformation (scale and rotation). + * 0;0 is the top left corner of the image. Can be outside of the image too.*/ lv_point_t pivot; + /**Mix this color to the images. In case of `LV_COLOR_FORMAT_A8` it will be the color of the visible pixels*/ lv_color_t recolor; + + /**The intensity of recoloring. 0 means, no recolor, 255 means full cover (transparent pixels remain transparent)*/ lv_opa_t recolor_opa; + /**Opacity in 0...255 range. + * LV_OPA_TRANSP, LV_OPA_10, LV_OPA_20, .. LV_OPA_COVER can be used as well*/ lv_opa_t opa; + + /**Describes how to blend the pixels of the image to the background. + * See `lv_blend_mode_t` for more details. + */ lv_blend_mode_t blend_mode : 4; + /**1: perform the transformation with anti-alaising */ uint16_t antialias : 1; + + /**If the image is smaller than the `image_area` field of `lv_draw_image_dsc_t` + * tile the image (repeat is both horizontally and vertically) to fill the + * `image_area` area*/ uint16_t tile : 1; + + /**Used internally to store some information about the palette or the color of A8 images*/ lv_draw_image_sup_t * sup; /** 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. + * 1. Layer rendering, where it might happen that only a smaller area of the layer is rendered and e.g. + * `clip_radius` needs to know what the original image was. * 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; - + /**Pointer to an A8 or L8 image descriptor to mask the image with. + * The mask is always center aligned. */ const lv_image_dsc_t * bitmap_mask_src; -} lv_draw_image_dsc_t; +}; /** * PErform the actual rendering of a decoded image - * @param draw_unit pointer to a draw unit + * @param t pointer to a draw task * @param draw_dsc the draw descriptor of the image * @param decoder_dsc pointer to the decoded image's descriptor * @param sup supplementary data * @param img_coords the absolute coordinates of the image * @param clipped_img_area the absolute clip coordinates */ -typedef void (*lv_draw_image_core_cb)(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, +typedef void (*lv_draw_image_core_cb)(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, const lv_area_t * img_coords, const lv_area_t * clipped_img_area); @@ -105,7 +141,7 @@ void lv_draw_image(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv /** * 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 dsc pointer to an initialized draw descriptor. `src` must be set to the layer to blend * @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) 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 index a39ee6164..08c90a786 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image_private.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_image_private.h @@ -28,7 +28,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_draw_image_sup_t { +struct _lv_draw_image_sup_t { lv_color_t alpha_color; const lv_color32_t * palette; uint32_t palette_size : 9; @@ -42,23 +42,23 @@ struct lv_draw_image_sup_t { /** * 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 t pointer to a draw task * @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, +void lv_draw_image_normal_helper(lv_draw_task_t * t, 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 t pointer to a draw task * @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, +void lv_draw_image_tiled_helper(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords, lv_draw_image_core_cb draw_core_cb); /** 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 e733c40d2..8f3715131 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label.c @@ -32,12 +32,17 @@ /********************** * TYPEDEFS **********************/ +enum { + RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER, + RECOLOR_CMD_STATE_PARAMETER, + RECOLOR_CMD_STATE_TEXT_INPUT, +}; +typedef unsigned char cmd_state_t; /********************** * STATIC PROTOTYPES **********************/ -static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, const lv_point_t * pos, - const lv_font_t * font, uint32_t letter, lv_draw_glyph_cb_t cb); +static uint8_t hex_char_to_num(char hex); /********************** * STATIC VARIABLES @@ -55,11 +60,24 @@ static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, * GLOBAL FUNCTIONS **********************/ +void lv_draw_letter_dsc_init(lv_draw_letter_dsc_t * dsc) +{ + lv_memzero(dsc, sizeof(lv_draw_letter_dsc_t)); + dsc->opa = LV_OPA_COVER; + dsc->color = lv_color_black(); + dsc->font = LV_FONT_DEFAULT; + dsc->rotation = 0; + dsc->scale_x = LV_SCALE_NONE; + dsc->scale_y = LV_SCALE_NONE; + dsc->base.dsc_size = sizeof(lv_draw_letter_dsc_t); +} + void lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc) { lv_memzero(dsc, sizeof(lv_draw_label_dsc_t)); dsc->opa = LV_OPA_COVER; dsc->color = lv_color_black(); + dsc->text_length = LV_TEXT_LEN_MAX; dsc->font = LV_FONT_DEFAULT; dsc->sel_start = LV_DRAW_LABEL_NO_TXT_SEL; dsc->sel_end = LV_DRAW_LABEL_NO_TXT_SEL; @@ -89,21 +107,20 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_label(lv_layer_t * layer, const lv_draw_label return; } - LV_PROFILER_BEGIN; - lv_draw_task_t * t = lv_draw_add_task(layer, coords); + LV_PROFILER_DRAW_BEGIN; + lv_draw_task_t * t = lv_draw_add_task(layer, coords, LV_DRAW_TASK_TYPE_LABEL); - t->draw_dsc = lv_malloc(sizeof(*dsc)); lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc)); - t->type = LV_DRAW_TASK_TYPE_LABEL; /*The text is stored in a local variable so malloc memory for it*/ if(dsc->text_local) { lv_draw_label_dsc_t * new_dsc = t->draw_dsc; - new_dsc->text = lv_strdup(dsc->text); + new_dsc->text = lv_strndup(dsc->text, dsc->text_length); + LV_ASSERT_MALLOC(new_dsc->text); } lv_draw_finalize_task_creation(layer, t); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } void LV_ATTRIBUTE_FAST_MEM lv_draw_character(lv_layer_t * layer, lv_draw_label_dsc_t * dsc, @@ -117,7 +134,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_character(lv_layer_t * layer, lv_draw_label_d if(lv_text_is_marker(unicode_letter)) return; - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; lv_font_glyph_dsc_t g; lv_font_get_glyph_dsc(dsc->font, &g, unicode_letter, 0); @@ -143,18 +160,52 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_character(lv_layer_t * layer, lv_draw_label_d dsc->text_local = 1; lv_draw_label(layer, dsc, &a); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } -void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, +void LV_ATTRIBUTE_FAST_MEM lv_draw_letter(lv_layer_t * layer, lv_draw_letter_dsc_t * dsc, const lv_point_t * point) +{ + if(dsc->opa <= LV_OPA_MIN) return; + if(dsc->font == NULL) { + LV_LOG_WARN("dsc->font == NULL"); + return; + } + + const lv_font_t * font = dsc->font; + + LV_PROFILER_DRAW_BEGIN; + lv_font_glyph_dsc_t g; + lv_font_get_glyph_dsc(font, &g, dsc->unicode, 0); + + font = g.resolved_font ? g.resolved_font : dsc->font; + + lv_area_t a; + a.x1 = point->x; + a.y1 = point->y; + a.x2 = a.x1 + g.adv_w; + a.y2 = a.y1 + lv_font_get_line_height(font); + + dsc->pivot.x = g.adv_w / 2 ; + dsc->pivot.y = font->line_height - font->base_line; + + lv_draw_task_t * t = lv_draw_add_task(layer, &a, LV_DRAW_TASK_TYPE_LETTER); + + lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc)); + + lv_draw_finalize_task_creation(layer, t); + LV_PROFILER_DRAW_END; +} + +void lv_draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords, lv_draw_glyph_cb_t cb) { + lv_draw_dsc_base_t * base_dsc = t->draw_dsc; const lv_font_t * font = dsc->font; 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, &t->clip_area); if(!clip_ok) return; lv_text_align_t align = dsc->align; @@ -168,10 +219,15 @@ void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_ } else { /*If EXPAND is enabled then not limit the text's width to the object's width*/ - lv_point_t p; - lv_text_get_size(&p, dsc->text, dsc->font, dsc->letter_space, dsc->line_space, LV_COORD_MAX, - dsc->flag); - w = p.x; + if(base_dsc->obj && !lv_obj_has_flag(base_dsc->obj, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS)) { + w = dsc->text_size.x; + } + else { + lv_point_t p; + lv_text_get_size(&p, dsc->text, dsc->font, dsc->letter_space, dsc->line_space, LV_COORD_MAX, + dsc->flag); + w = p.x; + } } int32_t line_height_font = lv_font_get_line_height(font); @@ -206,14 +262,16 @@ 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 remaining_len = dsc->text_length; + + uint32_t line_end = line_start + lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, dsc->letter_space, + w, NULL, dsc->flag); /*Go the first visible line*/ - while(pos.y + line_height_font < draw_unit->clip_area->y1) { + while(pos.y + line_height_font < t->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], remaining_len, font, dsc->letter_space, w, NULL, dsc->flag); pos.y += line_height; /*Save at the threshold coordinate*/ @@ -228,14 +286,16 @@ void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_ /*Align to middle*/ if(align == LV_TEXT_ALIGN_CENTER) { - line_width = lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space); + line_width = lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, + dsc->flag); pos.x += (lv_area_get_width(coords) - line_width) / 2; } /*Align to the right*/ else if(align == LV_TEXT_ALIGN_RIGHT) { - line_width = lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space); + line_width = lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, + dsc->flag); pos.x += lv_area_get_width(coords) - line_width; } @@ -253,45 +313,147 @@ void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_ draw_letter_dsc.opa = dsc->opa; draw_letter_dsc.bg_coords = &bg_coords; draw_letter_dsc.color = dsc->color; + draw_letter_dsc.rotation = dsc->rotation; + + /* Set letter outline stroke attributes */ + draw_letter_dsc.outline_stroke_width = dsc->outline_stroke_width; + draw_letter_dsc.outline_stroke_opa = dsc->outline_stroke_opa; + draw_letter_dsc.outline_stroke_color = dsc->outline_stroke_color; lv_draw_fill_dsc_t fill_dsc; lv_draw_fill_dsc_init(&fill_dsc); fill_dsc.opa = dsc->opa; int32_t underline_width = font->underline_thickness ? font->underline_thickness : 1; int32_t line_start_x; - uint32_t i; + uint32_t next_char_offset; + uint32_t recolor_command_start_index = 0; int32_t letter_w; + cmd_state_t recolor_cmd_state = RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER; + lv_color_t recolor = lv_color_black(); /* Holds the selected color inside the recolor command */ + uint8_t is_first_space_after_cmd = 0; /*Write out all lines*/ - while(dsc->text[line_start] != '\0') { + while(remaining_len && dsc->text[line_start] != '\0') { pos.x += x_ofs; line_start_x = pos.x; /*Write all letter of a line*/ - i = 0; + recolor_cmd_state = RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER; + next_char_offset = 0; #if LV_USE_BIDI - char * bidi_txt = lv_malloc(line_end - line_start + 1); + size_t bidi_size = line_end - line_start; + char * bidi_txt = lv_malloc(bidi_size + 1); LV_ASSERT_MALLOC(bidi_txt); - lv_bidi_process_paragraph(dsc->text + line_start, bidi_txt, line_end - line_start, base_dir, NULL, 0); + + /** + * has_bided = 1: already executed lv_bidi_process_paragraph. + * has_bided = 0: has not been executed lv_bidi_process_paragraph.*/ + if(dsc->has_bided) { + lv_memcpy(bidi_txt, &dsc->text[line_start], bidi_size); + } + else { + lv_bidi_process_paragraph(dsc->text + line_start, bidi_txt, bidi_size, base_dir, NULL, 0); + } #else const char * bidi_txt = dsc->text + line_start; #endif - while(i < line_end - line_start) { + while(next_char_offset < remaining_len && next_char_offset < line_end - line_start) { uint32_t logical_char_pos = 0; - if(sel_start != 0xFFFF && sel_end != 0xFFFF) { + + /* Check if the text selection is enabled */ + if(sel_start != LV_DRAW_LABEL_NO_TXT_SEL && sel_end != LV_DRAW_LABEL_NO_TXT_SEL) { #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); + if(dsc->has_bided) { + logical_char_pos = lv_text_encoded_get_char_id(dsc->text, line_start + next_char_offset); + } + else { + logical_char_pos = lv_text_encoded_get_char_id(dsc->text, line_start); + uint32_t c_idx = lv_text_encoded_get_char_id(bidi_txt, next_char_offset); + logical_char_pos += lv_bidi_get_logical_pos(bidi_txt, NULL, line_end - line_start, base_dir, c_idx, 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 + next_char_offset); #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, &next_char_offset); + + /* If recolor is enabled */ + if((dsc->flag & LV_TEXT_FLAG_RECOLOR) != 0) { + + if(letter == (uint32_t)LV_TXT_COLOR_CMD[0]) { + /* Handle the recolor command marker depending of the current recolor state */ + + if(recolor_cmd_state == RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER) { + recolor_command_start_index = next_char_offset; + recolor_cmd_state = RECOLOR_CMD_STATE_PARAMETER; + continue; + } + /*Other start char in parameter escaped cmd. char*/ + else if(recolor_cmd_state == RECOLOR_CMD_STATE_PARAMETER) { + recolor_cmd_state = RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER; + } + /* If letter is LV_TXT_COLOR_CMD and we were in the CMD_STATE_IN then the recolor close marked has been found */ + else if(recolor_cmd_state == RECOLOR_CMD_STATE_TEXT_INPUT) { + recolor_cmd_state = RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER; + continue; + } + } + + /* Find the first space (aka ' ') after the recolor command parameter, we need to skip rendering it */ + if((recolor_cmd_state == RECOLOR_CMD_STATE_PARAMETER) && (letter == ' ') && (is_first_space_after_cmd == 0)) { + is_first_space_after_cmd = 1; + } + else { + is_first_space_after_cmd = 0; + } + + /* Skip the color parameter and wait the space after it + * Once we have reach the space ' ', then we will extract the color information + * and store it into the recolor variable */ + if(recolor_cmd_state == RECOLOR_CMD_STATE_PARAMETER) { + /* Not an space? Continue with the next character */ + if(letter != ' ') { + continue; + } + + /*Get the recolor parameter*/ + if((next_char_offset - recolor_command_start_index) == LABEL_RECOLOR_PAR_LENGTH + 1) { + /* Temporary buffer to hold the recolor information */ + char buf[LABEL_RECOLOR_PAR_LENGTH + 1]; + lv_memcpy(buf, &bidi_txt[recolor_command_start_index], LABEL_RECOLOR_PAR_LENGTH); + buf[LABEL_RECOLOR_PAR_LENGTH] = '\0'; + + uint8_t r, g, b; + r = (hex_char_to_num(buf[0]) << 4) + hex_char_to_num(buf[1]); + g = (hex_char_to_num(buf[2]) << 4) + hex_char_to_num(buf[3]); + b = (hex_char_to_num(buf[4]) << 4) + hex_char_to_num(buf[5]); + + recolor = lv_color_make(r, g, b); + } + else { + recolor.red = dsc->color.red; + recolor.blue = dsc->color.blue; + recolor.green = dsc->color.green; + } + + /*After the parameter the text is in the command*/ + recolor_cmd_state = RECOLOR_CMD_STATE_TEXT_INPUT; + } + + /* Don't draw the first space after the recolor command */ + if(is_first_space_after_cmd) { + continue; + } + } + + /* If we're in the CMD_STATE_IN state then we need to subtract the recolor command length */ + if(((dsc->flag & LV_TEXT_FLAG_RECOLOR) != 0) && (recolor_cmd_state == RECOLOR_CMD_STATE_TEXT_INPUT)) { + logical_char_pos -= (LABEL_RECOLOR_PAR_LENGTH + 1); + } letter_w = lv_font_get_glyph_width(font, letter, letter_next); @@ -301,7 +463,7 @@ void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_ bg_coords.x2 = pos.x + letter_w - 1; bg_coords.y2 = pos.y + line_height - 1; - if(i >= line_end - line_start) { + if(next_char_offset >= line_end - line_start) { if(dsc->decor & LV_TEXT_DECOR_UNDERLINE) { lv_area_t fill_area; fill_area.x1 = line_start_x; @@ -310,7 +472,7 @@ void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_ fill_area.y2 = fill_area.y1 + underline_width - 1; fill_dsc.color = dsc->color; - cb(draw_unit, NULL, &fill_dsc, &fill_area); + cb(t, NULL, &fill_dsc, &fill_area); } if(dsc->decor & LV_TEXT_DECOR_STRIKETHROUGH) { lv_area_t fill_area; @@ -320,20 +482,25 @@ void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_ fill_area.y2 = fill_area.y1 + underline_width - 1; fill_dsc.color = dsc->color; - cb(draw_unit, NULL, &fill_dsc, &fill_area); + cb(t, NULL, &fill_dsc, &fill_area); } } - if(sel_start != 0xFFFF && sel_end != 0xFFFF && logical_char_pos >= sel_start && logical_char_pos < sel_end) { + /* Handle text selection */ + if(sel_start != LV_DRAW_LABEL_NO_TXT_SEL && sel_end != LV_DRAW_LABEL_NO_TXT_SEL + && logical_char_pos >= sel_start && logical_char_pos < sel_end) { draw_letter_dsc.color = dsc->sel_color; fill_dsc.color = dsc->sel_bg_color; - cb(draw_unit, NULL, &fill_dsc, &bg_coords); + cb(t, NULL, &fill_dsc, &bg_coords); + } + else if(recolor_cmd_state == RECOLOR_CMD_STATE_TEXT_INPUT) { + draw_letter_dsc.color = recolor; } else { draw_letter_dsc.color = dsc->color; } - draw_letter(draw_unit, &draw_letter_dsc, &pos, font, letter, cb); + lv_draw_unit_draw_letter(t, &draw_letter_dsc, &pos, font, letter, cb); if(letter_w > 0) { pos.x += letter_w + dsc->letter_space; @@ -345,28 +512,31 @@ void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_ bidi_txt = NULL; #endif /*Go to next line*/ + remaining_len -= line_end - line_start; line_start = line_end; - line_end += lv_text_get_next_line(&dsc->text[line_start], font, dsc->letter_space, w, NULL, dsc->flag); + if(remaining_len) { + line_end += lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, dsc->letter_space, w, NULL, dsc->flag); + } pos.x = coords->x1; /*Align to middle*/ if(align == LV_TEXT_ALIGN_CENTER) { line_width = - lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space); + lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag); pos.x += (lv_area_get_width(coords) - line_width) / 2; } /*Align to the right*/ else if(align == LV_TEXT_ALIGN_RIGHT) { line_width = - lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space); + lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag); pos.x += lv_area_get_width(coords) - line_width; } /*Go the next line position*/ pos.y += line_height; - if(pos.y > draw_unit->clip_area->y2) break; + if(pos.y > t->clip_area.y2) break; } if(draw_letter_dsc._draw_buf) lv_draw_buf_destroy(draw_letter_dsc._draw_buf); @@ -378,15 +548,27 @@ void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_ * STATIC FUNCTIONS **********************/ -static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, const lv_point_t * pos, - const lv_font_t * font, uint32_t letter, lv_draw_glyph_cb_t cb) +/** + * Convert a hexadecimal characters to a number (0..15) + * @param hex Pointer to a hexadecimal character (0..9, A..F) + * @return the numerical value of `hex` or 0 on error + */ +static uint8_t hex_char_to_num(char hex) +{ + if(hex >= '0' && hex <= '9') return hex - '0'; + if(hex >= 'a') hex -= 'a' - 'A'; /*Convert to upper case*/ + return 'A' <= hex && hex <= 'F' ? hex - 'A' + 10 : 0; +} + +void lv_draw_unit_draw_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * dsc, const lv_point_t * pos, + const lv_font_t * font, uint32_t letter, lv_draw_glyph_cb_t cb) { lv_font_glyph_dsc_t g; if(lv_text_is_marker(letter)) /*Markers are valid letters but should not be rendered.*/ return; - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; bool g_ret = lv_font_get_glyph_dsc(font, &g, letter, '\0'); if(g_ret == false) { /*Add warning if the dsc is not found*/ @@ -395,7 +577,7 @@ static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, /*Don't draw anything if the character is empty. E.g. space*/ if((g.box_h == 0) || (g.box_w == 0)) { - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return; } @@ -404,11 +586,13 @@ static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, letter_coords.x2 = letter_coords.x1 + g.box_w - 1; letter_coords.y1 = pos->y + (font->line_height - font->base_line) - g.box_h - g.ofs_y; letter_coords.y2 = letter_coords.y1 + g.box_h - 1; + lv_area_move(&letter_coords, -dsc->pivot.x, -dsc->pivot.y); /*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)) { - LV_PROFILER_END; + if(lv_area_is_out(&letter_coords, &t->clip_area, 0) && + dsc->bg_coords && + lv_area_is_out(dsc->bg_coords, &t->clip_area, 0)) { + LV_PROFILER_DRAW_END; return; } @@ -420,8 +604,7 @@ static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, if(draw_buf == NULL) { if(dsc->_draw_buf) lv_draw_buf_destroy(dsc->_draw_buf); - uint32_t h = g.box_h; - if(h * g.box_w < 64) h *= 2; /*Alloc a slightly larger buffer*/ + uint32_t h = LV_ROUND_UP(g.box_h, 32); /*Assume a larger size to avoid many reallocations*/ 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; @@ -429,8 +612,15 @@ static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, } } - dsc->glyph_data = (void *) lv_font_get_glyph_bitmap(&g, draw_buf); - dsc->format = dsc->glyph_data ? g.format : LV_FONT_GLYPH_FORMAT_NONE; + dsc->format = g.format; + + if(g.format == LV_FONT_GLYPH_FORMAT_VECTOR) { + + /*Load the outline of the glyph, even if the function says bitmap*/ + g.outline_stroke_width = dsc->outline_stroke_width; + 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 { dsc->format = LV_FONT_GLYPH_FORMAT_NONE; @@ -438,9 +628,9 @@ static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, dsc->letter_coords = &letter_coords; dsc->g = &g; - cb(draw_unit, dsc, NULL, NULL); + cb(t, dsc, NULL, NULL); lv_font_glyph_release_draw_data(&g); - LV_PROFILER_END; + LV_PROFILER_DRAW_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 67afaf5c7..3420bd5b2 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label.h @@ -32,34 +32,114 @@ extern "C" { typedef struct { lv_draw_dsc_base_t base; + /**The text to draw*/ const char * text; + + /**The size of the text*/ + lv_point_t text_size; + + /**The font to use. Fallback fonts are also handled.*/ const lv_font_t * font; - uint32_t sel_start; - uint32_t sel_end; + + /**Color of the text*/ lv_color_t color; - lv_color_t sel_color; - lv_color_t sel_bg_color; + + /**Extra space between the lines*/ int32_t line_space; + + /**Extra space between the characters*/ int32_t letter_space; + + /**Offset the text with this value horizontally*/ int32_t ofs_x; + + /**Offset the text with this value vertically*/ int32_t ofs_y; + + /**Rotation of the letters in 0.1 degree unit*/ + int32_t rotation; + + /**The first characters index for selection (not byte index). `LV_DRAW_LABEL_NO_TXT_SEL` for no selection*/ + uint32_t sel_start; + + /**The last characters's index for selection (not byte index). `LV_DRAW_LABEL_NO_TXT_SEL` for no selection*/ + uint32_t sel_end; + + /**Color of the selected characters*/ + lv_color_t sel_color; + + /**Background color of the selected characters*/ + lv_color_t sel_bg_color; + + /**The number of characters to render. 0: means render until reaching the `\0` termination.*/ + uint32_t text_length; + + /**Opacity of the text in 0...255 range. + * LV_OPA_TRANSP, LV_OPA_10, LV_OPA_20, .. LV_OPA_COVER can be used as well*/ lv_opa_t opa; - lv_base_dir_t bidi_dir; + + /**The alignment of the text `LV_TEXT_ALIGN_LEFT/RIGHT/CENTER`*/ lv_text_align_t align; - lv_text_flag_t flag; + + /**The base direction. Used when type setting Right-to-left (e.g. Arabic) texts*/ + lv_base_dir_t bidi_dir; + + /**Text decoration, e.g. underline*/ + lv_text_decor_t decor : 3; + + /**Some flags to control type setting*/ + lv_text_flag_t flag : 5; + + /**1: malloc a buffer and copy `text` there. + * 0: `text` will be valid during rendering.*/ + uint8_t text_local : 1; + + /**Indicate that the text is constant and its pointer can be safely saved e.g. in a cache.*/ + uint8_t text_static : 1; + + /**1: already executed lv_bidi_process_paragraph. + * 0: has not been executed lv_bidi_process_paragraph.*/ + uint8_t has_bided : 1; + + /**Pointer to an externally stored struct where some data can be cached to speed up rendering*/ + lv_draw_label_hint_t * hint; + + /* Properties of the letter outlines */ + lv_opa_t outline_stroke_opa; + lv_color_t outline_stroke_color; + int32_t outline_stroke_width; + +} lv_draw_label_dsc_t; + +typedef struct { + lv_draw_dsc_base_t base; + + uint32_t unicode; + const lv_font_t * font; + lv_color_t color; + + int32_t rotation; + int32_t scale_x; + int32_t scale_y; + int32_t skew_x; + int32_t skew_y; + lv_point_t pivot; + + lv_opa_t opa; lv_text_decor_t decor : 3; lv_blend_mode_t blend_mode : 3; - /** - * < 1: malloc buffer and copy `text` there. - * 0: `text` is const and it's pointer will be valid during rendering.*/ - uint8_t text_local : 1; - lv_draw_label_hint_t * hint; -} lv_draw_label_dsc_t; + + /* Properties of the letter outlines */ + lv_opa_t outline_stroke_opa; + int32_t outline_stroke_width; + lv_color_t outline_stroke_color; + +} lv_draw_letter_dsc_t; /** * Passed as a parameter to `lv_draw_label_iterate_characters` to * draw the characters one by one - * @param draw_unit pointer to a draw unit + * @param t pointer to a draw task * @param dsc pointer to `lv_draw_glyph_dsc_t` to describe the character to draw * if NULL don't draw character * @param fill_dsc pointer to a fill descriptor to draw a background for the character or @@ -68,13 +148,15 @@ typedef struct { * @param fill_area the area to fill * if NULL do not fill anything */ -typedef void(*lv_draw_glyph_cb_t)(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, lv_draw_fill_dsc_t * fill_dsc, +typedef void(*lv_draw_glyph_cb_t)(lv_draw_task_t * t, lv_draw_glyph_dsc_t * dsc, lv_draw_fill_dsc_t * fill_dsc, const lv_area_t * fill_area); /********************** * GLOBAL PROTOTYPES **********************/ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_letter_dsc_init(lv_draw_letter_dsc_t * dsc); + /** * Initialize a label draw descriptor * @param dsc pointer to a draw descriptor @@ -96,7 +178,7 @@ lv_draw_label_dsc_t * lv_draw_task_get_label_dsc(lv_draw_task_t * task); void lv_draw_glyph_dsc_init(lv_draw_glyph_dsc_t * dsc); /** - * Crate a draw task to render a text + * Create a draw task to render a text * @param layer pointer to a layer * @param dsc pointer to draw descriptor * @param coords coordinates of the character @@ -105,7 +187,7 @@ void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_label(lv_layer_t * layer, const lv_draw const lv_area_t * coords); /** - * Crate a draw task to render a single character + * Create a draw task to render a single character * @param layer pointer to a layer * @param dsc pointer to draw descriptor * @param point position of the label @@ -114,17 +196,45 @@ void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_label(lv_layer_t * layer, const lv_draw void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_character(lv_layer_t * layer, lv_draw_label_dsc_t * dsc, const lv_point_t * point, uint32_t unicode_letter); +/** + * Draw a single letter + * @param layer pointer to a layer + * @param dsc pointer to draw descriptor + * @param point position of the label + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_letter(lv_layer_t * layer, lv_draw_letter_dsc_t * dsc, + const lv_point_t * point); + /** * Should be used during rendering the characters to get the position and other * parameters of the characters - * @param draw_unit pointer to a draw unit + * @param t pointer to a draw task * @param dsc pointer to draw descriptor * @param coords coordinates of the label * @param cb a callback to call to draw each glyphs one by one */ -void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, +void lv_draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords, lv_draw_glyph_cb_t cb); +/** + * @brief Draw a single letter using the provided draw unit, glyph descriptor, position, font, and callback. + * + * This function is responsible for rendering a single character from a text string, + * applying the necessary styling described by the glyph descriptor (`dsc`). It handles + * the retrieval of the glyph's description, checks its visibility within the clipping area, + * and invokes the callback (`cb`) to render the glyph at the specified position (`pos`) + * using the given font (`font`). + * + * @param t Pointer to the drawing task. + * @param dsc Pointer to the descriptor containing styling for the glyph to be drawn. + * @param pos Pointer to the point coordinates where the letter should be drawn. + * @param font Pointer to the font containing the glyph. + * @param letter The Unicode code point of the letter to be drawn. + * @param cb Callback function to execute the actual rendering of the glyph. + */ +void lv_draw_unit_draw_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * dsc, const lv_point_t * pos, + const lv_font_t * font, uint32_t letter, lv_draw_glyph_cb_t cb); + /*********************** * GLOBAL VARIABLES ***********************/ 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 index 163651da5..0ec17817a 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label_private.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_label_private.h @@ -29,7 +29,7 @@ extern "C" { * 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 { +struct _lv_draw_label_hint_t { /** Index of the line at `y` coordinate*/ int32_t line_start; @@ -41,14 +41,20 @@ struct lv_draw_label_hint_t { 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. */ +struct _lv_draw_glyph_dsc_t { + /** Depends on `format` field, it could be image source or draw buf of bitmap or vector data. */ + const void * glyph_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_font_glyph_dsc_t * g; lv_color_t color; lv_opa_t opa; + lv_color_t outline_stroke_color; + lv_opa_t outline_stroke_opa; + int32_t outline_stroke_width; + int32_t rotation; + lv_point_t pivot; /**< Rotation pivot point associated with total glyph including line_height */ lv_draw_buf_t * _draw_buf; /**< a shared draw buf for get_bitmap, do not use it directly, use glyph_data instead */ }; 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 00fc203b1..283d4bf89 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_line.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_line.c @@ -55,21 +55,20 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_line(lv_layer_t * layer, const lv_draw_line_d if(dsc->width == 0) return; if(dsc->opa <= LV_OPA_MIN) return; - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; + lv_area_t a; a.x1 = (int32_t)LV_MIN(dsc->p1.x, dsc->p2.x) - dsc->width; a.x2 = (int32_t)LV_MAX(dsc->p1.x, dsc->p2.x) + dsc->width; a.y1 = (int32_t)LV_MIN(dsc->p1.y, dsc->p2.y) - dsc->width; a.y2 = (int32_t)LV_MAX(dsc->p1.y, dsc->p2.y) + dsc->width; - lv_draw_task_t * t = lv_draw_add_task(layer, &a); + lv_draw_task_t * t = lv_draw_add_task(layer, &a, LV_DRAW_TASK_TYPE_LINE); - t->draw_dsc = lv_malloc(sizeof(*dsc)); lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc)); - t->type = LV_DRAW_TASK_TYPE_LINE; lv_draw_finalize_task_creation(layer, t); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } /********************** 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 72430fa79..79cc4f954 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_line.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_line.h @@ -28,17 +28,36 @@ extern "C" { typedef struct { lv_draw_dsc_base_t base; + /**The first point of the line. If `LV_USE_FLOAT` is enabled float number can be also used*/ lv_point_precise_t p1; + + /**The second point of the line. If `LV_USE_FLOAT` is enabled float number can be also used*/ lv_point_precise_t p2; + + /**The color of the line*/ lv_color_t color; + + /**The width (thickness) of the line*/ int32_t width; + + /** The length of a dash (0: don't dash)*/ int32_t dash_width; + + /** The length of the gaps between dashes (0: don't dash)*/ int32_t dash_gap; + + /**Opacity of the line in 0...255 range. + * LV_OPA_TRANSP, LV_OPA_10, LV_OPA_20, .. LV_OPA_COVER can be used as well*/ lv_opa_t opa; - lv_blend_mode_t blend_mode : 2; + + /**Make the line start rounded*/ uint8_t round_start : 1; + + /**Make the line end rounded*/ 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 */ + + /**1: Do not bother with line ending (if it's not visible for any reason) */ + uint8_t raw_end : 1; } 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 3ee6b62bc..3feea1773 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask.c @@ -53,13 +53,11 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_mask_rect(lv_layer_t * layer, const lv_draw_m LV_LOG_WARN("Only layers with alpha channel can be masked"); return; } - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; - lv_draw_task_t * t = lv_draw_add_task(layer, &layer->buf_area); + lv_draw_task_t * t = lv_draw_add_task(layer, &layer->buf_area, LV_DRAW_TASK_TYPE_MASK_RECTANGLE); - t->draw_dsc = lv_malloc(sizeof(*dsc)); lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc)); - t->type = LV_DRAW_TASK_TYPE_MASK_RECTANGLE; lv_draw_dsc_base_t * base_dsc = t->draw_dsc; base_dsc->layer = layer; @@ -73,7 +71,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_mask_rect(lv_layer_t * layer, const lv_draw_m } lv_draw_finalize_task_creation(layer, t); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } /********************** 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 index 040df7ebe..c3b4e61bb 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask_private.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_mask_private.h @@ -28,11 +28,18 @@ extern "C" { /********************** * TYPEDEFS **********************/ -struct lv_draw_mask_rect_dsc_t { +struct _lv_draw_mask_rect_dsc_t { lv_draw_dsc_base_t base; + /**The area t mask.*/ lv_area_t area; + + /**The radius of masking*/ int32_t radius; + + /**0: clear the content out of the `area`. + * 1: don't touch the area out of `area`*/ + uint32_t keep_outside : 1; }; diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_private.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_private.h index d8244f799..057d4dd08 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_private.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_private.h @@ -19,6 +19,8 @@ extern "C" { *********************/ #include "lv_draw.h" +#include "../osal/lv_os.h" +#include "../misc/cache/lv_cache.h" /********************* * DEFINES @@ -28,7 +30,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_draw_task_t { +struct _lv_draw_task_t { lv_draw_task_t * next; lv_draw_task_type_t type; @@ -52,12 +54,16 @@ struct lv_draw_task_t { * 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; + lv_layer_t * target_layer; #if LV_DRAW_TRANSFORM_USE_MATRIX /** Transform matrix to be applied when rendering the layer */ lv_matrix_t matrix; #endif + /* Reference to the draw unit for debug or draw context purposes */ + lv_draw_unit_t * draw_unit; + volatile int state; /** int instead of lv_draw_task_state_t to be sure its atomic */ void * draw_dsc; @@ -77,19 +83,18 @@ struct lv_draw_task_t { }; -struct lv_draw_mask_t { +struct _lv_draw_mask_t { void * user_data; }; -struct lv_draw_unit_t { +struct _lv_draw_unit_t { lv_draw_unit_t * next; /** - * The target_layer on which drawing should happen + * Name and ID of the draw unit, for debugging purposes only. */ - lv_layer_t * target_layer; - - const lv_area_t * clip_area; + const char * name; + int32_t idx; /** * Called to try to assign a draw task to itself. @@ -171,11 +176,11 @@ struct lv_draw_unit_t { typedef struct { lv_draw_unit_t * unit_head; uint32_t unit_cnt; - uint32_t used_memory_for_layers_kb; + uint32_t used_memory_for_layers; /* measured as bytes */ #if LV_USE_OS lv_thread_sync_t sync; #else - int dispatch_req; + volatile int dispatch_req; #endif lv_mutex_t circle_cache_mutex; bool task_running; 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 ec2acc57a..3ee299ac5 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_rect.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_rect.c @@ -68,6 +68,19 @@ lv_draw_fill_dsc_t * lv_draw_task_get_fill_dsc(lv_draw_task_t * task) return task->type == LV_DRAW_TASK_TYPE_FILL ? (lv_draw_fill_dsc_t *)task->draw_dsc : NULL; } +void lv_draw_fill(lv_layer_t * layer, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords) +{ + if(dsc->opa <= LV_OPA_MIN) return; + + LV_PROFILER_DRAW_BEGIN; + lv_draw_task_t * t = lv_draw_add_task(layer, coords, LV_DRAW_TASK_TYPE_FILL); + + lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc)); + + lv_draw_finalize_task_creation(layer, t); + LV_PROFILER_DRAW_END; +} + void lv_draw_border_dsc_init(lv_draw_border_dsc_t * dsc) { lv_memzero(dsc, sizeof(*dsc)); @@ -81,6 +94,19 @@ lv_draw_border_dsc_t * lv_draw_task_get_border_dsc(lv_draw_task_t * task) return task->type == LV_DRAW_TASK_TYPE_BORDER ? (lv_draw_border_dsc_t *)task->draw_dsc : NULL; } +void lv_draw_border(lv_layer_t * layer, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords) +{ + if(dsc->opa <= LV_OPA_MIN) return; + + LV_PROFILER_DRAW_BEGIN; + lv_draw_task_t * t = lv_draw_add_task(layer, coords, LV_DRAW_TASK_TYPE_BORDER); + + lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc)); + + lv_draw_finalize_task_creation(layer, t); + LV_PROFILER_DRAW_END; +} + void lv_draw_box_shadow_dsc_init(lv_draw_box_shadow_dsc_t * dsc) { lv_memzero(dsc, sizeof(*dsc)); @@ -93,10 +119,23 @@ lv_draw_box_shadow_dsc_t * lv_draw_task_get_box_shadow_dsc(lv_draw_task_t * task return task->type == LV_DRAW_TASK_TYPE_BOX_SHADOW ? (lv_draw_box_shadow_dsc_t *)task->draw_dsc : NULL; } +void lv_draw_box_shadow(lv_layer_t * layer, const lv_draw_box_shadow_dsc_t * dsc, const lv_area_t * coords) +{ + if(dsc->opa <= LV_OPA_MIN) return; + + LV_PROFILER_DRAW_BEGIN; + lv_draw_task_t * t = lv_draw_add_task(layer, coords, LV_DRAW_TASK_TYPE_BOX_SHADOW); + + lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc)); + + lv_draw_finalize_task_creation(layer, t); + LV_PROFILER_DRAW_END; +} + void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; bool has_shadow; bool has_fill; bool has_border; @@ -145,9 +184,9 @@ void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_a /*Shadow*/ if(has_shadow) { /*Check whether the shadow is visible*/ - t = lv_draw_add_task(layer, coords); - lv_draw_box_shadow_dsc_t * shadow_dsc = lv_malloc(sizeof(lv_draw_box_shadow_dsc_t)); - t->draw_dsc = shadow_dsc; + t = lv_draw_add_task(layer, coords, LV_DRAW_TASK_TYPE_BOX_SHADOW); + lv_draw_box_shadow_dsc_t * shadow_dsc = t->draw_dsc; + lv_area_increase(&t->_real_area, dsc->shadow_spread, dsc->shadow_spread); lv_area_increase(&t->_real_area, dsc->shadow_width, dsc->shadow_width); lv_area_move(&t->_real_area, dsc->shadow_offset_x, dsc->shadow_offset_y); @@ -161,7 +200,6 @@ void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_a shadow_dsc->ofs_x = dsc->shadow_offset_x; shadow_dsc->ofs_y = dsc->shadow_offset_y; shadow_dsc->bg_cover = bg_cover; - t->type = LV_DRAW_TASK_TYPE_BOX_SHADOW; lv_draw_finalize_task_creation(layer, t); } @@ -176,17 +214,16 @@ void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_a bg_coords.y2 -= (dsc->border_side & LV_BORDER_SIDE_BOTTOM) ? 1 : 0; } - t = lv_draw_add_task(layer, &bg_coords); - lv_draw_fill_dsc_t * bg_dsc = lv_malloc(sizeof(lv_draw_fill_dsc_t)); + t = lv_draw_add_task(layer, &bg_coords, LV_DRAW_TASK_TYPE_FILL); + lv_draw_fill_dsc_t * bg_dsc = t->draw_dsc; + lv_draw_fill_dsc_init(bg_dsc); - t->draw_dsc = bg_dsc; bg_dsc->base = dsc->base; bg_dsc->base.dsc_size = sizeof(lv_draw_fill_dsc_t); bg_dsc->radius = dsc->radius; bg_dsc->color = dsc->bg_color; bg_dsc->grad = dsc->bg_grad; bg_dsc->opa = dsc->bg_opa; - t->type = LV_DRAW_TASK_TYPE_FILL; lv_draw_finalize_task_creation(layer, t); } @@ -199,28 +236,29 @@ void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_a if(src_type == LV_IMAGE_SRC_VARIABLE || src_type == LV_IMAGE_SRC_FILE) { res = lv_image_decoder_get_info(dsc->bg_image_src, &header); } - else if(src_type == LV_IMAGE_SRC_UNKNOWN) { - res = LV_RESULT_INVALID; - } else { lv_memzero(&header, sizeof(header)); + + if(src_type == LV_IMAGE_SRC_UNKNOWN) { + res = LV_RESULT_INVALID; + } } if(res == LV_RESULT_OK) { if(src_type == LV_IMAGE_SRC_VARIABLE || src_type == LV_IMAGE_SRC_FILE) { if(dsc->bg_image_tiled) { - t = lv_draw_add_task(layer, coords); + t = lv_draw_add_task(layer, coords, LV_DRAW_TASK_TYPE_IMAGE); } else { lv_area_t a = {0, 0, header.w - 1, header.h - 1}; lv_area_align(coords, &a, LV_ALIGN_CENTER, 0, 0); - t = lv_draw_add_task(layer, &a); + t = lv_draw_add_task(layer, &a, LV_DRAW_TASK_TYPE_IMAGE); } - lv_draw_image_dsc_t * bg_image_dsc = lv_malloc(sizeof(lv_draw_image_dsc_t)); + lv_draw_image_dsc_t * bg_image_dsc = t->draw_dsc; + lv_draw_image_dsc_init(bg_image_dsc); - t->draw_dsc = bg_image_dsc; bg_image_dsc->base = dsc->base; bg_image_dsc->base.dsc_size = sizeof(lv_draw_image_dsc_t); bg_image_dsc->src = dsc->bg_image_src; @@ -230,7 +268,7 @@ void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_a 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; + bg_image_dsc->image_area = *coords; lv_draw_finalize_task_creation(layer, t); } else { @@ -239,11 +277,11 @@ void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_a lv_area_t a = {0, 0, s.x - 1, s.y - 1}; lv_area_align(coords, &a, LV_ALIGN_CENTER, 0, 0); - t = lv_draw_add_task(layer, &a); + t = lv_draw_add_task(layer, &a, LV_DRAW_TASK_TYPE_LABEL); + + lv_draw_label_dsc_t * bg_label_dsc = t->draw_dsc; - lv_draw_label_dsc_t * bg_label_dsc = lv_malloc(sizeof(lv_draw_label_dsc_t)); lv_draw_label_dsc_init(bg_label_dsc); - t->draw_dsc = bg_label_dsc; bg_label_dsc->base = dsc->base; bg_label_dsc->base.dsc_size = sizeof(lv_draw_label_dsc_t); bg_label_dsc->color = dsc->bg_image_recolor; @@ -257,9 +295,9 @@ void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_a /*Border*/ if(has_border) { - t = lv_draw_add_task(layer, coords); - lv_draw_border_dsc_t * border_dsc = lv_malloc(sizeof(lv_draw_border_dsc_t)); - t->draw_dsc = border_dsc; + t = lv_draw_add_task(layer, coords, LV_DRAW_TASK_TYPE_BORDER); + lv_draw_border_dsc_t * border_dsc = t->draw_dsc; + border_dsc->base = dsc->base; border_dsc->base.dsc_size = sizeof(lv_draw_border_dsc_t); border_dsc->radius = dsc->radius; @@ -267,7 +305,6 @@ void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_a border_dsc->opa = dsc->border_opa; border_dsc->width = dsc->border_width; border_dsc->side = dsc->border_side; - t->type = LV_DRAW_TASK_TYPE_BORDER; lv_draw_finalize_task_creation(layer, t); } @@ -275,9 +312,8 @@ void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_a if(has_outline) { lv_area_t outline_coords = *coords; lv_area_increase(&outline_coords, dsc->outline_width + dsc->outline_pad, dsc->outline_width + dsc->outline_pad); - t = lv_draw_add_task(layer, &outline_coords); - lv_draw_border_dsc_t * outline_dsc = lv_malloc(sizeof(lv_draw_border_dsc_t)); - t->draw_dsc = outline_dsc; + t = lv_draw_add_task(layer, &outline_coords, LV_DRAW_TASK_TYPE_BORDER); + lv_draw_border_dsc_t * outline_dsc = t->draw_dsc; lv_area_increase(&t->_real_area, dsc->outline_width, dsc->outline_width); lv_area_increase(&t->_real_area, dsc->outline_pad, dsc->outline_pad); outline_dsc->base = dsc->base; @@ -288,13 +324,12 @@ void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_a outline_dsc->opa = dsc->outline_opa; outline_dsc->width = dsc->outline_width; outline_dsc->side = LV_BORDER_SIDE_FULL; - t->type = LV_DRAW_TASK_TYPE_BORDER; lv_draw_finalize_task_creation(layer, t); } LV_ASSERT_MEM_INTEGRITY(); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_rect.h b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_rect.h index 6fe3a82e7..85ec3af17 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_rect.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_rect.h @@ -17,7 +17,6 @@ extern "C" { #include "../misc/lv_color.h" #include "../misc/lv_area.h" #include "../misc/lv_style.h" -#include "sw/lv_draw_sw_gradient.h" /********************* * DEFINES @@ -72,21 +71,41 @@ typedef struct { typedef struct { lv_draw_dsc_base_t base; + /**Radius, LV_RADIUS_CIRCLE for max. radius */ int32_t radius; + /**Opacity in 0...255 range. + * LV_OPA_TRANSP, LV_OPA_10, LV_OPA_20, .. LV_OPA_COVER can be used as well*/ lv_opa_t opa; + + /**The color of the rectangle. + * If the gradient is set (grad.dir!=LV_GRAD_DIR_NONE) it's ignored. */ lv_color_t color; + + /**Describe a gradient. If `grad.dir` is not `LV_GRAD_DIR_NONE` `color` will be ignored*/ lv_grad_dsc_t grad; } lv_draw_fill_dsc_t; typedef struct { lv_draw_dsc_base_t base; + /**Radius, LV_RADIUS_CIRCLE for max. radius */ int32_t radius; + /**The color of the border. */ lv_color_t color; + + + /**The width of the border in pixels */ int32_t width; + + /**Opacity in 0...255 range. + * LV_OPA_TRANSP, LV_OPA_10, LV_OPA_20, .. LV_OPA_COVER can be used as well*/ lv_opa_t opa; + + /**LV_BORDER_SIDE_NONE/LEFT/RIGHT/TOP/BOTTOM/FULL. + * LV_BORDER_SIDE_INTERNAL is an information for upper layers + * and shouldn't be used here. */ lv_border_side_t side : 5; } lv_draw_border_dsc_t; @@ -94,14 +113,30 @@ typedef struct { typedef struct { lv_draw_dsc_base_t base; + /**Radius, LV_RADIUS_CIRCLE for max. radius */ int32_t radius; + /**Color of the the shadow */ lv_color_t color; + + /**Width of the shadow. (radius of the blur)*/ int32_t width; + + /**Make the rectangle larger with this value in all directions. Can be negative too. */ int32_t spread; + + /**Offset the rectangle horizontally.*/ int32_t ofs_x; + + /**Offset the rectangle vertically.*/ int32_t ofs_y; + + /**Opacity in 0...255 range. + * LV_OPA_TRANSP, LV_OPA_10, LV_OPA_20, .. LV_OPA_COVER can be used as well*/ lv_opa_t opa; + + /**Set `bg_cover` to 1 if the background will cover the shadow. + * It's a hint to the renderer about it might skip some masking.*/ uint8_t bg_cover : 1; } lv_draw_box_shadow_dsc_t; @@ -128,6 +163,14 @@ void lv_draw_fill_dsc_init(lv_draw_fill_dsc_t * dsc); */ lv_draw_fill_dsc_t * lv_draw_task_get_fill_dsc(lv_draw_task_t * task); +/** + * Fill an area + * @param layer pointer to a layer + * @param dsc pointer to an initialized draw descriptor variable + * @param coords the coordinates of the rectangle + */ +void lv_draw_fill(lv_layer_t * layer, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords); + /** * Initialize a border draw descriptor. * @param dsc pointer to a draw descriptor @@ -141,6 +184,14 @@ void lv_draw_border_dsc_init(lv_draw_border_dsc_t * dsc); */ lv_draw_border_dsc_t * lv_draw_task_get_border_dsc(lv_draw_task_t * task); +/** + * Draw a border + * @param layer pointer to a layer + * @param dsc pointer to an initialized draw descriptor variable + * @param coords the coordinates of the rectangle + */ +void lv_draw_border(lv_layer_t * layer, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords); + /** * Initialize a box shadow draw descriptor. * @param dsc pointer to a draw descriptor @@ -154,6 +205,14 @@ void lv_draw_box_shadow_dsc_init(lv_draw_box_shadow_dsc_t * dsc); */ lv_draw_box_shadow_dsc_t * lv_draw_task_get_box_shadow_dsc(lv_draw_task_t * task); +/** + * Draw a box shadow + * @param layer pointer to a layer + * @param dsc pointer to an initialized draw descriptor variable + * @param coords the coordinates of the rectangle + */ +void lv_draw_box_shadow(lv_layer_t * layer, const lv_draw_box_shadow_dsc_t * dsc, const lv_area_t * coords); + /** * The rectangle is a wrapper for fill, border, bg. image and box shadow. * Internally fill, border, image and box shadow draw tasks will be created. 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 6bf1c7c21..f36f82875 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle.c @@ -40,16 +40,16 @@ void lv_draw_triangle_dsc_init(lv_draw_triangle_dsc_t * dsc) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; lv_memzero(dsc, sizeof(lv_draw_triangle_dsc_t)); - dsc->bg_color = lv_color_white(); - dsc->bg_grad.stops[0].color = lv_color_white(); - dsc->bg_grad.stops[1].color = lv_color_black(); - dsc->bg_grad.stops[1].frac = 0xFF; - dsc->bg_grad.stops_count = 2; - dsc->bg_opa = LV_OPA_COVER; + dsc->color = lv_color_white(); + dsc->grad.stops[0].color = lv_color_white(); + dsc->grad.stops[1].color = lv_color_black(); + dsc->grad.stops[1].frac = 0xFF; + dsc->grad.stops_count = 2; + dsc->opa = LV_OPA_COVER; dsc->base.dsc_size = sizeof(lv_draw_triangle_dsc_t); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } lv_draw_triangle_dsc_t * lv_draw_task_get_triangle_dsc(lv_draw_task_t * task) @@ -59,23 +59,22 @@ 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; + if(dsc->opa <= LV_OPA_MIN) return; + + LV_PROFILER_DRAW_BEGIN; - 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); a.y1 = (int32_t)LV_MIN3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y); a.x2 = (int32_t)LV_MAX3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); a.y2 = (int32_t)LV_MAX3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y); - lv_draw_task_t * t = lv_draw_add_task(layer, &a); + lv_draw_task_t * t = lv_draw_add_task(layer, &a, LV_DRAW_TASK_TYPE_TRIANGLE); - t->draw_dsc = lv_malloc(sizeof(*dsc)); lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc)); - t->type = LV_DRAW_TASK_TYPE_TRIANGLE; lv_draw_finalize_task_creation(layer, t); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } /********************** 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 b1ad8e58b..db53d4795 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_triangle.h @@ -25,11 +25,19 @@ extern "C" { typedef struct { lv_draw_dsc_base_t base; - lv_opa_t bg_opa; - lv_color_t bg_color; - lv_grad_dsc_t bg_grad; - + /**Points of the triangle. If `LV_USE_FLOAT` is enabled floats can be used here*/ lv_point_precise_t p[3]; + + /**Color of the triangle*/ + lv_color_t color; + + /**Opacity of the arc in 0...255 range. + * LV_OPA_TRANSP, LV_OPA_10, LV_OPA_20, .. LV_OPA_COVER can be used as well*/ + lv_opa_t opa; + + /**Describe a gradient. If `grad.dir` is not `LV_GRAD_DIR_NONE` `color` will be ignored*/ + lv_grad_dsc_t grad; + } lv_draw_triangle_dsc_t; /********************** 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 28a08f289..5ed6477f6 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector.c @@ -228,10 +228,10 @@ void lv_vector_path_get_bounding(const lv_vector_path_t * path, lv_area_t * area if(p[i].y > y2) y2 = p[i].y; } - area->x1 = (int32_t)x1; - area->y1 = (int32_t)y1; - area->x2 = (int32_t)x2; - area->y2 = (int32_t)y2; + area->x1 = lroundf(x1); + area->y1 = lroundf(y1); + area->x2 = lroundf(x2); + area->y2 = lroundf(y2); } void lv_vector_path_append_rect(lv_vector_path_t * path, const lv_area_t * rect, float rx, float ry) @@ -412,6 +412,11 @@ void lv_vector_path_append_arc(lv_vector_path_t * path, const lv_fpoint_t * c, f start.x + cx, start.y + cy }); } + else { + lv_vector_path_move_to(path, &(lv_fpoint_t) { + start.x + cx, start.y + cy + }); + } for(int i = 0; i < n_curves; ++i) { float end_angle = start_angle + ((i != n_curves - 1) ? MATH_HALF_PI * sweep_sign : fract); @@ -541,6 +546,11 @@ void lv_vector_dsc_set_fill_rule(lv_vector_dsc_t * dsc, lv_vector_fill_t rule) dsc->current_dsc.fill_dsc.fill_rule = rule; } +void lv_vector_dsc_set_fill_units(lv_vector_dsc_t * dsc, const lv_vector_fill_units_t units) +{ + dsc->current_dsc.fill_dsc.fill_units = units; +} + void lv_vector_dsc_set_fill_image(lv_vector_dsc_t * dsc, const lv_draw_image_dsc_t * img_dsc) { dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_PATTERN; @@ -571,7 +581,7 @@ void lv_vector_dsc_set_fill_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gra dsc->current_dsc.fill_dsc.gradient.spread = spread; } -void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops, +void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_grad_stop_t * stops, uint16_t count) { if(count > LV_GRADIENT_MAX_STOPS) { @@ -579,7 +589,7 @@ void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv count = LV_GRADIENT_MAX_STOPS; } - lv_memcpy(&(dsc->current_dsc.fill_dsc.gradient.stops), stops, sizeof(lv_gradient_stop_t) * count); + lv_memcpy(&(dsc->current_dsc.fill_dsc.gradient.stops), stops, sizeof(lv_grad_stop_t) * count); dsc->current_dsc.fill_dsc.gradient.stops_count = count; } @@ -674,7 +684,7 @@ void lv_vector_dsc_set_stroke_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_g dsc->current_dsc.stroke_dsc.gradient.spread = spread; } -void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops, +void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_grad_stop_t * stops, uint16_t count) { if(count > LV_GRADIENT_MAX_STOPS) { @@ -682,7 +692,7 @@ void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const count = LV_GRADIENT_MAX_STOPS; } - lv_memcpy(&(dsc->current_dsc.stroke_dsc.gradient.stops), stops, sizeof(lv_gradient_stop_t) * count); + lv_memcpy(&(dsc->current_dsc.stroke_dsc.gradient.stops), stops, sizeof(lv_grad_stop_t) * count); dsc->current_dsc.stroke_dsc.gradient.stops_count = count; } @@ -722,6 +732,11 @@ void lv_vector_clear_area(lv_vector_dsc_t * dsc, const lv_area_t * rect) return; } + lv_area_t final_rect; + if(!lv_area_intersect(&final_rect, &r, rect)) { + return; + } + if(!dsc->tasks.task_list) { dsc->tasks.task_list = lv_malloc(sizeof(lv_ll_t)); LV_ASSERT_MALLOC(dsc->tasks.task_list); @@ -733,7 +748,7 @@ void lv_vector_clear_area(lv_vector_dsc_t * dsc, const lv_area_t * rect) new_task->dsc.fill_dsc.color = dsc->current_dsc.fill_dsc.color; new_task->dsc.fill_dsc.opa = dsc->current_dsc.fill_dsc.opa; - lv_area_copy(&(new_task->dsc.scissor_area), rect); + lv_area_copy(&(new_task->dsc.scissor_area), &final_rect); } void lv_draw_vector(lv_vector_dsc_t * dsc) @@ -744,9 +759,7 @@ void lv_draw_vector(lv_vector_dsc_t * dsc) lv_layer_t * layer = dsc->layer; - lv_draw_task_t * t = lv_draw_add_task(layer, &(layer->_clip_area)); - t->type = LV_DRAW_TASK_TYPE_VECTOR; - t->draw_dsc = lv_malloc(sizeof(lv_draw_vector_task_dsc_t)); + lv_draw_task_t * t = lv_draw_add_task(layer, &(layer->_clip_area), LV_DRAW_TASK_TYPE_VECTOR); lv_memcpy(t->draw_dsc, &(dsc->tasks), sizeof(lv_draw_vector_task_dsc_t)); lv_draw_finalize_task_creation(layer, t); dsc->tasks.task_list = NULL; @@ -780,6 +793,8 @@ void lv_vector_dsc_skew(lv_vector_dsc_t * dsc, float skew_x, float skew_y) void lv_vector_for_each_destroy_tasks(lv_ll_t * task_list, vector_draw_task_cb cb, void * data) { + if(task_list == NULL) return; + lv_vector_draw_task * task = lv_ll_get_head(task_list); lv_vector_draw_task * next_task = NULL; 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 38ce78ae1..ccb03df73 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector.h @@ -86,7 +86,12 @@ typedef enum { LV_VECTOR_GRADIENT_STYLE_RADIAL, } lv_vector_gradient_style_t; -struct lv_fpoint_t { +typedef enum { + LV_VECTOR_FILL_UNITS_OBJECT_BOUNDING_BOX = 0, /** Relative coordinates relative to the object bounding box. */ + LV_VECTOR_FILL_UNITS_USER_SPACE_ON_USE, /** Absolute coordinates relative to the layer's coordinate system */ +} lv_vector_fill_units_t; + +struct _lv_fpoint_t { float x; float y; }; @@ -272,6 +277,15 @@ void lv_vector_dsc_set_fill_opa(lv_vector_dsc_t * dsc, lv_opa_t opa); */ void lv_vector_dsc_set_fill_rule(lv_vector_dsc_t * dsc, lv_vector_fill_t rule); +/** + * Set the fill units for descriptor. + * @param dsc pointer to a vector graphic descriptor + * @param units the units to be set in lv_vector_fill_units_t format + * @note The units can be either relative to the object bounding box or absolute in user space. + * This API specifically affects the drawing position of the fill image and does not impact other elements. + */ +void lv_vector_dsc_set_fill_units(lv_vector_dsc_t * dsc, const lv_vector_fill_units_t units); + /** * Set fill image for descriptor * @param dsc pointer to a vector graphic descriptor @@ -309,10 +323,10 @@ void lv_vector_dsc_set_fill_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gra /** * 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 stops an array of `lv_grad_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, +void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_grad_stop_t * stops, uint16_t count); /** @@ -407,10 +421,10 @@ void lv_vector_dsc_set_stroke_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_g /** * 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 stops an array of `lv_grad_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, +void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_grad_stop_t * stops, uint16_t count); /** 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 index 5257a301e..7b2d4e04a 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector_private.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_draw_vector_private.h @@ -26,16 +26,16 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_vector_path_t { +struct _lv_vector_path_t { lv_vector_path_quality_t quality; lv_array_t ops; lv_array_t points; }; -struct lv_vector_gradient_t { +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 */ + lv_grad_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; @@ -46,17 +46,18 @@ struct lv_vector_gradient_t { lv_vector_gradient_spread_t spread; }; -struct lv_vector_fill_dsc_t { +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_vector_fill_units_t fill_units; lv_draw_image_dsc_t img_dsc; lv_vector_gradient_t gradient; lv_matrix_t matrix; }; -struct lv_vector_stroke_dsc_t { +struct _lv_vector_stroke_dsc_t { lv_vector_draw_style_t style; lv_color32_t color; lv_opa_t opa; @@ -69,7 +70,7 @@ struct lv_vector_stroke_dsc_t { lv_matrix_t matrix; }; -struct lv_vector_draw_dsc_t { +struct _lv_vector_draw_dsc_t { lv_vector_fill_dsc_t fill_dsc; lv_vector_stroke_dsc_t stroke_dsc; lv_matrix_t matrix; @@ -77,19 +78,18 @@ struct lv_vector_draw_dsc_t { lv_area_t scissor_area; }; -struct lv_draw_vector_task_dsc_t { +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 { +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 **********************/ 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 90934c105..48d62c89f 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder.c @@ -128,16 +128,20 @@ 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); + if(res == LV_RESULT_OK && dsc->decoded != NULL) { + LV_ASSERT_MSG(dsc->decoded->unaligned_data && dsc->decoded->handlers, "Invalid draw buffer"); + + /* Flush the D-Cache if enabled and the image was successfully opened */ + if(dsc->args.flush_cache) { + 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; @@ -335,15 +339,12 @@ static lv_image_decoder_t * image_decoder_get_info(lv_image_decoder_dsc_t * dsc, } /*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_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."); @@ -351,8 +352,9 @@ static lv_image_decoder_t * image_decoder_get_info(lv_image_decoder_dsc_t * dsc, } break; } - - decoder_prev = decoder; + else { + LV_LOG_TRACE("Can't open image with decoder %s. Trying next decoder.", decoder->name); + } } } 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 e898edc9d..3b8089aff 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder.h @@ -19,7 +19,6 @@ extern "C" { #include "../misc/lv_fs.h" #include "../misc/lv_types.h" #include "../misc/lv_area.h" -#include "../misc/cache/lv_cache.h" /********************* * DEFINES @@ -76,6 +75,16 @@ 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); +/** + * Custom drawing functions for special image formats. + * @param layer pointer to a layer + * @param dsc pointer to decoder descriptor + * @param coords the coordinates of the image + * @param draw_dsc the draw image descriptor + * @param clip_area the clip area of the image + */ +typedef void (*lv_image_decoder_custom_draw_t)(lv_layer_t * layer, const lv_image_decoder_dsc_t * dsc, + const lv_area_t * coords, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * clip_area); /********************** * GLOBAL PROTOTYPES **********************/ 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 index 27ef26140..c7369d0aa 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder_private.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_image_decoder_private.h @@ -13,8 +13,8 @@ extern "C" { /********************* * INCLUDES *********************/ - #include "lv_image_decoder.h" +#include "../misc/cache/lv_cache.h" /********************* * DEFINES @@ -33,7 +33,7 @@ extern "C" { * Default args: * all field are zero or false. */ -struct lv_image_decoder_args_t { +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. */ @@ -41,18 +41,20 @@ struct lv_image_decoder_args_t { bool flush_cache; /**< Whether to flush the data cache after decoding */ }; -struct lv_image_decoder_t { +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_image_decoder_custom_draw_t custom_draw_cb; + const char * name; void * user_data; }; -struct lv_image_cache_data_t { +struct _lv_image_cache_data_t { lv_cache_slot_size_t slot; const void * src; @@ -63,7 +65,7 @@ struct lv_image_cache_data_t { void * user_data; }; -struct lv_image_header_cache_data_t { +struct _lv_image_header_cache_data_t { const void * src; lv_image_src_t src_type; @@ -72,7 +74,7 @@ struct lv_image_header_cache_data_t { }; /**Describe an image decoding session. Stores data about the decoding*/ -struct lv_image_decoder_dsc_t { +struct _lv_image_decoder_dsc_t { /**The decoder which was able to open the image source*/ lv_image_decoder_t * decoder; 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 ecd50882e..922c65e90 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/lv_image_dsc.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/lv_image_dsc.h @@ -29,7 +29,7 @@ LV_EXPORT_CONST_INT(LV_IMAGE_HEADER_MAGIC); * TYPEDEFS **********************/ -typedef enum lv_image_flags_t { +typedef enum _lvimage_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. @@ -55,6 +55,11 @@ typedef enum lv_image_flags_t { */ LV_IMAGE_FLAGS_MODIFIABLE = 0x0020, + /** + * The image has custom drawing methods. + */ + LV_IMAGE_FLAGS_CUSTOM_DRAW = 0x0040, + /** * Flags reserved for user, lvgl won't use these bits. */ @@ -124,6 +129,7 @@ typedef struct { uint32_t data_size; /**< Size of the image in bytes*/ 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*/ + const void * reserved_2; /**< A reserved field to make it has same size as lv_draw_buf_t*/ } lv_image_dsc_t; /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx.c b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx.c new file mode 100644 index 000000000..fb0a3d67e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx.c @@ -0,0 +1,405 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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. + * + */ + +/** + * @file lv_draw_nema_gfx.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_refr.h" + +#if LV_USE_NEMA_GFX + +#include "lv_draw_nema_gfx.h" +#include "../../font/lv_font.h" +#include "../../font/lv_font_fmt_txt.h" + +/********************* + * DEFINES + *********************/ + +#define DRAW_UNIT_ID_NEMA_GFX 7 + +/********************** + * TYPEDEFS + **********************/ + +#if LV_USE_OS +/** + * Structure of pending nema_gfx draw task + */ +typedef struct _nema_gfx_draw_task_t { + lv_draw_task_t * task; + bool flushed; +} nema_gfx_draw_task_t; +#endif + +/********************** + * STATIC PROTOTYPES + **********************/ + +#if LV_USE_OS + static void nema_gfx_render_thread_cb(void * ptr); +#endif + +static void nema_gfx_execute_drawing(lv_draw_nema_gfx_unit_t * u); + +static int32_t nema_gfx_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer); + +static int32_t nema_gfx_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task); + +static int32_t nema_gfx_delete(lv_draw_unit_t * draw_unit); + +static int32_t nema_gfx_wait_for_finish(lv_draw_unit_t * draw_unit); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_nema_gfx_init(void) +{ + lv_draw_nema_gfx_unit_t * draw_nema_gfx_unit = lv_draw_create_unit(sizeof(lv_draw_nema_gfx_unit_t)); + /*Initialize NemaGFX*/ + nema_init(); + + draw_nema_gfx_unit->base_unit.dispatch_cb = nema_gfx_dispatch; + draw_nema_gfx_unit->base_unit.evaluate_cb = nema_gfx_evaluate; + draw_nema_gfx_unit->base_unit.delete_cb = nema_gfx_delete; + draw_nema_gfx_unit->base_unit.wait_for_finish_cb = nema_gfx_wait_for_finish; + draw_nema_gfx_unit->base_unit.name = "NEMA_GFX"; + +#if LV_USE_NEMA_VG + /*Initialize NemaVG */ + nema_vg_init(LV_NEMA_GFX_MAX_RESX, LV_NEMA_GFX_MAX_RESY); + /* Allocate VG Buffers*/ + draw_nema_gfx_unit->paint = nema_vg_paint_create(); + draw_nema_gfx_unit->gradient = nema_vg_grad_create(); + draw_nema_gfx_unit->path = nema_vg_path_create(); + /*Initialize Freetype Support*/ + lv_draw_nema_gfx_label_init(&(draw_nema_gfx_unit->base_unit)); +#endif + /*Create GPU Command List*/ + draw_nema_gfx_unit->cl = nema_cl_create(); + /*Bind Command List*/ + nema_cl_bind_circular(&(draw_nema_gfx_unit->cl)); + + +#if LV_USE_OS + lv_thread_init(&draw_nema_gfx_unit->thread, "nemagfx", LV_DRAW_THREAD_PRIO, nema_gfx_render_thread_cb, 2 * 1024, + draw_nema_gfx_unit); +#endif +} + +void lv_draw_nema_gfx_deinit(void) +{ + return; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static int32_t nema_gfx_wait_for_finish(lv_draw_unit_t * draw_unit) +{ + lv_draw_nema_gfx_unit_t * draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *)draw_unit; + nema_cl_submit(&(draw_nema_gfx_unit->cl)); + nema_cl_wait(&(draw_nema_gfx_unit->cl)); + return 1; +} + +static int32_t nema_gfx_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task) +{ + lv_draw_nema_gfx_unit_t * draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *)draw_unit; + + switch(task->type) { + case LV_DRAW_TASK_TYPE_LAYER: { + if(task->preference_score > 80) { + task->preference_score = 80; + task->preferred_draw_unit_id = DRAW_UNIT_ID_NEMA_GFX; + } + return 1; + } +#if LV_USE_NEMA_VG + case LV_DRAW_TASK_TYPE_TRIANGLE: + case LV_DRAW_TASK_TYPE_ARC: + case LV_DRAW_TASK_TYPE_FILL: { + if(task->preference_score > 80) { + task->preference_score = 80; + task->preferred_draw_unit_id = DRAW_UNIT_ID_NEMA_GFX; + } + return 1; + } +#else + case LV_DRAW_TASK_TYPE_FILL: { + lv_draw_fill_dsc_t * draw_fill_dsc = (lv_draw_fill_dsc_t *) task->draw_dsc; + if((draw_fill_dsc->grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_NONE)) { + if(task->preference_score > 80) { + task->preference_score = 80; + task->preferred_draw_unit_id = DRAW_UNIT_ID_NEMA_GFX; + } + return 1; + } + break; + } + case LV_DRAW_TASK_TYPE_TRIANGLE: { + lv_draw_triangle_dsc_t * draw_triangle_dsc = (lv_draw_triangle_dsc_t *) task->draw_dsc; + if((draw_triangle_dsc->grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_NONE)) { + if(task->preference_score > 80) { + task->preference_score = 80; + task->preferred_draw_unit_id = DRAW_UNIT_ID_NEMA_GFX; + } + return 1; + } + break; + } +#endif + case LV_DRAW_TASK_TYPE_IMAGE: { + lv_draw_image_dsc_t * draw_image_dsc = (lv_draw_image_dsc_t *) task->draw_dsc; + /*Guard for previous NemaGFX Version*/ +#ifndef NEMA_BLOP_RECOLOR + if(draw_image_dsc->recolor_opa > LV_OPA_MIN) + break; +#endif + const lv_image_dsc_t * img_dsc = draw_image_dsc->src; + if(!lv_nemagfx_is_cf_supported(img_dsc->header.cf)) + break; + + if(draw_image_dsc->blend_mode != LV_BLEND_MODE_SUBTRACTIVE) { + if(task->preference_score > 80) { + task->preference_score = 80; + task->preferred_draw_unit_id = DRAW_UNIT_ID_NEMA_GFX; + } + return 1; + } + break; + } + case LV_DRAW_TASK_TYPE_LABEL: { + lv_draw_label_dsc_t * draw_label_dsc = (lv_draw_label_dsc_t *) task->draw_dsc; + lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *)(draw_label_dsc->font->dsc); + if(fdsc->bitmap_format != LV_FONT_FMT_TXT_COMPRESSED) { + if(task->preference_score > 80) { + task->preference_score = 80; + task->preferred_draw_unit_id = DRAW_UNIT_ID_NEMA_GFX; + } + return 1; + } + break; + } + case LV_DRAW_TASK_TYPE_LINE: { + lv_draw_line_dsc_t * draw_line_dsc = (lv_draw_line_dsc_t *) task->draw_dsc; + bool is_dashed = (draw_line_dsc->dash_width && draw_line_dsc->dash_gap); + if(!is_dashed && !(draw_line_dsc->round_end || draw_line_dsc->round_start)) { + if(task->preference_score > 80) { + task->preference_score = 80; + task->preferred_draw_unit_id = DRAW_UNIT_ID_NEMA_GFX; + } + return 1; + } + break; + } + case LV_DRAW_TASK_TYPE_BORDER: { + const lv_draw_border_dsc_t * draw_dsc = (lv_draw_border_dsc_t *) task->draw_dsc; + if((!(draw_dsc->side != (lv_border_side_t)LV_BORDER_SIDE_FULL && draw_dsc->radius > 0)) && + (draw_dsc->radius > draw_dsc->width)) { + if(task->preference_score > 80) { + task->preference_score = 80; + task->preferred_draw_unit_id = DRAW_UNIT_ID_NEMA_GFX; + } + return 1; + } + break; + } + case LV_DRAW_TASK_TYPE_BOX_SHADOW: + case LV_DRAW_TASK_TYPE_MASK_RECTANGLE: + case LV_DRAW_TASK_TYPE_MASK_BITMAP: +#if LV_USE_VECTOR_GRAPHIC + case LV_DRAW_TASK_TYPE_VECTOR: +#endif + default: + break; + } + nema_cl_wait(&(draw_nema_gfx_unit->cl)); + return 0; +} + +static int32_t nema_gfx_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) +{ + lv_draw_nema_gfx_unit_t * draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *) draw_unit; + + /* Return immediately if it's busy with draw task. */ + if(draw_nema_gfx_unit->task_act) + return 0; + + /* Try to get an ready to draw. */ + lv_draw_task_t * t = lv_draw_get_available_task(layer, NULL, DRAW_UNIT_ID_NEMA_GFX); + + /* Return 0 is no selection, some tasks can be supported by other units. */ + if(t == NULL || t->preferred_draw_unit_id != DRAW_UNIT_ID_NEMA_GFX) + return LV_DRAW_UNIT_IDLE; + + void * buf = lv_draw_layer_alloc_buf(layer); + if(buf == NULL) + return LV_DRAW_UNIT_IDLE; + + t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; + draw_nema_gfx_unit->task_act = t; + +#if LV_USE_OS + /* Let the render thread work. */ + if(draw_nema_gfx_unit->inited) + lv_thread_sync_signal(&draw_nema_gfx_unit->sync); +#else + nema_gfx_execute_drawing(draw_nema_gfx_unit); + + draw_nema_gfx_unit->task_act->state = LV_DRAW_TASK_STATE_READY; + draw_nema_gfx_unit->task_act = NULL; + + /* The draw unit is free now. Request a new dispatching as it can get a new task. */ + lv_draw_dispatch_request(); +#endif + + return 1; +} + +static void nema_gfx_execute_drawing(lv_draw_nema_gfx_unit_t * u) +{ + lv_draw_task_t * t = u->task_act; + /* remember draw unit for access to unit's context */ + t->draw_unit = (lv_draw_unit_t *)u; + + switch(t->type) { + case LV_DRAW_TASK_TYPE_FILL: + lv_draw_nema_gfx_fill(t, t->draw_dsc, &t->area); + break; + case LV_DRAW_TASK_TYPE_IMAGE: + lv_draw_nema_gfx_img(t, t->draw_dsc, &t->area); + break; + case LV_DRAW_TASK_TYPE_TRIANGLE: + lv_draw_nema_gfx_triangle(t, t->draw_dsc); + break; + case LV_DRAW_TASK_TYPE_LABEL: + lv_draw_nema_gfx_label(t, t->draw_dsc, &t->area); + break; + case LV_DRAW_TASK_TYPE_LAYER: + lv_draw_nema_gfx_layer(t, t->draw_dsc, &t->area); + break; + case LV_DRAW_TASK_TYPE_LINE: + lv_draw_nema_gfx_line(t, t->draw_dsc); + break; +#if LV_USE_NEMA_VG + case LV_DRAW_TASK_TYPE_ARC: + lv_draw_nema_gfx_arc(t, t->draw_dsc, &t->area); + break; +#endif + case LV_DRAW_TASK_TYPE_BORDER: + lv_draw_nema_gfx_border(t, t->draw_dsc, &t->area); + break; + default: + break; + } +} + +static int32_t nema_gfx_delete(lv_draw_unit_t * draw_unit) +{ +#if LV_USE_NEMA_VG + /*Free VG Buffers*/ + lv_draw_nema_gfx_unit_t * draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *) draw_unit; + nema_vg_paint_destroy(draw_nema_gfx_unit->paint); + nema_vg_path_destroy(draw_nema_gfx_unit->path); + nema_vg_grad_destroy(draw_nema_gfx_unit->gradient); +#endif + +#if LV_USE_OS + lv_draw_nema_gfx_unit_t * _draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *) draw_unit; + LV_LOG_INFO("Cancel NemaGFX draw thread."); + _draw_nema_gfx_unit->exit_status = true; + + if(_draw_nema_gfx_unit->inited) + lv_thread_sync_signal(&_draw_nema_gfx_unit->sync); + + lv_result_t res = lv_thread_delete(&_draw_nema_gfx_unit->thread); + + return res; +#endif + +#if LV_USE_NEMA_VG == 0 && LV_USE_OS == LV_OS_NONE + LV_UNUSED(draw_unit); +#endif + return 0; +} + +#if LV_USE_OS +static void nema_gfx_render_thread_cb(void * ptr) +{ + lv_draw_nema_gfx_unit_t * u = ptr; + + lv_thread_sync_init(&u->sync); + u->inited = true; + + while(1) { + /* Wait for sync if there is no task set. */ + while(u->task_act == NULL) { + if(u->exit_status) + break; + + lv_thread_sync_wait(&u->sync); + } + + if(u->exit_status) { + LV_LOG_INFO("Ready to exit NemaGFX draw thread."); + break; + } + + if(u->task_act) { + nema_gfx_execute_drawing(u); + } + /* Signal the ready state to dispatcher. */ + u->task_act->state = LV_DRAW_TASK_STATE_READY; + /* Cleanup. */ + u->task_act = NULL; + + /* The draw unit is free now. Request a new dispatching as it can get a new task. */ + lv_draw_dispatch_request(); + } + + u->inited = false; + lv_thread_sync_delete(&u->sync); + LV_LOG_INFO("Exit NemaGFX draw thread."); +} +#endif + +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx.h b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx.h new file mode 100644 index 000000000..8197fab28 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx.h @@ -0,0 +1,124 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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. + * + */ + +/** + * @file lv_draw_nema_gfx.h + * + */ + +#ifndef LV_DRAW_NEMA_GFX_H +#define LV_DRAW_NEMA_GFX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_NEMA_GFX + +#include "lv_draw_nema_gfx_utils.h" + +#include "../lv_draw_private.h" +#include "../lv_draw_buf_private.h" +#include "../lv_draw_image_private.h" +#include "../lv_image_decoder_private.h" +#include "../lv_draw_label_private.h" +#include "../lv_draw_mask_private.h" +#include "../lv_draw_rect_private.h" +#include "../lv_draw_triangle_private.h" +#include "../lv_draw_vector_private.h" + +#include "../../misc/lv_area_private.h" + +/********************** + * 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; + nema_cmdlist_t cl; +#if LV_USE_NEMA_VG + NEMA_VG_PAINT_HANDLE paint; + NEMA_VG_GRAD_HANDLE gradient; + NEMA_VG_PATH_HANDLE path; +#endif +} lv_draw_nema_gfx_unit_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_nema_gfx_init(void); + +void lv_draw_nema_gfx_deinit(void); + +void lv_draw_nema_gfx_fill(lv_draw_task_t * t, + const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords); + +void lv_draw_nema_gfx_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc); + +void lv_draw_nema_gfx_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_nema_gfx_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_nema_gfx_label_init(lv_draw_unit_t * draw_unit); + +void lv_draw_nema_gfx_layer(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_area_t * coords); + +void lv_draw_nema_gfx_line(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc); + +void lv_draw_nema_gfx_border(lv_draw_task_t * t, const lv_draw_border_dsc_t * dsc, + const lv_area_t * coords); + +void lv_draw_nema_gfx_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, + const lv_area_t * coords); + + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_NEMA_GFX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_NEMA_GFX_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_arc.c b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_arc.c new file mode 100644 index 000000000..40115acf1 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_arc.c @@ -0,0 +1,105 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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. + * + */ + +/** + * @file lv_draw_nema_gfx_arc.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_nema_gfx.h" + +#if LV_USE_NEMA_GFX && LV_USE_NEMA_VG + +/********************** + * GLOBAL FUNCTIONS + **********************/ +void lv_draw_nema_gfx_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords) +{ + + LV_UNUSED(coords); + + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) + return; + if(dsc->width == 0) + return; + if(dsc->start_angle == dsc->end_angle) + return; + + lv_draw_nema_gfx_unit_t * draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *)t->draw_unit; + + lv_layer_t * layer = t->target_layer; + lv_point_t center = {dsc->center.x - layer->buf_area.x1, dsc->center.y - layer->buf_area.y1}; + + lv_area_t clip_area; + lv_area_copy(&clip_area, &t->clip_area); + lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); + + nema_set_clip(clip_area.x1, clip_area.y1, lv_area_get_width(&clip_area), lv_area_get_height(&clip_area)); + + lv_value_precise_t start_angle = dsc->start_angle; + lv_value_precise_t end_angle = dsc->end_angle; + + if(start_angle >= end_angle) { + end_angle += 360.0f; + } + + if(end_angle - start_angle > 360.0f) { + start_angle = 0.0f; + end_angle = 360.0f; + } + else { + while(end_angle > 360.0f) { + start_angle -= 360.0f; + end_angle -= 360.0f; + } + } + + nema_vg_paint_clear(draw_nema_gfx_unit->paint); + nema_vg_paint_set_type(draw_nema_gfx_unit->paint, NEMA_VG_PAINT_COLOR); + lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa); + uint32_t bg_color = nema_rgba(col32.red, col32.green, col32.blue, col32.alpha); + nema_vg_paint_set_paint_color(draw_nema_gfx_unit->paint, bg_color); // green + nema_vg_paint_set_stroke_width(draw_nema_gfx_unit->paint, dsc->width); + nema_vg_set_blend(NEMA_BL_SRC_OVER | NEMA_BLOP_SRC_PREMULT); + + if(dsc->rounded == 1) { + nema_vg_draw_ring(center.x, center.y, (float)dsc->radius - (float)dsc->width * 0.5f, start_angle, end_angle, + draw_nema_gfx_unit->paint); + } + else { + nema_vg_draw_ring_generic(center.x, center.y, (float)dsc->radius - (float)dsc->width * 0.5f, start_angle, + end_angle, draw_nema_gfx_unit->paint, 0U); + } + + nema_cl_submit(&(draw_nema_gfx_unit->cl)); + +} + +#endif + diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_border.c b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_border.c new file mode 100644 index 000000000..31dec2c4b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_border.c @@ -0,0 +1,226 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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. + * + */ + +/** + * @file lv_draw_nema_gfx_fill.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_nema_gfx.h" + +#if LV_USE_NEMA_GFX +#include + +/********************** + * GLOBAL FUNCTIONS + **********************/ +void lv_draw_nema_gfx_border(lv_draw_task_t * t, 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_nema_gfx_unit_t * draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *)t->draw_unit; + + lv_layer_t * layer = t->target_layer; + lv_area_t inward_coords; + int32_t width = dsc->width; + + /* Move border inwards to align with software rendered border */ + inward_coords.x1 = coords->x1 + ceil(width / 2.0f); + inward_coords.x2 = coords->x2 - floor(width / 2.0f); + inward_coords.y1 = coords->y1 + ceil(width / 2.0f); + inward_coords.y2 = coords->y2 - floor(width / 2.0f); + + lv_area_move(&inward_coords, -layer->buf_area.x1, -layer->buf_area.y1); + + lv_area_t clip_area; + lv_area_copy(&clip_area, &t->clip_area); + lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); + + nema_set_clip(clip_area.x1, clip_area.y1, lv_area_get_width(&clip_area), lv_area_get_height(&clip_area)); + + lv_area_t clipped_coords; + if(!lv_area_intersect(&clipped_coords, &inward_coords, &clip_area)) + return; /*Fully clipped, nothing to do*/ + + lv_color_format_t dst_cf = layer->draw_buf->header.cf; + uint32_t dst_nema_cf = lv_nemagfx_cf_to_nema(dst_cf); + + /* the stride should be computed internally for NEMA_TSC images and images missing a stride value */ + int32_t stride = (dst_cf >= LV_COLOR_FORMAT_NEMA_TSC_START && dst_cf <= LV_COLOR_FORMAT_NEMA_TSC_END) ? + -1 : lv_area_get_width(&(layer->buf_area)) * lv_color_format_get_size(dst_cf); + + nema_bind_dst_tex((uintptr_t)NEMA_VIRT2PHYS(layer->draw_buf->data), lv_area_get_width(&(layer->buf_area)), + lv_area_get_height(&(layer->buf_area)), dst_nema_cf, stride); + + /* Recalculate float Dimensions */ + float x1 = (float)coords->x1 + ((float)width / 2.0f) - (float)layer->buf_area.x1; + float x2 = (float)coords->x2 - ((float)width / 2.0f) - (float)layer->buf_area.x1; + float y1 = (float)coords->y1 + ((float)width / 2.0f) - (float)layer->buf_area.y1; + float y2 = (float)coords->y2 - ((float)width / 2.0f) - (float)layer->buf_area.y1; + float coords_bg_w = x2 - x1 + 1; + float coords_bg_h = y2 - y1 + 1; + int32_t short_side = LV_MIN(coords_bg_w, coords_bg_h); + float radius = (float)LV_MIN(dsc->radius, short_side >> 1); + + lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa); + uint32_t bg_color = nema_rgba(col32.red, col32.green, col32.blue, col32.alpha); + + if(col32.alpha < 255U) { + nema_set_blend_fill(NEMA_BL_SRC_OVER); + bg_color = nema_premultiply_rgba(bg_color); + } + else { + nema_set_blend_fill(NEMA_BL_SRC); + } + + if(radius > 0.0f) { + nema_draw_rounded_rect_aa(x1, y1, coords_bg_w, coords_bg_h, radius, width, bg_color); + } + else { + lv_area_t rect_coords = *coords; + lv_area_move(&rect_coords, -layer->buf_area.x1, -layer->buf_area.y1); + int32_t border_width = lv_area_get_width(&rect_coords); + int32_t border_height = lv_area_get_height(&rect_coords); + + if(dsc->side & LV_BORDER_SIDE_TOP) { + float x = rect_coords.x1 + width; + float y = rect_coords.y1; + float w = border_width - 2 * width; + float h = width; + nema_enable_aa(1, 0, 1, 0); + nema_fill_rect_f(x, y, w, h, bg_color); + } + + if(dsc->side & LV_BORDER_SIDE_BOTTOM) { + float x = rect_coords.x1 + width; + float y = rect_coords.y1 + border_height - width; + float w = border_width - 2 * width; + float h = width; + nema_enable_aa(1, 0, 1, 0); + nema_fill_rect_f(x, y, w, h, bg_color); + } + + if(dsc->side & LV_BORDER_SIDE_LEFT) { + float x = rect_coords.x1; + float y = rect_coords.y1 + width; + float w = width; + float h = border_height - 2 * width; + nema_enable_aa(0, 1, 0, 1); + nema_fill_rect_f(x, y, w, h, bg_color); + } + + if(dsc->side & LV_BORDER_SIDE_RIGHT) { + float x = rect_coords.x1 + border_width - width; + float y = rect_coords.y1 + width; + float w = width; + float h = border_height - 2 * width; + nema_enable_aa(0, 1, 0, 1); + nema_fill_rect_f(x, y, w, h, bg_color); + } + + /*Draw small corner rectangles + Top Left*/ + if(dsc->side & LV_BORDER_SIDE_TOP || dsc->side & LV_BORDER_SIDE_LEFT) { + float x = rect_coords.x1; + float y = rect_coords.y1; + float w = width; + float h = width; + + if(!(dsc->side & LV_BORDER_SIDE_TOP)) + nema_enable_aa(1, 1, 0, 1); + else if(!(dsc->side & LV_BORDER_SIDE_LEFT)) + nema_enable_aa(1, 0, 1, 1); + else + nema_enable_aa(1, 0, 0, 1); + + nema_fill_rect_f(x, y, w, h, bg_color); + } + + /*Top Right*/ + if(dsc->side & LV_BORDER_SIDE_TOP || dsc->side & LV_BORDER_SIDE_RIGHT) { + float x = rect_coords.x1 + border_width - width; + float y = rect_coords.y1; + float w = width; + float h = width; + + if(!(dsc->side & LV_BORDER_SIDE_TOP)) + nema_enable_aa(1, 1, 0, 1); + else if(!(dsc->side & LV_BORDER_SIDE_RIGHT)) + nema_enable_aa(1, 1, 1, 0); + else + nema_enable_aa(1, 1, 0, 0); + + nema_fill_rect_f(x, y, w, h, bg_color); + } + + /*Bottom Right*/ + if(dsc->side & LV_BORDER_SIDE_BOTTOM || dsc->side & LV_BORDER_SIDE_RIGHT) { + float x = rect_coords.x1 + border_width - width; + float y = rect_coords.y1 + border_height - width; + float w = width; + float h = width; + + if(!(dsc->side & LV_BORDER_SIDE_BOTTOM)) + nema_enable_aa(0, 1, 1, 1); + else if(!(dsc->side & LV_BORDER_SIDE_RIGHT)) + nema_enable_aa(1, 1, 1, 0); + else + nema_enable_aa(0, 1, 1, 0); + + nema_fill_rect_f(x, y, w, h, bg_color); + } + + /*Bottom Left*/ + if(dsc->side & LV_BORDER_SIDE_BOTTOM || dsc->side & LV_BORDER_SIDE_LEFT) { + float x = rect_coords.x1; + float y = rect_coords.y1 + border_height - width; + float w = width; + float h = width; + + if(!(dsc->side & LV_BORDER_SIDE_BOTTOM)) + nema_enable_aa(0, 1, 1, 1); + else if(!(dsc->side & LV_BORDER_SIDE_LEFT)) + nema_enable_aa(1, 0, 1, 1); + else + nema_enable_aa(0, 0, 1, 1); + + nema_fill_rect_f(x, y, w, h, bg_color); + } + + } + + nema_cl_submit(&(draw_nema_gfx_unit->cl)); + +} +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_fill.c b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_fill.c new file mode 100644 index 000000000..6199abf35 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_fill.c @@ -0,0 +1,149 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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. + * + */ + +/** + * @file lv_draw_nema_gfx_fill.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_nema_gfx.h" + +#if LV_USE_NEMA_GFX + +/********************** + * GLOBAL FUNCTIONS + **********************/ +void lv_draw_nema_gfx_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords) +{ + if(dsc->opa <= LV_OPA_MIN) return; + + lv_draw_nema_gfx_unit_t * draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *)t->draw_unit; + + lv_layer_t * layer = t->target_layer; + lv_area_t rel_coords; + lv_area_copy(&rel_coords, coords); + lv_area_move(&rel_coords, -layer->buf_area.x1, -layer->buf_area.y1); + + lv_area_t rel_clip_area; + lv_area_copy(&rel_clip_area, &t->clip_area); + lv_area_move(&rel_clip_area, -layer->buf_area.x1, -layer->buf_area.y1); + + nema_set_clip(rel_clip_area.x1, rel_clip_area.y1, lv_area_get_width(&rel_clip_area), + lv_area_get_height(&rel_clip_area)); + + lv_area_t clipped_coords; + if(!lv_area_intersect(&clipped_coords, &rel_coords, &rel_clip_area)) + return; /*Fully clipped, nothing to do*/ + + lv_color_format_t dst_cf = layer->draw_buf->header.cf; + uint32_t dst_nema_cf = lv_nemagfx_cf_to_nema(dst_cf); + + /* the stride should be computed internally for NEMA_TSC images and images missing a stride value */ + int32_t stride = (dst_cf >= LV_COLOR_FORMAT_NEMA_TSC_START && dst_cf <= LV_COLOR_FORMAT_NEMA_TSC_END) ? + -1 : lv_area_get_width(&(layer->buf_area)) * lv_color_format_get_size(dst_cf); + + nema_bind_dst_tex((uintptr_t)NEMA_VIRT2PHYS(layer->draw_buf->data), lv_area_get_width(&(layer->buf_area)), + lv_area_get_height(&(layer->buf_area)), dst_nema_cf, stride); + + int32_t coords_bg_w = lv_area_get_width(&rel_coords); + int32_t coords_bg_h = lv_area_get_height(&rel_coords); + int32_t short_side = LV_MIN(coords_bg_w, coords_bg_h); + int32_t radius = LV_MIN(dsc->radius, short_side >> 1); + + if((dsc->grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_NONE)) { + + lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa); + uint32_t bg_color = nema_rgba(col32.red, col32.green, col32.blue, col32.alpha); + + if(col32.alpha < 255U) { + nema_set_blend_fill(NEMA_BL_SRC_OVER); + bg_color = nema_premultiply_rgba(bg_color); + } + else { + nema_set_blend_fill(NEMA_BL_SRC); + } + + if(radius > 0.f) + nema_fill_rounded_rect_aa(rel_coords.x1, rel_coords.y1, coords_bg_w, coords_bg_h, radius, bg_color); + else + nema_fill_rect(rel_coords.x1, rel_coords.y1, coords_bg_w, coords_bg_h, bg_color); + } +#if LV_USE_NEMA_VG + else { + + nema_vg_paint_clear(draw_nema_gfx_unit->paint); + + nema_vg_paint_set_type(draw_nema_gfx_unit->paint, NEMA_VG_PAINT_GRAD_LINEAR); + nema_vg_set_blend(NEMA_BL_SRC_OVER | NEMA_BLOP_SRC_PREMULT); + + float stops[LV_GRADIENT_MAX_STOPS]; + color_var_t colors[LV_GRADIENT_MAX_STOPS]; + + uint32_t cnt = LV_MAX(dsc->grad.stops_count, LV_GRADIENT_MAX_STOPS); + + for(uint8_t i = 0; i < cnt; i++) { + stops[i] = (float)(dsc->grad.stops[i].frac) / 255.f; + colors[i].a = LV_OPA_MIX2(dsc->grad.stops[i].opa, dsc->opa); + colors[i].r = dsc->grad.stops[i].color.red; + colors[i].g = dsc->grad.stops[i].color.green; + colors[i].b = dsc->grad.stops[i].color.blue; + } + + nema_vg_grad_set(draw_nema_gfx_unit->gradient, cnt, stops, colors); + + float x0, y0, x1, y1; + + if(dsc->grad.dir == LV_GRAD_DIR_HOR) { + x0 = rel_coords.x1; + x1 = rel_coords.x2; + y0 = rel_coords.y1; + y1 = rel_coords.y1; + } + else { + x0 = rel_coords.x1; + x1 = rel_coords.x1; + y0 = rel_coords.y1; + y1 = rel_coords.y2; + } + + nema_vg_paint_set_grad_linear(draw_nema_gfx_unit->paint, draw_nema_gfx_unit->gradient, x0, y0, x1, y1, + NEMA_TEX_CLAMP | NEMA_FILTER_BL); + + if(radius > 0.f) + nema_vg_draw_rounded_rect(rel_coords.x1, rel_coords.y1, coords_bg_w, coords_bg_h, radius, radius, NULL, + draw_nema_gfx_unit->paint); + else + nema_vg_draw_rect(rel_coords.x1, rel_coords.y1, coords_bg_w, coords_bg_h, NULL, draw_nema_gfx_unit->paint); + } +#endif + + nema_cl_submit(&(draw_nema_gfx_unit->cl)); + +} +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_img.c b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_img.c new file mode 100644 index 000000000..88437806c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_img.c @@ -0,0 +1,283 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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. + * + */ + +/** + * @file lv_draw_nema_gfx_fill.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_nema_gfx.h" + +#if LV_USE_NEMA_GFX + + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void _draw_nema_gfx_tile(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords); + +static void _draw_nema_gfx_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords); + +static uint32_t lv_nemagfx_mask_cf_to_nema(lv_color_format_t cf); + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void _draw_nema_gfx_tile(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords) +{ + + lv_image_decoder_dsc_t decoder_dsc; + lv_result_t res = lv_image_decoder_open(&decoder_dsc, dsc->src, NULL); + if(res != LV_RESULT_OK) { + LV_LOG_ERROR("Failed to open image"); + return; + } + + int32_t img_w = dsc->header.w; + int32_t img_h = dsc->header.h; + + lv_area_t tile_area; + if(lv_area_get_width(&dsc->image_area) >= 0) { + tile_area = dsc->image_area; + } + else { + tile_area = *coords; + } + lv_area_set_width(&tile_area, img_w); + lv_area_set_height(&tile_area, img_h); + + int32_t tile_x_start = tile_area.x1; + + while(tile_area.y1 <= t->clip_area.y2) { + while(tile_area.x1 <= t->clip_area.x2) { + + lv_area_t clipped_img_area; + if(lv_area_intersect(&clipped_img_area, &tile_area, &t->clip_area)) { + _draw_nema_gfx_img(t, dsc, &tile_area); + } + + tile_area.x1 += img_w; + tile_area.x2 += img_w; + } + + tile_area.y1 += img_h; + tile_area.y2 += img_h; + tile_area.x1 = tile_x_start; + tile_area.x2 = tile_x_start + img_w - 1; + } + + lv_image_decoder_close(&decoder_dsc); +} + +static void _draw_nema_gfx_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords) +{ + if(dsc->opa <= LV_OPA_MIN) return; + + lv_draw_nema_gfx_unit_t * draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *)t->draw_unit; + + lv_layer_t * layer = t->target_layer; + const lv_image_dsc_t * img_dsc = dsc->src; + + bool masked = dsc->bitmap_mask_src != NULL; + + lv_area_t blend_area; + /*Let's get the blend area which is the intersection of the area to fill and the clip area.*/ + if(!lv_area_intersect(&blend_area, coords, &t->clip_area)) + return; /*Fully clipped, nothing to do*/ + + lv_area_t rel_clip_area; + lv_area_copy(&rel_clip_area, &t->clip_area); + lv_area_move(&rel_clip_area, -layer->buf_area.x1, -layer->buf_area.y1); + + bool has_transform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE); + bool recolor = (dsc->recolor_opa > LV_OPA_MIN); + + /*Make the blend area relative to the buffer*/ + lv_area_move(&blend_area, -layer->buf_area.x1, -layer->buf_area.y1); + + uint32_t tex_w = lv_area_get_width(coords); + uint32_t tex_h = lv_area_get_height(coords); + + nema_set_clip(rel_clip_area.x1, rel_clip_area.y1, lv_area_get_width(&rel_clip_area), + lv_area_get_height(&rel_clip_area)); + + lv_color_format_t dst_cf = layer->draw_buf->header.cf; + uint32_t dst_nema_cf = lv_nemagfx_cf_to_nema(dst_cf); + + const void * src_buf = img_dsc->data; + + uint32_t blending_mode = lv_nemagfx_blending_mode(dsc->blend_mode); + + lv_color_format_t src_cf = img_dsc->header.cf; + + /*Image contains Alpha*/ + if(src_cf == LV_COLOR_FORMAT_ARGB8888 || src_cf == LV_COLOR_FORMAT_XRGB8888) { + blending_mode |= NEMA_BLOP_SRC_PREMULT; + } + + uint32_t src_nema_cf = lv_nemagfx_cf_to_nema(src_cf); + /* the stride should be computed internally for NEMA_TSC images and images missing a stride value */ + int32_t src_stride = (src_cf >= LV_COLOR_FORMAT_NEMA_TSC_START && src_cf <= LV_COLOR_FORMAT_NEMA_TSC_END) + || img_dsc->header.stride == 0 ? -1 : (int32_t)img_dsc->header.stride; + + int32_t stride = (dst_cf >= LV_COLOR_FORMAT_NEMA_TSC_START && dst_cf <= LV_COLOR_FORMAT_NEMA_TSC_END) ? + -1 : lv_area_get_width(&(layer->buf_area)) * lv_color_format_get_size(dst_cf); + + nema_bind_dst_tex((uintptr_t)NEMA_VIRT2PHYS(layer->draw_buf->data), lv_area_get_width(&(layer->buf_area)), + lv_area_get_height(&(layer->buf_area)), dst_nema_cf, stride); + + if(!LV_COLOR_FORMAT_IS_INDEXED(src_cf)) { + nema_bind_src_tex((uintptr_t)(src_buf), tex_w, tex_h, src_nema_cf, src_stride, + dsc->antialias ? NEMA_FILTER_BL : NEMA_FILTER_PS); + } + else { + nema_bind_lut_tex((uintptr_t)((uint8_t *)src_buf + LV_COLOR_INDEXED_PALETTE_SIZE(src_cf) * 4), tex_w, tex_h, + src_nema_cf, src_stride, NEMA_FILTER_PS, (uintptr_t)(src_buf), NEMA_BGRA8888); + blending_mode |= NEMA_BLOP_LUT; + } + + /*Guard for previous NemaGFX Version*/ +#ifdef NEMA_BLOP_RECOLOR + if(recolor) { + lv_color32_t col32 = lv_color_to_32(dsc->recolor, LV_OPA_MIX2(dsc->recolor_opa, dsc->opa)); + uint32_t color = nema_rgba(col32.red, col32.green, col32.blue, col32.alpha); + nema_set_recolor_color(color); + blending_mode |= NEMA_BLOP_RECOLOR; + } +#endif + + if(dsc->opa < 255) { + uint32_t rgba = ((uint32_t)dsc->opa << 24U) | ((uint32_t)dsc->opa << 16U) | ((uint32_t)dsc->opa << 8U) | (( + uint32_t)dsc->opa); + nema_set_const_color(rgba); + blending_mode |= NEMA_BLOP_MODULATE_A; + } + + if(!has_transform && masked && !recolor) { + if(dsc->bitmap_mask_src->header.cf == LV_COLOR_FORMAT_A8 || dsc->bitmap_mask_src->header.cf == LV_COLOR_FORMAT_L8) { + blending_mode |= NEMA_BLOP_STENCIL_TXTY; + const lv_image_dsc_t * mask = dsc->bitmap_mask_src; + const void * mask_buf = mask->data; + + const lv_area_t * image_area; + lv_area_t mask_area; + if(lv_area_get_width(&dsc->image_area) < 0) image_area = coords; + else image_area = &dsc->image_area; + + lv_area_set(&mask_area, 0, 0, dsc->bitmap_mask_src->header.w - 1, dsc->bitmap_mask_src->header.h - 1); + lv_area_align(image_area, &mask_area, LV_ALIGN_CENTER, 0, 0); + + mask_buf += dsc->bitmap_mask_src->header.w * (coords->y1 - mask_area.y1) + (coords->x1 - mask_area.x1); + + nema_bind_tex(NEMA_TEX3, (uintptr_t)NEMA_VIRT2PHYS(mask_buf), mask->header.w, mask->header.h, + lv_nemagfx_mask_cf_to_nema(mask->header.cf), + mask->header.stride, NEMA_FILTER_BL); + } + } + + nema_set_blend_blit(blending_mode); + + if(!has_transform) { + nema_blit_rect((coords->x1 - layer->buf_area.x1), + (coords->y1 - layer->buf_area.y1), tex_w, tex_h); + } + else { + /*Calculate the transformed points*/ + float x0 = (coords->x1 - layer->buf_area.x1); + float y0 = (coords->y1 - layer->buf_area.y1); + float x1 = x0 + tex_w ; + float y1 = y0; + float x2 = x0 + tex_w ; + float y2 = y0 + tex_h; + float x3 = x0 ; + float y3 = y0 + tex_h; + + nema_matrix3x3_t m; + nema_mat3x3_load_identity(m); + nema_mat3x3_translate(m, -x0, -y0); + nema_mat3x3_translate(m, -(float)dsc->pivot.x, -(float)dsc->pivot.y); + nema_mat3x3_rotate(m, (dsc->rotation / 10.0f)); /* angle is 1/10 degree */ + float scale_x = 1.f * dsc->scale_x / LV_SCALE_NONE; + float scale_y = 1.f * dsc->scale_y / LV_SCALE_NONE; + nema_mat3x3_scale(m, (float)scale_x, (float)scale_y); + nema_mat3x3_translate(m, (float)dsc->pivot.x, (float)dsc->pivot.y); + nema_mat3x3_translate(m, x0, y0); + + /*Apply Transformation Matrix to Vertices*/ + nema_mat3x3_mul_vec(m, &x0, &y0); + nema_mat3x3_mul_vec(m, &x1, &y1); + nema_mat3x3_mul_vec(m, &x2, &y2); + nema_mat3x3_mul_vec(m, &x3, &y3); + + nema_blit_quad_fit(x0, y0, + x1, y1, + x2, y2, + x3, y3); + } + + nema_cl_submit(&(draw_nema_gfx_unit->cl)); + +} + +/*NemaGFX does mask operations with A8,A4,A2 and A1 formats*/ +static uint32_t lv_nemagfx_mask_cf_to_nema(lv_color_format_t cf) +{ + switch(cf) { + case LV_COLOR_FORMAT_A1: + return NEMA_A1; + case LV_COLOR_FORMAT_A2: + return NEMA_A2; + case LV_COLOR_FORMAT_A4: + return NEMA_A4; + case LV_COLOR_FORMAT_A8: + case LV_COLOR_FORMAT_L8: + default: + break; + } + + return NEMA_A8; +} + +/********************** + * GLOBAL FUNCTIONS + **********************/ +void lv_draw_nema_gfx_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords) +{ + + if(!dsc->tile) { + _draw_nema_gfx_img(t, dsc, coords); + } + else { + _draw_nema_gfx_tile(t, dsc, coords); + } + +} +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_label.c b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_label.c new file mode 100644 index 000000000..9275fe2cf --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_label.c @@ -0,0 +1,850 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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. + * + */ + +/** + * @file lv_draw_nema_gfx_fill.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_nema_gfx.h" + +#if LV_USE_NEMA_GFX +#include "../../misc/lv_utils.h" +#include "../../misc/lv_bidi_private.h" +#include "../../misc/lv_text_private.h" +#include "../../lvgl.h" +#include "../../libs/freetype/lv_freetype_private.h" +#include "../../core/lv_global.h" + +/********************* + * DEFINES + *********************/ +#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 FT_F26DOT6_SHIFT 6 +#define NEMA_COORD_LIMIT 2046 + +#define font_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->font_draw_buf_handlers) + +/** After converting the font reference size, it is also necessary to scale the 26dot6 data + * in the path to the real physical size + */ +#define FT_F26DOT6_TO_PATH_SCALE(x) (LV_FREETYPE_F26DOT6_TO_FLOAT(x) / (1 << FT_F26DOT6_SHIFT)) + +/*Forward declarations*/ +void nema_set_matrix(nema_matrix3x3_t m); +void nema_raster_rect(int x, int y, int w, int h); + +/********************** + * TYPEDEFS + **********************/ +enum { + RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER, + RECOLOR_CMD_STATE_PARAMETER, + RECOLOR_CMD_STATE_TEXT_INPUT, +}; +typedef unsigned char cmd_state_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void _draw_nema_gfx_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, + lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area); + +static void _draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, + const lv_area_t * coords); + +static inline uint8_t _bpp_nema_gfx_format(lv_draw_glyph_dsc_t * glyph_draw_dsc); + +static void _draw_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * dsc, const lv_point_t * pos, + const lv_font_t * font, uint32_t letter); + +static uint8_t hex_char_to_num(char hex); + +static bool is_raw_bitmap; + +#if LV_USE_FREETYPE && LV_USE_NEMA_VG + + #include "lv_nema_gfx_path.h" + + static void _draw_nema_gfx_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc); + + static void freetype_outline_event_cb(lv_event_t * e); + + static void lv_nema_gfx_outline_push(const lv_freetype_outline_event_param_t * param); + + static void lv_nema_outline_event_alloc(const lv_freetype_outline_event_param_t * param); +#endif + +/********************** + * GLOBAL FUNCTIONS + **********************/ +void lv_draw_nema_gfx_label_init(lv_draw_unit_t * draw_unit) +{ +#if LV_USE_FREETYPE + /*Set up the freetype outline event*/ + lv_freetype_outline_add_event(freetype_outline_event_cb, LV_EVENT_ALL, draw_unit); +#else + LV_UNUSED(draw_unit); +#endif /* LV_USE_FREETYPE */ +} + +void lv_draw_nema_gfx_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords) +{ + if(dsc->opa <= LV_OPA_MIN) return; + + lv_layer_t * layer = t->target_layer; + + lv_area_t clip_area; + lv_area_copy(&clip_area, &t->clip_area); + lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); + + lv_color_format_t dst_cf = layer->draw_buf->header.cf; + uint32_t dst_nema_cf = lv_nemagfx_cf_to_nema(dst_cf); + + int32_t stride = (dst_cf >= LV_COLOR_FORMAT_NEMA_TSC_START && dst_cf <= LV_COLOR_FORMAT_NEMA_TSC_END) ? + -1 : lv_area_get_width(&(layer->buf_area)) * lv_color_format_get_size(dst_cf); + + nema_bind_dst_tex((uintptr_t)NEMA_VIRT2PHYS(layer->draw_buf->data), lv_area_get_width(&(layer->buf_area)), + lv_area_get_height(&(layer->buf_area)), dst_nema_cf, stride); + + nema_set_clip(clip_area.x1, clip_area.y1, lv_area_get_width(&clip_area), lv_area_get_height(&clip_area)); + + _draw_label_iterate_characters(t, dsc, coords); + + lv_draw_nema_gfx_unit_t * draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *)t->draw_unit; + nema_cl_submit(&(draw_nema_gfx_unit->cl)); + nema_cl_wait(&(draw_nema_gfx_unit->cl)); +} + +/********************** + * STATIC FUNCTIONS + **********************/ +#if LV_USE_FREETYPE && LV_USE_NEMA_VG + +static void _draw_nema_gfx_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc) +{ + + lv_area_t blend_area; + if(!_lv_area_intersect(&blend_area, glyph_draw_dsc->letter_coords, &t->clip_area)) + return; + + lv_draw_nema_gfx_unit_t * draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *)t->draw_unit; + + lv_nema_gfx_path_t * nema_gfx_path = (lv_nema_gfx_path_t *)glyph_draw_dsc->glyph_data; + + lv_point_t pos = {glyph_draw_dsc->letter_coords->x1, glyph_draw_dsc->letter_coords->y1}; + + float scale = FT_F26DOT6_TO_PATH_SCALE(lv_freetype_outline_get_scale(glyph_draw_dsc->g->resolved_font)); + + /*Calculate Path Matrix*/ + nema_matrix3x3_t matrix; + nema_mat3x3_load_identity(matrix); + nema_mat3x3_scale(matrix, scale, -scale); + nema_mat3x3_translate(matrix, pos.x - glyph_draw_dsc->g->ofs_x, + pos.y + glyph_draw_dsc->g->box_h + glyph_draw_dsc->g->ofs_y); + + nema_vg_path_clear(nema_gfx_path->path); + nema_vg_paint_clear(nema_gfx_path->paint); + + nema_vg_set_fill_rule(NEMA_VG_FILL_EVEN_ODD); + + nema_vg_path_set_shape(nema_gfx_path->path, nema_gfx_path->seg_size, nema_gfx_path->seg, nema_gfx_path->data_size, + nema_gfx_path->data); + + nema_vg_paint_set_type(nema_gfx_path->paint, NEMA_VG_PAINT_COLOR); + + lv_color32_t dsc_col32 = lv_color_to_32(glyph_draw_dsc->color, glyph_draw_dsc->opa); + uint32_t nema_dsc_color = nema_rgba(dsc_col32.red, dsc_col32.green, dsc_col32.blue, dsc_col32.alpha); + + nema_vg_paint_set_paint_color(nema_gfx_path->paint, nema_dsc_color); + + nema_vg_path_set_matrix(nema_gfx_path->path, matrix); + nema_vg_draw_path(nema_gfx_path->path, nema_gfx_path->paint); + + return; +} + +static void freetype_outline_event_cb(lv_event_t * e) +{ + LV_PROFILER_DRAW_BEGIN; + lv_event_code_t code = lv_event_get_code(e); + lv_freetype_outline_event_param_t * param = lv_event_get_param(e); + + switch(code) { + case LV_EVENT_CREATE: + param->outline = lv_nema_gfx_path_create(); + lv_nema_outline_event_alloc(param); + break; + case LV_EVENT_DELETE: + lv_nema_gfx_path_destroy(param->outline); + break; + case LV_EVENT_INSERT: + lv_nema_gfx_outline_push(param); + break; + default: + LV_LOG_WARN("unknown event code: %d", code); + break; + } + LV_PROFILER_DRAW_END; +} + +static void lv_nema_gfx_outline_push(const lv_freetype_outline_event_param_t * param) +{ + LV_PROFILER_DRAW_BEGIN; + lv_nema_gfx_path_t * outline = param->outline; + LV_ASSERT_NULL(outline); + + lv_freetype_outline_type_t type = param->type; + switch(type) { + case LV_FREETYPE_OUTLINE_END: + lv_nema_gfx_path_end(outline); + break; + case LV_FREETYPE_OUTLINE_MOVE_TO: + lv_nema_gfx_path_move_to(outline, param->to.x, param->to.y); + break; + case LV_FREETYPE_OUTLINE_LINE_TO: + lv_nema_gfx_path_line_to(outline, param->to.x, param->to.y); + break; + case LV_FREETYPE_OUTLINE_CUBIC_TO: + lv_nema_gfx_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_nema_gfx_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); + LV_ASSERT(false); + break; + } + LV_PROFILER_DRAW_END; +} + +static void lv_nema_outline_event_alloc(const lv_freetype_outline_event_param_t * param) +{ + lv_nema_gfx_path_t * outline = param->outline; + outline->data_size = param->sizes.data_size; + outline->seg_size = param->sizes.segments_size; + lv_nema_gfx_path_alloc(outline); +} + +#endif /* LV_USE_FREETYPE && LV_USE_NEMA_VG */ + +/** + * Convert a hexadecimal characters to a number (0..15) + * @param hex Pointer to a hexadecimal character (0..9, A..F) + * @return the numerical value of `hex` or 0 on error + */ +static uint8_t hex_char_to_num(char hex) +{ + if(hex >= '0' && hex <= '9') return hex - '0'; + if(hex >= 'a') hex -= 'a' - 'A'; /*Convert to upper case*/ + return 'A' <= hex && hex <= 'F' ? hex - 'A' + 10 : 0; +} + + +static inline uint8_t _bpp_nema_gfx_format(lv_draw_glyph_dsc_t * glyph_draw_dsc) +{ + uint32_t format = glyph_draw_dsc->g->format; + + switch(format) { + case LV_FONT_GLYPH_FORMAT_A1: + return NEMA_A1; + case LV_FONT_GLYPH_FORMAT_A2: + return NEMA_A2; + case LV_FONT_GLYPH_FORMAT_A4: + return NEMA_A4; + case LV_FONT_GLYPH_FORMAT_A8: + default: + return NEMA_A8; + } +} + +static void _draw_nema_gfx_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, + lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area) +{ + if(glyph_draw_dsc) { + if(glyph_draw_dsc->format == LV_FONT_GLYPH_FORMAT_NONE) { +#if LV_USE_FONT_PLACEHOLDER + /* 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_nema_gfx_border(t, &border_draw_dsc, glyph_draw_dsc->bg_coords); +#endif + } + else if(glyph_draw_dsc->format >= LV_FONT_GLYPH_FORMAT_A1 && + glyph_draw_dsc->format <= LV_FONT_GLYPH_FORMAT_A8) { + /*Do not draw transparent things*/ + if(glyph_draw_dsc->opa <= LV_OPA_MIN) + return; + + lv_layer_t * layer = t->target_layer; + + lv_area_t blend_area; + if(!lv_area_intersect(&blend_area, glyph_draw_dsc->letter_coords, &t->clip_area)) + return; + + const lv_draw_buf_t * draw_buf = glyph_draw_dsc->glyph_data; + const void * mask_buf; + uint32_t src_cf; + lv_area_t mask_area = *glyph_draw_dsc->letter_coords; + + lv_area_t rel_coords; + lv_area_copy(&rel_coords, &blend_area); + lv_area_move(&rel_coords, -layer->buf_area.x1, -layer->buf_area.y1); + + int32_t x, y, w, h; + + /*Read the static font*/ + if(is_raw_bitmap) { + mask_buf = glyph_draw_dsc->glyph_data; + src_cf = _bpp_nema_gfx_format(glyph_draw_dsc); + x = glyph_draw_dsc->letter_coords->x1 - layer->buf_area.x1; + y = glyph_draw_dsc->letter_coords->y1 - layer->buf_area.y1; + w = glyph_draw_dsc->g->box_w; + h = glyph_draw_dsc->g->box_h; + } + /*Read the draw buffer*/ + else { + mask_buf = draw_buf->data; + src_cf = lv_nemagfx_cf_to_nema(draw_buf->header.cf); + mask_area.x2 = mask_area.x1 + lv_draw_buf_width_to_stride(lv_area_get_width(&mask_area), LV_COLOR_FORMAT_A8) - 1; + mask_buf += draw_buf->header.stride * (blend_area.y1 - mask_area.y1) + (blend_area.x1 - mask_area.x1); + x = rel_coords.x1; + y = rel_coords.y1; + w = lv_area_get_width(&rel_coords); + h = lv_area_get_height(&rel_coords); + } + + if(is_raw_bitmap && (glyph_draw_dsc->format <= LV_FONT_GLYPH_FORMAT_A4)) { + nema_bind_src_tex((uintptr_t)(mask_buf), w * h, 1, src_cf, glyph_draw_dsc->g->stride, NEMA_FILTER_PS); + nema_matrix3x3_t m = { + {1, w, -x - (y * w) - (0.5 * w)}, + {0, 1, 0}, + {0, 0, 1} + }; + nema_set_matrix(m); + nema_raster_rect(x, y, w, h); + } + else { + nema_bind_src_tex((uintptr_t)(mask_buf), lv_area_get_width(&mask_area), lv_area_get_height(&mask_area), src_cf, + glyph_draw_dsc->g->stride ? glyph_draw_dsc->g->stride : lv_area_get_width(&mask_area), + NEMA_FILTER_BL); + nema_blit_rect(x, y, w, h); + lv_draw_nema_gfx_unit_t * draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *)t->draw_unit; + nema_cl_submit(&(draw_nema_gfx_unit->cl)); + nema_cl_wait(&(draw_nema_gfx_unit->cl)); + } + } + else if(glyph_draw_dsc->format == 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; + img_dsc.opa = glyph_draw_dsc->opa; + img_dsc.src = glyph_draw_dsc->glyph_data; + lv_draw_nema_gfx_img(t, &img_dsc, glyph_draw_dsc->letter_coords); +#endif + } + +#if LV_USE_FREETYPE && LV_USE_NEMA_VG + else if(glyph_draw_dsc->format == LV_FONT_GLYPH_FORMAT_VECTOR) { + if(lv_freetype_is_outline_font(glyph_draw_dsc->g->resolved_font)) { + _draw_nema_gfx_outline(t, glyph_draw_dsc); + } + } +#endif + + } + + if(fill_draw_dsc && fill_area) { + lv_draw_nema_gfx_fill(t, fill_draw_dsc, fill_area); + } + +} + +static inline void _set_color_blend(uint32_t color, uint8_t alpha) +{ + nema_set_tex_color(color); + + if(alpha < 255U) { + nema_set_blend_blit(NEMA_BL_SIMPLE | NEMA_BLOP_MODULATE_A); + nema_set_const_color(color); + } + else { + nema_set_blend_blit(NEMA_BL_SIMPLE); + } +} + +static void _draw_label_iterate_characters(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, + const lv_area_t * coords) +{ + const lv_font_t * font = dsc->font; + int32_t w; + + lv_area_t clipped_area; + bool clip_ok = lv_area_intersect(&clipped_area, coords, &t->clip_area); + if(!clip_ok) return; + + lv_text_align_t align = dsc->align; + lv_base_dir_t base_dir = dsc->bidi_dir; + + lv_bidi_calculate_align(&align, &base_dir, dsc->text); + + if((dsc->flag & LV_TEXT_FLAG_EXPAND) == 0) { + /*Normally use the label's width as width*/ + w = lv_area_get_width(coords); + } + else { + /*If EXPAND is enabled then not limit the text's width to the object's width*/ + lv_point_t p; + lv_text_get_size(&p, dsc->text, dsc->font, dsc->letter_space, dsc->line_space, LV_COORD_MAX, + dsc->flag); + w = p.x; + } + + int32_t line_height_font = lv_font_get_line_height(font); + int32_t line_height = line_height_font + dsc->line_space; + + /*Init variables for the first line*/ + int32_t line_width = 0; + lv_point_t pos; + lv_point_set(&pos, coords->x1, coords->y1); + + int32_t x_ofs = 0; + int32_t y_ofs = 0; + x_ofs = dsc->ofs_x; + y_ofs = dsc->ofs_y; + pos.y += y_ofs; + + uint32_t line_start = 0; + int32_t last_line_start = -1; + + /*Check the hint to use the cached info*/ + if(dsc->hint && y_ofs == 0 && coords->y1 < 0) { + /*If the label changed too much recalculate the hint.*/ + if(LV_ABS(dsc->hint->coord_y - coords->y1) > LV_LABEL_HINT_UPDATE_TH - 2 * line_height) { + dsc->hint->line_start = -1; + } + last_line_start = dsc->hint->line_start; + } + + /*Use the hint if it's valid*/ + if(dsc->hint && last_line_start >= 0) { + line_start = last_line_start; + pos.y += dsc->hint->y; + } + + uint32_t remaining_len = dsc->text_length; + + uint32_t line_end = line_start + lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, dsc->letter_space, + w, NULL, dsc->flag); + + /*Go the first visible line*/ + while(pos.y + line_height_font < t->clip_area.y1) { + /*Go to next line*/ + line_start = line_end; + line_end += lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, dsc->letter_space, w, NULL, dsc->flag); + pos.y += line_height; + + /*Save at the threshold coordinate*/ + if(dsc->hint && pos.y >= -LV_LABEL_HINT_UPDATE_TH && dsc->hint->line_start < 0) { + dsc->hint->line_start = line_start; + dsc->hint->y = pos.y - coords->y1; + dsc->hint->coord_y = coords->y1; + } + + if(dsc->text[line_start] == '\0') return; + } + + /*Align to middle*/ + if(align == LV_TEXT_ALIGN_CENTER) { + line_width = lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, + dsc->flag); + + pos.x += (lv_area_get_width(coords) - line_width) / 2; + + } + /*Align to the right*/ + else if(align == LV_TEXT_ALIGN_RIGHT) { + line_width = lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, + dsc->flag); + pos.x += lv_area_get_width(coords) - line_width; + } + + uint32_t sel_start = dsc->sel_start; + uint32_t sel_end = dsc->sel_end; + if(sel_start > sel_end) { + uint32_t tmp = sel_start; + sel_start = sel_end; + sel_end = tmp; + } + + lv_area_t bg_coords; + lv_draw_glyph_dsc_t draw_letter_dsc; + lv_draw_glyph_dsc_init(&draw_letter_dsc); + draw_letter_dsc.opa = dsc->opa; + draw_letter_dsc.bg_coords = &bg_coords; + draw_letter_dsc.color = dsc->color; + draw_letter_dsc.rotation = dsc->rotation; + + lv_draw_fill_dsc_t fill_dsc; + lv_draw_fill_dsc_init(&fill_dsc); + fill_dsc.opa = dsc->opa; + int32_t underline_width = font->underline_thickness ? font->underline_thickness : 1; + int32_t line_start_x; + uint32_t next_char_offset; + uint32_t recolor_command_start_index = 0; + int32_t letter_w; + cmd_state_t recolor_cmd_state = RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER; + lv_color_t recolor = lv_color_black(); /* Holds the selected color inside the recolor command */ + uint8_t is_first_space_after_cmd = 0; + + lv_color32_t dsc_col32 = lv_color_to_32(dsc->color, dsc->opa); + uint32_t nema_dsc_color = nema_rgba(dsc_col32.red, dsc_col32.green, dsc_col32.blue, dsc_col32.alpha); + lv_color32_t dsc_sel_col32 = lv_color_to_32(dsc->sel_color, dsc->opa); + uint32_t nema_dsc_sel_color = nema_rgba(dsc_sel_col32.red, dsc_sel_col32.green, dsc_sel_col32.blue, + dsc_sel_col32.alpha); + uint32_t blend_color; + uint8_t blend_alpha = 255; + + _set_color_blend(nema_dsc_color, dsc_col32.alpha); + + uint8_t cur_state = 2; + uint8_t prev_state = 2; + + /*Write out all lines*/ + while(remaining_len && dsc->text[line_start] != '\0') { + pos.x += x_ofs; + line_start_x = pos.x; + + /*Write all letter of a line*/ + recolor_cmd_state = RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER; + next_char_offset = 0; +#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); +#else + const char * bidi_txt = dsc->text + line_start; +#endif + + while(next_char_offset < remaining_len && next_char_offset < line_end - line_start) { + uint32_t logical_char_pos = 0; + + /* Check if the text selection is enabled */ + if(sel_start != LV_DRAW_LABEL_NO_TXT_SEL && sel_end != LV_DRAW_LABEL_NO_TXT_SEL) { +#if LV_USE_BIDI + logical_char_pos = lv_text_encoded_get_char_id(dsc->text, line_start); + uint32_t c_idx = lv_text_encoded_get_char_id(bidi_txt, next_char_offset); + logical_char_pos += lv_bidi_get_logical_pos(bidi_txt, NULL, line_end - line_start, base_dir, c_idx, NULL); +#else + logical_char_pos = lv_text_encoded_get_char_id(dsc->text, line_start + next_char_offset); +#endif + } + + uint32_t letter; + uint32_t letter_next; + lv_text_encoded_letter_next_2(bidi_txt, &letter, &letter_next, &next_char_offset); + + /* If recolor is enabled */ + if((dsc->flag & LV_TEXT_FLAG_RECOLOR) != 0) { + + if(letter == (uint32_t)LV_TXT_COLOR_CMD[0]) { + /* Handle the recolor command marker depending of the current recolor state */ + + if(recolor_cmd_state == RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER) { + recolor_command_start_index = next_char_offset; + recolor_cmd_state = RECOLOR_CMD_STATE_PARAMETER; + continue; + } + /*Other start char in parameter escaped cmd. char*/ + else if(recolor_cmd_state == RECOLOR_CMD_STATE_PARAMETER) { + recolor_cmd_state = RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER; + } + /* If letter is LV_TXT_COLOR_CMD and we were in the CMD_STATE_IN then the recolor close marked has been found */ + else if(recolor_cmd_state == RECOLOR_CMD_STATE_TEXT_INPUT) { + recolor_cmd_state = RECOLOR_CMD_STATE_WAIT_FOR_PARAMETER; + continue; + } + } + + /* Find the first space (aka ' ') after the recolor command parameter, we need to skip rendering it */ + if((recolor_cmd_state == RECOLOR_CMD_STATE_PARAMETER) && (letter == ' ') && (is_first_space_after_cmd == 0)) { + is_first_space_after_cmd = 1; + } + else { + is_first_space_after_cmd = 0; + } + + /* Skip the color parameter and wait the space after it + * Once we have reach the space ' ', then we will extract the color information + * and store it into the recolor variable */ + if(recolor_cmd_state == RECOLOR_CMD_STATE_PARAMETER) { + /* Not an space? Continue with the next character */ + if(letter != ' ') { + continue; + } + + /*Get the recolor parameter*/ + if((next_char_offset - recolor_command_start_index) == LABEL_RECOLOR_PAR_LENGTH + 1) { + /* Temporary buffer to hold the recolor information */ + char buf[LABEL_RECOLOR_PAR_LENGTH + 1]; + lv_memcpy(buf, &bidi_txt[recolor_command_start_index], LABEL_RECOLOR_PAR_LENGTH); + buf[LABEL_RECOLOR_PAR_LENGTH] = '\0'; + + uint8_t r, g, b; + r = (hex_char_to_num(buf[0]) << 4) + hex_char_to_num(buf[1]); + g = (hex_char_to_num(buf[2]) << 4) + hex_char_to_num(buf[3]); + b = (hex_char_to_num(buf[4]) << 4) + hex_char_to_num(buf[5]); + + recolor = lv_color_make(r, g, b); + } + else { + recolor.red = dsc->color.red; + recolor.blue = dsc->color.blue; + recolor.green = dsc->color.green; + } + + /*After the parameter the text is in the command*/ + recolor_cmd_state = RECOLOR_CMD_STATE_TEXT_INPUT; + } + + /* Don't draw the first space after the recolor command */ + if(is_first_space_after_cmd) { + continue; + } + } + + /* If we're in the CMD_STATE_IN state then we need to subtract the recolor command length */ + if(((dsc->flag & LV_TEXT_FLAG_RECOLOR) != 0) && (recolor_cmd_state == RECOLOR_CMD_STATE_TEXT_INPUT)) { + logical_char_pos -= (LABEL_RECOLOR_PAR_LENGTH + 1); + } + + letter_w = lv_font_get_glyph_width(font, letter, letter_next); + + /*Always set the bg_coordinates for placeholder drawing*/ + bg_coords.x1 = pos.x; + bg_coords.y1 = pos.y; + bg_coords.x2 = pos.x + letter_w - 1; + bg_coords.y2 = pos.y + line_height - 1; + + if(next_char_offset >= line_end - line_start) { + if(dsc->decor & LV_TEXT_DECOR_UNDERLINE) { + lv_area_t fill_area; + fill_area.x1 = line_start_x; + fill_area.x2 = pos.x + letter_w - 1; + fill_area.y1 = pos.y + font->line_height - font->base_line - font->underline_position; + fill_area.y2 = fill_area.y1 + underline_width - 1; + + fill_dsc.color = dsc->color; + lv_draw_nema_gfx_fill(t, &fill_dsc, &fill_area); + } + if(dsc->decor & LV_TEXT_DECOR_STRIKETHROUGH) { + lv_area_t fill_area; + fill_area.x1 = line_start_x; + fill_area.x2 = pos.x + letter_w - 1; + fill_area.y1 = pos.y + (font->line_height - font->base_line) * 2 / 3 + font->underline_thickness / 2; + fill_area.y2 = fill_area.y1 + underline_width - 1; + + fill_dsc.color = dsc->color; + lv_draw_nema_gfx_fill(t, &fill_dsc, &fill_area); + } + } + + /* Handle text selection */ + if(sel_start != LV_DRAW_LABEL_NO_TXT_SEL && sel_end != LV_DRAW_LABEL_NO_TXT_SEL + && logical_char_pos >= sel_start && logical_char_pos < sel_end) { + draw_letter_dsc.color = dsc->sel_color; + fill_dsc.color = dsc->sel_bg_color; + lv_draw_nema_gfx_fill(t, &fill_dsc, &bg_coords); + cur_state = 0 ; + blend_alpha = dsc_sel_col32.alpha; + blend_color = nema_dsc_sel_color; + } + else if(recolor_cmd_state == RECOLOR_CMD_STATE_TEXT_INPUT) { + draw_letter_dsc.color = recolor; + cur_state = 1 ; + blend_alpha = dsc_col32.alpha; + lv_color32_t dsc_recolor_col32 = lv_color_to_32(recolor, dsc->opa); + blend_color = nema_rgba(dsc_recolor_col32.red, dsc_recolor_col32.green, dsc_recolor_col32.blue, + dsc_recolor_col32.alpha); + } + else { + draw_letter_dsc.color = dsc->color; + cur_state = 2; + blend_alpha = dsc_col32.alpha; + blend_color = nema_dsc_color; + } + + if(cur_state != prev_state) { + _set_color_blend(blend_color, blend_alpha); + prev_state = cur_state; + } + + _draw_letter(t, &draw_letter_dsc, &pos, font, letter); + + if(letter_w > 0) { + pos.x += letter_w + dsc->letter_space; + } + } + +#if LV_USE_BIDI + lv_free(bidi_txt); + bidi_txt = NULL; +#endif + /*Go to next line*/ + remaining_len -= line_end - line_start; + line_start = line_end; + if(remaining_len) { + line_end += lv_text_get_next_line(&dsc->text[line_start], remaining_len, font, dsc->letter_space, w, NULL, dsc->flag); + } + + pos.x = coords->x1; + /*Align to middle*/ + if(align == LV_TEXT_ALIGN_CENTER) { + line_width = + lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag); + + pos.x += (lv_area_get_width(coords) - line_width) / 2; + } + /*Align to the right*/ + else if(align == LV_TEXT_ALIGN_RIGHT) { + line_width = + lv_text_get_width_with_flags(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space, dsc->flag); + pos.x += lv_area_get_width(coords) - line_width; + } + + /*Go the next line position*/ + pos.y += line_height; + + if(pos.y > t->clip_area.y2) break; + } + + if(draw_letter_dsc._draw_buf) lv_draw_buf_destroy(draw_letter_dsc._draw_buf); + + LV_ASSERT_MEM_INTEGRITY(); +} + +static void _draw_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * dsc, const lv_point_t * pos, + const lv_font_t * font, uint32_t letter) +{ + lv_font_glyph_dsc_t g; + + if(lv_text_is_marker(letter)) /*Markers are valid letters but should not be rendered.*/ + return; + + LV_PROFILER_DRAW_BEGIN; + bool g_ret = lv_font_get_glyph_dsc(font, &g, letter, '\0'); + if(g_ret == false) { + /*Add warning if the dsc is not found*/ + LV_LOG_WARN("lv_draw_letter: glyph dsc. not found for U+%" LV_PRIX32, letter); + } + + /*Don't draw anything if the character is empty. E.g. space*/ + if((g.box_h == 0) || (g.box_w == 0)) { + LV_PROFILER_DRAW_END; + return; + } + + lv_area_t letter_coords; + letter_coords.x1 = pos->x + g.ofs_x; + letter_coords.x2 = letter_coords.x1 + g.box_w - 1; + letter_coords.y1 = pos->y + (font->line_height - font->base_line) - g.box_h - g.ofs_y; + letter_coords.y2 = letter_coords.y1 + g.box_h - 1; + lv_area_move(&letter_coords, -dsc->pivot.x, -dsc->pivot.y); + + /*If the letter is completely out of mask don't draw it*/ + if(lv_area_is_out(&letter_coords, &t->clip_area, 0) && + dsc->bg_coords && + lv_area_is_out(dsc->bg_coords, &t->clip_area, 0)) { + LV_PROFILER_DRAW_END; + return; + } + + if(g.resolved_font) { + lv_draw_buf_t * draw_buf = NULL; + if(LV_FONT_GLYPH_FORMAT_NONE < g.format && g.format < LV_FONT_GLYPH_FORMAT_IMAGE) { + /*Only check draw buf for bitmap glyph*/ + draw_buf = lv_draw_buf_reshape(dsc->_draw_buf, 0, g.box_w, g.box_h, LV_STRIDE_AUTO); + if(draw_buf == NULL) { + if(dsc->_draw_buf) lv_draw_buf_destroy(dsc->_draw_buf); + + uint32_t h = LV_ROUND_UP(g.box_h, 32); /*Assume a larger size to avoid many reallocations*/ + 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; + } + } + + /* Performance Optimization for lv_font_fmt_txt_dsc_t fonts, always request raw bitmaps */ + /*Exception for w*h >= NEMA_COORD_LIMIT due to HW limitation on data handling*/ + is_raw_bitmap = false; + if(g.box_h * g.box_w <= NEMA_COORD_LIMIT) { + g.req_raw_bitmap = 1; + if(font->get_glyph_bitmap == lv_font_get_bitmap_fmt_txt) { + lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *)font->dsc; + if(fdsc->bitmap_format == LV_FONT_FMT_TXT_PLAIN) { + is_raw_bitmap = true; + } + } + } + + dsc->glyph_data = g.resolved_font->get_glyph_bitmap(&g, draw_buf); + + dsc->format = dsc->glyph_data ? g.format : LV_FONT_GLYPH_FORMAT_NONE; + } + else { + dsc->format = LV_FONT_GLYPH_FORMAT_NONE; + } + + dsc->letter_coords = &letter_coords; + dsc->g = &g; + _draw_nema_gfx_letter(t, dsc, NULL, NULL); + + if(g.resolved_font && font->release_glyph) { + lv_draw_nema_gfx_unit_t * draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *)t->draw_unit; + nema_cl_submit(&(draw_nema_gfx_unit->cl)); + nema_cl_wait(&(draw_nema_gfx_unit->cl)); + font->release_glyph(font, &g); + } + + LV_PROFILER_DRAW_END; +} + +#endif /*LV_USE_NEMA_GFX*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_layer.c b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_layer.c new file mode 100644 index 000000000..0c64564c6 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_layer.c @@ -0,0 +1,57 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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. + * + */ + +/** + * @file lv_draw_nema_gfx_fill.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_nema_gfx.h" + +#if LV_USE_NEMA_GFX + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_nema_gfx_layer(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords) +{ + lv_layer_t * layer_to_draw = (lv_layer_t *)draw_dsc->src; + + /*It can happen that nothing was draw on a layer and therefore its buffer is not allocated. + *In this case just return. */ + if(layer_to_draw->draw_buf == NULL) return; + + lv_draw_image_dsc_t new_draw_dsc = *draw_dsc; + new_draw_dsc.src = layer_to_draw->draw_buf; + + lv_draw_nema_gfx_img(t, &new_draw_dsc, coords); +} + +#endif /*LV_USE_NEMA_GFX*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_line.c b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_line.c new file mode 100644 index 000000000..ad6e24e01 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_line.c @@ -0,0 +1,96 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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. + * + */ + +/** + * @file lv_draw_nema_gfx_fill.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_nema_gfx.h" + +#if LV_USE_NEMA_GFX + +/********************** + * GLOBAL FUNCTIONS + **********************/ +void lv_draw_nema_gfx_line(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc) +{ + if(dsc->width == 0) + return; + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) + return; + if(dsc->p1.x == dsc->p2.x && dsc->p1.y == dsc->p2.y) + return; + + lv_draw_nema_gfx_unit_t * draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *)t->draw_unit; + + lv_layer_t * layer = t->target_layer; + lv_area_t clip_area; + clip_area.x1 = LV_MIN(dsc->p1.x, dsc->p2.x) - dsc->width / 2; + clip_area.x2 = LV_MAX(dsc->p1.x, dsc->p2.x) + dsc->width / 2; + 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, &t->clip_area)) + return; /*Fully clipped, nothing to do*/ + + lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); + + lv_point_t point1 = {dsc->p1.x - layer->buf_area.x1, dsc->p1.y - layer->buf_area.y1}; + lv_point_t point2 = {dsc->p2.x - layer->buf_area.x1, dsc->p2.y - layer->buf_area.y1}; + + nema_set_clip(clip_area.x1, clip_area.y1, lv_area_get_width(&clip_area), lv_area_get_height(&clip_area)); + + lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa); + + uint32_t bg_color = nema_rgba(col32.red, col32.green, col32.blue, col32.alpha); + + lv_color_format_t dst_cf = layer->draw_buf->header.cf; + uint32_t dst_nema_cf = lv_nemagfx_cf_to_nema(dst_cf); + + /* the stride should be computed internally for NEMA_TSC images and images missing a stride value */ + int32_t stride = (dst_cf >= LV_COLOR_FORMAT_NEMA_TSC_START && dst_cf <= LV_COLOR_FORMAT_NEMA_TSC_END) ? + -1 : lv_area_get_width(&(layer->buf_area)) * lv_color_format_get_size(dst_cf); + + nema_bind_dst_tex((uintptr_t)NEMA_VIRT2PHYS(layer->draw_buf->data), lv_area_get_width(&(layer->buf_area)), + lv_area_get_height(&(layer->buf_area)), dst_nema_cf, stride); + + if(col32.alpha < 255U) { + nema_set_blend_fill(NEMA_BL_SIMPLE); + } + else { + nema_set_blend_fill(NEMA_BL_SRC); + } + + nema_draw_line_aa(point1.x, point1.y, point2.x, point2.y, dsc->width, bg_color); + + nema_cl_submit(&(draw_nema_gfx_unit->cl)); + +} +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_stm32_hal.c b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_stm32_hal.c new file mode 100644 index 000000000..cb6abaf33 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_stm32_hal.c @@ -0,0 +1,254 @@ +/** + * @file lv_draw_nema_gfx_hal.c + * + * Global functions that implement some HAL functionality + * which Nema will call directly. + */ + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_NEMA_GFX + +#if LV_USE_NEMA_HAL == LV_NEMA_HAL_STM32 + +#include "../../misc/lv_types.h" +#include "../../misc/lv_assert.h" +#include "../../stdlib/lv_string.h" + +#include +#include + +#include +#include + +#include LV_NEMA_STM32_HAL_INCLUDE + +#include "tsi_malloc.h" + +extern GPU2D_HandleTypeDef hgpu2d; + +/********************* + * DEFINES + *********************/ + +#define RING_SIZE 1024 /* Ring Buffer Size in byte */ + +/* NemaGFX byte pool size in bytes. + * One byte per peixel for masking/stencling plus 10240 for additional allocations. + */ +#if defined(LV_NEMA_GFX_MAX_RESX) && defined(LV_NEMA_GFX_MAX_RESY) + #define NEMAGFX_MEM_POOL_SIZE ((LV_NEMA_GFX_MAX_RESX * LV_NEMA_GFX_MAX_RESY) + 10240) +#else + /* LV_USE_NEMA_VG is 0 so masking/stencling memory is not needed. */ + #define NEMAGFX_MEM_POOL_SIZE 10240 +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) + static void GPU2D_CommandListCpltCallback(GPU2D_HandleTypeDef * hgpu2d, uint32_t CmdListID); +#endif + +/********************** + * STATIC VARIABLES + **********************/ + +static uint8_t nemagfx_pool_mem[NEMAGFX_MEM_POOL_SIZE]; /* NemaGFX memory pool */ + +static nema_ringbuffer_t ring_buffer_str; +static volatile int last_cl_id = -1; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) + static void GPU2D_CommandListCpltCallback(GPU2D_HandleTypeDef * hgpu2d, uint32_t CmdListID) +#else + void HAL_GPU2D_CommandListCpltCallback(GPU2D_HandleTypeDef * hgpu2d, uint32_t CmdListID) +#endif +{ + LV_UNUSED(hgpu2d); + + last_cl_id = CmdListID; +} + +int32_t nema_sys_init(void) +{ + int error_code = 0; + + /* Setup GPU2D Callback */ +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) + /* Register Command List Complete Callback */ + HAL_GPU2D_RegisterCommandListCpltCallback(&hgpu2d, GPU2D_CommandListCpltCallback); +#endif + + /* Initialise Mem Space */ + error_code = tsi_malloc_init_pool_aligned(0, (void *)nemagfx_pool_mem, (uintptr_t)nemagfx_pool_mem, + NEMAGFX_MEM_POOL_SIZE, 1, 8); + LV_ASSERT(error_code == 0); + + /* Allocate ring_buffer memory */ + ring_buffer_str.bo = nema_buffer_create(RING_SIZE); + LV_ASSERT(ring_buffer_str.bo.base_virt); + + /* Initialize Ring Buffer */ + error_code = nema_rb_init(&ring_buffer_str, 1); + if(error_code < 0) { + return error_code; + } + + /* Reset last_cl_id counter */ + last_cl_id = 0; + + return error_code; +} + +uint32_t nema_reg_read(uint32_t reg) +{ + return HAL_GPU2D_ReadRegister(&hgpu2d, reg); +} + +void nema_reg_write(uint32_t reg, uint32_t value) +{ + HAL_GPU2D_WriteRegister(&hgpu2d, reg, value); +} + + + + +int nema_wait_irq(void) +{ + return 0; +} + + +int nema_wait_irq_cl(int cl_id) +{ + while(last_cl_id < cl_id) { + (void)nema_wait_irq(); + } + + return 0; +} + +int nema_wait_irq_brk(int brk_id) +{ + while(nema_reg_read(GPU2D_BREAKPOINT) == 0U) { + (void)nema_wait_irq(); + } + + return 0; +} + +void nema_host_free(void * ptr) +{ + tsi_free(ptr); +} + +void * nema_host_malloc(unsigned size) +{ + return tsi_malloc(size); +} + +nema_buffer_t nema_buffer_create(int size) +{ + nema_buffer_t bo; + lv_memset(&bo, 0, sizeof(bo)); + bo.base_virt = tsi_malloc(size); + bo.base_phys = (uint32_t)bo.base_virt; + bo.size = size; + LV_ASSERT_MSG(bo.base_virt != 0, "Unable to allocate memory in nema_buffer_create"); + + return bo; +} + +nema_buffer_t nema_buffer_create_pool(int pool, int size) +{ + LV_UNUSED(pool); + + return nema_buffer_create(size); +} + +void * nema_buffer_map(nema_buffer_t * bo) +{ + return bo->base_virt; +} + +void nema_buffer_unmap(nema_buffer_t * bo) +{ + LV_UNUSED(bo); +} + +void nema_buffer_destroy(nema_buffer_t * bo) +{ + if(bo->fd == -1) { + return; /* Buffer weren't allocated! */ + } + + tsi_free(bo->base_virt); + + bo->base_virt = (void *)0; + bo->base_phys = 0; + bo->size = 0; + bo->fd = -1; /* Buffer not allocated */ +} + +uintptr_t nema_buffer_phys(nema_buffer_t * bo) +{ + return bo->base_phys; +} + +void nema_buffer_flush(nema_buffer_t * bo) +{ + LV_UNUSED(bo); +} + +int nema_mutex_lock(int mutex_id) +{ + int retval = 0; + + LV_UNUSED(mutex_id); + + return retval; +} + +int nema_mutex_unlock(int mutex_id) +{ + int retval = 0; + + LV_UNUSED(mutex_id); + + return retval; +} + +void platform_disable_cache(void) +{ + +} + +void platform_invalidate_cache(void) +{ + +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /* LV_USE_NEMA_HAL == LV_NEMA_HAL_STM32 */ + +#endif /* LV_USE_NEMA_GFX */ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_triangle.c b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_triangle.c new file mode 100644 index 000000000..658da8da0 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_triangle.c @@ -0,0 +1,171 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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. + * + */ + +/** + * @file lv_draw_nema_gfx_fill.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_nema_gfx.h" + +#if LV_USE_NEMA_GFX + +/********************** + * GLOBAL FUNCTIONS + **********************/ +void lv_draw_nema_gfx_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc) +{ + if(dsc->opa <= LV_OPA_MIN) return; + + lv_draw_nema_gfx_unit_t * draw_nema_gfx_unit = (lv_draw_nema_gfx_unit_t *)t->draw_unit; + + lv_layer_t * layer = t->target_layer; + + lv_area_t rel_clip_area; + lv_area_copy(&rel_clip_area, &t->clip_area); + lv_area_move(&rel_clip_area, -layer->buf_area.x1, -layer->buf_area.y1); + + lv_area_t coords; + coords.x1 = (int32_t)LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); + coords.y1 = (int32_t)LV_MIN3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y); + coords.x2 = (int32_t)LV_MAX3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); + coords.y2 = (int32_t)LV_MAX3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y); + + lv_area_move(&coords, -layer->buf_area.x1, -layer->buf_area.y1); + + lv_area_t clipped_coords; + if(!lv_area_intersect(&clipped_coords, &coords, &rel_clip_area)) + return; /* Fully clipped, nothing to do */ + + nema_set_clip(rel_clip_area.x1, rel_clip_area.y1, lv_area_get_width(&rel_clip_area), + lv_area_get_height(&rel_clip_area)); + + lv_color_format_t dst_cf = layer->draw_buf->header.cf; + uint32_t dst_nema_cf = lv_nemagfx_cf_to_nema(dst_cf); + + /* the stride should be computed internally for NEMA_TSC images and images missing a stride value */ + int32_t stride = (dst_cf >= LV_COLOR_FORMAT_NEMA_TSC_START && dst_cf <= LV_COLOR_FORMAT_NEMA_TSC_END) ? + -1 : lv_area_get_width(&(layer->buf_area)) * lv_color_format_get_size(dst_cf); + + nema_bind_dst_tex((uintptr_t)NEMA_VIRT2PHYS(layer->draw_buf->data), lv_area_get_width(&(layer->buf_area)), + lv_area_get_height(&(layer->buf_area)), dst_nema_cf, stride); + + if(dsc->grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_NONE) { + + lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa); + + if(col32.alpha < 255U) { + nema_set_blend_fill(NEMA_BL_SIMPLE); + } + else { + nema_set_blend_fill(NEMA_BL_SRC); + } + + uint32_t bg_color = nema_rgba(col32.red, col32.green, col32.blue, col32.alpha); + + nema_enable_aa(1, 1, 1, 0); + nema_fill_triangle(dsc->p[0].x, dsc->p[0].y, dsc->p[1].x, dsc->p[1].y, dsc->p[2].x, dsc->p[2].y, bg_color); + } +#if LV_USE_NEMA_VG + else { + + nema_vg_path_clear(draw_nema_gfx_unit->path); + nema_vg_paint_clear(draw_nema_gfx_unit->paint); + + nema_vg_paint_set_type(draw_nema_gfx_unit->paint, NEMA_VG_PAINT_GRAD_LINEAR); + nema_vg_set_blend(NEMA_BL_SRC_OVER | NEMA_BLOP_SRC_PREMULT); + nema_vg_set_fill_rule(NEMA_VG_FILL_EVEN_ODD); + + + float stops[LV_GRADIENT_MAX_STOPS]; + color_var_t colors[LV_GRADIENT_MAX_STOPS]; + + uint32_t cnt = LV_MAX(dsc->grad.stops_count, LV_GRADIENT_MAX_STOPS); + + for(uint8_t i = 0; i < cnt; i++) { + stops[i] = (float)(dsc->grad.stops[i].frac) / 255.f; + colors[i].a = dsc->grad.stops[i].opa; + colors[i].r = dsc->grad.stops[i].color.red; + colors[i].g = dsc->grad.stops[i].color.green; + colors[i].b = dsc->grad.stops[i].color.blue; + } + + nema_vg_grad_set(draw_nema_gfx_unit->gradient, cnt, stops, colors); + + //Calculate Bounding Box + float min_x = LV_MIN(dsc->p[0].x, dsc->p[1].x); + min_x = LV_MIN(dsc->p[2].x, min_x); + + float min_y = LV_MIN(dsc->p[0].y, dsc->p[1].y); + min_y = LV_MIN(dsc->p[2].y, min_y); + + float max_x = LV_MAX(dsc->p[0].x, dsc->p[1].x); + max_x = LV_MAX(dsc->p[2].x, max_x); + + float max_y = LV_MAX(dsc->p[0].y, dsc->p[1].y); + max_y = LV_MAX(dsc->p[2].y, max_y); + + float x0, x1, y0, y1; + + if(dsc->grad.dir == LV_GRAD_DIR_HOR) { + x0 = min_x; + x1 = max_x; + y0 = min_y; + y1 = min_y; + } + else { + x0 = min_x; + x1 = min_x; + y0 = min_y; + y1 = max_y; + } + + y0 -= (float) layer->buf_area.y1; + y1 -= (float) layer->buf_area.y1; + x0 -= (float) layer->buf_area.x1; + x1 -= (float) layer->buf_area.x1; + + uint8_t cmds_polygon[] = {NEMA_VG_PRIM_MOVE, NEMA_VG_PRIM_POLYGON}; + float triangle_coords[] = {dsc->p[0].x - layer->buf_area.x1, dsc->p[0].y - layer->buf_area.y1, + 4.0f, + dsc->p[1].x - layer->buf_area.x1, dsc->p[1].y - layer->buf_area.y1, + dsc->p[2].x - layer->buf_area.x1, dsc->p[2].y - layer->buf_area.y1 + }; + nema_enable_aa(0, 0, 0, 0); + nema_vg_paint_set_grad_linear(draw_nema_gfx_unit->paint, draw_nema_gfx_unit->gradient, x0, y0, x1, y1, + NEMA_TEX_CLAMP | NEMA_FILTER_BL); + nema_vg_path_set_shape(draw_nema_gfx_unit->path, 2, cmds_polygon, 7, triangle_coords); + nema_vg_draw_path(draw_nema_gfx_unit->path, draw_nema_gfx_unit->paint); + } +#endif + + nema_cl_submit(&(draw_nema_gfx_unit->cl)); + +} +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_utils.c b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_utils.c new file mode 100644 index 000000000..2ecce650d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_utils.c @@ -0,0 +1,143 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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. + * + */ + +/** + * @file lv_draw_nema_gfx_utils.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_nema_gfx.h" + +#if LV_USE_NEMA_GFX + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +uint32_t lv_nemagfx_cf_to_nema(lv_color_format_t cf) +{ + switch(cf) { + case LV_COLOR_FORMAT_A1: + return NEMA_A1; + case LV_COLOR_FORMAT_A2: + return NEMA_A2; + case LV_COLOR_FORMAT_A4: + return NEMA_A4; + case LV_COLOR_FORMAT_A8: + return NEMA_A8; + case LV_COLOR_FORMAT_I1: + return NEMA_L1; + case LV_COLOR_FORMAT_I2: + return NEMA_L2; + case LV_COLOR_FORMAT_I4: + return NEMA_L4; + case LV_COLOR_FORMAT_L8: + case LV_COLOR_FORMAT_I8: + return NEMA_L8; + case LV_COLOR_FORMAT_RGB565: + return NEMA_RGB565; + case LV_COLOR_FORMAT_RGB888: + return NEMA_BGR24; + case LV_COLOR_FORMAT_ARGB8888: + return NEMA_BGRA8888; + case LV_COLOR_FORMAT_XRGB8888: + return NEMA_BGRX8888; + case LV_COLOR_FORMAT_NEMA_TSC4: + return NEMA_TSC4; + case LV_COLOR_FORMAT_NEMA_TSC6: + return NEMA_TSC6; + case LV_COLOR_FORMAT_NEMA_TSC6A: + return NEMA_TSC6A; + case LV_COLOR_FORMAT_NEMA_TSC12: + return NEMA_TSC12; + case LV_COLOR_FORMAT_NEMA_TSC12A: + return NEMA_TSC12A; + /*Guard for previous NemaGFX Version*/ +#ifdef NEMA_TSC6AP + case LV_COLOR_FORMAT_NEMA_TSC6AP: + return NEMA_TSC6AP; +#endif + default: + return LV_NEMA_GFX_COLOR_FORMAT; + } +} + +uint32_t lv_nemagfx_blending_mode(lv_blend_mode_t lv_blend_mode) +{ + uint32_t blending_mode; + switch(lv_blend_mode) { + case LV_BLEND_MODE_NORMAL: + blending_mode = NEMA_BL_SIMPLE; + break; + case LV_BLEND_MODE_ADDITIVE: + blending_mode = NEMA_BL_ADD; + break; + case LV_BLEND_MODE_MULTIPLY: + blending_mode = nema_blending_mode(NEMA_BF_DESTCOLOR, NEMA_BF_INVSRCALPHA, NEMA_BLOP_SRC_PREMULT); + break; + default: + blending_mode = NEMA_BL_SIMPLE; + break; + } + return blending_mode; +} + +void lv_nemagfx_grad_set(NEMA_VG_GRAD_HANDLE gradient, lv_grad_dsc_t lv_grad, lv_opa_t opa) +{ + + float stops[LV_GRADIENT_MAX_STOPS]; + color_var_t colors[LV_GRADIENT_MAX_STOPS]; + + uint32_t cnt = LV_MAX(lv_grad.stops_count, LV_GRADIENT_MAX_STOPS); + + for(uint8_t i = 0; i < cnt; i++) { + stops[i] = (float)(lv_grad.stops[i].frac) / 255.f; + colors[i].a = LV_OPA_MIX2(lv_grad.stops[i].opa, opa); + colors[i].r = lv_grad.stops[i].color.red; + colors[i].g = lv_grad.stops[i].color.green; + colors[i].b = lv_grad.stops[i].color.blue; + } + + nema_vg_grad_set(gradient, cnt, stops, colors); +} + +bool lv_nemagfx_is_cf_supported(lv_color_format_t cf) +{ + + switch(cf) { + case LV_COLOR_FORMAT_ARGB8565: + case LV_COLOR_FORMAT_RGB565A8: + return false; + default: + break; + } + return true; +} + +#endif /*LV_USE_NEMA_GFX*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_utils.h b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_utils.h new file mode 100644 index 000000000..a4f90b14c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_draw_nema_gfx_utils.h @@ -0,0 +1,132 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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. + * + */ + +/** + * @file lv_draw_nema_gfx.h + * + */ + +#ifndef LV_DRAW_NEMA_GFX_UTILS_H +#define LV_DRAW_NEMA_GFX_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_NEMA_GFX +#include "../sw/lv_draw_sw.h" + +#include "nema_core.h" +#include "nema_utils.h" +#include "nema_error.h" +#include "nema_provisional.h" +#include "nema_vg.h" + +/********************* + * DEFINES + *********************/ + +#ifndef NEMA_VIRT2PHYS +#define NEMA_VIRT2PHYS +#else +uintptr_t NEMA_VIRT2PHYS(void * addr); +#endif + +/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/ +#if LV_COLOR_DEPTH == 8 +#define LV_NEMA_GFX_COLOR_FORMAT NEMA_L8 +#define LV_NEMA_GFX_FORMAT_MULTIPLIER 1 +#elif LV_COLOR_DEPTH == 16 +#define LV_NEMA_GFX_COLOR_FORMAT NEMA_RGB565 +#define LV_NEMA_GFX_FORMAT_MULTIPLIER 2 +#elif LV_COLOR_DEPTH == 24 +#define LV_NEMA_GFX_COLOR_FORMAT NEMA_BGR24 +#define LV_NEMA_GFX_FORMAT_MULTIPLIER 3 +#elif LV_COLOR_DEPTH == 32 +#define LV_NEMA_GFX_COLOR_FORMAT NEMA_BGRA8888 +#define LV_NEMA_GFX_FORMAT_MULTIPLIER 4 +#else +/*Can't use GPU with other formats*/ +#error Selected Color Depth Not Supported +#endif + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Check if `lv_color_format_t` is supported. + * @param cf The LVGL color format + * @return True/false + */ +bool lv_nemagfx_is_cf_supported(lv_color_format_t cf); + +/** + * Convert a `lv_color_format_t` to a Nema color format. + * @param cf The LVGL color format + * @return The Nema color format + */ +uint32_t lv_nemagfx_cf_to_nema(lv_color_format_t cf); + +/** + * Get NemaGFX blending mode + * + * @param[in] lv_blend_mode The LVGL blend mode + * + * @return NemaGFX blending mode + * + */ +uint32_t lv_nemagfx_blending_mode(lv_blend_mode_t lv_blend_mode); + + +/** + * Get NemaGFX blending mode + * + * @param[in] gradient NemaGFX Gradient Buffer + * + * @param[in] lv_grad Gradient descriptor + * + * @param[in] opa Descriptor's opacity + * +*/ +void lv_nemagfx_grad_set(NEMA_VG_GRAD_HANDLE gradient, lv_grad_dsc_t lv_grad, lv_opa_t opa); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_NEMA_GFX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_NEMA_GFX_UTILS_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_nema_gfx_path.c b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_nema_gfx_path.c new file mode 100644 index 000000000..55a774b24 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_nema_gfx_path.c @@ -0,0 +1,159 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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. + * + */ + +/** + * @file lv_nema_gfx_path.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../core/lv_refr.h" + +#if LV_USE_NEMA_GFX +#if LV_USE_NEMA_VG + +#include "lv_nema_gfx_path.h" + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +static int data_point = 0; +static int seg_point = 0; + +lv_nema_gfx_path_t * lv_nema_gfx_path_create(void) +{ + LV_PROFILER_DRAW_BEGIN; + lv_nema_gfx_path_t * nema_gfx_path = lv_malloc_zeroed(sizeof(lv_nema_gfx_path_t)); + LV_ASSERT_MALLOC(nema_gfx_path); + nema_gfx_path->seg = NULL; + nema_gfx_path->data = NULL; + nema_gfx_path->seg_size = 0; + nema_gfx_path->data_size = 0; + data_point = 0; + seg_point = 0; + LV_PROFILER_DRAW_END; + return nema_gfx_path; +} + +void lv_nema_gfx_path_alloc(lv_nema_gfx_path_t * nema_gfx_path) +{ + LV_PROFILER_DRAW_BEGIN; + nema_gfx_path->path = nema_vg_path_create(); + nema_gfx_path->paint = nema_vg_paint_create(); + nema_gfx_path->data = (float *) lv_malloc(nema_gfx_path->data_size * sizeof(float)); + LV_ASSERT_MALLOC(nema_gfx_path->data); + nema_gfx_path->seg = (uint8_t *) lv_malloc(nema_gfx_path->seg_size * sizeof(uint8_t)); + LV_ASSERT_MALLOC(nema_gfx_path->seg); + LV_PROFILER_DRAW_END; +} + +void lv_nema_gfx_path_destroy(lv_nema_gfx_path_t * nema_gfx_path) +{ + LV_PROFILER_DRAW_BEGIN; + LV_ASSERT_NULL(nema_gfx_path); + + if(nema_gfx_path->path != NULL) { + nema_vg_path_destroy(nema_gfx_path->path); + nema_gfx_path->path = NULL; + } + + if(nema_gfx_path->paint != NULL) { + nema_vg_paint_destroy(nema_gfx_path->paint); + nema_gfx_path->paint = NULL; + } + + if(nema_gfx_path->data != NULL) { + lv_free(nema_gfx_path->data); + nema_gfx_path->data = NULL; + } + if(nema_gfx_path->seg != NULL) { + lv_free(nema_gfx_path->seg); + nema_gfx_path->seg = NULL; + } + lv_free(nema_gfx_path); + LV_PROFILER_DRAW_END; +} + +void lv_nema_gfx_path_move_to(lv_nema_gfx_path_t * path, float x, float y) +{ + LV_ASSERT_NULL(path); + LV_ASSERT(path->data_size > data_point + 1); + LV_ASSERT(path->seg_size > seg_point); + path->seg[seg_point++] = NEMA_VG_PRIM_MOVE; + path->data[data_point++] = x; + path->data[data_point++] = y; +} + +void lv_nema_gfx_path_line_to(lv_nema_gfx_path_t * path, float x, float y) +{ + LV_ASSERT_NULL(path); + LV_ASSERT(path->data_size > data_point + 1); + LV_ASSERT(path->seg_size > seg_point); + path->seg[seg_point++] = NEMA_VG_PRIM_LINE; + path->data[data_point++] = x; + path->data[data_point++] = y; + +} + +void lv_nema_gfx_path_quad_to(lv_nema_gfx_path_t * path, float cx, float cy, float x, float y) +{ + LV_ASSERT_NULL(path); + LV_ASSERT(path->data_size > data_point + 3); + LV_ASSERT(path->seg_size > seg_point); + path->seg[seg_point++] = NEMA_VG_PRIM_BEZIER_QUAD; + path->data[data_point++] = cx; + path->data[data_point++] = cy; + path->data[data_point++] = x; + path->data[data_point++] = y; +} + +void lv_nema_gfx_path_cubic_to(lv_nema_gfx_path_t * path, float cx1, float cy1, float cx2, float cy2, float x, float y) +{ + LV_ASSERT_NULL(path); + LV_ASSERT(path->data_size > data_point + 5); + LV_ASSERT(path->seg_size > seg_point); + path->seg[seg_point++] = NEMA_VG_PRIM_BEZIER_CUBIC; + path->data[data_point++] = cx1; + path->data[data_point++] = cy1; + path->data[data_point++] = cx2; + path->data[data_point++] = cy2; + path->data[data_point++] = x; + path->data[data_point++] = y; +} + +void lv_nema_gfx_path_end(lv_nema_gfx_path_t * path) +{ + /* Do Path end jobs....whatever*/ + seg_point = 0; + data_point = 0; + +} + +#endif /*LV_USE_NEMA_VG*/ +#endif /*LV_USE_NEMA_GFX*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_nema_gfx_path.h b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_nema_gfx_path.h new file mode 100644 index 000000000..0ff811833 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nema_gfx/lv_nema_gfx_path.h @@ -0,0 +1,97 @@ +/** + * MIT License + * + * ----------------------------------------------------------------------------- + * Copyright (c) 2008-24 Think Silicon Single Member PC + * ----------------------------------------------------------------------------- + * + * 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 (including the next paragraph) + * 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. + * + */ + +/** + * @file lv_nema_gfx_path.h + * + */ + +#ifndef LV_NEMA_GFX_PATH_H +#define LV_NEMA_GFX_PATH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_nema_gfx.h" + +#if LV_USE_NEMA_GFX +#if LV_USE_NEMA_VG + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + NEMA_VG_PATH_HANDLE path; + NEMA_VG_PAINT_HANDLE paint; + float * data; + uint8_t * seg; + uint32_t data_size; + uint32_t seg_size; +} lv_nema_gfx_path_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_nema_gfx_path_t * lv_nema_gfx_path_create(void); + +void lv_nema_gfx_path_alloc(lv_nema_gfx_path_t * nema_gfx_path); + +void lv_nema_gfx_path_destroy(lv_nema_gfx_path_t * nema_gfx_path); + +void lv_nema_gfx_path_move_to(lv_nema_gfx_path_t * nema_gfx_path, + float x, float y); + +void lv_nema_gfx_path_line_to(lv_nema_gfx_path_t * nema_gfx_path, + float x, float y); + +void lv_nema_gfx_path_quad_to(lv_nema_gfx_path_t * nema_gfx_path, + float cx, float cy, + float x, float y); + +void lv_nema_gfx_path_cubic_to(lv_nema_gfx_path_t * nema_gfx_path, + float cx1, float cy1, + float cx2, float cy2, + float x, float y); + +void lv_nema_gfx_path_end(lv_nema_gfx_path_t * nema_gfx_path); + + + +#endif /*LV_USE_NEMA_VG*/ +#endif /*LV_USE_NEMA_GFX*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_NEMA_GFX_PATH_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_buf_g2d.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_buf_g2d.c new file mode 100644 index 000000000..8653ea529 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_buf_g2d.c @@ -0,0 +1,92 @@ +/** + * @file lv_draw_buf_g2d.c + * + */ + +/** + * Copyright 2024 NXP + * + * SPDX-License-Identifier: MIT + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_g2d.h" + +#if LV_USE_DRAW_G2D +#include "../../lv_draw_buf_private.h" +#include "g2d.h" +#include "lv_g2d_buf_map.h" +#include "lv_g2d_utils.h" + + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void * _buf_malloc(size_t size_bytes, lv_color_format_t color_format); + +static void _buf_free(void * buf); + +static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_buf_g2d_init_handlers(void) +{ + lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers(); + + handlers->buf_malloc_cb = _buf_malloc; + handlers->buf_free_cb = _buf_free; + handlers->invalidate_cache_cb = _invalidate_cache; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void * _buf_malloc(size_t size_bytes, lv_color_format_t color_format) +{ + LV_UNUSED(color_format); + + size_bytes += LV_DRAW_BUF_ALIGN - 1; + struct g2d_buf * buf = g2d_alloc(size_bytes, 1); + G2D_ASSERT_MSG(buf, "Failed to alloc buffer."); + g2d_insert_buf_map(buf->buf_vaddr, buf); + return buf->buf_vaddr; +} + +static void _buf_free(void * buf) +{ + g2d_free_item(buf); +} + +static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area) +{ + LV_UNUSED(area); + struct g2d_buf * buf = g2d_search_buf_map(draw_buf->data); + G2D_ASSERT_MSG(buf, "Failed to find buffer in map."); + g2d_cache_op(buf, G2D_CACHE_FLUSH); +} + +#endif /*LV_USE_DRAW_G2D*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d.c new file mode 100644 index 000000000..42c6e40ec --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d.c @@ -0,0 +1,336 @@ +/** + * @file lv_draw_g2d.c + * + */ + +/** + * Copyright 2024 NXP + * + * SPDX-License-Identifier: MIT + */ + +#include "lv_draw_g2d.h" + +#if LV_USE_DRAW_G2D +#include "../../../misc/lv_area_private.h" +#include "g2d.h" +#include "lv_g2d_buf_map.h" + +/********************* + * DEFINES + *********************/ + +#define DRAW_UNIT_ID_G2D 8 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/** + * Evaluate a task and set the score and preferred G2D unit. + * Return 1 if task is preferred, 0 otherwise (task is not supported). + */ +static int32_t _g2d_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task); + +/** + * Dispatch a task to the G2D unit. + * Return 1 if task was dispatched, 0 otherwise (task not supported). + */ +static int32_t _g2d_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer); + +/** + * Delete the G2D draw unit. + */ +static int32_t _g2d_delete(lv_draw_unit_t * draw_unit); + +#if LV_USE_G2D_DRAW_THREAD + static void _g2d_render_thread_cb(void * ptr); +#endif + +static void _g2d_execute_drawing(lv_draw_task_t * t); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_g2d_init(void) +{ + lv_draw_buf_g2d_init_handlers(); + + lv_draw_g2d_unit_t * draw_g2d_unit = lv_draw_create_unit(sizeof(lv_draw_g2d_unit_t)); + draw_g2d_unit->base_unit.evaluate_cb = _g2d_evaluate; + draw_g2d_unit->base_unit.dispatch_cb = _g2d_dispatch; + draw_g2d_unit->base_unit.delete_cb = _g2d_delete; + draw_g2d_unit->base_unit.name = "G2D"; + g2d_create_buf_map(); + if(g2d_open(&draw_g2d_unit->g2d_handle)) { + LV_LOG_ERROR("g2d_open fail.\n"); + } +#if LV_USE_G2D_DRAW_THREAD + lv_draw_sw_thread_dsc_t * thread_dsc = &draw_g2d_unit->thread_dsc; + thread_dsc->idx = 0; + thread_dsc->draw_unit = (void *) draw_g2d_unit; + lv_thread_init(&thread_dsc->thread, "g2ddraw", LV_DRAW_THREAD_PRIO, _g2d_render_thread_cb, LV_DRAW_THREAD_STACK_SIZE, + thread_dsc); +#endif +} + +void lv_draw_g2d_deinit(void) +{ + g2d_free_buf_map(); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static inline bool _g2d_dest_cf_supported(lv_color_format_t cf) +{ + bool is_cf_supported = false; + + switch(cf) { + case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_XRGB8888: + is_cf_supported = true; + break; + default: + break; + } + + return is_cf_supported; +} + +static inline bool _g2d_src_cf_supported(lv_draw_unit_t * drawunit, lv_color_format_t cf) +{ + bool is_cf_supported = false; + + switch(cf) { + case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_XRGB8888: + is_cf_supported = true; + break; + case LV_COLOR_FORMAT_RGB565: { + int32_t hw_pxp = 0; + lv_draw_g2d_unit_t * u = (lv_draw_g2d_unit_t *)drawunit; + g2d_query_hardware(u->g2d_handle, G2D_HARDWARE_PXP, &hw_pxp); + if(!hw_pxp) { + is_cf_supported = true; + } + } + break; + default: + break; + } + + return is_cf_supported; +} + +static bool _g2d_draw_img_supported(const lv_draw_image_dsc_t * draw_dsc) +{ + bool is_tiled = draw_dsc->tile; + /* Tiled image (repeat image) is currently not supported. */ + if(is_tiled) + return false; + + bool has_recolor = (draw_dsc->recolor_opa > LV_OPA_MIN); + bool has_rotation = (draw_dsc->rotation != 0); + + /* Recolor or rotation are not supported. */ + if(has_recolor || has_rotation) + return false; + + return true; +} + +static int32_t _g2d_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t) +{ + LV_UNUSED(u); + + const lv_draw_dsc_base_t * draw_dsc_base = (lv_draw_dsc_base_t *) t->draw_dsc; + lv_draw_buf_t * draw_buf = draw_dsc_base->layer->draw_buf; + + if(!_g2d_dest_cf_supported(draw_dsc_base->layer->color_format)) + return 0; + + if(draw_buf && !g2d_search_buf_map(draw_buf->data)) + return 0; + + switch(t->type) { + case LV_DRAW_TASK_TYPE_FILL: { + const lv_draw_fill_dsc_t * draw_dsc = (lv_draw_fill_dsc_t *) t->draw_dsc; + + /* Most simple case: just a plain rectangle (no radius, no gradient). */ + if((draw_dsc->radius != 0) || (draw_dsc->grad.dir != (lv_grad_dir_t)LV_GRAD_DIR_NONE)) + return 0; + + if(t->preference_score > 70) { + t->preference_score = 70; + t->preferred_draw_unit_id = DRAW_UNIT_ID_G2D; + } + return 1; + } + case LV_DRAW_TASK_TYPE_IMAGE: { + const lv_draw_image_dsc_t * draw_dsc = (lv_draw_image_dsc_t *) t->draw_dsc; + + if(!_g2d_src_cf_supported(u, draw_dsc->header.cf)) + return 0; + + if(!_g2d_draw_img_supported(draw_dsc)) + return 0; + + if(t->preference_score > 70) { + t->preference_score = 70; + t->preferred_draw_unit_id = DRAW_UNIT_ID_G2D; + } + return 1; + } + default: + return 0; + } + + return 0; + +} + +static int32_t _g2d_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) +{ + lv_draw_g2d_unit_t * draw_g2d_unit = (lv_draw_g2d_unit_t *) draw_unit; + +#if LV_USE_OS + lv_draw_sw_thread_dsc_t * thread_dsc = &draw_g2d_unit->thread_dsc; + + /* Return immediately if it's busy with draw task. */ + if(thread_dsc->task_act) + return 0; +#else + /* Return immediately if it's busy with draw task. */ + if(draw_g2d_unit->task_act) + return 0; +#endif + + /* Try to get an ready to draw. */ + lv_draw_task_t * t = lv_draw_get_available_task(layer, NULL, DRAW_UNIT_ID_G2D); + + if(t == NULL || t->preferred_draw_unit_id != DRAW_UNIT_ID_G2D) + return LV_DRAW_UNIT_IDLE; + + if(lv_draw_layer_alloc_buf(layer) == NULL) + return LV_DRAW_UNIT_IDLE; + + t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; + t->draw_unit = draw_unit; + +#if LV_USE_G2D_DRAW_THREAD + thread_dsc->task_act = t; + + /* Let the render thread work. */ + if(thread_dsc->inited) + lv_thread_sync_signal(&thread_dsc->sync); +#else + draw_g2d_unit->task_act = t; + + _g2d_execute_drawing(t); + + draw_g2d_unit->task_act->state = LV_DRAW_TASK_STATE_READY; + draw_g2d_unit->task_act = NULL; + + /* The draw unit is free now. Request a new dispatching as it can get a new task. */ + lv_draw_dispatch_request(); +#endif + + return 1; +} + +static int32_t _g2d_delete(lv_draw_unit_t * draw_unit) +{ + lv_draw_g2d_unit_t * draw_g2d_unit = (lv_draw_g2d_unit_t *) draw_unit; + lv_result_t res = LV_RESULT_OK; + +#if LV_USE_G2D_DRAW_THREAD + lv_draw_sw_thread_dsc_t * thread_dsc = &draw_g2d_unit->thread_dsc; + LV_LOG_INFO("Cancel G2D draw thread."); + thread_dsc->exit_status = true; + + if(thread_dsc->inited) + lv_thread_sync_signal(&thread_dsc->sync); + + res = lv_thread_delete(&thread_dsc->thread); +#endif + g2d_close(draw_g2d_unit->g2d_handle); + + return res; +} + +static void _g2d_execute_drawing(lv_draw_task_t * t) +{ + lv_layer_t * layer = t->target_layer; + lv_draw_buf_t * draw_buf = layer->draw_buf; + + /* Invalidate only the drawing area */ + lv_draw_buf_invalidate_cache(draw_buf, NULL); + + switch(t->type) { + case LV_DRAW_TASK_TYPE_FILL: + lv_draw_g2d_fill(t); + break; + case LV_DRAW_TASK_TYPE_IMAGE: + lv_draw_g2d_img(t); + break; + default: + break; + } +} + +#if LV_USE_G2D_DRAW_THREAD +static void _g2d_render_thread_cb(void * ptr) +{ + lv_draw_sw_thread_dsc_t * thread_dsc = ptr; + + lv_thread_sync_init(&thread_dsc->sync); + thread_dsc->inited = true; + + while(1) { + /* Wait for sync if there is no task set. */ + while(thread_dsc->task_act == NULL) { + if(thread_dsc->exit_status) + break; + + lv_thread_sync_wait(&thread_dsc->sync); + } + + if(thread_dsc->exit_status) { + LV_LOG_INFO("Ready to exit G2D draw thread."); + break; + } + + _g2d_execute_drawing(thread_dsc->task_act); + + /* Signal the ready state to dispatcher. */ + thread_dsc->task_act->state = LV_DRAW_TASK_STATE_READY; + + /* Cleanup. */ + thread_dsc->task_act = NULL; + + /* The draw unit is free now. Request a new dispatching as it can get a new task. */ + lv_draw_dispatch_request(); + } + + thread_dsc->inited = false; + lv_thread_sync_delete(&thread_dsc->sync); + LV_LOG_INFO("Exit G2D draw thread."); +} +#endif + +#endif /*LV_USE_DRAW_G2D*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d.h b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d.h new file mode 100644 index 000000000..061aa3c31 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d.h @@ -0,0 +1,71 @@ +/** + * @file lv_draw_g2d.h + * + */ + +/** + * Copyright 2024 NXP + * + * SPDX-License-Identifier: MIT + */ + +#ifndef LV_DRAW_G2D_H +#define LV_DRAW_G2D_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" + +#if LV_USE_DRAW_G2D +#include "../../sw/lv_draw_sw_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct lv_draw_g2d_unit { + lv_draw_unit_t base_unit; +#if LV_USE_OS + lv_draw_sw_thread_dsc_t thread_dsc; +#else + lv_draw_task_t * task_act; +#endif + + void * g2d_handle; +} lv_draw_g2d_unit_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_g2d_init(void); + +void lv_draw_g2d_deinit(void); + +void lv_draw_buf_g2d_init_handlers(void); + +void lv_draw_g2d_fill(lv_draw_task_t * t); + +void lv_draw_g2d_img(lv_draw_task_t * t); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_G2D*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_G2D_H*/ \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d_fill.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d_fill.c new file mode 100644 index 000000000..5863e4d6c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d_fill.c @@ -0,0 +1,178 @@ +/** + * @file lv_draw_g2d_fill.c + * + */ + +/** + * Copyright 2024 NXP + * + * SPDX-License-Identifier: MIT + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_g2d.h" + +#if LV_USE_DRAW_G2D +#include +#include "g2d.h" +#include "../../../misc/lv_area_private.h" +#include "lv_g2d_buf_map.h" +#include "lv_g2d_utils.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/* Blit simple w/ opa and alpha channel */ +static void _g2d_fill(void * g2d_handle, struct g2d_surface * dst_surf); +static void _g2d_fill_with_opa(void * g2d_handle, struct g2d_surface * dst_surf, struct g2d_surface * src_surf); + +static void _g2d_set_src_surf(struct g2d_surface * src_surf, struct g2d_buf * buf, const lv_area_t * area, + lv_color_t color, lv_opa_t opa); + +static void _g2d_set_dst_surf(struct g2d_surface * dst_surf, struct g2d_buf * buf, const lv_area_t * area, + int32_t stride, lv_color_t color); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_g2d_fill(lv_draw_task_t * t) +{ + lv_draw_fill_dsc_t * dsc = t->draw_dsc; + + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) + return; + + lv_draw_g2d_unit_t * u = (lv_draw_g2d_unit_t *)t->draw_unit; + lv_layer_t * layer = t->target_layer; + lv_draw_buf_t * draw_buf = layer->draw_buf; + lv_area_t * coords = &t->area; + + lv_area_t rel_coords; + lv_area_copy(&rel_coords, coords); + lv_area_move(&rel_coords, -layer->buf_area.x1, -layer->buf_area.y1); + + lv_area_t rel_clip_area; + lv_area_copy(&rel_clip_area, &t->clip_area); + 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)) + return; /*Fully clipped, nothing to do*/ + + /* G2D takes stride in pixels. */ + int32_t stride = draw_buf->header.stride / (lv_color_format_get_bpp(draw_buf->header.cf) / 8); + + /* Destination buffer */ + struct g2d_buf * dst_buf = g2d_search_buf_map(draw_buf->data); + + bool has_opa = (dsc->opa < (lv_opa_t)LV_OPA_MAX); + struct g2d_surface dst_surf; + _g2d_set_dst_surf(&dst_surf, dst_buf, &blend_area, stride, dsc->color); + + if(has_opa) { + struct g2d_buf * tmp_buf = g2d_alloc(lv_area_get_width(&blend_area) * lv_area_get_height(&blend_area) * sizeof( + lv_color32_t), 1); + G2D_ASSERT_MSG(tmp_buf, "Failed to alloc temporary buffer."); + struct g2d_surface src_surf; + _g2d_set_src_surf(&src_surf, tmp_buf, &blend_area, dsc->color, dsc->opa); + _g2d_fill_with_opa(u->g2d_handle, &dst_surf, &src_surf); + g2d_free(tmp_buf); + } + else { + _g2d_fill(u->g2d_handle, &dst_surf); + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void _g2d_set_src_surf(struct g2d_surface * src_surf, struct g2d_buf * buf, const lv_area_t * area, + lv_color_t color, lv_opa_t opa) +{ + int32_t width = lv_area_get_width(area); + int32_t height = lv_area_get_height(area); + + src_surf->format = G2D_RGBA8888; + + src_surf->left = 0; + src_surf->top = 0; + src_surf->right = width; + src_surf->bottom = height; + src_surf->stride = width; + src_surf->width = width; + src_surf->height = height; + + src_surf->planes[0] = buf->buf_paddr; + src_surf->rot = G2D_ROTATION_0; + + src_surf->clrcolor = g2d_rgba_to_u32(color); + src_surf->global_alpha = opa; + src_surf->blendfunc = G2D_ONE | G2D_PRE_MULTIPLIED_ALPHA; +} + +static void _g2d_set_dst_surf(struct g2d_surface * dst_surf, struct g2d_buf * buf, const lv_area_t * area, + int32_t stride, lv_color_t color) +{ + int32_t width = lv_area_get_width(area); + int32_t height = lv_area_get_height(area); + + dst_surf->format = G2D_RGBA8888; + + dst_surf->left = area->x1; + dst_surf->top = area->y1; + dst_surf->right = area->x1 + width; + dst_surf->bottom = area->y1 + height; + dst_surf->stride = stride; + dst_surf->width = width; + dst_surf->height = height; + + dst_surf->planes[0] = buf->buf_paddr; + dst_surf->rot = G2D_ROTATION_0; + + dst_surf->clrcolor = g2d_rgba_to_u32(color); + dst_surf->global_alpha = 0xff; + dst_surf->blendfunc = G2D_ONE_MINUS_SRC_ALPHA | G2D_PRE_MULTIPLIED_ALPHA; +} + +static void _g2d_fill_with_opa(void * g2d_handle, struct g2d_surface * dst_surf, struct g2d_surface * src_surf) +{ + g2d_clear(g2d_handle, src_surf); + + g2d_enable(g2d_handle, G2D_BLEND); + g2d_enable(g2d_handle, G2D_GLOBAL_ALPHA); + g2d_blit(g2d_handle, src_surf, dst_surf); + g2d_finish(g2d_handle); + g2d_disable(g2d_handle, G2D_GLOBAL_ALPHA); + g2d_disable(g2d_handle, G2D_BLEND); +} + +static void _g2d_fill(void * g2d_handle, struct g2d_surface * dst_surf) +{ + g2d_clear(g2d_handle, dst_surf); + + g2d_finish(g2d_handle); +} + +#endif /*LV_USE_DRAW_G2D*/ \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d_img.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d_img.c new file mode 100644 index 000000000..3b7093484 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_draw_g2d_img.c @@ -0,0 +1,214 @@ +/** + * @file lv_draw_g2d_img.c + * + */ + +/** + * Copyright 2024 NXP + * + * SPDX-License-Identifier: MIT + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_g2d.h" + +#if LV_USE_DRAW_G2D +#include +#include +#include "g2d.h" +#include "../../../misc/lv_area_private.h" +#include "lv_g2d_utils.h" +#include "lv_g2d_buf_map.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static struct g2d_buf * _g2d_handle_src_buf(const lv_image_dsc_t * data); + +static void _g2d_set_src_surf(struct g2d_surface * src_surf, struct g2d_buf * buf, const lv_area_t * area, + int32_t stride, lv_color_format_t cf, lv_opa_t opa); + +static void _g2d_set_dst_surf(struct g2d_surface * dst_surf, struct g2d_buf * buf, const lv_area_t * area, + int32_t stride, lv_color_format_t cf, const lv_draw_image_dsc_t * dsc); + +/* Blit simple w/ opa and alpha channel */ +static void _g2d_blit(void * g2d_handle, struct g2d_surface * dst_surf, struct g2d_surface * src_surf); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_g2d_img(lv_draw_task_t * t) +{ + lv_draw_image_dsc_t * dsc = t->draw_dsc; + + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) + return; + + lv_draw_g2d_unit_t * u = (lv_draw_g2d_unit_t *)t->draw_unit; + lv_layer_t * layer = t->target_layer; + lv_draw_buf_t * draw_buf = layer->draw_buf; + const lv_image_dsc_t * img_dsc = dsc->src; + lv_area_t * coords = &t->area; + + lv_area_t rel_coords; + lv_area_copy(&rel_coords, coords); + lv_area_move(&rel_coords, -layer->buf_area.x1, -layer->buf_area.y1); + + lv_area_t clip_area; + lv_area_copy(&clip_area, &t->clip_area); + lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); + + lv_area_t blend_area; + 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, &clip_area)) + return; /*Fully clipped, nothing to do*/ + + lv_area_t src_area; + src_area.x1 = blend_area.x1 - (coords->x1 - layer->buf_area.x1); + src_area.y1 = blend_area.y1 - (coords->y1 - layer->buf_area.y1); + src_area.x2 = src_area.x1 + lv_area_get_width(&blend_area); + src_area.y2 = src_area.y1 + lv_area_get_height(&blend_area); + int32_t src_stride = img_dsc->header.stride / (lv_color_format_get_bpp(img_dsc->header.cf) / 8); + lv_color_format_t src_cf = img_dsc->header.cf; + + /* Source image */ + struct g2d_buf * src_buf = _g2d_handle_src_buf(img_dsc); + + /* Destination buffer */ + struct g2d_buf * dst_buf = g2d_search_buf_map(draw_buf->data); + + /* G2D takes stride in pixels. */ + int32_t dest_stride = draw_buf->header.stride / (lv_color_format_get_bpp(draw_buf->header.cf) / 8); + lv_color_format_t dest_cf = draw_buf->header.cf; + + struct g2d_surface src_surf; + struct g2d_surface dst_surf; + + _g2d_set_src_surf(&src_surf, src_buf, &src_area, src_stride, src_cf, dsc->opa); + _g2d_set_dst_surf(&dst_surf, dst_buf, &blend_area, dest_stride, dest_cf, dsc); + + _g2d_blit(u->g2d_handle, &dst_surf, &src_surf); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static struct g2d_buf * _g2d_handle_src_buf(const lv_image_dsc_t * img_dsc) +{ + struct g2d_buf * src_buf = g2d_search_buf_map((void *)img_dsc->data); + + if(src_buf == NULL) { + src_buf = g2d_alloc(img_dsc->data_size, 1); + G2D_ASSERT_MSG(src_buf, "Failed to alloc source buffer."); + memcpy((uint8_t *)src_buf->buf_vaddr, img_dsc->data, img_dsc->data_size); + g2d_cache_op(src_buf, G2D_CACHE_FLUSH); + g2d_insert_buf_map((void *)img_dsc->data, src_buf); + } + + return src_buf; +} + +static void _g2d_set_src_surf(struct g2d_surface * src_surf, struct g2d_buf * buf, const lv_area_t * area, + int32_t stride, lv_color_format_t cf, lv_opa_t opa) +{ + src_surf->format = g2d_get_buf_format(cf); + + src_surf->left = area->x1; + src_surf->top = area->y1; + src_surf->right = area->x2; + src_surf->bottom = area->y2; + src_surf->stride = stride; + src_surf->width = area->x2 - area->x1; + src_surf->height = area->y2 - area->y1; + + src_surf->planes[0] = buf->buf_paddr; + src_surf->rot = G2D_ROTATION_0; + + src_surf->clrcolor = g2d_rgba_to_u32(lv_color_black()); + src_surf->global_alpha = opa; + src_surf->blendfunc = G2D_ONE | G2D_PRE_MULTIPLIED_ALPHA; +} + +static void _g2d_set_dst_surf(struct g2d_surface * dst_surf, struct g2d_buf * buf, const lv_area_t * area, + int32_t stride, lv_color_format_t cf, const lv_draw_image_dsc_t * dsc) +{ + int32_t width = lv_area_get_width(area); + int32_t height = lv_area_get_height(area); + + lv_point_t pivot = dsc->pivot; + /*The offsets are now relative to the transformation result with pivot ULC*/ + int32_t piv_offset_x = 0; + int32_t piv_offset_y = 0; + int32_t trim_x = 0; + int32_t trim_y = 0; + int32_t dest_w; + int32_t dest_h; + + float fp_scale_x = (float)dsc->scale_x / LV_SCALE_NONE; + float fp_scale_y = (float)dsc->scale_y / LV_SCALE_NONE; + int32_t int_scale_x = (int32_t)fp_scale_x; + int32_t int_scale_y = (int32_t)fp_scale_y; + + /*Any scale_factor in (k, k + 1] will result in a trim equal to k*/ + trim_x = (fp_scale_x == int_scale_x) ? int_scale_x - 1 : int_scale_x; + trim_y = (fp_scale_y == int_scale_y) ? int_scale_y - 1 : int_scale_y; + + dest_w = width * fp_scale_x + trim_x; + dest_h = height * 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); + + dst_surf->format = g2d_get_buf_format(cf); + + dst_surf->left = area->x1 + piv_offset_x; + dst_surf->top = area->y1 + piv_offset_y; + dst_surf->right = area->x1 + piv_offset_x + dest_w - trim_x; + dst_surf->bottom = area->y1 + piv_offset_y + dest_h - trim_y; + dst_surf->stride = stride; + dst_surf->width = dest_w - trim_x; + dst_surf->height = dest_h - trim_y; + + dst_surf->planes[0] = buf->buf_paddr; + dst_surf->rot = G2D_ROTATION_0; + + dst_surf->clrcolor = g2d_rgba_to_u32(lv_color_black()); + dst_surf->global_alpha = 0xff; + dst_surf->blendfunc = G2D_ONE_MINUS_SRC_ALPHA | G2D_PRE_MULTIPLIED_ALPHA; +} + +static void _g2d_blit(void * g2d_handle, struct g2d_surface * dst_surf, struct g2d_surface * src_surf) +{ + g2d_enable(g2d_handle, G2D_BLEND); + g2d_enable(g2d_handle, G2D_GLOBAL_ALPHA); + g2d_blit(g2d_handle, src_surf, dst_surf); + g2d_finish(g2d_handle); + g2d_disable(g2d_handle, G2D_GLOBAL_ALPHA); + g2d_disable(g2d_handle, G2D_BLEND); +} +#endif /*LV_USE_DRAW_G2D*/ \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_buf_map.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_buf_map.c new file mode 100644 index 000000000..00de516f6 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_buf_map.c @@ -0,0 +1,247 @@ +/** + * @file lv_g2d_buf_map.c + * + */ + +/** + * Copyright 2024 NXP + * + * SPDX-License-Identifier: MIT + */ + +#include "lv_g2d_buf_map.h" + +#if LV_USE_DRAW_G2D +#include +#include "lv_g2d_utils.h" +#include "g2d.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static unsigned long _map_hash_function(void * ptr); + +static lv_map_item_t * _map_create_item(void * key, struct g2d_buf * value); + +static void _map_free_item(lv_map_item_t * item); + +static void _handle_collision(unsigned long index, lv_map_item_t * item); + +/********************** + * STATIC VARIABLES + **********************/ + +static lv_buf_map_t * table; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void g2d_create_buf_map(void) +{ + table = (lv_buf_map_t *) lv_malloc(sizeof(lv_buf_map_t)); + table->size = LV_G2D_HASH_TABLE_SIZE; + table->count = 0; + table->items = (lv_map_item_t **) lv_malloc_zeroed(table->size * sizeof(lv_map_item_t *)); + table->overflow_list = (lv_array_t **) lv_malloc_zeroed(table->size * sizeof(lv_array_t *)); +} + +void g2d_free_buf_map(void) +{ + for(int i = 0; i < table->size; i++) { + if(table->overflow_list[i]) { + lv_array_deinit(table->overflow_list[i]); + lv_free(table->overflow_list[i]); + } + + lv_map_item_t * item = table->items[i]; + if(item != NULL) + _map_free_item(item); + } + + lv_free(table->items); + lv_free(table->overflow_list); + lv_free(table); +} + +void g2d_insert_buf_map(void * key, struct g2d_buf * value) +{ + lv_map_item_t * item = _map_create_item(key, value); + int index = _map_hash_function(key); + + if(table->items[index] == NULL) { + /* Key not found. */ + if(table->count == table->size) { + /* Table is full. */ + _map_free_item(item); + G2D_ASSERT_MSG(false, "Hash table is full."); + return; + } + } + else { + if(table->items[index]->key == key) { + /* Key already exists, update value. */ + table->items[index]->value = value; + return; + } + else { + /* Handle the collision */ + _handle_collision(index, item); + return; + } + } + + /* Insert item. */ + table->items[index] = item; + table->count++; +} + +struct g2d_buf * g2d_search_buf_map(void * key) +{ + int index = _map_hash_function(key); + lv_map_item_t * item = table->items[index]; + lv_array_t * list = (lv_array_t *)table->overflow_list[index]; + + if(item == NULL) + return NULL; + + if(item->key == key) + return item->value; + + if(list == NULL) + return NULL; + + for(uint32_t i = 0; i < lv_array_size(list); i++) { + item = (lv_map_item_t *)lv_array_at(list, i); + if(item->key == key) + return item->value; + } + + return NULL; +} + +void g2d_free_item(void * key) +{ + /* Delete an item from the table. */ + int index = _map_hash_function(key); + lv_map_item_t * item = table->items[index]; + lv_array_t * list = (lv_array_t *)table->overflow_list[index]; + + if(item == NULL) { + return; + } + else if(list == NULL && item->key == key) { + /* No collision chain, just remove item. */ + table->items[index] = NULL; + _map_free_item(item); + table->count--; + return; + } + else if(list != NULL) { + /* Collision chain exists. */ + for(uint32_t i = 0; i < lv_array_size(list); i++) { + item = (lv_map_item_t *)lv_array_at(list, i); + if(item->key == key) { + lv_array_remove(list, i); + return; + } + } + } +} + +void g2d_print_table(void) +{ + LV_LOG("\nHash Table\n-------------------\n"); + + for(int i = 0; i < table->size; i++) { + if(table->items[i]) { + LV_LOG("Index:%d, Key:%p, Value:%p\n", i, table->items[i] -> key, (void *)table->items[i]->value); + if(table->overflow_list[i]) { + for(uint32_t j = 0 ; j < lv_array_size(table->overflow_list[i]); j++) { + lv_map_item_t * item = (lv_map_item_t *)lv_array_at(table->overflow_list[i], j); + LV_LOG("Index:%d, Key:%p, Value:%p\n", i, item -> key, (void *)item->value); + } + + } + } + } + + LV_LOG("-------------------\n\n"); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static unsigned long _map_hash_function(void * ptr) +{ + unsigned long i = 0; + char str[64]; + G2D_ASSERT_MSG(ptr, "Key is null."); + sprintf(str, "%p", ptr); + + for(int j = 0; str[j]; j++) + i += str[j]; + + return i % LV_G2D_HASH_TABLE_SIZE; +} + +static void _handle_collision(unsigned long index, lv_map_item_t * item) +{ + if(table->overflow_list[index] == NULL) { + /* Create the list. */ + lv_array_t * list = (lv_array_t *) lv_malloc(sizeof(lv_array_t));; + lv_array_init(list, LV_ARRAY_DEFAULT_CAPACITY, sizeof(lv_map_item_t)); + lv_array_push_back(list, item); + table->overflow_list[index] = list; + return; + } + else { + lv_array_t * list = (lv_array_t *)table->overflow_list[index]; + for(uint32_t i = 0; i < lv_array_size(list); i++) { + lv_map_item_t * it = (lv_map_item_t *)lv_array_at(list, i); + if(it->key == item->key) { + /* Key exists, update value. */ + it->value = item->value; + return; + } + } + /* Insert to the list. */ + lv_array_push_back(table->overflow_list[index], item); + return; + } +} + +static lv_map_item_t * _map_create_item(void * key, struct g2d_buf * value) +{ + lv_map_item_t * item = (lv_map_item_t *) lv_malloc(sizeof(lv_map_item_t)); + G2D_ASSERT_MSG(item, "Failed to alloc item."); + item->key = key; + item->value = value; + return item; +} + +static void _map_free_item(lv_map_item_t * item) +{ + /* Also free the g2d_buf. */ + g2d_free(item->value); + item->key = NULL; + item->value = NULL; + lv_free(item); + item = NULL; +} + +#endif /*LV_USE_DRAW_G2D*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_buf_map.h b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_buf_map.h new file mode 100644 index 000000000..6e2196d30 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_buf_map.h @@ -0,0 +1,81 @@ + +/** + * @file lv_g2d_buf_map.h + * + */ + +/** + * Copyright 2024 NXP + * + * SPDX-License-Identifier: MIT + */ + +#ifndef LV_G2D_BUF_MAP_H +#define LV_G2D_BUF_MAP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" + +#if LV_USE_DRAW_G2D + +#include "../../../misc/lv_array.h" +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/* Map item definition. */ +typedef struct lv_map_item { + /* Virtual address buffer. */ + void * key; + struct g2d_buf * value; +} lv_map_item_t; + +/*Buf map definition. */ +typedef struct lv_buf_map { + lv_map_item_t ** items; + lv_array_t ** overflow_list; + + int size; + int count; +} lv_buf_map_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void g2d_create_buf_map(void); + +void g2d_free_buf_map(void); + +void g2d_insert_buf_map(void * key, struct g2d_buf * value); + +struct g2d_buf * g2d_search_buf_map(void * key); + +void g2d_free_item(void * key); + +void g2d_print_table(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_G2D*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_G2D_BUF_MAP_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_utils.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_utils.c new file mode 100644 index 000000000..c353040d2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_utils.c @@ -0,0 +1,97 @@ +/** + * @file lv_g2d_utils.c + * + */ + +/** + * Copyright 2024 NXP + * + * SPDX-License-Identifier: MIT + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_g2d_utils.h" + +#if LV_USE_DRAW_G2D +#include "lv_g2d_buf_map.h" +#include "lv_draw_g2d.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** +* MACROS +**********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +g2d_format_t g2d_get_buf_format(lv_color_format_t cf) +{ + g2d_format_t color_f = G2D_RGB565; + + switch(cf) { + case LV_COLOR_FORMAT_RGB565: + color_f = G2D_RGB565; + break; + case LV_COLOR_FORMAT_ARGB8888: + color_f = G2D_BGRA8888; + break; + case LV_COLOR_FORMAT_XRGB8888: + color_f = G2D_BGRX8888; + break; + case LV_COLOR_FORMAT_RGB888: + color_f = G2D_BGR888; + break; + case LV_COLOR_FORMAT_NV12: + color_f = G2D_NV12; + break; + case LV_COLOR_FORMAT_I420: + color_f = G2D_I420; + break; + case LV_COLOR_FORMAT_NV21: + color_f = G2D_NV21; + break; + case LV_COLOR_FORMAT_YUY2: + color_f = G2D_YUYV; + break; + case LV_COLOR_FORMAT_UYVY: + color_f = G2D_UYVY; + break; + default: + G2D_ASSERT_MSG(false, "Unsupported color format."); + break; + } + return color_f; +} + +uint32_t g2d_rgba_to_u32(lv_color_t color) +{ + return (uint32_t)((color.red) + (color.green << 8) + (color.blue << 16) + ((uint32_t)0xff << 24)); +} + +int32_t g2d_get_buf_fd(const lv_draw_buf_t * draw_buf) +{ + struct g2d_buf * buf = g2d_search_buf_map(draw_buf->data); + G2D_ASSERT_MSG(buf, "Failed to find buffer in map."); + return g2d_buf_export_fd(buf); +} + +/********************** +* STATIC FUNCTIONS +**********************/ + +#endif /*LV_USE_DRAW_G2D*/ \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_utils.h b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_utils.h new file mode 100644 index 000000000..f3923e150 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/g2d/lv_g2d_utils.h @@ -0,0 +1,72 @@ +/** + * @file lv_g2d_utils.h + * + */ + +/** + * Copyright 2024 NXP + * + * SPDX-License-Identifier: MIT + */ + +#ifndef LV_G2D_UTILS_H +#define LV_G2D_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../../lv_conf_internal.h" + +#if LV_USE_DRAW_G2D +#include "../../sw/lv_draw_sw_private.h" +#include "g2d.h" +#include "g2dExt.h" + +/********************* + * DEFINES + *********************/ + +#if LV_USE_G2D_ASSERT +#define G2D_ASSERT(expr) LV_ASSERT(expr) +#else +#define G2D_ASSERT(expr) +#endif + +#define G2D_ASSERT_MSG(expr, msg) \ + do { \ + if(!(expr)) { \ + LV_LOG_ERROR(msg); \ + G2D_ASSERT(false); \ + } \ + } while(0) + +/********************** + * TYPEDEFS + **********************/ + +typedef enum g2d_format g2d_format_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +g2d_format_t g2d_get_buf_format(lv_color_format_t cf); + +uint32_t g2d_rgba_to_u32(lv_color_t color); + +int32_t g2d_get_buf_fd(const lv_draw_buf_t * draw_buf); +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_G2D*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_G2D_UTILS_H*/ \ No newline at end of file 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 636fe4379..6bcbe82ac 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 @@ -92,9 +92,10 @@ void lv_draw_pxp_init(void) draw_pxp_unit->base_unit.evaluate_cb = _pxp_evaluate; draw_pxp_unit->base_unit.dispatch_cb = _pxp_dispatch; draw_pxp_unit->base_unit.delete_cb = _pxp_delete; + draw_pxp_unit->base_unit.name = "NXP_PXP"; #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); + lv_thread_init(&draw_pxp_unit->thread, "pxpdraw", LV_DRAW_THREAD_PRIO, _pxp_render_thread_cb, 2 * 1024, draw_pxp_unit); #endif #endif /*LV_USE_DRAW_PXP*/ } @@ -209,6 +210,11 @@ static bool _pxp_draw_img_supported(const lv_draw_image_dsc_t * draw_dsc) { const lv_image_dsc_t * img_dsc = draw_dsc->src; + bool is_tiled = draw_dsc->tile; + /* Tiled image (repeat image) is currently not supported. */ + if(is_tiled) + return false; + bool has_recolor = (draw_dsc->recolor_opa > LV_OPA_MIN); bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE || draw_dsc->scale_y != LV_SCALE_NONE); @@ -294,7 +300,7 @@ 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) + if(img_dsc->header.cf >= LV_COLOR_FORMAT_PROPRIETARY_START) return 0; if((!_pxp_src_cf_supported(img_dsc->header.cf)) || @@ -326,7 +332,7 @@ static int32_t _pxp_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) return 0; /* Try to get an ready to draw. */ - lv_draw_task_t * t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_PXP); + lv_draw_task_t * t = lv_draw_get_available_task(layer, NULL, DRAW_UNIT_ID_PXP); if(t == NULL || t->preferred_draw_unit_id != DRAW_UNIT_ID_PXP) return LV_DRAW_UNIT_IDLE; @@ -335,8 +341,6 @@ static int32_t _pxp_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) 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_PXP_DRAW_THREAD @@ -380,12 +384,11 @@ static int32_t _pxp_delete(lv_draw_unit_t * draw_unit) static void _pxp_execute_drawing(lv_draw_pxp_unit_t * u) { lv_draw_task_t * t = u->task_act; - lv_draw_unit_t * draw_unit = (lv_draw_unit_t *)u; - lv_layer_t * layer = draw_unit->target_layer; + lv_layer_t * layer = t->target_layer; 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, &t->clip_area)) return; /*Fully clipped, nothing to do*/ /* Make area relative to the buffer */ @@ -394,15 +397,19 @@ static void _pxp_execute_drawing(lv_draw_pxp_unit_t * u) /* Invalidate only the drawing area */ lv_draw_buf_invalidate_cache(draw_buf, &draw_area); +#if LV_USE_PARALLEL_DRAW_DEBUG + t->draw_unit = &u->base_unit; +#endif + switch(t->type) { case LV_DRAW_TASK_TYPE_FILL: - lv_draw_pxp_fill(draw_unit, t->draw_dsc, &t->area); + lv_draw_pxp_fill(t); break; case LV_DRAW_TASK_TYPE_IMAGE: - lv_draw_pxp_img(draw_unit, t->draw_dsc, &t->area); + lv_draw_pxp_img(t); break; case LV_DRAW_TASK_TYPE_LAYER: - lv_draw_pxp_layer(draw_unit, t->draw_dsc, &t->area); + lv_draw_pxp_layer(t); break; default: break; @@ -412,15 +419,11 @@ 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, &t->clip_area)) return; - int32_t idx = 0; - lv_draw_unit_t * draw_unit_tmp = _draw_info.unit_head; - while(draw_unit_tmp != (lv_draw_unit_t *)u) { - draw_unit_tmp = draw_unit_tmp->next; - idx++; - } + int32_t idx = u->base_unit.idx; + 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); diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.h b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.h index d34ad3f84..38b7e3ca7 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/pxp/lv_draw_pxp.h @@ -24,7 +24,8 @@ extern "C" { #if LV_USE_PXP #if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP -#include "../../sw/lv_draw_sw_private.h" +#include "../../lv_draw_private.h" +#include "../../../display/lv_display_private.h" #include "../../../misc/lv_area_private.h" /********************* @@ -35,7 +36,16 @@ extern "C" { * TYPEDEFS **********************/ -typedef lv_draw_sw_unit_t lv_draw_pxp_unit_t; +typedef struct lv_draw_pxp_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 +} lv_draw_pxp_unit_t; /********************** * GLOBAL PROTOTYPES @@ -52,14 +62,11 @@ void lv_draw_pxp_rotate(const void * src_buf, void * dest_buf, int32_t src_width #if LV_USE_DRAW_PXP void lv_draw_buf_pxp_init_handlers(void); -void lv_draw_pxp_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, - const lv_area_t * coords); +void lv_draw_pxp_fill(lv_draw_task_t * t); -void lv_draw_pxp_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc, - const lv_area_t * coords); +void lv_draw_pxp_img(lv_draw_task_t * t); -void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, - const lv_area_t * coords); +void lv_draw_pxp_layer(lv_draw_task_t * t); /********************** * MACROS 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 33b80473c..6aa315956 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 @@ -47,13 +47,15 @@ static void _pxp_fill(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t d * GLOBAL FUNCTIONS **********************/ -void lv_draw_pxp_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, - const lv_area_t * coords) +void lv_draw_pxp_fill(lv_draw_task_t * t) { + const lv_draw_fill_dsc_t * dsc = t->draw_dsc; + const lv_area_t * coords = &t->area; + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) return; - lv_layer_t * layer = draw_unit->target_layer; + lv_layer_t * layer = t->target_layer; lv_draw_buf_t * draw_buf = layer->draw_buf; lv_area_t rel_coords; @@ -61,7 +63,7 @@ void lv_draw_pxp_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc lv_area_move(&rel_coords, -layer->buf_area.x1, -layer->buf_area.y1); lv_area_t rel_clip_area; - lv_area_copy(&rel_clip_area, draw_unit->clip_area); + lv_area_copy(&rel_clip_area, &t->clip_area); lv_area_move(&rel_clip_area, -layer->buf_area.x1, -layer->buf_area.y1); lv_area_t blend_area; 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 79f3790e9..320eaed2e 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 @@ -61,13 +61,15 @@ static void _pxp_blit(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t d * GLOBAL FUNCTIONS **********************/ -void lv_draw_pxp_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc, - const lv_area_t * coords) +void lv_draw_pxp_img(lv_draw_task_t * t) { + const lv_draw_image_dsc_t * dsc = t->draw_dsc; + const lv_area_t * coords = &t->area; + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) return; - lv_layer_t * layer = draw_unit->target_layer; + lv_layer_t * layer = t->target_layer; lv_draw_buf_t * draw_buf = layer->draw_buf; const lv_image_dsc_t * img_dsc = dsc->src; @@ -76,7 +78,7 @@ void lv_draw_pxp_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc lv_area_move(&rel_coords, -layer->buf_area.x1, -layer->buf_area.y1); lv_area_t rel_clip_area; - lv_area_copy(&rel_clip_area, draw_unit->clip_area); + lv_area_copy(&rel_clip_area, &t->clip_area); lv_area_move(&rel_clip_area, -layer->buf_area.x1, -layer->buf_area.y1); lv_area_t blend_area; @@ -91,8 +93,8 @@ void lv_draw_pxp_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc lv_area_t src_area; src_area.x1 = blend_area.x1 - (coords->x1 - layer->buf_area.x1); src_area.y1 = blend_area.y1 - (coords->y1 - layer->buf_area.y1); - src_area.x2 = src_area.x1 + lv_area_get_width(coords) - 1; - src_area.y2 = src_area.y1 + lv_area_get_height(coords) - 1; + src_area.x2 = src_area.x1 + lv_area_get_width(&blend_area) - 1; + src_area.y2 = src_area.y1 + lv_area_get_height(&blend_area) - 1; int32_t src_stride = img_dsc->header.stride; lv_color_format_t src_cf = img_dsc->header.cf; 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 34cb285b7..f515a20b5 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 @@ -51,9 +51,10 @@ * GLOBAL FUNCTIONS **********************/ -void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, - const lv_area_t * coords) +void lv_draw_pxp_layer(lv_draw_task_t * t) { + lv_draw_image_dsc_t * draw_dsc = t->draw_dsc; + lv_layer_t * layer_to_draw = (lv_layer_t *)draw_dsc->src; const lv_draw_buf_t * draw_buf = layer_to_draw->draw_buf; @@ -73,9 +74,12 @@ void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * d lv_draw_image_dsc_t new_draw_dsc = *draw_dsc; new_draw_dsc.src = draw_buf; - lv_draw_pxp_img(draw_unit, &new_draw_dsc, coords); + t->draw_dsc = &new_draw_dsc; + lv_draw_pxp_img(t); + t->draw_dsc = draw_dsc; #if LV_USE_LAYER_DEBUG || LV_USE_PARALLEL_DRAW_DEBUG + const lv_area_t * coords = &t->area; lv_area_t area_rot; lv_area_copy(&area_rot, coords); if(draw_dsc->rotation || draw_dsc->scale_x != LV_SCALE_NONE || draw_dsc->scale_y != LV_SCALE_NONE) { @@ -91,7 +95,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, &t->clip_area)) return; #endif #if LV_USE_LAYER_DEBUG @@ -99,37 +103,32 @@ void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * d lv_draw_fill_dsc_init(&fill_dsc); fill_dsc.color = lv_color_hex(layer_to_draw->color_format == LV_COLOR_FORMAT_ARGB8888 ? 0xff0000 : 0x00ff00); fill_dsc.opa = LV_OPA_20; - lv_draw_sw_fill(draw_unit, &fill_dsc, &area_rot); + lv_draw_sw_fill(t, &fill_dsc, &area_rot); lv_draw_border_dsc_t border_dsc; lv_draw_border_dsc_init(&border_dsc); border_dsc.color = fill_dsc.color; border_dsc.opa = LV_OPA_60; border_dsc.width = 2; - lv_draw_sw_border(draw_unit, &border_dsc, &area_rot); + lv_draw_sw_border(t, &border_dsc, &area_rot); #endif #if LV_USE_PARALLEL_DRAW_DEBUG - uint32_t idx = 0; - lv_draw_unit_t * draw_unit_tmp = _draw_info.unit_head; - while(draw_unit_tmp != draw_unit) { - draw_unit_tmp = draw_unit_tmp->next; - idx++; - } + int32_t idx = t->draw_unit->idx; 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.opa = LV_OPA_10; - lv_draw_sw_fill(draw_unit, &fill_dsc, &area_rot); + lv_draw_sw_fill(t, &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.opa = LV_OPA_100; border_dsc.width = 2; - lv_draw_sw_border(draw_unit, &border_dsc, &area_rot); + lv_draw_sw_border(t, &border_dsc, &area_rot); lv_point_t txt_size; lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE); @@ -142,7 +141,7 @@ void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * d lv_draw_fill_dsc_init(&fill_dsc); fill_dsc.color = lv_color_black(); - lv_draw_sw_fill(draw_unit, &fill_dsc, &txt_area); + lv_draw_sw_fill(t, &fill_dsc, &txt_area); char buf[8]; lv_snprintf(buf, sizeof(buf), "%d", idx); @@ -150,7 +149,7 @@ void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * d lv_draw_label_dsc_init(&label_dsc); label_dsc.color = lv_color_white(); label_dsc.text = buf; - lv_draw_sw_label(draw_unit, &label_dsc, &txt_area); + lv_draw_sw_label(t, &label_dsc, &txt_area); #endif } 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 85403956f..f42bf6fb1 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 @@ -121,11 +121,11 @@ 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_bits = LV_ROUND_UP(w * bits_per_pixel, 8); uint32_t width_bytes = width_bits / 8; uint8_t align_bytes = vglite_get_stride_alignment(cf); - return (width_bytes + align_bytes - 1) & ~(align_bytes - 1); + return LV_ROUND_UP(width_bytes, align_bytes); } #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 c6fc016f4..55f711213 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 @@ -39,16 +39,18 @@ /** * Structure of pending vglite draw task */ -typedef struct _vglite_draw_task_t { - lv_draw_task_t * task; +typedef struct _vglite_flush_task { + vglite_draw_task_t * task; bool flushed; -} vglite_draw_tasks_t; +} vglite_flush_task_t; #endif /********************** * STATIC PROTOTYPES **********************/ +static inline void _vglite_cleanup_task(vglite_draw_task_t * task); + /* * Evaluate a task and set the score and preferred VGLite draw unit. * Return 1 if task is preferred, 0 otherwise (task is not supported). @@ -91,7 +93,7 @@ static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u); * Two indexes, _head and _tail, are used to signal the beginning * and the end of the valid tasks that are pending. */ - static vglite_draw_tasks_t _draw_task_buf[VGLITE_TASK_BUF_SIZE]; + static vglite_flush_task_t _draw_task_buf[VGLITE_TASK_BUF_SIZE]; static volatile int _head = 0; static volatile int _tail = 0; #endif @@ -115,9 +117,11 @@ void lv_draw_vglite_init(void) draw_vglite_unit->base_unit.wait_for_finish_cb = _vglite_wait_for_finish; #endif draw_vglite_unit->base_unit.delete_cb = _vglite_delete; + draw_vglite_unit->base_unit.name = "NXP_VGLITE"; #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); + lv_thread_init(&draw_vglite_unit->thread, "vglitedraw", LV_DRAW_THREAD_PRIO, _vglite_render_thread_cb, 4 * 1024, + draw_vglite_unit); #endif } @@ -145,7 +149,7 @@ static inline bool _vglite_src_cf_supported(lv_color_format_t cf) case LV_COLOR_FORMAT_L8: case LV_COLOR_FORMAT_RGB565: #if CHIPID == 0x555 - case LV_COLOR_FORMAT_RGB565A8: + case LV_COLOR_FORMAT_ARGB8565: case LV_COLOR_FORMAT_RGB888: #endif case LV_COLOR_FORMAT_ARGB8888: @@ -170,7 +174,7 @@ static inline bool _vglite_dest_cf_supported(lv_color_format_t cf) #endif case LV_COLOR_FORMAT_RGB565: #if CHIPID == 0x555 - case LV_COLOR_FORMAT_RGB565A8: + case LV_COLOR_FORMAT_ARGB8565: case LV_COLOR_FORMAT_RGB888: #endif case LV_COLOR_FORMAT_ARGB8888: @@ -251,14 +255,23 @@ static int32_t _vglite_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(img_dsc->header.cf >= LV_COLOR_FORMAT_PROPRIETARY_START) { + return 0; + } + +#if CHIPID == 0x255 + if(draw_dsc->tile) + return 0; +#endif #if LV_USE_VGLITE_BLIT_SPLIT bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE || draw_dsc->scale_y != LV_SCALE_NONE); + bool is_tiled = draw_dsc->tile; #endif if((!_vglite_src_cf_supported(img_dsc->header.cf)) #if LV_USE_VGLITE_BLIT_SPLIT - || has_transform + || has_transform || is_tiled #endif || (!vglite_src_buf_aligned(img_dsc->data, img_dsc->header.stride, img_dsc->header.cf)) ) @@ -281,12 +294,16 @@ static int32_t _vglite_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) { lv_draw_vglite_unit_t * draw_vglite_unit = (lv_draw_vglite_unit_t *) draw_unit; - /* Return immediately if it's busy with draw task. */ - if(draw_vglite_unit->task_act) + /* Return immediately if draw unit is busy. */ + if(draw_vglite_unit->task_act +#if LV_USE_VGLITE_DRAW_ASYNC + || draw_vglite_unit->wait_for_finish +#endif + ) return 0; /* Try to get an ready to draw. */ - lv_draw_task_t * t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_VGLITE); + lv_draw_task_t * t = lv_draw_get_available_task(layer, NULL, DRAW_UNIT_ID_VGLITE); if(t == NULL) return LV_DRAW_UNIT_IDLE; @@ -305,14 +322,15 @@ static int32_t _vglite_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) return 1; } } + vglite_draw_task_t * vglite_task = lv_malloc_zeroed(sizeof(vglite_draw_task_t)); + LV_ASSERT_MALLOC(vglite_task); + + vglite_task->t = t; if(lv_draw_layer_alloc_buf(layer) == NULL) 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; + draw_vglite_unit->task_act = vglite_task; #if LV_USE_VGLITE_DRAW_THREAD /* Let the render thread work. */ @@ -321,7 +339,8 @@ static int32_t _vglite_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) #else _vglite_execute_drawing(draw_vglite_unit); - draw_vglite_unit->task_act->state = LV_DRAW_TASK_STATE_READY; + draw_vglite_unit->task_act->t->state = LV_DRAW_TASK_STATE_READY; + _vglite_cleanup_task(draw_vglite_unit->task_act); draw_vglite_unit->task_act = NULL; /* The draw unit is free now. Request a new dispatching as it can get a new task. */ @@ -371,9 +390,8 @@ static int32_t _vglite_delete(lv_draw_unit_t * draw_unit) static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u) { - lv_draw_task_t * t = u->task_act; - lv_draw_unit_t * draw_unit = (lv_draw_unit_t *)u; - lv_layer_t * layer = draw_unit->target_layer; + vglite_draw_task_t * vglite_task = u->task_act; + lv_layer_t * layer = vglite_task->t->target_layer; lv_draw_buf_t * draw_buf = layer->draw_buf; /* Set target buffer */ @@ -381,11 +399,11 @@ static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u) draw_buf->header.cf); lv_area_t clip_area; - lv_area_copy(&clip_area, draw_unit->clip_area); + lv_area_copy(&clip_area, &vglite_task->t->clip_area); lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); lv_area_t draw_area; - lv_area_copy(&draw_area, &t->area); + lv_area_copy(&draw_area, &vglite_task->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)) @@ -394,36 +412,41 @@ static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u) if(_draw_info.unit_cnt > 1) lv_draw_buf_invalidate_cache(draw_buf, &draw_area); +#if LV_USE_PARALLEL_DRAW_DEBUG + /* remember draw unit for debug purposes */ + vglite_task->t->draw_unit = &u->base_unit; +#endif + /* Set scissor area, excluding the split blit case */ #if LV_USE_VGLITE_BLIT_SPLIT - if(t->type != LV_DRAW_TASK_TYPE_IMAGE || t->type != LV_DRAW_TASK_TYPE_LAYER) + if(vglite_task->t->type != LV_DRAW_TASK_TYPE_IMAGE || vglite_task->t->type != LV_DRAW_TASK_TYPE_LAYER) #endif vglite_set_scissor(&clip_area); - switch(t->type) { + switch(vglite_task->t->type) { case LV_DRAW_TASK_TYPE_LABEL: - lv_draw_vglite_label(draw_unit, t->draw_dsc, &t->area); + lv_draw_vglite_label(vglite_task); break; case LV_DRAW_TASK_TYPE_FILL: - lv_draw_vglite_fill(draw_unit, t->draw_dsc, &t->area); + lv_draw_vglite_fill(vglite_task); break; case LV_DRAW_TASK_TYPE_BORDER: - lv_draw_vglite_border(draw_unit, t->draw_dsc, &t->area); + lv_draw_vglite_border(vglite_task); break; case LV_DRAW_TASK_TYPE_IMAGE: - lv_draw_vglite_img(draw_unit, t->draw_dsc, &t->area); + lv_draw_vglite_img(vglite_task); break; case LV_DRAW_TASK_TYPE_ARC: - lv_draw_vglite_arc(draw_unit, t->draw_dsc, &t->area); + lv_draw_vglite_arc(vglite_task); break; case LV_DRAW_TASK_TYPE_LINE: - lv_draw_vglite_line(draw_unit, t->draw_dsc); + lv_draw_vglite_line(vglite_task); break; case LV_DRAW_TASK_TYPE_LAYER: - lv_draw_vglite_layer(draw_unit, t->draw_dsc, &t->area); + lv_draw_vglite_layer(vglite_task); break; case LV_DRAW_TASK_TYPE_TRIANGLE: - lv_draw_vglite_triangle(draw_unit, t->draw_dsc); + lv_draw_vglite_triangle(vglite_task); break; default: break; @@ -434,17 +457,13 @@ static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u) #if LV_USE_PARALLEL_DRAW_DEBUG /*Layers manage it for themselves*/ - if(t->type != LV_DRAW_TASK_TYPE_LAYER) { + if(vglite_task->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, &vglite_task->t->area, &vglite_task->t->clip_area)) return; - int32_t idx = 0; - lv_draw_unit_t * draw_unit_tmp = _draw_info.unit_head; - while(draw_unit_tmp != (lv_draw_unit_t *)u) { - draw_unit_tmp = draw_unit_tmp->next; - idx++; - } + int32_t idx = u->base_unit.idx; + 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); @@ -452,7 +471,7 @@ static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u) rect_dsc.bg_opa = LV_OPA_10; rect_dsc.border_opa = LV_OPA_80; rect_dsc.border_width = 1; - lv_draw_sw_fill((lv_draw_unit_t *)u, &rect_dsc, &draw_area); + lv_draw_sw_fill(vglite_task->t, &rect_dsc, &draw_area); lv_point_t txt_size; lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE); @@ -465,7 +484,7 @@ static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u) lv_draw_rect_dsc_init(&rect_dsc); rect_dsc.bg_color = lv_color_white(); - lv_draw_sw_fill((lv_draw_unit_t *)u, &rect_dsc, &txt_area); + lv_draw_sw_fill(vglite_task->t, &rect_dsc, &txt_area); char buf[8]; lv_snprintf(buf, sizeof(buf), "%d", idx); @@ -473,13 +492,29 @@ static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u) lv_draw_label_dsc_init(&label_dsc); label_dsc.color = lv_color_black(); label_dsc.text = buf; - lv_draw_sw_label((lv_draw_unit_t *)u, &label_dsc, &txt_area); + lv_draw_sw_label(vglite_task->t, &label_dsc, &txt_area); } #endif } +static inline void _vglite_cleanup_task(vglite_draw_task_t * task) +{ + if(task->path != NULL) { + VGLITE_CHECK_ERROR(vg_lite_clear_path(task->path)); + lv_free(task->path); + } + if(task->gradient != NULL) { + VGLITE_CHECK_ERROR(vg_lite_clear_grad(task->gradient)); + lv_free(task->gradient); + } + if(task->path_data != NULL) + lv_free(task->path_data); + + lv_free(task); +} + #if LV_USE_VGLITE_DRAW_ASYNC -static inline void _vglite_queue_task(lv_draw_task_t * task) +static inline void _vglite_queue_task(vglite_draw_task_t * task) { VGLITE_ASSERT_MSG(((_tail + 1) % VGLITE_TASK_BUF_SIZE) != _head, "VGLite task buffer full."); @@ -488,12 +523,13 @@ static inline void _vglite_queue_task(lv_draw_task_t * task) _tail = (_tail + 1) % VGLITE_TASK_BUF_SIZE; } -static inline void _vglite_signal_task_ready(lv_draw_task_t * task) +static inline void _vglite_signal_task_ready(vglite_draw_task_t * task) { /* Signal the ready state to dispatcher. */ - task->state = LV_DRAW_TASK_STATE_READY; + task->t->state = LV_DRAW_TASK_STATE_READY; _head = (_head + 1) % VGLITE_TASK_BUF_SIZE; + _vglite_cleanup_task(task); /* No need to cleanup the tasks in buffer as we advance with the _head. */ } @@ -502,7 +538,7 @@ 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_draw_task_t * task = _draw_task_buf[i % VGLITE_TASK_BUF_SIZE].task; _vglite_signal_task_ready(task); } @@ -515,7 +551,7 @@ static inline void _vglite_signal_flushed_task_ready(void) for(int i = _head; i < end; i++) { if(_draw_task_buf[i % VGLITE_TASK_BUF_SIZE].flushed) { - lv_draw_task_t * task = _draw_task_buf[i % VGLITE_TASK_BUF_SIZE].task; + vglite_draw_task_t * task = _draw_task_buf[i % VGLITE_TASK_BUF_SIZE].task; _vglite_signal_task_ready(task); @@ -542,8 +578,8 @@ static void _vglite_render_thread_cb(void * ptr) while(u->task_act == NULL #if LV_USE_VGLITE_DRAW_ASYNC /* - * Wait for sync if _draw_task_buf is empty. - * The thread will have to run to complete any pending tasks. + * Wait for sync if wait_for_finish is triggered. + * The thread will have to run and mark as complete any pending tasks. */ && !u->wait_for_finish #endif @@ -567,7 +603,6 @@ static void _vglite_render_thread_cb(void * ptr) } #if LV_USE_VGLITE_DRAW_ASYNC if(u->wait_for_finish) { - u->wait_for_finish = false; vglite_wait_for_finish(); _vglite_signal_all_task_ready(); } @@ -576,10 +611,19 @@ static void _vglite_render_thread_cb(void * ptr) } #else /* Signal the ready state to dispatcher. */ - u->task_act->state = LV_DRAW_TASK_STATE_READY; + u->task_act->t->state = LV_DRAW_TASK_STATE_READY; + _vglite_cleanup_task(u->task_act); #endif - /* Cleanup. */ + + /* Cleanup draw unit running condition. */ +#if LV_USE_VGLITE_DRAW_ASYNC + if(u->wait_for_finish) + u->wait_for_finish = false; + else + u->task_act = NULL; +#else u->task_act = NULL; +#endif /* The draw unit is free now. Request a new dispatching as it can get a new task. */ lv_draw_dispatch_request(); 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 93b18cd7e..61dd1cd0d 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 @@ -24,9 +24,16 @@ extern "C" { #if LV_USE_DRAW_VGLITE #include "../../lv_draw_private.h" -#include "../../sw/lv_draw_sw_private.h" +#include "../../../display/lv_display_private.h" #include "../../../misc/lv_area_private.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" +#include "vg_lite.h" + /********************* * DEFINES *********************/ @@ -35,8 +42,22 @@ extern "C" { * TYPEDEFS **********************/ +typedef struct vglite_draw_task { + lv_draw_task_t * t; + vg_lite_path_t * path; + vg_lite_linear_gradient_t * gradient; + int32_t * path_data; +} vglite_draw_task_t; + typedef struct lv_draw_vglite_unit { - lv_draw_sw_unit_t; + lv_draw_unit_t base_unit; + vglite_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 #if LV_USE_VGLITE_DRAW_ASYNC volatile bool wait_for_finish; #endif @@ -52,27 +73,21 @@ void lv_draw_vglite_init(void); void lv_draw_vglite_deinit(void); -void lv_draw_vglite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, - const lv_area_t * coords); +void lv_draw_vglite_arc(vglite_draw_task_t * vglite_task); -void lv_draw_vglite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc, - const lv_area_t * coords); +void lv_draw_vglite_border(vglite_draw_task_t * vglite_task); -void lv_draw_vglite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, - const lv_area_t * coords); +void lv_draw_vglite_fill(vglite_draw_task_t * vglite_task); -void lv_draw_vglite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc, - const lv_area_t * coords); +void lv_draw_vglite_img(vglite_draw_task_t * vglite_task); -void lv_draw_vglite_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, - const lv_area_t * coords); +void lv_draw_vglite_label(vglite_draw_task_t * vglite_task); -void lv_draw_vglite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, - const lv_area_t * coords); +void lv_draw_vglite_layer(vglite_draw_task_t * vglite_task); -void lv_draw_vglite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc); +void lv_draw_vglite_line(vglite_draw_task_t * vglite_task); -void lv_draw_vglite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc); +void lv_draw_vglite_triangle(vglite_draw_task_t * vglite_task); /********************** * MACROS diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_arc.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_arc.c index 6b0d4fe55..d58a1bbec 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_arc.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_draw_vglite_arc.c @@ -49,7 +49,7 @@ static const uint16_t TperDegree[90] = { /* intermediate arc params */ typedef struct _vg_arc { - int32_t angle; /* angle <90deg */ + uint32_t angle; /* angle <90deg */ int32_t quarter; /* 0-3 counter-clockwise */ int32_t rad; /* radius */ int32_t p0x; /* point P0 */ @@ -81,8 +81,8 @@ typedef struct _cubic_cont_pt { * @param[in] dsc Arc description structure (width, rounded ending, opacity) * */ -static void _vglite_draw_arc(const lv_point_t * center, const lv_area_t * clip_area, - const lv_draw_arc_dsc_t * dsc); +static void _vglite_draw_arc(vglite_draw_task_t * vglite_task, const lv_point_t * center, + const lv_area_t * clip_area, const lv_draw_arc_dsc_t * dsc); /********************** * STATIC VARIABLES @@ -96,10 +96,10 @@ static void _vglite_draw_arc(const lv_point_t * center, const lv_area_t * clip_a * GLOBAL FUNCTIONS **********************/ -void lv_draw_vglite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, - const lv_area_t * coords) +void lv_draw_vglite_arc(vglite_draw_task_t * vglite_task) { - LV_UNUSED(coords); + lv_draw_task_t * t = vglite_task->t; + const lv_draw_arc_dsc_t * dsc = t->draw_dsc; if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) return; @@ -108,14 +108,14 @@ void lv_draw_vglite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * ds if(dsc->start_angle == dsc->end_angle) return; - lv_layer_t * layer = draw_unit->target_layer; + lv_layer_t * layer = t->target_layer; lv_point_t center = {dsc->center.x - layer->buf_area.x1, dsc->center.y - layer->buf_area.y1}; lv_area_t clip_area; - lv_area_copy(&clip_area, draw_unit->clip_area); + lv_area_copy(&clip_area, &t->clip_area); lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); - _vglite_draw_arc(¢er, &clip_area, dsc); + _vglite_draw_arc(vglite_task, ¢er, &clip_area, dsc); } /********************** @@ -140,11 +140,11 @@ static void _copy_arc(vg_arc * dst, vg_arc * src) /** * Rotate the point according given rotation angle rotation center is 0,0 */ -static void _rotate_point(int32_t angle, int32_t * x, int32_t * y) +static void _rotate_point(int16_t angle, int32_t * x, int32_t * y) { int32_t ori_x = *x; int32_t ori_y = *y; - int16_t alpha = (int16_t)angle; + int16_t alpha = angle; *x = ((lv_trigo_cos(alpha) * ori_x) / LV_TRIGO_SIN_MAX) - ((lv_trigo_sin(alpha) * ori_y) / LV_TRIGO_SIN_MAX); *y = ((lv_trigo_sin(alpha) * ori_x) / LV_TRIGO_SIN_MAX) + ((lv_trigo_cos(alpha) * ori_y) / LV_TRIGO_SIN_MAX); } @@ -269,7 +269,7 @@ static uint16_t _get_bez_t_from_pos(float pt, cubic_cont_pt cp, bool dec) * Gives relative coords of the control points * for the sub-arc starting at angle with given angle span */ -static void _get_subarc_control_points(vg_arc * arc, int32_t span) +static void _get_subarc_control_points(vg_arc * arc, uint32_t span) { vg_arc fullarc = {0}; fullarc.angle = arc->angle; @@ -427,10 +427,10 @@ static void _get_arc_control_points(vg_arc * arc, bool start) * center: (in) the center of the circle in draw coordinates * cw: (in) true if arc is clockwise */ -static void _add_split_arc_path(int32_t * arc_path, int * pidx, vg_arc * q_arc, const lv_point_t * center, bool cw) +static void _add_split_arc_path(int32_t * arc_path, uint32_t * pidx, vg_arc * q_arc, const lv_point_t * center, bool cw) { /* assumes first control point already in array arc_path[] */ - int idx = *pidx; + uint32_t idx = *pidx; if(cw) { #if BEZIER_DBG_CONTROL_POINTS arc_path[idx++] = VLC_OP_LINE; @@ -477,15 +477,15 @@ static void _add_split_arc_path(int32_t * arc_path, int * pidx, vg_arc * q_arc, *pidx = idx; } -static void _add_arc_path(int32_t * arc_path, int * pidx, int32_t radius, +static void _add_arc_path(int32_t * arc_path, uint32_t * pidx, uint32_t radius, int32_t start_angle, int32_t end_angle, const lv_point_t * center, bool cw) { /* set number of arcs to draw */ vg_arc q_arc; - int32_t start_arc_angle = start_angle % 90; - int32_t end_arc_angle = end_angle % 90; - int32_t inv_start_arc_angle = (start_arc_angle > 0) ? (90 - start_arc_angle) : 0; - int32_t nbarc = (end_angle - start_angle - inv_start_arc_angle - end_arc_angle) / 90; + uint32_t start_arc_angle = start_angle % 90; + uint32_t end_arc_angle = end_angle % 90; + uint32_t inv_start_arc_angle = (start_arc_angle > 0) ? (90 - start_arc_angle) : 0; + uint32_t nbarc = (end_angle - start_angle - inv_start_arc_angle - end_arc_angle) / 90; q_arc.rad = radius; /* handle special case of start & end point in the same quarter */ @@ -508,7 +508,7 @@ static void _add_arc_path(int32_t * arc_path, int * pidx, int32_t radius, _add_split_arc_path(arc_path, pidx, &q_arc, center, cw); } /* full arcs */ - for(int32_t q = 0; q < nbarc ; q++) { + for(uint32_t q = 0; q < nbarc ; q++) { q_arc.quarter = (q + ((start_angle + 89) / 90)) % 4; q_arc.angle = 90; /* get cubic points relative to center */ @@ -559,22 +559,25 @@ static void _add_arc_path(int32_t * arc_path, int * pidx, int32_t radius, } } -static void _vglite_draw_arc(const lv_point_t * center, const lv_area_t * clip_area, - const lv_draw_arc_dsc_t * dsc) +static void _vglite_draw_arc(vglite_draw_task_t * vglite_task, const lv_point_t * center, + const lv_area_t * clip_area, const lv_draw_arc_dsc_t * dsc) { - vg_lite_path_t path; - uint16_t start_angle = dsc->start_angle; - uint16_t end_angle = dsc->end_angle; + vg_lite_path_t * path = lv_malloc_zeroed(sizeof(vg_lite_path_t)); + LV_ASSERT_MALLOC(path); + vglite_task->path = path; + int16_t start_angle = dsc->start_angle; + int16_t end_angle = dsc->end_angle; /* be sure end_angle > start_angle */ if(end_angle < start_angle) end_angle += 360; bool donut = ((end_angle - start_angle) % 360 == 0) ? true : false; - vg_lite_buffer_t * vgbuf = vglite_get_dest_buf(); + vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); - int32_t arc_path[ARC_PATH_DATA_MAX_SIZE]; - lv_memzero(arc_path, sizeof(arc_path)); + int32_t * arc_path = lv_malloc_zeroed(ARC_PATH_DATA_MAX_SIZE * sizeof(int32_t)); + LV_ASSERT_MALLOC(arc_path); + vglite_task->path_data = arc_path; /*** Init path ***/ int32_t width = dsc->width; /* inner arc radius = outer arc radius - width */ @@ -583,7 +586,7 @@ static void _vglite_draw_arc(const lv_point_t * center, const lv_area_t * clip_a if(width > radius) width = radius; - int pidx = 0; + uint32_t pidx = 0; int32_t cp_x, cp_y; /* control point coords */ /* first control point of curve */ @@ -665,22 +668,17 @@ static void _vglite_draw_arc(const lv_point_t * center, const lv_area_t * clip_a arc_path[pidx++] = VLC_OP_END; - VGLITE_CHECK_ERROR(vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_HIGH, (uint32_t)pidx * sizeof(int32_t), arc_path, + VGLITE_CHECK_ERROR(vg_lite_init_path(path, VG_LITE_S32, VG_LITE_HIGH, (uint32_t)pidx * sizeof(int32_t), arc_path, (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f)); lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa); vg_lite_color_t vgcol = vglite_get_color(col32, false); - vg_lite_matrix_t matrix; - vg_lite_identity(&matrix); - /*** Draw arc ***/ - VGLITE_CHECK_ERROR(vg_lite_draw(vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol)); + VGLITE_CHECK_ERROR(vg_lite_draw(dest_buf, path, VG_LITE_FILL_NON_ZERO, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); vglite_run(); - - VGLITE_CHECK_ERROR(vg_lite_clear_path(&path)); } #endif /*LV_USE_DRAW_VGLITE*/ 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 db762fb61..c04c9926c 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 @@ -37,6 +37,11 @@ * TYPEDEFS **********************/ +typedef struct scissoring_rects { + vg_lite_rectangle_t rect[MAX_NUM_RECTANGLES]; + uint32_t num_rect; +} scissoring_rects_t ; + /********************** * STATIC PROTOTYPES **********************/ @@ -49,8 +54,23 @@ * @param[in] dsc Description of the rectangle border/outline * */ -static void _vglite_draw_border(const lv_area_t * coords, const lv_area_t * clip_area, - const lv_draw_border_dsc_t * dsc); +static void _vglite_draw_border(vglite_draw_task_t * task, const lv_area_t * coords, + const lv_area_t * clip_area, const lv_draw_border_dsc_t * dsc); + +/** + * Create scissor area based on the border side + * + * @param[in] coords Coordinates of the rectangle border/outline (relative to dest buff) + * @param[in] line_width Width of the line + * @param[in] border_side Sides of the border + * @param[in] radius Radius of the border + * @param[out] scissoring_rects Struct that contains the array of scissors + * + */ + +static void _border_set_scissoring(const lv_area_t * coords, int32_t line_width, + uint32_t border_side, int32_t radius, + scissoring_rects_t * scissoring_rects); /********************** * STATIC VARIABLES @@ -64,9 +84,11 @@ static void _vglite_draw_border(const lv_area_t * coords, const lv_area_t * clip * GLOBAL FUNCTIONS **********************/ -void lv_draw_vglite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc, - const lv_area_t * coords) +void lv_draw_vglite_border(vglite_draw_task_t * vglite_task) { + const lv_draw_border_dsc_t * dsc = vglite_task->t->draw_dsc; + const lv_area_t * coords = &vglite_task->t->area; + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) return; if(dsc->width == 0) @@ -74,7 +96,7 @@ void lv_draw_vglite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_ if(dsc->side == (lv_border_side_t)LV_BORDER_SIDE_NONE) return; - lv_layer_t * layer = draw_unit->target_layer; + lv_layer_t * layer = vglite_task->t->target_layer; lv_area_t inward_coords; int32_t width = dsc->width; @@ -87,25 +109,67 @@ void lv_draw_vglite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_ lv_area_move(&inward_coords, -layer->buf_area.x1, -layer->buf_area.y1); lv_area_t clip_area; - lv_area_copy(&clip_area, draw_unit->clip_area); + lv_area_copy(&clip_area, &vglite_task->t->clip_area); 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)) return; /*Fully clipped, nothing to do*/ - _vglite_draw_border(&inward_coords, &clip_area, dsc); + _vglite_draw_border(vglite_task, &inward_coords, &clip_area, dsc); } /********************** * STATIC FUNCTIONS **********************/ -static void _vglite_draw_border(const lv_area_t * coords, const lv_area_t * clip_area, - const lv_draw_border_dsc_t * dsc) +static void _border_set_scissoring(const lv_area_t * coords, int32_t line_width, + uint32_t border_side, int32_t radius, + scissoring_rects_t * scissoring_rects) +{ + 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) { + scissoring_rects->rect[scissoring_rects->num_rect].x = coords->x1 - ceil(line_width / 2.0f); + scissoring_rects->rect[scissoring_rects->num_rect].y = coords->y1 - ceil(line_width / 2.0f); + scissoring_rects->rect[scissoring_rects->num_rect].width = coords->x2 - coords->x1 + line_width; + scissoring_rects->rect[scissoring_rects->num_rect].height = final_radius + ceil(line_width / 2.0f); + scissoring_rects->num_rect++; + } + + if(border_side & LV_BORDER_SIDE_LEFT) { + scissoring_rects->rect[scissoring_rects->num_rect].x = coords->x1 - ceil(line_width / 2.0f); + scissoring_rects->rect[scissoring_rects->num_rect].y = coords->y1 - ceil(line_width / 2.0f); + scissoring_rects->rect[scissoring_rects->num_rect].width = final_radius + ceil(line_width / 2.0f); + scissoring_rects->rect[scissoring_rects->num_rect].height = coords->y2 - coords->y1 + line_width + 1; + scissoring_rects->num_rect++; + } + + if(border_side & LV_BORDER_SIDE_RIGHT) { + scissoring_rects->rect[scissoring_rects->num_rect].x = coords->x2 - final_radius + 1; + scissoring_rects->rect[scissoring_rects->num_rect].y = coords->y1 - ceil(line_width / 2.0f); + scissoring_rects->rect[scissoring_rects->num_rect].width = final_radius + ceil(line_width / 2.0f); + scissoring_rects->rect[scissoring_rects->num_rect].height = coords->y2 - coords->y1 + line_width + 1; + scissoring_rects->num_rect++; + } + + if(border_side & LV_BORDER_SIDE_BOTTOM) { + scissoring_rects->rect[scissoring_rects->num_rect].x = coords->x1 - ceil(line_width / 2.0f); + scissoring_rects->rect[scissoring_rects->num_rect].y = coords->y2 - final_radius + 1; + scissoring_rects->rect[scissoring_rects->num_rect].width = coords->x2 - coords->x1 + line_width; + scissoring_rects->rect[scissoring_rects->num_rect].height = final_radius + ceil(line_width / 2.0f); + scissoring_rects->num_rect++; + } +} + +static void _vglite_draw_border(vglite_draw_task_t * vglite_task, const lv_area_t * coords, + const lv_area_t * clip_area, const lv_draw_border_dsc_t * dsc) { int32_t radius = dsc->radius; - vg_lite_buffer_t * vgbuf = vglite_get_dest_buf(); + vg_lite_buffer_t * buf = vglite_get_dest_buf(); if(radius < 0) return; @@ -118,86 +182,67 @@ static void _vglite_draw_border(const lv_area_t * coords, const lv_area_t * clip vg_lite_join_style_t join_style = (radius) ? VG_LITE_JOIN_ROUND : VG_LITE_JOIN_MITER; /*** Init path ***/ - int32_t path_data[RECT_PATH_DATA_MAX_SIZE]; + int32_t * path_data = lv_malloc_zeroed(RECT_PATH_DATA_MAX_SIZE * sizeof(int32_t)); + LV_ASSERT_MALLOC(path_data); + vglite_task->path_data = path_data; + uint32_t path_data_size; vglite_create_rect_path_data(path_data, &path_data_size, radius, coords); vg_lite_quality_t path_quality = radius > 0 ? VG_LITE_HIGH : VG_LITE_MEDIUM; - vg_lite_path_t path; - VGLITE_CHECK_ERROR(vg_lite_init_path(&path, VG_LITE_S32, path_quality, path_data_size, path_data, + vg_lite_path_t * path = lv_malloc_zeroed(sizeof(vg_lite_path_t)); + LV_ASSERT_MALLOC(path); + vglite_task->path = path; + VGLITE_CHECK_ERROR(vg_lite_init_path(path, VG_LITE_S32, path_quality, path_data_size, path_data, (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f)); lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa); vg_lite_color_t vgcol = vglite_get_color(col32, false); - vg_lite_matrix_t matrix; - 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; + scissoring_rects_t scissoring_rects; + scissoring_rects.num_rect = 0; - 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); + bool has_vg_mask_feat = vg_lite_query_feature(gcFEATURE_BIT_VG_MASK); - 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++; + VGLITE_CHECK_ERROR(vg_lite_set_draw_path_type(path, VG_LITE_DRAW_STROKE_PATH)); + + VGLITE_CHECK_ERROR(vg_lite_set_stroke(path, cap_style, join_style, line_width, 8, NULL, 0, 0, vgcol)); + + VGLITE_CHECK_ERROR(vg_lite_update_stroke(path)); + + if(border_side != LV_BORDER_SIDE_FULL) { + _border_set_scissoring(coords, line_width, border_side, radius, &scissoring_rects); + + if(has_vg_mask_feat) { + /*** Enable scissor and apply scissor rects ***/ + VGLITE_CHECK_ERROR(vg_lite_enable_scissor()); + VGLITE_CHECK_ERROR(vg_lite_scissor_rects(buf, scissoring_rects.num_rect, scissoring_rects.rect)); + + /*** Draw border ***/ + VGLITE_CHECK_ERROR(vg_lite_draw(buf, path, VG_LITE_FILL_NON_ZERO, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); + + /*** Disable scissor ***/ + VGLITE_CHECK_ERROR(vg_lite_disable_scissor()); + } + else { + for(uint32_t i = 0; i < scissoring_rects.num_rect; i++) { + VGLITE_CHECK_ERROR(vg_lite_set_scissor(scissoring_rects.rect[i].x, scissoring_rects.rect[i].y, + scissoring_rects.rect[i].x + scissoring_rects.rect[i].width, + scissoring_rects.rect[i].y + scissoring_rects.rect[i].height)); + VGLITE_CHECK_ERROR(vg_lite_draw(buf, path, VG_LITE_FILL_NON_ZERO, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); + } + } } - - 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++; + else { + /*** Draw border ***/ + VGLITE_CHECK_ERROR(vg_lite_draw(buf, path, VG_LITE_FILL_NON_ZERO, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); } - 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)); - - VGLITE_CHECK_ERROR(vg_lite_set_stroke(&path, cap_style, join_style, line_width, 8, NULL, 0, 0, vgcol)); - - VGLITE_CHECK_ERROR(vg_lite_update_stroke(&path)); - - VGLITE_CHECK_ERROR(vg_lite_draw(vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol)); - 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 97089ce55..c58c09fce 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 @@ -34,6 +34,17 @@ * STATIC PROTOTYPES **********************/ +/** + * Set rectangle path data + * + * @param[in/out] path_data Coordinates of the rectangle + * @param[in/out] path_data_size Size of path_data (bytes) + * @param[in] p Points of the rectangle + * + */ +static void _vglite_set_rectangle(int32_t * path_data, uint32_t * path_data_size, + const lv_area_t * dest_area); + /** * Fill area, with optional opacity. * @@ -41,7 +52,8 @@ * @param[in] dsc Description of the area to fill (color, opa) * */ -static void _vglite_fill(const lv_area_t * dest_area, const lv_draw_fill_dsc_t * dsc); +static void _vglite_fill(vglite_draw_task_t * task, const lv_area_t * dest_area, + const lv_draw_fill_dsc_t * dsc); /** * Draw rectangle background with effects (rounded corners, gradient) @@ -51,8 +63,8 @@ static void _vglite_fill(const lv_area_t * dest_area, const lv_draw_fill_dsc_t * * @param[in] dsc Description of the rectangle background * */ -static void _vglite_draw_rect(const lv_area_t * coords, const lv_area_t * clip_area, - const lv_draw_fill_dsc_t * dsc); +static void _vglite_draw_rect(vglite_draw_task_t * task, const lv_area_t * coords, + const lv_area_t * clip_area, const lv_draw_fill_dsc_t * dsc); /********************** * STATIC VARIABLES @@ -66,19 +78,21 @@ static void _vglite_draw_rect(const lv_area_t * coords, const lv_area_t * clip_a * GLOBAL FUNCTIONS **********************/ -void lv_draw_vglite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, - const lv_area_t * coords) +void lv_draw_vglite_fill(vglite_draw_task_t * vglite_task) { + const lv_draw_fill_dsc_t * dsc = vglite_task->t->draw_dsc; + const lv_area_t * coords = &vglite_task->t->area; + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) return; - lv_layer_t * layer = draw_unit->target_layer; + lv_layer_t * layer = vglite_task->t->target_layer; lv_area_t relative_coords; lv_area_copy(&relative_coords, coords); lv_area_move(&relative_coords, -layer->buf_area.x1, -layer->buf_area.y1); lv_area_t clip_area; - lv_area_copy(&clip_area, draw_unit->clip_area); + lv_area_copy(&clip_area, &vglite_task->t->clip_area); lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); lv_area_t clipped_coords; @@ -89,18 +103,42 @@ void lv_draw_vglite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * * Most simple case: just a plain rectangle (no radius, no gradient) */ if((dsc->radius == 0) && (dsc->grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_NONE)) - _vglite_fill(&clipped_coords, dsc); + _vglite_fill(vglite_task, &clipped_coords, dsc); else - _vglite_draw_rect(&relative_coords, &clip_area, dsc); + _vglite_draw_rect(vglite_task, &relative_coords, &clip_area, dsc); } /********************** * STATIC FUNCTIONS **********************/ -static void _vglite_fill(const lv_area_t * dest_area, const lv_draw_fill_dsc_t * dsc) +static void _vglite_set_rectangle(int32_t * path_data, uint32_t * path_data_size, const lv_area_t * dest_area) { - vg_lite_buffer_t * vgbuf = vglite_get_dest_buf(); + uint32_t pidx = 0; + path_data[pidx++] = VLC_OP_MOVE; + path_data[pidx++] = dest_area->x1; + path_data[pidx++] = dest_area->y1; + path_data[pidx++] = VLC_OP_LINE; + path_data[pidx++] = dest_area->x2 + 1; + path_data[pidx++] = dest_area->y1; + path_data[pidx++] = VLC_OP_LINE; + path_data[pidx++] = dest_area->x2 + 1; + path_data[pidx++] = dest_area->y2 + 1; + path_data[pidx++] = VLC_OP_LINE; + path_data[pidx++] = dest_area->x1; + path_data[pidx++] = dest_area->y2 + 1; + path_data[pidx++] = VLC_OP_LINE; + path_data[pidx++] = dest_area->x1; + path_data[pidx++] = dest_area->y1; + path_data[pidx++] = VLC_OP_END; + + *path_data_size = pidx * sizeof(int32_t); +} + +static void _vglite_fill(vglite_draw_task_t * vglite_task, const lv_area_t * dest_area, + const lv_draw_fill_dsc_t * dsc) +{ + vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa); vg_lite_color_t vgcol = vglite_get_color(col32, false); @@ -113,73 +151,74 @@ static void _vglite_fill(const lv_area_t * dest_area, const lv_draw_fill_dsc_t * .height = lv_area_get_height(dest_area) }; - VGLITE_CHECK_ERROR(vg_lite_clear(vgbuf, &rect, vgcol)); + VGLITE_CHECK_ERROR(vg_lite_clear(dest_buf, &rect, vgcol)); vglite_run(); } else { /*fill with transparency*/ - vg_lite_path_t path; - int32_t path_data[] = { /*VG rectangular path*/ - VLC_OP_MOVE, dest_area->x1, dest_area->y1, - VLC_OP_LINE, dest_area->x2 + 1, dest_area->y1, - VLC_OP_LINE, dest_area->x2 + 1, dest_area->y2 + 1, - VLC_OP_LINE, dest_area->x1, dest_area->y2 + 1, - VLC_OP_LINE, dest_area->x1, dest_area->y1, - VLC_OP_END - }; + vg_lite_path_t * path = lv_malloc_zeroed(sizeof(vg_lite_path_t)); + LV_ASSERT_MALLOC(path); + vglite_task->path = path; - VGLITE_CHECK_ERROR(vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_MEDIUM, sizeof(path_data), path_data, + uint32_t path_data_size; + int32_t * path_data = lv_malloc_zeroed(16 * sizeof(int32_t)); + LV_ASSERT_MALLOC(path_data); + vglite_task->path_data = path_data; + _vglite_set_rectangle(path_data, &path_data_size, dest_area); + + VGLITE_CHECK_ERROR(vg_lite_init_path(path, VG_LITE_S32, VG_LITE_MEDIUM, path_data_size, path_data, (vg_lite_float_t) dest_area->x1, (vg_lite_float_t) dest_area->y1, ((vg_lite_float_t) dest_area->x2) + 1.0f, ((vg_lite_float_t) dest_area->y2) + 1.0f)); - vg_lite_matrix_t matrix; - vg_lite_identity(&matrix); - /*Draw rectangle*/ - VGLITE_CHECK_ERROR(vg_lite_draw(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol)); + VGLITE_CHECK_ERROR(vg_lite_draw(dest_buf, path, VG_LITE_FILL_EVEN_ODD, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); vglite_run(); - - VGLITE_CHECK_ERROR(vg_lite_clear_path(&path)); } } -static void _vglite_draw_rect(const lv_area_t * coords, const lv_area_t * clip_area, - const lv_draw_fill_dsc_t * dsc) +static void _vglite_draw_rect(vglite_draw_task_t * vglite_task, const lv_area_t * coords, + const lv_area_t * clip_area, const lv_draw_fill_dsc_t * dsc) { int32_t width = lv_area_get_width(coords); int32_t height = lv_area_get_height(coords); int32_t radius = dsc->radius; lv_opa_t opa = dsc->opa; - vg_lite_buffer_t * vgbuf = vglite_get_dest_buf(); + vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); if(dsc->radius < 0) return; /*** Init path ***/ - int32_t path_data[RECT_PATH_DATA_MAX_SIZE]; + int32_t * path_data = lv_malloc_zeroed(RECT_PATH_DATA_MAX_SIZE * sizeof(int32_t)); + LV_ASSERT_MALLOC(path_data); + vglite_task->path_data = path_data; + uint32_t path_data_size; vglite_create_rect_path_data(path_data, &path_data_size, radius, coords); vg_lite_quality_t path_quality = dsc->radius > 0 ? VG_LITE_HIGH : VG_LITE_MEDIUM; - vg_lite_path_t path; - VGLITE_CHECK_ERROR(vg_lite_init_path(&path, VG_LITE_S32, path_quality, path_data_size, path_data, + vg_lite_path_t * path = lv_malloc_zeroed(sizeof(vg_lite_path_t)); + LV_ASSERT_MALLOC(path); + vglite_task->path = path; + VGLITE_CHECK_ERROR(vg_lite_init_path(path, VG_LITE_S32, path_quality, path_data_size, path_data, (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f)); - vg_lite_matrix_t matrix; - vg_lite_identity(&matrix); - /*** Init Color ***/ lv_color32_t col32 = lv_color_to_32(dsc->color, opa); vg_lite_color_t vgcol = vglite_get_color(col32, false); - vg_lite_linear_gradient_t gradient; + vg_lite_linear_gradient_t * gradient; bool has_gradient = (dsc->grad.dir != (lv_grad_dir_t)LV_GRAD_DIR_NONE); /*** Init Gradient ***/ if(has_gradient) { + gradient = lv_malloc_zeroed(sizeof(vg_lite_linear_gradient_t)); + LV_ASSERT_MALLOC(gradient); + vglite_task->gradient = gradient; + vg_lite_matrix_t * grad_matrix; vg_lite_uint32_t colors[LV_GRADIENT_MAX_STOPS]; @@ -187,7 +226,7 @@ static void _vglite_draw_rect(const lv_area_t * coords, const lv_area_t * clip_a lv_color32_t col32[LV_GRADIENT_MAX_STOPS]; /* Gradient setup */ - vg_lite_uint32_t cnt = LV_MAX(dsc->grad.stops_count, LV_GRADIENT_MAX_STOPS); + vg_lite_uint32_t cnt = LV_MIN(dsc->grad.stops_count, LV_GRADIENT_MAX_STOPS); lv_opa_t opa; for(uint8_t i = 0; i < cnt; i++) { @@ -199,15 +238,13 @@ static void _vglite_draw_rect(const lv_area_t * coords, const lv_area_t * clip_a colors[i] = vglite_get_color(col32[i], true); } - lv_memzero(&gradient, sizeof(vg_lite_linear_gradient_t)); + VGLITE_CHECK_ERROR(vg_lite_init_grad(gradient)); - VGLITE_CHECK_ERROR(vg_lite_init_grad(&gradient)); + VGLITE_CHECK_ERROR(vg_lite_set_grad(gradient, cnt, colors, stops)); - VGLITE_CHECK_ERROR(vg_lite_set_grad(&gradient, cnt, colors, stops)); + VGLITE_CHECK_ERROR(vg_lite_update_grad(gradient)); - VGLITE_CHECK_ERROR(vg_lite_update_grad(&gradient)); - - grad_matrix = vg_lite_get_grad_matrix(&gradient); + grad_matrix = vg_lite_get_grad_matrix(gradient); vg_lite_identity(grad_matrix); vg_lite_translate((float)coords->x1, (float)coords->y1, grad_matrix); @@ -219,19 +256,14 @@ static void _vglite_draw_rect(const lv_area_t * coords, const lv_area_t * clip_a vg_lite_scale((float)width / 256.0f, 1.0f, grad_matrix); } - VGLITE_CHECK_ERROR(vg_lite_draw_gradient(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, &gradient, + VGLITE_CHECK_ERROR(vg_lite_draw_gradient(dest_buf, path, VG_LITE_FILL_EVEN_ODD, NULL, gradient, VG_LITE_BLEND_SRC_OVER)); } else { - VGLITE_CHECK_ERROR(vg_lite_draw(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol)); + VGLITE_CHECK_ERROR(vg_lite_draw(dest_buf, path, VG_LITE_FILL_EVEN_ODD, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); } vglite_run(); - - VGLITE_CHECK_ERROR(vg_lite_clear_path(&path)); - - if(has_gradient) - VGLITE_CHECK_ERROR(vg_lite_clear_grad(&gradient)); } #endif /*LV_USE_DRAW_VGLITE*/ 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 49fdffaff..b01afe729 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 @@ -70,7 +70,7 @@ static void _move_buf_close_to_area(void ** buf, lv_area_t * area, uint32_t stride, lv_color_format_t cf); /** - * BLock Image Transfer - copy rectangular image from src_buf to dst_buf with effects. + * BLock Image Transfer - copy rectangular image from src_buf to dest_buf with effects. * By default, image is copied directly, with optional opacity. * * @param dest_buf Destination buffer @@ -99,11 +99,12 @@ static void _vglite_blit_split(void * dest_buf, lv_area_t * dest_area, uint32_t * @param[in] dsc Image descriptor * */ -static void _vglite_draw_pattern(const lv_area_t * clip_area, const lv_area_t * coords, +static void _vglite_draw_pattern(vglite_draw_task_t * vglite_task, const lv_area_t * clip_area, + const lv_area_t * coords, const lv_draw_image_dsc_t * dsc); /** - * BLock Image Transfer - copy rectangular image from src_buf to dst_buf with or without effects. + * BLock Image Transfer - copy rectangular image from src_buf to dest_buf with or without effects. * * @param[in] src_area Source area with relative coordinates to src buffer * @param[in] dsc Image descriptor @@ -125,13 +126,15 @@ static vg_lite_color_t _vglite_recolor(const lv_draw_image_dsc_t * dsc); * GLOBAL FUNCTIONS **********************/ -void lv_draw_vglite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc, - const lv_area_t * coords) +void lv_draw_vglite_img(vglite_draw_task_t * vglite_task) { + const lv_draw_image_dsc_t * dsc = vglite_task->t->draw_dsc; + const lv_area_t * coords = &vglite_task->t->area; + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) return; - lv_layer_t * layer = draw_unit->target_layer; + lv_layer_t * layer = vglite_task->t->target_layer; const lv_image_dsc_t * img_dsc = dsc->src; lv_area_t relative_coords; @@ -139,7 +142,7 @@ void lv_draw_vglite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * lv_area_move(&relative_coords, -layer->buf_area.x1, -layer->buf_area.y1); lv_area_t clip_area; - lv_area_copy(&clip_area, draw_unit->clip_area); + lv_area_copy(&clip_area, &vglite_task->t->clip_area); lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); lv_area_t blend_area; @@ -160,7 +163,7 @@ void lv_draw_vglite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * lv_color_format_t src_cf = img_dsc->header.cf; uint32_t src_stride = img_dsc->header.stride; - /* Set src_vgbuf structure. */ + /* Set src_buf structure. */ vglite_set_src_buf(src_buf, img_dsc->header.w, img_dsc->header.h, src_stride, src_cf); #if LV_USE_VGLITE_BLIT_SPLIT @@ -175,7 +178,7 @@ void lv_draw_vglite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * vglite_set_transformation_matrix(&blend_area, dsc); bool is_tiled = dsc->tile; if(is_tiled) - _vglite_draw_pattern(&clip_area, &relative_coords, dsc); + _vglite_draw_pattern(vglite_task, &clip_area, &relative_coords, dsc); else _vglite_blit(&src_area, dsc); #endif /*LV_USE_VGLITE_BLIT_SPLIT*/ @@ -186,8 +189,8 @@ void lv_draw_vglite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * **********************/ static void _vglite_blit(const lv_area_t * src_area, const lv_draw_image_dsc_t * dsc) { - vg_lite_buffer_t * dst_vgbuf = vglite_get_dest_buf(); - vg_lite_buffer_t * src_vgbuf = vglite_get_src_buf(); + vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); + vg_lite_buffer_t * src_buf = vglite_get_src_buf(); vg_lite_rectangle_t rect = { .x = (vg_lite_int32_t)src_area->x1, @@ -196,15 +199,15 @@ static void _vglite_blit(const lv_area_t * src_area, const lv_draw_image_dsc_t * .height = (vg_lite_int32_t)lv_area_get_height(src_area) }; - src_vgbuf->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; - src_vgbuf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT; + src_buf->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; + src_buf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT; vg_lite_color_t vgcol = _vglite_recolor(dsc); - vg_lite_matrix_t * vgmatrix = vglite_get_matrix(); + vg_lite_matrix_t * matrix = vglite_get_matrix(); vg_lite_blend_t vgblend = vglite_get_blend_mode(dsc->blend_mode); - VGLITE_CHECK_ERROR(vg_lite_blit_rect(dst_vgbuf, src_vgbuf, &rect, vgmatrix, vgblend, vgcol, VG_LITE_FILTER_POINT)); + VGLITE_CHECK_ERROR(vg_lite_blit_rect(dest_buf, src_buf, &rect, matrix, vgblend, vgcol, VG_LITE_FILTER_POINT)); vglite_run(); } @@ -260,7 +263,7 @@ static void _vglite_blit_split(void * dest_buf, lv_area_t * dest_area, uint32_t if((src_area->x2 < VGLITE_BLIT_SPLIT_THR) && (src_area->y2 < VGLITE_BLIT_SPLIT_THR)) { - /* Set new dest_vgbuf and src_vgbuf memory addresses */ + /* Set new dest_buf and src_buf memory addresses */ vglite_set_dest_buf_ptr(dest_buf); vglite_set_src_buf_ptr(src_buf); @@ -350,7 +353,7 @@ static void _vglite_blit_split(void * dest_buf, lv_area_t * dest_area, uint32_t tile_src_area.x2 += shift_src_x; tile_dest_area.x2 += shift_dest_x; - /* Set new dest_vgbuf and src_vgbuf memory addresses */ + /* Set new dest_buf and src_buf memory addresses */ vglite_set_dest_buf_ptr(tile_dest_buf); vglite_set_src_buf_ptr(tile_src_buf); @@ -372,36 +375,38 @@ static void _vglite_blit_split(void * dest_buf, lv_area_t * dest_area, uint32_t } #endif /*LV_USE_VGLITE_BLIT_SPLIT*/ -static void _vglite_draw_pattern(const lv_area_t * clip_area, const lv_area_t * coords, +static void _vglite_draw_pattern(vglite_draw_task_t * vglite_task, const lv_area_t * clip_area, + const lv_area_t * coords, const lv_draw_image_dsc_t * dsc) { /* Target buffer */ - vg_lite_buffer_t * dst_vgbuf = vglite_get_dest_buf(); + vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); /* Path to draw */ - int32_t path_data[RECT_PATH_DATA_MAX_SIZE]; + int32_t * path_data = lv_malloc_zeroed(RECT_PATH_DATA_MAX_SIZE * sizeof(int32_t)); + LV_ASSERT_MALLOC(path_data); + vglite_task->path_data = path_data; + uint32_t path_data_size; 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; - VGLITE_CHECK_ERROR(vg_lite_init_path(&path, VG_LITE_S32, path_quality, path_data_size, path_data, + vg_lite_path_t * path = lv_malloc_zeroed(sizeof(vg_lite_path_t)); + LV_ASSERT_MALLOC(path); + vglite_task->path = path; + VGLITE_CHECK_ERROR(vg_lite_init_path(path, VG_LITE_S32, path_quality, path_data_size, path_data, (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f)); - /* Path Matrix */ - vg_lite_matrix_t path_matrix; - vg_lite_identity(&path_matrix); - /* Pattern Image */ - vg_lite_buffer_t * src_vgbuf = vglite_get_src_buf(); - src_vgbuf->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; - src_vgbuf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT; + vg_lite_buffer_t * src_buf = vglite_get_src_buf(); + src_buf->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; + src_buf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT; /* Pattern 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); + vg_lite_matrix_t matrix; + vg_lite_identity(&matrix); + vg_lite_translate((vg_lite_float_t)dsc->image_area.x1, (vg_lite_float_t)dsc->image_area.y1, &matrix); /* Blend mode */ vg_lite_blend_t vgblend = vglite_get_blend_mode(dsc->blend_mode); @@ -413,9 +418,10 @@ static void _vglite_draw_pattern(const lv_area_t * clip_area, const lv_area_t * 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, + VGLITE_CHECK_ERROR(vg_lite_draw_pattern(dest_buf, path, VG_LITE_FILL_NON_ZERO, NULL, + src_buf, &matrix, vgblend, VG_LITE_PATTERN_REPEAT, 0, vgcol, filter)); + vglite_run(); } static vg_lite_color_t _vglite_recolor(const lv_draw_image_dsc_t * dsc) 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 9af7c6837..da6a6ce8e 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 @@ -22,6 +22,7 @@ #include "../../lv_draw_label_private.h" #include "../../../stdlib/lv_string.h" +#include "../../../font/lv_font_fmt_txt_private.h" /********************* * DEFINES @@ -35,7 +36,7 @@ * STATIC PROTOTYPES **********************/ -static void _draw_vglite_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc, +static void _draw_vglite_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area); /** @@ -52,6 +53,8 @@ static void _vglite_draw_letter(const lv_area_t * mask_area, lv_color_t color, l * STATIC VARIABLES **********************/ +static bool _use_static_bitmap = false; + /********************** * GLOBAL VARIABLES **********************/ @@ -64,33 +67,60 @@ static void _vglite_draw_letter(const lv_area_t * mask_area, lv_color_t color, l * GLOBAL FUNCTIONS **********************/ -void lv_draw_vglite_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, - const lv_area_t * coords) +void lv_draw_vglite_label(vglite_draw_task_t * vglite_task) { + const lv_draw_label_dsc_t * dsc = vglite_task->t->draw_dsc; + const lv_area_t * coords = &vglite_task->t->area; + if(dsc->opa <= LV_OPA_MIN) return; - lv_draw_label_iterate_characters(draw_unit, dsc, coords, _draw_vglite_letter); + lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *)dsc->font->dsc; + bool is_src_buf_aligned = vglite_src_buf_aligned(fdsc->glyph_bitmap, fdsc->stride, LV_COLOR_FORMAT_A8); + bool has_static_bitmap = lv_font_has_static_bitmap(dsc->font); + + _use_static_bitmap = is_src_buf_aligned & has_static_bitmap; + + lv_draw_label_iterate_characters(vglite_task->t, dsc, coords, _draw_vglite_letter); } /********************** * STATIC FUNCTIONS **********************/ -static void _draw_vglite_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc, +static void _draw_vglite_letter(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area) { if(glyph_draw_dsc) { + switch(glyph_draw_dsc->format) { case LV_FONT_GLYPH_FORMAT_NONE: { #if LV_USE_FONT_PLACEHOLDER /* Draw a placeholder rectangle*/ + vglite_draw_task_t * vglite_task = lv_malloc_zeroed(sizeof(vglite_draw_task_t)); + LV_ASSERT_MALLOC(vglite_task); + 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); + + vglite_task->t = t; + vglite_task->t->draw_dsc = &border_draw_dsc; + vglite_task->t->area = *glyph_draw_dsc->bg_coords; + + lv_draw_vglite_border(vglite_task); + + /** Cleanup for vglite_task */ + VGLITE_CHECK_ERROR(vg_lite_finish()); + if(vglite_task->path) { + VGLITE_CHECK_ERROR(vg_lite_clear_path(vglite_task->path)); + lv_free(vglite_task->path_data); + lv_free(vglite_task->path); + } + lv_free(vglite_task); #endif } break; @@ -99,19 +129,34 @@ static void _draw_vglite_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t if(glyph_draw_dsc->opa <= LV_OPA_MIN) return; - lv_layer_t * layer = draw_unit->target_layer; + lv_layer_t * layer = t->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, &t->clip_area)) return; lv_area_move(&blend_area, -layer->buf_area.x1, -layer->buf_area.y1); - const lv_draw_buf_t * draw_buf = glyph_draw_dsc->glyph_data; - const void * mask_buf = draw_buf->data; + const void * mask_buf = NULL; + const lv_draw_buf_t * draw_buf = NULL; + uint32_t mask_stride; + if(!_use_static_bitmap) { + draw_buf = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); + if(draw_buf != NULL) { + mask_buf = draw_buf->data; + } + else { + return; + } + mask_stride = draw_buf->header.stride; + } + else { + glyph_draw_dsc->g->req_raw_bitmap = 1; + mask_buf = lv_font_get_glyph_static_bitmap(glyph_draw_dsc->g); + mask_stride = glyph_draw_dsc->g->stride; + } uint32_t mask_width = lv_area_get_width(glyph_draw_dsc->letter_coords); uint32_t mask_height = lv_area_get_height(glyph_draw_dsc->letter_coords); - uint32_t mask_stride = draw_buf->header.stride; lv_area_t mask_area; mask_area.x1 = blend_area.x1 - (glyph_draw_dsc->letter_coords->x1 - layer->buf_area.x1); @@ -119,24 +164,49 @@ 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; - /* Set src_vgbuf structure. */ + /* Set src_buf structure. */ vglite_set_src_buf(mask_buf, mask_width, mask_height, mask_stride, LV_COLOR_FORMAT_A8); - /* Set vgmatrix. */ + /* Set matrix. */ vglite_set_translation_matrix(&blend_area); - lv_draw_buf_invalidate_cache(draw_buf, &mask_area); + if(!_use_static_bitmap) + lv_draw_buf_invalidate_cache(draw_buf, &mask_area); _vglite_draw_letter(&mask_area, glyph_draw_dsc->color, glyph_draw_dsc->opa); } break; case LV_FONT_GLYPH_FORMAT_IMAGE: { #if LV_USE_IMGFONT + glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); + vglite_draw_task_t * vglite_task = lv_malloc_zeroed(sizeof(vglite_draw_task_t)); + LV_ASSERT_MALLOC(vglite_task); + 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); + + void * old_dsc = t->draw_dsc; + lv_area_t old_area = t->area; + + t->draw_dsc = &img_dsc; + t->area = *glyph_draw_dsc->letter_coords; + vglite_task->t = t; + + lv_draw_vglite_img(vglite_task); + + /** Cleanup for vglite_task */ + vg_lite_finish(); + if(vglite_task->path) { + VGLITE_CHECK_ERROR(vg_lite_clear_path(vglite_task->path)); + lv_free(vglite_task->path_data); + lv_free(vglite_task->path); + } + lv_free(vglite_task); + + t->draw_dsc = old_dsc; + t->area = old_area; #endif } break; @@ -146,17 +216,37 @@ static void _draw_vglite_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t } if(fill_draw_dsc && fill_area) { - lv_draw_vglite_fill(draw_unit, fill_draw_dsc, fill_area); + vglite_draw_task_t * vglite_task = lv_malloc_zeroed(sizeof(vglite_draw_task_t)); + LV_ASSERT_MALLOC(vglite_task); + + t->draw_dsc = fill_draw_dsc; + t->area = *fill_area; + vglite_task->t = t; + + lv_draw_vglite_fill(vglite_task); + + /** Cleanup for vglite_task */ + vg_lite_finish(); + if(vglite_task->path) { + VGLITE_CHECK_ERROR(vg_lite_clear_path(vglite_task->path)); + lv_free(vglite_task->path_data); + lv_free(vglite_task->path); + } + if(vglite_task->gradient) { + VGLITE_CHECK_ERROR(vg_lite_clear_grad(vglite_task->gradient)); + lv_free(vglite_task->gradient); + } + lv_free(vglite_task); } } static void _vglite_draw_letter(const lv_area_t * mask_area, lv_color_t color, lv_opa_t opa) { - vg_lite_buffer_t * dst_vgbuf = vglite_get_dest_buf(); - vg_lite_buffer_t * mask_vgbuf = vglite_get_src_buf(); + vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); + vg_lite_buffer_t * mask_buf = vglite_get_src_buf(); - mask_vgbuf->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; - mask_vgbuf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT; + mask_buf->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; + mask_buf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT; vg_lite_rectangle_t rect = { .x = (vg_lite_int32_t)mask_area->x1, @@ -168,10 +258,10 @@ static void _vglite_draw_letter(const lv_area_t * mask_area, lv_color_t color, l lv_color32_t col32 = lv_color_to_32(color, opa); vg_lite_color_t vgcol = vglite_get_color(col32, false); - vg_lite_matrix_t * vgmatrix = vglite_get_matrix(); + vg_lite_matrix_t * matrix = vglite_get_matrix(); /*Blit with font color as paint color*/ - VGLITE_CHECK_ERROR(vg_lite_blit_rect(dst_vgbuf, mask_vgbuf, &rect, vgmatrix, VG_LITE_BLEND_SRC_OVER, vgcol, + VGLITE_CHECK_ERROR(vg_lite_blit_rect(dest_buf, mask_buf, &rect, matrix, VG_LITE_BLEND_SRC_OVER, vgcol, VG_LITE_FILTER_POINT)); vglite_run(); 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 ce3f59ea5..559b1107c 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 @@ -46,9 +46,10 @@ * GLOBAL FUNCTIONS **********************/ -void lv_draw_vglite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, - const lv_area_t * coords) +void lv_draw_vglite_layer(vglite_draw_task_t * vglite_task) { + lv_draw_image_dsc_t * draw_dsc = vglite_task->t->draw_dsc; + lv_layer_t * layer_to_draw = (lv_layer_t *)draw_dsc->src; const lv_draw_buf_t * draw_buf = layer_to_draw->draw_buf; @@ -70,9 +71,12 @@ void lv_draw_vglite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t lv_draw_image_dsc_t new_draw_dsc = *draw_dsc; new_draw_dsc.src = draw_buf; - lv_draw_vglite_img(draw_unit, &new_draw_dsc, coords); + vglite_task->t->draw_dsc = &new_draw_dsc; + lv_draw_vglite_img(vglite_task); + vglite_task->t->draw_dsc = draw_dsc; #if LV_USE_LAYER_DEBUG || LV_USE_PARALLEL_DRAW_DEBUG + const lv_area_t * coords = &vglite_task->t->area; lv_area_t area_rot; lv_area_copy(&area_rot, coords); bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE || @@ -91,7 +95,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, &vglite_task->t->clip_area)) return; #endif #if LV_USE_LAYER_DEBUG @@ -99,37 +103,32 @@ void lv_draw_vglite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t lv_draw_fill_dsc_init(&fill_dsc); fill_dsc.color = lv_color_hex(layer_to_draw->color_format == LV_COLOR_FORMAT_ARGB8888 ? 0xff0000 : 0x00ff00); fill_dsc.opa = LV_OPA_20; - lv_draw_sw_fill(draw_unit, &fill_dsc, &area_rot); + lv_draw_sw_fill(vglite_task->t, &fill_dsc, &area_rot); lv_draw_border_dsc_t border_dsc; lv_draw_border_dsc_init(&border_dsc); border_dsc.color = fill_dsc.color; border_dsc.opa = LV_OPA_60; border_dsc.width = 2; - lv_draw_sw_border(draw_unit, &border_dsc, &area_rot); + lv_draw_sw_border(vglite_task->t, &border_dsc, &area_rot); #endif #if LV_USE_PARALLEL_DRAW_DEBUG - uint32_t idx = 0; - lv_draw_unit_t * draw_unit_tmp = _draw_info.unit_head; - while(draw_unit_tmp != draw_unit) { - draw_unit_tmp = draw_unit_tmp->next; - idx++; - } + int32_t idx = vglite_task->t->draw_unit->idx; 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.opa = LV_OPA_10; - lv_draw_sw_fill(draw_unit, &fill_dsc, &area_rot); + lv_draw_sw_fill(vglite_task->t, &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.opa = LV_OPA_100; border_dsc.width = 2; - lv_draw_sw_border(draw_unit, &border_dsc, &area_rot); + lv_draw_sw_border(vglite_task->t, &border_dsc, &area_rot); lv_point_t txt_size; lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE); @@ -142,7 +141,7 @@ void lv_draw_vglite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t lv_draw_fill_dsc_init(&fill_dsc); fill_dsc.color = lv_color_black(); - lv_draw_sw_fill(draw_unit, &fill_dsc, &txt_area); + lv_draw_sw_fill(vglite_task->t, &fill_dsc, &txt_area); char buf[8]; lv_snprintf(buf, sizeof(buf), "%d", idx); @@ -150,7 +149,7 @@ void lv_draw_vglite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t lv_draw_label_dsc_init(&label_dsc); label_dsc.color = lv_color_white(); label_dsc.text = buf; - lv_draw_sw_label(draw_unit, &label_dsc, &txt_area); + lv_draw_sw_label(vglite_task->t, &label_dsc, &txt_area); #endif } 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 f70c02b20..105b7add8 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 @@ -31,6 +31,18 @@ * STATIC PROTOTYPES **********************/ +/** + * Set line path data + * + * @param[in/out] line_path Coordinates of the line + * @param[in/out] path_data_size Size of path_data (bytes) + * @param[in] p1 First point of the line + * @patam[in] p2 Second point of the line + * + */ +static void _vglite_set_line(int32_t * line_path, uint32_t * path_data_size, + const lv_point_t * point1, const lv_point_t * point2); + /** * Draw line shape with effects * @@ -40,7 +52,7 @@ * @param[in] dsc Line description structure (width, rounded ending, opacity, ...) * */ -static void _vglite_draw_line(const lv_point_t * point1, const lv_point_t * point2, +static void _vglite_draw_line(vglite_draw_task_t * vglite_task, const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip_area, const lv_draw_line_dsc_t * dsc); /********************** @@ -55,8 +67,10 @@ static void _vglite_draw_line(const lv_point_t * point1, const lv_point_t * poin * GLOBAL FUNCTIONS **********************/ -void lv_draw_vglite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc) +void lv_draw_vglite_line(vglite_draw_task_t * vglite_task) { + const lv_draw_line_dsc_t * dsc = vglite_task->t->draw_dsc; + if(dsc->width == 0) return; if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) @@ -64,14 +78,14 @@ void lv_draw_vglite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * if(dsc->p1.x == dsc->p2.x && dsc->p1.y == dsc->p2.y) return; - lv_layer_t * layer = draw_unit->target_layer; + lv_layer_t * layer = vglite_task->t->target_layer; lv_area_t clip_area; clip_area.x1 = LV_MIN(dsc->p1.x, dsc->p2.x) - dsc->width / 2; clip_area.x2 = LV_MAX(dsc->p1.x, dsc->p2.x) + dsc->width / 2; 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, &vglite_task->t->clip_area)) return; /*Fully clipped, nothing to do*/ lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); @@ -79,18 +93,35 @@ void lv_draw_vglite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * lv_point_t point1 = {dsc->p1.x - layer->buf_area.x1, dsc->p1.y - layer->buf_area.y1}; lv_point_t point2 = {dsc->p2.x - layer->buf_area.x1, dsc->p2.y - layer->buf_area.y1}; - _vglite_draw_line(&point1, &point2, &clip_area, dsc); + _vglite_draw_line(vglite_task, &point1, &point2, &clip_area, dsc); } /********************** * STATIC FUNCTIONS **********************/ -static void _vglite_draw_line(const lv_point_t * point1, const lv_point_t * point2, +static void _vglite_set_line(int32_t * line_path, uint32_t * path_data_size, const lv_point_t * point1, + const lv_point_t * point2) +{ + uint32_t pidx = 0; + line_path[pidx++] = VLC_OP_MOVE; + line_path[pidx++] = point1->x; + line_path[pidx++] = point1->y; + line_path[pidx++] = VLC_OP_LINE; + line_path[pidx++] = point2->x; + line_path[pidx++] = point2->y; + line_path[pidx++] = VLC_OP_END; + + *path_data_size = pidx * sizeof(int32_t); +} + +static void _vglite_draw_line(vglite_draw_task_t * vglite_task, const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip_area, const lv_draw_line_dsc_t * dsc) { - vg_lite_path_t path; - vg_lite_buffer_t * vgbuf = vglite_get_dest_buf(); + vg_lite_path_t * path = lv_malloc_zeroed(sizeof(vg_lite_path_t)); + LV_ASSERT_MALLOC(path); + vglite_task->path = path; + vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); vg_lite_cap_style_t cap_style = (dsc->round_start || dsc->round_end) ? VG_LITE_CAP_ROUND : VG_LITE_CAP_BUTT; vg_lite_join_style_t join_style = (dsc->round_start || dsc->round_end) ? VG_LITE_JOIN_ROUND : VG_LITE_JOIN_MITER; @@ -106,40 +137,33 @@ static void _vglite_draw_line(const lv_point_t * point1, const lv_point_t * poin stroke_dash_phase = (vg_lite_float_t)dsc->dash_width / 2; } - vg_lite_blend_t vgblend = vglite_get_blend_mode(dsc->blend_mode); - /*** Init path ***/ int32_t width = dsc->width; - int32_t line_path[] = { /*VG line path*/ - VLC_OP_MOVE, point1->x, point1->y, - VLC_OP_LINE, point2->x, point2->y, - VLC_OP_END - }; + uint32_t path_data_size = 0; + int32_t * line_path = lv_malloc_zeroed(7 * sizeof(int32_t)); + LV_ASSERT_MALLOC(line_path); + vglite_task->path_data = line_path; + _vglite_set_line(line_path, &path_data_size, point1, point2); - VGLITE_CHECK_ERROR(vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_HIGH, sizeof(line_path), line_path, + VGLITE_CHECK_ERROR(vg_lite_init_path(path, VG_LITE_S32, VG_LITE_HIGH, path_data_size, line_path, (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f)); lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa); vg_lite_color_t vgcol = vglite_get_color(col32, false); - vg_lite_matrix_t matrix; - vg_lite_identity(&matrix); - /*** Draw line ***/ - VGLITE_CHECK_ERROR(vg_lite_set_draw_path_type(&path, VG_LITE_DRAW_STROKE_PATH)); + VGLITE_CHECK_ERROR(vg_lite_set_draw_path_type(path, VG_LITE_DRAW_STROKE_PATH)); - VGLITE_CHECK_ERROR(vg_lite_set_stroke(&path, cap_style, join_style, width, 8, stroke_dash_pattern, stroke_dash_count, + VGLITE_CHECK_ERROR(vg_lite_set_stroke(path, cap_style, join_style, width, 8, stroke_dash_pattern, stroke_dash_count, stroke_dash_phase, vgcol)); - VGLITE_CHECK_ERROR(vg_lite_update_stroke(&path)); + VGLITE_CHECK_ERROR(vg_lite_update_stroke(path)); - VGLITE_CHECK_ERROR(vg_lite_draw(vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, vgblend, vgcol)); + VGLITE_CHECK_ERROR(vg_lite_draw(dest_buf, path, VG_LITE_FILL_NON_ZERO, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); vglite_run(); - - VGLITE_CHECK_ERROR(vg_lite_clear_path(&path)); } #endif /*LV_USE_DRAW_VGLITE*/ 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 8556fdf2a..95da98790 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 @@ -34,15 +34,28 @@ * STATIC PROTOTYPES **********************/ +/** + * Set triangle path data + * + * @param[in/out] path_data Coordinates of the triangle + * @param[in/out] path_data_size Size of path_data (bytes) + * @param[in] p Points of the triangle + * + */ +static void _vglite_set_triangle(int32_t * path_data, uint32_t * path_data_size, + const lv_point_precise_t * p); + /** * Draw triangle shape with effects (opacity, gradient) * + * @param[in] vglite_task The current vglite task * @param[in] coords Coordinates of the triangle (relative to dest buff) * @param[in] clip_area Clipping area with relative coordinates to dest buff * @param[in] dsc Description of the triangle * */ -static void _vglite_draw_triangle(const lv_area_t * coords, const lv_area_t * clip_area, +static void _vglite_draw_triangle(vglite_draw_task_t * vglite_task, const lv_area_t * coords, + const lv_area_t * clip_area, const lv_draw_triangle_dsc_t * dsc); /********************** @@ -57,14 +70,16 @@ static void _vglite_draw_triangle(const lv_area_t * coords, const lv_area_t * cl * GLOBAL FUNCTIONS **********************/ -void lv_draw_vglite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc) +void lv_draw_vglite_triangle(vglite_draw_task_t * vglite_task) { - if(dsc->bg_opa <= (lv_opa_t)LV_OPA_MIN) + const lv_draw_triangle_dsc_t * dsc = vglite_task->t->draw_dsc; + + if(dsc->opa <= (lv_opa_t)LV_OPA_MIN) return; - lv_layer_t * layer = draw_unit->target_layer; + lv_layer_t * layer = vglite_task->t->target_layer; lv_area_t clip_area; - lv_area_copy(&clip_area, draw_unit->clip_area); + lv_area_copy(&clip_area, &vglite_task->t->clip_area); lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1); lv_area_t coords; @@ -79,17 +94,38 @@ void lv_draw_vglite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_ if(!lv_area_intersect(&clipped_coords, &coords, &clip_area)) return; /* Fully clipped, nothing to do */ - _vglite_draw_triangle(&coords, &clip_area, dsc); + _vglite_draw_triangle(vglite_task, &coords, &clip_area, dsc); } /********************** * STATIC FUNCTIONS **********************/ -static void _vglite_draw_triangle(const lv_area_t * coords, const lv_area_t * clip_area, +static void _vglite_set_triangle(int32_t * path_data, uint32_t * path_data_size, const lv_point_precise_t * p) +{ + uint32_t pidx = 0; + path_data[pidx++] = VLC_OP_MOVE; + path_data[pidx++] = p[0].x; + path_data[pidx++] = p[0].y; + path_data[pidx++] = VLC_OP_LINE; + path_data[pidx++] = p[1].x; + path_data[pidx++] = p[1].y; + path_data[pidx++] = VLC_OP_LINE; + path_data[pidx++] = p[2].x; + path_data[pidx++] = p[2].y; + path_data[pidx++] = VLC_OP_LINE; + path_data[pidx++] = p[0].x; + path_data[pidx++] = p[0].y; + path_data[pidx++] = VLC_OP_END; + + *path_data_size = pidx * sizeof(int32_t); +} + +static void _vglite_draw_triangle(vglite_draw_task_t * vglite_task, const lv_area_t * coords, + const lv_area_t * clip_area, const lv_draw_triangle_dsc_t * dsc) { - vg_lite_buffer_t * vgbuf = vglite_get_dest_buf(); + vg_lite_buffer_t * dest_buf = vglite_get_dest_buf(); lv_area_t tri_area; tri_area.x1 = (int32_t)LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); @@ -101,31 +137,34 @@ static void _vglite_draw_triangle(const lv_area_t * coords, const lv_area_t * cl uint32_t height = lv_area_get_height(&tri_area); /* Init path */ - int32_t triangle_path[] = { /*VG line path*/ - VLC_OP_MOVE, dsc->p[0].x, dsc->p[0].y, - VLC_OP_LINE, dsc->p[1].x, dsc->p[1].y, - VLC_OP_LINE, dsc->p[2].x, dsc->p[2].y, - VLC_OP_LINE, dsc->p[0].x, dsc->p[0].y, - VLC_OP_END - }; + uint32_t path_data_size; + int32_t * triangle_path = lv_malloc_zeroed(13 * sizeof(int32_t)); + LV_ASSERT_MALLOC(triangle_path); + vglite_task->path_data = triangle_path; + _vglite_set_triangle(triangle_path, &path_data_size, dsc->p); - vg_lite_path_t path; - VGLITE_CHECK_ERROR(vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_HIGH, sizeof(triangle_path), triangle_path, + + vg_lite_path_t * path = lv_malloc_zeroed(sizeof(vg_lite_path_t)); + LV_ASSERT_MALLOC(path); + vglite_task->path = path; + VGLITE_CHECK_ERROR(vg_lite_init_path(path, VG_LITE_S32, VG_LITE_HIGH, path_data_size, triangle_path, (vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1, ((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f)); - vg_lite_matrix_t matrix; - vg_lite_identity(&matrix); - /* Init Color */ - lv_color32_t col32 = lv_color_to_32(dsc->bg_color, dsc->bg_opa); + lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa); vg_lite_color_t vgcol = vglite_get_color(col32, false); - vg_lite_linear_gradient_t gradient; - bool has_gradient = (dsc->bg_grad.dir != (lv_grad_dir_t)LV_GRAD_DIR_NONE); + vg_lite_linear_gradient_t * gradient; + + bool has_gradient = (dsc->grad.dir != (lv_grad_dir_t)LV_GRAD_DIR_NONE); /* Init Gradient*/ if(has_gradient) { + gradient = lv_malloc_zeroed(sizeof(vg_lite_linear_gradient_t)); + LV_ASSERT_MALLOC(gradient); + vglite_task->gradient = gradient; + vg_lite_matrix_t * grad_matrix; vg_lite_uint32_t colors[LV_GRADIENT_MAX_STOPS]; @@ -133,50 +172,43 @@ static void _vglite_draw_triangle(const lv_area_t * coords, const lv_area_t * cl lv_color32_t col32[LV_GRADIENT_MAX_STOPS]; /* Gradient Setup */ - vg_lite_uint32_t cnt = LV_MAX(dsc->bg_grad.stops_count, LV_GRADIENT_MAX_STOPS); - lv_opa_t bg_opa; + vg_lite_uint32_t cnt = LV_MIN(dsc->grad.stops_count, LV_GRADIENT_MAX_STOPS); + lv_opa_t 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); + stops[i] = dsc->grad.stops[i].frac; + opa = LV_OPA_MIX2(dsc->grad.stops[i].opa, dsc->opa); - col32[i] = lv_color_to_32(dsc->bg_grad.stops[i].color, bg_opa); + col32[i] = lv_color_to_32(dsc->grad.stops[i].color, opa); colors[i] = vglite_get_color(col32[i], true); } - lv_memzero(&gradient, sizeof(vg_lite_linear_gradient_t)); + VGLITE_CHECK_ERROR(vg_lite_init_grad(gradient)); - VGLITE_CHECK_ERROR(vg_lite_init_grad(&gradient)); + VGLITE_CHECK_ERROR(vg_lite_set_grad(gradient, cnt, colors, stops)); - VGLITE_CHECK_ERROR(vg_lite_set_grad(&gradient, cnt, colors, stops)); + VGLITE_CHECK_ERROR(vg_lite_update_grad(gradient)); - VGLITE_CHECK_ERROR(vg_lite_update_grad(&gradient)); + grad_matrix = vg_lite_get_grad_matrix(gradient); + VGLITE_CHECK_ERROR(vg_lite_identity(grad_matrix)); + VGLITE_CHECK_ERROR(vg_lite_translate((float)coords->x1, (float)coords->y1, grad_matrix)); - grad_matrix = vg_lite_get_grad_matrix(&gradient); - vg_lite_identity(grad_matrix); - vg_lite_translate((float)coords->x1, (float)coords->y1, grad_matrix); - - if(dsc->bg_grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_VER) { - vg_lite_scale(1.0f, (float)height / 256.0f, grad_matrix); - vg_lite_rotate(90.0f, grad_matrix); + if(dsc->grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_VER) { + VGLITE_CHECK_ERROR(vg_lite_scale(1.0f, (float)height / 256.0f, grad_matrix)); + VGLITE_CHECK_ERROR(vg_lite_rotate(90.0f, grad_matrix)); } else { /*LV_GRAD_DIR_HOR*/ - vg_lite_scale((float)width / 256.0f, 1.0f, grad_matrix); + VGLITE_CHECK_ERROR(vg_lite_scale((float)width / 256.0f, 1.0f, grad_matrix)); } - VGLITE_CHECK_ERROR(vg_lite_draw_gradient(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, &gradient, + VGLITE_CHECK_ERROR(vg_lite_draw_gradient(dest_buf, path, VG_LITE_FILL_EVEN_ODD, NULL, gradient, VG_LITE_BLEND_SRC_OVER)); } else { - VGLITE_CHECK_ERROR(vg_lite_draw(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol)); + VGLITE_CHECK_ERROR(vg_lite_draw(dest_buf, path, VG_LITE_FILL_EVEN_ODD, NULL, VG_LITE_BLEND_SRC_OVER, vgcol)); } vglite_run(); - - VGLITE_CHECK_ERROR(vg_lite_clear_path(&path)); - - if(has_gradient) - VGLITE_CHECK_ERROR(vg_lite_clear_grad(&gradient)); } #endif /*LV_USE_DRAW_VGLITE*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_buf.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_buf.c index a72c8e554..76f9dc13e 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_buf.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_buf.c @@ -38,8 +38,8 @@ static inline void _set_vgbuf_ptr(vg_lite_buffer_t * vgbuf, void * buf); * STATIC VARIABLES **********************/ -static vg_lite_buffer_t _dest_vgbuf; -static vg_lite_buffer_t _src_vgbuf; +static vg_lite_buffer_t _dest_buf; +static vg_lite_buffer_t _src_buf; /********************** * MACROS @@ -51,34 +51,34 @@ static vg_lite_buffer_t _src_vgbuf; vg_lite_buffer_t * vglite_get_dest_buf(void) { - return &_dest_vgbuf; + return &_dest_buf; } vg_lite_buffer_t * vglite_get_src_buf(void) { - return &_src_vgbuf; + return &_src_buf; } void vglite_set_dest_buf_ptr(void * buf) { - _set_vgbuf_ptr(&_dest_vgbuf, buf); + _set_vgbuf_ptr(&_dest_buf, buf); } void vglite_set_src_buf_ptr(const void * buf) { - _set_vgbuf_ptr(&_src_vgbuf, (void *)buf); + _set_vgbuf_ptr(&_src_buf, (void *)buf); } void vglite_set_dest_buf(const void * buf, uint32_t width, uint32_t height, uint32_t stride, lv_color_format_t cf) { - vglite_set_buf(&_dest_vgbuf, (void *)buf, width, height, stride, cf); + vglite_set_buf(&_dest_buf, (void *)buf, width, height, stride, cf); } void vglite_set_src_buf(const void * buf, uint32_t width, uint32_t height, uint32_t stride, lv_color_format_t cf) { - vglite_set_buf(&_src_vgbuf, (void *)buf, width, height, stride, cf); + vglite_set_buf(&_src_buf, (void *)buf, width, height, stride, cf); } void vglite_set_buf(vg_lite_buffer_t * vgbuf, void * buf, diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_buf.h b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_buf.h index 3ef434748..c15d918d0 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_buf.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_buf.h @@ -22,7 +22,7 @@ extern "C" { #include "../../../lv_conf_internal.h" #if LV_USE_DRAW_VGLITE -#include "../../sw/lv_draw_sw.h" +#include "../../lv_draw.h" #include "vg_lite.h" diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_matrix.c b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_matrix.c index 0594b53dc..f41ed3746 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_matrix.c +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_matrix.c @@ -33,7 +33,7 @@ * STATIC VARIABLES **********************/ -static vg_lite_matrix_t _vgmatrix; +static vg_lite_matrix_t _matrix; /********************** * MACROS @@ -45,13 +45,13 @@ static vg_lite_matrix_t _vgmatrix; vg_lite_matrix_t * vglite_get_matrix(void) { - return &_vgmatrix; + return &_matrix; } void vglite_set_translation_matrix(const lv_area_t * dest_area) { - vg_lite_identity(&_vgmatrix); - vg_lite_translate((vg_lite_float_t)dest_area->x1, (vg_lite_float_t)dest_area->y1, &_vgmatrix); + vg_lite_identity(&_matrix); + vg_lite_translate((vg_lite_float_t)dest_area->x1, (vg_lite_float_t)dest_area->y1, &_matrix); } void vglite_set_transformation_matrix(const lv_area_t * dest_area, const lv_draw_image_dsc_t * dsc) @@ -62,15 +62,15 @@ void vglite_set_transformation_matrix(const lv_area_t * dest_area, const lv_draw bool has_rotation = (dsc->rotation != 0); if(has_scale || has_rotation) { - vg_lite_translate(dsc->pivot.x, dsc->pivot.y, &_vgmatrix); + vg_lite_translate(dsc->pivot.x, dsc->pivot.y, &_matrix); if(has_rotation) - vg_lite_rotate(dsc->rotation / 10.0f, &_vgmatrix); /* angle is 1/10 degree */ + vg_lite_rotate(dsc->rotation / 10.0f, &_matrix); /* angle is 1/10 degree */ if(has_scale) { vg_lite_float_t scale_x = 1.0f * dsc->scale_x / LV_SCALE_NONE; vg_lite_float_t scale_y = 1.0f * dsc->scale_y / LV_SCALE_NONE; - vg_lite_scale(scale_x, scale_y, &_vgmatrix); + vg_lite_scale(scale_x, scale_y, &_matrix); } - vg_lite_translate(0.0f - dsc->pivot.x, 0.0f - dsc->pivot.y, &_vgmatrix); + vg_lite_translate(0.0f - dsc->pivot.x, 0.0f - dsc->pivot.y, &_matrix); } } diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_matrix.h b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_matrix.h index 832cd86bb..0f735d69e 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_matrix.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_matrix.h @@ -22,7 +22,9 @@ extern "C" { #include "../../../lv_conf_internal.h" #if LV_USE_DRAW_VGLITE -#include "../../sw/lv_draw_sw.h" + +#include "../../lv_draw_image.h" +#include "../../lv_draw.h" #include "vg_lite.h" diff --git a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_path.h b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_path.h index f38593aeb..a4cd21e58 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_path.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/nxp/vglite/lv_vglite_path.h @@ -22,7 +22,8 @@ extern "C" { #include "../../../lv_conf_internal.h" #if LV_USE_DRAW_VGLITE -#include "../../sw/lv_draw_sw.h" +#include "../../lv_draw.h" +#include "../../lv_draw_triangle.h" /********************* * DEFINES 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 b3afa5a40..5daa29ecd 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 @@ -186,6 +186,9 @@ vg_lite_buffer_format_t vglite_get_buf_format(lv_color_format_t cf) case LV_COLOR_FORMAT_L8: vg_buffer_format = VG_LITE_L8; break; + case LV_COLOR_FORMAT_A4: + vg_buffer_format = VG_LITE_A4; + break; case LV_COLOR_FORMAT_A8: vg_buffer_format = VG_LITE_A8; break; @@ -204,8 +207,8 @@ vg_lite_buffer_format_t vglite_get_buf_format(lv_color_format_t cf) case LV_COLOR_FORMAT_RGB565: vg_buffer_format = VG_LITE_BGR565; break; - case LV_COLOR_FORMAT_RGB565A8: - vg_buffer_format = VG_LITE_ABGR8565; + case LV_COLOR_FORMAT_ARGB8565: + vg_buffer_format = VG_LITE_BGRA5658; break; case LV_COLOR_FORMAT_RGB888: vg_buffer_format = VG_LITE_BGR888; @@ -233,6 +236,7 @@ uint8_t vglite_get_stride_alignment(lv_color_format_t cf) case LV_COLOR_FORMAT_I1: case LV_COLOR_FORMAT_I2: case LV_COLOR_FORMAT_I4: + case LV_COLOR_FORMAT_A4: align_bytes = 8; break; case LV_COLOR_FORMAT_I8: @@ -243,7 +247,7 @@ uint8_t vglite_get_stride_alignment(lv_color_format_t cf) case LV_COLOR_FORMAT_RGB565: align_bytes = 32; break; - case LV_COLOR_FORMAT_RGB565A8: + case LV_COLOR_FORMAT_ARGB8565: case LV_COLOR_FORMAT_RGB888: align_bytes = 48; break; 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 6615c4c79..c61e04ecd 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 @@ -22,7 +22,7 @@ extern "C" { #include "../../../lv_conf_internal.h" #if LV_USE_DRAW_VGLITE -#include "../../sw/lv_draw_sw.h" +#include "../../lv_draw.h" #include "vg_lite.h" #include "vg_lite_options.h" @@ -49,6 +49,7 @@ extern "C" { } \ } while(0) +#if LV_USE_VGLITE_CHECK_ERROR #define VGLITE_CHECK_ERROR(function) \ do { \ vg_lite_error_t error = function; \ @@ -58,6 +59,9 @@ extern "C" { VGLITE_ASSERT(false); \ } \ } while (0) +#else +#define VGLITE_CHECK_ERROR(function) function +#endif /********************** * TYPEDEFS diff --git a/lib/libesp32_lvgl/lvgl/src/draw/opengles/lv_draw_opengles.c b/lib/libesp32_lvgl/lvgl/src/draw/opengles/lv_draw_opengles.c new file mode 100644 index 000000000..fac8bebcc --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/opengles/lv_draw_opengles.c @@ -0,0 +1,634 @@ +/** + * @file lv_draw_opengles.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_draw_opengles.h" +#if LV_USE_DRAW_OPENGLES +#include "../lv_draw_private.h" +#include "../../misc/cache/lv_cache_entry_private.h" +#include "../../drivers/glfw/lv_opengles_debug.h" +#include "../../drivers/glfw/lv_opengles_texture.h" +#include "../../drivers/glfw/lv_opengles_driver.h" +#include +#include +#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" +#include "../../draw/lv_draw_3d.h" +#include "../../core/lv_obj.h" +#include "../../core/lv_refr_private.h" +#include "../../display/lv_display_private.h" +#include "../../stdlib/lv_string.h" +#include "../../misc/lv_area_private.h" + +/********************* + * DEFINES + *********************/ + +#define DRAW_UNIT_ID_OPENGLES 6 + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_draw_unit_t base_unit; + lv_draw_task_t * task_act; + lv_cache_t * texture_cache; + unsigned int framebuffer; + lv_draw_buf_t render_draw_buf; +} lv_draw_opengles_unit_t; + +typedef struct { + lv_draw_dsc_base_t * draw_dsc; + int32_t w; + int32_t h; + unsigned int texture; +} cache_data_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static bool opengles_texture_cache_create_cb(cache_data_t * cached_data, void * user_data); +static void opengles_texture_cache_free_cb(cache_data_t * cached_data, void * user_data); +static lv_cache_compare_res_t opengles_texture_cache_compare_cb(const cache_data_t * lhs, const cache_data_t * rhs); + +static void blend_texture_layer(lv_draw_task_t * t); +static void draw_from_cached_texture(lv_draw_task_t * t); + +static void execute_drawing(lv_draw_opengles_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_opengles_unit_t * u, cache_data_t * cache_data); + +static unsigned int layer_get_texture(lv_layer_t * layer); +static unsigned int get_framebuffer(lv_draw_opengles_unit_t * u); +static unsigned int create_texture(int32_t w, int32_t h, const void * data); + +#if LV_USE_3DTEXTURE + static void lv_draw_opengles_3d(lv_draw_task_t * t, const lv_draw_3d_dsc_t * dsc, const lv_area_t * coords); +#endif + +/********************** + * STATIC VARIABLES + **********************/ + +static lv_draw_opengles_unit_t * g_unit; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_opengles_init(void) +{ + lv_draw_opengles_unit_t * draw_opengles_unit = lv_draw_create_unit(sizeof(lv_draw_opengles_unit_t)); + draw_opengles_unit->base_unit.dispatch_cb = dispatch; + draw_opengles_unit->base_unit.evaluate_cb = evaluate; + draw_opengles_unit->base_unit.name = "OPENGLES"; + draw_opengles_unit->texture_cache = lv_cache_create(&lv_cache_class_lru_rb_count, + sizeof(cache_data_t), 128, (lv_cache_ops_t) { + .compare_cb = (lv_cache_compare_cb_t)opengles_texture_cache_compare_cb, + .create_cb = (lv_cache_create_cb_t)opengles_texture_cache_create_cb, + .free_cb = (lv_cache_free_cb_t)opengles_texture_cache_free_cb, + }); + lv_cache_set_name(draw_opengles_unit->texture_cache, "OPENGLES_TEXTURE"); + + lv_draw_buf_init(&draw_opengles_unit->render_draw_buf, 0, 0, LV_COLOR_FORMAT_ARGB8888, LV_STRIDE_AUTO, NULL, 0); + + g_unit = draw_opengles_unit; +} + +void lv_draw_opengles_deinit(void) +{ + lv_free(g_unit->render_draw_buf.unaligned_data); + lv_cache_destroy(g_unit->texture_cache, g_unit); + if(g_unit->framebuffer != 0) { + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + GL_CALL(glDeleteFramebuffers(1, &g_unit->framebuffer)); + } + g_unit = NULL; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static bool opengles_texture_cache_create_cb(cache_data_t * cached_data, void * user_data) +{ + return draw_to_texture((lv_draw_opengles_unit_t *)user_data, cached_data); +} + +static void opengles_texture_cache_free_cb(cache_data_t * cached_data, void * user_data) +{ + LV_UNUSED(user_data); + + lv_free(cached_data->draw_dsc); + GL_CALL(glDeleteTextures(1, &cached_data->texture)); + cached_data->draw_dsc = NULL; + cached_data->texture = 0; +} + +static lv_cache_compare_res_t opengles_texture_cache_compare_cb(const cache_data_t * lhs, const cache_data_t * rhs) +{ + if(lhs == rhs) return 0; + + if(lhs->w != rhs->w) { + return lhs->w > rhs->w ? 1 : -1; + } + if(lhs->h != rhs->h) { + return lhs->h > rhs->h ? 1 : -1; + } + + uint32_t lhs_dsc_size = lhs->draw_dsc->dsc_size; + uint32_t rhs_dsc_size = rhs->draw_dsc->dsc_size; + + if(lhs_dsc_size != rhs_dsc_size) { + return lhs_dsc_size > rhs_dsc_size ? 1 : -1; + } + + 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; + } + + return 0; +} + +static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) +{ + lv_draw_opengles_unit_t * draw_opengles_unit = (lv_draw_opengles_unit_t *) draw_unit; + + /*Return immediately if it's busy with a draw task*/ + if(draw_opengles_unit->task_act) return 0; + + lv_draw_task_t * t = NULL; + t = lv_draw_get_available_task(layer, NULL, DRAW_UNIT_ID_OPENGLES); + if(t == NULL) return -1; + + unsigned int texture = layer_get_texture(layer); + if(texture == 0) { + lv_display_t * disp = lv_refr_get_disp_refreshing(); + if(layer != disp->layer_head) { + void * buf = lv_draw_layer_alloc_buf(layer); + if(buf == NULL) return -1; + + int32_t w = lv_area_get_width(&layer->buf_area); + int32_t h = lv_area_get_height(&layer->buf_area); + + texture = create_texture(w, h, NULL); + + layer->user_data = (void *)(uintptr_t)texture; + } + else { + layer->user_data = (void *)(uintptr_t)lv_opengles_texture_get_texture_id(disp); + } + } + + t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; + draw_opengles_unit->task_act = t; + + execute_drawing(draw_opengles_unit); + + draw_opengles_unit->task_act->state = LV_DRAW_TASK_STATE_READY; + draw_opengles_unit->task_act = NULL; + + /*The draw unit is free now. Request a new dispatching as it can get a new task*/ + lv_draw_dispatch_request(); + return 1; +} + +static int32_t evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task) +{ + LV_UNUSED(draw_unit); + + if(task->type == LV_DRAW_TASK_TYPE_IMAGE && + ((lv_draw_image_dsc_t *)task->draw_dsc)->header.cf >= LV_COLOR_FORMAT_PROPRIETARY_START) { + return 0; + } + + /*If not refreshing the display probably it's a canvas rendering + *which his not supported in OpenGL as it's not a texture.*/ + if(lv_refr_get_disp_refreshing() == NULL) return 0; + + if(((lv_draw_dsc_base_t *)task->draw_dsc)->user_data == NULL) { + task->preference_score = 0; + task->preferred_draw_unit_id = DRAW_UNIT_ID_OPENGLES; + } + return 0; +} + +static bool draw_to_texture(lv_draw_opengles_unit_t * u, cache_data_t * cache_data) +{ + lv_draw_task_t * task = u->task_act; + + lv_layer_t dest_layer; + lv_layer_init(&dest_layer); + + int32_t texture_w = lv_area_get_width(&task->_real_area); + int32_t texture_h = lv_area_get_height(&task->_real_area); + + if(NULL == lv_draw_buf_reshape(&u->render_draw_buf, LV_COLOR_FORMAT_ARGB8888, texture_w, texture_h, LV_STRIDE_AUTO)) { + uint8_t * data = u->render_draw_buf.unaligned_data; + uint32_t data_size = LV_DRAW_BUF_SIZE(texture_w, texture_h, LV_COLOR_FORMAT_ARGB8888); + data = lv_realloc(data, data_size); + LV_ASSERT_MALLOC(data); + lv_result_t init_result = lv_draw_buf_init(&u->render_draw_buf, texture_w, texture_h, LV_COLOR_FORMAT_ARGB8888, + LV_STRIDE_AUTO, data, data_size); + LV_ASSERT(init_result == LV_RESULT_OK); + } + + dest_layer.draw_buf = &u->render_draw_buf; + dest_layer.color_format = LV_COLOR_FORMAT_ARGB8888; + + dest_layer.buf_area = task->_real_area; + dest_layer._clip_area = task->_real_area; + dest_layer.phy_clip_area = task->_real_area; + lv_memzero(u->render_draw_buf.data, lv_area_get_size(&task->_real_area) * 4); + + 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); + } + + lv_draw_dsc_base_t * base_dsc = task->draw_dsc; + cache_data->draw_dsc = lv_malloc(base_dsc->dsc_size); + lv_memcpy((void *)cache_data->draw_dsc, base_dsc, base_dsc->dsc_size); + + switch(task->type) { + case LV_DRAW_TASK_TYPE_FILL: { + lv_draw_fill_dsc_t * fill_dsc = task->draw_dsc; + lv_draw_rect_dsc_t rect_dsc; + lv_draw_rect_dsc_init(&rect_dsc); + rect_dsc.base.user_data = (void *)(uintptr_t)1; + rect_dsc.bg_color = fill_dsc->color; + rect_dsc.bg_grad = fill_dsc->grad; + rect_dsc.radius = fill_dsc->radius; + rect_dsc.bg_opa = fill_dsc->opa; + + lv_draw_rect(&dest_layer, &rect_dsc, &task->area); + } + break; + case LV_DRAW_TASK_TYPE_BORDER: { + 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 = (void *)(uintptr_t)1; + rect_dsc.bg_opa = LV_OPA_TRANSP; + rect_dsc.radius = border_dsc->radius; + rect_dsc.border_color = border_dsc->color; + rect_dsc.border_opa = border_dsc->opa; + rect_dsc.border_side = border_dsc->side; + rect_dsc.border_width = border_dsc->width; + 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 = (void *)(uintptr_t)1; + 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_memcpy(&label_dsc, task->draw_dsc, sizeof(label_dsc)); + label_dsc.base.user_data = (void *)(uintptr_t)1; + 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 = (void *)(uintptr_t)1; + 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 = (void *)(uintptr_t)1; + 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 = (void *)(uintptr_t)1; + lv_draw_triangle(&dest_layer, &triangle_dsc); + } + break; + case LV_DRAW_TASK_TYPE_IMAGE: { + lv_draw_image_dsc_t image_dsc; + lv_memcpy(&image_dsc, task->draw_dsc, sizeof(image_dsc)); + image_dsc.base.user_data = (void *)(uintptr_t)1; + lv_draw_image(&dest_layer, &image_dsc, &task->area); + break; + } + default: + /*The malloced cache_data->draw_dsc will be freed automatically on failure + *in opengles_texture_cache_free_cb*/ + return false; + } + + while(dest_layer.draw_task_head) { + lv_draw_dispatch_layer(disp, &dest_layer); + if(dest_layer.draw_task_head) { + lv_draw_dispatch_wait_for_request(); + } + } + + unsigned int texture = create_texture(texture_w, texture_h, u->render_draw_buf.data); + + cache_data->w = texture_w; + cache_data->h = texture_h; + cache_data->texture = texture; + + if(obj) { + lv_obj_set_flag(obj, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS, original_send_draw_task_event); + } + + return true; +} + +static void blend_texture_layer(lv_draw_task_t * t) +{ + lv_draw_image_dsc_t * draw_dsc = t->draw_dsc; + lv_draw_opengles_unit_t * u = (lv_draw_opengles_unit_t *)t->draw_unit; + lv_area_t area; + area.x1 = -draw_dsc->pivot.x; + area.y1 = -draw_dsc->pivot.y; + area.x1 = (area.x1 * draw_dsc->scale_x) / 256; + area.y1 = (area.y1 * draw_dsc->scale_y) / 256; + area.x1 += t->area.x1 + draw_dsc->pivot.x; + area.y1 += t->area.y1 + draw_dsc->pivot.y; + lv_area_set_width(&area, lv_area_get_width(&t->area) * draw_dsc->scale_x / 256); + lv_area_set_height(&area, lv_area_get_height(&t->area) * draw_dsc->scale_y / 256); + + lv_layer_t * src_layer = (lv_layer_t *)draw_dsc->src; + unsigned int src_texture = layer_get_texture(src_layer); + + + lv_layer_t * dest_layer = t->target_layer; + unsigned int target_texture = layer_get_texture(dest_layer); + LV_ASSERT(target_texture != 0); + int32_t targ_tex_w = lv_area_get_width(&dest_layer->buf_area); + int32_t targ_tex_h = lv_area_get_height(&dest_layer->buf_area); + + GL_CALL(glBindTexture(GL_TEXTURE_2D, target_texture)); + + unsigned int framebuffer = get_framebuffer(u); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0)); + + lv_opengles_viewport(0, 0, targ_tex_w, targ_tex_h); + // TODO rotation + lv_opengles_render_texture(src_texture, &area, draw_dsc->opa, targ_tex_w, targ_tex_h, &t->clip_area, false); + + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + + + GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); + GL_CALL(glDeleteTextures(1, &src_texture)); +} + +static void draw_from_cached_texture(lv_draw_task_t * t) +{ + lv_draw_opengles_unit_t * u = (lv_draw_opengles_unit_t *)t->draw_unit; + 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->_real_area); + data_to_find.h = lv_area_get_height(&t->_real_area); + data_to_find.texture = 0; + + /*user_data stores the renderer to differentiate it from SW rendered tasks. + *However the cached texture is independent from the renderer so use NULL user_data*/ + 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. */ + lv_area_t a = t->area; + 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); + } + else if(t->type == LV_DRAW_TASK_TYPE_TRIANGLE) { + lv_draw_triangle_dsc_t * tri_dsc = (lv_draw_triangle_dsc_t *)data_to_find.draw_dsc; + tri_dsc->p[0].x -= t->area.x1; + tri_dsc->p[0].y -= t->area.y1; + tri_dsc->p[1].x -= t->area.x1; + tri_dsc->p[1].y -= t->area.y1; + tri_dsc->p[2].x -= t->area.x1; + tri_dsc->p[2].y -= t->area.y1; + } + else if(t->type == LV_DRAW_TASK_TYPE_LINE) { + lv_draw_line_dsc_t * line_dsc = (lv_draw_line_dsc_t *)data_to_find.draw_dsc; + line_dsc->p1.x -= t->area.x1; + line_dsc->p1.y -= t->area.y1; + line_dsc->p2.x -= t->area.x1; + line_dsc->p2.y -= t->area.y1; + } + else if(t->type == LV_DRAW_TASK_TYPE_ARC) { + lv_draw_arc_dsc_t * arc_dsc = (lv_draw_arc_dsc_t *)data_to_find.draw_dsc; + arc_dsc->center.x -= t->area.x1; + arc_dsc->center.y -= t->area.y1; + } + + lv_area_move(&t->area, -a.x1, -a.y1); + lv_area_move(&t->_real_area, -a.x1, -a.y1); + + lv_cache_entry_t * entry_cached = lv_cache_acquire_or_create(u->texture_cache, &data_to_find, u); + + lv_area_move(&t->area, a.x1, a.y1); + lv_area_move(&t->_real_area, a.x1, a.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); + unsigned int texture = data_cached->texture; + + lv_layer_t * dest_layer = t->target_layer; + + unsigned int target_texture = layer_get_texture(dest_layer); + LV_ASSERT(target_texture != 0); + int32_t targ_tex_w = lv_area_get_width(&dest_layer->buf_area); + int32_t targ_tex_h = lv_area_get_height(&dest_layer->buf_area); + + GL_CALL(glBindTexture(GL_TEXTURE_2D, target_texture)); + + unsigned int framebuffer = get_framebuffer(u); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0)); + + lv_opengles_viewport(0, 0, targ_tex_w, targ_tex_h); + lv_area_move(&t->clip_area, -dest_layer->buf_area.x1, -dest_layer->buf_area.y1); + lv_area_t render_area = t->_real_area; + lv_area_move(&render_area, -dest_layer->buf_area.x1, -dest_layer->buf_area.y1); + lv_opengles_render_texture(texture, &render_area, 0xff, targ_tex_w, targ_tex_h, &t->clip_area, true); + + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + + lv_cache_release(u->texture_cache, entry_cached, u); + + /*Do not cache non static (const) texts as the text's pointer can be freed/reallocated + *at any time resulting in a wild pointer in the cached draw dsc. */ + if(t->type == LV_DRAW_TASK_TYPE_LABEL) { + lv_draw_label_dsc_t * label_dsc = t->draw_dsc; + if(!label_dsc->text_static) { + lv_cache_drop(u->texture_cache, &data_to_find, u); + } + } +} + +static void execute_drawing(lv_draw_opengles_unit_t * u) +{ + lv_draw_task_t * t = u->task_act; + t->draw_unit = (lv_draw_unit_t *)u; + + 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) { + lv_layer_t * layer = t->target_layer; + lv_area_t fill_area = t->area; + lv_area_intersect(&fill_area, &fill_area, &t->clip_area); + lv_area_move(&fill_area, -layer->buf_area.x1, -layer->buf_area.y1); + + unsigned int target_texture = layer_get_texture(layer); + LV_ASSERT(target_texture != 0); + int32_t targ_tex_w = lv_area_get_width(&layer->buf_area); + int32_t targ_tex_h = lv_area_get_height(&layer->buf_area); + + unsigned int framebuffer = get_framebuffer(u); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0)); + + lv_opengles_viewport(0, 0, targ_tex_w, targ_tex_h); + lv_opengles_render_fill(fill_dsc->color, &fill_area, fill_dsc->opa, targ_tex_w, targ_tex_h); + + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + + return; + } + } + + if(t->type == LV_DRAW_TASK_TYPE_LAYER) { + blend_texture_layer(t); + return; + } + +#if LV_USE_3DTEXTURE + if(t->type == LV_DRAW_TASK_TYPE_3D) { + lv_draw_opengles_3d(t, t->draw_dsc, &t->area); + return; + } +#endif + + draw_from_cached_texture(t); +} + +static unsigned int layer_get_texture(lv_layer_t * layer) +{ + return (unsigned int)(uintptr_t)layer->user_data; +} + +static unsigned int get_framebuffer(lv_draw_opengles_unit_t * u) +{ + if(u->framebuffer == 0) { + GL_CALL(glGenFramebuffers(1, &u->framebuffer)); + } + return u->framebuffer; +} + +static unsigned int create_texture(int32_t w, int32_t h, const void * data) +{ + unsigned int texture; + + GL_CALL(glGenTextures(1, &texture)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, texture)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + 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_COLOR_DEPTH 32, 24, 16 are supported but the cached textures will always + * have full ARGB pixels since the alpha channel is required for blending. + */ + GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, data)); + + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 20); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + return texture; +} + +#if LV_USE_3DTEXTURE +static void lv_draw_opengles_3d(lv_draw_task_t * t, const lv_draw_3d_dsc_t * dsc, const lv_area_t * coords) +{ + lv_draw_opengles_unit_t * u = (lv_draw_opengles_unit_t *) t->draw_unit; + + lv_layer_t * dest_layer = t->target_layer; + unsigned int target_texture = layer_get_texture(dest_layer); + LV_ASSERT(target_texture != 0); + int32_t targ_tex_w = lv_area_get_width(&dest_layer->buf_area); + int32_t targ_tex_h = lv_area_get_height(&dest_layer->buf_area); + + GL_CALL(glBindTexture(GL_TEXTURE_2D, target_texture)); + + unsigned int framebuffer = get_framebuffer(u); + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)); + GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target_texture, 0)); + + lv_opengles_viewport(0, 0, targ_tex_w, targ_tex_h); + lv_area_t clip_area = t->clip_area; + lv_area_move(&clip_area, -dest_layer->buf_area.x1, -dest_layer->buf_area.y1); + + lv_opengles_render_texture(dsc->tex_id, coords, dsc->opa, targ_tex_w, targ_tex_h, &clip_area, true); + + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, 0)); +} +#endif /*LV_USE_3DTEXTURE*/ + +#endif /*LV_USE_DRAW_OPENGLES*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/opengles/lv_draw_opengles.h b/lib/libesp32_lvgl/lvgl/src/draw/opengles/lv_draw_opengles.h new file mode 100644 index 000000000..1285c93ec --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/opengles/lv_draw_opengles.h @@ -0,0 +1,45 @@ +/** + * @file lv_draw_opengles.h + * + */ + +#ifndef LV_DRAW_OPENGLES_H +#define LV_DRAW_OPENGLES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_DRAW_OPENGLES + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_draw_opengles_init(void); +void lv_draw_opengles_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_OPENGLES*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_OPENGLES_H*/ 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 039b147a7..fca89756d 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 @@ -9,6 +9,7 @@ #include "lv_draw_dave2d.h" #if LV_USE_DRAW_DAVE2D #include "../../lv_draw_buf_private.h" +#include "../../../misc/lv_area_private.h" /********************* * DEFINES @@ -79,6 +80,7 @@ void lv_draw_dave2d_init(void) lv_draw_dave2d_unit_t * draw_dave2d_unit = lv_draw_create_unit(sizeof(lv_draw_dave2d_unit_t)); draw_dave2d_unit->base_unit.dispatch_cb = lv_draw_dave2d_dispatch; draw_dave2d_unit->base_unit.evaluate_cb = _dave2d_evaluate; + draw_dave2d_unit->base_unit.name = "DAVE2D"; draw_dave2d_unit->idx = DRAW_UNIT_ID_DAVE2D; result = lv_dave2d_init(); @@ -97,7 +99,8 @@ void lv_draw_dave2d_init(void) 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); + lv_thread_init(&draw_dave2d_unit->thread, "dave2d", LV_DRAW_THREAD_PRIO, _dave2d_render_thread_cb, 8 * 1024, + draw_dave2d_unit); #endif } @@ -215,6 +218,11 @@ static int32_t _dave2d_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t) LV_UNUSED(u); int32_t ret = 0; + lv_draw_dsc_base_t * draw_dsc_base = (lv_draw_dsc_base_t *) t->draw_dsc; + + if(!lv_draw_dave2d_is_dest_cf_supported(draw_dsc_base->layer->color_format)) + return 0; + switch(t->type) { case LV_DRAW_TASK_TYPE_FILL: { #if USE_D2 @@ -242,6 +250,12 @@ static int32_t _dave2d_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t) } case LV_DRAW_TASK_TYPE_IMAGE: { + lv_draw_image_dsc_t * dsc = t->draw_dsc; + if((dsc->header.cf >= LV_COLOR_FORMAT_PROPRIETARY_START) || (dsc->header.cf == LV_COLOR_FORMAT_RGB888) || + (dsc->header.cf == LV_COLOR_FORMAT_RGB565A8)) { + ret = 0; + break; + } #if USE_D2 t->preferred_draw_unit_id = DRAW_UNIT_ID_DAVE2D; t->preference_score = 0; @@ -344,10 +358,10 @@ static int32_t lv_draw_dave2d_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * if(draw_dave2d_unit->task_act) return 0; lv_draw_task_t * t = NULL; - t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_DAVE2D); + t = lv_draw_get_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); + t = lv_draw_get_available_task(layer, NULL, DRAW_UNIT_ID_DAVE2D); } if(t == NULL) { @@ -360,6 +374,11 @@ static int32_t lv_draw_dave2d_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * return LV_DRAW_UNIT_IDLE; /*Couldn't start rendering*/ } + /* Return if target buffer format is not supported. */ + if(!lv_draw_dave2d_is_dest_cf_supported(layer->color_format)) { + return LV_DRAW_UNIT_IDLE; /*Couldn't start rendering*/ + } + void * buf = lv_draw_layer_alloc_buf(layer); if(buf == NULL) { return LV_DRAW_UNIT_IDLE; /*Couldn't start rendering*/ @@ -379,8 +398,6 @@ static int32_t lv_draw_dave2d_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * #endif t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; - draw_dave2d_unit->base_unit.target_layer = layer; - draw_dave2d_unit->base_unit.clip_area = &t->clip_area; draw_dave2d_unit->task_act = t; #if LV_USE_OS @@ -431,17 +448,20 @@ static void execute_drawing(lv_draw_dave2d_unit_t * u) /*Render the draw task*/ lv_draw_task_t * t = u->task_act; + /* remember draw unit for access to unit's context */ + t->draw_unit = (lv_draw_unit_t *)u; + #if defined(RENESAS_CORTEX_M85) #if (BSP_CFG_DCACHE_ENABLED) - lv_layer_t * layer = u->base_unit.target_layer; + lv_layer_t * layer = t->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, &t->clip_area); - x = 0 - u->base_unit.target_layer->buf_area.x1; - y = 0 - u->base_unit.target_layer->buf_area.y1; + x = 0 - t->target_layer->buf_area.x1; + y = 0 - t->target_layer->buf_area.y1; lv_area_move(&clipped_area, x, y); @@ -452,39 +472,39 @@ static void execute_drawing(lv_draw_dave2d_unit_t * u) switch(t->type) { case LV_DRAW_TASK_TYPE_FILL: - lv_draw_dave2d_fill(u, t->draw_dsc, &t->area); + lv_draw_dave2d_fill(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_BORDER: - lv_draw_dave2d_border(u, t->draw_dsc, &t->area); + lv_draw_dave2d_border(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_BOX_SHADOW: - //lv_draw_dave2d_box_shadow(u, t->draw_dsc, &t->area); + //lv_draw_dave2d_box_shadow(t, t->draw_dsc, &t->area); break; #if 0 case LV_DRAW_TASK_TYPE_BG_IMG: - //lv_draw_dave2d_bg_image(u, t->draw_dsc, &t->area); + //lv_draw_dave2d_bg_image(t, t->draw_dsc, &t->area); break; #endif case LV_DRAW_TASK_TYPE_LABEL: - lv_draw_dave2d_label(u, t->draw_dsc, &t->area); + lv_draw_dave2d_label(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_IMAGE: - lv_draw_dave2d_image(u, t->draw_dsc, &t->area); + lv_draw_dave2d_image(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_LINE: - lv_draw_dave2d_line(u, t->draw_dsc); + lv_draw_dave2d_line(t, t->draw_dsc); break; case LV_DRAW_TASK_TYPE_ARC: - lv_draw_dave2d_arc(u, t->draw_dsc, &t->area); + lv_draw_dave2d_arc(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_TRIANGLE: - lv_draw_dave2d_triangle(u, t->draw_dsc); + lv_draw_dave2d_triangle(t, t->draw_dsc); break; case LV_DRAW_TASK_TYPE_LAYER: - //lv_draw_dave2d_layer(u, t->draw_dsc, &t->area); + //lv_draw_dave2d_layer(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_MASK_RECTANGLE: - //lv_draw_dave2d_mask_rect(u, t->draw_dsc, &t->area); + //lv_draw_dave2d_mask_rect(t, t->draw_dsc, &t->area); break; default: break; 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 186f57a75..6f29b70be 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 @@ -16,8 +16,18 @@ extern "C" { #include "../../../lv_conf_internal.h" #if LV_USE_DRAW_DAVE2D #include "../../lv_draw.h" +#include "../../lv_draw_private.h" #include "hal_data.h" #include "lv_draw_dave2d_utils.h" +#include "../../lv_draw_rect.h" +#include "../../lv_draw_line.h" +#include "../../lv_draw_arc.h" +#include "../../lv_draw_label.h" +#include "../../lv_draw_image.h" +#include "../../lv_draw_triangle.h" +#include "../../lv_draw_buf.h" + + /********************* * DEFINES @@ -50,32 +60,32 @@ typedef struct { void lv_draw_dave2d_init(void); -void lv_draw_dave2d_image(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, +void lv_draw_dave2d_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords); -void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords); +void lv_draw_dave2d_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords); -void lv_draw_dave2d_border(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc, +void lv_draw_dave2d_border(lv_draw_task_t * t, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords); -void lv_draw_dave2d_box_shadow(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_box_shadow_dsc_t * dsc, +void lv_draw_dave2d_box_shadow(lv_draw_task_t * t, const lv_draw_box_shadow_dsc_t * dsc, const lv_area_t * coords); -void lv_draw_dave2d_label(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords); +void lv_draw_dave2d_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords); -void lv_draw_dave2d_arc(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords); +void lv_draw_dave2d_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords); -void lv_draw_dave2d_line(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc); +void lv_draw_dave2d_line(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc); -void lv_draw_dave2d_layer(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, +void lv_draw_dave2d_layer(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords); -void lv_draw_dave2d_triangle(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc); +void lv_draw_dave2d_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc); -void lv_draw_dave2d_mask_rect(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_mask_rect_dsc_t * dsc, +void lv_draw_dave2d_mask_rect(lv_draw_task_t * t, const lv_draw_mask_rect_dsc_t * dsc, const lv_area_t * coords); -void lv_draw_dave2d_transform(lv_draw_dave2d_unit_t * draw_unit, const lv_area_t * dest_area, const void * src_buf, +void lv_draw_dave2d_transform(lv_draw_task_t * t, const lv_area_t * dest_area, const void * src_buf, int32_t src_w, int32_t src_h, int32_t src_stride, const lv_draw_image_dsc_t * draw_dsc, const lv_draw_image_sup_t * sup, lv_color_format_t cf, void * dest_buf); 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 03775387a..42a7c27d2 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 @@ -1,7 +1,9 @@ #include "lv_draw_dave2d.h" #if LV_USE_DRAW_DAVE2D -void lv_draw_dave2d_arc(lv_draw_dave2d_unit_t * u, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords) +#include "../../../misc/lv_area_private.h" + +void lv_draw_dave2d_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords) { uint32_t flags = 0; @@ -15,13 +17,14 @@ void lv_draw_dave2d_arc(lv_draw_dave2d_unit_t * u, const lv_draw_arc_dsc_t * dsc lv_point_t arc_centre; int32_t x; int32_t y; + lv_draw_dave2d_unit_t * u = (lv_draw_dave2d_unit_t *)t->draw_unit; - if(!lv_area_intersect(&clipped_area, coords, u->base_unit.clip_area)) return; + if(!lv_area_intersect(&clipped_area, coords, &t->clip_area)) return; - x = 0 - u->base_unit.target_layer->buf_area.x1; - y = 0 - u->base_unit.target_layer->buf_area.y1; + x = 0 - t->target_layer->buf_area.x1; + y = 0 - t->target_layer->buf_area.y1; - buffer_area = u->base_unit.target_layer->buf_area; + buffer_area = t->target_layer->buf_area; arc_centre = dsc->center; arc_centre.x = arc_centre.x - buffer_area.x1; @@ -50,7 +53,7 @@ void lv_draw_dave2d_arc(lv_draw_dave2d_unit_t * u, const lv_draw_arc_dsc_t * dsc // // Generate render operations // - d2_framebuffer_from_layer(u->d2_handle, u->base_unit.target_layer); + d2_framebuffer_from_layer(u->d2_handle, t->target_layer); d2_setalpha(u->d2_handle, dsc->opa); 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 6033251df..8298c2a9a 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 @@ -1,15 +1,17 @@ #include "lv_draw_dave2d.h" #if LV_USE_DRAW_DAVE2D -static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * draw_unit, const lv_area_t * outer_area, +#include "../../../misc/lv_area_private.h" + +static void dave2d_draw_border_complex(lv_draw_task_t * t, const lv_area_t * outer_area, const lv_area_t * inner_area, int32_t rout, int32_t rin, lv_color_t color, lv_opa_t opa); -static void dave2d_draw_border_simple(lv_draw_dave2d_unit_t * draw_unit, const lv_area_t * outer_area, +static void dave2d_draw_border_simple(lv_draw_task_t * t, const lv_area_t * outer_area, const lv_area_t * inner_area, lv_color_t color, lv_opa_t opa); -void lv_draw_dave2d_border(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc, +void lv_draw_dave2d_border(lv_draw_task_t * t, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords) { if(dsc->opa <= LV_OPA_MIN) return; @@ -34,15 +36,15 @@ void lv_draw_dave2d_border(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_bord if(rin < 0) rin = 0; if(rout == 0 && rin == 0) { - dave2d_draw_border_simple(draw_unit, coords, &area_inner, dsc->color, dsc->opa); + dave2d_draw_border_simple(t, coords, &area_inner, dsc->color, dsc->opa); } else { - dave2d_draw_border_complex(draw_unit, coords, &area_inner, rout, rin, dsc->color, dsc->opa); + dave2d_draw_border_complex(t, coords, &area_inner, rout, rin, dsc->color, dsc->opa); } } -static void dave2d_draw_border_simple(lv_draw_dave2d_unit_t * u, const lv_area_t * outer_area, +static void dave2d_draw_border_simple(lv_draw_task_t * t, const lv_area_t * outer_area, const lv_area_t * inner_area, lv_color_t color, lv_opa_t opa) @@ -55,9 +57,11 @@ 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, &t->clip_area); if(!is_common) return; + lv_draw_dave2d_unit_t * u = (lv_draw_dave2d_unit_t *)t->draw_unit; + #if LV_USE_OS lv_result_t status; status = lv_mutex_lock(u->pd2Mutex); @@ -67,8 +71,8 @@ static void dave2d_draw_border_simple(lv_draw_dave2d_unit_t * u, const lv_area_t local_outer_area = *outer_area; local_inner_area = *inner_area; - x = 0 - u->base_unit.target_layer->buf_area.x1; - y = 0 - u->base_unit.target_layer->buf_area.y1; + x = 0 - t->target_layer->buf_area.x1; + y = 0 - t->target_layer->buf_area.y1; lv_area_move(&clip_area, x, y); lv_area_move(&local_outer_area, x, y); @@ -81,7 +85,7 @@ static void dave2d_draw_border_simple(lv_draw_dave2d_unit_t * u, const lv_area_t // Generate render operations // - d2_framebuffer_from_layer(u->d2_handle, u->base_unit.target_layer); + d2_framebuffer_from_layer(u->d2_handle, t->target_layer); d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(color)); d2_setalpha(u->d2_handle, opa); @@ -153,7 +157,7 @@ static void dave2d_draw_border_simple(lv_draw_dave2d_unit_t * u, const lv_area_t #endif } -static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * u, const lv_area_t * orig_outer_area, +static void dave2d_draw_border_complex(lv_draw_task_t * t, const lv_area_t * orig_outer_area, const lv_area_t * orig_inner_area, int32_t rout, int32_t rin, lv_color_t color, lv_opa_t opa) { @@ -169,8 +173,9 @@ 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; + lv_draw_dave2d_unit_t * u = (lv_draw_dave2d_unit_t *)t->draw_unit; - if(!lv_area_intersect(&draw_area, &outer_area, u->base_unit.clip_area)) return; + if(!lv_area_intersect(&draw_area, &outer_area, &t->clip_area)) return; #if LV_USE_OS lv_result_t status; @@ -178,8 +183,8 @@ static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * u, const lv_area_ LV_ASSERT(LV_RESULT_OK == status); #endif - x = 0 - u->base_unit.target_layer->buf_area.x1; - y = 0 - u->base_unit.target_layer->buf_area.y1; + x = 0 - t->target_layer->buf_area.x1; + y = 0 - t->target_layer->buf_area.y1; lv_area_move(&draw_area, x, y); lv_area_move(&outer_area, x, y); @@ -192,7 +197,7 @@ static void dave2d_draw_border_complex(lv_draw_dave2d_unit_t * u, const lv_area_ // Generate render operations // - d2_framebuffer_from_layer(u->d2_handle, u->base_unit.target_layer); + d2_framebuffer_from_layer(u->d2_handle, t->target_layer); d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(color)); d2_setalpha(u->d2_handle, opa); 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 e2ffcd9fe..8a0eec2a8 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 @@ -1,7 +1,9 @@ #include "lv_draw_dave2d.h" #if LV_USE_DRAW_DAVE2D -void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords) +#include "../../../misc/lv_area_private.h" + +void lv_draw_dave2d_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords) { lv_area_t draw_area; lv_area_t coordinates; @@ -13,8 +15,9 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d d2_u32 flags = 0; lv_point_t arc_centre; + lv_draw_dave2d_unit_t * u = (lv_draw_dave2d_unit_t *)t->draw_unit; - is_common = lv_area_intersect(&draw_area, coords, u->base_unit.clip_area); + is_common = lv_area_intersect(&draw_area, coords, &t->clip_area); if(!is_common) return; #if LV_USE_OS @@ -25,8 +28,8 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d lv_area_copy(&coordinates, coords); - x = 0 - u->base_unit.target_layer->buf_area.x1; - y = 0 - u->base_unit.target_layer->buf_area.y1; + x = 0 - t->target_layer->buf_area.x1; + y = 0 - t->target_layer->buf_area.y1; lv_area_move(&draw_area, x, y); lv_area_move(&coordinates, x, y); @@ -38,7 +41,7 @@ void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * d d2_selectrenderbuffer(u->d2_handle, u->renderbuffer); #endif - d2_framebuffer_from_layer(u->d2_handle, u->base_unit.target_layer); + d2_framebuffer_from_layer(u->d2_handle, t->target_layer); if(LV_GRAD_DIR_NONE != dsc->grad.dir) { float a1; 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 dc001151a..af7892e06 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 @@ -9,6 +9,9 @@ #include "lv_draw_dave2d.h" #if LV_USE_DRAW_DAVE2D +#include "../../lv_image_decoder_private.h" +#include "../../lv_draw_image_private.h" + /********************* * DEFINES *********************/ @@ -20,7 +23,7 @@ /********************** * STATIC PROTOTYPES **********************/ -static void img_draw_core(lv_draw_unit_t * u_base, const lv_draw_image_dsc_t * draw_dsc, +static void img_draw_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, const lv_area_t * img_coords, const lv_area_t * clipped_img_area); @@ -36,14 +39,14 @@ static void img_draw_core(lv_draw_unit_t * u_base, const lv_draw_image_dsc_t * d * GLOBAL FUNCTIONS **********************/ -void lv_draw_dave2d_image(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, +void lv_draw_dave2d_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, 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(t, 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(t, draw_dsc, coords, img_draw_core); } } @@ -51,12 +54,12 @@ void lv_draw_dave2d_image(lv_draw_dave2d_unit_t * draw_unit, const lv_draw_image * STATIC FUNCTIONS **********************/ -static void img_draw_core(lv_draw_unit_t * u_base, const lv_draw_image_dsc_t * draw_dsc, +static void img_draw_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, const lv_area_t * img_coords, const lv_area_t * clipped_img_area) { - lv_draw_dave2d_unit_t * u = (lv_draw_dave2d_unit_t *)u_base; + lv_draw_dave2d_unit_t * u = (lv_draw_dave2d_unit_t *)t->draw_unit; (void)sup; //remove warning about unused parameter @@ -88,12 +91,12 @@ static void img_draw_core(lv_draw_unit_t * u_base, const lv_draw_image_dsc_t * d LV_ASSERT(LV_RESULT_OK == status); #endif - buffer_area = u->base_unit.target_layer->buf_area; + buffer_area = t->target_layer->buf_area; draw_area = *img_coords; clipped_area = *clipped_img_area; - x = 0 - u->base_unit.target_layer->buf_area.x1; - y = 0 - u->base_unit.target_layer->buf_area.y1; + x = 0 - t->target_layer->buf_area.x1; + y = 0 - t->target_layer->buf_area.y1; lv_area_move(&draw_area, x, y); lv_area_move(&buffer_area, x, y); @@ -200,7 +203,7 @@ static void img_draw_core(lv_draw_unit_t * u_base, const lv_draw_image_dsc_t * d } - d2_framebuffer_from_layer(u->d2_handle, u->base_unit.target_layer); + d2_framebuffer_from_layer(u->d2_handle, t->target_layer); 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); 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 f5760e623..f16b08b23 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 @@ -1,22 +1,23 @@ #include "lv_draw_dave2d.h" #if LV_USE_DRAW_DAVE2D -static void lv_draw_dave2d_draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc, +#include "../../lv_draw_label_private.h" +#include "../../../misc/lv_area_private.h" + +static void lv_draw_dave2d_draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area); static lv_draw_dave2d_unit_t * unit = NULL; -void lv_draw_dave2d_label(lv_draw_dave2d_unit_t * u, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_dave2d_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords) { if(dsc->opa <= LV_OPA_MIN) return; - unit = u; - - lv_draw_label_iterate_characters(&u->base_unit, dsc, coords, lv_draw_dave2d_draw_letter_cb); + lv_draw_label_iterate_characters(t, dsc, coords, lv_draw_dave2d_draw_letter_cb); } -static void lv_draw_dave2d_draw_letter_cb(lv_draw_unit_t * u, lv_draw_glyph_dsc_t * glyph_draw_dsc, +static void lv_draw_dave2d_draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area) { @@ -28,13 +29,14 @@ static void lv_draw_dave2d_draw_letter_cb(lv_draw_unit_t * u, lv_draw_glyph_dsc_ int32_t y; letter_coords = *glyph_draw_dsc->letter_coords; + lv_draw_dave2d_unit_t * unit = (lv_draw_dave2d_unit_t *)t->draw_unit; 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, &t->clip_area); if(!is_common) return; - x = 0 - unit->base_unit.target_layer->buf_area.x1; - y = 0 - unit->base_unit.target_layer->buf_area.y1; + x = 0 - t->target_layer->buf_area.x1; + y = 0 - t->target_layer->buf_area.y1; lv_area_move(&clip_area, x, y); lv_area_move(&letter_coords, x, y); @@ -53,7 +55,7 @@ static void lv_draw_dave2d_draw_letter_cb(lv_draw_unit_t * u, lv_draw_glyph_dsc_ // Generate render operations // - d2_framebuffer_from_layer(unit->d2_handle, unit->base_unit.target_layer); + d2_framebuffer_from_layer(unit->d2_handle, t->target_layer); current_fillmode = d2_getfillmode(unit->d2_handle); @@ -71,11 +73,12 @@ static void lv_draw_dave2d_draw_letter_cb(lv_draw_unit_t * u, lv_draw_glyph_dsc_ border_draw_dsc.color = glyph_draw_dsc->color; border_draw_dsc.width = 1; //lv_draw_sw_border(u, &border_draw_dsc, glyph_draw_dsc->bg_coords); - lv_draw_dave2d_border(unit, &border_draw_dsc, glyph_draw_dsc->bg_coords); + lv_draw_dave2d_border(t, &border_draw_dsc, glyph_draw_dsc->bg_coords); #endif } break; case LV_FONT_GLYPH_FORMAT_A1 ... LV_FONT_GLYPH_FORMAT_A8: { + glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); lv_area_t mask_area = letter_coords; mask_area.x2 = mask_area.x1 + lv_draw_buf_width_to_stride(lv_area_get_width(&mask_area), LV_COLOR_FORMAT_A8) - 1; // lv_draw_sw_blend_dsc_t blend_dsc; @@ -122,6 +125,7 @@ static void lv_draw_dave2d_draw_letter_cb(lv_draw_unit_t * u, lv_draw_glyph_dsc_ break; case LV_FONT_GLYPH_FORMAT_IMAGE: { #if LV_USE_IMGFONT + glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); lv_draw_image_dsc_t img_dsc; lv_draw_image_dsc_init(&img_dsc); img_dsc.rotation = 0; @@ -129,7 +133,7 @@ static void lv_draw_dave2d_draw_letter_cb(lv_draw_unit_t * u, lv_draw_glyph_dsc_ img_dsc.scale_y = LV_SCALE_NONE; img_dsc.opa = glyph_draw_dsc->opa; img_dsc.src = glyph_draw_dsc->glyph_data; - //lv_draw_sw_image(draw_unit, &img_dsc, glyph_draw_dsc->letter_coords); + //lv_draw_sw_image(t, &img_dsc, glyph_draw_dsc->letter_coords); #endif } break; @@ -148,7 +152,7 @@ static void lv_draw_dave2d_draw_letter_cb(lv_draw_unit_t * u, lv_draw_glyph_dsc_ if(fill_draw_dsc && fill_area) { //lv_draw_sw_fill(u, fill_draw_dsc, fill_area); - lv_draw_dave2d_fill(unit, fill_draw_dsc, fill_area); + lv_draw_dave2d_fill(t, fill_draw_dsc, fill_area); } #if LV_USE_OS 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 ef188eb4a..b6e7008df 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 @@ -1,7 +1,9 @@ #include "lv_draw_dave2d.h" #if LV_USE_DRAW_DAVE2D -void lv_draw_dave2d_line(lv_draw_dave2d_unit_t * u, const lv_draw_line_dsc_t * dsc) +#include "../../../misc/lv_area_private.h" + +void lv_draw_dave2d_line(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc) { lv_area_t clip_line; @@ -13,6 +15,7 @@ void lv_draw_dave2d_line(lv_draw_dave2d_unit_t * u, const lv_draw_line_dsc_t * d lv_value_precise_t p2_y; int32_t x; int32_t y; + lv_draw_dave2d_unit_t * u = (lv_draw_dave2d_unit_t *)t->draw_unit; clip_line.x1 = LV_MIN(dsc->p1.x, dsc->p2.x) - dsc->width / 2; clip_line.x2 = LV_MAX(dsc->p1.x, dsc->p2.x) + dsc->width / 2; @@ -20,7 +23,7 @@ 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, &t->clip_area); if(!is_common) return; #if LV_USE_OS @@ -29,14 +32,14 @@ void lv_draw_dave2d_line(lv_draw_dave2d_unit_t * u, const lv_draw_line_dsc_t * d LV_ASSERT(LV_RESULT_OK == status); #endif - buffer_area = u->base_unit.target_layer->buf_area; + buffer_area = t->target_layer->buf_area; p1_x = dsc->p1.x - buffer_area.x1; p1_y = dsc->p1.y - buffer_area.y1; p2_x = dsc->p2.x - buffer_area.x1; p2_y = dsc->p2.y - buffer_area.y1; - x = 0 - u->base_unit.target_layer->buf_area.x1; - y = 0 - u->base_unit.target_layer->buf_area.y1; + x = 0 - t->target_layer->buf_area.x1; + y = 0 - t->target_layer->buf_area.y1; lv_area_move(&clip_line, x, y); lv_area_move(&buffer_area, x, y); @@ -54,7 +57,7 @@ void lv_draw_dave2d_line(lv_draw_dave2d_unit_t * u, const lv_draw_line_dsc_t * d // // Generate render operations // - d2_framebuffer_from_layer(u->d2_handle, u->base_unit.target_layer); + d2_framebuffer_from_layer(u->d2_handle, t->target_layer); d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->color)); 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 fe94a9a40..ea880509d 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 @@ -1,17 +1,22 @@ #include "lv_draw_dave2d.h" #if LV_USE_DRAW_DAVE2D -void lv_draw_dave2d_mask_rect(lv_draw_dave2d_unit_t * u, const lv_draw_mask_rect_dsc_t * dsc, const lv_area_t * coords) +#include "../../../misc/lv_area_private.h" + +void lv_draw_dave2d_mask_rect(lv_draw_task_t * t, const lv_draw_mask_rect_dsc_t * dsc, + const lv_area_t * coords) { lv_area_t clipped_area; lv_area_t coordinates; int32_t x; int32_t y; - if(!lv_area_intersect(&clipped_area, coords, u->base_unit.clip_area)) return; + lv_draw_dave2d_unit_t * u = (lv_draw_dave2d_unit_t *)t->draw_unit; - x = 0 - u->base_unit.target_layer->buf_area.x1; - y = 0 - u->base_unit.target_layer->buf_area.y1; + if(!lv_area_intersect(&clipped_area, coords, &t->clip_area)) return; + + x = 0 - t->target_layer->buf_area.x1; + y = 0 - t->target_layer->buf_area.y1; coordinates = *coords; @@ -28,7 +33,7 @@ void lv_draw_dave2d_mask_rect(lv_draw_dave2d_unit_t * u, const lv_draw_mask_rect d2_selectrenderbuffer(u->d2_handle, u->renderbuffer); #endif - d2_framebuffer_from_layer(u->d2_handle, u->base_unit.target_layer); + d2_framebuffer_from_layer(u->d2_handle, t->target_layer); 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); 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 502200797..74fd5095a 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 @@ -1,13 +1,16 @@ #include "lv_draw_dave2d.h" #if LV_USE_DRAW_DAVE2D -void lv_draw_dave2d_triangle(lv_draw_dave2d_unit_t * u, const lv_draw_triangle_dsc_t * dsc) +#include "../../../misc/lv_area_private.h" + +void lv_draw_dave2d_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc) { lv_area_t clipped_area; d2_u32 flags = 0; d2_u8 current_alpha_mode = 0; int32_t x; int32_t y; + lv_draw_dave2d_unit_t * u = (lv_draw_dave2d_unit_t *)t->draw_unit; lv_area_t tri_area; tri_area.x1 = LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); @@ -15,7 +18,7 @@ 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, &t->clip_area)) return; #if LV_USE_OS lv_result_t status; @@ -23,8 +26,8 @@ void lv_draw_dave2d_triangle(lv_draw_dave2d_unit_t * u, const lv_draw_triangle_d LV_ASSERT(LV_RESULT_OK == status); #endif - x = 0 - u->base_unit.target_layer->buf_area.x1; - y = 0 - u->base_unit.target_layer->buf_area.y1; + x = 0 - t->target_layer->buf_area.x1; + y = 0 - t->target_layer->buf_area.y1; lv_area_move(&clipped_area, x, y); @@ -76,20 +79,20 @@ void lv_draw_dave2d_triangle(lv_draw_dave2d_unit_t * u, const lv_draw_triangle_d } } - p[0].x -= u->base_unit.target_layer->buf_area.x1; - p[1].x -= u->base_unit.target_layer->buf_area.x1; - p[2].x -= u->base_unit.target_layer->buf_area.x1; + p[0].x -= t->target_layer->buf_area.x1; + p[1].x -= t->target_layer->buf_area.x1; + p[2].x -= t->target_layer->buf_area.x1; - p[0].y -= u->base_unit.target_layer->buf_area.y1; - p[1].y -= u->base_unit.target_layer->buf_area.y1; - p[2].y -= u->base_unit.target_layer->buf_area.y1; + p[0].y -= t->target_layer->buf_area.y1; + p[1].y -= t->target_layer->buf_area.y1; + p[2].y -= t->target_layer->buf_area.y1; p[1].y -= 1; p[2].y -= 1; current_alpha_mode = d2_getalphamode(u->d2_handle); - if(LV_GRAD_DIR_NONE != dsc->bg_grad.dir) { + if(LV_GRAD_DIR_NONE != dsc->grad.dir) { float a1; float a2; @@ -101,9 +104,9 @@ void lv_draw_dave2d_triangle(lv_draw_dave2d_unit_t * u, const lv_draw_triangle_d int32_t y0_i ; int32_t y3_i ; - if(LV_GRAD_DIR_VER == dsc->bg_grad.dir) { - a1 = dsc->bg_grad.stops[0].opa; - a2 = dsc->bg_grad.stops[dsc->bg_grad.stops_count - 1].opa; + if(LV_GRAD_DIR_VER == dsc->grad.dir) { + a1 = dsc->grad.stops[0].opa; + a2 = dsc->grad.stops[dsc->grad.stops_count - 1].opa; y1 = LV_MIN3(p[0].y, p[1].y, p[2].y); y2 = LV_MAX3(p[0].y, p[1].y, p[2].y); @@ -125,22 +128,22 @@ void lv_draw_dave2d_triangle(lv_draw_dave2d_unit_t * u, const lv_draw_triangle_d d2_setalphagradient(u->d2_handle, 0, D2_FIX4(0), D2_FIX4(y0_i), D2_FIX4(0), D2_FIX4((y3_i - y0_i))); } - else if(LV_GRAD_DIR_HOR == dsc->bg_grad.dir) { + else if(LV_GRAD_DIR_HOR == dsc->grad.dir) { /* TODO */ LV_ASSERT(0); } - d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->bg_grad.stops[0].color)); + d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->grad.stops[0].color)); d2_setalphamode(u->d2_handle, d2_am_gradient1); } else { - d2_setalpha(u->d2_handle, dsc->bg_opa); + d2_setalpha(u->d2_handle, dsc->opa); d2_setalphamode(u->d2_handle, d2_am_constant); - d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->bg_color)); + d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->color)); } - d2_framebuffer_from_layer(u->d2_handle, u->base_unit.target_layer); + d2_framebuffer_from_layer(u->d2_handle, t->target_layer); 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); 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 98fb80609..666a5c416 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 @@ -75,7 +75,7 @@ d2_s32 lv_draw_dave2d_cf_fb_get(void) d2_fb_mode = d2_mode_argb8888; break; case DISPLAY_IN_FORMAT_32BITS_RGB888: ///< RGB888, 32 bits - d2_fb_mode = d2_mode_rgb888; + d2_fb_mode = d2_mode_argb8888; //GLCDC ignores Alpha when configured for RGB888 break; case DISPLAY_IN_FORMAT_16BITS_ARGB4444: ///< ARGB4444, 16 bits d2_fb_mode = d2_mode_argb4444; @@ -99,19 +99,38 @@ d2_u32 lv_draw_dave2d_lv_colour_fmt_to_d2_fmt(lv_color_format_t colour_format) d2_u32 d2_lvgl_mode = 0; switch(colour_format) { + case(LV_COLOR_FORMAT_I1): + d2_lvgl_mode = d2_mode_i1; + break; + case(LV_COLOR_FORMAT_I2): + d2_lvgl_mode = d2_mode_i2; + break; + case(LV_COLOR_FORMAT_I4): + d2_lvgl_mode = d2_mode_i4; + break; + case(LV_COLOR_FORMAT_I8): + d2_lvgl_mode = d2_mode_i8; + break; case(LV_COLOR_FORMAT_A8): - d2_lvgl_mode = d2_mode_alpha8; //? + d2_lvgl_mode = d2_mode_alpha8; break; case(LV_COLOR_FORMAT_RGB565): d2_lvgl_mode = d2_mode_rgb565; break; - case(LV_COLOR_FORMAT_RGB888): - d2_lvgl_mode = d2_mode_argb8888; //? + case(LV_COLOR_FORMAT_ARGB1555): + d2_lvgl_mode = d2_mode_argb1555; + break; + case(LV_COLOR_FORMAT_ARGB4444): + d2_lvgl_mode = d2_mode_argb4444; break; case(LV_COLOR_FORMAT_ARGB8888): d2_lvgl_mode = d2_mode_argb8888; break; + case(LV_COLOR_FORMAT_XRGB8888): + d2_lvgl_mode = d2_mode_argb8888; + break; + case(LV_COLOR_FORMAT_RGB888): //LV_COLOR_FORMAT_RGB888 is a 3 byte format, d2_mode_rgb888 is a 4 byte format, not supported default: LV_ASSERT(0); break; @@ -133,6 +152,27 @@ void d2_framebuffer_from_layer(d2_device * handle, lv_layer_t * layer) lv_draw_dave2d_lv_colour_fmt_to_d2_fmt(layer->color_format)); } +bool lv_draw_dave2d_is_dest_cf_supported(lv_color_format_t cf) +{ + bool result; + + switch(cf) { + case LV_COLOR_FORMAT_A8: + case LV_COLOR_FORMAT_RGB565: + case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_XRGB8888: + case LV_COLOR_FORMAT_ARGB4444: + result = true; + break; + + default: + result = false; + break; + } + + return result; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_utils.h b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_utils.h index 67c510267..db9a17817 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_utils.h +++ b/lib/libesp32_lvgl/lvgl/src/draw/renesas/dave2d/lv_draw_dave2d_utils.h @@ -34,6 +34,8 @@ d2_u32 lv_draw_dave2d_lv_colour_fmt_to_d2_fmt(lv_color_format_t colour_format); void d2_framebuffer_from_layer(d2_device * handle, lv_layer_t * layer); +bool lv_draw_dave2d_is_dest_cf_supported(lv_color_format_t cf); + /********************** * MACROS **********************/ 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 c155ac114..4b7d3dd77 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 @@ -25,6 +25,14 @@ /********************** * TYPEDEFS **********************/ + +typedef struct { + lv_draw_unit_t base_unit; + lv_draw_task_t * task_act; + lv_cache_t * texture_cache; + lv_draw_buf_t render_draw_buf; +} lv_draw_sdl_unit_t; + typedef struct { lv_draw_dsc_base_t * draw_dsc; int32_t w; @@ -45,7 +53,6 @@ static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * cache_data); /********************** * GLOBAL PROTOTYPES **********************/ -static uint8_t sdl_render_buf[2048 * 1024 * 4]; /********************** * STATIC VARIABLES @@ -111,6 +118,7 @@ void lv_draw_sdl_init(void) lv_draw_sdl_unit_t * draw_sdl_unit = lv_draw_create_unit(sizeof(lv_draw_sdl_unit_t)); draw_sdl_unit->base_unit.dispatch_cb = dispatch; draw_sdl_unit->base_unit.evaluate_cb = evaluate; + draw_sdl_unit->base_unit.name = "SDL"; draw_sdl_unit->texture_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(cache_data_t), 128, (lv_cache_ops_t) { .compare_cb = (lv_cache_compare_cb_t)sdl_texture_cache_compare_cb, @@ -118,6 +126,8 @@ void lv_draw_sdl_init(void) .free_cb = (lv_cache_free_cb_t)sdl_texture_cache_free_cb, }); lv_cache_set_name(draw_sdl_unit->texture_cache, "SDL_TEXTURE"); + + lv_draw_buf_init(&draw_sdl_unit->render_draw_buf, 0, 0, LV_COLOR_FORMAT_ARGB8888, LV_STRIDE_AUTO, NULL, 0); } /********************** @@ -132,7 +142,7 @@ static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) if(draw_sdl_unit->task_act) return 0; lv_draw_task_t * t = NULL; - t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_SDL); + t = lv_draw_get_available_task(layer, NULL, DRAW_UNIT_ID_SDL); if(t == NULL) return -1; lv_display_t * disp = lv_refr_get_disp_refreshing(); @@ -149,8 +159,6 @@ static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) } t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; - draw_sdl_unit->base_unit.target_layer = layer; - draw_sdl_unit->base_unit.clip_area = &t->clip_area; draw_sdl_unit->task_act = t; execute_drawing(draw_sdl_unit); @@ -167,6 +175,15 @@ static int32_t evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task) { LV_UNUSED(draw_unit); + if(task->type == LV_DRAW_TASK_TYPE_IMAGE && + ((lv_draw_image_dsc_t *)task->draw_dsc)->header.cf >= LV_COLOR_FORMAT_PROPRIETARY_START) { + return 0; + } + + /*If not refreshing the display probably it's a canvas rendering + *which his not support in SDL as it's not a texture.*/ + if(lv_refr_get_disp_refreshing() == NULL) return 0; + if(((lv_draw_dsc_base_t *)task->draw_dsc)->user_data == NULL) { task->preference_score = 0; task->preferred_draw_unit_id = DRAW_UNIT_ID_SDL; @@ -179,21 +196,30 @@ 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)); + lv_layer_init(&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, 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; + if(!lv_draw_buf_reshape(&u->render_draw_buf, LV_COLOR_FORMAT_ARGB8888, texture_w, texture_h, LV_STRIDE_AUTO)) { + uint8_t * data = u->render_draw_buf.unaligned_data; + uint32_t data_size = LV_DRAW_BUF_SIZE(texture_w, texture_h, LV_COLOR_FORMAT_ARGB8888); + if(data == NULL) data = malloc(data_size); + else data = realloc(data, data_size); + LV_ASSERT_MALLOC(data); + lv_result_t init_result = lv_draw_buf_init(&u->render_draw_buf, texture_w, texture_h, LV_COLOR_FORMAT_ARGB8888, + LV_STRIDE_AUTO, data, data_size); + LV_ASSERT(init_result == LV_RESULT_OK); + } + + + dest_layer.draw_buf = &u->render_draw_buf; + dest_layer.color_format = LV_COLOR_FORMAT_ARGB8888; 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_memzero(u->render_draw_buf.data, lv_area_get_size(&task->_real_area) * 4); lv_display_t * disp = lv_refr_get_disp_refreshing(); @@ -297,7 +323,7 @@ static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * cache_data) 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); + SDL_UpdateTexture(texture, NULL, u->render_draw_buf.data, texture_w * 4); lv_draw_dsc_base_t * base_dsc = task->draw_dsc; @@ -308,24 +334,23 @@ static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * cache_data) cache_data->texture = texture; if(obj) { - lv_obj_update_flag(obj, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS, original_send_draw_task_event); + lv_obj_set_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) +static void blend_texture_layer(lv_draw_task_t * t) { lv_display_t * disp = lv_refr_get_disp_refreshing(); SDL_Renderer * renderer = lv_sdl_window_get_renderer(disp); SDL_Rect clip_rect; - clip_rect.x = u->base_unit.clip_area->x1; - clip_rect.y = u->base_unit.clip_area->y1; - clip_rect.w = lv_area_get_width(u->base_unit.clip_area); - clip_rect.h = lv_area_get_height(u->base_unit.clip_area); + clip_rect.x = t->clip_area.x1; + clip_rect.y = t->clip_area.y1; + clip_rect.w = lv_area_get_width(&t->clip_area); + clip_rect.h = lv_area_get_height(&t->clip_area); - lv_draw_task_t * t = u->task_act; 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; @@ -343,12 +368,11 @@ static void blend_texture_layer(lv_draw_sdl_unit_t * u) SDL_SetTextureAlphaMod(src_texture, draw_dsc->opa); SDL_SetTextureBlendMode(src_texture, SDL_BLENDMODE_BLEND); - SDL_SetRenderTarget(renderer, layer_get_texture(u->base_unit.target_layer)); + SDL_SetRenderTarget(renderer, layer_get_texture(t->target_layer)); SDL_RenderSetClipRect(renderer, &clip_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); @@ -370,24 +394,47 @@ 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. */ + /*Absolute coordinates are different for the same draw_dsc on a different position. + *So make everything relative to 0;0 before caching*/ + lv_area_t a = t->area; 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); } + else if(t->type == LV_DRAW_TASK_TYPE_TRIANGLE) { + lv_draw_triangle_dsc_t * tri_dsc = (lv_draw_triangle_dsc_t *)data_to_find.draw_dsc; + tri_dsc->p[0].x -= t->area.x1; + tri_dsc->p[0].y -= t->area.y1; + tri_dsc->p[1].x -= t->area.x1; + tri_dsc->p[1].y -= t->area.y1; + tri_dsc->p[2].x -= t->area.x1; + tri_dsc->p[2].y -= t->area.y1; + } + else if(t->type == LV_DRAW_TASK_TYPE_LINE) { + lv_draw_line_dsc_t * line_dsc = (lv_draw_line_dsc_t *)data_to_find.draw_dsc; + line_dsc->p1.x -= t->area.x1; + line_dsc->p1.y -= t->area.y1; + line_dsc->p2.x -= t->area.x1; + line_dsc->p2.y -= t->area.y1; + } + else if(t->type == LV_DRAW_TASK_TYPE_ARC) { + lv_draw_arc_dsc_t * arc_dsc = (lv_draw_arc_dsc_t *)data_to_find.draw_dsc; + arc_dsc->center.x -= t->area.x1; + arc_dsc->center.y -= t->area.y1; + } + + lv_area_move(&t->area, -a.x1, -a.y1); + lv_area_move(&t->_real_area, -a.x1, -a.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); - } + + lv_area_move(&t->area, a.x1, a.y1); + lv_area_move(&t->_real_area, a.x1, a.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); @@ -395,12 +442,12 @@ static void draw_from_cached_texture(lv_draw_sdl_unit_t * u) 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; + lv_layer_t * dest_layer = t->target_layer; SDL_Rect clip_rect; - clip_rect.x = u->base_unit.clip_area->x1 - dest_layer->buf_area.x1; - clip_rect.y = u->base_unit.clip_area->y1 - dest_layer->buf_area.y1; - clip_rect.w = lv_area_get_width(u->base_unit.clip_area); - clip_rect.h = lv_area_get_height(u->base_unit.clip_area); + clip_rect.x = t->clip_area.x1 - dest_layer->buf_area.x1; + clip_rect.y = t->clip_area.y1 - dest_layer->buf_area.y1; + clip_rect.w = lv_area_get_width(&t->clip_area); + clip_rect.h = lv_area_get_height(&t->clip_area); SDL_Rect rect; @@ -418,10 +465,11 @@ static void draw_from_cached_texture(lv_draw_sdl_unit_t * u) lv_cache_release(u->texture_cache, entry_cached, u); - /*Do not cache label's with local text as the text will be freed*/ + /*Do not cache non static (const) texts as the text's pointer can be freed/reallocated + *at any time resulting in a wild pointer in the cached draw dsc. */ if(t->type == LV_DRAW_TASK_TYPE_LABEL) { lv_draw_label_dsc_t * label_dsc = t->draw_dsc; - if(label_dsc->text_local) { + if(!label_dsc->text_static) { lv_cache_drop(u->texture_cache, &data_to_find, NULL); } } @@ -435,9 +483,9 @@ static void execute_drawing(lv_draw_sdl_unit_t * u) 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); + lv_layer_t * layer = t->target_layer; + lv_area_t fill_area; + lv_area_intersect(&fill_area, &t->area, &t->clip_area); rect.x = fill_area.x1 - layer->buf_area.x1; rect.y = fill_area.y1 - layer->buf_area.y1; @@ -454,7 +502,7 @@ static void execute_drawing(lv_draw_sdl_unit_t * u) } if(t->type == LV_DRAW_TASK_TYPE_LAYER) { - blend_texture_layer(u); + blend_texture_layer(t); return; } 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 d9b061de1..db1a4a8a3 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 @@ -37,13 +37,6 @@ extern "C" { * TYPEDEFS **********************/ -typedef struct { - lv_draw_unit_t base_unit; - lv_draw_task_t * task_act; - uint32_t texture_cache_data_type; - lv_cache_t * texture_cache; -} lv_draw_sdl_unit_t; - /********************** * 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 77c6cc4de..3fa42677d 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 @@ -18,6 +18,8 @@ extern "C" { #include "../../../lv_conf_internal.h" #include "../../../misc/lv_area_private.h" +#include "../../../draw/lv_draw_private.h" +#include "../../../draw/lv_draw_image_private.h" #if LV_USE_DRAW_ARM2D_SYNC @@ -48,7 +50,7 @@ extern "C" { __img_coords, \ __src_stride, \ __blend_area, \ - __draw_unit, \ + __draw_task, \ __draw_dsc) \ lv_draw_sw_image_helium( (__transformed), \ (__cf), \ @@ -56,7 +58,7 @@ extern "C" { (__img_coords), \ (__src_stride), \ (__blend_area), \ - (__draw_unit), \ + (__draw_task), \ (__draw_dsc)) #endif @@ -175,11 +177,11 @@ static inline lv_result_t lv_draw_sw_image_helium( const lv_area_t * coords, int32_t src_stride, const lv_area_t * des_area, - lv_draw_unit_t * draw_unit, + lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc) { lv_result_t result = LV_RESULT_INVALID; - lv_layer_t * layer = draw_unit->target_layer; + lv_layer_t * layer = t->target_layer; lv_color_format_t des_cf = layer->color_format; static bool arm_2d_initialized = false; @@ -192,19 +194,27 @@ static inline lv_result_t lv_draw_sw_image_helium( if (!is_transform) { break; } + #if ARM_2D_VERSION < 10202ul if(draw_dsc->scale_x != draw_dsc->scale_y) { break; } + #endif /* filter the unsupported colour format combination */ if((LV_COLOR_FORMAT_RGB565 == des_cf) && !( (LV_COLOR_FORMAT_RGB565 == src_cf) - || (LV_COLOR_FORMAT_RGB565A8 == src_cf))) { + || (LV_COLOR_FORMAT_RGB565A8 == src_cf) + #if __ARM_2D_CFG_SUPPORT_CCCA8888_IMPLICIT_CONVERSION__ && ARM_2D_VERSION > 10201ul + || (LV_COLOR_FORMAT_ARGB8888 == src_cf) + || (LV_COLOR_FORMAT_XRGB8888 == src_cf) + #endif + || (LV_COLOR_FORMAT_A8 == src_cf))) { break; } - #if 0 /* a temporary patch */ + #if ARM_2D_VERSION > 10201ul if((LV_COLOR_FORMAT_XRGB8888 == des_cf) && !( (LV_COLOR_FORMAT_ARGB8888 == src_cf) - || (LV_COLOR_FORMAT_XRGB8888 == src_cf))) { + || (LV_COLOR_FORMAT_XRGB8888 == src_cf) + || (LV_COLOR_FORMAT_A8 == src_cf))) { break; } #else @@ -218,7 +228,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, &t->clip_area)) { break; } @@ -268,8 +278,8 @@ static inline lv_result_t lv_draw_sw_image_helium( target_region = (arm_2d_region_t) { .tLocation = { - .iX = (int16_t)(coords->x1 - draw_unit->clip_area->x1), - .iY = (int16_t)(coords->y1 - draw_unit->clip_area->y1), + .iX = (int16_t)(coords->x1 - t->clip_area.x1), + .iY = (int16_t)(coords->y1 - t->clip_area.y1), }, .tSize = src_size, }; @@ -289,12 +299,12 @@ static inline lv_result_t lv_draw_sw_image_helium( clip_region = (arm_2d_region_t) { .tLocation = { - .iX = (int16_t)(draw_unit->clip_area->x1 - layer->buf_area.x1), - .iY = (int16_t)(draw_unit->clip_area->y1 - layer->buf_area.y1), + .iX = (int16_t)(t->clip_area.x1 - layer->buf_area.x1), + .iY = (int16_t)(t->clip_area.y1 - layer->buf_area.y1), }, .tSize = { - .iWidth = (int16_t)lv_area_get_width(draw_unit->clip_area), - .iHeight = (int16_t)lv_area_get_height(draw_unit->clip_area), + .iWidth = (int16_t)lv_area_get_width(&t->clip_area), + .iHeight = (int16_t)lv_area_get_height(&t->clip_area), }, }; @@ -318,13 +328,21 @@ static inline lv_result_t lv_draw_sw_image_helium( .pchBuffer = (uint8_t *)src_buf, }; + #if ARM_2D_VERSION > 10201ul + static const bool bIsNewFrame = true; + arm_2d_point_float_t source_center, target_center; + source_center.fX = draw_dsc->pivot.x; + source_center.fY = draw_dsc->pivot.y; + target_center.fX = target_region.tLocation.iX + draw_dsc->pivot.x; + target_center.fY = target_region.tLocation.iY + draw_dsc->pivot.y; + #else static arm_2d_location_t source_center, target_center; source_center.iX = draw_dsc->pivot.x; source_center.iY = draw_dsc->pivot.y; target_center = target_region.tLocation; target_center.iX += draw_dsc->pivot.x; target_center.iY += draw_dsc->pivot.y; - + #endif if(LV_COLOR_FORMAT_A8 == src_cf) { source_tile.tInfo.bHasEnforcedColour = true; @@ -332,6 +350,21 @@ static inline lv_result_t lv_draw_sw_image_helium( if(LV_COLOR_FORMAT_RGB565 == des_cf) { + #if ARM_2D_VERSION > 10201ul + arm_2dp_rgb565_fill_colour_with_mask_opacity_and_transform_xy( + NULL, + &source_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + draw_dsc->scale_y / 256.0f, + lv_color_to_u16(draw_dsc->recolor), + opa, + &target_center + ); + #else arm_2d_rgb565_fill_colour_with_mask_opacity_and_transform( &source_tile, &target_tile, @@ -343,9 +376,26 @@ static inline lv_result_t lv_draw_sw_image_helium( opa, &target_center ); - + #endif } else if(LV_COLOR_FORMAT_XRGB8888 == des_cf) { + #if ARM_2D_VERSION > 10201ul + + arm_2dp_cccn888_fill_colour_with_mask_opacity_and_transform_xy( + NULL, + &source_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + draw_dsc->scale_y / 256.0f, + lv_color_to_int(draw_dsc->recolor), + opa, + &target_center + ); + + #else arm_2d_cccn888_fill_colour_with_mask_opacity_and_transform( &source_tile, &target_tile, @@ -357,6 +407,7 @@ static inline lv_result_t lv_draw_sw_image_helium( opa, &target_center ); + #endif } else { break; @@ -377,6 +428,23 @@ static inline lv_result_t lv_draw_sw_image_helium( mask_tile.tInfo.tColourInfo.chScheme = ARM_2D_COLOUR_GRAY8; mask_tile.pchBuffer = (uint8_t *)mask_buf; + #if ARM_2D_VERSION > 10201ul + + arm_2dp_rgb565_tile_transform_xy_with_src_mask_and_opacity( + NULL, + &source_tile, + &mask_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + draw_dsc->scale_y / 256.0f, + opa, + &target_center + ); + + #else if(opa >= LV_OPA_MAX) { arm_2d_rgb565_tile_transform_with_src_mask( &source_tile, @@ -402,11 +470,27 @@ static inline lv_result_t lv_draw_sw_image_helium( &target_center ); } - + #endif } else if(LV_COLOR_FORMAT_RGB565 == src_cf) { LV_ASSERT(LV_COLOR_FORMAT_RGB565 == des_cf); + #if ARM_2D_VERSION > 10201ul + + arm_2dp_rgb565_tile_transform_xy_only_with_opacity( + NULL, + &source_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + draw_dsc->scale_y / 256.0f, + opa, + &target_center + ); + + #else if(opa >= LV_OPA_MAX) { #if ARM_2D_VERSION >= 10106 arm_2d_rgb565_tile_transform_only( @@ -444,75 +528,81 @@ static inline lv_result_t lv_draw_sw_image_helium( &target_center ); } - + #endif } - #if 0 /* a temporary patch */ + #if ARM_2D_VERSION > 10201ul else if(LV_COLOR_FORMAT_ARGB8888 == src_cf) { - LV_ASSERT(LV_COLOR_FORMAT_XRGB8888 == des_cf); + if (LV_COLOR_FORMAT_XRGB8888 == des_cf) { + source_tile.tInfo.bHasEnforcedColour = true; + source_tile.tInfo.tColourInfo.chScheme = ARM_2D_COLOUR_CCCA8888; - static arm_2d_tile_t mask_tile; - mask_tile = source_tile; - - mask_tile.tInfo.bHasEnforcedColour = true; - mask_tile.tInfo.tColourInfo.chScheme = ARM_2D_CHANNEL_8in32; - mask_tile.pchBuffer = (uint8_t *)src_buf + 3; - - if(opa >= LV_OPA_MAX) { - arm_2d_cccn888_tile_transform_with_src_mask( + arm_2dp_cccn888_tile_transform_xy_only_with_opacity( + NULL, &source_tile, - &mask_tile, - &target_tile, - NULL, - source_center, - ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), - draw_dsc->scale_x / 256.0f, - &target_center - ); - } - else { - arm_2d_cccn888_tile_transform_with_src_mask_and_opacity( - &source_tile, - &mask_tile, &target_tile, NULL, source_center, ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), draw_dsc->scale_x / 256.0f, + draw_dsc->scale_y / 256.0f, opa, &target_center ); } + else if(LV_COLOR_FORMAT_RGB565 == des_cf) { + source_tile.tInfo.bHasEnforcedColour = true; + source_tile.tInfo.tColourInfo.chScheme = ARM_2D_COLOUR_CCCA8888; + arm_2dp_rgb565_tile_transform_xy_only_with_opacity( + NULL, + &source_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + draw_dsc->scale_y / 256.0f, + opa, + &target_center + ); + } } else if(LV_COLOR_FORMAT_XRGB8888 == src_cf) { - LV_ASSERT(LV_COLOR_FORMAT_XRGB8888 == des_cf); - - if(opa >= LV_OPA_MAX) { - arm_2d_cccn888_tile_transform_only( - &source_tile, - &target_tile, - NULL, - source_center, - ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), - draw_dsc->scale_x / 256.0f, - &target_center - ); - } - else { - arm_2d_cccn888_tile_transform_only_with_opacity( + if(LV_COLOR_FORMAT_XRGB8888 == des_cf) { + arm_2dp_cccn888_tile_transform_xy_only_with_opacity( + NULL, &source_tile, &target_tile, NULL, source_center, ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), draw_dsc->scale_x / 256.0f, + draw_dsc->scale_y / 256.0f, opa, &target_center ); } + else if(LV_COLOR_FORMAT_RGB565 == des_cf) { - } + source_tile.tInfo.bHasEnforcedColour = true; + source_tile.tInfo.tColourInfo.chScheme = ARM_2D_COLOUR_CCCA8888; + + arm_2dp_rgb565_tile_transform_xy_only_with_opacity( + NULL, + &source_tile, + &target_tile, + NULL, + source_center, + ARM_2D_ANGLE((draw_dsc->rotation / 10.0f)), + draw_dsc->scale_x / 256.0f, + draw_dsc->scale_y / 256.0f, + opa, + &target_center + ); + + } #endif + } else { break; } 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 4304d7406..bab4b72ac 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 @@ -9,6 +9,12 @@ #include "lv_blend_helium.h" +/*GCC Workaround: missing .note.GNU-stack section implies executable stack*/ +#ifdef __ELF__ +.section .note.GNU-stack,"",%progbits +#endif /* __ELF__ */ + + #if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_HELIUM && defined(__ARM_FEATURE_MVE) && __ARM_FEATURE_MVE && LV_USE_NATIVE_HELIUM_ASM .data @@ -699,3 +705,4 @@ export_set xrgb8888, argb8888, 31, 32, normal export_set argb8888, argb8888, 32, 32, normal #endif /*LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_HELIUM && defined(__ARM_FEATURE_MVE) && __ARM_FEATURE_MVE && LV_USE_NATIVE_HELIUM_ASM*/ + 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 6f48eba64..19e630815 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 * */ @@ -19,10 +19,16 @@ #if LV_DRAW_SW_SUPPORT_RGB565 #include "lv_draw_sw_blend_to_rgb565.h" #endif +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + #include "lv_draw_sw_blend_to_rgb565_swapped.h" +#endif #if LV_DRAW_SW_SUPPORT_ARGB8888 #include "lv_draw_sw_blend_to_argb8888.h" #endif -#if LV_DRAW_SW_SUPPORT_RGB888 +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + #include "lv_draw_sw_blend_to_argb8888_premultiplied.h" +#endif +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 #include "lv_draw_sw_blend_to_rgb888.h" #endif #if LV_DRAW_SW_SUPPORT_I1 @@ -41,6 +47,14 @@ /********************** * STATIC PROTOTYPES **********************/ + +static inline void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_color(lv_color_format_t layer_cf, + lv_draw_sw_blend_fill_dsc_t * fill_dsc); + +static inline void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image(lv_color_format_t layer_cf, + lv_draw_sw_blend_image_dsc_t * image_dsc); + + /********************** * STATIC VARIABLES **********************/ @@ -53,19 +67,26 @@ * GLOBAL FUNCTIONS **********************/ -void lv_draw_sw_blend(lv_draw_unit_t * draw_unit, const lv_draw_sw_blend_dsc_t * blend_dsc) +void lv_draw_sw_blend(lv_draw_task_t * t, const lv_draw_sw_blend_dsc_t * blend_dsc) { /*Do not draw transparent things*/ if(blend_dsc->opa <= LV_OPA_MIN) return; 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, &t->clip_area)) return; - LV_PROFILER_BEGIN; - lv_layer_t * layer = draw_unit->target_layer; + LV_PROFILER_DRAW_BEGIN; + lv_layer_t * layer = t->target_layer; uint32_t layer_stride_byte = layer->draw_buf->header.stride; + lv_draw_sw_blend_handler_t handler = lv_draw_sw_get_blend_handler(layer->color_format); + if(handler) { + handler(t, blend_dsc); + LV_PROFILER_DRAW_END; + return; + } + if(blend_dsc->src_buf == NULL) { lv_draw_sw_blend_fill_dsc_t fill_dsc; fill_dsc.dest_w = lv_area_get_width(&blend_area); @@ -73,6 +94,7 @@ void lv_draw_sw_blend(lv_draw_unit_t * draw_unit, const lv_draw_sw_blend_dsc_t * fill_dsc.dest_stride = layer_stride_byte; fill_dsc.opa = blend_dsc->opa; fill_dsc.color = blend_dsc->color; + fill_dsc.mask_stride = 0; if(blend_dsc->mask_buf == NULL) fill_dsc.mask_buf = NULL; else if(blend_dsc->mask_res == LV_DRAW_SW_MASK_RES_FULL_COVER) fill_dsc.mask_buf = NULL; @@ -89,54 +111,16 @@ 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); } - 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; - } + lv_draw_sw_blend_color(layer->color_format, &fill_dsc); } else { if(!lv_area_intersect(&blend_area, &blend_area, blend_dsc->src_area)) { - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return; } if(blend_dsc->mask_area && !lv_area_intersect(&blend_area, &blend_area, blend_dsc->mask_area)) { - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return; } @@ -155,13 +139,14 @@ void lv_draw_sw_blend(lv_draw_unit_t * draw_unit, const lv_draw_sw_blend_dsc_t * 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) >> 3; image_dsc.src_buf = src_buf; - + image_dsc.mask_stride = 0; 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; if(image_dsc.mask_buf) { + LV_ASSERT_NULL(blend_dsc->mask_area); image_dsc.mask_buf = blend_dsc->mask_buf; image_dsc.mask_stride = blend_dsc->mask_stride ? blend_dsc->mask_stride : lv_area_get_width(blend_dsc->mask_area); image_dsc.mask_buf += image_dsc.mask_stride * (blend_area.y1 - blend_dsc->mask_area->y1) + @@ -177,52 +162,122 @@ void lv_draw_sw_blend(lv_draw_unit_t * draw_unit, const lv_draw_sw_blend_dsc_t * 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; - } + lv_draw_sw_blend_image(layer->color_format, &image_dsc); } - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } /********************** * STATIC FUNCTIONS **********************/ +static inline void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color(lv_color_format_t layer_cf, + lv_draw_sw_blend_fill_dsc_t * fill_dsc) +{ + switch(layer_cf) { +#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_RGB565_SWAPPED + case LV_COLOR_FORMAT_RGB565_SWAPPED: + lv_draw_sw_blend_color_to_rgb565_swapped(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_ARGB8888_PREMULTIPLIED + case LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED: + lv_draw_sw_blend_color_to_argb8888_premultiplied(fill_dsc); + 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; + } +} + +static inline void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image(lv_color_format_t layer_cf, + lv_draw_sw_blend_image_dsc_t * image_dsc) +{ + switch(layer_cf) { +#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_RGB565_SWAPPED + case LV_COLOR_FORMAT_RGB565_SWAPPED: + lv_draw_sw_blend_image_to_rgb565_swapped(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_ARGB8888_PREMULTIPLIED + case LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED: + lv_draw_sw_blend_image_to_argb8888_premultiplied(image_dsc); + 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; + } +} + #endif 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 1528cacc3..83970fbda 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 @@ -32,12 +32,24 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ +/** + * Custom draw function for SW rendering. + * @param t pointer to a draw task + * @param dsc pointer to an initialized blend descriptor + */ +typedef void (*lv_draw_sw_blend_handler_t)(lv_draw_task_t * t, const lv_draw_sw_blend_dsc_t * dsc); + +typedef struct { + lv_color_format_t dest_cf; + lv_draw_sw_blend_handler_t handler; +} lv_draw_sw_custom_blend_handler_t; + /** * Call the blend function of the `layer`. * @param draw_unit pointer to a draw unit * @param dsc pointer to an initialized blend descriptor */ -void lv_draw_sw_blend(lv_draw_unit_t * draw_unit, const lv_draw_sw_blend_dsc_t * dsc); +void lv_draw_sw_blend(lv_draw_task_t * t, const lv_draw_sw_blend_dsc_t * dsc); /********************** * MACROS 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 index 532f4c966..731f9ad00 100644 --- 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 @@ -30,7 +30,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_draw_sw_blend_dsc_t { +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 */ @@ -46,7 +46,7 @@ struct lv_draw_sw_blend_dsc_t { lv_blend_mode_t blend_mode; /**< E.g. LV_BLEND_MODE_ADDITIVE*/ }; -struct lv_draw_sw_blend_fill_dsc_t { +struct _lv_draw_sw_blend_fill_dsc_t { void * dest_buf; int32_t dest_w; int32_t dest_h; @@ -58,7 +58,7 @@ struct lv_draw_sw_blend_fill_dsc_t { lv_area_t relative_area; }; -struct lv_draw_sw_blend_image_dsc_t { +struct _lv_draw_sw_blend_image_dsc_t { void * dest_buf; int32_t dest_w; int32_t dest_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 index 9c3194c20..dc56243a6 100644 --- 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 @@ -1,4 +1,4 @@ -/** +/** * @file lv_draw_sw_blend_al88.c * */ @@ -62,7 +62,7 @@ static void /* LV_ATTRIBUTE_FAST_MEM */ al88_image_blend(lv_draw_sw_blend_image_ static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); #endif -#if LV_DRAW_SW_SUPPORT_RGB888 +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 static void /* LV_ATTRIBUTE_FAST_MEM */ rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t src_px_size); #endif @@ -647,6 +647,7 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_ 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; @@ -719,7 +720,7 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_ #endif -#if LV_DRAW_SW_SUPPORT_RGB888 +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t src_px_size) @@ -1018,6 +1019,9 @@ static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(lv_color16a_t * case LV_BLEND_MODE_MULTIPLY: res.lumi = (dest->lumi * src.lumi) >> 8; break; + case LV_BLEND_MODE_DIFFERENCE: + res.lumi = LV_ABS(dest->lumi - src.lumi); + break; default: LV_LOG_WARN("Not supported blend mode: %d", mode); return; 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 index b83523b92..63197c919 100644 --- 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 @@ -1,4 +1,4 @@ -/** +/** * @file 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 4bf3ef491..2e1bc5b1b 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 * */ @@ -64,11 +64,19 @@ typedef struct { static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); #endif -#if LV_DRAW_SW_SUPPORT_RGB888 +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_swapped_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 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_PREMULTIPLIED + static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_premultiplied_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); static inline void /* LV_ATTRIBUTE_FAST_MEM */ lv_color_8_32_mix(const uint8_t src, lv_color32_t * dest, uint8_t mix); @@ -80,8 +88,11 @@ static void lv_color_mix_with_alpha_cache_init(lv_color_mix_alpha_cache_t * cach 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); + static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * buf, uint32_t stride); +static inline lv_color16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color16_from_u16(uint16_t raw); + /********************** * STATIC VARIABLES **********************/ @@ -186,6 +197,22 @@ 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_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888 + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_WITH_OPA + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_WITH_MASK + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_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 @@ -236,7 +263,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_argb8888(lv_draw_sw_blend_f uint32_t color32 = lv_color_to_u32(dsc->color); uint32_t * dest_buf = dsc->dest_buf; for(y = 0; y < h; y++) { - for(x = 0; x < w - 16; x += 16) { + for(x = 0; x < w - 15; x += 16) { dest_buf[x + 0] = color32; dest_buf[x + 1] = color32; dest_buf[x + 2] = color32; @@ -264,7 +291,6 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_argb8888(lv_draw_sw_blend_f dest_buf = drawbuf_next_row(dest_buf, dest_stride); } } - } /*Opacity only*/ else if(mask == NULL && opa < LV_OPA_MAX) { @@ -276,10 +302,10 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_argb8888(lv_draw_sw_blend_f for(x = 0; x < w; x++) { dest_buf[x] = lv_color_32_32_mix(color_argb, dest_buf[x], &cache); } + dest_buf = drawbuf_next_row(dest_buf, dest_stride); } } - } /*Masked with full opacity*/ else if(mask && opa >= LV_OPA_MAX) { @@ -296,7 +322,6 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_argb8888(lv_draw_sw_blend_f mask += mask_stride; } } - } /*Masked with opacity*/ else { @@ -323,6 +348,11 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_argb8888(lv_draw_sw_blend_i rgb565_image_blend(dsc); break; #endif +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + case LV_COLOR_FORMAT_RGB565_SWAPPED: + rgb565_swapped_image_blend(dsc); + break; +#endif #if LV_DRAW_SW_SUPPORT_RGB888 case LV_COLOR_FORMAT_RGB888: rgb888_image_blend(dsc, 3); @@ -332,6 +362,11 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_argb8888(lv_draw_sw_blend_i case LV_COLOR_FORMAT_XRGB8888: rgb888_image_blend(dsc, 4); break; +#endif +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + case LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED: + argb8888_premultiplied_image_blend(dsc); + break; #endif case LV_COLOR_FORMAT_ARGB8888: argb8888_image_blend(dsc); @@ -477,11 +512,11 @@ static void LV_ATTRIBUTE_FAST_MEM al88_image_blend(lv_draw_sw_blend_image_dsc_t 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; - */ + 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); @@ -658,6 +693,7 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_ lv_color_mix_alpha_cache_t cache; lv_color_mix_with_alpha_cache_init(&cache); + int32_t x; int32_t y; @@ -739,11 +775,120 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_ #endif -#if LV_DRAW_SW_SUPPORT_RGB888 +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + +static void LV_ATTRIBUTE_FAST_MEM rgb565_swapped_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 uint16_t * src_buf_u16 = 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_color32_t color_argb; + lv_color_mix_alpha_cache_t cache; + lv_color_mix_with_alpha_cache_init(&cache); + + int32_t x; + int32_t y; + + LV_UNUSED(color_argb); + + uint16_t raw; + lv_color16_t px; + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL) { + lv_result_t accelerated; + if(opa >= LV_OPA_MAX) { + accelerated = LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888(dsc); + } + else { + accelerated = LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc); + } + if(LV_RESULT_INVALID == accelerated) { + color_argb.alpha = opa; + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + raw = lv_color_swap_16(src_buf_u16[x]); /* swap byte order */ + px = lv_color16_from_u16(raw); + color_argb.red = (px.red * 2106) >> 8; /*To make it rounded*/ + color_argb.green = (px.green * 1037) >> 8; + color_argb.blue = (px.blue * 2106) >> 8; + dest_buf_c32[x] = lv_color_32_32_mix(color_argb, dest_buf_c32[x], &cache); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + color_argb.alpha = mask_buf[x]; + raw = lv_color_swap_16(src_buf_u16[x]); /* swap byte order */ + px = lv_color16_from_u16(raw); + color_argb.red = (px.red * 2106) >> 8; /*To make it rounded*/ + color_argb.green = (px.green * 1037) >> 8; + color_argb.blue = (px.blue * 2106) >> 8; + dest_buf_c32[x] = lv_color_32_32_mix(color_argb, dest_buf_c32[x], &cache); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + mask_buf += mask_stride; + } + } + } + else { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + color_argb.alpha = LV_OPA_MIX2(mask_buf[x], opa); + raw = lv_color_swap_16(src_buf_u16[x]); /* swap byte order */ + px = lv_color16_from_u16(raw); + color_argb.red = (px.red * 2106) >> 8; /*To make it rounded*/ + color_argb.green = (px.green * 1037) >> 8; + color_argb.blue = (px.blue * 2106) >> 8; + dest_buf_c32[x] = lv_color_32_32_mix(color_argb, dest_buf_c32[x], &cache); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + mask_buf += mask_stride; + } + } + } + } + else { + lv_color32_t src_argb; + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + raw = lv_color_swap_16(src_buf_u16[x]); /* swap byte order */ + px = lv_color16_from_u16(raw); + src_argb.red = (px.red * 2106) >> 8; + src_argb.green = (px.green * 1037) >> 8; + src_argb.blue = (px.blue * 2106) >> 8; + if(mask_buf == NULL) src_argb.alpha = opa; + else src_argb.alpha = LV_OPA_MIX2(mask_buf[x], opa); + blend_non_normal_pixel(&dest_buf_c32[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_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 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; @@ -789,7 +934,6 @@ static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_ } } } - } if(mask_buf == NULL && opa < LV_OPA_MAX) { if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc, src_px_size)) { @@ -805,7 +949,6 @@ static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_ src_buf = drawbuf_next_row(src_buf, src_stride); } } - } if(mask_buf && opa >= LV_OPA_MAX) { if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc, src_px_size)) { @@ -949,6 +1092,149 @@ static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_ds } } +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + +static void LV_ATTRIBUTE_FAST_MEM argb8888_premultiplied_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_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_color32_t color_argb; + lv_color_mix_alpha_cache_t cache; + lv_color_mix_with_alpha_cache_init(&cache); + + int32_t x; + int32_t y; + + /* Process the normal blend mode (for premultiplied alpha) */ + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + /* Unpremultiply the source color by using the reciprocal of the alpha */ + color_argb = src_buf_c32[x]; + if(color_argb.alpha != 0) { + uint16_t reciprocal_alpha = (255 * 256) / color_argb.alpha; + color_argb.red = (color_argb.red * reciprocal_alpha) >> 8; + color_argb.green = (color_argb.green * reciprocal_alpha) >> 8; + color_argb.blue = (color_argb.blue * reciprocal_alpha) >> 8; + + /* Blend with destination */ + dest_buf_c32[x] = lv_color_32_32_mix(color_argb, dest_buf_c32[x], &cache); + } + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, 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_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + /* Unpremultiply the source color by using the reciprocal of the alpha */ + color_argb = src_buf_c32[x]; + if(color_argb.alpha != 0) { + uint16_t reciprocal_alpha = (255 * 256) / color_argb.alpha; + color_argb.red = (color_argb.red * reciprocal_alpha) >> 8; + color_argb.green = (color_argb.green * reciprocal_alpha) >> 8; + color_argb.blue = (color_argb.blue * reciprocal_alpha) >> 8; + color_argb.alpha = LV_OPA_MIX2(color_argb.alpha, opa); + } + + /* Blend with destination */ + dest_buf_c32[x] = lv_color_32_32_mix(color_argb, dest_buf_c32[x], &cache); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, 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_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + /* Unpremultiply the source color by using the reciprocal of the alpha */ + color_argb = src_buf_c32[x]; + if(color_argb.alpha != 0) { + uint16_t reciprocal_alpha = (255 * 256) / color_argb.alpha; + color_argb.red = (color_argb.red * reciprocal_alpha) >> 8; + color_argb.green = (color_argb.green * reciprocal_alpha) >> 8; + color_argb.blue = (color_argb.blue * reciprocal_alpha) >> 8; + color_argb.alpha = LV_OPA_MIX2(color_argb.alpha, mask_buf[x]); + } + + /* Blend with destination */ + dest_buf_c32[x] = lv_color_32_32_mix(color_argb, dest_buf_c32[x], &cache); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, 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_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + /* Unpremultiply the source color by using the reciprocal of the alpha */ + color_argb = src_buf_c32[x]; + if(color_argb.alpha != 0) { + uint16_t reciprocal_alpha = (255 * 256) / color_argb.alpha; + color_argb.red = (color_argb.red * reciprocal_alpha) >> 8; + color_argb.green = (color_argb.green * reciprocal_alpha) >> 8; + color_argb.blue = (color_argb.blue * reciprocal_alpha) >> 8; + color_argb.alpha = LV_OPA_MIX3(color_argb.alpha, opa, mask_buf[x]); + } + + /* Blend with destination */ + dest_buf_c32[x] = lv_color_32_32_mix(color_argb, dest_buf_c32[x], &cache); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, 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++) { + /* Unpremultiply the source color by using the reciprocal of the alpha */ + color_argb = src_buf_c32[x]; + if(color_argb.alpha != 0) { + uint16_t reciprocal_alpha = (255 * 256) / color_argb.alpha; + color_argb.red = (color_argb.red * reciprocal_alpha) >> 8; + color_argb.green = (color_argb.green * reciprocal_alpha) >> 8; + color_argb.blue = (color_argb.blue * reciprocal_alpha) >> 8; + } + 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 with destination using non-normal blend mode */ + blend_non_normal_pixel(&dest_buf_c32[x], color_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_c32 = drawbuf_next_row(src_buf_c32, src_stride); + } + } +} + +#endif + static inline void LV_ATTRIBUTE_FAST_MEM lv_color_8_32_mix(const uint8_t src, lv_color32_t * dest, uint8_t mix) { @@ -991,7 +1277,7 @@ static inline lv_color32_t LV_ATTRIBUTE_FAST_MEM lv_color_32_32_mix(lv_color32_t 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); + 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; } @@ -1046,6 +1332,11 @@ static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(lv_color32_t * d res.green = (dest->green * src.green) >> 8; res.blue = (dest->blue * src.blue) >> 8; break; + case LV_BLEND_MODE_DIFFERENCE: + res.red = LV_ABS(dest->red - src.red); + res.green = LV_ABS(dest->green - src.green); + res.blue = LV_ABS(dest->blue - src.blue); + break; default: LV_LOG_WARN("Not supported blend mode: %d", mode); return; @@ -1059,6 +1350,15 @@ static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, ui return (void *)((uint8_t *)buf + stride); } -#endif +static inline lv_color16_t LV_ATTRIBUTE_FAST_MEM lv_color16_from_u16(uint16_t raw) +{ + lv_color16_t c; + c.red = (raw >> 11) & 0x1F; + c.green = (raw >> 5) & 0x3F; + c.blue = raw & 0x1F; + return c; +} -#endif +#endif /* LV_DRAW_SW_SUPPORT_ARGB8888 */ + +#endif /* LV_USE_DRAW_SW */ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888_premultiplied.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888_premultiplied.c new file mode 100644 index 000000000..c0b303165 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888_premultiplied.c @@ -0,0 +1,835 @@ +/** + * @file lv_draw_sw_blend_to_argb8888_premultiplied.c + * @brief Implementation of ARGB8888 Premultiplied blending for LVGL. + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_sw_blend_to_argb8888_premultiplied.h" +#if LV_USE_DRAW_SW + +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + +#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" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_color32_t fg_saved; + lv_color32_t bg_saved; + lv_color32_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_ARGB8888 + static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 +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_premultiplied_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); + +static inline void /* LV_ATTRIBUTE_FAST_MEM */ blend_non_normal_pixel_premultiplied( + lv_color32_t * dest, lv_color32_t src, lv_blend_mode_t mode, lv_color_mix_alpha_cache_t * cache); + +static inline lv_color32_t lv_color_32_32_mix_premul(lv_color32_t fg, lv_color32_t bg, + lv_color_mix_alpha_cache_t * cache); + +static void lv_color_mix_with_alpha_cache_init(lv_color_mix_alpha_cache_t * cache); + +static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * buf, uint32_t stride); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_OPA + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_MASK + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_MIX_MASK_OPA + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_OPA + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_MASK + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_MIX_MASK_OPA + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_OPA + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_MASK + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_MIX_MASK_OPA + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +/********************** + * GLOBAL FUNCTIONS + **********************/ +/** + * @brief Blend a solid color into an ARGB8888 premultiplied buffer. + * + * This function applies a solid color to the destination buffer with optional + * opacity and masking. The input color is first converted to a premultiplied + * alpha format before blending. + * + * @param dsc Blending descriptor containing destination buffer, color, and opacity + */ +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_argb8888_premultiplied(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; + + /* Convert source color to premultiplied */ + if(opa >= LV_OPA_MAX) opa = 0xff; + lv_color32_t color_argb = lv_color_to_32(dsc->color, opa); + lv_color32_t color_argb_premul; + if(opa == 0xff) { + color_argb_premul = color_argb; + } + else { + color_argb_premul.alpha = opa; + color_argb_premul.red = (color_argb.red * opa) >> 8; + color_argb_premul.green = (color_argb.green * opa) >> 8; + color_argb_premul.blue = (color_argb.blue * opa) >> 8; + } + + /* Simple fill */ + if(mask == NULL && opa >= LV_OPA_MAX) { + uint32_t color32 = lv_color_to_u32(dsc->color); + uint32_t * dest_buf = dsc->dest_buf; + + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + dest_buf[x] = color32; + } + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + } + } + /* Opacity only */ + else if(mask == NULL && opa < LV_OPA_MAX) { + lv_color32_t * dest_buf = dsc->dest_buf; + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + dest_buf[x] = lv_color_32_32_mix_premul(color_argb_premul, dest_buf[x], &cache); + } + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + } + } + /* Masked fill */ + else if(mask && opa >= LV_OPA_MAX) { + lv_color32_t * dest_buf = dsc->dest_buf; + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color32_t color_premul = color_argb; + if(mask[x] >= LV_OPA_MAX) { + dest_buf[x] = lv_color_32_32_mix_premul(color_premul, dest_buf[x], &cache); + } + else if(mask[x] > LV_OPA_MIN) { + color_premul.alpha = mask[x]; + color_premul.red = (color_premul.red * color_premul.alpha) >> 8; + color_premul.green = (color_premul.green * color_premul.alpha) >> 8; + color_premul.blue = (color_premul.blue * color_premul.alpha) >> 8; + dest_buf[x] = lv_color_32_32_mix_premul(color_premul, dest_buf[x], &cache); + } + } + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + mask += mask_stride; + } + } + /* Masked with opacity */ + else { + lv_color32_t * dest_buf = dsc->dest_buf; + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + lv_color32_t color_premul = color_argb; + lv_opa_t alpha = LV_OPA_MIX2(mask[x], opa); + if(alpha >= LV_OPA_MAX) { + dest_buf[x] = lv_color_32_32_mix_premul(color_premul, dest_buf[x], &cache); + } + else if(mask[x] > LV_OPA_MIN) { + color_premul.alpha = alpha; + color_premul.red = (color_premul.red * color_premul.alpha) >> 8; + color_premul.green = (color_premul.green * color_premul.alpha) >> 8; + color_premul.blue = (color_premul.blue * color_premul.alpha) >> 8; + dest_buf[x] = lv_color_32_32_mix_premul(color_premul, dest_buf[x], &cache); + } + } + dest_buf = drawbuf_next_row(dest_buf, dest_stride); + mask += mask_stride; + } + } +} + +/** + * @brief Blend an image into an ARGB8888 premultiplied buffer. + * + * This function blends an image stored in ARGB8888 premultiplied format + * into the destination buffer. It accounts for opacity and optional masking. + * + * @param dsc Blending descriptor containing source and destination buffer information + */ +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_argb8888_premultiplied(lv_draw_sw_blend_image_dsc_t * dsc) +{ + switch(dsc->src_color_format) { +#if LV_DRAW_SW_SUPPORT_ARGB8888 + case LV_COLOR_FORMAT_ARGB8888: + argb8888_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_PREMULTIPLIED: + argb8888_premultiplied_image_blend(dsc); + break; + + default: + LV_LOG_WARN("Not supported source color format"); + break; + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#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_color32_t * dest_buf_c32 = 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_color32_t color_argb; + 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_ARGB8888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + color_argb = src_buf_c32[x]; + + if(color_argb.alpha >= LV_OPA_MAX) { + color_argb.alpha = 0xff; + dest_buf_c32[x] = color_argb; + } + else if(color_argb.alpha > LV_OPA_MIN) { + /*Premultiplication can cause loss of precision which can result slightly + *darker color when blending the same color to the background.*/ + if(dest_buf_c32[x].red != color_argb.red || + dest_buf_c32[x].green != color_argb.green || + dest_buf_c32[x].blue != color_argb.blue) { + + color_argb.red = (color_argb.red * color_argb.alpha) >> 8; + color_argb.green = (color_argb.green * color_argb.alpha) >> 8; + color_argb.blue = (color_argb.blue * color_argb.alpha) >> 8; + dest_buf_c32[x] = lv_color_32_32_mix_premul(color_argb, dest_buf_c32[x], &cache); + } + } + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, 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_ARGB8888_PREMULTIPLIED_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + color_argb = src_buf_c32[x]; + + /* Apply global opacity */ + lv_opa_t alpha = LV_OPA_MIX2(color_argb.alpha, opa); + + if(alpha >= LV_OPA_MAX) { + color_argb.alpha = 0xff; + dest_buf_c32[x] = color_argb; + } + else if(alpha > LV_OPA_MIN) { + /*Premultiplication can cause loss of precision which can result slightly + *darker color when blending the same color to the background.*/ + if(dest_buf_c32[x].red != color_argb.red || + dest_buf_c32[x].green != color_argb.green || + dest_buf_c32[x].blue != color_argb.blue) { + color_argb.alpha = alpha; + color_argb.red = (color_argb.red * color_argb.alpha) >> 8; + color_argb.green = (color_argb.green * color_argb.alpha) >> 8; + color_argb.blue = (color_argb.blue * color_argb.alpha) >> 8; + dest_buf_c32[x] = lv_color_32_32_mix_premul(color_argb, dest_buf_c32[x], &cache); + } + } + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, 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_ARGB8888_PREMULTIPLIED_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + color_argb = src_buf_c32[x]; + + /* Apply mask opacity */ + lv_opa_t alpha = LV_OPA_MIX2(color_argb.alpha, mask_buf[x]); + + if(alpha >= LV_OPA_MAX) { + color_argb.alpha = 0xff; + dest_buf_c32[x] = color_argb; + } + else if(alpha > LV_OPA_MIN) { + /*Premultiplication can cause loss of precision which can result slightly + *darker color when blending the same color to the background.*/ + if(dest_buf_c32[x].red != color_argb.red || + dest_buf_c32[x].green != color_argb.green || + dest_buf_c32[x].blue != color_argb.blue) { + color_argb.alpha = alpha; + color_argb.red = (color_argb.red * color_argb.alpha) >> 8; + color_argb.green = (color_argb.green * color_argb.alpha) >> 8; + color_argb.blue = (color_argb.blue * color_argb.alpha) >> 8; + dest_buf_c32[x] = lv_color_32_32_mix_premul(color_argb, dest_buf_c32[x], &cache); + } + } + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, 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_ARGB8888_PREMULTIPLIED_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + color_argb = src_buf_c32[x]; + + /* Apply both mask and global opacity */ + lv_opa_t alpha = LV_OPA_MIX3(color_argb.alpha, opa, mask_buf[x]); + + if(alpha >= LV_OPA_MAX) { + color_argb.alpha = 0xff; + dest_buf_c32[x] = color_argb; + } + else if(alpha > LV_OPA_MIN) { + /*Premultiplication can cause loss of precision which can result slightly + *darker color when blending the same color to the background.*/ + if(dest_buf_c32[x].red != color_argb.red || + dest_buf_c32[x].green != color_argb.green || + dest_buf_c32[x].blue != color_argb.blue) { + color_argb.alpha = alpha; + color_argb.red = (color_argb.red * color_argb.alpha) >> 8; + color_argb.green = (color_argb.green * color_argb.alpha) >> 8; + color_argb.blue = (color_argb.blue * color_argb.alpha) >> 8; + dest_buf_c32[x] = lv_color_32_32_mix_premul(color_argb, dest_buf_c32[x], &cache); + } + } + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, 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++) { + color_argb = src_buf_c32[x]; + + /* Apply mask and/or opacity */ + 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); + + /* Premultiply alpha */ + color_argb.red = (color_argb.red * color_argb.alpha) >> 8; + color_argb.green = (color_argb.green * color_argb.alpha) >> 8; + color_argb.blue = (color_argb.blue * color_argb.alpha) >> 8; + + blend_non_normal_pixel_premultiplied(&dest_buf_c32[x], color_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_c32 = drawbuf_next_row(src_buf_c32, src_stride); + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 + +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_color32_t * dest_buf_c32 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint8_t * src_buf = 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_color32_t color_argb; + 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; + + LV_UNUSED(color_argb); + + 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_ARGB8888_PREMULTIPLIED(dsc, src_px_size)) { + if(src_px_size == 4) { + uint32_t line_in_bytes = w * 4; + for(y = 0; y < h; y++) { + lv_memcpy(dest_buf_c32, src_buf, line_in_bytes); + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf = drawbuf_next_row(src_buf, src_stride); + } + } + else if(src_px_size == 3) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 3) { + dest_buf_c32[dest_x].red = src_buf[src_x + 2]; + dest_buf_c32[dest_x].green = src_buf[src_x + 1]; + dest_buf_c32[dest_x].blue = src_buf[src_x + 0]; + dest_buf_c32[dest_x].alpha = 0xff; + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf = drawbuf_next_row(src_buf, src_stride); + } + } + } + } + if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_OPA(dsc, src_px_size)) { + color_argb.alpha = opa; + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += src_px_size) { + color_argb.red = (src_buf[src_x + 2] * color_argb.alpha) >> 8; + color_argb.green = (src_buf[src_x + 1] * color_argb.alpha) >> 8; + color_argb.blue = (src_buf[src_x + 0] * color_argb.alpha) >> 8; + dest_buf_c32[dest_x] = lv_color_32_32_mix_premul(color_argb, dest_buf_c32[dest_x], &cache); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf = drawbuf_next_row(src_buf, src_stride); + } + } + } + if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_MASK(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) { + color_argb.alpha = mask_buf[dest_x]; + color_argb.red = (src_buf[src_x + 2] * color_argb.alpha) >> 8; + color_argb.green = (src_buf[src_x + 1] * color_argb.alpha) >> 8; + color_argb.blue = (src_buf[src_x + 0] * color_argb.alpha) >> 8; + dest_buf_c32[dest_x] = lv_color_32_32_mix_premul(color_argb, dest_buf_c32[dest_x], &cache); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf = drawbuf_next_row(src_buf, src_stride); + mask_buf += mask_stride; + } + } + } + if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_MIX_MASK_OPA(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) { + color_argb.alpha = (opa * mask_buf[dest_x]) >> 8; + color_argb.red = (src_buf[src_x + 2] * color_argb.alpha) >> 8;; + color_argb.green = (src_buf[src_x + 1] * color_argb.alpha) >> 8;; + color_argb.blue = (src_buf[src_x + 0] * color_argb.alpha) >> 8;; + dest_buf_c32[dest_x] = lv_color_32_32_mix_premul(color_argb, dest_buf_c32[dest_x], &cache); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, dest_stride); + src_buf = drawbuf_next_row(src_buf, 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[src_x + 2]; + src_argb.green = src_buf[src_x + 1]; + src_argb.blue = src_buf[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_premultiplied(&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 = drawbuf_next_row(src_buf, src_stride); + } + } +} + +#endif + + +static void LV_ATTRIBUTE_FAST_MEM argb8888_premultiplied_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_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_color32_t color_argb; + 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_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + dest_buf_c32[x] = lv_color_32_32_mix_premul(src_buf_c32[x], dest_buf_c32[x], &cache); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, 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_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + color_argb = src_buf_c32[x]; + + /* Unpremultiply the source color by using the reciprocal of the alpha */ + if(color_argb.alpha != 0) { + uint16_t reciprocal_alpha = (255 * 256) / color_argb.alpha; + color_argb.red = (color_argb.red * reciprocal_alpha) >> 8; + color_argb.green = (color_argb.green * reciprocal_alpha) >> 8; + color_argb.blue = (color_argb.blue * reciprocal_alpha) >> 8; + } + + /* Apply global opacity */ + color_argb.alpha = LV_OPA_MIX2(color_argb.alpha, opa); + + /* Premultiply alpha */ + color_argb.red = (color_argb.red * color_argb.alpha) >> 8; + color_argb.green = (color_argb.green * color_argb.alpha) >> 8; + color_argb.blue = (color_argb.blue * color_argb.alpha) >> 8; + + dest_buf_c32[x] = lv_color_32_32_mix_premul(color_argb, dest_buf_c32[x], &cache); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, 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_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + color_argb = src_buf_c32[x]; + + /* Unpremultiply the source color by using the reciprocal of the alpha */ + if(color_argb.alpha != 0) { + uint16_t reciprocal_alpha = (255 * 256) / color_argb.alpha; + color_argb.red = (color_argb.red * reciprocal_alpha) >> 8; + color_argb.green = (color_argb.green * reciprocal_alpha) >> 8; + color_argb.blue = (color_argb.blue * reciprocal_alpha) >> 8; + } + /* Adjust alpha using mask */ + color_argb.alpha = LV_OPA_MIX2(color_argb.alpha, mask_buf[x]); + + /* Premultiply alpha */ + color_argb.red = (color_argb.red * color_argb.alpha) >> 8; + color_argb.green = (color_argb.green * color_argb.alpha) >> 8; + color_argb.blue = (color_argb.blue * color_argb.alpha) >> 8; + + dest_buf_c32[x] = lv_color_32_32_mix_premul(color_argb, dest_buf_c32[x], &cache); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, 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_PREMULTIPLIED_BLEND_NORMAL_TO_ARGB8888_PREMULTIPLIED_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + color_argb = src_buf_c32[x]; + + /* Unpremultiply the source color by using the reciprocal of the alpha */ + if(color_argb.alpha != 0) { + uint16_t reciprocal_alpha = (255 * 256) / color_argb.alpha; + color_argb.red = (color_argb.red * reciprocal_alpha) >> 8; + color_argb.green = (color_argb.green * reciprocal_alpha) >> 8; + color_argb.blue = (color_argb.blue * reciprocal_alpha) >> 8; + } + + /* Adjust alpha using both mask and opacity */ + color_argb.alpha = LV_OPA_MIX3(color_argb.alpha, opa, mask_buf[x]); + + /* Premultiply alpha */ + color_argb.red = (color_argb.red * color_argb.alpha) >> 8; + color_argb.green = (color_argb.green * color_argb.alpha) >> 8; + color_argb.blue = (color_argb.blue * color_argb.alpha) >> 8; + + dest_buf_c32[x] = lv_color_32_32_mix_premul(color_argb, dest_buf_c32[x], &cache); + } + dest_buf_c32 = drawbuf_next_row(dest_buf_c32, 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++) { + color_argb = src_buf_c32[x]; + + /* Unpremultiply the source color by using the reciprocal of the alpha */ + if(color_argb.alpha != 0) { + uint16_t reciprocal_alpha = (255 * 256) / color_argb.alpha; + color_argb.red = (color_argb.red * reciprocal_alpha) >> 8; + color_argb.green = (color_argb.green * reciprocal_alpha) >> 8; + color_argb.blue = (color_argb.blue * reciprocal_alpha) >> 8; + } + + /* Adjust alpha if needed */ + 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); + + /* Premultiply alpha */ + color_argb.red = (color_argb.red * color_argb.alpha) >> 8; + color_argb.green = (color_argb.green * color_argb.alpha) >> 8; + color_argb.blue = (color_argb.blue * color_argb.alpha) >> 8; + + blend_non_normal_pixel_premultiplied(&dest_buf_c32[x], color_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_c32 = drawbuf_next_row(src_buf_c32, src_stride); + } + } +} + +/** + * @brief Mix two ARGB8888 premultiplied colors. + * + * This function blends the foreground (`fg`) and background (`bg`) colors. + * The foreground color is assumed to be premultiplied. + * + * @param fg Foreground color (premultiplied alpha) + * @param bg Background color + * @param cache Alpha blending cache for optimization + * @return lv_color32_t Blended color result + */ +static inline lv_color32_t lv_color_32_32_mix_premul(lv_color32_t fg, lv_color32_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) { + return fg; + } + /* Transparent foreground: use the background */ + else if(fg.alpha <= LV_OPA_MIN) { + return bg; + } + /* Opaque background: use simple mix */ + else if(bg.alpha == 255) { + return lv_color_mix32_premultiplied(fg, bg); + } + else { + /* Check cache to avoid redundant calculations */ + if(bg.alpha != cache->bg_saved.alpha || fg.alpha != cache->fg_saved.alpha) { + /* Compute final alpha value */ + cache->res_alpha_saved = 255 - LV_OPA_MIX2(255 - fg.alpha, 255 - bg.alpha); + LV_ASSERT(cache->res_alpha_saved != 0); + + /* Compute premultiplied blending ratio */ + cache->ratio_saved = (uint32_t)((uint32_t)fg.alpha * 255) / cache->res_alpha_saved; + } + + /* Check if color blending is already cached */ + if(!lv_color32_eq(bg, cache->bg_saved) || !lv_color32_eq(fg, cache->fg_saved)) { + cache->fg_saved = fg; + cache->bg_saved = bg; + + /* Blend using premultiplied alpha */ + uint32_t inv_fg_alpha = 255 - fg.alpha; + cache->res_saved.red = fg.red + ((bg.red * inv_fg_alpha) >> 8); + cache->res_saved.green = fg.green + ((bg.green * inv_fg_alpha) >> 8); + cache->res_saved.blue = fg.blue + ((bg.blue * inv_fg_alpha) >> 8); + cache->res_saved.alpha = cache->res_alpha_saved; + } + + return cache->res_saved; + } +} + +static void lv_color_mix_with_alpha_cache_init(lv_color_mix_alpha_cache_t * cache) +{ + lv_memzero(&cache->fg_saved, sizeof(lv_color32_t)); + lv_memzero(&cache->bg_saved, sizeof(lv_color32_t)); + lv_memzero(&cache->res_saved, sizeof(lv_color32_t)); + cache->res_alpha_saved = 255; + cache->ratio_saved = 255; +} + + +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 blend_non_normal_pixel_premultiplied( + lv_color32_t * dest, lv_color32_t src, lv_blend_mode_t mode, lv_color_mix_alpha_cache_t * cache) +{ + lv_color32_t res; + uint8_t src_alpha = src.alpha; /* Premultiplied alpha of source */ + uint8_t dest_alpha = dest->alpha; + + switch(mode) { + case LV_BLEND_MODE_ADDITIVE: + /* Ensure RGB remains premultiplied */ + res.red = LV_MIN(dest->red + src.red, dest_alpha); + res.green = LV_MIN(dest->green + src.green, dest_alpha); + res.blue = LV_MIN(dest->blue + src.blue, dest_alpha); + break; + + case LV_BLEND_MODE_SUBTRACTIVE: + /* Ensure RGB remains non-negative and premultiplied */ + res.red = LV_MAX(dest->red - src.red, 0); + res.green = LV_MAX(dest->green - src.green, 0); + res.blue = LV_MAX(dest->blue - src.blue, 0); + break; + + case LV_BLEND_MODE_MULTIPLY: + /* Adjusted for premultiplied alpha: scale the result properly */ + res.red = ((dest->red * src.red) / LV_MAX(src_alpha, 1)); + res.green = ((dest->green * src.green) / LV_MAX(src_alpha, 1)); + res.blue = ((dest->blue * src.blue) / LV_MAX(src_alpha, 1)); + break; + + case LV_BLEND_MODE_DIFFERENCE: + res.red = LV_ABS(dest->red - src.red); + res.green = LV_ABS(dest->green - src.green); + res.blue = LV_ABS(dest->blue - src.blue); + break; + + default: + LV_LOG_WARN("Not supported blend mode: %d", mode); + return; + } + + res.alpha = src_alpha; /* Keep the alpha from premultiplied source */ + *dest = lv_color_32_32_mix_premul(res, *dest, cache); +} + +#endif /* LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED */ + +#endif /* LV_USE_DRAW_SW */ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888_premultiplied.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888_premultiplied.h new file mode 100644 index 000000000..a4de2f269 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888_premultiplied.h @@ -0,0 +1,45 @@ +/** + * @file lv_draw_sw_blend_to_argb8888_premultiplied.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_TO_ARGB8888_PREMULTIPLIED_H +#define LV_DRAW_SW_BLEND_TO_ARGB8888_PREMULTIPLIED_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_argb8888_premultiplied(lv_draw_sw_blend_fill_dsc_t * dsc); + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_argb8888_premultiplied(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_ARGB8888_PREMULTIPLIED_H*/ \ No newline at end of file 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 index 1e056ee66..eaeccfab7 100644 --- 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 @@ -50,7 +50,11 @@ static void /* LV_ATTRIBUTE_FAST_MEM */ i1_image_blend(lv_draw_sw_blend_image_ds static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); #endif -#if LV_DRAW_SW_SUPPORT_RGB888 +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_swapped_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 static void /* LV_ATTRIBUTE_FAST_MEM */ rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t src_px_size); #endif @@ -74,6 +78,8 @@ static inline uint8_t /* LV_ATTRIBUTE_FAST_MEM */ get_bit(const uint8_t * buf, i static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * buf, uint32_t stride); +static inline lv_color16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color16_from_u16(uint16_t raw); + /********************** * STATIC VARIABLES **********************/ @@ -82,7 +88,7 @@ static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * b * MACROS **********************/ -#define I1_LUM_THRESHOLD 127 +#define I1_LUM_THRESHOLD LV_DRAW_SW_I1_LUM_THRESHOLD #ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_I1 #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_I1(...) LV_RESULT_INVALID @@ -132,6 +138,22 @@ static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * b #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_I1_MIX_MASK_OPA(...) LV_RESULT_INVALID #endif +#ifndef LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_I1 + #define LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_I1(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_I1_WITH_OPA + #define LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_I1_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_I1_WITH_MASK + #define LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_I1_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_I1_MIX_MASK_OPA + #define LV_DRAW_SW_RGB565_SWAPPED_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 @@ -314,6 +336,11 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_i1(lv_draw_sw_blend_image_d rgb565_image_blend(dsc); break; #endif +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + case LV_COLOR_FORMAT_RGB565_SWAPPED: + rgb565_swapped_image_blend(dsc); + break; +#endif #if LV_DRAW_SW_SUPPORT_RGB888 case LV_COLOR_FORMAT_RGB888: rgb888_image_blend(dsc, 3); @@ -810,7 +837,7 @@ static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_ds } #endif -#if LV_DRAW_SW_SUPPORT_RGB888 +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t src_px_size) { @@ -828,9 +855,9 @@ static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_ 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) { @@ -954,6 +981,7 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_ 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) { @@ -1050,6 +1078,132 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_ } #endif +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED +static void LV_ATTRIBUTE_FAST_MEM rgb565_swapped_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 uint16_t * src_buf_u16 = 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; + lv_color16_t px; + + + if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_SWAPPED_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++) { + px = lv_color16_from_u16(lv_color_swap_16(src_buf_u16[src_x])); + uint8_t src = lv_color16_luminance(px); + 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_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_SWAPPED_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++) { + px = lv_color16_from_u16(lv_color_swap_16(src_buf_u16[src_x])); + uint8_t src = lv_color16_luminance(px); + 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_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_SWAPPED_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++) { + px = lv_color16_from_u16(lv_color_swap_16(src_buf_u16[src_x])); + uint8_t src = lv_color16_luminance(px); + 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_u16 = drawbuf_next_row(src_buf_u16, src_stride); + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_SWAPPED_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++) { + px = lv_color16_from_u16(lv_color_swap_16(src_buf_u16[src_x])); + uint8_t src = lv_color16_luminance(px); + 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_u16 = drawbuf_next_row(src_buf_u16, 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++) { + px = lv_color16_from_u16(lv_color_swap_16(src_buf_u16[src_x])); + src_argb.red = (px.red * 2106) >> 8; + src_argb.green = (px.green * 1037) >> 8; + src_argb.blue = (px.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_u16 = drawbuf_next_row(src_buf_u16, 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) { @@ -1066,6 +1220,9 @@ static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(uint8_t * dest_b case LV_BLEND_MODE_MULTIPLY: res = (dest_lumi * src_lumi) >> 8; break; + case LV_BLEND_MODE_DIFFERENCE: + res = LV_ABS(dest_lumi - src_lumi); + break; default: LV_LOG_WARN("Not supported blend mode: %d", mode); return; @@ -1114,4 +1271,13 @@ static inline uint8_t LV_ATTRIBUTE_FAST_MEM get_bit(const uint8_t * buf, int32_t return (buf[bit_idx / 8] >> (7 - (bit_idx % 8))) & 1; } +static inline lv_color16_t LV_ATTRIBUTE_FAST_MEM lv_color16_from_u16(uint16_t raw) +{ + lv_color16_t c; + c.red = (raw >> 11) & 0x1F; + c.green = (raw >> 5) & 0x3F; + c.blue = raw & 0x1F; + return c; +} + #endif 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 index fa9c0251f..91bb1162a 100644 --- 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 @@ -1,4 +1,4 @@ -/** +/** * @file lv_draw_sw_blend_l8.c * */ @@ -54,7 +54,11 @@ static void /* LV_ATTRIBUTE_FAST_MEM */ l8_image_blend(lv_draw_sw_blend_image_ds static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); #endif -#if LV_DRAW_SW_SUPPORT_RGB888 +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_image_blend_swapped(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 static void /* LV_ATTRIBUTE_FAST_MEM */ rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t src_px_size); #endif @@ -70,6 +74,8 @@ static inline void /* LV_ATTRIBUTE_FAST_MEM */ blend_non_normal_pixel(uint8_t * static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * buf, uint32_t stride); +static inline lv_color16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color16_from_u16(uint16_t raw); + /********************** * STATIC VARIABLES **********************/ @@ -288,6 +294,11 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_l8(lv_draw_sw_blend_image_d rgb565_image_blend(dsc); break; #endif +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + case LV_COLOR_FORMAT_RGB565_SWAPPED: + rgb565_image_blend_swapped(dsc); + break; +#endif #if LV_DRAW_SW_SUPPORT_RGB888 case LV_COLOR_FORMAT_RGB888: rgb888_image_blend(dsc, 3); @@ -596,6 +607,7 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_ 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; @@ -668,7 +680,105 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_ #endif -#if LV_DRAW_SW_SUPPORT_RGB888 +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED +static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend_swapped(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 uint16_t * src_buf_u16 = 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; + + uint16_t raw; + lv_color16_t px; + + 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++) { + raw = lv_color_swap_16(src_buf_u16[src_x]); /* swap byte order */ + px = lv_color16_from_u16(raw); + dest_buf_u8[dest_x] = lv_color16_luminance(px); + } + dest_buf_u8 += dest_stride; + src_buf_u16 = drawbuf_next_row(src_buf_u16, 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++) { + raw = lv_color_swap_16(src_buf_u16[src_x]); /* swap byte order */ + px = lv_color16_from_u16(raw); + lv_color_8_8_mix(lv_color16_luminance(px), &dest_buf_u8[dest_x], opa); + } + dest_buf_u8 += dest_stride; + src_buf_u16 = drawbuf_next_row(src_buf_u16, 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++) { + raw = lv_color_swap_16(src_buf_u16[src_x]); /* swap byte order */ + px = lv_color16_from_u16(raw); + lv_color_8_8_mix(lv_color16_luminance(px), &dest_buf_u8[dest_x], mask_buf[src_x]); + } + dest_buf_u8 += dest_stride; + src_buf_u16 = drawbuf_next_row(src_buf_u16, 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++) { + raw = lv_color_swap_16(src_buf_u16[src_x]); /* swap byte order */ + px = lv_color16_from_u16(raw); + lv_color_8_8_mix(lv_color16_luminance(px), &dest_buf_u8[dest_x], LV_OPA_MIX2(opa, mask_buf[src_x])); + } + dest_buf_u8 += dest_stride; + src_buf_u16 = drawbuf_next_row(src_buf_u16, 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++) { + raw = lv_color_swap_16(src_buf_u16[src_x]); /* swap byte order */ + px = lv_color16_from_u16(raw); + src_argb.red = (px.red * 2106) >> 8; + src_argb.green = (px.green * 1037) >> 8; + src_argb.blue = (px.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_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t src_px_size) @@ -748,6 +858,7 @@ static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_ 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; @@ -856,7 +967,6 @@ static inline void LV_ATTRIBUTE_FAST_MEM lv_color_8_8_mix(const uint8_t src, uin } } - #if LV_DRAW_SW_SUPPORT_I1 static inline uint8_t LV_ATTRIBUTE_FAST_MEM get_bit(const uint8_t * buf, int32_t bit_idx) @@ -880,6 +990,9 @@ static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(uint8_t * dest, case LV_BLEND_MODE_MULTIPLY: res = (*dest * src_lumi) >> 8; break; + case LV_BLEND_MODE_DIFFERENCE: + res = LV_ABS(*dest - src_lumi); + break; default: LV_LOG_WARN("Not supported blend mode: %d", mode); return; @@ -892,6 +1005,15 @@ static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, ui return (void *)((uint8_t *)buf + stride); } +static inline lv_color16_t LV_ATTRIBUTE_FAST_MEM lv_color16_from_u16(uint16_t raw) +{ + lv_color16_t c; + c.red = (raw >> 11) & 0x1F; + c.green = (raw >> 5) & 0x3F; + c.blue = raw & 0x1F; + return c; +} + #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 index 079218e5a..04f4b44a6 100644 --- 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 @@ -1,4 +1,4 @@ -/** +/** * @file 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 1fa8c06b2..bca595caa 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 * */ @@ -54,7 +54,11 @@ static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); -#if LV_DRAW_SW_SUPPORT_RGB888 +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_swapped_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 static void /* LV_ATTRIBUTE_FAST_MEM */ rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t src_px_size); #endif @@ -63,6 +67,10 @@ static void /* LV_ATTRIBUTE_FAST_MEM */ rgb888_image_blend(lv_draw_sw_blend_imag static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); #endif +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_premultiplied_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); @@ -71,6 +79,8 @@ static inline uint16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color_24_16_mix(const uint static inline void * /* LV_ATTRIBUTE_FAST_MEM */ drawbuf_next_row(const void * buf, uint32_t stride); +static inline lv_color16_t /* LV_ATTRIBUTE_FAST_MEM */ lv_color16_from_u16(uint16_t raw); + /********************** * STATIC VARIABLES **********************/ @@ -175,6 +185,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_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565 + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_WITH_OPA + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_WITH_MASK + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_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 @@ -234,7 +260,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_rgb565(lv_draw_sw_blend_fil LV_UNUSED(dest_buf_u16); /*Simple fill*/ - if(mask == NULL && opa >= LV_OPA_MAX) { + if(mask == NULL && opa >= LV_OPA_MAX) { if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_RGB565(dsc)) { for(y = 0; y < h; y++) { uint16_t * dest_end_final = dest_buf_u16 + w; @@ -311,9 +337,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_rgb565(lv_draw_sw_blend_fil dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); } } - } - /*Masked with full opacity*/ else if(mask && opa >= LV_OPA_MAX) { if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_RGB565_WITH_MASK(dsc)) { @@ -343,7 +367,6 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_rgb565(lv_draw_sw_blend_fil mask += mask_stride; } } - } /*Masked with opacity*/ else if(mask && opa < LV_OPA_MAX) { @@ -365,6 +388,11 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_rgb565(lv_draw_sw_blend_ima case LV_COLOR_FORMAT_RGB565: rgb565_image_blend(dsc); break; +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + case LV_COLOR_FORMAT_RGB565_SWAPPED: + rgb565_swapped_image_blend(dsc); + break; +#endif #if LV_DRAW_SW_SUPPORT_RGB888 case LV_COLOR_FORMAT_RGB888: rgb888_image_blend(dsc, 3); @@ -380,6 +408,11 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_rgb565(lv_draw_sw_blend_ima argb8888_image_blend(dsc); break; #endif +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + case LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED: + argb8888_premultiplied_image_blend(dsc); + break; +#endif #if LV_DRAW_SW_SUPPORT_L8 case LV_COLOR_FORMAT_L8: l8_image_blend(dsc); @@ -449,7 +482,6 @@ static void LV_ATTRIBUTE_FAST_MEM i1_image_blend(lv_draw_sw_blend_image_dsc_t * } 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; @@ -495,6 +527,10 @@ static void LV_ATTRIBUTE_FAST_MEM i1_image_blend(lv_draw_sw_blend_image_dsc_t * ((((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; + case LV_BLEND_MODE_DIFFERENCE: + /*Difference blending mode*/ + res = (LV_ABS(dest_buf_u16[dest_x] - l8_to_rgb565(chan_val))); + break; default: LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); return; @@ -613,6 +649,11 @@ static void LV_ATTRIBUTE_FAST_MEM al88_image_blend(lv_draw_sw_blend_image_dsc_t res += ((dest_buf_c16[dest_x].green * g) >> 6) << 5; res += (dest_buf_c16[dest_x].blue * rb) >> 5; break; + case LV_BLEND_MODE_DIFFERENCE: + res = (LV_ABS(dest_buf_c16[dest_x].red - rb)) << 11; + res += (LV_ABS(dest_buf_c16[dest_x].green - g)) << 5; + res += LV_ABS(dest_buf_c16[dest_x].blue - rb); + break; default: LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); return; @@ -728,6 +769,11 @@ static void LV_ATTRIBUTE_FAST_MEM l8_image_blend(lv_draw_sw_blend_image_dsc_t * res += ((dest_buf_c16[dest_x].green * g) >> 6) << 5; res += (dest_buf_c16[dest_x].blue * rb) >> 5; break; + case LV_BLEND_MODE_DIFFERENCE: + res = (LV_ABS(dest_buf_c16[dest_x].red - rb)) << 11; + res += (LV_ABS(dest_buf_c16[dest_x].green - g)) << 5; + res += LV_ABS(dest_buf_c16[dest_x].blue - rb); + break; default: LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); return; @@ -841,6 +887,11 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_ res += ((dest_buf_c16[x].green * src_buf_c16[x].green) >> 6) << 5; res += (dest_buf_c16[x].blue * src_buf_c16[x].blue) >> 5; break; + case LV_BLEND_MODE_DIFFERENCE: + res = (LV_ABS(dest_buf_c16[x].red - src_buf_c16[x].red)) << 11; + res += (LV_ABS(dest_buf_c16[x].green - src_buf_c16[x].green)) << 5; + res += LV_ABS(dest_buf_c16[x].blue - src_buf_c16[x].blue); + break; default: LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); return; @@ -862,7 +913,129 @@ static void LV_ATTRIBUTE_FAST_MEM rgb565_image_blend(lv_draw_sw_blend_image_dsc_ } } -#if LV_DRAW_SW_SUPPORT_RGB888 +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED +static void LV_ATTRIBUTE_FAST_MEM rgb565_swapped_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 uint16_t * src_buf_u16 = 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_RGB565_BLEND_NORMAL_TO_RGB565(dsc)) { + uint32_t line_in_bytes = w * 2; + for(y = 0; y < h; y++) { + lv_memcpy(dest_buf_u16, src_buf_u16, line_in_bytes); + lv_draw_sw_rgb565_swap((uint8_t *) dest_buf_u16, w); + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + dest_buf_u16[x] = lv_color_16_16_mix(lv_color_swap_16(src_buf_u16[x]), dest_buf_u16[x], opa); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + dest_buf_u16[x] = lv_color_16_16_mix(lv_color_swap_16(src_buf_u16[x]), dest_buf_u16[x], mask_buf[x]); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + mask_buf += mask_stride; + } + } + } + else { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + dest_buf_u16[x] = lv_color_16_16_mix(lv_color_swap_16(src_buf_u16[x]), dest_buf_u16[x], LV_OPA_MIX2(mask_buf[x], opa)); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, 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(x = 0; x < w; x++) { + uint16_t raw; + lv_color16_t px; + raw = lv_color_swap_16(src_buf_u16[x]); /* swap byte order */ + px = lv_color16_from_u16(raw); + + switch(dsc->blend_mode) { + case LV_BLEND_MODE_ADDITIVE: + if(src_buf_u16[x] == 0x0000) continue; /*Do not add pure black*/ + res = (LV_MIN(dest_buf_c16[x].red + px.red, 31)) << 11; + res += (LV_MIN(dest_buf_c16[x].green + px.green, 63)) << 5; + res += LV_MIN(dest_buf_c16[x].blue + px.blue, 31); + break; + case LV_BLEND_MODE_SUBTRACTIVE: + if(src_buf_u16[x] == 0x0000) continue; /*Do not subtract pure black*/ + res = (LV_MAX(dest_buf_c16[x].red - px.red, 0)) << 11; + res += (LV_MAX(dest_buf_c16[x].green - px.green, 0)) << 5; + res += LV_MAX(dest_buf_c16[x].blue - px.blue, 0); + break; + case LV_BLEND_MODE_MULTIPLY: + if(src_buf_u16[x] == 0xffff) continue; /*Do not multiply with pure white (considered as 1)*/ + res = ((dest_buf_c16[x].red * px.red) >> 5) << 11; + res += ((dest_buf_c16[x].green * px.green) >> 6) << 5; + res += (dest_buf_c16[x].blue * px.blue) >> 5; + break; + case LV_BLEND_MODE_DIFFERENCE: + res = (LV_ABS(dest_buf_c16[x].red - px.red)) << 11; + res += (LV_ABS(dest_buf_c16[x].green - px.green)) << 5; + res += LV_ABS(dest_buf_c16[x].blue - px.blue); + break; + default: + LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); + return; + } + + if(mask_buf == NULL) { + dest_buf_u16[x] = lv_color_16_16_mix(res, dest_buf_u16[x], opa); + } + else { + if(opa >= LV_OPA_MAX) dest_buf_u16[x] = lv_color_16_16_mix(res, dest_buf_u16[x], mask_buf[x]); + else dest_buf_u16[x] = lv_color_16_16_mix(res, dest_buf_u16[x], LV_OPA_MIX2(mask_buf[x], opa)); + } + } + + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + if(mask_buf) mask_buf += mask_stride; + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_t * dsc, const uint8_t src_px_size) { @@ -951,6 +1124,11 @@ static void LV_ATTRIBUTE_FAST_MEM rgb888_image_blend(lv_draw_sw_blend_image_dsc_ res += ((dest_buf_c16[dest_x].green * (src_buf_u8[src_x + 1] >> 2)) >> 6) << 5; res += (dest_buf_c16[dest_x].blue * (src_buf_u8[src_x + 0] >> 3)) >> 5; break; + case LV_BLEND_MODE_DIFFERENCE: + res = (LV_ABS(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 2] >> 3))) << 11; + res += (LV_ABS(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2))) << 5; + res += LV_ABS(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 0] >> 3)); + break; default: LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); return; @@ -1064,6 +1242,11 @@ static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_ds res += ((dest_buf_c16[dest_x].green * (src_buf_u8[src_x + 1] >> 2)) >> 6) << 5; res += (dest_buf_c16[dest_x].blue * (src_buf_u8[src_x + 0] >> 3)) >> 5; break; + case LV_BLEND_MODE_DIFFERENCE: + res = (LV_ABS(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 2] >> 3))) << 11; + res += (LV_ABS(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2))) << 5; + res += LV_ABS(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 0] >> 3)); + break; default: LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); return; @@ -1091,6 +1274,175 @@ static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_ds #endif +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + +static inline uint16_t LV_ATTRIBUTE_FAST_MEM lv_color_24_16_mix_premult(const uint8_t * c1, uint16_t c2, uint8_t mix) +{ + if(mix == 0) { + return c2; + } + else if(mix == 255) { + return ((c1[2] & 0xF8) << 8) + ((c1[1] & 0xFC) << 3) + ((c1[0] & 0xF8) >> 3); + } + else { + lv_opa_t mix_inv = 255 - mix; + + uint8_t r = (c1[2] >> 3) + ((((c2 >> 11) & 0x1F) * mix_inv) >> 8); + uint8_t g = (c1[1] >> 2) + ((((c2 >> 5) & 0x3F) * mix_inv) >> 8); + uint8_t b = (c1[0] >> 3) + ((((c2 >> 0) & 0x1F) * mix_inv) >> 8); + + return (r << 11) + (g << 5) + (b); + } +} + +static void LV_ATTRIBUTE_FAST_MEM argb8888_premultiplied_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_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) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_PREMULTIPLIED_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 += 4) { + /*For the trivial case use the premultipled image as it is. + *For the other cases unpremultiply as another alpha also needs to be applied.*/ + dest_buf_u16[dest_x] = lv_color_24_16_mix_premult(&src_buf_u8[src_x], dest_buf_u16[dest_x], src_buf_u8[src_x + 3]); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_PREMULTIPLIED_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 += 4) { + if(src_buf_u8[src_x + 3] > 0) { + uint8_t src_buf_u8_unpremult[3]; + uint16_t reciprocal = (255 * 256) / src_buf_u8[src_x + 3]; + src_buf_u8_unpremult[0] = (src_buf_u8[src_x + 0] * reciprocal) >> 8; + src_buf_u8_unpremult[1] = (src_buf_u8[src_x + 1] * reciprocal) >> 8; + src_buf_u8_unpremult[2] = (src_buf_u8[src_x + 2] * reciprocal) >> 8; + dest_buf_u16[dest_x] = lv_color_24_16_mix(src_buf_u8_unpremult, dest_buf_u16[dest_x], + LV_OPA_MIX2(src_buf_u8[src_x + 3], opa)); + } + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_PREMULTIPLIED_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 += 4) { + if(src_buf_u8[src_x + 3] > 0) { + uint8_t src_buf_u8_unpremult[3]; + uint16_t reciprocal = (255 * 256) / src_buf_u8[src_x + 3]; + src_buf_u8_unpremult[0] = (src_buf_u8[src_x + 0] * reciprocal) >> 8; + src_buf_u8_unpremult[1] = (src_buf_u8[src_x + 1] * reciprocal) >> 8; + src_buf_u8_unpremult[2] = (src_buf_u8[src_x + 2] * reciprocal) >> 8; + dest_buf_u16[dest_x] = lv_color_24_16_mix(src_buf_u8_unpremult, dest_buf_u16[dest_x], + LV_OPA_MIX2(src_buf_u8[src_x + 3], mask_buf[dest_x])); + } + + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_PREMULTIPLIED_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 += 4) { + if(src_buf_u8[src_x + 3] > 0) { + uint8_t src_buf_u8_unpremult[3]; + uint16_t reciprocal = (255 * 256) / src_buf_u8[src_x + 3]; + src_buf_u8_unpremult[0] = (src_buf_u8[src_x + 0] * reciprocal) >> 8; + src_buf_u8_unpremult[1] = (src_buf_u8[src_x + 1] * reciprocal) >> 8; + src_buf_u8_unpremult[2] = (src_buf_u8[src_x + 2] * reciprocal) >> 8; + dest_buf_u16[dest_x] = lv_color_24_16_mix(src_buf_u8_unpremult, dest_buf_u16[dest_x], + LV_OPA_MIX3(src_buf_u8[src_x + 3], mask_buf[dest_x], opa)); + } + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += 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) { + switch(dsc->blend_mode) { + case LV_BLEND_MODE_ADDITIVE: + res = (LV_MIN(dest_buf_c16[dest_x].red + (src_buf_u8[src_x + 2] >> 3), 31)) << 11; + res += (LV_MIN(dest_buf_c16[dest_x].green + (src_buf_u8[src_x + 1] >> 2), 63)) << 5; + res += LV_MIN(dest_buf_c16[dest_x].blue + (src_buf_u8[src_x + 0] >> 3), 31); + break; + case LV_BLEND_MODE_SUBTRACTIVE: + res = (LV_MAX(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 2] >> 3), 0)) << 11; + res += (LV_MAX(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2), 0)) << 5; + res += LV_MAX(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 0] >> 3), 0); + break; + case LV_BLEND_MODE_MULTIPLY: + res = ((dest_buf_c16[dest_x].red * (src_buf_u8[src_x + 2] >> 3)) >> 5) << 11; + res += ((dest_buf_c16[dest_x].green * (src_buf_u8[src_x + 1] >> 2)) >> 6) << 5; + res += (dest_buf_c16[dest_x].blue * (src_buf_u8[src_x + 0] >> 3)) >> 5; + break; + case LV_BLEND_MODE_DIFFERENCE: + res = (LV_ABS(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 2] >> 3))) << 11; + res += (LV_ABS(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2))) << 5; + res += LV_ABS(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 0] >> 3)); + break; + default: + LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); + return; + } + + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + /* Blending premultiplied ARGB8888 to RGB565 with no mask and full opacity */ + dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], src_buf_u8[src_x + 3]); + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + /* Blending premultiplied ARGB8888 to RGB565 with no mask and partial opacity */ + dest_buf_u16[dest_x] = lv_color_16_16_mix(res, dest_buf_u16[dest_x], LV_OPA_MIX2(opa, src_buf_u8[src_x + 3])); + } + 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_u8[src_x + 3])); + } + } + + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + if(mask_buf) mask_buf += mask_stride; + } + } +} + +#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); @@ -1145,6 +1497,15 @@ static inline void * LV_ATTRIBUTE_FAST_MEM drawbuf_next_row(const void * buf, ui return (void *)((uint8_t *)buf + stride); } -#endif +static inline lv_color16_t LV_ATTRIBUTE_FAST_MEM lv_color16_from_u16(uint16_t raw) +{ + lv_color16_t c; + c.red = (raw >> 11) & 0x1F; + c.green = (raw >> 5) & 0x3F; + c.blue = raw & 0x1F; + return c; +} -#endif +#endif /*LV_DRAW_SW_SUPPORT_RGB565*/ + +#endif /*LV_USE_DRAW_SW*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565_swapped.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565_swapped.c new file mode 100644 index 000000000..88845845c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565_swapped.c @@ -0,0 +1,1560 @@ +/** + * @file lv_draw_sw_blend_to_rgb565_swapped.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_sw_blend_to_rgb565_swapped.h" +#if LV_USE_DRAW_SW + +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + +#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_AL88 + static void /* LV_ATTRIBUTE_FAST_MEM */ al88_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 + +#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 + +static void /* LV_ATTRIBUTE_FAST_MEM */ rgb565_swapped_image_blend(lv_draw_sw_blend_image_dsc_t * dsc); + +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 +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 + +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_premultiplied_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); + +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_RGB565_SWAPPED + #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_SWAPPED(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_SWAPPED_WITH_OPA + #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_SWAPPED_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_SWAPPED_WITH_MASK + #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_SWAPPED_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_COLOR_BLEND_TO_RGB565_SWAPPED_MIX_MASK_OPA + #define LV_DRAW_SW_COLOR_BLEND_TO_RGB565_SWAPPED_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_SWAPPED + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_SWAPPED(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA + #define LV_DRAW_SW_L8_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_SWAPPED + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_SWAPPED(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA + #define LV_DRAW_SW_AL88_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_SWAPPED + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_SWAPPED(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA + #define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_SWAPPED + #define LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_SWAPPED(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA + #define LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK + #define LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA + #define LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_SWAPPED + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_SWAPPED(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA + #define LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_SWAPPED + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_SWAPPED(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA + #define LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_SWAPPED + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_SWAPPED(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_SWAPPED + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_SWAPPED(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA + #define LV_DRAW_SW_I1_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA(...) LV_RESULT_INVALID +#endif + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Fill an area with a color. + * Supports normal fill, fill with opacity, fill with mask, and fill with mask and opacity. + * dest_buf and color have native color depth. (RGB565, RGB888, XRGB8888) + * The background (dest_buf) cannot have alpha channel + * @param dest_buf + * @param dest_area + * @param dest_stride + * @param color + * @param opa + * @param mask + * @param mask_stride + */ +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_rgb565_swapped(lv_draw_sw_blend_fill_dsc_t * dsc) +{ + int32_t w = dsc->dest_w; + int32_t h = dsc->dest_h; + uint16_t color16 = lv_color_to_u16(dsc->color); /* Normal color */ + uint16_t color16_swapped = lv_color_swap_16(color16); /* Swapped color, use directly if no mixing is needed */ + lv_opa_t opa = dsc->opa; + const lv_opa_t * mask = dsc->mask_buf; + int32_t mask_stride = dsc->mask_stride; + uint16_t * dest_buf_u16 = dsc->dest_buf; + 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(color16); + LV_UNUSED(color16_swapped); + LV_UNUSED(mask_stride); + LV_UNUSED(dest_stride); + LV_UNUSED(dest_buf_u16); + + /*Simple fill*/ + if(mask == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_RGB565_SWAPPED(dsc)) { + for(y = 0; y < h; y++) { + uint16_t * dest_end_final = dest_buf_u16 + w; + uint32_t * dest_end_mid = (uint32_t *)((uint16_t *) dest_buf_u16 + ((w - 1) & ~(0xF))); + + if((lv_uintptr_t)&dest_buf_u16[0] & 0x3) { + dest_buf_u16[0] = color16_swapped; + dest_buf_u16++; + } + + uint32_t c32 = (uint32_t)color16_swapped + ((uint32_t)color16_swapped << 16); + uint32_t * dest32 = (uint32_t *)dest_buf_u16; + while(dest32 < dest_end_mid) { + dest32[0] = c32; + dest32[1] = c32; + dest32[2] = c32; + dest32[3] = c32; + dest32[4] = c32; + dest32[5] = c32; + dest32[6] = c32; + dest32[7] = c32; + dest32 += 8; + } + + dest_buf_u16 = (uint16_t *)dest32; + + while(dest_buf_u16 < dest_end_final) { + *dest_buf_u16 = color16_swapped; + dest_buf_u16++; + } + + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + dest_buf_u16 -= w; + } + } + + } + /*Opacity only*/ + else if(mask == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_RGB565_SWAPPED_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + /*Make sure the last dest_color doesn't match the first one so that it will be calculated*/ + uint16_t last_dest_color = dest_buf_u16[0] - 1; + uint16_t last_res_color = 0; + for(x = 0; x < w; x++) { + if(last_dest_color != dest_buf_u16[x]) { + uint16_t px = lv_color_swap_16(dest_buf_u16[x]); /* Swap destination so it becomes unswapped now */ + last_res_color = lv_color_16_16_mix(color16, px, opa); /* Color mix of unswapped colors */ + last_res_color = lv_color_swap_16(last_res_color); + last_dest_color = dest_buf_u16[x]; + } + + dest_buf_u16[x] = last_res_color; + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + } + } + } + /*Masked with full opacity*/ + else if(mask && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_RGB565_SWAPPED_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + x = 0; + if((lv_uintptr_t)(mask) & 0x1) { + uint16_t px = dest_buf_u16[x]; + px = lv_color_swap_16(px); /* Swap destination */ + px = lv_color_16_16_mix(color16, px, mask[x]); /* Color mix */ + dest_buf_u16[x] = lv_color_swap_16(px); /* Write back swapped */ + x++; + } + + for(; x <= w - 2; x += 2) { + uint16_t mask16 = *((uint16_t *)&mask[x]); + if(mask16 == 0xFFFF) { + dest_buf_u16[x + 0] = color16_swapped; + dest_buf_u16[x + 1] = color16_swapped; + } + else if(mask16 != 0) { + uint16_t px0 = lv_color_swap_16(dest_buf_u16[x + 0]); /* Swap destination */ + uint16_t px1 = lv_color_swap_16(dest_buf_u16[x + 1]); /* Swap destination */ + + px0 = lv_color_16_16_mix(color16, px0, mask[x + 0]); /* Color mix */ + px1 = lv_color_16_16_mix(color16, px1, mask[x + 1]); /* Color mix */ + + dest_buf_u16[x + 0] = lv_color_swap_16(px0); /* Write back swapped */ + dest_buf_u16[x + 1] = lv_color_swap_16(px1); /* Write back swapped */ + + } + } + + for(; x < w ; x++) { + uint16_t px = dest_buf_u16[x]; + px = lv_color_swap_16(px); /* Swap destination */ + px = lv_color_16_16_mix(color16, px, mask[x]); /* Color mix */ + dest_buf_u16[x] = lv_color_swap_16(px); /* Write back swapped */ + + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + mask += mask_stride; + } + } + } + /*Masked with opacity*/ + else if(mask && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_RGB565_SWAPPED_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + uint16_t px = dest_buf_u16[x]; + px = lv_color_swap_16(px); /* Swap destination */ + + uint8_t mix_opa = LV_OPA_MIX2(mask[x], opa); + px = lv_color_16_16_mix(color16, px, mix_opa); /* Color mix */ + + dest_buf_u16[x] = lv_color_swap_16(px); /* Write back swapped */ + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + mask += mask_stride; + } + } + } +} + +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_rgb565_swapped(lv_draw_sw_blend_image_dsc_t * dsc) +{ + switch(dsc->src_color_format) { + case LV_COLOR_FORMAT_RGB565_SWAPPED: + rgb565_swapped_image_blend(dsc); + break; +#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_ARGB8888_PREMULTIPLIED + case LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED: + argb8888_premultiplied_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; + } +} + +/********************** + * 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; + 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_SWAPPED(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_swap_16(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_SWAPPED_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_swap_16(lv_color_8_16_mix(chan_val, lv_color_swap_16(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_SWAPPED_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_swap_16(lv_color_8_16_mix(chan_val, lv_color_swap_16(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_SWAPPED_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_swap_16(lv_color_8_16_mix(chan_val, lv_color_swap_16(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: + res = (LV_MIN(lv_color_swap_16(dest_buf_u16[dest_x]) + l8_to_rgb565(chan_val), 0xFFFF)); + break; + case LV_BLEND_MODE_SUBTRACTIVE: + res = (LV_MAX(lv_color_swap_16(dest_buf_u16[dest_x]) - l8_to_rgb565(chan_val), 0)); + break; + case LV_BLEND_MODE_MULTIPLY: + res = ((((lv_color_swap_16(dest_buf_u16[dest_x]) >> 11) * (l8_to_rgb565(chan_val) >> 3)) & 0x1F) << 11) | + ((((lv_color_swap_16(dest_buf_u16[dest_x]) >> 5) & 0x3F) * ((l8_to_rgb565(chan_val) >> 2) & 0x3F) >> 6) << 5) | + (((lv_color_swap_16(dest_buf_u16[dest_x]) & 0x1F) * (l8_to_rgb565(chan_val) & 0x1F)) >> 5); + break; + case LV_BLEND_MODE_DIFFERENCE: + res = (LV_ABS(lv_color_swap_16(dest_buf_u16[dest_x]) - l8_to_rgb565(chan_val))); + 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_swap_16(res); + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_16_16_mix(res, lv_color_swap_16(dest_buf_u16[dest_x]), opa)); + } + else { + if(opa >= LV_OPA_MAX) + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_16_16_mix(res, lv_color_swap_16(dest_buf_u16[dest_x]), + mask_buf[dest_x])); + else + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_16_16_mix(res, lv_color_swap_16(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_SWAPPED(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_swap_16(lv_color_8_16_mix(src_buf_al88[src_x].lumi, + lv_color_swap_16(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_SWAPPED_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_swap_16(lv_color_8_16_mix(src_buf_al88[src_x].lumi, + lv_color_swap_16(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_SWAPPED_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_swap_16(lv_color_8_16_mix(src_buf_al88[src_x].lumi, + lv_color_swap_16(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_SWAPPED_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_swap_16(lv_color_8_16_mix(src_buf_al88[src_x].lumi, + lv_color_swap_16(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; + lv_draw_sw_rgb565_swap((uint8_t *) dest_buf_u16, w); + 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; + case LV_BLEND_MODE_DIFFERENCE: + res = (LV_ABS(dest_buf_c16[dest_x].red - rb)) << 11; + res += (LV_ABS(dest_buf_c16[dest_x].green - g)) << 5; + res += LV_ABS(dest_buf_c16[dest_x].blue - rb); + 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_swap_16(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_swap_16(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_swap_16(lv_color_16_16_mix(res, dest_buf_u16[dest_x], + mask_buf[dest_x])); + else dest_buf_u16[dest_x] = lv_color_swap_16(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_SWAPPED(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_swap_16(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_SWAPPED_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_swap_16(lv_color_8_16_mix(src_buf_l8[src_x], lv_color_swap_16(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_SWAPPED_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_swap_16(lv_color_8_16_mix(src_buf_l8[src_x], lv_color_swap_16(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_SWAPPED_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_swap_16(lv_color_8_16_mix(src_buf_l8[src_x], lv_color_swap_16(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; + lv_draw_sw_rgb565_swap((uint8_t *) dest_buf_u16, w); + 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; + case LV_BLEND_MODE_DIFFERENCE: + res = (LV_ABS(dest_buf_c16[dest_x].red - rb)) << 11; + res += (LV_ABS(dest_buf_c16[dest_x].green - g)) << 5; + res += LV_ABS(dest_buf_c16[dest_x].blue - rb); + 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_swap_16(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_swap_16(lv_color_16_16_mix(res, dest_buf_u16[dest_x], + mask_buf[dest_x])); + else dest_buf_u16[dest_x] = lv_color_swap_16(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 + +#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; + uint16_t * dest_buf_u16 = dsc->dest_buf; + int32_t dest_stride = dsc->dest_stride; + const uint16_t * src_buf_u16 = 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_RGB565_BLEND_NORMAL_TO_RGB565_SWAPPED(dsc)) { + uint32_t line_in_bytes = w * 2; + for(y = 0; y < h; y++) { + lv_memcpy(dest_buf_u16, src_buf_u16, line_in_bytes); + lv_draw_sw_rgb565_swap((uint8_t *) dest_buf_u16, w); + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + dest_buf_u16[x] = lv_color_swap_16(lv_color_16_16_mix(src_buf_u16[x], lv_color_swap_16(dest_buf_u16[x]), opa)); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + dest_buf_u16[x] = lv_color_swap_16(lv_color_16_16_mix(src_buf_u16[x], lv_color_swap_16(dest_buf_u16[x]), mask_buf[x])); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + mask_buf += mask_stride; + } + } + } + else { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + dest_buf_u16[x] = lv_color_swap_16(lv_color_16_16_mix(src_buf_u16[x], lv_color_swap_16(dest_buf_u16[x]), + LV_OPA_MIX2(mask_buf[x], opa))); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, 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; + lv_color16_t * src_buf_c16 = (lv_color16_t *) src_buf_u16; + for(x = 0; x < w; x++) { + switch(dsc->blend_mode) { + case LV_BLEND_MODE_ADDITIVE: + if(src_buf_u16[x] == 0x0000) continue; /*Do not add pure black*/ + dest_buf_u16[x] = lv_color_swap_16(dest_buf_u16[x]); + res = (LV_MIN(dest_buf_c16[x].red + src_buf_c16[x].red, 31)) << 11; + res += (LV_MIN(dest_buf_c16[x].green + src_buf_c16[x].green, 63)) << 5; + res += LV_MIN(dest_buf_c16[x].blue + src_buf_c16[x].blue, 31); + break; + case LV_BLEND_MODE_SUBTRACTIVE: + if(src_buf_u16[x] == 0x0000) continue; /*Do not subtract pure black*/ + dest_buf_u16[x] = lv_color_swap_16(dest_buf_u16[x]); + res = (LV_MAX(dest_buf_c16[x].red - src_buf_c16[x].red, 0)) << 11; + res += (LV_MAX(dest_buf_c16[x].green - src_buf_c16[x].green, 0)) << 5; + res += LV_MAX(dest_buf_c16[x].blue - src_buf_c16[x].blue, 0); + break; + case LV_BLEND_MODE_MULTIPLY: + if(src_buf_u16[x] == 0xffff) continue; /*Do not multiply with pure white (considered as 1)*/ + dest_buf_u16[x] = lv_color_swap_16(dest_buf_u16[x]); + res = ((dest_buf_c16[x].red * src_buf_c16[x].red) >> 5) << 11; + res += ((dest_buf_c16[x].green * src_buf_c16[x].green) >> 6) << 5; + res += (dest_buf_c16[x].blue * src_buf_c16[x].blue) >> 5; + break; + case LV_BLEND_MODE_DIFFERENCE: + dest_buf_u16[x] = lv_color_swap_16(dest_buf_u16[x]); + res = (LV_ABS(dest_buf_c16[x].red - src_buf_c16[x].red)) << 11; + res += (LV_ABS(dest_buf_c16[x].green - src_buf_c16[x].green)) << 5; + res += LV_ABS(dest_buf_c16[x].blue - src_buf_c16[x].blue); + break; + default: + LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); + return; + } + + if(mask_buf == NULL) { + dest_buf_u16[x] = lv_color_swap_16(lv_color_16_16_mix(res, dest_buf_u16[x], opa)); + } + else { + if(opa >= LV_OPA_MAX) dest_buf_u16[x] = lv_color_swap_16(lv_color_16_16_mix(res, dest_buf_u16[x], mask_buf[x])); + else dest_buf_u16[x] = lv_color_swap_16(lv_color_16_16_mix(res, dest_buf_u16[x], LV_OPA_MIX2(mask_buf[x], opa))); + } + } + + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + if(mask_buf) mask_buf += mask_stride; + } + } +} +#endif + +static void LV_ATTRIBUTE_FAST_MEM rgb565_swapped_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 uint16_t * src_buf_u16 = 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_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_SWAPPED(dsc)) { + uint32_t line_in_bytes = w * 2; + for(y = 0; y < h; y++) { + lv_memcpy(dest_buf_u16, src_buf_u16, line_in_bytes); + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + uint16_t px = lv_color_swap_16(dest_buf_u16[x]); + px = lv_color_16_16_mix(lv_color_swap_16(src_buf_u16[x]), px, opa); + dest_buf_u16[x] = lv_color_swap_16(px); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + uint16_t px = lv_color_swap_16(dest_buf_u16[x]); + px = lv_color_16_16_mix(lv_color_swap_16(src_buf_u16[x]), px, mask_buf[x]); + dest_buf_u16[x] = lv_color_swap_16(px); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + mask_buf += mask_stride; + } + } + } + else { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_SWAPPED_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + uint16_t px = lv_color_swap_16(dest_buf_u16[x]); + px = lv_color_16_16_mix(lv_color_swap_16(src_buf_u16[x]), px, LV_OPA_MIX2(mask_buf[x], opa)); + dest_buf_u16[x] = lv_color_swap_16(px); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, 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(x = 0; x < w; x++) { + uint16_t raw; + lv_color16_t src_px; + raw = lv_color_swap_16(src_buf_u16[x]); /* swap byte order */ + lv_memcpy(&src_px, &raw, sizeof(src_px)); + switch(dsc->blend_mode) { + case LV_BLEND_MODE_ADDITIVE: + if(src_buf_u16[x] == 0x0000) continue; /*Do not add pure black*/ + dest_buf_u16[x] = lv_color_swap_16(dest_buf_u16[x]); + res = (LV_MIN(dest_buf_c16[x].red + src_px.red, 31)) << 11; + res += (LV_MIN(dest_buf_c16[x].green + src_px.green, 63)) << 5; + res += LV_MIN(dest_buf_c16[x].blue + src_px.blue, 31); + break; + case LV_BLEND_MODE_SUBTRACTIVE: + if(src_buf_u16[x] == 0x0000) continue; /*Do not subtract pure black*/ + dest_buf_u16[x] = lv_color_swap_16(dest_buf_u16[x]); + res = (LV_MAX(dest_buf_c16[x].red - src_px.red, 0)) << 11; + res += (LV_MAX(dest_buf_c16[x].green - src_px.green, 0)) << 5; + res += LV_MAX(dest_buf_c16[x].blue - src_px.blue, 0); + break; + case LV_BLEND_MODE_MULTIPLY: + if(src_buf_u16[x] == 0xffff) continue; /*Do not multiply with pure white (considered as 1)*/ + dest_buf_u16[x] = lv_color_swap_16(dest_buf_u16[x]); + res = ((dest_buf_c16[x].red * src_px.red) >> 5) << 11; + res += ((dest_buf_c16[x].green * src_px.green) >> 6) << 5; + res += (dest_buf_c16[x].blue * src_px.blue) >> 5; + break; + case LV_BLEND_MODE_DIFFERENCE: + dest_buf_u16[x] = lv_color_swap_16(dest_buf_u16[x]); + res = (LV_ABS(dest_buf_c16[x].red - src_px.red)) << 11; + res += (LV_ABS(dest_buf_c16[x].green - src_px.green)) << 5; + res += LV_ABS(dest_buf_c16[x].blue - src_px.blue); + break; + default: + LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); + return; + } + + if(mask_buf == NULL) { + dest_buf_u16[x] = lv_color_swap_16(lv_color_16_16_mix(res, dest_buf_u16[x], opa)); + } + else { + if(opa >= LV_OPA_MAX) dest_buf_u16[x] = lv_color_swap_16(lv_color_16_16_mix(res, dest_buf_u16[x], mask_buf[x])); + else dest_buf_u16[x] = lv_color_swap_16(lv_color_16_16_mix(res, dest_buf_u16[x], LV_OPA_MIX2(mask_buf[x], opa))); + } + } + + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u16 = drawbuf_next_row(src_buf_u16, src_stride); + if(mask_buf) mask_buf += mask_stride; + } + } +} + +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 + +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; + uint16_t * dest_buf_u16 = 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) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_SWAPPED(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_u16[dest_x] = lv_color_swap_16(((src_buf_u8[src_x + 2] & 0xF8) << 8) + + ((src_buf_u8[src_x + 1] & 0xFC) << 3) + + ((src_buf_u8[src_x + 0] & 0xF8) >> 3)); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA(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_u16[dest_x] = lv_color_swap_16(lv_color_24_16_mix(&src_buf_u8[src_x], lv_color_swap_16(dest_buf_u16[dest_x]), + opa)); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, 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_RGB565_SWAPPED_WITH_MASK(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_u16[dest_x] = lv_color_swap_16(lv_color_24_16_mix(&src_buf_u8[src_x], lv_color_swap_16(dest_buf_u16[dest_x]), + mask_buf[dest_x])); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, 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_RGB565_SWAPPED_MIX_MASK_OPA(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_u16[dest_x] = lv_color_swap_16(lv_color_24_16_mix(&src_buf_u8[src_x], lv_color_swap_16(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_u8 += 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; + lv_draw_sw_rgb565_swap((uint8_t *) dest_buf_u16, w); + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += src_px_size) { + switch(dsc->blend_mode) { + case LV_BLEND_MODE_ADDITIVE: + res = (LV_MIN(dest_buf_c16[dest_x].red + (src_buf_u8[src_x + 2] >> 3), 31)) << 11; + res += (LV_MIN(dest_buf_c16[dest_x].green + (src_buf_u8[src_x + 1] >> 2), 63)) << 5; + res += LV_MIN(dest_buf_c16[dest_x].blue + (src_buf_u8[src_x + 0] >> 3), 31); + break; + case LV_BLEND_MODE_SUBTRACTIVE: + res = (LV_MAX(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 2] >> 3), 0)) << 11; + res += (LV_MAX(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2), 0)) << 5; + res += LV_MAX(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 0] >> 3), 0); + break; + case LV_BLEND_MODE_MULTIPLY: + res = ((dest_buf_c16[dest_x].red * (src_buf_u8[src_x + 2] >> 3)) >> 5) << 11; + res += ((dest_buf_c16[dest_x].green * (src_buf_u8[src_x + 1] >> 2)) >> 6) << 5; + res += (dest_buf_c16[dest_x].blue * (src_buf_u8[src_x + 0] >> 3)) >> 5; + break; + case LV_BLEND_MODE_DIFFERENCE: + res = (LV_ABS(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 2] >> 3))) << 11; + res += (LV_ABS(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2))) << 5; + res += LV_ABS(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 0] >> 3)); + break; + default: + LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); + return; + } + + if(mask_buf == NULL) { + dest_buf_u16[dest_x] = lv_color_swap_16(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_swap_16(lv_color_16_16_mix(res, dest_buf_u16[dest_x], + mask_buf[dest_x])); + else dest_buf_u16[dest_x] = lv_color_swap_16(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_u8 += src_stride; + if(mask_buf) mask_buf += mask_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; + uint16_t * dest_buf_u16 = 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) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_SWAPPED(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 4) { + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_24_16_mix(&src_buf_u8[src_x], lv_color_swap_16(dest_buf_u16[dest_x]), + src_buf_u8[src_x + 3])); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 4) { + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_24_16_mix(&src_buf_u8[src_x], lv_color_swap_16(dest_buf_u16[dest_x]), + LV_OPA_MIX2(src_buf_u8[src_x + 3], + opa))); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 4) { + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_24_16_mix(&src_buf_u8[src_x], lv_color_swap_16(dest_buf_u16[dest_x]), + LV_OPA_MIX2(src_buf_u8[src_x + 3], mask_buf[dest_x]))); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += 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_RGB565_SWAPPED_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 4) { + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_24_16_mix(&src_buf_u8[src_x], lv_color_swap_16(dest_buf_u16[dest_x]), + LV_OPA_MIX3(src_buf_u8[src_x + 3], mask_buf[dest_x], opa))); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += 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; + lv_draw_sw_rgb565_swap((uint8_t *) dest_buf_u16, w); + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 4) { + switch(dsc->blend_mode) { + case LV_BLEND_MODE_ADDITIVE: + res = (LV_MIN(dest_buf_c16[dest_x].red + (src_buf_u8[src_x + 2] >> 3), 31)) << 11; + res += (LV_MIN(dest_buf_c16[dest_x].green + (src_buf_u8[src_x + 1] >> 2), 63)) << 5; + res += LV_MIN(dest_buf_c16[dest_x].blue + (src_buf_u8[src_x + 0] >> 3), 31); + break; + case LV_BLEND_MODE_SUBTRACTIVE: + res = (LV_MAX(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 2] >> 3), 0)) << 11; + res += (LV_MAX(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2), 0)) << 5; + res += LV_MAX(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 0] >> 3), 0); + break; + case LV_BLEND_MODE_MULTIPLY: + res = ((dest_buf_c16[dest_x].red * (src_buf_u8[src_x + 2] >> 3)) >> 5) << 11; + res += ((dest_buf_c16[dest_x].green * (src_buf_u8[src_x + 1] >> 2)) >> 6) << 5; + res += (dest_buf_c16[dest_x].blue * (src_buf_u8[src_x + 0] >> 3)) >> 5; + break; + case LV_BLEND_MODE_DIFFERENCE: + res = (LV_ABS(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 2] >> 3))) << 11; + res += (LV_ABS(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2))) << 5; + res += LV_ABS(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 0] >> 3)); + 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_swap_16(lv_color_16_16_mix(res, dest_buf_u16[dest_x], src_buf_u8[src_x + 3])); + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_16_16_mix(res, dest_buf_u16[dest_x], LV_OPA_MIX2(opa, + src_buf_u8[src_x + 3]))); + } + else { + if(opa >= LV_OPA_MAX) dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_16_16_mix(res, dest_buf_u16[dest_x], + mask_buf[dest_x])); + else dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_16_16_mix(res, dest_buf_u16[dest_x], LV_OPA_MIX3(mask_buf[dest_x], + opa, + src_buf_u8[src_x + 3]))); + } + } + + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + if(mask_buf) mask_buf += mask_stride; + } + } +} + +#endif + +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + +static inline uint16_t LV_ATTRIBUTE_FAST_MEM lv_color_24_16_mix_premult(const uint8_t * c1, uint16_t c2, uint8_t mix) +{ + if(mix == 0) { + return c2; + } + else if(mix == 255) { + return ((c1[2] & 0xF8) << 8) + ((c1[1] & 0xFC) << 3) + ((c1[0] & 0xF8) >> 3); + } + else { + lv_opa_t mix_inv = 255 - mix; + + uint8_t r = (c1[2] >> 3) + ((((c2 >> 11) & 0x1F) * mix_inv) >> 8); + uint8_t g = (c1[1] >> 2) + ((((c2 >> 5) & 0x3F) * mix_inv) >> 8); + uint8_t b = (c1[0] >> 3) + ((((c2 >> 0) & 0x1F) * mix_inv) >> 8); + + return (r << 11) + (g << 5) + (b); + } +} + +static void LV_ATTRIBUTE_FAST_MEM argb8888_premultiplied_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_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) { + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_SWAPPED(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 4) { + /*For the trivial case use the premultipled image as it is. + *For the other cases unpremultiply as another alpha also needs to be applied.*/ + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_24_16_mix_premult(&src_buf_u8[src_x], + lv_color_swap_16(dest_buf_u16[dest_x]), src_buf_u8[src_x + 3])); + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + } + } + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 4) { + if(src_buf_u8[src_x + 3] > 0) { + uint8_t src_buf_u8_unpremult[3]; + uint16_t reciprocal = (255 * 256) / src_buf_u8[src_x + 3]; + src_buf_u8_unpremult[0] = (src_buf_u8[src_x + 0] * reciprocal) >> 8; + src_buf_u8_unpremult[1] = (src_buf_u8[src_x + 1] * reciprocal) >> 8; + src_buf_u8_unpremult[2] = (src_buf_u8[src_x + 2] * reciprocal) >> 8; + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_24_16_mix(src_buf_u8_unpremult, lv_color_swap_16(dest_buf_u16[dest_x]), + LV_OPA_MIX2(src_buf_u8[src_x + 3], opa))); + } + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + } + } + } + else if(mask_buf && opa >= LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_SWAPPED_WITH_MASK(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 4) { + if(src_buf_u8[src_x + 3] > 0) { + uint8_t src_buf_u8_unpremult[3]; + uint16_t reciprocal = (255 * 256) / src_buf_u8[src_x + 3]; + src_buf_u8_unpremult[0] = (src_buf_u8[src_x + 0] * reciprocal) >> 8; + src_buf_u8_unpremult[1] = (src_buf_u8[src_x + 1] * reciprocal) >> 8; + src_buf_u8_unpremult[2] = (src_buf_u8[src_x + 2] * reciprocal) >> 8; + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_24_16_mix(src_buf_u8_unpremult, lv_color_swap_16(dest_buf_u16[dest_x]), + LV_OPA_MIX2(src_buf_u8[src_x + 3], mask_buf[dest_x]))); + } + + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + mask_buf += mask_stride; + } + } + } + else if(mask_buf && opa < LV_OPA_MAX) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB565_SWAPPED_MIX_MASK_OPA(dsc)) { + for(y = 0; y < h; y++) { + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 4) { + if(src_buf_u8[src_x + 3] > 0) { + uint8_t src_buf_u8_unpremult[3]; + uint16_t reciprocal = (255 * 256) / src_buf_u8[src_x + 3]; + src_buf_u8_unpremult[0] = (src_buf_u8[src_x + 0] * reciprocal) >> 8; + src_buf_u8_unpremult[1] = (src_buf_u8[src_x + 1] * reciprocal) >> 8; + src_buf_u8_unpremult[2] = (src_buf_u8[src_x + 2] * reciprocal) >> 8; + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_24_16_mix(src_buf_u8_unpremult, lv_color_swap_16(dest_buf_u16[dest_x]), + LV_OPA_MIX3(src_buf_u8[src_x + 3], mask_buf[dest_x], opa))); + } + } + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += 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; + lv_draw_sw_rgb565_swap((uint8_t *) dest_buf_u16, w); + for(dest_x = 0, src_x = 0; dest_x < w; dest_x++, src_x += 4) { + switch(dsc->blend_mode) { + case LV_BLEND_MODE_ADDITIVE: + res = (LV_MIN(dest_buf_c16[dest_x].red + (src_buf_u8[src_x + 2] >> 3), 31)) << 11; + res += (LV_MIN(dest_buf_c16[dest_x].green + (src_buf_u8[src_x + 1] >> 2), 63)) << 5; + res += LV_MIN(dest_buf_c16[dest_x].blue + (src_buf_u8[src_x + 0] >> 3), 31); + break; + case LV_BLEND_MODE_SUBTRACTIVE: + res = (LV_MAX(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 2] >> 3), 0)) << 11; + res += (LV_MAX(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2), 0)) << 5; + res += LV_MAX(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 0] >> 3), 0); + break; + case LV_BLEND_MODE_MULTIPLY: + res = ((dest_buf_c16[dest_x].red * (src_buf_u8[src_x + 2] >> 3)) >> 5) << 11; + res += ((dest_buf_c16[dest_x].green * (src_buf_u8[src_x + 1] >> 2)) >> 6) << 5; + res += (dest_buf_c16[dest_x].blue * (src_buf_u8[src_x + 0] >> 3)) >> 5; + break; + case LV_BLEND_MODE_DIFFERENCE: + res = (LV_ABS(dest_buf_c16[dest_x].red - (src_buf_u8[src_x + 2] >> 3))) << 11; + res += (LV_ABS(dest_buf_c16[dest_x].green - (src_buf_u8[src_x + 1] >> 2))) << 5; + res += LV_ABS(dest_buf_c16[dest_x].blue - (src_buf_u8[src_x + 0] >> 3)); + break; + default: + LV_LOG_WARN("Not supported blend mode: %d", dsc->blend_mode); + return; + } + + if(mask_buf == NULL && opa >= LV_OPA_MAX) { + /* Blending premultiplied ARGB8888 to RGB565 with no mask and full opacity */ + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_16_16_mix(res, dest_buf_u16[dest_x], src_buf_u8[src_x + 3])); + } + else if(mask_buf == NULL && opa < LV_OPA_MAX) { + /* Blending premultiplied ARGB8888 to RGB565 with no mask and partial opacity */ + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_16_16_mix(res, dest_buf_u16[dest_x], LV_OPA_MIX2(opa, + src_buf_u8[src_x + 3]))); + } + else { + if(opa >= LV_OPA_MAX) + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_16_16_mix(res, dest_buf_u16[dest_x], mask_buf[dest_x])); + else + dest_buf_u16[dest_x] = lv_color_swap_16(lv_color_16_16_mix(res, dest_buf_u16[dest_x], LV_OPA_MIX3(mask_buf[dest_x], opa, + src_buf_u8[src_x + 3]))); + } + } + + dest_buf_u16 = drawbuf_next_row(dest_buf_u16, dest_stride); + src_buf_u8 += src_stride; + if(mask_buf) mask_buf += mask_stride; + } + } +} + +#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) { + return c2; + } + else if(mix == 255) { + return ((c1[2] & 0xF8) << 8) + ((c1[1] & 0xFC) << 3) + ((c1[0] & 0xF8) >> 3); + } + else { + lv_opa_t mix_inv = 255 - mix; + + return ((((c1[2] >> 3) * mix + ((c2 >> 11) & 0x1F) * mix_inv) << 3) & 0xF800) + + ((((c1[1] >> 2) * mix + ((c2 >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0) + + (((c1[0] >> 3) * mix + (c2 & 0x1F) * 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 drawbuf_next_row(const void * buf, uint32_t stride) +{ + return (void *)((uint8_t *)buf + stride); +} + +#endif /*LV_DRAW_SW_SUPPORT_RGB565_SWAPPED*/ + +#endif /*LV_USE_DRAW_SW*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565_swapped.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565_swapped.h new file mode 100644 index 000000000..475b765d2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb565_swapped.h @@ -0,0 +1,45 @@ +/** + * @file lv_draw_sw_blend_to_rgb565_swapped.h + * + */ + +#ifndef LV_DRAW_SW_BLEND_TO_RGB565_SWAPPED_H +#define LV_DRAW_SW_BLEND_TO_RGB565_SWAPPED_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_rgb565_swapped(lv_draw_sw_blend_fill_dsc_t * dsc); + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_blend_image_to_rgb565_swapped(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_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 e29e934c1..a99d4bce4 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,7 @@ #include "lv_draw_sw_blend_to_rgb888.h" #if LV_USE_DRAW_SW -#if LV_DRAW_SW_SUPPORT_RGB888 +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 #include "lv_draw_sw_blend_private.h" #include "../../../misc/lv_math.h" @@ -65,12 +65,18 @@ static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_image_blend(lv_draw_sw_blend_im uint32_t dest_px_size); #endif +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED +static void /* LV_ATTRIBUTE_FAST_MEM */ argb8888_premultiplied_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); 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); /********************** @@ -161,6 +167,22 @@ 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_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB888 + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB888(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB888_WITH_OPA + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB888_WITH_OPA(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB888_WITH_MASK + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB888_WITH_MASK(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_BLEND_NORMAL_TO_RGB888_MIX_MASK_OPA + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_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 @@ -284,6 +306,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_rgb888(lv_draw_sw_blend_fil for(x = 0, mask_x = 0; x < w; x += dest_px_size, mask_x++) { lv_color_24_24_mix((const uint8_t *)&color32, &dest_buf[x], mask[mask_x]); } + dest_buf += dest_stride; mask += mask_stride; } @@ -310,7 +333,6 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_color_to_rgb888(lv_draw_sw_blend_fil 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: @@ -330,6 +352,11 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_blend_image_to_rgb888(lv_draw_sw_blend_ima argb8888_image_blend(dsc, dest_px_size); break; #endif +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + case LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED: + argb8888_premultiplied_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); @@ -903,6 +930,138 @@ static void LV_ATTRIBUTE_FAST_MEM argb8888_image_blend(lv_draw_sw_blend_image_ds #endif +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + +static inline void LV_ATTRIBUTE_FAST_MEM lv_color_24_24_mix_premult(const uint8_t * src, uint8_t * dest, uint8_t mix) +{ + if(mix == 0) return; + + if(mix >= LV_OPA_MAX) { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + } + else { + lv_opa_t mix_inv = 255 - mix; + dest[0] = (uint32_t)src[0] + ((uint32_t)(dest[0] * mix_inv) >> 8); + dest[1] = (uint32_t)src[1] + ((uint32_t)(dest[1] * mix_inv) >> 8); + dest[2] = (uint32_t)src[2] + ((uint32_t)(dest[2] * mix_inv) >> 8); + } +} + +static void LV_ATTRIBUTE_FAST_MEM argb8888_premultiplied_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 = 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 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_ARGB8888_PREMULTIPLIED_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++) { + /*For the trivial case use the premultipled image as it is. + *For the other cases unpremultiply as another alpha also needs to be applied.*/ + lv_color_24_24_mix_premult((const uint8_t *)&src_buf_c32[src_x], &dest_buf[dest_x], src_buf_c32[src_x].alpha); + } + dest_buf += 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_PREMULTIPLIED_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_color32_t src_pixel = src_buf_c32[src_x]; + if(src_pixel.alpha > 0) { + uint16_t reciprocal = (255 * 256) / src_pixel.alpha; + src_pixel.red = (src_pixel.red * reciprocal) >> 8; + src_pixel.green = (src_pixel.green * reciprocal) >> 8; + src_pixel.blue = (src_pixel.blue * reciprocal) >> 8; + lv_color_24_24_mix((const uint8_t *)&src_pixel, &dest_buf[dest_x], LV_OPA_MIX2(src_pixel.alpha, opa)); + } + } + dest_buf += 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_PREMULTIPLIED_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_color32_t src_pixel = src_buf_c32[src_x]; + if(src_pixel.alpha > 0) { + uint16_t reciprocal = (255 * 256) / src_pixel.alpha; + src_pixel.red = (src_pixel.red * reciprocal) >> 8; + src_pixel.green = (src_pixel.green * reciprocal) >> 8; + src_pixel.blue = (src_pixel.blue * reciprocal) >> 8; + lv_color_24_24_mix((const uint8_t *)&src_pixel, &dest_buf[dest_x], LV_OPA_MIX2(src_pixel.alpha, mask_buf[src_x])); + } + } + dest_buf += 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_PREMULTIPLIED_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_color32_t src_pixel = src_buf_c32[src_x]; + if(src_pixel.alpha > 0) { + uint16_t reciprocal = (255 * 256) / src_pixel.alpha; + src_pixel.red = (src_pixel.red * reciprocal) >> 8; + src_pixel.green = (src_pixel.green * reciprocal) >> 8; + src_pixel.blue = (src_pixel.blue * reciprocal) >> 8; + lv_color_24_24_mix((const uint8_t *)&src_pixel, &dest_buf[dest_x], LV_OPA_MIX3(src_pixel.alpha, mask_buf[src_x], opa)); + } + } + dest_buf += dest_stride; + src_buf_c32 = drawbuf_next_row(src_buf_c32, 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 = src_buf_c32[src_x]; + if(src_argb.alpha > 0) { + uint16_t reciprocal = (255 * 256) / src_argb.alpha; + src_argb.red = (src_argb.red * reciprocal) >> 8; + src_argb.green = (src_argb.green * reciprocal) >> 8; + src_argb.blue = (src_argb.blue * reciprocal) >> 8; + } + if(mask_buf == NULL) src_argb.alpha = LV_OPA_MIX2(src_argb.alpha, opa); + else src_argb.alpha = LV_OPA_MIX3(src_argb.alpha, mask_buf[dest_x], opa); + + blend_non_normal_pixel(&dest_buf[dest_x], src_argb, dsc->blend_mode); + } + if(mask_buf) mask_buf += mask_stride; + dest_buf += dest_stride; + src_buf_c32 = drawbuf_next_row(src_buf_c32, src_stride); + } + } +} + +#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}; @@ -922,6 +1081,11 @@ static inline void LV_ATTRIBUTE_FAST_MEM blend_non_normal_pixel(uint8_t * dest, res[1] = (dest[1] * src.green) >> 8; res[2] = (dest[2] * src.red) >> 8; break; + case LV_BLEND_MODE_DIFFERENCE: + res[0] = LV_ABS((int16_t)dest[0] - src.blue); + res[1] = LV_ABS((int16_t)dest[1] - src.green); + res[2] = LV_ABS((int16_t)dest[2] - src.red); + break; default: LV_LOG_WARN("Not supported blend mode: %d", mode); return; @@ -974,12 +1138,11 @@ static inline uint8_t LV_ATTRIBUTE_FAST_MEM get_bit(const uint8_t * buf, int32_t #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 /*LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888*/ -#endif +#endif /*LV_USE_DRAW_SW*/ 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 e82120440..83480c554 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 @@ -9,13 +9,18 @@ #include "lv_blend_neon.h" + +/*Workaround: missing .note.GNU-stack section implies executable stack*/ +#ifdef __ELF__ +.section .note.GNU-stack,"",%progbits +#endif /* __ELF__ */ + #if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON .text .fpu neon .arch armv7a .syntax unified -.altmacro .p2align 2 @ d0 ~ d3 : src B,G,R,A @@ -70,249 +75,263 @@ TMP_Q1 .qn q14 OPA .dn d31 .macro convert reg, bpp, intlv -.if bpp >= 31 - .if intlv - vzip.8 reg&_B, reg&_R @ BRBRBRBR GGGGGGGG BRBRBRBR AAAAAAAA - vzip.8 reg&_G, reg&_A @ BRBRBRBR GAGAGAGA BRBRBRBR GAGAGAGA - vzip.8 reg&_R, reg&_A @ BRBRBRBR GAGAGAGA BGRABGRA BGRABGRA - vzip.8 reg&_B, reg&_G @ BGRABGRA BGRABGRA BGRABGRA BGRABGRA +.if \bpp >= 31 + .if \intlv + vzip.8 \reg\()_B, \reg\()_R @ BRBRBRBR GGGGGGGG BRBRBRBR AAAAAAAA + vzip.8 \reg\()_G, \reg\()_A @ BRBRBRBR GAGAGAGA BRBRBRBR GAGAGAGA + vzip.8 \reg\()_R, \reg\()_A @ BRBRBRBR GAGAGAGA BGRABGRA BGRABGRA + vzip.8 \reg\()_B, \reg\()_G @ BGRABGRA BGRABGRA BGRABGRA BGRABGRA .else - vuzp.8 reg&_B, reg&_G @ BRBRBRBR GAGAGAGA BGRABGRA BGRABGRA - vuzp.8 reg&_R, reg&_A @ BRBRBRBR GAGAGAGA BRBRBRBR GAGAGAGA - vuzp.8 reg&_G, reg&_A @ BRBRBRBR GGGGGGGG BRBRBRBR AAAAAAAA - vuzp.8 reg&_B, reg&_R @ BBBBBBBB GGGGGGGG RRRRRRRR AAAAAAAA + vuzp.8 \reg\()_B, \reg\()_G @ BRBRBRBR GAGAGAGA BGRABGRA BGRABGRA + vuzp.8 \reg\()_R, \reg\()_A @ BRBRBRBR GAGAGAGA BRBRBRBR GAGAGAGA + vuzp.8 \reg\()_G, \reg\()_A @ BRBRBRBR GGGGGGGG BRBRBRBR AAAAAAAA + vuzp.8 \reg\()_B, \reg\()_R @ BBBBBBBB GGGGGGGG RRRRRRRR AAAAAAAA .endif -.elseif bpp == 24 - .if intlv @ for init only (same B,G,R for all channel) - vzip.8 reg&_B, reg&_G @ BGBGBGBG BGBGBGBG RRRRRRRR - vzip.16 reg&_B, reg&_R @ BGRRBGRR BGBGBGBG BGRRBGRR - vsli.64 reg&_8888_L, reg&_8888_L, #24 @ BGRBGRRB BGBBGBGB - vsli.64 reg&_B, reg&_G, #48 @ BGRBGRBG - vsri.64 reg&_R, reg&_B, #8 @ GRBGRBGR - vsri.64 reg&_G, reg&_R, #8 @ RBGRBGRB +.elseif \bpp == 24 + .if \intlv @ for init only (same B,G,R for all channel) + vzip.8 \reg\()_B, \reg\()_G @ BGBGBGBG BGBGBGBG RRRRRRRR + vzip.16 \reg\()_B, \reg\()_R @ BGRRBGRR BGBGBGBG BGRRBGRR + vsli.64 \reg\()_8888_L, \reg\()_8888_L, #24 @ BGRBGRRB BGBBGBGB + vsli.64 \reg\()_B, \reg\()_G, #48 @ BGRBGRBG + vsri.64 \reg\()_R, \reg\()_B, #8 @ GRBGRBGR + vsri.64 \reg\()_G, \reg\()_R, #8 @ RBGRBGRB .endif -.elseif bpp == 16 - .if intlv - vshll.u8 reg&_565, reg&_R, #8 @ RRRrrRRR 00000000 - vshll.u8 TMP_Q0, reg&_G, #8 @ GGGgggGG 00000000 - vshll.u8 TMP_Q1, reg&_B, #8 @ BBBbbBBB 00000000 - vsri.16 reg&_565, TMP_Q0, #5 @ RRRrrGGG gggGG000 - vsri.16 reg&_565, TMP_Q1, #11 @ RRRrrGGG gggBBBbb +.elseif \bpp == 16 + .if \intlv + vshll.u8 \reg\()_565, \reg\()_R, #8 @ RRRrrRRR 00000000 + vshll.u8 TMP_Q0, \reg\()_G, #8 @ GGGgggGG 00000000 + vshll.u8 TMP_Q1, \reg\()_B, #8 @ BBBbbBBB 00000000 + vsri.16 \reg\()_565, TMP_Q0, #5 @ RRRrrGGG gggGG000 + vsri.16 \reg\()_565, TMP_Q1, #11 @ RRRrrGGG gggBBBbb .else - vshr.u8 TMP_Q0, reg&_565, #3 @ 000RRRrr 000gggBB - vshrn.i16 reg&_G, reg&_565, #5 @ rrGGGggg - vshrn.i16 reg&_R, TMP_Q0, #5 @ RRRrr000 - vshl.i8 reg&_G, reg&_G, #2 @ GGGggg00 - vshl.i16 TMP_Q1, reg&_565, #3 @ rrGGGggg BBBbb000 - vsri.8 reg&_R, reg&_R, #5 @ RRRrrRRR - vmovn.i16 reg&_B, TMP_Q1 @ BBBbb000 - vsri.8 reg&_G, reg&_G, #6 @ GGGgggGG - vsri.8 reg&_B, reg&_B, #5 @ BBBbbBBB + vshr.u8 TMP_Q0, \reg\()_565, #3 @ 000RRRrr 000gggBB + vshrn.i16 \reg\()_G, \reg\()_565, #5 @ rrGGGggg + vshrn.i16 \reg\()_R, TMP_Q0, #5 @ RRRrr000 + vshl.i8 \reg\()_G, \reg\()_G, #2 @ GGGggg00 + vshl.i16 TMP_Q1, \reg\()_565, #3 @ rrGGGggg BBBbb000 + vsri.8 \reg\()_R, \reg\()_R, #5 @ RRRrrRRR + vmovn.i16 \reg\()_B, TMP_Q1 @ BBBbb000 + vsri.8 \reg\()_G, \reg\()_G, #6 @ GGGgggGG + vsri.8 \reg\()_B, \reg\()_B, #5 @ BBBbbBBB .endif .endif .endm .macro ldst op, bpp, len, mem, reg, cvt, wb -.if bpp >= 31 - .if len == 8 - .if cvt - v&op&4.8 {reg&_B, reg&_G, reg&_R, reg&_A}, [mem&_ADDR]&wb +.if \bpp >= 31 + .if \len == 8 + .if \cvt + v\op\()4.8 {\reg\()_B, \reg\()_G, \reg\()_R, \reg\()_A}, [\mem\()_ADDR]\wb .else - v&op&1.32 {reg&_8888_L, reg&_8888_H}, [mem&_ADDR]&wb + v\op\()1.32 {\reg\()_8888_L, \reg\()_8888_H}, [\mem\()_ADDR]\wb .endif .else - .if (op == st) && cvt - convert reg, bpp, 1 + .ifc \op,st + .if \cvt + convert \reg, \bpp, 1 + .endif .endif - .if len == 7 - v&op&1.32 {reg&_8888_L}, [mem&_ADDR]! - v&op&1.32 {reg&_R}, [mem&_ADDR]! - v&op&1.32 {reg&_A[0]}, [mem&_ADDR]! - .elseif len == 6 - v&op&1.32 {reg&_8888_L}, [mem&_ADDR]! - v&op&1.32 {reg&_R}, [mem&_ADDR]! - .elseif len == 5 - v&op&1.32 {reg&_8888_L}, [mem&_ADDR]! - v&op&1.32 {reg&_R[0]}, [mem&_ADDR]! - .elseif len == 4 - v&op&1.32 {reg&_8888_L}, [mem&_ADDR]&wb - .elseif len == 3 - v&op&1.32 {reg&_B}, [mem&_ADDR]! - v&op&1.32 {reg&_G[0]}, [mem&_ADDR]! - .elseif len == 2 - v&op&1.32 {reg&_B}, [mem&_ADDR]&wb - .elseif len == 1 - v&op&1.32 {reg&_B[0]}, [mem&_ADDR]&wb + .if \len == 7 + v\op\()1.32 {\reg\()_8888_L}, [\mem\()_ADDR]! + v\op\()1.32 {\reg\()_R}, [\mem\()_ADDR]! + v\op\()1.32 {\reg\()_A[0]}, [\mem\()_ADDR]! + .elseif \len == 6 + v\op\()1.32 {\reg\()_8888_L}, [\mem\()_ADDR]! + v\op\()1.32 {\reg\()_R}, [\mem\()_ADDR]! + .elseif \len == 5 + v\op\()1.32 {\reg\()_8888_L}, [\mem\()_ADDR]! + v\op\()1.32 {\reg\()_R[0]}, [\mem\()_ADDR]! + .elseif \len == 4 + v\op\()1.32 {\reg\()_8888_L}, [\mem\()_ADDR]\wb + .elseif \len == 3 + v\op\()1.32 {\reg\()_B}, [\mem\()_ADDR]! + v\op\()1.32 {\reg\()_G[0]}, [\mem\()_ADDR]! + .elseif \len == 2 + v\op\()1.32 {\reg\()_B}, [\mem\()_ADDR]\wb + .elseif \len == 1 + v\op\()1.32 {\reg\()_B[0]}, [\mem\()_ADDR]\wb .else .error "[32bpp]len should be 1~8" .endif - .if (op == ld) && cvt - convert reg, bpp, 0 + .ifc \op,ld + .if \cvt + convert \reg, \bpp, 0 + .endif .endif - .if (wb&1) && (len != 4) && (len != 2) && (len != 1) - sub mem&_ADDR, #4*len + .ifb \wb + .if (\len != 4) && (\len != 2) && (\len != 1) + sub \mem\()_ADDR, #4*\len + .endif .endif .endif -.elseif bpp == 24 - .if len == 8 - .if cvt - v&op&3.8 {reg&_B, reg&_G, reg&_R}, [mem&_ADDR]&wb +.elseif \bpp == 24 + .if \len == 8 + .if \cvt + v\op\()3.8 {\reg\()_B, \reg\()_G, \reg\()_R}, [\mem\()_ADDR]\wb .else - v&op&1.8 {reg&_B, reg&_G, reg&_R}, [mem&_ADDR]&wb + v\op\()1.8 {\reg\()_B, \reg\()_G, \reg\()_R}, [\mem\()_ADDR]\wb .endif - .elseif (len < 8) && (len > 0) - .if cvt - v&op&3.8 {reg&_B[0], reg&_G[0], reg&_R[0]}, [mem&_ADDR]! - .if len > 1 - v&op&3.8 {reg&_B[1], reg&_G[1], reg&_R[1]}, [mem&_ADDR]! + .elseif (\len < 8) && (\len > 0) + .if \cvt + v\op\()3.8 {\reg\()_B[0], \reg\()_G[0], \reg\()_R[0]}, [\mem\()_ADDR]! + .if \len > 1 + v\op\()3.8 {\reg\()_B[1], \reg\()_G[1], \reg\()_R[1]}, [\mem\()_ADDR]! .endif - .if len > 2 - v&op&3.8 {reg&_B[2], reg&_G[2], reg&_R[2]}, [mem&_ADDR]! + .if \len > 2 + v\op\()3.8 {\reg\()_B[2], \reg\()_G[2], \reg\()_R[2]}, [\mem\()_ADDR]! .endif - .if len > 3 - v&op&3.8 {reg&_B[3], reg&_G[3], reg&_R[3]}, [mem&_ADDR]! + .if \len > 3 + v\op\()3.8 {\reg\()_B[3], \reg\()_G[3], \reg\()_R[3]}, [\mem\()_ADDR]! .endif - .if len > 4 - v&op&3.8 {reg&_B[4], reg&_G[4], reg&_R[4]}, [mem&_ADDR]! + .if \len > 4 + v\op\()3.8 {\reg\()_B[4], \reg\()_G[4], \reg\()_R[4]}, [\mem\()_ADDR]! .endif - .if len > 5 - v&op&3.8 {reg&_B[5], reg&_G[5], reg&_R[5]}, [mem&_ADDR]! + .if \len > 5 + v\op\()3.8 {\reg\()_B[5], \reg\()_G[5], \reg\()_R[5]}, [\mem\()_ADDR]! .endif - .if len > 6 - v&op&3.8 {reg&_B[6], reg&_G[6], reg&_R[6]}, [mem&_ADDR]! + .if \len > 6 + v\op\()3.8 {\reg\()_B[6], \reg\()_G[6], \reg\()_R[6]}, [\mem\()_ADDR]! .endif - .if wb&1 - sub mem&_ADDR, #3*len + .ifb \wb + sub \mem\()_ADDR, #3*\len .endif .else - .if len == 7 - v&op&1.32 {reg&_8888_L}, [mem&_ADDR]! - v&op&1.32 {reg&_R[0]}, [mem&_ADDR]! - v&op&1.8 {reg&_R[4]}, [mem&_ADDR]! - .elseif len == 6 - v&op&1.32 {reg&_8888_L}, [mem&_ADDR]! - v&op&1.16 {reg&_R[0]}, [mem&_ADDR]! - .elseif len == 5 - v&op&1.32 {reg&_B}, [mem&_ADDR]! - v&op&1.32 {reg&_G[0]}, [mem&_ADDR]! - v&op&1.16 {reg&_G[2]}, [mem&_ADDR]! - v&op&1.8 {reg&_G[6]}, [mem&_ADDR]! - .elseif len == 4 - v&op&1.32 {reg&_B}, [mem&_ADDR]! - v&op&1.32 {reg&_G[0]}, [mem&_ADDR]! - .elseif len == 3 - v&op&1.32 {reg&_B}, [mem&_ADDR]! - v&op&1.8 {reg&_G[0]}, [mem&_ADDR]! - .elseif len == 2 - v&op&1.32 {reg&_B[0]}, [mem&_ADDR]! - v&op&1.16 {reg&_B[2]}, [mem&_ADDR]! - .elseif len == 1 - v&op&1.16 {reg&_B[0]}, [mem&_ADDR]! - v&op&1.8 {reg&_B[2]}, [mem&_ADDR]! + .if \len == 7 + v\op\()1.32 {\reg\()_8888_L}, [\mem\()_ADDR]! + v\op\()1.32 {\reg\()_R[0]}, [\mem\()_ADDR]! + v\op\()1.8 {\reg\()_R[4]}, [\mem\()_ADDR]! + .elseif \len == 6 + v\op\()1.32 {\reg\()_8888_L}, [\mem\()_ADDR]! + v\op\()1.16 {\reg\()_R[0]}, [\mem\()_ADDR]! + .elseif \len == 5 + v\op\()1.32 {\reg\()_B}, [\mem\()_ADDR]! + v\op\()1.32 {\reg\()_G[0]}, [\mem\()_ADDR]! + v\op\()1.16 {\reg\()_G[2]}, [\mem\()_ADDR]! + v\op\()1.8 {\reg\()_G[6]}, [\mem\()_ADDR]! + .elseif \len == 4 + v\op\()1.32 {\reg\()_B}, [\mem\()_ADDR]! + v\op\()1.32 {\reg\()_G[0]}, [\mem\()_ADDR]! + .elseif \len == 3 + v\op\()1.32 {\reg\()_B}, [\mem\()_ADDR]! + v\op\()1.8 {\reg\()_G[0]}, [\mem\()_ADDR]! + .elseif \len == 2 + v\op\()1.32 {\reg\()_B[0]}, [\mem\()_ADDR]! + v\op\()1.16 {\reg\()_B[2]}, [\mem\()_ADDR]! + .elseif \len == 1 + v\op\()1.16 {\reg\()_B[0]}, [\mem\()_ADDR]! + v\op\()1.8 {\reg\()_B[2]}, [\mem\()_ADDR]! .endif - .if wb&1 - sub mem&_ADDR, #3*len + .ifb \wb + sub \mem\()_ADDR, #3*\len .endif .endif .else .error "[24bpp]len should be 1~8" .endif -.elseif bpp == 16 - .if (op == st) && cvt - convert reg, bpp, 1 +.elseif \bpp == 16 + .ifc \op,st + .if \cvt + convert \reg, \bpp, 1 + .endif .endif - .if len == 8 - v&op&1.16 {reg&_565}, [mem&_ADDR]&wb - .elseif len == 7 - v&op&1.16 {reg&_565_L}, [mem&_ADDR]! - v&op&1.32 {reg&_565_H[0]}, [mem&_ADDR]! - v&op&1.16 {reg&_565_H[2]}, [mem&_ADDR]! - .if wb&1 - sub mem&_ADDR, #14 + .if \len == 8 + v\op\()1.16 {\reg\()_565}, [\mem\()_ADDR]\wb + .elseif \len == 7 + v\op\()1.16 {\reg\()_565_L}, [\mem\()_ADDR]! + v\op\()1.32 {\reg\()_565_H[0]}, [\mem\()_ADDR]! + v\op\()1.16 {\reg\()_565_H[2]}, [\mem\()_ADDR]! + .ifb \wb + sub \mem\()_ADDR, #14 .endif - .elseif len == 6 - v&op&1.16 {reg&_565_L}, [mem&_ADDR]! - v&op&1.32 {reg&_565_H[0]}, [mem&_ADDR]! - .if wb&1 - sub mem&_ADDR, #12 + .elseif \len == 6 + v\op\()1.16 {\reg\()_565_L}, [\mem\()_ADDR]! + v\op\()1.32 {\reg\()_565_H[0]}, [\mem\()_ADDR]! + .ifb \wb + sub \mem\()_ADDR, #12 .endif - .elseif len == 5 - v&op&1.16 {reg&_565_L}, [mem&_ADDR]! - v&op&1.16 {reg&_565_H[0]}, [mem&_ADDR]! - .if wb&1 - sub mem&_ADDR, #10 + .elseif \len == 5 + v\op\()1.16 {\reg\()_565_L}, [\mem\()_ADDR]! + v\op\()1.16 {\reg\()_565_H[0]}, [\mem\()_ADDR]! + .ifb \wb + sub \mem\()_ADDR, #10 .endif - .elseif len == 4 - v&op&1.16 {reg&_565_L}, [mem&_ADDR]&wb - .elseif len == 3 - v&op&1.32 {reg&_565_L[0]}, [mem&_ADDR]! - v&op&1.16 {reg&_565_L[2]}, [mem&_ADDR]! - .if wb&1 - sub mem&_ADDR, #6 + .elseif \len == 4 + v\op\()1.16 {\reg\()_565_L}, [\mem\()_ADDR]\wb + .elseif \len == 3 + v\op\()1.32 {\reg\()_565_L[0]}, [\mem\()_ADDR]! + v\op\()1.16 {\reg\()_565_L[2]}, [\mem\()_ADDR]! + .ifb \wb + sub \mem\()_ADDR, #6 .endif - .elseif len == 2 - v&op&1.32 {reg&_565_L[0]}, [mem&_ADDR]&wb - .elseif len == 1 - v&op&1.16 {reg&_565_L[0]}, [mem&_ADDR]&wb + .elseif \len == 2 + v\op\()1.32 {\reg\()_565_L[0]}, [\mem\()_ADDR]\wb + .elseif \len == 1 + v\op\()1.16 {\reg\()_565_L[0]}, [\mem\()_ADDR]\wb .else .error "[16bpp]len should be 1~8" .endif - .if (op == ld) && cvt - convert reg, bpp, 0 + .ifc \op,ld + .if \cvt + convert \reg, \bpp, 0 + .endif .endif -.elseif bpp == 8 - .if len == 8 - v&op&1.8 {reg&_A}, [mem&_ADDR]&wb - .elseif len == 7 - v&op&1.32 {reg&_A[0]}, [mem&_ADDR]! - v&op&1.16 {reg&_A[2]}, [mem&_ADDR]! - v&op&1.8 {reg&_A[6]}, [mem&_ADDR]! - .if wb&1 - sub mem&_ADDR, #7 +.elseif \bpp == 8 + .if \len == 8 + v\op\()1.8 {\reg\()_A}, [\mem\()_ADDR]\wb + .elseif \len == 7 + v\op\()1.32 {\reg\()_A[0]}, [\mem\()_ADDR]! + v\op\()1.16 {\reg\()_A[2]}, [\mem\()_ADDR]! + v\op\()1.8 {\reg\()_A[6]}, [\mem\()_ADDR]! + .ifb \wb + sub \mem\()_ADDR, #7 .endif - .elseif len == 6 - v&op&1.32 {reg&_A[0]}, [mem&_ADDR]! - v&op&1.16 {reg&_A[2]}, [mem&_ADDR]! - .if wb&1 - sub mem&_ADDR, #6 + .elseif \len == 6 + v\op\()1.32 {\reg\()_A[0]}, [\mem\()_ADDR]! + v\op\()1.16 {\reg\()_A[2]}, [\mem\()_ADDR]! + .ifb \wb + sub \mem\()_ADDR, #6 .endif - .elseif len == 5 - v&op&1.32 {reg&_A[0]}, [mem&_ADDR]! - v&op&1.8 {reg&_A[4]}, [mem&_ADDR]! - .if wb&1 - sub mem&_ADDR, #5 + .elseif \len == 5 + v\op\()1.32 {\reg\()_A[0]}, [\mem\()_ADDR]! + v\op\()1.8 {\reg\()_A[4]}, [\mem\()_ADDR]! + .ifb \wb + sub \mem\()_ADDR, #5 .endif - .elseif len == 4 - v&op&1.32 {reg&_A[0]}, [mem&_ADDR]&wb - .elseif len == 3 - v&op&1.16 {reg&_A[0]}, [mem&_ADDR]! - v&op&1.8 {reg&_A[2]}, [mem&_ADDR]! - .if wb&1 - sub mem&_ADDR, #3 + .elseif \len == 4 + v\op\()1.32 {\reg\()_A[0]}, [\mem\()_ADDR]\wb + .elseif \len == 3 + v\op\()1.16 {\reg\()_A[0]}, [\mem\()_ADDR]! + v\op\()1.8 {\reg\()_A[2]}, [\mem\()_ADDR]! + .ifb \wb + sub \mem\()_ADDR, #3 .endif - .elseif len == 2 - v&op&1.16 {reg&_A[0]}, [mem&_ADDR]&wb - .elseif len == 1 - v&op&1.8 {reg&_A[0]}, [mem&_ADDR]&wb + .elseif \len == 2 + v\op\()1.16 {\reg\()_A[0]}, [\mem\()_ADDR]\wb + .elseif \len == 1 + v\op\()1.8 {\reg\()_A[0]}, [\mem\()_ADDR]\wb .else .error "[8bpp]len should be 1~8" .endif -.elseif (bpp == 0) && wb&1 - .if len == 8 - v&op&3.8 {reg&_B[], reg&_G[], reg&_R[]}, [mem&_ADDR] - .else - .error "[color]len should be 8" +.elseif \bpp == 0 + .ifb \wb + .if \len == 8 + v\op\()3.8 {\reg\()_B[], \reg\()_G[], \reg\()_R[]}, [\mem\()_ADDR] + .else + .error "[color]len should be 8" + .endif .endif .endif -.if (op == ld) && cvt && (bpp > 8) && (bpp < 32) - vmov.u8 reg&_A, #0xFF +.ifc \op,ld + .if \cvt && (\bpp > 8) && (\bpp < 32) + vmov.u8 \reg\()_A, #0xFF + .endif .endif .endm .macro premult alpha - vmull.u8 PREMULT_B, S_B, alpha - vmull.u8 PREMULT_G, S_G, alpha - vmull.u8 PREMULT_R, S_R, alpha + vmull.u8 PREMULT_B, S_B, \alpha + vmull.u8 PREMULT_G, S_G, \alpha + vmull.u8 PREMULT_R, S_R, \alpha .endm .macro init src_bpp, dst_bpp, mask, opa @@ -321,46 +340,46 @@ TMP_Q1 .qn q14 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] sub MASK_STRIDE, MASK_STRIDE, DST_W .endif -.if opa +.if \opa vld1.8 {OPA[]}, [r0] .else vmov.u8 OPA, #0xFF .endif vmvn D_A, OPA -.if dst_bpp == 16 +.if \dst_bpp == 16 sub DST_STRIDE, DST_STRIDE, DST_W, lsl #1 -.elseif dst_bpp == 24 +.elseif \dst_bpp == 24 sub DST_STRIDE, DST_STRIDE, DST_W sub DST_STRIDE, DST_STRIDE, DST_W, lsl #1 -.elseif dst_bpp >= 31 +.elseif \dst_bpp >= 31 sub DST_STRIDE, DST_STRIDE, DST_W, lsl #2 .endif -.if src_bpp == 0 - .if mask || opa - ldst ld, src_bpp, 8, SRC, S, 1 +.if \src_bpp == 0 + .if \mask || \opa + ldst ld, \src_bpp, 8, SRC, S, 1 vmov.u8 S_A, #0xFF premult OPA .else - ldst ld, src_bpp, 8, SRC, D, 1 + ldst ld, \src_bpp, 8, SRC, D, 1 vmov.u8 D_A, #0xFF - convert D, dst_bpp, 1 + convert D, \dst_bpp, 1 .endif .else -.if src_bpp == 16 +.if \src_bpp == 16 sub SRC_STRIDE, SRC_STRIDE, DST_W, lsl #1 -.elseif src_bpp == 24 +.elseif \src_bpp == 24 sub SRC_STRIDE, SRC_STRIDE, DST_W sub SRC_STRIDE, SRC_STRIDE, DST_W, lsl #1 -.elseif src_bpp >= 31 +.elseif \src_bpp >= 31 sub SRC_STRIDE, SRC_STRIDE, DST_W, lsl #2 .endif .endif @@ -387,33 +406,33 @@ TMP_Q1 .qn q14 cbz BG_MASK, 99f @ return bg; vmov.u8 TMP_D2, #0xFF vmovl.u8 TMP_Q0, D_A - .if len > 4 + .if \len > 4 vmovl.u16 S_565, TMP_D1 .endif vmovl.u16 TMP_Q0, TMP_D0 vmull.u8 TMP_Q1, S_A, TMP_D2 vcvt.f32.u32 TMP_Q0, TMP_Q0 - .if len > 4 + .if \len > 4 vmovl.u16 D_565, TMP_D3 vcvt.f32.u32 S_565, S_565 .endif vmovl.u16 TMP_Q1, TMP_D2 vrecpe.f32 TMP_Q0, TMP_Q0 vcvt.f32.u32 TMP_Q1, TMP_Q1 - .if len > 4 + .if \len > 4 vcvt.f32.u32 D_565, D_565 vrecpe.f32 S_565, S_565 .endif vmul.f32 TMP_Q0, TMP_Q0, TMP_Q1 - .if len > 4 + .if \len > 4 vmul.f32 S_565, S_565, D_565 .endif vcvt.u32.f32 TMP_Q0, TMP_Q0 - .if len > 4 + .if \len > 4 vcvt.u32.f32 S_565, S_565 .endif vmovn.u32 TMP_D0, TMP_Q0 - .if len > 4 + .if \len > 4 vmovn.u32 TMP_D1, S_565 .endif vmovn.u16 TMP_D0, TMP_Q0 @@ -423,14 +442,14 @@ TMP_Q1 .qn q14 .endm .macro blend mode, dst_bpp -.if dst_bpp == 32 +.if \dst_bpp == 32 vmov TMP_D0, FG_MASK, BG_MASK vmovl.s8 TMP_Q0, TMP_D0 vsli.8 TMP_Q0, TMP_Q0, #4 cbz FG_MASK, 98f .endif -.if mode == normal -.if dst_bpp == 32 +.ifc \mode,normal +.if \dst_bpp == 32 cbz BG_MASK, 97f mvns BG_MASK, BG_MASK beq 96f @@ -445,7 +464,7 @@ TMP_Q1 .qn q14 vqrshrn.u16 D_B, PREMULT_B, #8 vqrshrn.u16 D_G, PREMULT_G, #8 vqrshrn.u16 D_R, PREMULT_R, #8 -.if dst_bpp == 32 +.if \dst_bpp == 32 beq 97f vbif D_B, S_565_L, TMP_D1 vbif D_G, S_565_H, TMP_D1 @@ -457,7 +476,7 @@ TMP_Q1 .qn q14 .else .error "blend mode is unsupported" .endif -.if dst_bpp == 32 +.if \dst_bpp == 32 98: vbif D_B, S_B, TMP_D0 vbif D_G, S_G, TMP_D0 @@ -468,70 +487,70 @@ TMP_Q1 .qn q14 .endm .macro process len, src_bpp, dst_bpp, mask, opa, mode -.if (src_bpp < 32) && (mask == 0) && (opa == 0) +.if (\src_bpp < 32) && (\mask == 0) && (\opa == 0) @ no blend - .if src_bpp == 0 || src_bpp == dst_bpp - ldst ld, src_bpp, len, SRC, D, 0, ! - ldst st, dst_bpp, len, DST, D, 0, ! + .if \src_bpp == 0 || \src_bpp == \dst_bpp + ldst ld, \src_bpp, \len, SRC, D, 0, ! + ldst st, \dst_bpp, \len, DST, D, 0, ! .else - ldst ld, src_bpp, len, SRC, D, 1, ! - ldst st, dst_bpp, len, DST, D, 1, ! + ldst ld, \src_bpp, \len, SRC, D, 1, ! + ldst st, \dst_bpp, \len, DST, D, 1, ! .endif -.elseif src_bpp < 32 +.elseif \src_bpp < 32 @ no src_a - .if src_bpp > 0 - ldst ld, src_bpp, len, SRC, S, 1, ! + .if \src_bpp > 0 + ldst ld, \src_bpp, \len, SRC, S, 1, ! .endif - ldst ld, dst_bpp, len, DST, D, 1 - .if mask - ldst ld, 8, len, MASK, S, 1, ! - .if opa + ldst ld, \dst_bpp, \len, DST, D, 1 + .if \mask + ldst ld, 8, \len, MASK, S, 1, ! + .if \opa vmull.u8 TMP_Q0, S_A, OPA vqrshrn.u16 S_A, TMP_Q0, #8 .endif vmvn M_A, S_A - .if dst_bpp < 32 + .if \dst_bpp < 32 premult S_A .else - calc_alpha len + calc_alpha \len .endif .else vmvn M_A, OPA - .if dst_bpp < 32 + .if \dst_bpp < 32 premult OPA .else vmov S_A, OPA - calc_alpha len + calc_alpha \len .endif .endif - blend mode, dst_bpp - ldst st, dst_bpp, len, DST, D, 1, ! + blend \mode, \dst_bpp + ldst st, \dst_bpp, \len, DST, D, 1, ! .else -@ src_a (+mask) (+opa) - ldst ld, src_bpp, len, SRC, S, 1, ! - ldst ld, dst_bpp, len, DST, D, 1 - .if mask == 0 - .if opa +@ src_a (+\mask) (+\opa) + ldst ld, \src_bpp, \len, SRC, S, 1, ! + ldst ld, \dst_bpp, \len, DST, D, 1 + .if \mask == 0 + .if \opa vmull.u8 TMP_Q0, S_A, OPA vqrshrn.u16 S_A, TMP_Q0, #8 .endif .else - ldst ld, 8, len, MASK, M, 1, ! + ldst ld, 8, \len, MASK, M, 1, ! vmull.u8 TMP_Q0, S_A, M_A vqrshrn.u16 S_A, TMP_Q0, #8 - .if opa + .if \opa vmull.u8 TMP_Q0, S_A, OPA vqrshrn.u16 S_A, TMP_Q0, #8 .endif .endif vmvn M_A, S_A - .if dst_bpp < 32 + .if \dst_bpp < 32 premult S_A .else - calc_alpha len + calc_alpha \len .endif - blend mode, dst_bpp - ldst st, dst_bpp, len, DST, D, 1, ! + blend \mode, \dst_bpp + ldst st, \dst_bpp, \len, DST, D, 1, ! .endif .endm @@ -542,40 +561,40 @@ TMP_Q1 .qn q14 beq 5f tst DST_W, #1 beq 6f - process 7, src_bpp, dst_bpp, mask, opa, mode + process 7, \src_bpp, \dst_bpp, \mask, \opa, \mode b 0f 6: - process 6, src_bpp, dst_bpp, mask, opa, mode + process 6, \src_bpp, \dst_bpp, \mask, \opa, \mode b 0f 5: tst DST_W, #1 beq 4f - process 5, src_bpp, dst_bpp, mask, opa, mode + process 5, \src_bpp, \dst_bpp, \mask, \opa, \mode b 0f 4: - process 4, src_bpp, dst_bpp, mask, opa, mode + process 4, \src_bpp, \dst_bpp, \mask, \opa, \mode b 0f 3: tst DST_W, #2 beq 1f tst DST_W, #1 beq 2f - process 3, src_bpp, dst_bpp, mask, opa, mode + process 3, \src_bpp, \dst_bpp, \mask, \opa, \mode b 0f 2: - process 2, src_bpp, dst_bpp, mask, opa, mode + process 2, \src_bpp, \dst_bpp, \mask, \opa, \mode b 0f 1: - process 1, src_bpp, dst_bpp, mask, opa, mode + process 1, \src_bpp, \dst_bpp, \mask, \opa, \mode 0: .endm .macro next src_bpp, mask add DST_ADDR, DST_ADDR, DST_STRIDE -.if src_bpp +.if \src_bpp add SRC_ADDR, SRC_ADDR, SRC_STRIDE .endif -.if mask +.if \mask add MASK_ADDR, MASK_ADDR, MASK_STRIDE .endif .endm @@ -589,49 +608,49 @@ TMP_Q1 .qn q14 .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 W, DST_W, DST_W, lsl #1 - pld [mem&_ADDR, W] -.elseif bpp == 16 - pld [mem&_ADDR, DST_W, lsl #1] -.elseif bpp == 8 - pld [mem&_ADDR, DST_W] + pld [\mem\()_ADDR, W] +.elseif \bpp == 16 + pld [\mem\()_ADDR, DST_W, lsl #1] +.elseif \bpp == 8 + pld [\mem\()_ADDR, DST_W] .endif .endm .macro blender src_bpp, dst_bpp, mask, opa, mode enter - init src_bpp, dst_bpp, mask, opa + 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 subs W, DST_W, #8 blt 7f 9: - process 8, src_bpp, dst_bpp, mask, opa, mode + process 8, \src_bpp, \dst_bpp, \mask, \opa, \mode subs W, W, #8 bge 9b tst DST_W, #7 beq 8f - tail src_bpp, dst_bpp, mask, opa, mode + tail \src_bpp, \dst_bpp, \mask, \opa, \mode 8: - next src_bpp, mask - preload SRC, src_bpp -.if mask || opa || (src_bpp == 32) - preload DST, dst_bpp + next \src_bpp, \mask + preload SRC, \src_bpp +.if \mask || \opa || (\src_bpp == 32) + preload DST, \dst_bpp .endif sub W, DST_W, #8 subs H, H, #1 bgt 9b exit 7: - tail src_bpp, dst_bpp, mask, opa, mode - next src_bpp, mask + tail \src_bpp, \dst_bpp, \mask, \opa, \mode + next \src_bpp, \mask subs H, H, #1 bgt 7b exit @@ -639,25 +658,25 @@ TMP_Q1 .qn q14 .macro export name, src_bpp, dst_bpp, mask, opa, mode .thumb_func -.func name -.global name -.hidden name -name&: - blender src_bpp, dst_bpp, mask, opa, mode +.func \name +.global \name +.hidden \name +\name\(): + blender \src_bpp, \dst_bpp, \mask, \opa, \mode .endfunc .endm .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 +.ifc \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 .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 @@ -683,3 +702,4 @@ export_set xrgb8888, argb8888, 31, 32, normal export_set argb8888, argb8888, 32, 32, normal #endif /*LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON*/ + 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 1ae578d15..8b1ef4cc5 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 @@ -14,6 +14,7 @@ #include "../../display/lv_display_private.h" #include "../../stdlib/lv_string.h" #include "../../core/lv_global.h" +#include "../../misc/lv_area_private.h" #if LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG #if LV_USE_THORVG_EXTERNAL @@ -38,58 +39,6 @@ *********************/ #define DRAW_UNIT_ID_SW 1 -#ifndef LV_DRAW_SW_RGB565_SWAP - #define LV_DRAW_SW_RGB565_SWAP(...) LV_RESULT_INVALID -#endif - -#ifndef LV_DRAW_SW_ROTATE90_ARGB8888 - #define LV_DRAW_SW_ROTATE90_ARGB8888(...) LV_RESULT_INVALID -#endif - -#ifndef LV_DRAW_SW_ROTATE180_ARGB8888 - #define LV_DRAW_SW_ROTATE180_ARGB8888(...) LV_RESULT_INVALID -#endif - -#ifndef LV_DRAW_SW_ROTATE270_ARGB8888 - #define LV_DRAW_SW_ROTATE270_ARGB8888(...) LV_RESULT_INVALID -#endif - -#ifndef LV_DRAW_SW_ROTATE90_RGB888 - #define LV_DRAW_SW_ROTATE90_RGB888(...) LV_RESULT_INVALID -#endif - -#ifndef LV_DRAW_SW_ROTATE180_RGB888 - #define LV_DRAW_SW_ROTATE180_RGB888(...) LV_RESULT_INVALID -#endif - -#ifndef LV_DRAW_SW_ROTATE270_RGB888 - #define LV_DRAW_SW_ROTATE270_RGB888(...) LV_RESULT_INVALID -#endif - -#ifndef LV_DRAW_SW_ROTATE90_RGB565 - #define LV_DRAW_SW_ROTATE90_RGB565(...) LV_RESULT_INVALID -#endif - -#ifndef LV_DRAW_SW_ROTATE180_RGB565 - #define LV_DRAW_SW_ROTATE180_RGB565(...) LV_RESULT_INVALID -#endif - -#ifndef LV_DRAW_SW_ROTATE270_RGB565 - #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 **********************/ @@ -101,53 +50,15 @@ static void render_thread_cb(void * ptr); #endif -static void execute_drawing(lv_draw_sw_unit_t * u); +static void execute_drawing(lv_draw_task_t * t); 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); - -#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 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 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 src_width, int32_t src_height, - int32_t src_stride, - int32_t dst_stride); +#if LV_USE_PARALLEL_DRAW_DEBUG + static void parallel_debug_draw(lv_draw_task_t * t, uint32_t idx); #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 **********************/ @@ -168,22 +79,37 @@ void lv_draw_sw_init(void) lv_draw_sw_mask_init(); #endif - uint32_t i; - for(i = 0; i < LV_DRAW_SW_DRAW_UNIT_CNT; i++) { - lv_draw_sw_unit_t * draw_sw_unit = lv_draw_create_unit(sizeof(lv_draw_sw_unit_t)); - draw_sw_unit->base_unit.dispatch_cb = dispatch; - draw_sw_unit->base_unit.evaluate_cb = evaluate; - draw_sw_unit->idx = i; - draw_sw_unit->base_unit.delete_cb = LV_USE_OS ? lv_draw_sw_delete : NULL; + lv_draw_sw_unit_t * draw_sw_unit = lv_draw_create_unit(sizeof(lv_draw_sw_unit_t)); + draw_sw_unit->base_unit.dispatch_cb = dispatch; + draw_sw_unit->base_unit.evaluate_cb = evaluate; + draw_sw_unit->base_unit.delete_cb = LV_USE_OS ? lv_draw_sw_delete : NULL; +#if LV_USE_DRAW_ARM2D_SYNC + draw_sw_unit->base_unit.name = "SW_ARM2D"; +#else + draw_sw_unit->base_unit.name = "SW"; +#endif #if LV_USE_OS - lv_thread_init(&draw_sw_unit->thread, LV_THREAD_PRIO_HIGH, render_thread_cb, LV_DRAW_THREAD_STACK_SIZE, draw_sw_unit); -#endif + uint32_t i; + for(i = 0; i < LV_DRAW_SW_DRAW_UNIT_CNT; i++) { + lv_draw_sw_thread_dsc_t * thread_dsc = &draw_sw_unit->thread_dscs[i]; + thread_dsc->idx = i; + thread_dsc->draw_unit = (void *) draw_sw_unit; + lv_thread_init(&thread_dsc->thread, "swdraw", LV_DRAW_THREAD_PRIO, render_thread_cb, + LV_DRAW_THREAD_STACK_SIZE, thread_dsc); } +#endif #if LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG - tvg_engine_init(TVG_ENGINE_SW, 0); + if(LV_DRAW_SW_DRAW_UNIT_CNT > 1) { + tvg_engine_init(TVG_ENGINE_SW, LV_DRAW_SW_DRAW_UNIT_CNT); + } + else { + tvg_engine_init(TVG_ENGINE_SW, 0); + } #endif + + lv_ll_init(&LV_GLOBAL_DEFAULT()->draw_sw_blend_handler_ll, sizeof(lv_draw_sw_custom_blend_handler_t)); } void lv_draw_sw_deinit(void) @@ -202,192 +128,82 @@ static int32_t lv_draw_sw_delete(lv_draw_unit_t * draw_unit) #if LV_USE_OS lv_draw_sw_unit_t * draw_sw_unit = (lv_draw_sw_unit_t *) draw_unit; - LV_LOG_INFO("cancel software rendering thread"); - draw_sw_unit->exit_status = true; + uint32_t i; + for(i = 0; i < LV_DRAW_SW_DRAW_UNIT_CNT; i++) { + lv_draw_sw_thread_dsc_t * thread_dsc = &draw_sw_unit->thread_dscs[i]; - if(draw_sw_unit->inited) { - lv_thread_sync_signal(&draw_sw_unit->sync); + LV_LOG_INFO("cancel software rendering thread"); + thread_dsc->exit_status = true; + + if(thread_dsc->inited) { + lv_thread_sync_signal(&thread_dsc->sync); + } + lv_thread_delete(&thread_dsc->thread); } - return lv_thread_delete(&draw_sw_unit->thread); + return 0; #else LV_UNUSED(draw_unit); return 0; #endif } -void lv_draw_sw_rgb565_swap(void * buf, uint32_t buf_size_px) +bool lv_draw_sw_register_blend_handler(lv_draw_sw_custom_blend_handler_t * handler) { - if(LV_DRAW_SW_RGB565_SWAP(buf, buf_size_px) == LV_RESULT_OK) return; + lv_draw_sw_custom_blend_handler_t * existing_handler = NULL; + lv_draw_sw_custom_blend_handler_t * new_handler = NULL; - uint32_t u32_cnt = buf_size_px / 2; - uint16_t * buf16 = buf; - uint32_t * buf32 = buf; - - while(u32_cnt >= 8) { - buf32[0] = ((buf32[0] & 0xff00ff00) >> 8) | ((buf32[0] & 0x00ff00ff) << 8); - buf32[1] = ((buf32[1] & 0xff00ff00) >> 8) | ((buf32[1] & 0x00ff00ff) << 8); - buf32[2] = ((buf32[2] & 0xff00ff00) >> 8) | ((buf32[2] & 0x00ff00ff) << 8); - buf32[3] = ((buf32[3] & 0xff00ff00) >> 8) | ((buf32[3] & 0x00ff00ff) << 8); - buf32[4] = ((buf32[4] & 0xff00ff00) >> 8) | ((buf32[4] & 0x00ff00ff) << 8); - buf32[5] = ((buf32[5] & 0xff00ff00) >> 8) | ((buf32[5] & 0x00ff00ff) << 8); - buf32[6] = ((buf32[6] & 0xff00ff00) >> 8) | ((buf32[6] & 0x00ff00ff) << 8); - buf32[7] = ((buf32[7] & 0xff00ff00) >> 8) | ((buf32[7] & 0x00ff00ff) << 8); - buf32 += 8; - u32_cnt -= 8; + // Check if a handler is already registered for the color format + LV_LL_READ(&LV_GLOBAL_DEFAULT()->draw_sw_blend_handler_ll, existing_handler) { + if(existing_handler->dest_cf == handler->dest_cf) { + new_handler = existing_handler; + break; + } } - while(u32_cnt) { - *buf32 = ((*buf32 & 0xff00ff00) >> 8) | ((*buf32 & 0x00ff00ff) << 8); - buf32++; - u32_cnt--; - } - - if(buf_size_px & 0x1) { - uint32_t e = buf_size_px - 1; - buf16[e] = ((buf16[e] & 0xff00) >> 8) | ((buf16[e] & 0x00ff) << 8); + if(new_handler == NULL) { + new_handler = lv_ll_ins_head(&LV_GLOBAL_DEFAULT()->draw_sw_blend_handler_ll); + if(new_handler == NULL) { + LV_ASSERT_MALLOC(new_handler); + return false; + } } + lv_memcpy(new_handler, handler, sizeof(lv_draw_sw_custom_blend_handler_t)); + return true; } -void lv_draw_sw_i1_invert(void * buf, uint32_t buf_size) +bool lv_draw_sw_unregister_blend_handler(lv_color_format_t dest_cf) { - if(buf == NULL) return; + lv_draw_sw_custom_blend_handler_t * handler; - 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]; + LV_LL_READ(&LV_GLOBAL_DEFAULT()->draw_sw_blend_handler_ll, handler) { + if(handler->dest_cf == dest_cf) { + lv_ll_remove(&LV_GLOBAL_DEFAULT()->draw_sw_blend_handler_ll, handler); + lv_free(handler); + return true; } - - 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]; - } + return false; } -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) +lv_draw_sw_blend_handler_t lv_draw_sw_get_blend_handler(lv_color_format_t dest_cf) { - if(rotation == LV_DISPLAY_ROTATION_90) { - 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; - } + lv_draw_sw_custom_blend_handler_t * handler; - return; + LV_LL_READ(&LV_GLOBAL_DEFAULT()->draw_sw_blend_handler_ll, handler) { + if(handler->dest_cf == dest_cf) { + return handler->handler; + } } - 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; - } - - 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; - } + return NULL; } /********************** * STATIC FUNCTIONS **********************/ -static inline void execute_drawing_unit(lv_draw_sw_unit_t * u) -{ - execute_drawing(u); - - u->task_act->state = LV_DRAW_TASK_STATE_READY; - u->task_act = NULL; - - /*The draw unit is free now. Request a new dispatching as it can get a new task*/ - lv_draw_dispatch_request(); -} static int32_t evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task) { @@ -403,18 +219,22 @@ static int32_t evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task) return 0; } - bool transformed = draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE || - draw_dsc->scale_y != LV_SCALE_NONE ? true : false; - bool masked = draw_dsc->bitmap_mask_src != NULL; - if(masked && transformed) return 0; lv_color_format_t cf = draw_dsc->header.cf; if(masked && (cf == LV_COLOR_FORMAT_A8 || cf == LV_COLOR_FORMAT_RGB565A8)) { return 0; } + + if(cf >= LV_COLOR_FORMAT_PROPRIETARY_START) { + return 0; + } } break; +#if LV_USE_3DTEXTURE + case LV_DRAW_TASK_TYPE_3D: + return 0; +#endif default: break; } @@ -429,138 +249,208 @@ static int32_t evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task) static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; lv_draw_sw_unit_t * draw_sw_unit = (lv_draw_sw_unit_t *) draw_unit; +#if LV_USE_OS + uint32_t i; + uint32_t taken_cnt = 0; + /* All idle (couldn't take any tasks): return LV_DRAW_UNIT_IDLE; + * All busy: return 0; as 0 tasks were taken + * Otherwise return taken_cnt; + */ + + /*If at least one is busy, it's not all idle*/ + bool all_idle = true; + for(i = 0; i < LV_DRAW_SW_DRAW_UNIT_CNT; i++) { + if(draw_sw_unit->thread_dscs[i].task_act) { + all_idle = false; + break; + } + } + + lv_draw_task_t * t = NULL; + for(i = 0; i < LV_DRAW_SW_DRAW_UNIT_CNT; i++) { + lv_draw_sw_thread_dsc_t * thread_dsc = &draw_sw_unit->thread_dscs[i]; + + /*Do nothing if busy*/ + if(thread_dsc->task_act) continue; + + /*Find an available task. Start from the previously taken task.*/ + t = lv_draw_get_next_available_task(layer, t, DRAW_UNIT_ID_SW); + + /*If there is not available task don't try other threads as there won't be available + *tasks for then either*/ + if(t == NULL) { + LV_PROFILER_DRAW_END; + if(all_idle) return LV_DRAW_UNIT_IDLE; /*Couldn't start rendering*/ + else return taken_cnt; + } + + /*Allocate a buffer if not done yet.*/ + void * buf = lv_draw_layer_alloc_buf(layer); + /*Do not return is failed. The other thread might already have a buffer can do something. */ + if(buf == NULL) continue; + + /*Take the task*/ + all_idle = false; + taken_cnt++; + t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; + thread_dsc->task_act = t; + + /*Let the render thread work*/ + if(thread_dsc->inited) lv_thread_sync_signal(&thread_dsc->sync); + } + + if(all_idle) return LV_DRAW_UNIT_IDLE; /*Couldn't start rendering*/ + else return taken_cnt; + +#else /*Return immediately if it's busy with draw task*/ if(draw_sw_unit->task_act) { - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return 0; } lv_draw_task_t * t = NULL; - t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_SW); + t = lv_draw_get_available_task(layer, NULL, DRAW_UNIT_ID_SW); if(t == NULL) { - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return LV_DRAW_UNIT_IDLE; /*Couldn't start rendering*/ } void * buf = lv_draw_layer_alloc_buf(layer); if(buf == NULL) { - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return LV_DRAW_UNIT_IDLE; /*Couldn't start rendering*/ } t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; - draw_sw_unit->base_unit.target_layer = layer; - draw_sw_unit->base_unit.clip_area = &t->clip_area; draw_sw_unit->task_act = t; -#if LV_USE_OS - /*Let the render thread work*/ - if(draw_sw_unit->inited) lv_thread_sync_signal(&draw_sw_unit->sync); -#else - execute_drawing_unit(draw_sw_unit); -#endif - LV_PROFILER_END; + execute_drawing(t); + draw_sw_unit->task_act->state = LV_DRAW_TASK_STATE_READY; + draw_sw_unit->task_act = NULL; + + /*The draw unit is free now. Request a new dispatching as it can get a new task*/ + lv_draw_dispatch_request(); + + LV_PROFILER_DRAW_END; return 1; +#endif + } #if LV_USE_OS static void render_thread_cb(void * ptr) { - lv_draw_sw_unit_t * u = ptr; + lv_draw_sw_thread_dsc_t * thread_dsc = ptr; - lv_thread_sync_init(&u->sync); - u->inited = true; + lv_thread_sync_init(&thread_dsc->sync); + thread_dsc->inited = true; while(1) { - while(u->task_act == NULL) { - if(u->exit_status) { + while(thread_dsc->task_act == NULL) { + if(thread_dsc->exit_status) { break; } - lv_thread_sync_wait(&u->sync); + lv_thread_sync_wait(&thread_dsc->sync); } - if(u->exit_status) { + if(thread_dsc->exit_status) { LV_LOG_INFO("ready to exit software rendering thread"); break; } - execute_drawing_unit(u); + execute_drawing(thread_dsc->task_act); +#if LV_USE_PARALLEL_DRAW_DEBUG + parallel_debug_draw(thread_dsc->task_act, thread_dsc->idx); +#endif + thread_dsc->task_act->state = LV_DRAW_TASK_STATE_READY; + thread_dsc->task_act = NULL; + + /*The draw unit is free now. Request a new dispatching as it can get a new task*/ + lv_draw_dispatch_request(); + } - u->inited = false; - lv_thread_sync_delete(&u->sync); + thread_dsc->inited = false; + lv_thread_sync_delete(&thread_dsc->sync); LV_LOG_INFO("exit software rendering thread"); } #endif -static void execute_drawing(lv_draw_sw_unit_t * u) +static void execute_drawing(lv_draw_task_t * t) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; /*Render the draw task*/ - lv_draw_task_t * t = u->task_act; switch(t->type) { case LV_DRAW_TASK_TYPE_FILL: - lv_draw_sw_fill((lv_draw_unit_t *)u, t->draw_dsc, &t->area); + lv_draw_sw_fill(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_BORDER: - lv_draw_sw_border((lv_draw_unit_t *)u, t->draw_dsc, &t->area); + lv_draw_sw_border(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_BOX_SHADOW: - lv_draw_sw_box_shadow((lv_draw_unit_t *)u, t->draw_dsc, &t->area); + lv_draw_sw_box_shadow(t, t->draw_dsc, &t->area); + break; + case LV_DRAW_TASK_TYPE_LETTER: + lv_draw_sw_letter(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_LABEL: - lv_draw_sw_label((lv_draw_unit_t *)u, t->draw_dsc, &t->area); + lv_draw_sw_label(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_IMAGE: - lv_draw_sw_image((lv_draw_unit_t *)u, t->draw_dsc, &t->area); + lv_draw_sw_image(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_ARC: - lv_draw_sw_arc((lv_draw_unit_t *)u, t->draw_dsc, &t->area); + lv_draw_sw_arc(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_LINE: - lv_draw_sw_line((lv_draw_unit_t *)u, t->draw_dsc); + lv_draw_sw_line(t, t->draw_dsc); break; case LV_DRAW_TASK_TYPE_TRIANGLE: - lv_draw_sw_triangle((lv_draw_unit_t *)u, t->draw_dsc); + lv_draw_sw_triangle(t, t->draw_dsc); break; case LV_DRAW_TASK_TYPE_LAYER: - lv_draw_sw_layer((lv_draw_unit_t *)u, t->draw_dsc, &t->area); + lv_draw_sw_layer(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_MASK_RECTANGLE: - lv_draw_sw_mask_rect((lv_draw_unit_t *)u, t->draw_dsc, &t->area); + lv_draw_sw_mask_rect(t, t->draw_dsc); break; #if LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG case LV_DRAW_TASK_TYPE_VECTOR: - lv_draw_sw_vector((lv_draw_unit_t *)u, t->draw_dsc); + lv_draw_sw_vector(t, t->draw_dsc); break; #endif default: break; } + + LV_PROFILER_DRAW_END; +} + #if LV_USE_PARALLEL_DRAW_DEBUG +static void parallel_debug_draw(lv_draw_task_t * t, uint32_t idx) +{ /*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, &t->clip_area)) return; - int32_t idx = 0; - lv_draw_unit_t * draw_unit_tmp = _draw_info.unit_head; - while(draw_unit_tmp != (lv_draw_unit_t *)u) { - draw_unit_tmp = draw_unit_tmp->next; - idx++; - } - 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.border_color = rect_dsc.bg_color; - rect_dsc.bg_opa = LV_OPA_10; - rect_dsc.border_opa = LV_OPA_80; - rect_dsc.border_width = 1; - lv_draw_sw_fill((lv_draw_unit_t *)u, &rect_dsc, &draw_area); + lv_draw_fill_dsc_t fill_dsc; + lv_draw_fill_dsc_init(&fill_dsc); + fill_dsc.color = lv_palette_main(idx % LV_PALETTE_LAST); + fill_dsc.opa = LV_OPA_10; + lv_draw_sw_fill(t, &fill_dsc, &draw_area); + + 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.opa = LV_OPA_60; + border_dsc.width = 1; + lv_draw_sw_border(t, &border_dsc, &draw_area); lv_point_t txt_size; lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE); @@ -571,9 +461,9 @@ static void execute_drawing(lv_draw_sw_unit_t * u) txt_area.x2 = draw_area.x1 + txt_size.x - 1; txt_area.y2 = draw_area.y1 + txt_size.y - 1; - lv_draw_rect_dsc_init(&rect_dsc); - rect_dsc.bg_color = lv_color_white(); - lv_draw_sw_fill((lv_draw_unit_t *)u, &rect_dsc, &txt_area); + lv_draw_fill_dsc_init(&fill_dsc); + fill_dsc.color = lv_color_white(); + lv_draw_sw_fill(t, &fill_dsc, &txt_area); char buf[8]; lv_snprintf(buf, sizeof(buf), "%d", idx); @@ -581,255 +471,10 @@ static void execute_drawing(lv_draw_sw_unit_t * u) lv_draw_label_dsc_init(&label_dsc); label_dsc.color = lv_color_black(); label_dsc.text = buf; - lv_draw_sw_label((lv_draw_unit_t *)u, &label_dsc, &txt_area); - } -#endif - LV_PROFILER_END; -} - -#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, src_width, src_height, src_stride, dst_stride)) { - return ; - } - - src_stride /= sizeof(uint32_t); - dst_stride /= sizeof(uint32_t); - - 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; - } + lv_draw_sw_label(t, &label_dsc, &txt_area); } } - -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) -{ - LV_UNUSED(dest_stride); - if(LV_RESULT_OK == LV_DRAW_SW_ROTATE180_ARGB8888(src, dst, src_width, src_height, src_stride, dst_stride)) { - return ; - } - - src_stride /= sizeof(uint32_t); - - for(int32_t y = 0; y < height; ++y) { - int32_t dstIndex = (height - y - 1) * src_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 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, src_width, src_height, src_stride, dst_stride)) { - return ; - } - - src_stride /= sizeof(uint32_t); - dst_stride /= sizeof(uint32_t); - - 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; - } - } -} - #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, src_width, src_height, src_stride, dst_stride)) { - return ; - } - - 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*/ - } - } -} - -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, src_width, src_height, src_stride, dst_stride)) { - return ; - } - - for(int32_t y = 0; y < height; ++y) { - for(int32_t x = 0; x < width; ++x) { - int32_t srcIndex = y * src_stride + x * 3; - int32_t dstIndex = (height - y - 1) * dest_stride + (width - x - 1) * 3; - dst[dstIndex] = src[srcIndex]; - dst[dstIndex + 1] = src[srcIndex + 1]; - dst[dstIndex + 2] = src[srcIndex + 2]; - } - } -} - -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, 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 * 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*/ - } - } -} - -#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, src_width, src_height, src_stride, dst_stride)) { - return ; - } - - src_stride /= sizeof(uint16_t); - dst_stride /= sizeof(uint16_t); - - 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; - } - } -} - -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, width, height, src_stride)) { - return ; - } - - src_stride /= sizeof(uint16_t); - dest_stride /= sizeof(uint16_t); - - 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 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, src_width, src_height, src_stride, dst_stride)) { - return ; - } - - src_stride /= sizeof(uint16_t); - dst_stride /= sizeof(uint16_t); - - 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; - } - } -} - -#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 6463afd86..d5e0df24c 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 * */ @@ -27,6 +27,8 @@ extern "C" { #include "../lv_draw_image.h" #include "../lv_draw_line.h" #include "../lv_draw_arc.h" +#include "lv_draw_sw_utils.h" +#include "blend/lv_draw_sw_blend.h" /********************* * DEFINES @@ -49,86 +51,87 @@ void lv_draw_sw_deinit(void); /** * Fill an area using SW render. Handle gradient and radius. - * @param draw_unit pointer to a draw unit + * @param t pointer to a draw task * @param dsc the draw descriptor * @param coords the coordinates of the rectangle */ -void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const lv_area_t * coords); +void lv_draw_sw_fill(lv_draw_task_t * t, lv_draw_fill_dsc_t * dsc, const lv_area_t * coords); /** * Draw border with SW render. - * @param draw_unit pointer to a draw unit + * @param t pointer to a draw task * @param dsc the draw descriptor * @param coords the coordinates of the rectangle */ -void lv_draw_sw_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords); +void lv_draw_sw_border(lv_draw_task_t * t, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords); /** * Draw box shadow with SW render. - * @param draw_unit pointer to a draw unit + * @param t pointer to a draw task * @param dsc the draw descriptor * @param coords the coordinates of the rectangle for which the box shadow should be drawn */ -void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_dsc_t * dsc, const lv_area_t * coords); +void lv_draw_sw_box_shadow(lv_draw_task_t * t, const lv_draw_box_shadow_dsc_t * dsc, const lv_area_t * coords); /** * Draw an image with SW render. It handles image decoding, tiling, transformations, and recoloring. - * @param draw_unit pointer to a draw unit + * @param t pointer to a draw task * @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, +void lv_draw_sw_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords); +void lv_draw_sw_letter(lv_draw_task_t * t, const lv_draw_letter_dsc_t * dsc, const lv_area_t * coords); + /** * Draw a label with SW render. - * @param draw_unit pointer to a draw unit + * @param t pointer to a draw task * @param dsc the draw descriptor * @param coords the coordinates of the label */ -void lv_draw_sw_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords); +void lv_draw_sw_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords); /** * Draw an arc with SW render. - * @param draw_unit pointer to a draw unit + * @param t pointer to a draw task * @param dsc the draw descriptor * @param coords the coordinates of the arc */ -void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords); +void lv_draw_sw_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords); /** * Draw a line with SW render. - * @param draw_unit pointer to a draw unit + * @param t pointer to a draw task * @param dsc the draw descriptor */ -void lv_draw_sw_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc); +void lv_draw_sw_line(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc); /** * Blend a layer with SW render - * @param draw_unit pointer to a draw unit + * @param t pointer to a draw task * @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); +void lv_draw_sw_layer(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords); /** * Draw a triangle with SW render. - * @param draw_unit pointer to a draw unit + * @param t pointer to a draw task * @param dsc the draw descriptor */ -void lv_draw_sw_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc); +void lv_draw_sw_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc); /** * Mask out a rectangle with radius from a current layer - * @param draw_unit pointer to a draw unit + * @param t pointer to a draw task * @param dsc the draw descriptor * @param coords the coordinates of the mask */ -void lv_draw_sw_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_dsc_t * dsc, const lv_area_t * coords); +void lv_draw_sw_mask_rect(lv_draw_task_t * t, const lv_draw_mask_rect_dsc_t * dsc); /** * Used internally to get a transformed are of an image - * @param draw_unit pointer to a draw unit * @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 @@ -139,51 +142,44 @@ void lv_draw_sw_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_ds * @param cf color format of the source buffer * @param dest_buf the destination buffer */ -void lv_draw_sw_transform(lv_draw_unit_t * draw_unit, const lv_area_t * dest_area, const void * src_buf, +void lv_draw_sw_transform(const lv_area_t * dest_area, const void * src_buf, int32_t src_w, int32_t src_h, int32_t src_stride, const lv_draw_image_dsc_t * draw_dsc, const lv_draw_image_sup_t * sup, lv_color_format_t cf, void * dest_buf); #if LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG /** * Draw vector graphics with SW render. - * @param draw_unit pointer to a draw unit + * @param t pointer to a draw task * @param dsc the draw descriptor */ -void lv_draw_sw_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_task_dsc_t * dsc); +void lv_draw_sw_vector(lv_draw_task_t * t, lv_draw_vector_task_dsc_t * dsc); #endif /** - * 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 + * Register a custom blend handler for a color format. + * Handler will be called when blending a color or an + * image to a buffer with the given color format. + * At most one handler can be registered for a color format. + * Subsequent registrations will overwrite the previous handler. + * + * @param handler pointer to a blend handler + * @return true if the handler was registered, false if the handler could not be registered */ -void lv_draw_sw_rgb565_swap(void * buf, uint32_t buf_size_px); +bool lv_draw_sw_register_blend_handler(lv_draw_sw_custom_blend_handler_t * handler); /** - * 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 + * Unregister a custom blend handler for a color format. + * @param dest_cf color format + * @return true if a handler was unregistered, false if no handler was registered */ -void lv_draw_sw_i1_invert(void * buf, uint32_t buf_size); +bool lv_draw_sw_unregister_blend_handler(lv_color_format_t dest_cf); /** - * 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_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 + * Get the blend handler for a color format. + * @param dest_cf color format + * @return pointer to the blend handler or NULL if no handler is registered */ -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); +lv_draw_sw_blend_handler_t lv_draw_sw_get_blend_handler(lv_color_format_t dest_cf); /*********************** * GLOBAL VARIABLES @@ -193,8 +189,6 @@ void lv_draw_sw_rotate(const void * src, void * dest, int32_t src_width, int32_t * MACROS **********************/ -#include "blend/lv_draw_sw_blend.h" - #endif /*LV_USE_DRAW_SW*/ #ifdef __cplusplus 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 ec2fb2fd9..982200c46 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 @@ -50,7 +50,7 @@ static void get_rounded_area(int16_t angle, int32_t radius, uint8_t thickness, l * GLOBAL FUNCTIONS **********************/ -void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_sw_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords) { #if LV_DRAW_SW_COMPLEX if(dsc->opa <= LV_OPA_MIN) return; @@ -62,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, &t->clip_area)) return; /*Draw a full ring*/ if(dsc->img_src == NULL && @@ -74,7 +74,7 @@ void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, c cir_dsc.width = width; cir_dsc.radius = LV_RADIUS_CIRCLE; cir_dsc.side = LV_BORDER_SIDE_FULL; - lv_draw_sw_border(draw_unit, &cir_dsc, &area_out); + lv_draw_sw_border(t, &cir_dsc, &area_out); return; } @@ -157,6 +157,7 @@ void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, c lv_area_t round_area_2; if(dsc->rounded) { circle_mask = lv_malloc(width * width); + LV_ASSERT_MALLOC(circle_mask); lv_memset(circle_mask, 0xff, width * width); lv_area_t circle_area = {0, 0, width - 1, width - 1}; lv_draw_sw_mask_radius_param_t circle_mask_param; @@ -172,6 +173,8 @@ void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, c circle_mask_tmp += width; } + lv_draw_sw_mask_free_param(&circle_mask_param); + get_rounded_area(start_angle, dsc->radius, width, &round_area_1); lv_area_move(&round_area_1, dsc->center.x, dsc->center.y); get_rounded_area(end_angle, dsc->radius, width, &round_area_2); @@ -216,7 +219,7 @@ void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, c } } - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); blend_area.y1 ++; blend_area.y2 ++; @@ -303,9 +306,9 @@ static void get_rounded_area(int16_t angle, int32_t radius, uint8_t thickness, l #else /*LV_DRAW_SW_COMPLEX*/ -void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_sw_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords) { - LV_UNUSED(draw_unit); + LV_UNUSED(t); LV_UNUSED(dsc); LV_UNUSED(coords); 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 07eb18c0e..f27f0c348 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 @@ -33,10 +33,10 @@ /********************** * STATIC PROTOTYPES **********************/ -static void draw_border_complex(lv_draw_unit_t * draw_unit, const lv_area_t * outer_area, const lv_area_t * inner_area, +static void draw_border_complex(lv_draw_task_t * t, const lv_area_t * outer_area, const lv_area_t * inner_area, int32_t rout, int32_t rin, lv_color_t color, lv_opa_t opa); -static void draw_border_simple(lv_draw_unit_t * draw_unit, const lv_area_t * outer_area, const lv_area_t * inner_area, +static void draw_border_simple(lv_draw_task_t * t, const lv_area_t * outer_area, const lv_area_t * inner_area, lv_color_t color, lv_opa_t opa); /********************** @@ -51,7 +51,7 @@ static void draw_border_simple(lv_draw_unit_t * draw_unit, const lv_area_t * out * GLOBAL FUNCTIONS **********************/ -void lv_draw_sw_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_sw_border(lv_draw_task_t * t, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords) { if(dsc->opa <= LV_OPA_MIN) return; if(dsc->width == 0) return; @@ -75,10 +75,10 @@ void lv_draw_sw_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * if(rin < 0) rin = 0; if(rout == 0 && rin == 0) { - draw_border_simple(draw_unit, coords, &area_inner, dsc->color, dsc->opa); + draw_border_simple(t, coords, &area_inner, dsc->color, dsc->opa); } else { - draw_border_complex(draw_unit, coords, &area_inner, rout, rin, dsc->color, dsc->opa); + draw_border_complex(t, coords, &area_inner, rout, rin, dsc->color, dsc->opa); } } @@ -87,14 +87,14 @@ void lv_draw_sw_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * * STATIC FUNCTIONS **********************/ -void draw_border_complex(lv_draw_unit_t * draw_unit, const lv_area_t * outer_area, const lv_area_t * inner_area, +void draw_border_complex(lv_draw_task_t * t, const lv_area_t * outer_area, const lv_area_t * 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; - if(!lv_area_intersect(&draw_area, outer_area, draw_unit->clip_area)) return; + if(!lv_area_intersect(&draw_area, outer_area, &t->clip_area)) return; int32_t draw_area_w = lv_area_get_width(&draw_area); lv_draw_sw_blend_dsc_t blend_dsc; @@ -151,7 +151,7 @@ void draw_border_complex(lv_draw_unit_t * draw_unit, const lv_area_t * outer_are blend_area.x2 = core_area.x2; blend_area.y1 = outer_area->y1; blend_area.y2 = inner_area->y1 - 1; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } if(bottom_side && split_hor) { @@ -159,7 +159,7 @@ void draw_border_complex(lv_draw_unit_t * draw_unit, const lv_area_t * outer_are blend_area.x2 = core_area.x2; blend_area.y1 = inner_area->y2 + 1; blend_area.y2 = outer_area->y2; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } /*If the border is very thick and the vertical sides overlap horizontally draw a single rectangle*/ @@ -168,7 +168,7 @@ void draw_border_complex(lv_draw_unit_t * draw_unit, const lv_area_t * outer_are blend_area.x2 = outer_area->x2; blend_area.y1 = core_area.y1; blend_area.y2 = core_area.y2; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } else { if(left_side) { @@ -176,7 +176,7 @@ void draw_border_complex(lv_draw_unit_t * draw_unit, const lv_area_t * outer_are blend_area.x2 = inner_area->x1 - 1; blend_area.y1 = core_area.y1; blend_area.y2 = core_area.y2; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } if(right_side) { @@ -184,7 +184,7 @@ void draw_border_complex(lv_draw_unit_t * draw_unit, const lv_area_t * outer_are blend_area.x2 = outer_area->x2; blend_area.y1 = core_area.y1; blend_area.y2 = core_area.y2; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } } @@ -208,13 +208,13 @@ void draw_border_complex(lv_draw_unit_t * draw_unit, const lv_area_t * outer_are if(top_y >= draw_area.y1) { blend_area.y1 = top_y; blend_area.y2 = top_y; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } if(bottom_y <= draw_area.y2) { blend_area.y1 = bottom_y; blend_area.y2 = bottom_y; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } } } @@ -231,7 +231,7 @@ void draw_border_complex(lv_draw_unit_t * draw_unit, const lv_area_t * outer_are lv_memset(mask_buf, 0xff, blend_w); blend_dsc.mask_res = lv_draw_sw_mask_apply(mask_list, mask_buf, blend_area.x1, h, blend_w); - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } } @@ -242,7 +242,7 @@ void draw_border_complex(lv_draw_unit_t * draw_unit, const lv_area_t * outer_are lv_memset(mask_buf, 0xff, blend_w); blend_dsc.mask_res = lv_draw_sw_mask_apply(mask_list, mask_buf, blend_area.x1, h, blend_w); - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } } } @@ -262,7 +262,7 @@ void draw_border_complex(lv_draw_unit_t * draw_unit, const lv_area_t * outer_are lv_memset(mask_buf, 0xff, blend_w); blend_dsc.mask_res = lv_draw_sw_mask_apply(mask_list, mask_buf, blend_area.x1, h, blend_w); - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } } @@ -273,7 +273,7 @@ void draw_border_complex(lv_draw_unit_t * draw_unit, const lv_area_t * outer_are lv_memset(mask_buf, 0xff, blend_w); blend_dsc.mask_res = lv_draw_sw_mask_apply(mask_list, mask_buf, blend_area.x1, h, blend_w); - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } } } @@ -283,9 +283,17 @@ void draw_border_complex(lv_draw_unit_t * draw_unit, const lv_area_t * outer_are if(rout > 0) lv_draw_sw_mask_free_param(&mask_rout_param); lv_free(mask_buf); +#else + LV_UNUSED(t); + LV_UNUSED(outer_area); + LV_UNUSED(inner_area); + LV_UNUSED(rout); + LV_UNUSED(rin); + LV_UNUSED(color); + LV_UNUSED(opa); #endif /*LV_DRAW_SW_COMPLEX*/ } -static void draw_border_simple(lv_draw_unit_t * draw_unit, const lv_area_t * outer_area, const lv_area_t * inner_area, +static void draw_border_simple(lv_draw_task_t * t, const lv_area_t * outer_area, const lv_area_t * inner_area, lv_color_t color, lv_opa_t opa) { lv_area_t a; @@ -306,14 +314,14 @@ static void draw_border_simple(lv_draw_unit_t * draw_unit, const lv_area_t * out a.y1 = outer_area->y1; a.y2 = inner_area->y1 - 1; if(top_side) { - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } /*Bottom*/ a.y1 = inner_area->y2 + 1; a.y2 = outer_area->y2; if(bottom_side) { - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } /*Left*/ @@ -322,14 +330,14 @@ static void draw_border_simple(lv_draw_unit_t * draw_unit, const lv_area_t * out a.y1 = (top_side) ? inner_area->y1 : outer_area->y1; a.y2 = (bottom_side) ? inner_area->y2 : outer_area->y2; if(left_side) { - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } /*Right*/ a.x1 = inner_area->x2 + 1; a.x2 = outer_area->x2; if(right_side) { - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(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 f80287566..ee693f5b6 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 @@ -55,7 +55,7 @@ static void /* LV_ATTRIBUTE_FAST_MEM */ shadow_blur_corner(int32_t size, int32_t * GLOBAL FUNCTIONS **********************/ -void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_sw_box_shadow(lv_draw_task_t * t, const lv_draw_box_shadow_dsc_t * dsc, const lv_area_t * coords) { /*Calculate the rectangle which is blurred to get the shadow in `shadow_area`*/ lv_area_t core_area; @@ -77,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, &t->clip_area)) return; /*Consider 1 px smaller bg to be sure the edge will be covered by the shadow*/ lv_area_t bg_area; @@ -104,11 +104,13 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ if(cache->cache_size == corner_size && cache->cache_r == r_sh) { /*Use the cache if available*/ sh_buf = lv_malloc(corner_size * corner_size); + LV_ASSERT_MALLOC(sh_buf); lv_memcpy(sh_buf, cache->cache, corner_size * corner_size); } else { /*A larger buffer is required for calculation*/ sh_buf = lv_malloc(corner_size * corner_size * sizeof(uint16_t)); + LV_ASSERT_MALLOC(sh_buf); shadow_draw_corner_buf(&core_area, (uint16_t *)sh_buf, dsc->width, r_sh); /*Cache the corner if it fits into the cache size*/ @@ -120,6 +122,7 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ } #else sh_buf = lv_malloc(corner_size * corner_size * sizeof(uint16_t)); + LV_ASSERT_MALLOC(sh_buf); shadow_draw_corner_buf(&core_area, (uint16_t *)sh_buf, dsc->width, r_sh); #endif /*LV_DRAW_SW_SHADOW_CACHE_SIZE*/ @@ -164,7 +167,7 @@ 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) && + if(lv_area_intersect(&clip_area_sub, &blend_area, &t->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; @@ -191,7 +194,7 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ else { blend_dsc.mask_buf = sh_buf_tmp; } - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); sh_buf_tmp += corner_size; } } @@ -207,7 +210,7 @@ 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) && + if(lv_area_intersect(&clip_area_sub, &blend_area, &t->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; @@ -234,7 +237,7 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ else { blend_dsc.mask_buf = sh_buf_tmp; } - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); sh_buf_tmp += corner_size; } } @@ -247,7 +250,7 @@ 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) && + if(lv_area_intersect(&clip_area_sub, &blend_area, &t->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; @@ -275,11 +278,11 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ lv_memset(mask_buf, sh_buf_tmp[0], w); blend_dsc.mask_res = lv_draw_sw_mask_apply(masks, mask_buf, clip_area_sub.x1, y, w); 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); + lv_draw_sw_blend(t, &blend_dsc); } else { blend_dsc.opa = opa == LV_OPA_COVER ? sh_buf_tmp[0] : LV_OPA_MIX2(sh_buf_tmp[0], dsc->opa); - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } sh_buf_tmp += corner_size; } @@ -294,7 +297,7 @@ 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) && + if(lv_area_intersect(&clip_area_sub, &blend_area, &t->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; @@ -325,11 +328,11 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ lv_memset(mask_buf, sh_buf_tmp[0], w); blend_dsc.mask_res = lv_draw_sw_mask_apply(masks, mask_buf, clip_area_sub.x1, y, w); 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); + lv_draw_sw_blend(t, &blend_dsc); } else { blend_dsc.opa = opa == LV_OPA_COVER ? sh_buf_tmp[0] : (sh_buf_tmp[0] * dsc->opa) >> 8; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } sh_buf_tmp += corner_size; @@ -349,7 +352,7 @@ 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) && + if(lv_area_intersect(&clip_area_sub, &blend_area, &t->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; @@ -374,7 +377,7 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ blend_dsc.mask_res = lv_draw_sw_mask_apply(masks, mask_buf, clip_area_sub.x1, y, w); 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); + lv_draw_sw_blend(t, &blend_dsc); } } } @@ -406,7 +409,7 @@ 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) && + if(lv_area_intersect(&clip_area_sub, &blend_area, &t->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; @@ -431,7 +434,7 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ 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); + lv_draw_sw_blend(t, &blend_dsc); } } } @@ -445,7 +448,7 @@ 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) && + if(lv_area_intersect(&clip_area_sub, &blend_area, &t->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; @@ -474,7 +477,7 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ blend_dsc.mask_buf = sh_buf_tmp; } - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); sh_buf_tmp += corner_size; } } @@ -490,7 +493,7 @@ 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) && + if(lv_area_intersect(&clip_area_sub, &blend_area, &t->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; @@ -517,7 +520,7 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ else { blend_dsc.mask_buf = sh_buf_tmp; } - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); sh_buf_tmp += corner_size; } } @@ -532,7 +535,7 @@ 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) && + if(lv_area_intersect(&clip_area_sub, &blend_area, &t->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) { @@ -544,7 +547,7 @@ void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_ lv_memset(mask_buf, 0xff, w); blend_dsc.mask_res = lv_draw_sw_mask_apply(masks, mask_buf, clip_area_sub.x1, y, w); - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } } } @@ -729,9 +732,9 @@ static void LV_ATTRIBUTE_FAST_MEM shadow_blur_corner(int32_t size, int32_t sw, u #else /*LV_DRAW_SW_COMPLEX*/ -void lv_draw_sw_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_sw_box_shadow(lv_draw_task_t * t, const lv_draw_box_shadow_dsc_t * dsc, const lv_area_t * coords) { - LV_UNUSED(draw_unit); + LV_UNUSED(t); LV_UNUSED(dsc); LV_UNUSED(coords); 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 0aeb55994..930457f67 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 * */ @@ -13,7 +13,7 @@ #if LV_USE_DRAW_SW #include "blend/lv_draw_sw_blend_private.h" -#include "lv_draw_sw_gradient_private.h" +#include "lv_draw_sw_grad.h" #include "../../misc/lv_math.h" #include "../../misc/lv_text_ap.h" #include "../../core/lv_refr.h" @@ -45,7 +45,7 @@ * GLOBAL FUNCTIONS **********************/ -void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_sw_fill(lv_draw_task_t * t, lv_draw_fill_dsc_t * dsc, const lv_area_t * coords) { if(dsc->opa <= LV_OPA_MIN) return; @@ -53,7 +53,7 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const 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, &t->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; @@ -65,7 +65,7 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const if(dsc->radius == 0 && (grad_dir == LV_GRAD_DIR_NONE)) { blend_dsc.blend_area = &bg_coords; blend_dsc.opa = dsc->opa; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); return; } @@ -104,7 +104,7 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const blend_dsc.opa = LV_OPA_COVER; /*Get gradient if appropriate*/ - lv_grad_t * grad = lv_gradient_get(&dsc->grad, coords_bg_w, coords_bg_h); + lv_draw_sw_grad_calc_t * grad = lv_draw_sw_grad_get(&dsc->grad, coords_bg_w, coords_bg_h); lv_opa_t * grad_opa_map = NULL; bool transp = false; if(grad && grad_dir >= LV_GRAD_DIR_HOR) { @@ -127,15 +127,16 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const /*Prepare complex gradient*/ if(grad_dir >= LV_GRAD_DIR_LINEAR) { + LV_ASSERT_NULL(grad); switch(grad_dir) { case LV_GRAD_DIR_LINEAR: - lv_gradient_linear_setup(&dsc->grad, coords); + lv_draw_sw_grad_linear_setup(&dsc->grad, coords); break; case LV_GRAD_DIR_RADIAL: - lv_gradient_radial_setup(&dsc->grad, coords); + lv_draw_sw_grad_radial_setup(&dsc->grad, coords); break; case LV_GRAD_DIR_CONICAL: - lv_gradient_conical_setup(&dsc->grad, coords); + lv_draw_sw_grad_conical_setup(&dsc->grad, coords); break; default: LV_LOG_WARN("Gradient type is not supported"); @@ -169,6 +170,7 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const switch(grad_dir) { case LV_GRAD_DIR_VER: + LV_ASSERT_NULL(grad); blend_dsc.color = grad->color_map[top_y - bg_coords.y1]; blend_dsc.opa = grad->opa_map[top_y - bg_coords.y1]; break; @@ -178,15 +180,15 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const 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); + lv_draw_sw_grad_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); + lv_draw_sw_grad_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); + lv_draw_sw_grad_conical_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, top_y - bg_coords.y1, coords_bg_w, grad); preblend = true; break; #endif @@ -201,7 +203,7 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const } blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; } - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } if(bottom_y <= clipped_coords.y2) { @@ -210,6 +212,7 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const switch(grad_dir) { case LV_GRAD_DIR_VER: + LV_ASSERT_NULL(grad); blend_dsc.color = grad->color_map[bottom_y - bg_coords.y1]; blend_dsc.opa = grad->opa_map[bottom_y - bg_coords.y1]; break; @@ -218,15 +221,18 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const 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); + lv_draw_sw_grad_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); + lv_draw_sw_grad_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); + lv_draw_sw_grad_conical_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, bottom_y - bg_coords.y1, coords_bg_w, + grad); preblend = true; break; #endif @@ -247,7 +253,7 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const } blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; } - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } } @@ -259,7 +265,7 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const blend_area.y2 = bg_coords.y2 - rout; blend_dsc.opa = opa; blend_dsc.mask_buf = NULL; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } /*With gradient draw line by line*/ else { @@ -277,6 +283,7 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const 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; + break; default: break; } @@ -289,25 +296,26 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const switch(grad_dir) { case LV_GRAD_DIR_VER: + LV_ASSERT_NULL(grad); 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); + lv_draw_sw_grad_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); + lv_draw_sw_grad_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); + lv_draw_sw_grad_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); + lv_draw_sw_blend(t, &blend_dsc); } } @@ -316,19 +324,19 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, lv_draw_fill_dsc_t * dsc, const lv_draw_sw_mask_free_param(&mask_rout_param); } if(grad) { - lv_gradient_cleanup(grad); + lv_draw_sw_grad_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); + lv_draw_sw_grad_linear_cleanup(&dsc->grad); break; case LV_GRAD_DIR_RADIAL: - lv_gradient_radial_cleanup(&dsc->grad); + lv_draw_sw_grad_radial_cleanup(&dsc->grad); break; case LV_GRAD_DIR_CONICAL: - lv_gradient_conical_cleanup(&dsc->grad); + lv_draw_sw_grad_conical_cleanup(&dsc->grad); break; default: break; 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_grad.c similarity index 78% rename from lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient.c rename to lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_grad.c index 92627108c..4550a6c95 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_grad.c @@ -1,12 +1,12 @@ -/** - * @file lv_draw_sw_gradient.c +/** + * @file lv_draw_sw_grad.c * */ /********************* * INCLUDES *********************/ -#include "lv_draw_sw_gradient_private.h" +#include "lv_draw_sw_grad.h" #if LV_USE_DRAW_SW #include "../../misc/lv_types.h" @@ -46,7 +46,7 @@ typedef struct { 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_draw_sw_grad_calc_t * cgrad; /*256 element cache buffer containing the gradient color map*/ } lv_grad_radial_state_t; typedef struct { @@ -54,7 +54,7 @@ typedef struct { int32_t a; int32_t b; int32_t c; - lv_grad_t * cgrad; /*256 element cache buffer containing the gradient color map*/ + lv_draw_sw_grad_calc_t * cgrad; /*256 element cache buffer containing the gradient color map*/ } lv_grad_linear_state_t; typedef struct { @@ -64,7 +64,7 @@ typedef struct { int32_t a; int32_t da; int32_t inv_da; - lv_grad_t * cgrad; /*256 element cache buffer containing the gradient color map*/ + lv_draw_sw_grad_calc_t * cgrad; /*256 element cache buffer containing the gradient color map*/ } lv_grad_conical_state_t; #endif @@ -72,8 +72,8 @@ typedef struct { /********************** * 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); +typedef lv_result_t (*op_cache_t)(lv_draw_sw_grad_calc_t * c, void * ctx); +static lv_draw_sw_grad_calc_t * allocate_item(const lv_grad_dsc_t * g, int32_t w, int32_t h); #if LV_USE_DRAW_SW_COMPLEX_GRADIENTS @@ -89,7 +89,7 @@ static lv_grad_t * allocate_item(const lv_grad_dsc_t * g, int32_t w, int32_t h); * STATIC FUNCTIONS **********************/ -static lv_grad_t * allocate_item(const lv_grad_dsc_t * g, int32_t w, int32_t h) +static lv_draw_sw_grad_calc_t * allocate_item(const lv_grad_dsc_t * g, int32_t w, int32_t h) { int32_t size; switch(g->dir) { @@ -106,8 +106,9 @@ static lv_grad_t * allocate_item(const lv_grad_dsc_t * g, int32_t w, int32_t h) 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); + size_t req_size = ALIGN(sizeof(lv_draw_sw_grad_calc_t)) + ALIGN(size * sizeof(lv_color_t)) + ALIGN(size * sizeof( + lv_opa_t)); + lv_draw_sw_grad_calc_t * item = lv_malloc(req_size); LV_ASSERT_MALLOC(item); if(item == NULL) return NULL; @@ -141,13 +142,13 @@ static inline int32_t extend_w(int32_t w, lv_grad_extend_t extend) * FUNCTIONS **********************/ -lv_grad_t * lv_gradient_get(const lv_grad_dsc_t * g, int32_t w, int32_t h) +lv_draw_sw_grad_calc_t * lv_draw_sw_grad_get(const lv_grad_dsc_t * g, int32_t w, int32_t h) { /* No gradient, no cache */ if(g->dir == LV_GRAD_DIR_NONE) return NULL; /* Step 1: Search cache for the given key */ - lv_grad_t * item = allocate_item(g, w, h); + lv_draw_sw_grad_calc_t * item = allocate_item(g, w, h); if(item == NULL) { LV_LOG_WARN("Failed to allocate item for the gradient"); return item; @@ -156,15 +157,15 @@ lv_grad_t * lv_gradient_get(const lv_grad_dsc_t * g, int32_t w, int32_t h) /* Step 3: Fill it with the gradient, as expected */ uint32_t i; for(i = 0; i < item->size; i++) { - lv_gradient_color_calculate(g, item->size, i, &item->color_map[i], &item->opa_map[i]); + lv_draw_sw_grad_color_calculate(g, item->size, i, &item->color_map[i], &item->opa_map[i]); } return item; } -void LV_ATTRIBUTE_FAST_MEM lv_gradient_color_calculate(const lv_grad_dsc_t * dsc, int32_t range, - int32_t frac, lv_grad_color_t * color_out, lv_opa_t * opa_out) +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_grad_color_calculate(const lv_grad_dsc_t * dsc, int32_t range, + int32_t frac, lv_color_t * color_out, lv_opa_t * opa_out) { - lv_grad_color_t tmp; + lv_color_t tmp; /*Clip out-of-bounds first*/ int32_t min = (dsc->stops[0].frac * range) >> 8; if(frac <= min) { @@ -214,22 +215,11 @@ void LV_ATTRIBUTE_FAST_MEM lv_gradient_color_calculate(const lv_grad_dsc_t * dsc *opa_out = LV_UDIV255(dsc->stops[found_i].opa * mix + dsc->stops[found_i - 1].opa * imix); } -void lv_gradient_cleanup(lv_grad_t * grad) +void lv_draw_sw_grad_cleanup(lv_draw_sw_grad_calc_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 @@ -277,7 +267,7 @@ void lv_gradient_init_stops(lv_grad_dsc_t * grad, const lv_color_t colors[], con */ -void lv_gradient_radial_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_sw_grad_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; @@ -305,7 +295,7 @@ void lv_gradient_radial_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) LV_ASSERT(r_end != 0); /* Create gradient color map */ - state->cgrad = lv_gradient_get(dsc, 256, 0); + state->cgrad = lv_draw_sw_grad_get(dsc, 256, 0); state->x0 = start.x; state->y0 = start.y; @@ -347,23 +337,23 @@ void lv_gradient_radial_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) } } -void lv_gradient_radial_cleanup(lv_grad_dsc_t * dsc) +void lv_draw_sw_grad_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_draw_sw_grad_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) +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_grad_radial_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, lv_draw_sw_grad_calc_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; + lv_draw_sw_grad_calc_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; @@ -466,7 +456,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_gradient_radial_get_line(lv_grad_dsc_t * dsc, int3 */ -void lv_gradient_linear_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_sw_grad_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; @@ -474,7 +464,7 @@ void lv_gradient_linear_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) dsc->state = state; /* Create gradient color map */ - state->cgrad = lv_gradient_get(dsc, 256, 0); + state->cgrad = lv_draw_sw_grad_get(dsc, 256, 0); /* Convert from percentage coordinates */ int32_t wdt = lv_area_get_width(coords); @@ -490,12 +480,13 @@ void lv_gradient_linear_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) int32_t dy = end.y - start.y; int32_t l2 = lv_sqr(dx) + lv_sqr(dy); + if(l2 == 0) l2 = 1; 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) +void lv_draw_sw_grad_linear_cleanup(lv_grad_dsc_t * dsc) { lv_grad_linear_state_t * state = dsc->state; if(state == NULL) @@ -505,13 +496,13 @@ void lv_gradient_linear_cleanup(lv_grad_dsc_t * dsc) 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) +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_grad_linear_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, lv_draw_sw_grad_calc_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; + lv_draw_sw_grad_calc_t * grad = state->cgrad; int32_t w; /* the result: this is an offset into the 256 element gradient color table */ int32_t x, d; @@ -539,7 +530,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_gradient_linear_get_line(lv_grad_dsc_t * dsc, int3 w is the unknown variable */ -void lv_gradient_conical_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_sw_grad_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; @@ -548,7 +539,7 @@ void lv_gradient_conical_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) dsc->state = state; /* Create gradient color map */ - state->cgrad = lv_gradient_get(dsc, 256, 0); + state->cgrad = lv_draw_sw_grad_get(dsc, 256, 0); /* Convert from percentage coordinates */ int32_t wdt = lv_area_get_width(coords); @@ -567,7 +558,7 @@ void lv_gradient_conical_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) state->inv_da = (1 << 16) / (beta - alpha); } -void lv_gradient_conical_cleanup(lv_grad_dsc_t * dsc) +void lv_draw_sw_grad_conical_cleanup(lv_grad_dsc_t * dsc) { lv_grad_conical_state_t * state = dsc->state; if(state == NULL) @@ -577,13 +568,13 @@ void lv_gradient_conical_cleanup(lv_grad_dsc_t * dsc) 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) +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_grad_conical_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, lv_draw_sw_grad_calc_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; + lv_draw_sw_grad_calc_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; @@ -618,51 +609,6 @@ void LV_ATTRIBUTE_FAST_MEM lv_gradient_conical_get_line(lv_grad_dsc_t * dsc, int } } -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_grad.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_grad.h new file mode 100644 index 000000000..42b36c211 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_grad.h @@ -0,0 +1,147 @@ +/** + * @file lv_draw_sw_grad.h + * + */ + +#ifndef LV_DRAW_SW_GRAD_H +#define LV_DRAW_SW_GRAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_color.h" +#include "../../misc/lv_style.h" + +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_color_t * color_map; + lv_opa_t * opa_map; + uint32_t size; +} lv_draw_sw_grad_calc_t; + + +/********************** + * PROTOTYPES + **********************/ + +/** Compute the color in the given gradient and fraction + * Gradient are specified in a virtual [0-255] range, so this function scales the virtual range to the given range + * @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_draw_sw_grad_color_calculate(const lv_grad_dsc_t * dsc, int32_t range, + int32_t frac, lv_color_t * color_out, lv_opa_t * opa_out); + +/** Get a gradient cache from the given parameters */ +lv_draw_sw_grad_calc_t * lv_draw_sw_grad_get(const lv_grad_dsc_t * gradient, int32_t w, int32_t h); + +/** + * Clean up the gradient item after it was get with `lv_grad_get_from_cache`. + * @param grad pointer to a gradient + */ +void lv_draw_sw_grad_cleanup(lv_draw_sw_grad_calc_t * grad); + +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + + +/** + * Calculate constants from the given parameters that are used during rendering + * @param dsc gradient descriptor + * @param coords the area where to draw the gradient + */ +void lv_draw_sw_grad_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_draw_sw_grad_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_draw_sw_grad_linear_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, + lv_draw_sw_grad_calc_t * result); + +/** + * Calculate constants from the given parameters that are used during rendering + * @param dsc gradient descriptor + * @param coords the area where to draw the gradient + */ +void lv_draw_sw_grad_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_draw_sw_grad_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_draw_sw_grad_radial_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, + lv_draw_sw_grad_calc_t * result); + +/** + * Calculate constants from the given parameters that are used during rendering + * @param dsc gradient descriptor + * @param coords the area where to draw the gradient + */ +void lv_draw_sw_grad_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_draw_sw_grad_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_draw_sw_grad_conical_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, + lv_draw_sw_grad_calc_t * result); + +#endif /*LV_USE_DRAW_SW_COMPLEX_GRADIENTS*/ + +#endif /*LV_USE_DRAW_SW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_GRADIENT_H*/ 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 deleted file mode 100644 index 01029cbab..000000000 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient.h +++ /dev/null @@ -1,203 +0,0 @@ -/** - * @file lv_draw_sw_gradient.h - * - */ - -#ifndef LV_DRAW_SW_GRADIENT_H -#define LV_DRAW_SW_GRADIENT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ -#include "../../misc/lv_color.h" -#include "../../misc/lv_style.h" - -#if LV_USE_DRAW_SW - -/********************* - * DEFINES - *********************/ -#if LV_GRADIENT_MAX_STOPS < 2 -#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; - -/********************** - * PROTOTYPES - **********************/ -/** Compute the color in the given gradient and fraction - * Gradient are specified in a virtual [0-255] range, so this function scales the virtual range to the given range - * @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, - int32_t frac, lv_grad_color_t * color_out, lv_opa_t * opa_out); - -/** Get a gradient cache from the given parameters */ -lv_grad_t * lv_gradient_get(const lv_grad_dsc_t * gradient, int32_t w, int32_t h); - -/** - * Clean up the gradient item after it was get with `lv_grad_get_from_cache`. - * @param grad pointer to a gradient - */ -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 -} /*extern "C"*/ -#endif - -#endif /*LV_DRAW_GRADIENT_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 42179a2a2..5d5574cff 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 * */ @@ -43,10 +43,18 @@ #define LV_DRAW_SW_RGB565_RECOLOR(...) LV_RESULT_INVALID #endif +#ifndef LV_DRAW_SW_RGB565_SWAPPED_RECOLOR + #define LV_DRAW_SW_RGB565_SWAPPED_RECOLOR(...) LV_RESULT_INVALID +#endif + #ifndef LV_DRAW_SW_RGB888_RECOLOR #define LV_DRAW_SW_RGB888_RECOLOR(...) LV_RESULT_INVALID #endif +#ifndef LV_DRAW_SW_ARGB8888_PREMULTIPLIED_RECOLOR + #define LV_DRAW_SW_ARGB8888_PREMULTIPLIED_RECOLOR(...) LV_RESULT_INVALID +#endif + /********************** * TYPEDEFS **********************/ @@ -55,10 +63,31 @@ * STATIC PROTOTYPES **********************/ -static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, + +static void img_draw_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, const lv_area_t * img_coords, const lv_area_t * clipped_img_area); + +#if LV_DRAW_SW_COMPLEX +static void radius_only(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_image_decoder_dsc_t * decoder_dsc, + const lv_area_t * img_coords, const lv_area_t * clipped_img_area); +#endif /*LV_DRAW_SW_COMPLEX*/ + +static void recolor_only(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_image_decoder_dsc_t * decoder_dsc, + const lv_area_t * img_coords, const lv_area_t * clipped_img_area); + +static void transform_and_recolor(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, + const lv_area_t * img_coords, const lv_area_t * clipped_img_area); + +static void recolor(lv_area_t relative_area, uint8_t * src_buf, uint8_t * dest_buf, int32_t src_stride, + lv_color_format_t cf, const lv_draw_image_dsc_t * draw_dsc); + +static bool apply_mask(const lv_draw_image_dsc_t * draw_dsc); + /********************** * STATIC VARIABLES **********************/ @@ -72,7 +101,7 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * GLOBAL FUNCTIONS **********************/ -void lv_draw_sw_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords) +void lv_draw_sw_layer(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords) { lv_layer_t * layer_to_draw = (lv_layer_t *)draw_dsc->src; @@ -80,9 +109,17 @@ void lv_draw_sw_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dr *In this case just return. */ if(layer_to_draw->draw_buf == NULL) return; + if(draw_dsc->bitmap_mask_src) { + bool visible = apply_mask(draw_dsc); + if(!visible) return; + } + + /*The source should be a draw_buf, not a layer*/ lv_draw_image_dsc_t new_draw_dsc = *draw_dsc; new_draw_dsc.src = layer_to_draw->draw_buf; - lv_draw_sw_image(draw_unit, &new_draw_dsc, coords); + + lv_draw_sw_image(t, &new_draw_dsc, coords); + #if LV_USE_LAYER_DEBUG || LV_USE_PARALLEL_DRAW_DEBUG lv_area_t area_rot; lv_area_copy(&area_rot, coords); @@ -99,77 +136,76 @@ 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, &t->clip_area)) return; #endif #if LV_USE_LAYER_DEBUG - lv_draw_fill_dsc_t fill_dsc; - lv_draw_fill_dsc_init(&fill_dsc); - fill_dsc.color = lv_color_hex(layer_to_draw->color_format == LV_COLOR_FORMAT_ARGB8888 ? 0xff0000 : 0x00ff00); - fill_dsc.opa = LV_OPA_20; - lv_draw_sw_fill(draw_unit, &fill_dsc, &area_rot); + { + lv_draw_fill_dsc_t fill_dsc; + lv_draw_fill_dsc_init(&fill_dsc); + fill_dsc.color = lv_color_hex(layer_to_draw->color_format == LV_COLOR_FORMAT_ARGB8888 ? 0xff0000 : 0x00ff00); + fill_dsc.opa = LV_OPA_20; + lv_draw_sw_fill(t, &fill_dsc, &area_rot); - lv_draw_border_dsc_t border_dsc; - lv_draw_border_dsc_init(&border_dsc); - border_dsc.color = fill_dsc.color; - border_dsc.opa = LV_OPA_60; - border_dsc.width = 2; - lv_draw_sw_border(draw_unit, &border_dsc, &area_rot); + lv_draw_border_dsc_t border_dsc; + lv_draw_border_dsc_init(&border_dsc); + border_dsc.color = fill_dsc.color; + border_dsc.opa = LV_OPA_60; + border_dsc.width = 2; + lv_draw_sw_border(t, &border_dsc, &area_rot); + } #endif #if LV_USE_PARALLEL_DRAW_DEBUG - uint32_t idx = 0; - lv_draw_unit_t * draw_unit_tmp = _draw_info.unit_head; - while(draw_unit_tmp != draw_unit) { - draw_unit_tmp = draw_unit_tmp->next; - idx++; + { + int32_t idx = t->draw_unit->idx; + + lv_draw_fill_dsc_t fill_dsc; + lv_draw_fill_dsc_init(&fill_dsc); + fill_dsc.color = lv_palette_main(idx % LV_PALETTE_LAST); + fill_dsc.opa = LV_OPA_10; + lv_draw_sw_fill(t, &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.opa = LV_OPA_60; + border_dsc.width = 1; + lv_draw_sw_border(t, &border_dsc, &area_rot); + + lv_point_t txt_size; + lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE); + + lv_area_t txt_area; + txt_area.x1 = draw_area.x1; + txt_area.x2 = draw_area.x1 + txt_size.x - 1; + txt_area.y2 = draw_area.y2; + txt_area.y1 = draw_area.y2 - txt_size.y + 1; + + lv_draw_fill_dsc_init(&fill_dsc); + fill_dsc.color = lv_color_black(); + lv_draw_sw_fill(t, &fill_dsc, &txt_area); + + char buf[8]; + lv_snprintf(buf, sizeof(buf), "%d", idx); + lv_draw_label_dsc_t label_dsc; + lv_draw_label_dsc_init(&label_dsc); + label_dsc.color = lv_color_white(); + label_dsc.text = buf; + lv_draw_sw_label(t, &label_dsc, &txt_area); } - - 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.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.opa = LV_OPA_100; - border_dsc.width = 2; - lv_draw_sw_border(draw_unit, &border_dsc, &area_rot); - - lv_point_t txt_size; - lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE); - - lv_area_t txt_area; - txt_area.x1 = draw_area.x1; - txt_area.x2 = draw_area.x1 + txt_size.x - 1; - txt_area.y2 = draw_area.y2; - txt_area.y1 = draw_area.y2 - txt_size.y + 1; - - lv_draw_fill_dsc_init(&fill_dsc); - fill_dsc.color = lv_color_black(); - lv_draw_sw_fill(draw_unit, &fill_dsc, &txt_area); - - char buf[8]; - lv_snprintf(buf, sizeof(buf), "%d", idx); - lv_draw_label_dsc_t label_dsc; - lv_draw_label_dsc_init(&label_dsc); - label_dsc.color = lv_color_white(); - label_dsc.text = buf; - lv_draw_sw_label(draw_unit, &label_dsc, &txt_area); #endif } -void lv_draw_sw_image(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, +void lv_draw_sw_image(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, 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(t, 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(t, draw_dsc, coords, img_draw_core); } } @@ -177,30 +213,30 @@ void lv_draw_sw_image(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dr * STATIC FUNCTIONS **********************/ -static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, +static void img_draw_core(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, const lv_area_t * img_coords, const lv_area_t * clipped_img_area) { bool transformed = draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE || draw_dsc->scale_y != LV_SCALE_NONE ? true : false; - bool masked = draw_dsc->bitmap_mask_src != NULL; + bool radius = draw_dsc->clip_radius > 0; - lv_draw_sw_blend_dsc_t blend_dsc; const lv_draw_buf_t * decoded = decoder_dsc->decoded; const uint8_t * src_buf = decoded->data; const lv_image_header_t * header = &decoded->header; uint32_t img_stride = decoded->header.stride; lv_color_format_t cf = decoded->header.cf; + lv_draw_sw_blend_dsc_t blend_dsc; lv_memzero(&blend_dsc, sizeof(lv_draw_sw_blend_dsc_t)); blend_dsc.opa = draw_dsc->opa; blend_dsc.blend_mode = draw_dsc->blend_mode; blend_dsc.src_stride = img_stride; - if(!transformed && !masked && cf == LV_COLOR_FORMAT_A8) { + if(!transformed && !radius && 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, &t->clip_area)) return; blend_dsc.mask_buf = (lv_opa_t *)src_buf; blend_dsc.mask_area = img_coords; @@ -210,9 +246,9 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; blend_dsc.blend_area = img_coords; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } - else if(!transformed && !masked && cf == LV_COLOR_FORMAT_RGB565A8 && draw_dsc->recolor_opa <= LV_OPA_MIN) { + else if(!transformed && !radius && cf == LV_COLOR_FORMAT_RGB565A8 && draw_dsc->recolor_opa <= LV_OPA_MIN) { int32_t src_h = lv_area_get_height(img_coords); int32_t src_w = lv_area_get_width(img_coords); blend_dsc.src_area = img_coords; @@ -229,52 +265,32 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t blend_dsc.mask_area = img_coords; blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; blend_dsc.src_color_format = LV_COLOR_FORMAT_RGB565; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); + } + else if(!transformed && !radius && (cf == LV_COLOR_FORMAT_L8 || cf == LV_COLOR_FORMAT_AL88)) { + blend_dsc.src_area = img_coords; + blend_dsc.src_buf = src_buf; + blend_dsc.blend_area = img_coords; + blend_dsc.src_color_format = cf; + lv_draw_sw_blend(t, &blend_dsc); } /*The simplest case just copy the pixels into the draw_buf. Blending will convert the colors if needed*/ - else if(!transformed && !masked && draw_dsc->recolor_opa <= LV_OPA_MIN) { + else if(!transformed && !radius && draw_dsc->recolor_opa <= LV_OPA_MIN) { blend_dsc.src_area = img_coords; blend_dsc.src_buf = src_buf; blend_dsc.blend_area = img_coords; blend_dsc.src_color_format = cf; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } + else if(!transformed && !radius && draw_dsc->recolor_opa > LV_OPA_MIN) { + recolor_only(t, draw_dsc, decoder_dsc, img_coords, clipped_img_area); + } +#if LV_DRAW_SW_COMPLEX /*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; - lv_draw_sw_blend(draw_unit, &blend_dsc); - - if(decoder_res == LV_RESULT_OK) lv_image_decoder_close(&mask_decoder_dsc); + else if(!transformed && radius && draw_dsc->recolor_opa <= LV_OPA_MIN) { + radius_only(t, draw_dsc, decoder_dsc, img_coords, clipped_img_area); } +#endif /*LV_DRAW_SW_COMPLEX*/ /* 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 */ @@ -282,184 +298,536 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t img_coords, /* src_h, src_w, src_x1, src_y1 */ img_stride, /* image stride */ clipped_img_area, /* blend area */ - draw_unit, /* target buffer, buffer width, buffer height, buffer stride */ + t, /* target buffer, buffer width, buffer height, buffer stride */ draw_dsc)) { /* opa, recolour_opa and colour */ /*In the other cases every pixel need to be checked one-by-one*/ + transform_and_recolor(t, draw_dsc, decoder_dsc, sup, img_coords, clipped_img_area); - lv_area_t blend_area = *clipped_img_area; - blend_dsc.blend_area = &blend_area; + } +} +#if LV_DRAW_SW_COMPLEX +static void radius_only(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_image_decoder_dsc_t * decoder_dsc, + const lv_area_t * img_coords, const lv_area_t * clipped_img_area) +{ - int32_t src_w = lv_area_get_width(img_coords); - int32_t src_h = lv_area_get_height(img_coords); - int32_t blend_w = lv_area_get_width(&blend_area); - int32_t blend_h = lv_area_get_height(&blend_area); + const lv_draw_buf_t * decoded = decoder_dsc->decoded; + uint32_t img_stride = decoded->header.stride; + lv_color_format_t cf = decoded->header.cf; + lv_color_format_t cf_ori = cf; - 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(cf == LV_COLOR_FORMAT_RGB565A8) { + cf = LV_COLOR_FORMAT_RGB565; + } + + lv_draw_sw_blend_dsc_t blend_dsc; + lv_memzero(&blend_dsc, sizeof(lv_draw_sw_blend_dsc_t)); + blend_dsc.opa = draw_dsc->opa; + blend_dsc.blend_mode = draw_dsc->blend_mode; + blend_dsc.src_stride = img_stride; + blend_dsc.src_area = img_coords; + blend_dsc.src_buf = decoded->data; + blend_dsc.src_color_format = cf; + + lv_area_t blend_area = *clipped_img_area; + blend_dsc.blend_area = &blend_area; + int32_t y_last = blend_area.y2; + blend_area.y2 = blend_area.y1; + + int32_t blend_w = lv_area_get_width(&blend_area); + uint8_t * mask_buf = lv_malloc(blend_w); + blend_dsc.mask_buf = mask_buf; + blend_dsc.mask_area = &blend_area; + blend_dsc.mask_stride = blend_w; + + if(cf == LV_COLOR_FORMAT_A8) { + blend_dsc.src_buf = NULL; + blend_dsc.color = draw_dsc->recolor; + } + + lv_draw_sw_mask_radius_param_t mask_param; + lv_draw_sw_mask_radius_init(&mask_param, &draw_dsc->image_area, draw_dsc->clip_radius, false); + + void * masks[2] = {0}; + masks[0] = &mask_param; + + int32_t image_h = lv_area_get_height(img_coords); + while(blend_area.y1 <= y_last) { + if(cf_ori == LV_COLOR_FORMAT_RGB565A8) { + const uint8_t * mask_start = decoded->data + img_stride * image_h; + int32_t y_ofs = blend_area.y1 - img_coords->y1; + int32_t x_ofs = blend_area.x1 - img_coords->x1; + lv_memcpy(mask_buf, mask_start + y_ofs * img_stride / 2 + x_ofs, blend_w); } - if(transformed) { - 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; - uint32_t px_size = lv_color_format_get_size(cf_final); - int32_t buf_h; - if(cf_final == LV_COLOR_FORMAT_RGB565A8) { - uint32_t buf_stride = blend_w * 3; - buf_h = MAX_BUF_SIZE / buf_stride; - if(buf_h > blend_h) buf_h = blend_h; - tmp_buf = lv_malloc(buf_stride * buf_h); + else if(cf_ori == LV_COLOR_FORMAT_A8) { + int32_t y_ofs = blend_area.y1 - img_coords->y1; + int32_t x_ofs = blend_area.x1 - img_coords->x1; + lv_memcpy(mask_buf, decoded->data + y_ofs * img_stride + x_ofs, blend_w); } else { - uint32_t buf_stride = blend_w * lv_color_format_get_size(cf_final); - buf_h = MAX_BUF_SIZE / buf_stride; - if(buf_h > blend_h) buf_h = blend_h; - tmp_buf = lv_malloc(buf_stride * buf_h); - } - LV_ASSERT_MALLOC(tmp_buf); + lv_memset(mask_buf, 0xff, blend_w); - blend_dsc.src_buf = tmp_buf; - blend_dsc.src_color_format = cf_final; - int32_t y_last = blend_area.y2; + } + + blend_dsc.mask_res = lv_draw_sw_mask_apply(masks, mask_buf, blend_area.x1, blend_area.y1, blend_w); + + if(cf_ori == LV_COLOR_FORMAT_RGB565A8 || cf_ori == LV_COLOR_FORMAT_A8) { + blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; + } + + /*Blend*/ + lv_draw_sw_blend(t, &blend_dsc); + + /*Go to the next area*/ + blend_area.y1 ++; + blend_area.y2 ++; + } + lv_free(mask_buf); + +} +#endif /*LV_DRAW_SW_COMPLEX*/ +static void recolor_only(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_image_decoder_dsc_t * decoder_dsc, + const lv_area_t * img_coords, const lv_area_t * clipped_img_area) +{ + lv_area_t blend_area = *clipped_img_area; + + const lv_draw_buf_t * decoded = decoder_dsc->decoded; + uint32_t img_stride = decoded->header.stride; + lv_color_format_t cf = decoded->header.cf; + uint32_t px_size = lv_color_format_get_size(cf); + int32_t src_h = lv_area_get_height(img_coords); + int32_t blend_w = lv_area_get_width(&blend_area); + int32_t blend_h = lv_area_get_height(&blend_area); + uint8_t * tmp_buf; + int32_t buf_h; + uint32_t buf_stride = blend_w * px_size; + if(buf_stride == 0) { + buf_stride = 1; + } + buf_h = MAX_BUF_SIZE / buf_stride; + if(buf_h > blend_h) buf_h = blend_h; + tmp_buf = lv_malloc(buf_stride * buf_h); + + lv_draw_sw_blend_dsc_t blend_dsc; + lv_memzero(&blend_dsc, sizeof(lv_draw_sw_blend_dsc_t)); + blend_dsc.opa = draw_dsc->opa; + blend_dsc.blend_mode = draw_dsc->blend_mode; + blend_dsc.src_stride = blend_w * px_size; + blend_dsc.src_area = &blend_area; + blend_dsc.blend_area = &blend_area; + blend_dsc.src_buf = tmp_buf; + blend_dsc.src_color_format = cf; + if(cf == LV_COLOR_FORMAT_RGB565A8) { + blend_dsc.mask_area = img_coords; + blend_dsc.mask_buf = decoded->data + img_stride * src_h; + blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; + blend_dsc.src_color_format = LV_COLOR_FORMAT_RGB565; + blend_dsc.mask_stride = img_stride / 2; + } + + int32_t y_last = blend_area.y2; + blend_area.y2 = blend_area.y1 + buf_h - 1; + while(blend_area.y1 <= y_last) { + lv_area_t relative_area; + lv_area_copy(&relative_area, &blend_area); + lv_area_move(&relative_area, -img_coords->x1, -img_coords->y1); + recolor(relative_area, decoded->data, tmp_buf, img_stride, blend_dsc.src_color_format, draw_dsc); + + lv_draw_sw_blend(t, &blend_dsc); + + /*Go to the next area*/ + blend_area.y1 = blend_area.y2 + 1; blend_area.y2 = blend_area.y1 + buf_h - 1; - - blend_dsc.src_area = &blend_area; - if(cf_final == LV_COLOR_FORMAT_RGB565A8) { - /*RGB565A8 images will blended as RGB565 + mask - *Therefore the stride can be different. */ - blend_dsc.src_stride = blend_w * 2; - blend_dsc.mask_buf = tmp_buf + blend_w * 2 * buf_h; - blend_dsc.mask_stride = blend_w; - blend_dsc.mask_area = &blend_area; - blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; - blend_dsc.src_color_format = LV_COLOR_FORMAT_RGB565; - } - else if(cf_final == LV_COLOR_FORMAT_A8) { - blend_dsc.mask_buf = blend_dsc.src_buf; - blend_dsc.mask_stride = blend_w; - blend_dsc.mask_area = &blend_area; - blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; - blend_dsc.color = draw_dsc->recolor; - blend_dsc.src_buf = NULL; - } - else { - blend_dsc.src_stride = blend_w * lv_color_format_get_size(cf_final); + if(blend_area.y2 > y_last) { + blend_area.y2 = y_last; } - while(blend_area.y1 <= y_last) { - /*Apply transformations if any or separate the channels*/ - lv_area_t relative_area; - lv_area_copy(&relative_area, &blend_area); - lv_area_move(&relative_area, -img_coords->x1, -img_coords->y1); - if(transformed) { - lv_draw_sw_transform(draw_unit, &relative_area, src_buf, src_w, src_h, img_stride, - draw_dsc, sup, cf, tmp_buf); + } + + lv_free(tmp_buf); + +} + +static void transform_and_recolor(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, + const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup, + const lv_area_t * img_coords, const lv_area_t * clipped_img_area) + +{ + const lv_draw_buf_t * decoded = decoder_dsc->decoded; + uint32_t img_stride = decoded->header.stride; + lv_color_format_t cf = decoded->header.cf; + lv_draw_sw_blend_dsc_t blend_dsc; + lv_memzero(&blend_dsc, sizeof(lv_draw_sw_blend_dsc_t)); + blend_dsc.opa = draw_dsc->opa; + blend_dsc.blend_mode = draw_dsc->blend_mode; + + lv_area_t blend_area = *clipped_img_area; + blend_dsc.blend_area = &blend_area; + + int32_t src_w = lv_area_get_width(img_coords); + int32_t src_h = lv_area_get_height(img_coords); + int32_t blend_w = lv_area_get_width(&blend_area); + int32_t blend_h = lv_area_get_height(&blend_area); + + bool do_recolor = draw_dsc->recolor_opa > LV_OPA_MIN; + if(cf == LV_COLOR_FORMAT_L8 || cf == LV_COLOR_FORMAT_A8) { + blend_dsc.color = draw_dsc->recolor; + do_recolor = false; + } + + lv_color_format_t cf_final = cf; + 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_RGB565_SWAPPED) cf_final = LV_COLOR_FORMAT_RGB565A8; + else if(cf_final == LV_COLOR_FORMAT_L8) cf_final = LV_COLOR_FORMAT_AL88; + + uint8_t * transformed_buf; + int32_t buf_h; + if(cf_final == LV_COLOR_FORMAT_RGB565A8) { + uint32_t buf_stride = blend_w * 3; + buf_h = MAX_BUF_SIZE / buf_stride; + if(buf_h > blend_h) buf_h = blend_h; + transformed_buf = lv_malloc(buf_stride * buf_h); + } + else { + uint32_t buf_stride = blend_w * lv_color_format_get_size(cf_final); + buf_h = MAX_BUF_SIZE / buf_stride; + if(buf_h > blend_h) buf_h = blend_h; + transformed_buf = lv_malloc(buf_stride * buf_h); + } + LV_ASSERT_MALLOC(transformed_buf); + + blend_dsc.src_buf = transformed_buf; + blend_dsc.src_color_format = cf_final; + int32_t y_last = blend_area.y2; + blend_area.y2 = blend_area.y1 + buf_h - 1; + + blend_dsc.src_area = &blend_area; + const uint8_t * src_buf = decoded->data; + if(cf_final == LV_COLOR_FORMAT_RGB565A8) { + /*RGB565A8 images will blended as RGB565 + mask + *Therefore the stride can be different. */ + blend_dsc.src_stride = blend_w * 2; + blend_dsc.mask_area = &blend_area; + blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; + blend_dsc.mask_buf = transformed_buf + blend_w * 2 * buf_h; + blend_dsc.src_color_format = LV_COLOR_FORMAT_RGB565; + } + else if(cf_final == LV_COLOR_FORMAT_A8) { + blend_dsc.mask_buf = transformed_buf; + blend_dsc.mask_stride = blend_w; + blend_dsc.mask_area = &blend_area; + blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; + blend_dsc.src_buf = NULL; + } + else { + blend_dsc.src_stride = blend_w * lv_color_format_get_size(cf_final); + } + + while(blend_area.y1 <= y_last) { + /*Apply transformations if any or separate the channels*/ + lv_area_t relative_area; + lv_area_copy(&relative_area, &blend_area); + lv_area_move(&relative_area, -img_coords->x1, -img_coords->y1); + lv_draw_sw_transform(&relative_area, src_buf, src_w, src_h, img_stride, + draw_dsc, sup, cf, transformed_buf); + + if(do_recolor) { + lv_area_t relative_area2; + lv_area_copy(&relative_area2, &blend_area); + lv_area_move(&relative_area2, -blend_area.x1, -blend_area.y1); + recolor(relative_area2, transformed_buf, transformed_buf, blend_dsc.src_stride, cf_final, draw_dsc); + } + + /*Blend*/ + lv_draw_sw_blend(t, &blend_dsc); + + /*Go to the next area*/ + blend_area.y1 = blend_area.y2 + 1; + blend_area.y2 = blend_area.y1 + buf_h - 1; + if(blend_area.y2 > y_last) { + blend_area.y2 = y_last; + if(cf_final == LV_COLOR_FORMAT_RGB565A8) { + blend_dsc.mask_buf = transformed_buf + blend_w * 2 * lv_area_get_height(&blend_area); } - else if(draw_dsc->recolor_opa >= LV_OPA_MIN) { - int32_t h = lv_area_get_height(&relative_area); - 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 + - relative_area.x1; - uint8_t * rgb_dest_buf = tmp_buf; - uint8_t * a_dest_buf = (uint8_t *)blend_dsc.mask_buf; - int32_t i; - for(i = 0; i < h; i++) { - lv_memcpy(rgb_dest_buf, rgb_src_buf, blend_w * 2); - lv_memcpy(a_dest_buf, a_src_buf, blend_w); - rgb_src_buf += stride_px * 2; - a_src_buf += stride_px; - rgb_dest_buf += blend_w * 2; - a_dest_buf += blend_w; - } - } - else if(cf_final != LV_COLOR_FORMAT_A8) { - const uint8_t * src_buf_tmp = src_buf + img_stride * relative_area.y1 + relative_area.x1 * px_size; - uint8_t * dest_buf_tmp = tmp_buf; - int32_t i; - for(i = 0; i < h; i++) { - lv_memcpy(dest_buf_tmp, src_buf_tmp, blend_w * px_size); - dest_buf_tmp += blend_w * px_size; - src_buf_tmp += img_stride; + } + } + + lv_free(transformed_buf); +} + +static void recolor(lv_area_t relative_area, uint8_t * src_buf, uint8_t * dest_buf, int32_t src_stride, + lv_color_format_t cf, const lv_draw_image_dsc_t * draw_dsc) +{ + int32_t w = lv_area_get_width(&relative_area); + int32_t h = lv_area_get_height(&relative_area); + + /*Apply recolor*/ + lv_color_t color = draw_dsc->recolor; + lv_opa_t mix = draw_dsc->recolor_opa; + lv_opa_t mix_inv = 255 - mix; + + if(cf == LV_COLOR_FORMAT_RGB565A8 || cf == LV_COLOR_FORMAT_RGB565) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_RECOLOR(dest_buf, relative_area, color, mix)) { + const uint8_t * src_buf_tmp = src_buf + src_stride * relative_area.y1 + relative_area.x1 * 2; + int32_t img_stride_px = src_stride / 2; + + uint16_t * buf16_src = (uint16_t *)src_buf_tmp; + uint16_t * buf16_dest = (uint16_t *)dest_buf; + uint16_t color16 = lv_color_to_u16(color); + if(mix >= LV_OPA_MAX) { + int32_t y; + for(y = 0; y < h; y++) { + int32_t x; + for(x = 0; x < w; x++) { + *buf16_dest = color16; + buf16_dest++; } + buf16_src += img_stride_px; } } + else { + uint16_t c_mult[3]; + c_mult[0] = (color.blue >> 3) * mix; + c_mult[1] = (color.green >> 2) * mix; + c_mult[2] = (color.red >> 3) * mix; - /*Apply recolor*/ - if(draw_dsc->recolor_opa > LV_OPA_MIN) { - lv_color_t color = draw_dsc->recolor; - lv_opa_t mix = draw_dsc->recolor_opa; - lv_opa_t mix_inv = 255 - mix; - if(cf_final == LV_COLOR_FORMAT_RGB565A8 || cf_final == LV_COLOR_FORMAT_RGB565) { - if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_RECOLOR(tmp_buf, blend_area, color, mix)) { - uint16_t c_mult[3]; - c_mult[0] = (color.blue >> 3) * mix; - c_mult[1] = (color.green >> 2) * mix; - c_mult[2] = (color.red >> 3) * mix; - uint16_t * buf16 = (uint16_t *)tmp_buf; - int32_t i; - int32_t size = lv_area_get_size(&blend_area); - for(i = 0; i < size; i++) { - buf16[i] = (((c_mult[2] + ((buf16[i] >> 11) & 0x1F) * mix_inv) << 3) & 0xF800) + - (((c_mult[1] + ((buf16[i] >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0) + - ((c_mult[0] + (buf16[i] & 0x1F) * mix_inv) >> 8); - } + int32_t y; + for(y = 0; y < h; y++) { + int32_t x; + for(x = 0; x < w; x++) { + *buf16_dest = (((c_mult[2] + ((buf16_src[x] >> 11) & 0x1F) * mix_inv) << 3) & 0xF800) + + (((c_mult[1] + ((buf16_src[x] >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0) + + ((c_mult[0] + (buf16_src[x] & 0x1F) * mix_inv) >> 8); + buf16_dest++; } - } - else if(cf_final != LV_COLOR_FORMAT_A8) { - if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_RECOLOR(tmp_buf, blend_area, color, mix, cf_final)) { - uint32_t size = lv_area_get_size(&blend_area); - uint32_t i; - uint16_t c_mult[3]; - c_mult[0] = color.blue * mix; - c_mult[1] = color.green * mix; - c_mult[2] = color.red * mix; - uint8_t * tmp_buf_2 = tmp_buf; - 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; - } - } - } - } - - /*Blend*/ - lv_draw_sw_blend(draw_unit, &blend_dsc); - - /*Go to the next area*/ - blend_area.y1 = blend_area.y2 + 1; - blend_area.y2 = blend_area.y1 + buf_h - 1; - if(blend_area.y2 > y_last) { - blend_area.y2 = y_last; - if(cf_final == LV_COLOR_FORMAT_RGB565A8) { - blend_dsc.mask_buf = tmp_buf + blend_w * 2 * lv_area_get_height(&blend_area); + buf16_src += img_stride_px; } } } + } + else if(cf == LV_COLOR_FORMAT_RGB565_SWAPPED) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB565_SWAPPED_RECOLOR(dest_buf, relative_area, color, mix)) { + const uint8_t * src_buf_tmp = src_buf + src_stride * relative_area.y1 + relative_area.x1 * 2; + int32_t img_stride_px = src_stride / 2; - lv_free(tmp_buf); + uint16_t * buf16_src = (uint16_t *)src_buf_tmp; + uint16_t * buf16_dest = (uint16_t *)dest_buf; + uint16_t color16 = lv_color_to_u16(color); + if(mix >= LV_OPA_MAX) { + int32_t y; + for(y = 0; y < h; y++) { + int32_t x; + for(x = 0; x < w; x++) { + *buf16_dest = color16; + buf16_dest++; + } + buf16_src += img_stride_px; + } + } + else { + uint16_t c_mult[3]; + c_mult[0] = (color.blue >> 3) * mix; + c_mult[1] = (color.green >> 2) * mix; + c_mult[2] = (color.red >> 3) * mix; + + int32_t y; + for(y = 0; y < h; y++) { + int32_t x; + for(x = 0; x < w; x++) { + *buf16_dest = lv_color_swap_16((((c_mult[2] + ((lv_color_swap_16(buf16_src[x]) >> 11) & 0x1F) * mix_inv) << 3) & 0xF800) + + + (((c_mult[1] + ((lv_color_swap_16(buf16_src[x]) >> 5) & 0x3F) * mix_inv) >> 3) & 0x07E0) + + ((c_mult[0] + (lv_color_swap_16(buf16_src[x]) & 0x1F) * mix_inv) >> 8)); + buf16_dest++; + } + buf16_src += img_stride_px; + } + } + } + } + else if(cf == LV_COLOR_FORMAT_RGB888 || cf == LV_COLOR_FORMAT_XRGB8888 || cf == LV_COLOR_FORMAT_ARGB8888) { + if(LV_RESULT_INVALID == LV_DRAW_SW_RGB888_RECOLOR(dest_buf, relative_area, color, mix, cf)) { + uint32_t px_size = lv_color_format_get_size(cf); + src_buf += src_stride * relative_area.y1 + relative_area.x1 * px_size; + if(mix >= LV_OPA_MAX) { + int32_t y; + for(y = 0; y < h; y++) { + int32_t x; + for(x = 0; x < w; x++) { + dest_buf[0] = color.blue; + dest_buf[1] = color.green; + dest_buf[2] = color.red; + if(cf == LV_COLOR_FORMAT_ARGB8888) dest_buf[3] = src_buf[3]; + src_buf += px_size; + dest_buf += px_size; + } + src_buf += src_stride - w * px_size; + } + } + else { + uint16_t c_mult[3]; + c_mult[0] = color.blue * mix; + c_mult[1] = color.green * mix; + c_mult[2] = color.red * mix; + int32_t y; + for(y = 0; y < h; y++) { + int32_t x; + for(x = 0; x < w; x++) { + dest_buf[0] = (c_mult[0] + (src_buf[0] * mix_inv)) >> 8; + dest_buf[1] = (c_mult[1] + (src_buf[1] * mix_inv)) >> 8; + dest_buf[2] = (c_mult[2] + (src_buf[2] * mix_inv)) >> 8; + if(cf == LV_COLOR_FORMAT_ARGB8888) dest_buf[3] = src_buf[3]; + src_buf += px_size; + dest_buf += px_size; + } + src_buf += src_stride - w * px_size; + } + } + } + } + else if(cf == LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED) { + if(LV_RESULT_INVALID == LV_DRAW_SW_ARGB8888_PREMULTIPLIED_RECOLOR(dest_buf, relative_area, color, mix, cf)) { + uint32_t px_size = lv_color_format_get_size(cf); + src_buf += src_stride * relative_area.y1 + relative_area.x1 * px_size; + + uint16_t c_mult[3]; + c_mult[0] = color.blue * mix; + c_mult[1] = color.green * mix; + c_mult[2] = color.red * mix; + + int32_t y; + for(y = 0; y < h; y++) { + int32_t x; + for(x = 0; x < w; x++) { + uint8_t alpha = src_buf[3]; + + if(alpha > 0) { + /* Step 1: Unpremultiply (convert to non-premultiplied RGB) */ + uint16_t reciprocal = (255 * 256) / alpha; + uint8_t r = (src_buf[2] * reciprocal) >> 8; + uint8_t g = (src_buf[1] * reciprocal) >> 8; + uint8_t b = (src_buf[0] * reciprocal) >> 8; + + /* Step 2: Apply recoloring */ + r = (c_mult[2] + (r * mix_inv)) >> 8; + g = (c_mult[1] + (g * mix_inv)) >> 8; + b = (c_mult[0] + (b * mix_inv)) >> 8; + + /* Step 3: Premultiply again */ + dest_buf[0] = (b * alpha) >> 8; + dest_buf[1] = (g * alpha) >> 8; + dest_buf[2] = (r * alpha) >> 8; + } + else { + /* If alpha is 0, just copy the pixel as is */ + dest_buf[0] = src_buf[0]; + dest_buf[1] = src_buf[1]; + dest_buf[2] = src_buf[2]; + } + + dest_buf[3] = alpha; /* Keep original alpha*/ + + src_buf += px_size; + dest_buf += px_size; + } + src_buf += src_stride - w * px_size; + } + } } } +static bool apply_mask(const lv_draw_image_dsc_t * draw_dsc) +{ + lv_layer_t * layer_to_draw = (lv_layer_t *)draw_dsc->src; + lv_draw_buf_t * image_draw_buf = layer_to_draw->draw_buf; + lv_image_decoder_dsc_t mask_decoder_dsc; + lv_area_t mask_area; + uint32_t mask_stride; + + 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 == NULL) { + if(decoder_res == LV_RESULT_OK) lv_image_decoder_close(&mask_decoder_dsc); + LV_LOG_WARN("Could open the mask. The mask is not applied."); + return true; + } + + if(mask_decoder_dsc.decoded->header.cf != LV_COLOR_FORMAT_A8 && + mask_decoder_dsc.decoded->header.cf != LV_COLOR_FORMAT_L8) { + lv_image_decoder_close(&mask_decoder_dsc); + LV_LOG_WARN("The mask image is not A8/L8 format. The mask is not applied."); + return true; + + } + + const lv_draw_buf_t * mask_draw_buf = mask_decoder_dsc.decoded; + mask_stride = mask_draw_buf->header.stride; + + /*Align the mask to the center*/ + lv_area_t image_area; + image_area = draw_dsc->image_area; /*Use the whole image area for the alignment*/ + lv_area_set(&mask_area, 0, 0, mask_draw_buf->header.w - 1, mask_draw_buf->header.h - 1); + lv_area_align(&image_area, &mask_area, LV_ALIGN_CENTER, 0, 0); + + image_area = + layer_to_draw->buf_area; /*The image can be smaller if only a part was rendered. Use this are during rendering*/ + + /*Only the intersection of the mask and image needs to be rendered + *If if there is no intersection there is nothing to render as the image is out of the mask.*/ + lv_area_t masked_area; + if(!lv_area_intersect(&masked_area, &mask_area, &image_area)) { + lv_image_decoder_close(&mask_decoder_dsc); + return false; + } + + /*Clear the sides if any*/ + lv_area_t side_area = {0}; + /*Top*/ + side_area.x2 = layer_to_draw->draw_buf->header.w - 1; + side_area.y2 = masked_area.y1 - 1 - image_area.y1; + lv_draw_buf_clear(layer_to_draw->draw_buf, &side_area); + + /*Bottom*/ + side_area.y1 = masked_area.y2 + 1 - image_area.y1; + side_area.y2 = layer_to_draw->draw_buf->header.h - 1; + lv_draw_buf_clear(layer_to_draw->draw_buf, &side_area); + + /*Left*/ + side_area.y1 = 0; + side_area.x1 = 0; + side_area.x2 = masked_area.x1 - 1 - image_area.x1; + lv_draw_buf_clear(layer_to_draw->draw_buf, &side_area); + + /*Right*/ + side_area.x1 = masked_area.x2 + 1 - image_area.x1; + side_area.x2 = layer_to_draw->draw_buf->header.w - 1; + lv_draw_buf_clear(layer_to_draw->draw_buf, &side_area); + + /*Seek to the first of the image and mask on the masked area*/ + uint8_t * img_start = lv_draw_buf_goto_xy(image_draw_buf, + masked_area.x1 - image_area.x1, + masked_area.y1 - image_area.y1); + uint8_t * mask_start = lv_draw_buf_goto_xy(mask_decoder_dsc.decoded, + masked_area.x1 - mask_area.x1, + masked_area.y1 - mask_area.y1); + + int32_t h = lv_area_get_height(&masked_area); + int32_t w = lv_area_get_width(&masked_area); + + int32_t y; + for(y = 0; y < h; y++) { + int32_t x; + for(x = 0; x < w; x++) { + img_start[x * 4 + 3] = LV_OPA_MIX2(mask_start[x], img_start[x * 4 + 3]); + } + img_start += layer_to_draw->draw_buf->header.stride; + mask_start += mask_stride; + } + + lv_image_decoder_close(&mask_decoder_dsc); + + return true; +} + #endif /*LV_USE_DRAW_SW*/ 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 3dec220d9..5bb69c98b 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 @@ -8,7 +8,16 @@ *********************/ #include "blend/lv_draw_sw_blend_private.h" #include "../lv_draw_label_private.h" +#include "../../draw/lv_draw_private.h" #include "lv_draw_sw.h" + +#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG + + #include "../../libs/freetype/lv_freetype_private.h" + #include "../lv_draw_vector_private.h" + +#endif + #if LV_USE_DRAW_SW #include "../../display/lv_display.h" @@ -27,14 +36,30 @@ /********************** * TYPEDEFS **********************/ +#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG + +typedef struct { + lv_vector_path_t * inside_path; /*The regular glyph*/ + lv_vector_path_t * outside_path; /*A bigger glyph that goes in the background for the letter outline*/ + lv_vector_path_t * cur_path; +} lv_draw_sw_letter_outlines_t; + +#endif /* LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG */ /********************** * STATIC PROTOTYPES **********************/ -static void /* LV_ATTRIBUTE_FAST_MEM */ draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc, +static void /* LV_ATTRIBUTE_FAST_MEM */ draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area); +#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG + + static void freetype_outline_event_cb(lv_event_t * e); + static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * dsc); + +#endif + /********************** * STATIC VARIABLES **********************/ @@ -51,78 +76,364 @@ static void /* LV_ATTRIBUTE_FAST_MEM */ draw_letter_cb(lv_draw_unit_t * draw_uni * GLOBAL FUNCTIONS **********************/ -void lv_draw_sw_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_sw_letter(lv_draw_task_t * t, const lv_draw_letter_dsc_t * dsc, const lv_area_t * coords) +{ + if(dsc->opa <= LV_OPA_MIN) + return; + + LV_PROFILER_DRAW_BEGIN; + + lv_draw_glyph_dsc_t glyph_dsc; + lv_draw_glyph_dsc_init(&glyph_dsc); + glyph_dsc.opa = dsc->opa; + glyph_dsc.bg_coords = NULL; + glyph_dsc.color = dsc->color; + glyph_dsc.rotation = dsc->rotation; + glyph_dsc.pivot = dsc->pivot; + + lv_draw_unit_draw_letter(t, &glyph_dsc, &(lv_point_t) { + .x = coords->x1, .y = coords->y1 + }, + dsc->font, dsc->unicode, draw_letter_cb); + + if(glyph_dsc._draw_buf) { + lv_draw_buf_destroy(glyph_dsc._draw_buf); + glyph_dsc._draw_buf = NULL; + } + + LV_PROFILER_DRAW_END; +} + +void lv_draw_sw_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords) { if(dsc->opa <= LV_OPA_MIN) return; - LV_PROFILER_BEGIN; - lv_draw_label_iterate_characters(draw_unit, dsc, coords, draw_letter_cb); - LV_PROFILER_END; + LV_PROFILER_DRAW_BEGIN; + +#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG + static bool is_init = false; + if(!is_init) { + lv_freetype_outline_add_event(freetype_outline_event_cb, LV_EVENT_ALL, t); + is_init = true; + } +#endif + + lv_draw_label_iterate_characters(t, dsc, coords, draw_letter_cb); + LV_PROFILER_DRAW_END; } /********************** * STATIC FUNCTIONS **********************/ -static void LV_ATTRIBUTE_FAST_MEM draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc, +static void LV_ATTRIBUTE_FAST_MEM draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area) { if(glyph_draw_dsc) { switch(glyph_draw_dsc->format) { case LV_FONT_GLYPH_FORMAT_NONE: { #if LV_USE_FONT_PLACEHOLDER + if(glyph_draw_dsc->bg_coords == NULL) break; /* 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_sw_border(draw_unit, &border_draw_dsc, glyph_draw_dsc->bg_coords); + lv_draw_sw_border(t, &border_draw_dsc, glyph_draw_dsc->bg_coords); #endif } break; case LV_FONT_GLYPH_FORMAT_A1: case LV_FONT_GLYPH_FORMAT_A2: + case LV_FONT_GLYPH_FORMAT_A3: case LV_FONT_GLYPH_FORMAT_A4: - case LV_FONT_GLYPH_FORMAT_A8: { - lv_area_t mask_area = *glyph_draw_dsc->letter_coords; - mask_area.x2 = mask_area.x1 + lv_draw_buf_width_to_stride(lv_area_get_width(&mask_area), LV_COLOR_FORMAT_A8) - 1; - lv_draw_sw_blend_dsc_t blend_dsc; - lv_memzero(&blend_dsc, sizeof(blend_dsc)); - blend_dsc.color = glyph_draw_dsc->color; - blend_dsc.opa = glyph_draw_dsc->opa; - lv_draw_buf_t * draw_buf = glyph_draw_dsc->glyph_data; - blend_dsc.mask_buf = draw_buf->data; - blend_dsc.mask_area = &mask_area; - blend_dsc.mask_stride = draw_buf->header.stride; - blend_dsc.blend_area = glyph_draw_dsc->letter_coords; - blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; - - lv_draw_sw_blend(draw_unit, &blend_dsc); - } - break; + case LV_FONT_GLYPH_FORMAT_A8: case LV_FONT_GLYPH_FORMAT_IMAGE: { -#if LV_USE_IMGFONT - lv_draw_image_dsc_t img_dsc; - lv_draw_image_dsc_init(&img_dsc); - img_dsc.rotation = 0; - img_dsc.scale_x = LV_SCALE_NONE; - img_dsc.scale_y = LV_SCALE_NONE; - img_dsc.opa = glyph_draw_dsc->opa; - img_dsc.src = glyph_draw_dsc->glyph_data; - lv_draw_sw_image(draw_unit, &img_dsc, glyph_draw_dsc->letter_coords); -#endif + if(glyph_draw_dsc->rotation % 3600 == 0 && glyph_draw_dsc->format != LV_FONT_GLYPH_FORMAT_IMAGE) { + lv_area_t mask_area = *glyph_draw_dsc->letter_coords; + + if(lv_font_has_static_bitmap(glyph_draw_dsc->g->resolved_font) && + glyph_draw_dsc->g->format == LV_FONT_GLYPH_FORMAT_A8) { + glyph_draw_dsc->g->req_raw_bitmap = 1; + const void * bitmap = lv_font_get_glyph_static_bitmap(glyph_draw_dsc->g); + lv_draw_sw_blend_dsc_t blend_dsc; + lv_memzero(&blend_dsc, sizeof(blend_dsc)); + blend_dsc.color = glyph_draw_dsc->color; + blend_dsc.opa = glyph_draw_dsc->opa; + blend_dsc.mask_buf = bitmap; + blend_dsc.mask_area = &mask_area; + blend_dsc.mask_stride = glyph_draw_dsc->g->stride; + blend_dsc.blend_area = glyph_draw_dsc->letter_coords; + blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; + lv_draw_sw_blend(t, &blend_dsc); + } + else { + glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); + mask_area.x2 = mask_area.x1 + lv_draw_buf_width_to_stride(lv_area_get_width(&mask_area), LV_COLOR_FORMAT_A8) - 1; + lv_draw_sw_blend_dsc_t blend_dsc; + lv_memzero(&blend_dsc, sizeof(blend_dsc)); + blend_dsc.color = glyph_draw_dsc->color; + blend_dsc.opa = glyph_draw_dsc->opa; + const lv_draw_buf_t * draw_buf = glyph_draw_dsc->glyph_data; + blend_dsc.mask_buf = draw_buf->data; + blend_dsc.mask_area = &mask_area; + blend_dsc.mask_stride = draw_buf->header.stride; + blend_dsc.blend_area = glyph_draw_dsc->letter_coords; + blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; + lv_draw_sw_blend(t, &blend_dsc); + } + } + else { + glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); + lv_draw_image_dsc_t img_dsc; + lv_draw_image_dsc_init(&img_dsc); + img_dsc.rotation = glyph_draw_dsc->rotation; + img_dsc.scale_x = LV_SCALE_NONE; + img_dsc.scale_y = LV_SCALE_NONE; + img_dsc.opa = glyph_draw_dsc->opa; + img_dsc.src = glyph_draw_dsc->glyph_data; + img_dsc.recolor = glyph_draw_dsc->color; + img_dsc.pivot = (lv_point_t) { + .x = glyph_draw_dsc->pivot.x, + .y = glyph_draw_dsc->g->box_h + glyph_draw_dsc->g->ofs_y + }; + lv_draw_sw_image(t, &img_dsc, glyph_draw_dsc->letter_coords); + } + break; } break; +#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG + case LV_FONT_GLYPH_FORMAT_VECTOR: { + draw_letter_outline(t, glyph_draw_dsc); + } + break; +#endif default: break; } - } if(fill_draw_dsc && fill_area) { - lv_draw_sw_fill(draw_unit, fill_draw_dsc, fill_area); + lv_draw_sw_fill(t, fill_draw_dsc, fill_area); } } +#if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG + +/* + * Renders the vectors paths representing a glyph with ThorVG + * the result is then blended into the draw buffer + */ +static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_dsc) +{ + + lv_draw_sw_letter_outlines_t * glyph_paths; + lv_vector_dsc_t * vector_dsc; + lv_draw_buf_t * draw_buf; + lv_matrix_t matrix; + lv_layer_t layer; + + glyph_paths = (lv_draw_sw_letter_outlines_t *) glyph_dsc->glyph_data; + LV_ASSERT_NULL(glyph_paths); + + int32_t cf; + int32_t w; + int32_t h; + uint32_t stride; + float scale; + lv_area_t buf_area; + + cf = LV_COLOR_FORMAT_ARGB8888; + + scale = LV_FREETYPE_F26DOT6_TO_FLOAT(lv_freetype_outline_get_scale(glyph_dsc->g->resolved_font)); + w = (int32_t)((float) glyph_dsc->g->box_w + glyph_dsc->outline_stroke_width * 2 * scale); + h = (int32_t)((float) glyph_dsc->g->box_h + glyph_dsc->outline_stroke_width * 2 * scale); + buf_area.x1 = 0; + buf_area.y1 = 0; + lv_area_set_width(&buf_area, w); + lv_area_set_height(&buf_area, h); + + stride = lv_draw_buf_width_to_stride(w, cf); + draw_buf = lv_draw_buf_create(w, h, cf, stride); + lv_draw_buf_clear(draw_buf, NULL); + + lv_memzero(&layer, sizeof(lv_layer_t)); + layer.draw_buf = draw_buf; + layer.color_format = cf; + layer.buf_area = buf_area; + layer.phy_clip_area = buf_area; + layer._clip_area = buf_area; + + lv_memzero(&matrix, sizeof(lv_matrix_t)); + + lv_matrix_identity(&matrix); + + vector_dsc = lv_vector_dsc_create(&layer); + + int32_t offset_x; + int32_t offset_y; + + offset_x = (int32_t)((float) glyph_dsc->g->ofs_x - glyph_dsc->outline_stroke_width * scale); + offset_y = (int32_t)((float) glyph_dsc->g->ofs_y - glyph_dsc->outline_stroke_width * scale); + + /*Invert Y-Axis - Freetype's origin point is in the bottom left corner*/ + lv_matrix_scale(&matrix, 1, -1); + lv_matrix_translate(&matrix, -offset_x, -h - offset_y); + lv_matrix_scale(&matrix, scale, scale); + lv_vector_dsc_set_transform(vector_dsc, &matrix); + + /*Set attributes color, line width etc*/ + if(cf == LV_COLOR_FORMAT_ARGB8888) { + + if(glyph_dsc->outline_stroke_width > 0) { + lv_vector_dsc_set_fill_color(vector_dsc, glyph_dsc->outline_stroke_color); + lv_vector_dsc_set_fill_opa(vector_dsc, glyph_dsc->outline_stroke_opa); + lv_vector_dsc_add_path(vector_dsc, glyph_paths->outside_path); + } + + lv_vector_dsc_set_fill_color(vector_dsc, glyph_dsc->color); + lv_vector_dsc_set_fill_opa(vector_dsc, glyph_dsc->opa); + lv_vector_dsc_add_path(vector_dsc, glyph_paths->inside_path); + + } + else { + LV_LOG_ERROR("Unsupported color format: %d", cf); + } + + lv_area_t old_area; + lv_area_t letter_coords; + + /*Render vector path(s) - set the clip area so that it matches + *the size of the temporary buffer used to render the glyph path(s)*/ + lv_memcpy(&old_area, &t->clip_area, sizeof(lv_area_t)); + lv_memcpy(&t->clip_area, &buf_area, sizeof(lv_area_t)); + + /*Can't call lv_draw_vector() as it would create a new draw task while + *the main thread also can create draw tasks. So create a dummy draw task + *manually to draw the outline*/ + if(vector_dsc->tasks.task_list) { + vector_dsc->tasks.base.layer = vector_dsc->layer; + lv_draw_task_t dummy_t; + lv_memzero(&dummy_t, sizeof(lv_draw_task_t)); + dummy_t.area = vector_dsc->layer->_clip_area; + dummy_t._real_area = vector_dsc->layer->_clip_area; + dummy_t.clip_area = vector_dsc->layer->_clip_area; + dummy_t.target_layer = vector_dsc->layer; + dummy_t.type = LV_DRAW_TASK_TYPE_VECTOR; + dummy_t.draw_dsc = &vector_dsc->tasks; + lv_draw_sw_vector(&dummy_t, dummy_t.draw_dsc); + } + + /*Restore previous draw area of the entire text label*/ + lv_memcpy(&t->clip_area, &old_area, sizeof(lv_area_t)); + + lv_memcpy(&letter_coords, glyph_dsc->letter_coords, sizeof(lv_area_t)); + lv_area_set_width(&letter_coords, w); + lv_area_set_height(&letter_coords, h); + + lv_draw_image_dsc_t img_dsc; + + lv_draw_image_dsc_init(&img_dsc); + img_dsc.rotation = 0; + img_dsc.scale_x = LV_SCALE_NONE; + img_dsc.scale_y = LV_SCALE_NONE; + img_dsc.opa = LV_OPA_100; + img_dsc.src = draw_buf; + lv_draw_sw_image(t, &img_dsc, &letter_coords); + + lv_vector_dsc_delete(vector_dsc); + lv_draw_buf_destroy(draw_buf); + +} + +/* Build the inside and outside vector paths for a glyph based + * on the received outline events emitted by lv_freetype_outline.c */ +static void freetype_outline_event_cb(lv_event_t * e) +{ + + lv_fpoint_t pnt; + lv_fpoint_t ctrl_pnt1; + lv_fpoint_t ctrl_pnt2; + lv_draw_sw_letter_outlines_t * glyph_paths; + lv_vector_path_t * path; + lv_freetype_outline_event_param_t * outline_event; + + outline_event = lv_event_get_param(e); + pnt.x = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->to.x); + pnt.y = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->to.y); + glyph_paths = outline_event->outline; + + if(lv_event_get_code(e) == LV_EVENT_CREATE) { + + glyph_paths = lv_malloc_zeroed(sizeof(lv_draw_sw_letter_outlines_t)); + LV_ASSERT_MALLOC(glyph_paths); + + glyph_paths->cur_path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_HIGH); + glyph_paths->inside_path = glyph_paths->cur_path; + outline_event->outline = glyph_paths; + return; + + } + else if(lv_event_get_code(e) == LV_EVENT_DELETE) { + + if(glyph_paths->inside_path != NULL) { + lv_vector_path_clear(glyph_paths->inside_path); + lv_vector_path_delete(glyph_paths->inside_path); + } + + if(glyph_paths->outside_path != NULL) { + lv_vector_path_clear(glyph_paths->outside_path); + lv_vector_path_delete(glyph_paths->outside_path); + } + + lv_free(glyph_paths); + return; + + } + else if(outline_event->type == LV_FREETYPE_OUTLINE_BORDER_START) { + + /* Inside path is done - create the border path */ + lv_vector_path_close(glyph_paths->cur_path); + glyph_paths->cur_path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_HIGH); + glyph_paths->outside_path = glyph_paths->cur_path; + return; + } + + path = glyph_paths->cur_path; + + switch(outline_event->type) { + + case LV_FREETYPE_OUTLINE_MOVE_TO: + lv_vector_path_move_to(path, &pnt); + break; + + case LV_FREETYPE_OUTLINE_LINE_TO: + lv_vector_path_line_to(path, &pnt); + break; + + case LV_FREETYPE_OUTLINE_CUBIC_TO: + ctrl_pnt1.x = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->control1.x); + ctrl_pnt1.y = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->control1.y); + ctrl_pnt2.x = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->control2.x); + ctrl_pnt2.y = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->control2.y); + lv_vector_path_cubic_to(path, &ctrl_pnt1, &ctrl_pnt2, &pnt); + break; + + case LV_FREETYPE_OUTLINE_CONIC_TO: + ctrl_pnt1.x = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->control1.x); + ctrl_pnt1.y = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->control1.y); + lv_vector_path_quad_to(path, &ctrl_pnt1, &pnt); + break; + case LV_FREETYPE_OUTLINE_END: + case LV_FREETYPE_OUTLINE_BORDER_START: + /* It's not necessary to close the path and + * border start is handled above + */ + break; + } +} + +#endif /* LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC */ + #endif /*LV_USE_DRAW_SW*/ 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 be3b19103..dbc4953d3 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 @@ -31,9 +31,9 @@ * STATIC PROTOTYPES **********************/ -static void /* LV_ATTRIBUTE_FAST_MEM */ draw_line_skew(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc); -static void /* LV_ATTRIBUTE_FAST_MEM */ draw_line_hor(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc); -static void /* LV_ATTRIBUTE_FAST_MEM */ draw_line_ver(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc); +static void /* LV_ATTRIBUTE_FAST_MEM */ draw_line_skew(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc); +static void /* LV_ATTRIBUTE_FAST_MEM */ draw_line_hor(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc); +static void /* LV_ATTRIBUTE_FAST_MEM */ draw_line_ver(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc); /********************** * STATIC VARIABLES @@ -47,7 +47,7 @@ static void /* LV_ATTRIBUTE_FAST_MEM */ draw_line_ver(lv_draw_unit_t * draw_unit * GLOBAL FUNCTIONS **********************/ -void lv_draw_sw_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc) +void lv_draw_sw_line(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc) { if(dsc->width == 0) return; if(dsc->opa <= LV_OPA_MIN) return; @@ -61,13 +61,13 @@ 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, &t->clip_area); if(!is_common) return; - LV_PROFILER_BEGIN; - if(dsc->p1.y == dsc->p2.y) draw_line_hor(draw_unit, dsc); - else if(dsc->p1.x == dsc->p2.x) draw_line_ver(draw_unit, dsc); - else draw_line_skew(draw_unit, dsc); + LV_PROFILER_DRAW_BEGIN; + if((int32_t)dsc->p1.y == (int32_t)dsc->p2.y) draw_line_hor(t, dsc); + else if((int32_t)dsc->p1.x == (int32_t)dsc->p2.x) draw_line_ver(t, dsc); + else draw_line_skew(t, dsc); if(dsc->round_end || dsc->round_start) { lv_draw_fill_dsc_t cir_dsc; @@ -85,7 +85,7 @@ void lv_draw_sw_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc) cir_area.y1 = (int32_t)dsc->p1.y - r; cir_area.x2 = (int32_t)dsc->p1.x + r - r_corr; cir_area.y2 = (int32_t)dsc->p1.y + r - r_corr ; - lv_draw_sw_fill(draw_unit, &cir_dsc, &cir_area); + lv_draw_sw_fill(t, &cir_dsc, &cir_area); } if(dsc->round_end) { @@ -93,16 +93,16 @@ void lv_draw_sw_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc) cir_area.y1 = (int32_t)dsc->p2.y - r; cir_area.x2 = (int32_t)dsc->p2.x + r - r_corr; cir_area.y2 = (int32_t)dsc->p2.y + r - r_corr ; - lv_draw_sw_fill(draw_unit, &cir_dsc, &cir_area); + lv_draw_sw_fill(t, &cir_dsc, &cir_area); } } - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } /********************** * STATIC FUNCTIONS **********************/ -static void LV_ATTRIBUTE_FAST_MEM draw_line_hor(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc) +static void LV_ATTRIBUTE_FAST_MEM draw_line_hor(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc) { int32_t w = dsc->width - 1; int32_t w_half0 = w >> 1; @@ -115,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, &t->clip_area); if(!is_common) return; bool dashed = dsc->dash_gap && dsc->dash_width; @@ -128,7 +128,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_line_hor(lv_draw_unit_t * draw_unit, cons /*If there is no mask then simply draw a rectangle*/ if(!dashed) { - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } #if LV_DRAW_SW_COMPLEX /*If there other mask apply it*/ @@ -167,7 +167,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_line_hor(lv_draw_unit_t * draw_unit, cons blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; } - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); blend_area.y1++; blend_area.y2++; @@ -177,7 +177,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_line_hor(lv_draw_unit_t * draw_unit, cons #endif /*LV_DRAW_SW_COMPLEX*/ } -static void LV_ATTRIBUTE_FAST_MEM draw_line_ver(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc) +static void LV_ATTRIBUTE_FAST_MEM draw_line_ver(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc) { int32_t w = dsc->width - 1; int32_t w_half0 = w >> 1; @@ -190,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, &t->clip_area); if(!is_common) return; bool dashed = dsc->dash_gap && dsc->dash_width; @@ -203,7 +203,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_line_ver(lv_draw_unit_t * draw_unit, cons /*If there is no mask then simply draw a rectangle*/ if(!dashed) { - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } #if LV_DRAW_SW_COMPLEX @@ -238,7 +238,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_line_ver(lv_draw_unit_t * draw_unit, cons } dash_cnt ++; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); blend_area.y1++; blend_area.y2++; @@ -248,7 +248,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_line_ver(lv_draw_unit_t * draw_unit, cons #endif /*LV_DRAW_SW_COMPLEX*/ } -static void LV_ATTRIBUTE_FAST_MEM draw_line_skew(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc) +static void LV_ATTRIBUTE_FAST_MEM draw_line_skew(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc) { #if LV_DRAW_SW_COMPLEX /*Keep the great y in p1*/ @@ -293,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, &t->clip_area); if(is_common == false) return; lv_draw_sw_mask_line_param_t mask_left_param; @@ -374,7 +374,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_line_skew(lv_draw_unit_t * draw_unit, con } else { blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); blend_area.y1 = blend_area.y2 + 1; blend_area.y2 = blend_area.y1; @@ -387,7 +387,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_line_skew(lv_draw_unit_t * draw_unit, con if(blend_area.y1 != blend_area.y2) { blend_area.y2--; blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } lv_free(mask_buf); @@ -399,7 +399,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_line_skew(lv_draw_unit_t * draw_unit, con lv_draw_sw_mask_free_param(&mask_bottom_param); } #else - LV_UNUSED(draw_unit); + LV_UNUSED(t); LV_UNUSED(dsc); LV_LOG_WARN("Can't draw skewed line with LV_DRAW_SW_COMPLEX == 0"); #endif /*LV_DRAW_SW_COMPLEX*/ 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 c4fd79220..0e1a17a67 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 @@ -1093,6 +1093,7 @@ static void circ_calc_aa4(lv_draw_sw_mask_radius_circle_dsc_t * c, int32_t radiu const size_t cir_xy_size = (radius + 1) * 2 * 2 * sizeof(int32_t); int32_t * cir_x = lv_malloc_zeroed(cir_xy_size); + LV_ASSERT_MALLOC(cir_x); int32_t * cir_y = &cir_x[(radius + 1) * 2]; uint32_t y_8th_cnt = 0; 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 3f7b306e4..a70ce2635 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 @@ -72,8 +72,6 @@ void lv_draw_sw_mask_init(void); void lv_draw_sw_mask_deinit(void); -//! @cond Doxygen_Suppress - /** * Apply the added buffers on a line. Used internally by the library's drawing routines. * @param masks the masks list to apply, must be ended with NULL pointer in array. @@ -91,8 +89,6 @@ lv_draw_sw_mask_res_t /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_mask_apply(void * m int32_t abs_y, int32_t len); -//! @endcond - /** * Free the data from the parameter. * It's called inside `lv_draw_sw_mask_remove_id` and `lv_draw_sw_mask_remove_custom` 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 index aeae9b8ea..24125384b 100644 --- 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 @@ -36,12 +36,12 @@ typedef struct { int32_t radius; /**< The radius of the entry */ } lv_draw_sw_mask_radius_circle_dsc_t; -struct lv_draw_sw_mask_common_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 { +struct _lv_draw_sw_mask_line_param_t { /** The first element must be the common descriptor */ lv_draw_sw_mask_common_dsc_t dsc; @@ -53,7 +53,7 @@ struct lv_draw_sw_mask_line_param_t { lv_point_t p2; /*Which side to keep?*/ - lv_draw_sw_mask_line_side_t side : 2; + lv_draw_sw_mask_line_side_t side : 3; } cfg; /** A point of the line */ @@ -79,7 +79,7 @@ struct lv_draw_sw_mask_line_param_t { uint8_t inv: 1; }; -struct lv_draw_sw_mask_angle_param_t { +struct _lv_draw_sw_mask_angle_param_t { /** The first element must be the common descriptor */ lv_draw_sw_mask_common_dsc_t dsc; @@ -94,7 +94,7 @@ struct lv_draw_sw_mask_angle_param_t { uint16_t delta_deg; }; -struct lv_draw_sw_mask_radius_param_t { +struct _lv_draw_sw_mask_radius_param_t { /** The first element must be the common descriptor */ lv_draw_sw_mask_common_dsc_t dsc; @@ -108,7 +108,7 @@ struct lv_draw_sw_mask_radius_param_t { lv_draw_sw_mask_radius_circle_dsc_t * circle; }; -struct lv_draw_sw_mask_fade_param_t { +struct _lv_draw_sw_mask_fade_param_t { /** The first element must be the common descriptor */ lv_draw_sw_mask_common_dsc_t dsc; @@ -122,7 +122,7 @@ struct lv_draw_sw_mask_fade_param_t { }; -struct lv_draw_sw_mask_map_param_t { +struct _lv_draw_sw_mask_map_param_t { /** The first element must be the common descriptor */ lv_draw_sw_mask_common_dsc_t dsc; 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 bd28d0d0e..221cc647f 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 @@ -43,42 +43,42 @@ * GLOBAL FUNCTIONS **********************/ -void lv_draw_sw_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_sw_mask_rect(lv_draw_task_t * t, const lv_draw_mask_rect_dsc_t * dsc) { - 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, &t->clip_area)) { return; } - lv_layer_t * target_layer = draw_unit->target_layer; + lv_layer_t * target_layer = t->target_layer; lv_area_t * buf_area = &target_layer->buf_area; lv_area_t clear_area; void * draw_buf = target_layer->draw_buf; - /*Clear the top part*/ - lv_area_set(&clear_area, draw_unit->clip_area->x1, draw_unit->clip_area->y1, draw_unit->clip_area->x2, - dsc->area.y1 - 1); - lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1); - lv_draw_buf_clear(draw_buf, &clear_area); + if(dsc->keep_outside == 0) { + /*Clear the top part*/ + lv_area_set(&clear_area, t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, + dsc->area.y1 - 1); + lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1); + lv_draw_buf_clear(draw_buf, &clear_area); - /*Clear the bottom part*/ - lv_area_set(&clear_area, draw_unit->clip_area->x1, dsc->area.y2 + 1, draw_unit->clip_area->x2, - draw_unit->clip_area->y2); - lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1); - lv_draw_buf_clear(draw_buf, &clear_area); + /*Clear the bottom part*/ + lv_area_set(&clear_area, t->clip_area.x1, dsc->area.y2 + 1, t->clip_area.x2, + t->clip_area.y2); + lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1); + lv_draw_buf_clear(draw_buf, &clear_area); - /*Clear the left part*/ - lv_area_set(&clear_area, draw_unit->clip_area->x1, dsc->area.y1, dsc->area.x1 - 1, dsc->area.y2); - lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1); - lv_draw_buf_clear(draw_buf, &clear_area); + /*Clear the left part*/ + lv_area_set(&clear_area, t->clip_area.x1, dsc->area.y1, dsc->area.x1 - 1, dsc->area.y2); + lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1); + lv_draw_buf_clear(draw_buf, &clear_area); - /*Clear the right part*/ - lv_area_set(&clear_area, dsc->area.x2 + 1, dsc->area.y1, draw_unit->clip_area->x2, dsc->area.y2); - lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1); - lv_draw_buf_clear(draw_buf, &clear_area); + /*Clear the right part*/ + lv_area_set(&clear_area, dsc->area.x2 + 1, dsc->area.y1, t->clip_area.x2, dsc->area.y2); + lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1); + lv_draw_buf_clear(draw_buf, &clear_area); + } lv_draw_sw_mask_radius_param_t param; lv_draw_sw_mask_radius_init(¶m, &dsc->area, dsc->radius, false); 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 index 38ba3b4c7..60bf4b631 100644 --- 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 @@ -31,16 +31,23 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_draw_sw_unit_t { - lv_draw_unit_t base_unit; +typedef struct { lv_draw_task_t * task_act; -#if LV_USE_OS - lv_thread_sync_t sync; lv_thread_t thread; + lv_thread_sync_t sync; + lv_draw_unit_t * draw_unit; + uint32_t idx; volatile bool inited; volatile bool exit_status; +} lv_draw_sw_thread_dsc_t; + +struct _lv_draw_sw_unit_t { + lv_draw_unit_t base_unit; +#if LV_USE_OS + lv_draw_sw_thread_dsc_t thread_dscs[LV_DRAW_SW_DRAW_UNIT_CNT]; +#else + lv_draw_task_t * task_act; #endif - uint32_t idx; }; #if LV_DRAW_SW_SHADOW_CACHE_SIZE 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 41036d430..30db0620b 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,7 +51,7 @@ 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 +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 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); @@ -63,12 +63,24 @@ static void transform_argb8888(const uint8_t * src, int32_t src_w, int32_t src_h int32_t x_end, uint8_t * dest_buf, bool aa); #endif +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED +static void transform_argb8888_premultiplied(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_RGB565_SWAPPED +static void transform_rgb565a8_swapped(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, @@ -76,14 +88,12 @@ 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 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 +#endif /*LV_DRAW_SW_SUPPORT_L8*/ /********************** * STATIC VARIABLES @@ -97,11 +107,10 @@ static void transform_l8_to_argb8888(const uint8_t * src, int32_t src_w, int32_t * GLOBAL FUNCTIONS **********************/ -void lv_draw_sw_transform(lv_draw_unit_t * draw_unit, const lv_area_t * dest_area, const void * src_buf, +void lv_draw_sw_transform(const lv_area_t * dest_area, const void * src_buf, int32_t src_w, int32_t src_h, int32_t src_stride, const lv_draw_image_dsc_t * draw_dsc, const lv_draw_image_sup_t * sup, lv_color_format_t src_cf, void * dest_buf) { - LV_UNUSED(draw_unit); LV_UNUSED(sup); point_transform_dsc_t tr_dsc; @@ -132,10 +141,7 @@ 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_L8) { - dest_stride = dest_w * ((draw_dsc->recolor_opa >= LV_OPA_MIN) ? 4 : 2); - } - else if(src_cf == LV_COLOR_FORMAT_RGB888) { + 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) || (src_cf == LV_COLOR_FORMAT_L8)) { @@ -146,7 +152,7 @@ void lv_draw_sw_transform(lv_draw_unit_t * draw_unit, const lv_area_t * dest_are } uint8_t * alpha_buf; - if(src_cf == LV_COLOR_FORMAT_RGB565 || src_cf == LV_COLOR_FORMAT_RGB565A8) { + if(src_cf == LV_COLOR_FORMAT_RGB565 || src_cf == LV_COLOR_FORMAT_RGB565_SWAPPED || src_cf == LV_COLOR_FORMAT_RGB565A8) { alpha_buf = dest_buf; alpha_buf += dest_stride * dest_h; } @@ -255,12 +261,25 @@ void lv_draw_sw_transform(lv_draw_unit_t * draw_unit, const lv_area_t * dest_are aa); break; #endif +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + case LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED: + transform_argb8888_premultiplied(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_RGB565_SWAPPED + case LV_COLOR_FORMAT_RGB565_SWAPPED: + transform_rgb565a8_swapped(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, @@ -268,17 +287,18 @@ void lv_draw_sw_transform(lv_draw_unit_t * draw_unit, const lv_area_t * dest_are alpha_buf, true, aa); break; #endif -#if LV_DRAW_SW_SUPPORT_L8 + +#if LV_DRAW_SW_SUPPORT_L8 && LV_DRAW_SW_SUPPORT_AL88 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); + 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 +#endif /*LV_DRAW_SW_SUPPORT_L8 && (LV_DRAW_SW_SUPPORT_ARGB8888 || LV_DRAW_SW_SUPPORT_AL88)*/ default: - break; + LV_LOG_WARN("Color format 0x%02X is not enabled. " + "See lv_color.h to find the name of the color formats and " + "enable the related LV_DRAW_SW_SUPPORT_* in lv_conf.h.", + src_cf); + return; } dest_buf = (uint8_t *)dest_buf + dest_stride; @@ -290,7 +310,7 @@ 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 +#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888 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, @@ -483,6 +503,138 @@ static void transform_argb8888(const uint8_t * src, int32_t src_w, int32_t src_h #endif +#if LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + +static lv_color32_t unpremultiply(lv_color32_t c) +{ + if(c.alpha == 0) { + c.red = 0; + c.green = 0; + c.blue = 0; + } + else { + uint16_t reciprocal_alpha = (255 * 256) / c.alpha; + c.red = (c.red * reciprocal_alpha) >> 8; + c.green = (c.green * reciprocal_alpha) >> 8; + c.blue = (c.blue * reciprocal_alpha) >> 8; + } + + return c; +} + +static void transform_argb8888_premultiplied(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_buf)[x] = 0x00000000; + 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; + } + else { + x_next = 1; + xs_fract = xs_fract - 0x80; + } + if(ys_fract < 0x80) { + y_next = -1; + ys_fract = 0x7F - ys_fract; + } + else { + y_next = 1; + ys_fract = ys_fract - 0x80; + } + + const lv_color32_t * src_c32 = (const lv_color32_t *)(src + ys_int * src_stride + xs_int * 4); + + dest_c32[x] = src_c32[0]; + + 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_color32_t px_hor = src_c32[x_next]; + lv_color32_t px_ver = *(const lv_color32_t *)((uint8_t *)src_c32 + y_next * src_stride); + + /*Have the non-premultipled colors first, mix them as needed, + *and premultiply again*/ + dest_c32[x] = unpremultiply(dest_c32[x]); + px_hor = unpremultiply(px_hor); + px_ver = unpremultiply(px_ver); + + if(px_ver.alpha == 0) { + dest_c32[x].alpha = (dest_c32[x].alpha * (0xFF - ys_fract)) >> 8; + + } + else if(!lv_color32_eq(dest_c32[x], px_ver)) { + if(dest_c32[x].alpha) dest_c32[x].alpha = ((px_ver.alpha * ys_fract) + (dest_c32[x].alpha * (0xFF - ys_fract))) >> 8; + px_ver.alpha = ys_fract; + dest_c32[x] = lv_color_mix32(px_ver, dest_c32[x]); + } + + if(px_hor.alpha == 0) { + dest_c32[x].alpha = (dest_c32[x].alpha * (0xFF - xs_fract)) >> 8; + } + else if(!lv_color32_eq(dest_c32[x], px_hor)) { + if(dest_c32[x].alpha) dest_c32[x].alpha = ((px_hor.alpha * xs_fract) + (dest_c32[x].alpha * (0xFF - xs_fract))) >> 8; + px_hor.alpha = xs_fract; + dest_c32[x] = lv_color_mix32(px_hor, dest_c32[x]); + } + + dest_c32[x].red = (dest_c32[x].red * dest_c32[x].alpha) >> 8; + dest_c32[x].green = (dest_c32[x].green * dest_c32[x].alpha) >> 8; + dest_c32[x].blue = (dest_c32[x].blue * dest_c32[x].alpha) >> 8; + + } + /*Partially out of the image*/ + else { + if((xs_int == 0 && x_next < 0) || (xs_int == src_w - 1 && x_next > 0)) { + dest_c32[x] = unpremultiply(dest_c32[x]); + lv_opa_t alpha = (dest_c32[x].alpha * (0x7F - xs_fract)) >> 7; + dest_c32[x].alpha = alpha; + dest_c32[x].red = (dest_c32[x].red * dest_c32[x].alpha) >> 8; + dest_c32[x].green = (dest_c32[x].green * dest_c32[x].alpha) >> 8; + dest_c32[x].blue = (dest_c32[x].blue * dest_c32[x].alpha) >> 8; + + } + else if((ys_int == 0 && y_next < 0) || (ys_int == src_h - 1 && y_next > 0)) { + dest_c32[x] = unpremultiply(dest_c32[x]); + lv_opa_t alpha = (dest_c32[x].alpha * (0x7F - ys_fract)) >> 7; + dest_c32[x].alpha = alpha; + dest_c32[x].red = (dest_c32[x].red * dest_c32[x].alpha) >> 8; + dest_c32[x].green = (dest_c32[x].green * dest_c32[x].alpha) >> 8; + dest_c32[x].blue = (dest_c32[x].blue * dest_c32[x].alpha) >> 8; + } + } + } +} +#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, @@ -598,6 +750,122 @@ static void transform_rgb565a8(const uint8_t * src, int32_t src_w, int32_t src_h #endif +#if LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + +static void transform_rgb565a8_swapped(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) +{ + int32_t xs_ups_start = xs_ups; + int32_t ys_ups_start = ys_ups; + + const lv_opa_t * src_alpha = src + src_stride * src_h; + + /*Must be signed type, because we would use negative array index calculated from stride*/ + int32_t alpha_stride = src_stride / 2; /*alpha map stride is always half of RGB map stride*/ + + 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) { + abuf[x] = 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 uint16_t * src_tmp_u16 = (const uint16_t *)(src + (ys_int * src_stride) + xs_int * 2); + cbuf[x] = lv_color_swap_16(src_tmp_u16[0]); /* swap the src pixels */ + + 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) { + + /* swap the src pixels */ + uint16_t px_hor = lv_color_swap_16(src_tmp_u16[x_next]); + uint16_t px_ver = lv_color_swap_16(*(const uint16_t *)((uint8_t *)src_tmp_u16 + (y_next * src_stride))); + + if(src_has_a8) { + const lv_opa_t * src_alpha_tmp = src_alpha; + src_alpha_tmp += (ys_int * alpha_stride) + xs_int; + abuf[x] = src_alpha_tmp[0]; + + lv_opa_t a_hor = src_alpha_tmp[x_next]; + lv_opa_t a_ver = src_alpha_tmp[y_next * alpha_stride]; + + if(a_ver != abuf[x]) a_ver = ((a_ver * ys_fract) + (abuf[x] * (0x100 - ys_fract))) >> 8; + if(a_hor != abuf[x]) a_hor = ((a_hor * xs_fract) + (abuf[x] * (0x100 - xs_fract))) >> 8; + abuf[x] = (a_ver + a_hor) >> 1; + + if(abuf[x] == 0x00) continue; + } + else { + abuf[x] = 0xff; + } + + if(cbuf[x] != px_ver || cbuf[x] != px_hor) { + uint16_t v = lv_color_16_16_mix(px_ver, cbuf[x], ys_fract); + uint16_t h = lv_color_16_16_mix(px_hor, cbuf[x], xs_fract); + cbuf[x] = lv_color_16_16_mix(h, v, LV_OPA_50); + } + } + /*Partially out of the image*/ + else { + lv_opa_t a; + if(src_has_a8) { + const lv_opa_t * src_alpha_tmp = src_alpha; + src_alpha_tmp += (ys_int * alpha_stride) + xs_int; + a = src_alpha_tmp[0]; + } + else { + a = 0xff; + } + + if((xs_int == 0 && x_next < 0) || (xs_int == src_w - 1 && x_next > 0)) { + abuf[x] = (a * (0xFF - xs_fract)) >> 8; + } + else if((ys_int == 0 && y_next < 0) || (ys_int == src_h - 1 && y_next > 0)) { + abuf[x] = (a * (0xFF - ys_fract)) >> 8; + } + else { + abuf[x] = a; + } + } + } +} + +#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, @@ -676,11 +944,8 @@ 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_L8 && LV_DRAW_SW_SUPPORT_AL88 -#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) @@ -757,89 +1022,7 @@ static void transform_l8_to_al88(const uint8_t * src, int32_t src_w, int32_t src } } -#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 +#endif /*LV_DRAW_SW_SUPPORT_L8 && LV_DRAW_SW_SUPPORT_AL88*/ 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 4d42c4e3c..8d7a4b119 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 @@ -18,7 +18,7 @@ #include "../../misc/lv_color.h" #include "../../stdlib/lv_string.h" #include "../lv_draw_triangle_private.h" -#include "lv_draw_sw_gradient_private.h" +#include "lv_draw_sw_grad.h" /********************* * DEFINES @@ -44,7 +44,7 @@ * GLOBAL FUNCTIONS **********************/ -void lv_draw_sw_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc) +void lv_draw_sw_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc) { #if LV_DRAW_SW_COMPLEX lv_area_t tri_area; @@ -55,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, &t->clip_area); if(!is_common) return; lv_point_t p[3]; @@ -126,17 +126,19 @@ void lv_draw_sw_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_ lv_area_t blend_area = draw_area; blend_area.y2 = blend_area.y1; lv_draw_sw_blend_dsc_t blend_dsc; - blend_dsc.color = dsc->bg_color; - blend_dsc.opa = dsc->bg_opa; + blend_dsc.color = dsc->color; + blend_dsc.opa = dsc->opa; blend_dsc.mask_buf = mask_buf; blend_dsc.blend_area = &blend_area; blend_dsc.mask_area = &blend_area; + blend_dsc.mask_stride = 0; blend_dsc.blend_mode = LV_BLEND_MODE_NORMAL; blend_dsc.src_buf = NULL; - lv_grad_dir_t grad_dir = dsc->bg_grad.dir; + lv_grad_dir_t grad_dir = dsc->grad.dir; - lv_grad_t * grad = lv_gradient_get(&dsc->bg_grad, lv_area_get_width(&tri_area), lv_area_get_height(&tri_area)); + lv_draw_sw_grad_calc_t * grad = lv_draw_sw_grad_get(&dsc->grad, lv_area_get_width(&tri_area), + lv_area_get_height(&tri_area)); lv_opa_t * grad_opa_map = NULL; if(grad && grad_dir == LV_GRAD_DIR_HOR) { blend_dsc.src_area = &blend_area; @@ -152,9 +154,10 @@ void lv_draw_sw_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_ lv_memset(mask_buf, 0xff, area_w); blend_dsc.mask_res = lv_draw_sw_mask_apply(masks, mask_buf, draw_area.x1, y, area_w); if(grad_dir == LV_GRAD_DIR_VER) { + LV_ASSERT_NULL(grad); blend_dsc.color = grad->color_map[y - tri_area.y1]; blend_dsc.opa = grad->opa_map[y - tri_area.y1]; - if(dsc->bg_opa < LV_OPA_MAX) blend_dsc.opa = LV_OPA_MIX2(blend_dsc.opa, dsc->bg_opa); + if(dsc->opa < LV_OPA_MAX) blend_dsc.opa = LV_OPA_MIX2(blend_dsc.opa, dsc->opa); } else if(grad_dir == LV_GRAD_DIR_HOR) { if(grad_opa_map) { @@ -174,7 +177,7 @@ void lv_draw_sw_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_ } } } - lv_draw_sw_blend(draw_unit, &blend_dsc); + lv_draw_sw_blend(t, &blend_dsc); } lv_free(mask_buf); @@ -183,11 +186,11 @@ void lv_draw_sw_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_ lv_draw_sw_mask_free_param(&mask_right); if(grad) { - lv_gradient_cleanup(grad); + lv_draw_sw_grad_cleanup(grad); } #else - LV_UNUSED(draw_unit); + LV_UNUSED(t); LV_UNUSED(dsc); LV_LOG_WARN("Can't draw triangles with LV_DRAW_SW_COMPLEX == 0"); #endif /*LV_DRAW_SW_COMPLEX*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_utils.c b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_utils.c new file mode 100644 index 000000000..0f2635a65 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_utils.c @@ -0,0 +1,596 @@ +/** + * @file lv_draw_sw_utils.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_draw_sw_utils.h" +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ +#ifndef LV_DRAW_SW_RGB565_SWAP + #define LV_DRAW_SW_RGB565_SWAP(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ROTATE90_ARGB8888 + #define LV_DRAW_SW_ROTATE90_ARGB8888(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ROTATE180_ARGB8888 + #define LV_DRAW_SW_ROTATE180_ARGB8888(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ROTATE270_ARGB8888 + #define LV_DRAW_SW_ROTATE270_ARGB8888(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ROTATE90_RGB888 + #define LV_DRAW_SW_ROTATE90_RGB888(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ROTATE180_RGB888 + #define LV_DRAW_SW_ROTATE180_RGB888(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ROTATE270_RGB888 + #define LV_DRAW_SW_ROTATE270_RGB888(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ROTATE90_RGB565 + #define LV_DRAW_SW_ROTATE90_RGB565(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ROTATE180_RGB565 + #define LV_DRAW_SW_ROTATE180_RGB565(...) LV_RESULT_INVALID +#endif + +#ifndef LV_DRAW_SW_ROTATE270_RGB565 + #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 + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +#if LV_DRAW_SW_SUPPORT_ARGB8888 || LV_DRAW_SW_SUPPORT_XRGB8888 +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 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 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 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 + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_draw_sw_i1_to_argb8888(const void * buf_i1, void * buf_argb8888, uint32_t width, uint32_t height, + uint32_t buf_i1_stride, uint32_t buf_argb8888_stride, uint32_t index0_color, uint32_t index1_color) +{ + /*Extract the bits of I1 px_map and convert them to ARGB8888*/ + const uint8_t * src = buf_i1; + uint32_t * dst = buf_argb8888; + uint32_t i1_row_byte_count = width / 8; + for(uint32_t row = 0; row < height; row++) { + uint32_t * dst_p = dst; + for(uint32_t i = 0; i < i1_row_byte_count; i++) { + /*From MSB to LSB (pixel 0 to pixel 7 in a byte)*/ + for(int32_t bit = 7; bit >= 0; bit--) { + *dst_p++ = ((src[i] >> bit) & 1) ? index1_color : index0_color; + } + } + src += buf_i1_stride; + dst += buf_argb8888_stride / 4; + } +} + +void lv_draw_sw_rgb565_swap(void * buf, uint32_t buf_size_px) +{ + if(LV_DRAW_SW_RGB565_SWAP(buf, buf_size_px) == LV_RESULT_OK) return; + + uint16_t * buf16 = buf; + + /*2 pixels will be processed later, so handle 1 pixel alignment*/ + if((lv_uintptr_t)buf16 & 0x2) { + buf16[0] = ((buf16[0] & 0xff00) >> 8) | ((buf16[0] & 0x00ff) << 8); + buf16++; + buf_size_px--; + } + + uint32_t * buf32 = (uint32_t *)buf16; + uint32_t u32_cnt = buf_size_px / 2; + + while(u32_cnt >= 8) { + buf32[0] = ((buf32[0] & 0xff00ff00) >> 8) | ((buf32[0] & 0x00ff00ff) << 8); + buf32[1] = ((buf32[1] & 0xff00ff00) >> 8) | ((buf32[1] & 0x00ff00ff) << 8); + buf32[2] = ((buf32[2] & 0xff00ff00) >> 8) | ((buf32[2] & 0x00ff00ff) << 8); + buf32[3] = ((buf32[3] & 0xff00ff00) >> 8) | ((buf32[3] & 0x00ff00ff) << 8); + buf32[4] = ((buf32[4] & 0xff00ff00) >> 8) | ((buf32[4] & 0x00ff00ff) << 8); + buf32[5] = ((buf32[5] & 0xff00ff00) >> 8) | ((buf32[5] & 0x00ff00ff) << 8); + buf32[6] = ((buf32[6] & 0xff00ff00) >> 8) | ((buf32[6] & 0x00ff00ff) << 8); + buf32[7] = ((buf32[7] & 0xff00ff00) >> 8) | ((buf32[7] & 0x00ff00ff) << 8); + buf32 += 8; + u32_cnt -= 8; + } + + while(u32_cnt) { + *buf32 = ((*buf32 & 0xff00ff00) >> 8) | ((*buf32 & 0x00ff00ff) << 8); + buf32++; + u32_cnt--; + } + + /*Process the last pixel if needed*/ + if(buf_size_px & 0x1) { + uint32_t e = buf_size_px - 1; + buf16[e] = ((buf16[e] & 0xff00) >> 8) | ((buf16[e] & 0x00ff) << 8); + } + +} + +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_i1_convert_to_vtiled(const void * buf, uint32_t buf_size, uint32_t width, uint32_t height, + void * out_buf, + uint32_t out_buf_size, bool bit_order_lsb) +{ + LV_ASSERT(buf && out_buf); + LV_ASSERT(width % 8 == 0 && height % 8 == 0); + LV_ASSERT(buf_size >= (width / 8) * height); + LV_ASSERT(out_buf_size >= buf_size); + + lv_memset(out_buf, 0, out_buf_size); + + const uint8_t * src_buf = (uint8_t *)buf; + uint8_t * dst_buf = (uint8_t *)out_buf; + + for(uint32_t y = 0; y < height; y++) { + for(uint32_t x = 0; x < width; x++) { + uint32_t src_index = y * width + x; + uint32_t dst_index = x * height + y; + uint8_t bit = (src_buf[src_index / 8] >> (7 - (src_index % 8))) & 0x01; + if(bit_order_lsb) { + dst_buf[dst_index / 8] |= (bit << (dst_index % 8)); + } + else { + dst_buf[dst_index / 8] |= (bit << (7 - (dst_index % 8))); + } + } + } +} + +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) +{ + if(rotation == LV_DISPLAY_ROTATION_90) { + 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; + } + + 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; + } + + 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; + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#if LV_DRAW_SW_SUPPORT_ARGB8888 || LV_DRAW_SW_SUPPORT_XRGB8888 + +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_ROTATE270_ARGB8888(src, dst, src_width, src_height, src_stride, dst_stride)) { + return ; + } + + src_stride /= sizeof(uint32_t); + dst_stride /= sizeof(uint32_t); + + 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; + } + } +} + +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) +{ + LV_UNUSED(dest_stride); + if(LV_RESULT_OK == LV_DRAW_SW_ROTATE180_ARGB8888(src, dst, src_width, src_height, src_stride, dst_stride)) { + return ; + } + + src_stride /= sizeof(uint32_t); + dest_stride /= sizeof(uint32_t); + + 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 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_ROTATE90_ARGB8888(src, dst, src_width, src_height, src_stride, dst_stride)) { + return ; + } + + src_stride /= sizeof(uint32_t); + dst_stride /= sizeof(uint32_t); + + 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; + } + } +} + +#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, src_width, src_height, src_stride, dst_stride)) { + return ; + } + + 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*/ + } + } +} + +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, src_width, src_height, src_stride, dst_stride)) { + return ; + } + + for(int32_t y = 0; y < height; ++y) { + for(int32_t x = 0; x < width; ++x) { + int32_t srcIndex = y * src_stride + x * 3; + int32_t dstIndex = (height - y - 1) * dest_stride + (width - x - 1) * 3; + dst[dstIndex] = src[srcIndex]; + dst[dstIndex + 1] = src[srcIndex + 1]; + dst[dstIndex + 2] = src[srcIndex + 2]; + } + } +} + +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, 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 * 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*/ + } + } +} + +#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_ROTATE270_RGB565(src, dst, src_width, src_height, src_stride, dst_stride)) { + return ; + } + + src_stride /= sizeof(uint16_t); + dst_stride /= sizeof(uint16_t); + + 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; + } + } +} + +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, width, height, src_stride)) { + return ; + } + + src_stride /= sizeof(uint16_t); + dest_stride /= sizeof(uint16_t); + + 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 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_ROTATE90_RGB565(src, dst, src_width, src_height, src_stride, dst_stride)) { + return ; + } + + src_stride /= sizeof(uint16_t); + dst_stride /= sizeof(uint16_t); + + 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; + } + } +} + +#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_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 = (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_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 = 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_utils.h b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_utils.h new file mode 100644 index 000000000..cf4789223 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_utils.h @@ -0,0 +1,111 @@ +/** + * @file lv_draw_sw_utils.h + * + */ + +#ifndef LV_DRAW_SW_UTILS_H +#define LV_DRAW_SW_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_DRAW_SW + +#include "../../misc/lv_area.h" +#include "../../misc/lv_color.h" +#include "../../display/lv_display.h" + + +/********************* + * DEFINES + *********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Converts an I1 buffer to ARGB8888 format. + * @param buf_i1 pointer to buffer with I1 formatted render + * @param buf_argb8888 pointer to buffer for ARGB8888 render + * @param width width in pixels of the area. + * must be a multiple of 8. + * @param height height in pixels of the area + * @param buf_i1_stride stride of i1 buffer in bytes + * @param buf_argb8888_stride stride of argb8888 buffer in bytes + * @param index0_color color of the 0 bits of i1 buf + * @param index1_color color of the 1 bits of i1 buf + */ +void lv_draw_sw_i1_to_argb8888(const void * buf_i1, void * buf_argb8888, uint32_t width, uint32_t height, + uint32_t buf_i1_stride, uint32_t buf_argb8888_stride, uint32_t index0_color, uint32_t index1_color); + +/** + * 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); + +/** + * 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); + + +/** + * Convert a draw buffer in I1 color format from htiled (row-wise) + * to vtiled (column-wise) buffer layout. The conversion assumes that the buffer width + * and height is rounded to a multiple of 8. + * @param buf pointer to the buffer to be converted + * @param buf_size size of the buffer in bytes + * @param width width of the buffer + * @param height height of the buffer + * @param out_buf pointer to the output buffer + * @param out_buf_size size of the output buffer in bytes + * @param bit_order_lsb bit order of the resulting vtiled buffer + */ +void lv_draw_sw_i1_convert_to_vtiled(const void * buf, uint32_t buf_size, uint32_t width, uint32_t height, + void * out_buf, + uint32_t out_buf_size, bool bit_order_lsb); + +/** + * 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_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_stride, + int32_t dest_stride, lv_display_rotation_t rotation, lv_color_format_t color_format); + +/*********************** + * GLOBAL VARIABLES + ***********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_DRAW_SW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_SW_UTILS_H*/ 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 4b99a47e9..6e3493f86 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 @@ -18,6 +18,9 @@ #include "../../libs/thorvg/thorvg_capi.h" #endif #include "../../stdlib/lv_string.h" +#include "blend/lv_draw_sw_blend_private.h" +#include "blend/lv_draw_sw_blend_to_rgb565.h" +#include "blend/lv_draw_sw_blend_to_rgb888.h" /********************* * DEFINES @@ -40,6 +43,12 @@ typedef struct { uint8_t a; } _tvg_color; +typedef struct { + Tvg_Canvas * canvas; + int32_t partial_y_offset; + int32_t translate_x; + int32_t translate_y; +} _tvg_draw_state; /********************** * STATIC PROTOTYPES **********************/ @@ -56,8 +65,8 @@ 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) - 1; - rect->h = lv_area_get_height(area) - 1; + rect->w = lv_area_get_width(area); + rect->h = lv_area_get_height(area); } static void lv_color_to_tvg(_tvg_color * color, const lv_color32_t * c, lv_opa_t opa) @@ -186,7 +195,7 @@ static void _setup_gradient(Tvg_Gradient * gradient, const lv_vector_gradient_t 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]); + const lv_grad_stop_t * s = &(grad->stops[i]); stops[i].offset = s->frac / 255.0f; stops[i].r = s->color.red; @@ -323,13 +332,17 @@ static void _set_paint_fill(Tvg_Paint * obj, Tvg_Canvas * canvas, const lv_vecto tvg_shape_set_fill_color(obj, c.r, c.g, c.b, c.a); } else if(dsc->style == LV_VECTOR_DRAW_STYLE_PATTERN) { - float x, y, w, h; - tvg_paint_get_bounds(obj, &x, &y, &w, &h, false); + lv_matrix_t imx = *matrix; + + if(dsc->fill_units == LV_VECTOR_FILL_UNITS_OBJECT_BOUNDING_BOX) { + /* Convert to object bounding box coordinates */ + float x, y, w, h; + tvg_paint_get_bounds(obj, &x, &y, &w, &h, false); + lv_matrix_translate(&imx, x, y); + } - lv_matrix_t imx; - lv_memcpy(&imx, matrix, sizeof(lv_matrix_t)); - lv_matrix_translate(&imx, x, y); lv_matrix_multiply(&imx, &dsc->matrix); + _set_paint_fill_pattern(obj, canvas, &dsc->img_dsc, &imx); } else if(dsc->style == LV_VECTOR_DRAW_STYLE_GRADIENT) { @@ -365,16 +378,56 @@ 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)); } +static void _blend_draw_buf(lv_draw_buf_t * draw_buf, const lv_area_t * dst_area, const lv_draw_buf_t * new_buf, + const lv_area_t * src_area) +{ + lv_draw_sw_blend_image_dsc_t fill_dsc; + fill_dsc.dest_w = src_area->x2; + fill_dsc.dest_h = src_area->y2; + fill_dsc.dest_stride = draw_buf->header.stride; + fill_dsc.dest_buf = draw_buf->data; + + fill_dsc.opa = LV_OPA_100; + fill_dsc.blend_mode = LV_BLEND_MODE_NORMAL; + fill_dsc.src_stride = new_buf->header.stride; + fill_dsc.src_color_format = new_buf->header.cf; + fill_dsc.src_buf = new_buf->data; + + fill_dsc.mask_buf = NULL; + fill_dsc.mask_stride = 0; + + fill_dsc.relative_area = *dst_area; + fill_dsc.src_area = *src_area; + + switch(draw_buf->header.cf) { +#if LV_DRAW_SW_SUPPORT_RGB565 + case LV_COLOR_FORMAT_RGB565: + case LV_COLOR_FORMAT_RGB565A8: + lv_draw_sw_blend_image_to_rgb565(&fill_dsc); + break; +#endif +#if LV_DRAW_SW_SUPPORT_RGB888 + case LV_COLOR_FORMAT_RGB888: + lv_draw_sw_blend_image_to_rgb888(&fill_dsc, 3); + break; +#endif + default: + break; + } +} + static void _task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc) { - Tvg_Canvas * canvas = (Tvg_Canvas *)ctx; + _tvg_draw_state * state = (_tvg_draw_state *)ctx; + Tvg_Canvas * canvas = (Tvg_Canvas *)state->canvas; Tvg_Paint * obj = tvg_shape_new(); - if(!path) { /*clear*/ - _tvg_rect rc; - lv_area_to_tvg(&rc, &dsc->scissor_area); + int32_t y_offset = state->partial_y_offset; + _tvg_rect rc; + lv_area_to_tvg(&rc, &dsc->scissor_area); + if(!path) { /*clear*/ _tvg_color c; lv_color_to_tvg(&c, &dsc->fill_dsc.color, dsc->fill_dsc.opa); @@ -384,31 +437,38 @@ static void _task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_ve 0.0f, 0.0f, 1.0f, }; _set_paint_matrix(obj, &mtx); - tvg_shape_append_rect(obj, rc.x, rc.y, rc.w, rc.h, 0, 0); + mtx.e23 -= (float)(y_offset); + tvg_shape_append_rect(obj, rc.x + state->translate_x, rc.y + state->translate_y, rc.w, rc.h, 0, 0); tvg_shape_set_fill_color(obj, c.r, c.g, c.b, c.a); } else { + tvg_canvas_set_viewport(canvas, (int32_t)rc.x + state->translate_x, (int32_t)(rc.y - y_offset) + state->translate_y, + (int32_t)rc.w, (int32_t)rc.h); + + lv_matrix_t matrix; + lv_matrix_identity(&matrix); + lv_matrix_translate(&matrix, state->translate_x, state->translate_y); + lv_matrix_multiply(&matrix, &dsc->matrix); Tvg_Matrix mtx; - lv_matrix_to_tvg(&mtx, &dsc->matrix); + lv_matrix_to_tvg(&mtx, &matrix); + mtx.e23 -= (float)(y_offset); _set_paint_matrix(obj, &mtx); _set_paint_shape(obj, path); - _set_paint_fill(obj, canvas, &dsc->fill_dsc, &dsc->matrix); + _set_paint_fill(obj, canvas, &dsc->fill_dsc, &matrix); _set_paint_stroke(obj, &dsc->stroke_dsc); _set_paint_blend_mode(obj, dsc->blend_mode); } - tvg_canvas_push(canvas, obj); } /********************** * GLOBAL FUNCTIONS **********************/ -void lv_draw_sw_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_task_dsc_t * dsc) -{ - LV_UNUSED(draw_unit); +void lv_draw_sw_vector(lv_draw_task_t * t, lv_draw_vector_task_dsc_t * dsc) +{ if(dsc->task_list == NULL) return; @@ -417,32 +477,47 @@ void lv_draw_sw_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_task_dsc if(draw_buf == NULL) return; + 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); + uint32_t stride = draw_buf->header.stride; + lv_color_format_t cf = draw_buf->header.cf; + bool allow_buffer = false; + lv_draw_buf_t * new_buf = NULL; + if(cf != LV_COLOR_FORMAT_ARGB8888 && \ cf != LV_COLOR_FORMAT_XRGB8888) { - LV_LOG_ERROR("unsupported layer color: %d", cf); - return; + allow_buffer = true; + new_buf = lv_draw_buf_create(width, height, LV_COLOR_FORMAT_ARGB8888, LV_STRIDE_AUTO); + lv_draw_buf_clear(new_buf, NULL); + buf = new_buf->data; + stride = new_buf->header.stride; } - - void * buf = draw_buf->data; - 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_area_to_tvg(&rc, &t->clip_area); + tvg_canvas_set_viewport(canvas, (int32_t)rc.x, (int32_t)(rc.y - layer->partial_y_offset), (int32_t)rc.w, (int32_t)rc.h); + + _tvg_draw_state state = {canvas, layer->partial_y_offset, -layer->buf_area.x1, -layer->buf_area.y1}; 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, &state); + dsc->task_list = NULL; if(tvg_canvas_draw(canvas) == TVG_RESULT_SUCCESS) { tvg_canvas_sync(canvas); } + if(allow_buffer) { + lv_area_t src_area = {0, 0, width, height}; + _blend_draw_buf(draw_buf, &layer->buf_area, new_buf, &src_area); + lv_draw_buf_destroy(new_buf); + } + tvg_canvas_destroy(canvas); } 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 1a991ce0f..47c9f91ce 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 @@ -51,7 +51,6 @@ static int32_t draw_delete(lv_draw_unit_t * draw_unit); /********************** * GLOBAL FUNCTIONS **********************/ - void lv_draw_vg_lite_init(void) { #if LV_VG_LITE_USE_GPU_INIT @@ -71,14 +70,16 @@ void lv_draw_vg_lite_init(void) unit->base_unit.dispatch_cb = draw_dispatch; unit->base_unit.evaluate_cb = draw_evaluate; unit->base_unit.delete_cb = draw_delete; + unit->base_unit.name = "VG_LITE"; lv_vg_lite_image_dsc_init(unit); #if LV_USE_VECTOR_GRAPHIC - lv_vg_lite_grad_init(unit, LV_VG_LITE_GRAD_CACHE_CNT); + unit->grad_ctx = lv_vg_lite_grad_ctx_create(LV_VG_LITE_GRAD_CACHE_CNT, unit); lv_vg_lite_stroke_init(unit, LV_VG_LITE_STROKE_CACHE_CNT); #endif lv_vg_lite_path_init(unit); lv_vg_lite_decoder_init(); + lv_draw_vg_lite_label_init(unit); } void lv_draw_vg_lite_deinit(void) @@ -91,8 +92,17 @@ void lv_draw_vg_lite_deinit(void) static bool check_image_is_supported(const lv_draw_image_dsc_t * dsc) { + return lv_vg_lite_is_src_cf_supported(dsc->header.cf); +} + +static bool check_arc_is_supported(const lv_draw_arc_dsc_t * dsc) +{ + if(dsc->img_src == NULL) { + return true; + } + lv_image_header_t header; - lv_result_t res = lv_image_decoder_get_info(dsc->src, &header); + lv_result_t res = lv_image_decoder_get_info(dsc->img_src, &header); if(res != LV_RESULT_OK) { LV_LOG_TRACE("get image info failed"); return false; @@ -104,9 +114,10 @@ static bool check_image_is_supported(const lv_draw_image_dsc_t * dsc) static void draw_execute(lv_draw_vg_lite_unit_t * u) { lv_draw_task_t * t = u->task_act; - lv_draw_unit_t * draw_unit = (lv_draw_unit_t *)u; + lv_layer_t * layer = t->target_layer; - lv_layer_t * layer = u->base_unit.target_layer; + /* remember draw unit for access to unit's context */ + t->draw_unit = (lv_draw_unit_t *)u; lv_vg_lite_buffer_from_draw_buf(&u->target_buffer, layer->draw_buf); @@ -124,47 +135,52 @@ static void draw_execute(lv_draw_vg_lite_unit_t * u) lv_vg_lite_matrix_multiply(&u->global_matrix, &layer_matrix); /* Crop out extra pixels drawn due to scaling accuracy issues */ + lv_area_t scissor_area = layer->phy_clip_area; +#else + lv_area_t scissor_area = layer->_clip_area; +#endif + lv_area_move(&scissor_area, -layer->buf_area.x1, -layer->buf_area.y1); 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_LETTER: + lv_draw_vg_lite_letter(t, t->draw_dsc, &t->area); + break; case LV_DRAW_TASK_TYPE_LABEL: - lv_draw_vg_lite_label(draw_unit, t->draw_dsc, &t->area); + lv_draw_vg_lite_label(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_FILL: - lv_draw_vg_lite_fill(draw_unit, t->draw_dsc, &t->area); + lv_draw_vg_lite_fill(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_BORDER: - lv_draw_vg_lite_border(draw_unit, t->draw_dsc, &t->area); + lv_draw_vg_lite_border(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_BOX_SHADOW: - lv_draw_vg_lite_box_shadow(draw_unit, t->draw_dsc, &t->area); + lv_draw_vg_lite_box_shadow(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_IMAGE: - lv_draw_vg_lite_img(draw_unit, t->draw_dsc, &t->area, false); + lv_draw_vg_lite_img(t, t->draw_dsc, &t->area, false); break; case LV_DRAW_TASK_TYPE_ARC: - lv_draw_vg_lite_arc(draw_unit, t->draw_dsc, &t->area); + lv_draw_vg_lite_arc(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_LINE: - lv_draw_vg_lite_line(draw_unit, t->draw_dsc); + lv_draw_vg_lite_line(t, t->draw_dsc); break; case LV_DRAW_TASK_TYPE_LAYER: - lv_draw_vg_lite_layer(draw_unit, t->draw_dsc, &t->area); + lv_draw_vg_lite_layer(t, t->draw_dsc, &t->area); break; case LV_DRAW_TASK_TYPE_TRIANGLE: - lv_draw_vg_lite_triangle(draw_unit, t->draw_dsc); + lv_draw_vg_lite_triangle(t, t->draw_dsc); break; case LV_DRAW_TASK_TYPE_MASK_RECTANGLE: - lv_draw_vg_lite_mask_rect(draw_unit, t->draw_dsc, &t->area); + lv_draw_vg_lite_mask_rect(t, t->draw_dsc, &t->area); break; #if LV_USE_VECTOR_GRAPHIC case LV_DRAW_TASK_TYPE_VECTOR: - lv_draw_vg_lite_vector(draw_unit, t->draw_dsc); + lv_draw_vg_lite_vector(t, t->draw_dsc); break; #endif default: @@ -184,7 +200,7 @@ static int32_t draw_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, VG_LITE_DRAW_UNIT_ID); + lv_draw_task_t * t = lv_draw_get_available_task(layer, NULL, VG_LITE_DRAW_UNIT_ID); /* 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) { @@ -203,8 +219,6 @@ static int32_t draw_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer) } t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; - u->base_unit.target_layer = layer; - u->base_unit.clip_area = &t->clip_area; u->task_act = t; draw_execute(u); @@ -229,6 +243,7 @@ static int32_t draw_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task) } switch(task->type) { + case LV_DRAW_TASK_TYPE_LETTER: case LV_DRAW_TASK_TYPE_LABEL: case LV_DRAW_TASK_TYPE_FILL: case LV_DRAW_TASK_TYPE_BORDER: @@ -237,7 +252,6 @@ static int32_t draw_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task) #endif case LV_DRAW_TASK_TYPE_LAYER: case LV_DRAW_TASK_TYPE_LINE: - case LV_DRAW_TASK_TYPE_ARC: case LV_DRAW_TASK_TYPE_TRIANGLE: case LV_DRAW_TASK_TYPE_MASK_RECTANGLE: @@ -246,6 +260,13 @@ static int32_t draw_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task) #endif break; + case LV_DRAW_TASK_TYPE_ARC: { + if(!check_arc_is_supported(task->draw_dsc)) { + return 0; + } + } + break; + case LV_DRAW_TASK_TYPE_IMAGE: { if(!check_image_is_supported(task->draw_dsc)) { return 0; @@ -258,9 +279,12 @@ static int32_t draw_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task) return 0; } - /* The draw unit is able to draw this task. */ - task->preference_score = 80; - task->preferred_draw_unit_id = VG_LITE_DRAW_UNIT_ID; + if(task->preference_score > 80) { + /* The draw unit is able to draw this task. */ + task->preference_score = 80; + task->preferred_draw_unit_id = VG_LITE_DRAW_UNIT_ID; + } + return 1; } @@ -270,11 +294,12 @@ static int32_t draw_delete(lv_draw_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_grad_ctx_delete(unit->grad_ctx); lv_vg_lite_stroke_deinit(unit); #endif lv_vg_lite_path_deinit(unit); lv_vg_lite_decoder_deinit(); + lv_draw_vg_lite_label_deinit(unit); 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 63ff7f504..0b873848b 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 @@ -13,11 +13,9 @@ extern "C" { /********************* * INCLUDES *********************/ - #include "../../lv_conf_internal.h" #if LV_USE_DRAW_VG_LITE - #include "../lv_draw.h" #include "../../draw/lv_draw_vector.h" #include "../../draw/lv_draw_arc.h" @@ -35,46 +33,53 @@ extern "C" { * TYPEDEFS **********************/ +struct _lv_draw_vg_lite_unit_t; + /********************** * GLOBAL PROTOTYPES **********************/ - void lv_draw_buf_vg_lite_init_handlers(void); void lv_draw_vg_lite_init(void); void lv_draw_vg_lite_deinit(void); -void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, +void lv_draw_vg_lite_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords); -void lv_draw_vg_lite_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_dsc_t * dsc, +void lv_draw_vg_lite_box_shadow(lv_draw_task_t * t, const lv_draw_box_shadow_dsc_t * dsc, const lv_area_t * coords); -void lv_draw_vg_lite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc, +void lv_draw_vg_lite_border(lv_draw_task_t * t, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords); -void lv_draw_vg_lite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, +void lv_draw_vg_lite_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords); -void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc, +void lv_draw_vg_lite_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords, bool no_cache); -void lv_draw_vg_lite_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, +void lv_draw_vg_lite_label_init(struct _lv_draw_vg_lite_unit_t * u); + +void lv_draw_vg_lite_label_deinit(struct _lv_draw_vg_lite_unit_t * u); + +void lv_draw_vg_lite_letter(lv_draw_task_t * t, const lv_draw_letter_dsc_t * dsc, const lv_area_t * coords); + +void lv_draw_vg_lite_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, const lv_area_t * coords); -void lv_draw_vg_lite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, +void lv_draw_vg_lite_layer(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * coords); -void lv_draw_vg_lite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc); +void lv_draw_vg_lite_line(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc); -void lv_draw_vg_lite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc); +void lv_draw_vg_lite_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc); -void lv_draw_vg_lite_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_dsc_t * dsc, +void lv_draw_vg_lite_mask_rect(lv_draw_task_t * t, const lv_draw_mask_rect_dsc_t * dsc, const lv_area_t * coords); #if LV_USE_VECTOR_GRAPHIC -void lv_draw_vg_lite_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_task_dsc_t * dsc); +void lv_draw_vg_lite_vector(lv_draw_task_t * t, const lv_draw_vector_task_dsc_t * dsc); #endif /********************** 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 be995ceac..6bba17abe 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 @@ -51,14 +51,13 @@ /********************** * GLOBAL FUNCTIONS **********************/ - -void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, +void lv_draw_vg_lite_arc(lv_draw_task_t * t, const lv_draw_arc_dsc_t * dsc, const lv_area_t * coords) { - lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit; + lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)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, &t->clip_area)) { /*Fully clipped, nothing to do*/ return; } @@ -80,16 +79,13 @@ void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * d return; } - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; 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, &clip_area); + lv_vg_lite_path_set_bounding_box_area(path, &clip_area); float radius_out = dsc->radius; float radius_in = dsc->radius - dsc->width; - float half_width = dsc->width * 0.5f; - float radius_center = radius_out - half_width; float cx = dsc->center.x; float cy = dsc->center.y; @@ -97,53 +93,66 @@ void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * d if(math_equal(sweep_angle, 360)) { lv_vg_lite_path_append_circle(path, cx, cy, radius_out, radius_out); - lv_vg_lite_path_append_circle(path, cx, cy, radius_in, radius_in); + + /* radius_in <= 0, normal fill circle */ + if(radius_in > 0) { + lv_vg_lite_path_append_circle(path, cx, cy, radius_in, radius_in); + } fill = VG_LITE_FILL_EVEN_ODD; } else { - /* radius_out start point */ float start_angle_rad = MATH_RADIANS(start_angle); - float start_x = radius_out * MATH_COSF(start_angle_rad) + cx; - float start_y = radius_out * MATH_SINF(start_angle_rad) + cy; - - /* radius_in start point */ float end_angle_rad = MATH_RADIANS(end_angle); - float end_x = radius_in * MATH_COSF(end_angle_rad) + cx; - float end_y = radius_in * MATH_SINF(end_angle_rad) + cy; - lv_vg_lite_path_move_to(path, start_x, start_y); + if(radius_in > 0) { + /* radius_out start point */ + float start_x = radius_out * MATH_COSF(start_angle_rad) + cx; + float start_y = radius_out * MATH_SINF(start_angle_rad) + cy; - /* radius_out arc */ - lv_vg_lite_path_append_arc(path, - cx, cy, - radius_out, - start_angle, - sweep_angle, - false); + /* radius_in start point */ + float end_x = radius_in * MATH_COSF(end_angle_rad) + cx; + float end_y = radius_in * MATH_SINF(end_angle_rad) + cy; - /* line to radius_in */ - lv_vg_lite_path_line_to(path, end_x, end_y); + lv_vg_lite_path_move_to(path, start_x, start_y); - /* radius_in arc */ - lv_vg_lite_path_append_arc(path, - cx, cy, - radius_in, - end_angle, - -sweep_angle, - false); + /* radius_out arc */ + lv_vg_lite_path_append_arc(path, + cx, cy, + radius_out, + start_angle, + sweep_angle, + false); - /* close arc */ - lv_vg_lite_path_close(path); + /* line to radius_in */ + lv_vg_lite_path_line_to(path, end_x, end_y); + + /* radius_in arc */ + lv_vg_lite_path_append_arc(path, + cx, cy, + radius_in, + end_angle, + -sweep_angle, + false); + + /* close arc */ + lv_vg_lite_path_close(path); + } + else { + /* draw a normal arc pie shape */ + lv_vg_lite_path_append_arc(path, cx, cy, radius_out, start_angle, sweep_angle, true); + } /* draw round */ - if(dsc->rounded && half_width > 0) { - float rcx1 = cx + radius_center * MATH_COSF(end_angle_rad); - float rcy1 = cy + radius_center * MATH_SINF(end_angle_rad); - lv_vg_lite_path_append_circle(path, rcx1, rcy1, half_width, half_width); + if(dsc->rounded && dsc->width > 0) { + float round_radius = radius_out > dsc->width ? dsc->width / 2.0f : radius_out / 2.0f; + float round_center = radius_out - round_radius; + float rcx1 = cx + round_center * MATH_COSF(end_angle_rad); + float rcy1 = cy + round_center * MATH_SINF(end_angle_rad); + lv_vg_lite_path_append_circle(path, rcx1, rcy1, round_radius, round_radius); - float rcx2 = cx + radius_center * MATH_COSF(start_angle_rad); - float rcy2 = cy + radius_center * MATH_SINF(start_angle_rad); - lv_vg_lite_path_append_circle(path, rcx2, rcy2, half_width, half_width); + float rcx2 = cx + round_center * MATH_COSF(start_angle_rad); + float rcy2 = cy + round_center * MATH_SINF(start_angle_rad); + lv_vg_lite_path_append_circle(path, rcx2, rcy2, round_radius, round_radius); } } @@ -151,55 +160,54 @@ void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * d vg_lite_matrix_t matrix = u->global_matrix; - vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true); - - vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); - - LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); - LV_VG_LITE_ASSERT_PATH(vg_lite_path); - LV_VG_LITE_ASSERT_MATRIX(&matrix); - - LV_PROFILER_BEGIN_TAG("vg_lite_draw"); - LV_VG_LITE_CHECK_ERROR(vg_lite_draw( - &u->target_buffer, - vg_lite_path, - fill, - &matrix, - VG_LITE_BLEND_SRC_OVER, - color)); - LV_PROFILER_END_TAG("vg_lite_draw"); - if(dsc->img_src) { vg_lite_buffer_t src_buf; lv_image_decoder_dsc_t decoder_dsc; if(lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->img_src, false, true)) { + + vg_lite_color_t img_color = 0; + if(dsc->opa < LV_OPA_COVER) { + /* normal image opa */ + src_buf.image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; + lv_memset(&img_color, dsc->opa, sizeof(img_color)); + } + vg_lite_matrix_t path_matrix = u->global_matrix; /* move image to center */ - vg_lite_translate(cx - radius_out, cy - radius_out, &matrix); + float img_half_w = decoder_dsc.decoded->header.w / 2.0f; + float img_half_h = decoder_dsc.decoded->header.h / 2.0f; + vg_lite_translate(cx - img_half_w, cy - img_half_h, &matrix); - LV_VG_LITE_ASSERT_MATRIX(&path_matrix); + lv_vg_lite_draw_pattern( + &u->target_buffer, + lv_vg_lite_path_get_path(path), + fill, + &path_matrix, + &src_buf, + &matrix, + VG_LITE_BLEND_SRC_OVER, + VG_LITE_PATTERN_COLOR, + 0, + img_color, + VG_LITE_FILTER_BI_LINEAR); - LV_PROFILER_BEGIN_TAG("vg_lite_draw_pattern"); - LV_VG_LITE_CHECK_ERROR(vg_lite_draw_pattern( - &u->target_buffer, - vg_lite_path, - fill, - &path_matrix, - &src_buf, - &matrix, - VG_LITE_BLEND_SRC_OVER, - VG_LITE_PATTERN_COLOR, - 0, - color, - VG_LITE_FILTER_BI_LINEAR)); - LV_PROFILER_END_TAG("vg_lite_draw_pattern"); lv_vg_lite_pending_add(u->image_dsc_pending, &decoder_dsc); } } + else { + /* normal color fill */ + lv_vg_lite_draw( + &u->target_buffer, + lv_vg_lite_path_get_path(path), + fill, + &matrix, + VG_LITE_BLEND_SRC_OVER, + lv_vg_lite_color(dsc->color, dsc->opa, true)); + } lv_vg_lite_path_drop(u, path); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } /********************** 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 5860baa1f..52c623ac2 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 @@ -16,11 +16,14 @@ #include "lv_draw_vg_lite_type.h" #include "lv_vg_lite_utils.h" #include "lv_vg_lite_path.h" +#include "lv_vg_lite_math.h" /********************* * DEFINES *********************/ +#define HAS_BORDER_SIDE(dsc_side, side) (((dsc_side) & (side)) == (side)) + /********************** * TYPEDEFS **********************/ @@ -29,6 +32,11 @@ * STATIC PROTOTYPES **********************/ +static vg_lite_fill_t path_append_inner_rect(lv_vg_lite_path_t * path, + const lv_draw_border_dsc_t * dsc, + int32_t x, int32_t y, int32_t w, int32_t h, + float r); + /********************** * STATIC VARIABLES **********************/ @@ -40,19 +48,18 @@ /********************** * GLOBAL FUNCTIONS **********************/ - -void lv_draw_vg_lite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc, +void lv_draw_vg_lite_border(lv_draw_task_t * t, const lv_draw_border_dsc_t * dsc, const lv_area_t * coords) { - lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit; + lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)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, &t->clip_area)) { /*Fully clipped, nothing to do*/ return; } - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; int32_t w = lv_area_get_width(coords); int32_t h = lv_area_get_height(coords); @@ -62,12 +69,9 @@ void lv_draw_vg_lite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc r_out = LV_MIN(r_out, r_short); } - int32_t border_w = dsc->width; - float r_in = LV_MAX(0, r_out - border_w); - 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_set_bounding_box_area(path, &clip_area); /* outer rect */ lv_vg_lite_path_append_rect(path, @@ -76,39 +80,310 @@ void lv_draw_vg_lite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc 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); + vg_lite_fill_t fill_rule = path_append_inner_rect(path, dsc, coords->x1, coords->y1, w, h, r_out); lv_vg_lite_path_end(path); vg_lite_matrix_t matrix = u->global_matrix; - vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true); - - vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); - - LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); - LV_VG_LITE_ASSERT_PATH(vg_lite_path); - LV_VG_LITE_ASSERT_MATRIX(&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_EVEN_ODD, - &matrix, - VG_LITE_BLEND_SRC_OVER, - color)); - LV_PROFILER_END_TAG("vg_lite_draw"); + lv_vg_lite_draw( + &u->target_buffer, + lv_vg_lite_path_get_path(path), + fill_rule, + &matrix, + VG_LITE_BLEND_SRC_OVER, + lv_vg_lite_color(dsc->color, dsc->opa, true)); lv_vg_lite_path_drop(u, path); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } /********************** * STATIC FUNCTIONS **********************/ +static vg_lite_fill_t path_append_inner_rect(lv_vg_lite_path_t * path, + const lv_draw_border_dsc_t * dsc, + int32_t x, int32_t y, int32_t w, int32_t h, + float r) +{ + LV_PROFILER_DRAW_BEGIN; + + const float half_w = w / 2.0f; + const float half_h = h / 2.0f; + const int32_t border_w = dsc->width; + const float border_w_max = LV_MIN(half_w, half_h); + + /* normal fill, no inner rect */ + if(border_w >= border_w_max) { + LV_PROFILER_DRAW_END; + return VG_LITE_FILL_EVEN_ODD; + } + + const float r_in = r - border_w; + + /* full border, simple rect */ + if(dsc->side == LV_BORDER_SIDE_FULL) { + lv_vg_lite_path_append_rect(path, + x + border_w, y + border_w, + w - border_w * 2, h - border_w * 2, + r_in < 0 ? 0 : r_in); + LV_PROFILER_DRAW_END; + return VG_LITE_FILL_EVEN_ODD; + } + + /* no-radius case, simple inner rect */ + if(dsc->radius <= 0) { + int32_t x_offset = 0; + int32_t y_offset = 0; + int32_t w_inner = w; + int32_t h_inner = h; + + if(dsc->side & LV_BORDER_SIDE_TOP) { + y_offset += border_w; + h_inner -= border_w; + } + if(dsc->side & LV_BORDER_SIDE_LEFT) { + x_offset += border_w; + w_inner -= border_w; + } + if(dsc->side & LV_BORDER_SIDE_BOTTOM) { + h_inner -= border_w; + } + if(dsc->side & LV_BORDER_SIDE_RIGHT) { + w_inner -= border_w; + } + + lv_vg_lite_path_append_rect(path, + x + x_offset, + y + y_offset, + w_inner, + h_inner, + 0); + LV_PROFILER_DRAW_END; + return VG_LITE_FILL_EVEN_ODD; + } + + /* reset outter rect path */ + lv_vg_lite_path_reset(path, VG_LITE_FP32); + + /* coordinate reference map: https://github.com/lvgl/lvgl/pull/6796 */ + const float c1_x = x + r; + const float c1_y = y + r; + const float c2_x = x + w - r; + const float c2_y = c1_y; + const float c3_x = c2_x; + const float c3_y = y + h - r; + const float c4_x = c1_x; + const float c4_y = c3_y; + + /* When border_w > r, No need to calculate the intersection of the arc and the line */ + if(r_in <= 0) { + const float p1_x = x; + const float p1_y = y + border_w; + const float p2_x = x; + const float p2_y = y + r; + const float p3_x = x + r; + const float p3_y = y; + const float p4_x = x + border_w; + const float p4_y = y; + + const float p5_x = x + w - border_w; + const float p5_y = y; + const float p6_x = x + w - r; + const float p6_y = y; + const float p7_x = x + w; + const float p7_y = y + r; + const float p8_x = x + w; + const float p8_y = y + border_w; + + const float p9_x = x + w; + const float p9_y = y + h - border_w; + const float p10_x = x + w; + const float p10_y = y + h - r; + const float p11_x = x + w - r; + const float p11_y = y + h; + const float p12_x = x + w - border_w; + const float p12_y = y + h; + + const float p13_x = x + border_w; + const float p13_y = y + h; + const float p14_x = x + r; + const float p14_y = y + h; + const float p15_x = x; + const float p15_y = y + h - r; + const float p16_x = x; + const float p16_y = y + h - border_w; + + if(dsc->side & LV_BORDER_SIDE_BOTTOM) { + lv_vg_lite_path_move_to(path, p16_x, p16_y); + lv_vg_lite_path_line_to(path, p9_x, p9_y); + lv_vg_lite_path_line_to(path, p10_x, p10_y); + lv_vg_lite_path_append_arc_right_angle(path, p10_x, p10_y, c3_x, c3_y, p11_x, p11_y); + lv_vg_lite_path_line_to(path, p14_x, p14_y); + lv_vg_lite_path_append_arc_right_angle(path, p14_x, p14_y, c4_x, c4_y, p15_x, p15_y); + lv_vg_lite_path_close(path); + } + + if(dsc->side & LV_BORDER_SIDE_TOP) { + lv_vg_lite_path_move_to(path, p1_x, p1_y); + lv_vg_lite_path_line_to(path, p2_x, p2_y); + lv_vg_lite_path_append_arc_right_angle(path, p2_x, p2_y, c1_x, c1_y, p3_x, p3_y); + lv_vg_lite_path_line_to(path, p6_x, p6_y); + lv_vg_lite_path_append_arc_right_angle(path, p6_x, p6_y, c2_x, c2_y, p7_x, p7_y); + lv_vg_lite_path_line_to(path, p8_x, p8_y); + lv_vg_lite_path_close(path); + } + + if(dsc->side & LV_BORDER_SIDE_LEFT) { + lv_vg_lite_path_move_to(path, p4_x, p4_y); + lv_vg_lite_path_line_to(path, p13_x, p13_y); + lv_vg_lite_path_line_to(path, p14_x, p14_y); + lv_vg_lite_path_append_arc_right_angle(path, p14_x, p14_y, c4_x, c4_y, p15_x, p15_y); + lv_vg_lite_path_line_to(path, p2_x, p2_y); + lv_vg_lite_path_append_arc_right_angle(path, p2_x, p2_y, c1_x, c1_y, p3_x, p3_y); + lv_vg_lite_path_close(path); + } + + if(dsc->side & LV_BORDER_SIDE_RIGHT) { + lv_vg_lite_path_move_to(path, p5_x, p5_y); + lv_vg_lite_path_line_to(path, p6_x, p6_y); + lv_vg_lite_path_append_arc_right_angle(path, p6_x, p6_y, c2_x, c2_y, p7_x, p7_y); + lv_vg_lite_path_line_to(path, p10_x, p10_y); + lv_vg_lite_path_append_arc_right_angle(path, p10_x, p10_y, c3_x, c3_y, p11_x, p11_y); + lv_vg_lite_path_line_to(path, p12_x, p12_y); + lv_vg_lite_path_close(path); + } + + LV_PROFILER_DRAW_END; + return VG_LITE_FILL_NON_ZERO; + } + + /* When border_w < r, Calculate the intersection of an arc and a line */ + + /* r^2 - r_in^2 = offset^2 */ + const float offset = MATH_SQRTF((2 * r - border_w) * border_w); + const float sweep_alpha = MATH_DEGREES(MATH_ACOSF(r_in / r)); + const float sweep_beta = 90 - sweep_alpha; + + const float p1_x = x + border_w; + const float p1_y = y + r; + const float p2_x = x; + const float p2_y = y + r; + const float p3_x = x + border_w; + const float p3_y = y + r - offset; + const float p4_x = x + r - offset; + const float p4_y = y + border_w; + const float p5_x = x + r; + const float p5_y = y; + const float p6_x = x + r; + const float p6_y = y + border_w; + + const float p7_x = x + w - r; + const float p7_y = y + border_w; + const float p8_x = x + w - r; + const float p8_y = y; + const float p10_x = x + w - border_w; + const float p10_y = y + r - offset; + const float p11_x = x + w; + const float p11_y = y + r; + const float p12_x = x + w - border_w; + const float p12_y = y + r; + + const float p13_x = x + w - border_w; + const float p13_y = y + h - r; + const float p14_x = x + w; + const float p14_y = y + h - r; + const float p16_x = x + w - r + offset; + const float p16_y = y + h - border_w; + const float p17_x = x + w - r; + const float p17_y = y + h; + const float p18_x = x + w - r; + const float p18_y = y + h - border_w; + + const float p19_x = x + r; + const float p19_y = y + h - border_w; + const float p20_x = x + r; + const float p20_y = y + h; + const float p21_x = x + r - offset; + const float p21_y = y + h - border_w; + const float p22_x = x + border_w; + const float p22_y = y + h - r + offset; + const float p23_x = x; + const float p23_y = y + h - r; + const float p24_x = x + border_w; + const float p24_y = y + h - r; + + if(dsc->side & LV_BORDER_SIDE_BOTTOM) { + lv_vg_lite_path_move_to(path, p21_x, p21_y); + lv_vg_lite_path_line_to(path, p16_x, p16_y); + lv_vg_lite_path_append_arc(path, c3_x, c3_y, r, sweep_beta, sweep_alpha, false); + lv_vg_lite_path_line_to(path, p20_x, p20_y); + lv_vg_lite_path_append_arc(path, c4_x, c4_y, r, 90, sweep_alpha, false); + lv_vg_lite_path_close(path); + } + + if(dsc->side & LV_BORDER_SIDE_TOP) { + lv_vg_lite_path_move_to(path, p4_x, p4_y); + lv_vg_lite_path_append_arc(path, c1_x, c1_y, r, 270 - sweep_alpha, sweep_alpha, false); + lv_vg_lite_path_line_to(path, p8_x, p8_y); + lv_vg_lite_path_append_arc(path, c2_x, c2_y, r, 270, sweep_alpha, false); + lv_vg_lite_path_close(path); + } + + if(dsc->side & LV_BORDER_SIDE_LEFT) { + lv_vg_lite_path_move_to(path, p3_x, p3_y); + lv_vg_lite_path_line_to(path, p22_x, p22_y); + lv_vg_lite_path_append_arc(path, c4_x, c4_y, r, 90 + sweep_beta, sweep_alpha, false); + lv_vg_lite_path_line_to(path, p2_x, p2_y); + lv_vg_lite_path_append_arc(path, c1_x, c1_y, r, 180, sweep_alpha, false); + lv_vg_lite_path_close(path); + } + + if(dsc->side & LV_BORDER_SIDE_RIGHT) { + lv_vg_lite_path_move_to(path, p10_x, p10_y); + lv_vg_lite_path_append_arc(path, c2_x, c2_y, r, 270 + sweep_beta, sweep_alpha, false); + lv_vg_lite_path_line_to(path, p14_x, p14_y); + lv_vg_lite_path_append_arc(path, c3_x, c3_y, r, 0, sweep_alpha, false); + lv_vg_lite_path_close(path); + } + + /* Draw the rounded corners adjacent to the border */ + + if(HAS_BORDER_SIDE(dsc->side, LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_LEFT)) { + lv_vg_lite_path_move_to(path, p2_x, p2_y); + lv_vg_lite_path_append_arc_right_angle(path, p2_x, p2_y, c1_x, c1_y, p5_x, p5_y); + lv_vg_lite_path_line_to(path, p6_x, p6_y); + lv_vg_lite_path_append_arc_right_angle(path, p6_x, p6_y, c1_x, c1_y, p1_x, p1_y); + lv_vg_lite_path_close(path); + } + + if(HAS_BORDER_SIDE(dsc->side, LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_RIGHT)) { + lv_vg_lite_path_move_to(path, p8_x, p8_y); + lv_vg_lite_path_append_arc_right_angle(path, p8_x, p8_y, c2_x, c2_y, p11_x, p11_y); + lv_vg_lite_path_line_to(path, p12_x, p12_y); + lv_vg_lite_path_append_arc_right_angle(path, p12_x, p12_y, c2_x, c2_y, p7_x, p7_y); + lv_vg_lite_path_close(path); + } + + if(HAS_BORDER_SIDE(dsc->side, LV_BORDER_SIDE_BOTTOM | LV_BORDER_SIDE_LEFT)) { + lv_vg_lite_path_move_to(path, p20_x, p20_y); + lv_vg_lite_path_append_arc_right_angle(path, p20_x, p20_y, c4_x, c4_y, p23_x, p23_y); + lv_vg_lite_path_line_to(path, p24_x, p24_y); + lv_vg_lite_path_append_arc_right_angle(path, p24_x, p24_y, c4_x, c4_y, p19_x, p19_y); + lv_vg_lite_path_close(path); + } + + if(HAS_BORDER_SIDE(dsc->side, LV_BORDER_SIDE_BOTTOM | LV_BORDER_SIDE_RIGHT)) { + lv_vg_lite_path_move_to(path, p14_x, p14_y); + lv_vg_lite_path_append_arc_right_angle(path, p14_x, p14_y, c3_x, c3_y, p17_x, p17_y); + lv_vg_lite_path_line_to(path, p18_x, p18_y); + lv_vg_lite_path_append_arc_right_angle(path, p18_x, p18_y, c3_x, c3_y, p13_x, p13_y); + lv_vg_lite_path_close(path); + } + + LV_PROFILER_DRAW_END; + return VG_LITE_FILL_NON_ZERO; +} + #endif /*LV_USE_DRAW_VG_LITE*/ 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 cad9500f8..543487138 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 @@ -38,7 +38,7 @@ * GLOBAL FUNCTIONS **********************/ -void lv_draw_vg_lite_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_shadow_dsc_t * dsc, +void lv_draw_vg_lite_box_shadow(lv_draw_task_t * t, const lv_draw_box_shadow_dsc_t * dsc, const lv_area_t * coords) { /*Calculate the rectangle which is blurred to get the shadow in `shadow_area`*/ @@ -58,9 +58,9 @@ void lv_draw_vg_lite_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_sh /*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, &t->clip_area)) return; - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; lv_draw_border_dsc_t border_dsc; lv_draw_border_dsc_init(&border_dsc); @@ -76,19 +76,20 @@ void lv_draw_vg_lite_box_shadow(lv_draw_unit_t * draw_unit, const lv_draw_box_sh border_dsc.opa = lv_map(w, 0, half_w, dsc->opa / 4, LV_OPA_0); border_dsc.radius++; lv_area_increase(&draw_area, 1, 1); - lv_draw_vg_lite_border(draw_unit, &border_dsc, &draw_area); - - /* fill center */ - if(dsc->ofs_x || dsc->ofs_y) { - lv_draw_fill_dsc_t fill_dsc; - lv_draw_fill_dsc_init(&fill_dsc); - fill_dsc.radius = dsc->radius; - fill_dsc.opa = dsc->opa; - fill_dsc.color = dsc->color; - lv_draw_vg_lite_fill(draw_unit, &fill_dsc, &core_area); - } + lv_draw_vg_lite_border(t, &border_dsc, &draw_area); } - LV_PROFILER_END; + + /* fill center */ + if(dsc->ofs_x || dsc->ofs_y) { + lv_draw_fill_dsc_t fill_dsc; + lv_draw_fill_dsc_init(&fill_dsc); + fill_dsc.radius = dsc->radius; + fill_dsc.opa = dsc->opa; + fill_dsc.color = dsc->color; + lv_draw_vg_lite_fill(t, &fill_dsc, &core_area); + } + + LV_PROFILER_DRAW_END; } /********************** 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 dbfd63df5..d0fd89aae 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 @@ -44,42 +44,35 @@ /********************** * GLOBAL FUNCTIONS **********************/ - -void lv_draw_vg_lite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_vg_lite_fill(lv_draw_task_t * t, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords) { - lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit; + lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)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, &t->clip_area)) { /*Fully clipped, nothing to do*/ return; } - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; vg_lite_matrix_t matrix = u->global_matrix; 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_set_bounding_box_area(path, &clip_area); lv_vg_lite_path_append_rect(path, coords->x1, coords->y1, lv_area_get_width(coords), lv_area_get_height(coords), dsc->radius); lv_vg_lite_path_end(path); - vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); - - LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); - LV_VG_LITE_ASSERT_PATH(vg_lite_path); - LV_VG_LITE_ASSERT_MATRIX(&matrix); - if(dsc->grad.dir != LV_GRAD_DIR_NONE) { #if LV_USE_VECTOR_GRAPHIC lv_vg_lite_draw_grad_helper( - u, + u->grad_ctx, &u->target_buffer, - vg_lite_path, + lv_vg_lite_path_get_path(path), coords, &dsc->grad, &matrix, @@ -89,22 +82,20 @@ void lv_draw_vg_lite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * 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); - 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_SRC_OVER, - color)); - LV_PROFILER_END_TAG("vg_lite_draw"); + else { + /* normal fill */ + lv_vg_lite_draw( + &u->target_buffer, + lv_vg_lite_path_get_path(path), + VG_LITE_FILL_EVEN_ODD, + &matrix, + VG_LITE_BLEND_SRC_OVER, + lv_vg_lite_color(dsc->color, dsc->opa, true)); } lv_vg_lite_path_drop(u, path); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } /********************** 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 86e43375e..a98aa6e0c 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 @@ -33,6 +33,8 @@ * STATIC PROTOTYPES **********************/ +static inline bool matrix_has_transform(const vg_lite_matrix_t * matrix); + /********************** * STATIC VARIABLES **********************/ @@ -44,11 +46,10 @@ /********************** * GLOBAL FUNCTIONS **********************/ - -void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc, +void lv_draw_vg_lite_img(lv_draw_task_t * t, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords, bool no_cache) { - lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit; + lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)t->draw_unit; /* The coordinates passed in by coords are not transformed, * so the transformed area needs to be calculated once. @@ -65,12 +66,12 @@ 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, &t->clip_area)) { /*Fully clipped, nothing to do*/ return; } - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; vg_lite_buffer_t src_buf; lv_image_decoder_dsc_t decoder_dsc; @@ -78,21 +79,11 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * /* if not support blend normal, premultiply alpha */ bool premultiply = !lv_vg_lite_support_blend_normal(); if(!lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->src, no_cache, premultiply)) { - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return; } - vg_lite_color_t color = 0; - 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_COVER) { - /* normal image opa */ - src_buf.image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; - lv_memset(&color, dsc->opa, sizeof(color)); - } + vg_lite_color_t color = lv_vg_lite_image_recolor(&src_buf, dsc); /* convert the blend mode to vg-lite blend mode, considering the premultiplied alpha */ bool has_pre_mul = lv_draw_buf_has_flag(decoder_dsc.decoded, LV_IMAGE_FLAGS_PREMULTIPLIED); @@ -107,33 +98,27 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * vg_lite_matrix_t matrix = u->global_matrix; lv_vg_lite_matrix_multiply(&matrix, &image_matrix); - LV_VG_LITE_ASSERT_SRC_BUFFER(&src_buf); - LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); - LV_VG_LITE_ASSERT_MATRIX(&matrix); - - 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; + bool has_transform = matrix_has_transform(&matrix); + vg_lite_filter_t filter = has_transform ? VG_LITE_FILTER_BI_LINEAR : VG_LITE_FILTER_POINT; /* If clipping is not required, blit directly */ - 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); - + if(lv_area_is_in(&image_tf_area, &t->clip_area, false) && dsc->clip_radius <= 0) { /* rect is used to crop the pixel-aligned padding area */ - vg_lite_rectangle_t rect; - lv_vg_lite_rect(&rect, &src_area); + vg_lite_rectangle_t rect = { + .x = 0, + .y = 0, + .width = lv_area_get_width(coords), + .height = lv_area_get_height(coords), + }; - LV_PROFILER_BEGIN_TAG("vg_lite_blit_rect"); - LV_VG_LITE_CHECK_ERROR(vg_lite_blit_rect( - &u->target_buffer, - &src_buf, - &rect, - &matrix, - blend, - color, - filter)); - LV_PROFILER_END_TAG("vg_lite_blit_rect"); + lv_vg_lite_blit_rect( + &u->target_buffer, + &src_buf, + &rect, + &matrix, + blend, + color, + filter); } else { lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); @@ -142,13 +127,13 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * * When the image is transformed or rounded, create a path around * the image and follow the image_matrix for coordinate transformation */ - if(!no_transform || dsc->clip_radius) { + if(has_transform || dsc->clip_radius) { /* apply the image transform to the path */ lv_vg_lite_path_set_transform(path, &image_matrix); lv_vg_lite_path_append_rect( path, 0, 0, - lv_area_get_width(coords), lv_area_get_height(coords), + lv_area_get_width(&dsc->image_area), lv_area_get_height(&dsc->image_area), dsc->clip_radius); lv_vg_lite_path_set_transform(path, NULL); } @@ -161,39 +146,48 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * 0); } - lv_vg_lite_path_set_bonding_box_area(path, &clip_area); + lv_vg_lite_path_set_bounding_box_area(path, &clip_area); lv_vg_lite_path_end(path); - vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); - LV_VG_LITE_ASSERT_PATH(vg_lite_path); - vg_lite_matrix_t 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( - &u->target_buffer, - vg_lite_path, - VG_LITE_FILL_EVEN_ODD, - &path_matrix, - &src_buf, - &matrix, - blend, - VG_LITE_PATTERN_COLOR, - 0, - color, - filter)); - LV_PROFILER_END_TAG("vg_lite_draw_pattern"); + lv_vg_lite_draw_pattern( + &u->target_buffer, + lv_vg_lite_path_get_path(path), + VG_LITE_FILL_EVEN_ODD, + &path_matrix, + &src_buf, + &matrix, + blend, + VG_LITE_PATTERN_COLOR, + 0, + color, + filter); lv_vg_lite_path_drop(u, path); } lv_vg_lite_pending_add(u->image_dsc_pending, &decoder_dsc); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } /********************** * STATIC FUNCTIONS **********************/ +static inline bool matrix_has_transform(const vg_lite_matrix_t * matrix) +{ + /** + * When the rotation angle is 0 or 180 degrees, + * it is considered that there is no transformation. + */ + return !((matrix->m[0][0] == 1.0f || 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[1][1] == -1.0f) && + matrix->m[2][0] == 0.0f && + matrix->m[2][1] == 0.0f && + matrix->m[2][2] == 1.0f); +} + #endif /*LV_USE_DRAW_VG_LITE*/ 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 6c4c365d8..afbdd37df 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,25 +7,34 @@ * 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" #if LV_USE_DRAW_VG_LITE +#include "lv_draw_vg_lite.h" +#include "lv_draw_vg_lite_type.h" #include "lv_vg_lite_utils.h" #include "lv_vg_lite_path.h" -#include "lv_draw_vg_lite_type.h" +#include "lv_vg_lite_pending.h" +#include "../../misc/cache/lv_cache_entry_private.h" +#include "../../misc/lv_area_private.h" +#include "../../libs/freetype/lv_freetype_private.h" +#include "../lv_draw_label_private.h" + /********************* * DEFINES *********************/ -#define PATH_QUALITY VG_LITE_HIGH #define PATH_DATA_COORD_FORMAT VG_LITE_S16 + +#if LV_VG_LITE_FLUSH_MAX_COUNT > 0 + #define PATH_FLUSH_COUNT_MAX 0 +#else + /* When using IDLE Flush mode, reduce the number of flushes */ + #define PATH_FLUSH_COUNT_MAX 8 +#endif + #define FT_F26DOT6_SHIFT 6 /** After converting the font reference size, it is also necessary to scale the 26dot6 data @@ -41,14 +50,16 @@ * STATIC PROTOTYPES **********************/ -static void draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc, +static void draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area); -static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_dsc_t * dsc); +static void draw_letter_bitmap(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc); + +static void bitmap_cache_release_cb(void * entry, void * user_data); #if LV_USE_FREETYPE static void freetype_outline_event_cb(lv_event_t * e); - static void draw_letter_outline(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_dsc_t * dsc); + static void draw_letter_outline(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc); #endif /* LV_USE_FREETYPE */ /********************** @@ -63,68 +74,125 @@ static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_d * GLOBAL FUNCTIONS **********************/ -void lv_draw_vg_lite_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc, - const lv_area_t * coords) +void lv_draw_vg_lite_label_init(struct _lv_draw_vg_lite_unit_t * u) { - LV_PROFILER_BEGIN; + LV_ASSERT_NULL(u); #if LV_USE_FREETYPE - static bool is_init = false; - if(!is_init) { - lv_freetype_outline_add_event(freetype_outline_event_cb, LV_EVENT_ALL, draw_unit); - is_init = true; - } + /*Set up the freetype outline event*/ + lv_freetype_outline_add_event(freetype_outline_event_cb, LV_EVENT_ALL, u); #endif /* LV_USE_FREETYPE */ - lv_draw_label_iterate_characters(draw_unit, dsc, coords, draw_letter_cb); - LV_PROFILER_END; + u->bitmap_font_pending = lv_vg_lite_pending_create(sizeof(lv_font_glyph_dsc_t), 8); + lv_vg_lite_pending_set_free_cb(u->bitmap_font_pending, bitmap_cache_release_cb, NULL); +} + +void lv_draw_vg_lite_label_deinit(struct _lv_draw_vg_lite_unit_t * u) +{ + LV_ASSERT_NULL(u); + LV_ASSERT_NULL(u->bitmap_font_pending) + lv_vg_lite_pending_destroy(u->bitmap_font_pending); + u->bitmap_font_pending = NULL; +} + +void lv_draw_vg_lite_letter(lv_draw_task_t * t, const lv_draw_letter_dsc_t * dsc, const lv_area_t * coords) +{ + if(dsc->opa <= LV_OPA_MIN) + return; + + LV_PROFILER_DRAW_BEGIN; + + lv_draw_glyph_dsc_t glyph_dsc; + lv_draw_glyph_dsc_init(&glyph_dsc); + glyph_dsc.opa = dsc->opa; + glyph_dsc.bg_coords = NULL; + glyph_dsc.color = dsc->color; + glyph_dsc.rotation = dsc->rotation; + glyph_dsc.pivot = dsc->pivot; + + lv_draw_unit_draw_letter(t, &glyph_dsc, &(lv_point_t) { + .x = coords->x1, .y = coords->y1 + }, + dsc->font, dsc->unicode, draw_letter_cb); + + if(glyph_dsc._draw_buf) { + lv_draw_buf_destroy(glyph_dsc._draw_buf); + glyph_dsc._draw_buf = NULL; + } + + LV_PROFILER_DRAW_END; +} + +void lv_draw_vg_lite_label(lv_draw_task_t * t, const lv_draw_label_dsc_t * dsc, + const lv_area_t * coords) +{ + LV_PROFILER_DRAW_BEGIN; + lv_draw_label_iterate_characters(t, dsc, coords, draw_letter_cb); + LV_PROFILER_DRAW_END; } /********************** * STATIC FUNCTIONS **********************/ -static void draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc, +static void draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_dsc, lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area) { - lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit; + lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)t->draw_unit; if(glyph_draw_dsc) { switch(glyph_draw_dsc->format) { case LV_FONT_GLYPH_FORMAT_A1: case LV_FONT_GLYPH_FORMAT_A2: + case LV_FONT_GLYPH_FORMAT_A3: case LV_FONT_GLYPH_FORMAT_A4: case LV_FONT_GLYPH_FORMAT_A8: { - draw_letter_bitmap(u, glyph_draw_dsc); + glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); + if(!glyph_draw_dsc->glyph_data) { + return; + } + + draw_letter_bitmap(t, glyph_draw_dsc); } break; #if LV_USE_FREETYPE case LV_FONT_GLYPH_FORMAT_VECTOR: { if(lv_freetype_is_outline_font(glyph_draw_dsc->g->resolved_font)) { - draw_letter_outline(u, glyph_draw_dsc); + if(!glyph_draw_dsc->glyph_data) { + return; + } + + draw_letter_outline(t, glyph_draw_dsc); } } break; #endif /* LV_USE_FREETYPE */ case LV_FONT_GLYPH_FORMAT_IMAGE: { + glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); + if(!glyph_draw_dsc->glyph_data) { + return; + } + lv_draw_image_dsc_t image_dsc; lv_draw_image_dsc_init(&image_dsc); image_dsc.opa = glyph_draw_dsc->opa; image_dsc.src = glyph_draw_dsc->glyph_data; - lv_draw_vg_lite_img(draw_unit, &image_dsc, glyph_draw_dsc->letter_coords, false); + image_dsc.rotation = glyph_draw_dsc->rotation; + lv_draw_vg_lite_img(t, &image_dsc, glyph_draw_dsc->letter_coords, false); } break; #if LV_USE_FONT_PLACEHOLDER case LV_FONT_GLYPH_FORMAT_NONE: { + if(glyph_draw_dsc->bg_coords == NULL) break; /* 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_vg_lite_border(draw_unit, &border_draw_dsc, glyph_draw_dsc->bg_coords); + lv_draw_vg_lite_border(t, &border_draw_dsc, glyph_draw_dsc->bg_coords); } break; #endif /* LV_USE_FONT_PLACEHOLDER */ @@ -135,53 +203,65 @@ static void draw_letter_cb(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * gly } if(fill_draw_dsc && fill_area) { - lv_draw_vg_lite_fill(draw_unit, fill_draw_dsc, fill_area); + lv_draw_vg_lite_fill(t, fill_draw_dsc, fill_area); + } + + /* Flush in time to avoid accumulation of drawing commands */ + u->letter_count++; + if(u->letter_count > PATH_FLUSH_COUNT_MAX) { + lv_vg_lite_flush(u); } } -static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_dsc_t * dsc) +static void draw_letter_bitmap(lv_draw_task_t * t, 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)) { + lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)t->draw_unit; + if(!lv_area_intersect(&clip_area, &t->clip_area, dsc->letter_coords)) { return; } - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; - lv_area_t image_area = *dsc->letter_coords; + const lv_area_t image_area = *dsc->letter_coords; vg_lite_matrix_t matrix = u->global_matrix; - vg_lite_translate(image_area.x1, image_area.y1, &matrix); + + const bool is_rotated = dsc->rotation % 3600 != 0; + + if(!is_rotated) { + vg_lite_translate(image_area.x1, image_area.y1, &matrix); + } + else { + vg_lite_translate(image_area.x1 + dsc->pivot.x, image_area.y1 + (dsc->g->box_h + dsc->g->ofs_y), &matrix); + vg_lite_rotate(dsc->rotation / 10.0f, &matrix); + vg_lite_translate(-dsc->pivot.x, -dsc->g->box_h - dsc->g->ofs_y, &matrix); + } vg_lite_buffer_t src_buf; - lv_draw_buf_t * draw_buf = dsc->glyph_data; + const lv_draw_buf_t * draw_buf = dsc->glyph_data; lv_vg_lite_buffer_from_draw_buf(&src_buf, draw_buf); - vg_lite_color_t color; - color = lv_vg_lite_color(dsc->color, dsc->opa, true); - - LV_VG_LITE_ASSERT_SRC_BUFFER(&src_buf); - LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); + const vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true); /* If clipping is not required, blit directly */ - 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); - + if(lv_area_is_in(&image_area, &t->clip_area, false)) { /* rect is used to crop the pixel-aligned padding area */ - vg_lite_rectangle_t rect; - lv_vg_lite_rect(&rect, &src_area); - LV_PROFILER_BEGIN_TAG("vg_lite_blit_rect"); - LV_VG_LITE_CHECK_ERROR(vg_lite_blit_rect( - &u->target_buffer, - &src_buf, - &rect, - &matrix, - VG_LITE_BLEND_SRC_OVER, - color, - VG_LITE_FILTER_LINEAR)); - LV_PROFILER_END_TAG("vg_lite_blit_rect"); + vg_lite_rectangle_t rect = { + .x = 0, + .y = 0, + .width = lv_area_get_width(&image_area), + .height = lv_area_get_height(&image_area) + }; + + lv_vg_lite_blit_rect( + &u->target_buffer, + &src_buf, + &rect, + &matrix, + VG_LITE_BLEND_SRC_OVER, + color, + VG_LITE_FILTER_LINEAR); } else { lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_S16); @@ -190,114 +270,141 @@ static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_d 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_set_bounding_box_area(path, &clip_area); lv_vg_lite_path_end(path); - vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); - LV_VG_LITE_ASSERT_PATH(vg_lite_path); - vg_lite_matrix_t path_matrix = u->global_matrix; - LV_VG_LITE_ASSERT_MATRIX(&path_matrix); + if(is_rotated) vg_lite_rotate(dsc->rotation / 10.0f, &path_matrix); - LV_PROFILER_BEGIN_TAG("vg_lite_draw_pattern"); - LV_VG_LITE_CHECK_ERROR(vg_lite_draw_pattern( - &u->target_buffer, - vg_lite_path, - VG_LITE_FILL_EVEN_ODD, - &path_matrix, - &src_buf, - &matrix, - VG_LITE_BLEND_SRC_OVER, - VG_LITE_PATTERN_COLOR, - 0, - color, - VG_LITE_FILTER_LINEAR)); - LV_PROFILER_END_TAG("vg_lite_draw_pattern"); + lv_vg_lite_draw_pattern( + &u->target_buffer, + lv_vg_lite_path_get_path(path), + VG_LITE_FILL_EVEN_ODD, + &path_matrix, + &src_buf, + &matrix, + VG_LITE_BLEND_SRC_OVER, + VG_LITE_PATTERN_COLOR, + 0, + color, + VG_LITE_FILTER_LINEAR); lv_vg_lite_path_drop(u, path); } - /* TODO: The temporary buffer of the built-in font is reused. - * You need to wait for the GPU to finish using the buffer before releasing it. - * Later, use the font cache for management to improve efficiency. - */ - lv_vg_lite_finish(u); - LV_PROFILER_END; + /* Check if the data has cache and add it to the pending list */ + if(dsc->g->entry) { + /* Increment the cache reference count */ + lv_cache_entry_acquire_data(dsc->g->entry); + lv_vg_lite_pending_add(u->bitmap_font_pending, dsc->g); + } + else { + /* No caching, wait for GPU finish before releasing the data */ + lv_vg_lite_finish(u); + } + + LV_PROFILER_DRAW_END; +} + +static void bitmap_cache_release_cb(void * entry, void * user_data) +{ + LV_UNUSED(user_data); + lv_font_glyph_dsc_t * g_dsc = entry; + lv_font_glyph_release_draw_data(g_dsc); } #if LV_USE_FREETYPE -static void draw_letter_outline(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_dsc_t * dsc) +static void draw_letter_outline(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc) { + lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)t->draw_unit; /* 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, &t->clip_area, dsc->letter_coords)) { return; } - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; /* vg-lite bounding_box will crop the pixels on the edge, so +1px is needed here */ path_clip_area.x2++; path_clip_area.y2++; 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}; + const 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)); + const float scale = FT_F26DOT6_TO_PATH_SCALE(lv_freetype_outline_get_scale(dsc->g->resolved_font)); + const bool is_rotated = dsc->rotation % 3600 != 0; /* calc convert matrix */ 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 = 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); - - vg_lite_scale(scale, scale, &draw_matrix); - vg_lite_scale(scale, scale, &matrix); - - /* calc inverse matrix */ - vg_lite_matrix_t result; - if(!lv_vg_lite_matrix_inverse(&result, &matrix)) { - LV_LOG_ERROR("no inverse matrix"); - LV_PROFILER_END; - return; + if(!is_rotated) { + vg_lite_translate(pos.x - dsc->g->ofs_x, pos.y + dsc->g->box_h + dsc->g->ofs_y, &matrix); + vg_lite_scale(scale, scale, &matrix); + } + else { + vg_lite_translate(pos.x - dsc->g->ofs_x + dsc->pivot.x, pos.y + dsc->g->box_h + dsc->g->ofs_y, &matrix); + vg_lite_rotate(dsc->rotation / 10.0f, &matrix); + vg_lite_translate(-dsc->pivot.x, 0, &matrix); + vg_lite_scale(scale, scale, &matrix); } - lv_point_precise_t p1 = { path_clip_area.x1, path_clip_area.y1 }; - lv_point_precise_t p1_res = lv_vg_lite_matrix_transform_point(&result, &p1); + if(vg_lite_query_feature(gcFEATURE_BIT_VG_SCISSOR)) { + /* set scissor area */ + lv_vg_lite_set_scissor_area(&t->clip_area); - lv_point_precise_t p2 = { path_clip_area.x2, path_clip_area.y2 }; - lv_point_precise_t p2_res = lv_vg_lite_matrix_transform_point(&result, &p2); + /* no bounding box */ + lv_vg_lite_path_set_bounding_box(outline, + (float)PATH_COORD_MIN, (float)PATH_COORD_MIN, + (float)PATH_COORD_MAX, (float)PATH_COORD_MAX); + } + else { + if(is_rotated) { + LV_LOG_WARN("clip may be incorrect when vg_lite_query_feature(gcFEATURE_BIT_VG_SCISSOR) is false"); + } - /* 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); + /* calc inverse matrix */ + vg_lite_matrix_t result; + if(!lv_vg_lite_matrix_inverse(&result, &matrix)) { + LV_LOG_ERROR("no inverse matrix"); + LV_PROFILER_DRAW_END; + return; + } - vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(outline); + const lv_point_precise_t p1 = { path_clip_area.x1, path_clip_area.y1 }; + const lv_point_precise_t p1_res = lv_vg_lite_matrix_transform_point(&result, &p1); - LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); - LV_VG_LITE_ASSERT_PATH(vg_lite_path); - LV_VG_LITE_ASSERT_MATRIX(&draw_matrix); + const lv_point_precise_t p2 = { path_clip_area.x2, path_clip_area.y2 }; + const lv_point_precise_t p2_res = lv_vg_lite_matrix_transform_point(&result, &p2); - 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, - &draw_matrix, VG_LITE_BLEND_SRC_OVER, lv_vg_lite_color(dsc->color, dsc->opa, true))); - LV_PROFILER_END_TAG("vg_lite_draw"); + /* Since the font uses Cartesian coordinates, the y coordinates need to be reversed */ + if(is_rotated) + lv_vg_lite_path_set_bounding_box(outline, + (float)PATH_COORD_MIN, (float)PATH_COORD_MIN, + (float)PATH_COORD_MAX, (float)PATH_COORD_MAX); + else lv_vg_lite_path_set_bounding_box(outline, p1_res.x, p2_res.y, p2_res.x, p1_res.y); + } - /* Flush in time to avoid accumulation of drawing commands */ - lv_vg_lite_flush(u); + /* matrix for drawing, different from matrix for calculating the bounding box */ + vg_lite_matrix_t draw_matrix = u->global_matrix; + lv_vg_lite_matrix_multiply(&draw_matrix, &matrix); - LV_PROFILER_END; + lv_vg_lite_draw( + &u->target_buffer, + lv_vg_lite_path_get_path(outline), + VG_LITE_FILL_NON_ZERO, + &draw_matrix, + VG_LITE_BLEND_SRC_OVER, + lv_vg_lite_color(dsc->color, dsc->opa, true)); + + LV_PROFILER_DRAW_END; } static void vg_lite_outline_push(const lv_freetype_outline_event_param_t * param) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; lv_vg_lite_path_t * outline = param->outline; LV_ASSERT_NULL(outline); @@ -331,18 +438,17 @@ static void vg_lite_outline_push(const lv_freetype_outline_event_param_t * param LV_ASSERT(false); break; } - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } static void freetype_outline_event_cb(lv_event_t * e) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; lv_event_code_t code = lv_event_get_code(e); lv_freetype_outline_event_param_t * param = lv_event_get_param(e); switch(code) { case LV_EVENT_CREATE: param->outline = lv_vg_lite_path_create(PATH_DATA_COORD_FORMAT); - lv_vg_lite_path_set_quality(param->outline, PATH_QUALITY); break; case LV_EVENT_DELETE: lv_vg_lite_path_destroy(param->outline); @@ -354,7 +460,7 @@ static void freetype_outline_event_cb(lv_event_t * e) LV_LOG_WARN("unknown event code: %d", code); break; } - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } #endif /* LV_USE_FREETYPE */ 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 8f2a17e80..7aa3c6c43 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 @@ -11,8 +11,9 @@ #if LV_USE_DRAW_VG_LITE -#include "lv_vg_lite_utils.h" #include "lv_draw_vg_lite_type.h" +#include "lv_vg_lite_utils.h" +#include "lv_vg_lite_path.h" /********************* * DEFINES @@ -37,19 +38,18 @@ /********************** * GLOBAL FUNCTIONS **********************/ - -void lv_draw_vg_lite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc, +void lv_draw_vg_lite_layer(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc, 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; + lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)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. */ if(layer->draw_buf == NULL) return; - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; /* The GPU output should already be premultiplied RGB */ if(!lv_draw_buf_has_flag(layer->draw_buf, LV_IMAGE_FLAGS_PREMULTIPLIED)) { @@ -58,13 +58,13 @@ void lv_draw_vg_lite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t lv_draw_image_dsc_t new_draw_dsc = *draw_dsc; new_draw_dsc.src = layer->draw_buf; - lv_draw_vg_lite_img(draw_unit, &new_draw_dsc, coords, true); + lv_draw_vg_lite_img(t, &new_draw_dsc, coords, true); /* Wait for the GPU drawing to complete here, * otherwise it may cause the drawing to fail. */ lv_vg_lite_finish(u); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } /********************** 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 e1ba695b7..5964bc13d 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 @@ -42,9 +42,10 @@ /********************** * GLOBAL FUNCTIONS **********************/ - -void lv_draw_vg_lite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc) +void lv_draw_vg_lite_line(lv_draw_task_t * t, const lv_draw_line_dsc_t * dsc) { + lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)t->draw_unit; + float p1_x = dsc->p1.x; float p1_y = dsc->p1.y; float p2_x = dsc->p2.x; @@ -61,13 +62,11 @@ 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, &t->clip_area)) { return; /*Fully clipped, nothing to do*/ } - LV_PROFILER_BEGIN; - - lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit; + LV_PROFILER_DRAW_BEGIN; int32_t dash_width = dsc->dash_width; int32_t dash_gap = dsc->dash_gap; @@ -87,8 +86,7 @@ void lv_draw_vg_lite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * } lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); - lv_vg_lite_path_set_quality(path, VG_LITE_MEDIUM); - lv_vg_lite_path_set_bonding_box_area(path, &rel_clip_area); + lv_vg_lite_path_set_bounding_box_area(path, &rel_clip_area); /* head point */ float head_start_x = p1_x + w2_dx; @@ -182,27 +180,17 @@ void lv_draw_vg_lite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * vg_lite_matrix_t matrix = u->global_matrix; - vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true); - - vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); - - LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); - LV_VG_LITE_ASSERT_PATH(vg_lite_path); - LV_VG_LITE_ASSERT_MATRIX(&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_EVEN_ODD, - &matrix, - VG_LITE_BLEND_SRC_OVER, - color)); - LV_PROFILER_END_TAG("vg_lite_draw"); + lv_vg_lite_draw( + &u->target_buffer, + lv_vg_lite_path_get_path(path), + VG_LITE_FILL_EVEN_ODD, + &matrix, + VG_LITE_BLEND_SRC_OVER, + lv_vg_lite_color(dsc->color, dsc->opa, true)); lv_vg_lite_path_drop(u, path); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } /********************** 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 3d24b2375..0620d981f 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 @@ -41,24 +41,51 @@ /********************** * GLOBAL FUNCTIONS **********************/ - -void lv_draw_vg_lite_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_rect_dsc_t * dsc, +void lv_draw_vg_lite_mask_rect(lv_draw_task_t * t, const lv_draw_mask_rect_dsc_t * dsc, const lv_area_t * coords) { 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, &t->clip_area)) { return; } - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_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_layer_t * target_layer = t->target_layer; + const lv_area_t * buf_area = &target_layer->buf_area; + lv_area_t clear_area; + + lv_draw_buf_t * draw_buf = target_layer->draw_buf; + + /*Clear the top part*/ + lv_area_set(&clear_area, t->clip_area.x1, t->clip_area.y1, t->clip_area.x2, + dsc->area.y1 - 1); + lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1); + lv_draw_buf_clear(draw_buf, &clear_area); + + /*Clear the bottom part*/ + lv_area_set(&clear_area, t->clip_area.x1, dsc->area.y2 + 1, t->clip_area.x2, + t->clip_area.y2); + lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1); + lv_draw_buf_clear(draw_buf, &clear_area); + + /*Clear the left part*/ + lv_area_set(&clear_area, t->clip_area.x1, dsc->area.y1, dsc->area.x1 - 1, dsc->area.y2); + lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1); + lv_draw_buf_clear(draw_buf, &clear_area); + + /*Clear the right part*/ + lv_area_set(&clear_area, dsc->area.x2 + 1, dsc->area.y1, t->clip_area.x2, dsc->area.y2); + lv_area_move(&clear_area, -buf_area->x1, -buf_area->y1); + lv_draw_buf_clear(draw_buf, &clear_area); + lv_draw_sw_mask_radius_param_t param; lv_draw_sw_mask_radius_init(¶m, &dsc->area, dsc->radius, false); @@ -74,7 +101,6 @@ void lv_draw_vg_lite_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_re lv_draw_sw_mask_res_t res = lv_draw_sw_mask_apply(masks, mask_buf, draw_area.x1, y, area_w); if(res == LV_DRAW_SW_MASK_RES_FULL_COVER) continue; - lv_layer_t * target_layer = draw_unit->target_layer; lv_color32_t * c32_buf = lv_draw_layer_go_to_xy(target_layer, draw_area.x1 - target_layer->buf_area.x1, y - target_layer->buf_area.y1); @@ -97,44 +123,39 @@ 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); + lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)t->draw_unit; 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); + lv_vg_lite_path_set_bounding_box_area(path, &t->clip_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, dsc->radius); - lv_vg_lite_path_append_rect(path, dsc->area.x1, dsc->area.y1, w, h, 0); + /* Nesting cropping regions using rounded rectangles and normal rectangles */ + lv_vg_lite_path_append_rect( + path, + dsc->area.x1, dsc->area.y1, + lv_area_get_width(&dsc->area), lv_area_get_height(&dsc->area), + dsc->radius); + lv_vg_lite_path_append_rect( + path, + t->clip_area.x1, t->clip_area.y1, + lv_area_get_width(&t->clip_area), lv_area_get_height(&t->clip_area), + 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_draw( + &u->target_buffer, + lv_vg_lite_path_get_path(path), + VG_LITE_FILL_EVEN_ODD, + &matrix, + VG_LITE_BLEND_DST_IN, + 0); lv_vg_lite_path_drop(u, path); #endif /*LV_USE_VG_LITE_THORVG*/ - LV_PROFILER_END; + LV_PROFILER_DRAW_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 63609130e..75bc0f4d7 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 @@ -40,8 +40,7 @@ /********************** * GLOBAL FUNCTIONS **********************/ - -void lv_draw_vg_lite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc) +void lv_draw_vg_lite_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc) { lv_area_t tri_area; tri_area.x1 = (int32_t)LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); @@ -51,37 +50,31 @@ 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, &t->clip_area); if(!is_common) return; - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; - lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit; + lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)t->draw_unit; lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); - lv_vg_lite_path_set_bonding_box_area(path, &clip_area); + lv_vg_lite_path_set_bounding_box_area(path, &clip_area); lv_vg_lite_path_move_to(path, dsc->p[0].x, dsc->p[0].y); lv_vg_lite_path_line_to(path, dsc->p[1].x, dsc->p[1].y); lv_vg_lite_path_line_to(path, dsc->p[2].x, dsc->p[2].y); lv_vg_lite_path_close(path); lv_vg_lite_path_end(path); - vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); - - LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); - LV_VG_LITE_ASSERT_PATH(vg_lite_path); - vg_lite_matrix_t matrix = u->global_matrix; - LV_VG_LITE_ASSERT_MATRIX(&matrix); - if(dsc->bg_grad.dir != LV_GRAD_DIR_NONE) { + if(dsc->grad.dir != LV_GRAD_DIR_NONE) { #if LV_USE_VECTOR_GRAPHIC lv_vg_lite_draw_grad_helper( - u, + u->grad_ctx, &u->target_buffer, - vg_lite_path, + lv_vg_lite_path_get_path(path), &tri_area, - &dsc->bg_grad, + &dsc->grad, &matrix, VG_LITE_FILL_EVEN_ODD, VG_LITE_BLEND_SRC_OVER); @@ -90,21 +83,18 @@ void lv_draw_vg_lite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle #endif } else { /* normal fill */ - vg_lite_color_t color = lv_vg_lite_color(dsc->bg_color, dsc->bg_opa, true); - 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_SRC_OVER, - color)); - LV_PROFILER_END_TAG("vg_lite_draw"); + lv_vg_lite_draw( + &u->target_buffer, + lv_vg_lite_path_get_path(path), + VG_LITE_FILL_EVEN_ODD, + &matrix, + VG_LITE_BLEND_SRC_OVER, + lv_vg_lite_color(dsc->color, dsc->opa, true)); } lv_vg_lite_path_drop(u, path); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } /********************** 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 d325be51b..99569bea4 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 @@ -35,23 +35,26 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_vg_lite_pending_t; +struct _lv_vg_lite_pending_t; +struct _lv_vg_lite_grad_ctx_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_grad_ctx_t * grad_ctx; lv_cache_t * stroke_cache; + struct _lv_vg_lite_pending_t * bitmap_font_pending; + uint16_t flush_count; + uint16_t letter_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; }; 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 481be5cdb..46870434c 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,8 +7,6 @@ * 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 @@ -19,7 +17,10 @@ #include "lv_vg_lite_utils.h" #include "lv_vg_lite_grad.h" #include "lv_vg_lite_stroke.h" +#include "../lv_image_decoder_private.h" +#include "../lv_draw_vector_private.h" #include +#include /********************* * DEFINES @@ -30,15 +31,15 @@ **********************/ typedef void * path_drop_data_t; -typedef void (*path_drop_func_t)(struct lv_draw_vg_lite_unit_t *, 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_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src); -static vg_lite_path_type_t lv_path_opa_to_path_type(const lv_vector_draw_dsc_t * dsc); +static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src, lv_fpoint_t * offset, + float expand_bound); 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); @@ -54,7 +55,7 @@ static vg_lite_fill_t lv_fill_to_vg(lv_vector_fill_t fill_rule); * GLOBAL FUNCTIONS **********************/ -void lv_draw_vg_lite_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_task_dsc_t * dsc) +void lv_draw_vg_lite_vector(lv_draw_task_t * t, const lv_draw_vector_task_dsc_t * dsc) { if(dsc->task_list == NULL) return; @@ -63,9 +64,11 @@ void lv_draw_vg_lite_vector(lv_draw_unit_t * draw_unit, const lv_draw_vector_tas if(layer->draw_buf == NULL) return; - LV_PROFILER_BEGIN; - lv_vector_for_each_destroy_tasks(dsc->task_list, task_draw_cb, draw_unit); - LV_PROFILER_END; + lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)t->draw_unit; + + LV_PROFILER_DRAW_BEGIN; + lv_vector_for_each_destroy_tasks(dsc->task_list, task_draw_cb, u); + LV_PROFILER_DRAW_END; } /********************** @@ -83,134 +86,34 @@ static vg_lite_color_t lv_color32_to_vg(lv_color32_t color, lv_opa_t opa) return (uint32_t)a << 24 | (uint32_t)color.blue << 16 | (uint32_t)color.green << 8 | color.red; } -static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc) +static void draw_fill(lv_draw_vg_lite_unit_t * u, + lv_vg_lite_path_t * lv_vg_path, + const lv_vector_draw_dsc_t * dsc, + vg_lite_matrix_t * matrix, + const lv_fpoint_t * offset) { - LV_PROFILER_BEGIN; - lv_draw_vg_lite_unit_t * u = ctx; - LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); + LV_PROFILER_DRAW_BEGIN; - /* clear area */ - if(!path) { - /* clear color needs to ignore fill_dsc.opa */ - vg_lite_color_t c = lv_color32_to_vg(dsc->fill_dsc.color, LV_OPA_COVER); - vg_lite_rectangle_t rect; - lv_vg_lite_rect(&rect, &dsc->scissor_area); - LV_PROFILER_BEGIN_TAG("vg_lite_clear"); - LV_VG_LITE_CHECK_ERROR(vg_lite_clear(&u->target_buffer, &rect, c)); - LV_PROFILER_END_TAG("vg_lite_clear"); - LV_PROFILER_END; - return; - } - - /* convert color */ - vg_lite_color_t vg_color = lv_color32_to_vg(dsc->fill_dsc.color, dsc->fill_dsc.opa); - - /* transform matrix */ - vg_lite_matrix_t 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); - - /* 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 */ - 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); - - /* 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; + const vg_lite_color_t vg_color = lv_color32_to_vg(dsc->fill_dsc.color, dsc->fill_dsc.opa); + const vg_lite_blend_t blend = lv_blend_to_vg(dsc->blend_mode); + const vg_lite_fill_t fill = lv_fill_to_vg(dsc->fill_dsc.fill_rule); /* 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); - } + lv_vg_lite_path_end(lv_vg_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 */ - lv_vg_lite_set_scissor_area(&dsc->scissor_area); - } - else { - /* calc inverse matrix */ - 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; - } - - /* Reverse the clip area on the source */ - lv_point_precise_t p1 = { dsc->scissor_area.x1, dsc->scissor_area.y1 }; - lv_point_precise_t p1_res = lv_vg_lite_matrix_transform_point(&result, &p1); - - /* vg-lite bounding_box will crop the pixels on the edge, so +1px is needed here */ - lv_point_precise_t p2 = { dsc->scissor_area.x2 + 1, dsc->scissor_area.y2 + 1 }; - lv_point_precise_t p2_res = lv_vg_lite_matrix_transform_point(&result, &p2); - - lv_vg_lite_path_set_bonding_box(lv_vg_path, p1_res.x, p1_res.y, p2_res.x, p2_res.y); - } - switch(dsc->fill_dsc.style) { case LV_VECTOR_DRAW_STYLE_SOLID: { /* normal draw shape */ - LV_PROFILER_BEGIN_TAG("vg_lite_draw"); - LV_VG_LITE_CHECK_ERROR(vg_lite_draw( - &u->target_buffer, - vg_path, - fill, - &matrix, - blend, - vg_color)); - LV_PROFILER_END_TAG("vg_lite_draw"); + lv_vg_lite_draw( + &u->target_buffer, + vg_path, + fill, + matrix, + blend, + vg_color); } break; case LV_VECTOR_DRAW_STYLE_PATTERN: { @@ -219,76 +122,212 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec lv_image_decoder_dsc_t decoder_dsc; if(lv_vg_lite_buffer_open_image(&image_buffer, &decoder_dsc, dsc->fill_dsc.img_dsc.src, false, true)) { /* Calculate pattern matrix. Should start from path bond box, and also apply fill matrix. */ - lv_matrix_t m = dsc->matrix; - lv_matrix_translate(&m, min_x, min_y); - lv_matrix_multiply(&m, &dsc->fill_dsc.matrix); + vg_lite_matrix_t pattern_matrix = *matrix; - vg_lite_matrix_t pattern_matrix; - lv_vg_lite_matrix(&pattern_matrix, &m); + if(dsc->fill_dsc.fill_units == LV_VECTOR_FILL_UNITS_OBJECT_BOUNDING_BOX) { + /* Convert to object bounding box coordinates */ + vg_lite_translate(offset->x, offset->y, &pattern_matrix); + } - vg_lite_color_t recolor = lv_vg_lite_color(dsc->fill_dsc.img_dsc.recolor, dsc->fill_dsc.img_dsc.recolor_opa, true); + vg_lite_matrix_t fill_matrix; + lv_vg_lite_matrix(&fill_matrix, &dsc->fill_dsc.matrix); + lv_vg_lite_matrix_multiply(&pattern_matrix, &fill_matrix); - LV_VG_LITE_ASSERT_MATRIX(&pattern_matrix); + vg_lite_color_t recolor = lv_vg_lite_image_recolor(&image_buffer, &dsc->fill_dsc.img_dsc); - LV_PROFILER_BEGIN_TAG("vg_lite_draw_pattern"); - LV_VG_LITE_CHECK_ERROR(vg_lite_draw_pattern( - &u->target_buffer, - vg_path, - fill, - &matrix, - &image_buffer, - &pattern_matrix, - blend, - VG_LITE_PATTERN_COLOR, - vg_color, - recolor, - VG_LITE_FILTER_BI_LINEAR)); - LV_PROFILER_END_TAG("vg_lite_draw_pattern"); + lv_vg_lite_draw_pattern( + &u->target_buffer, + vg_path, + fill, + matrix, + &image_buffer, + &pattern_matrix, + blend, + VG_LITE_PATTERN_COLOR, + 0, + recolor, + VG_LITE_FILTER_BI_LINEAR); lv_vg_lite_pending_add(u->image_dsc_pending, &decoder_dsc); } } break; case LV_VECTOR_DRAW_STYLE_GRADIENT: { - vg_lite_matrix_t grad_matrix; - vg_lite_identity(&grad_matrix); + vg_lite_matrix_t grad_matrix = *matrix; -#if !LV_USE_VG_LITE_THORVG - /* Workaround inconsistent matrix behavior between device and ThorVG */ - lv_vg_lite_matrix_multiply(&grad_matrix, &matrix); +#if LV_USE_VG_LITE_THORVG + /* Workaround inconsistent radial gradient matrix behavior between device and ThorVG */ + if(dsc->fill_dsc.gradient.style == LV_VECTOR_GRADIENT_STYLE_RADIAL) { + /* Restore matrix to identity */ + vg_lite_identity(&grad_matrix); + } #endif + vg_lite_matrix_t fill_matrix; lv_vg_lite_matrix(&fill_matrix, &dsc->fill_dsc.matrix); lv_vg_lite_matrix_multiply(&grad_matrix, &fill_matrix); lv_vg_lite_draw_grad( - u, + u->grad_ctx, &u->target_buffer, vg_path, &dsc->fill_dsc.gradient, &grad_matrix, - &matrix, + matrix, fill, blend); } break; default: - LV_LOG_WARN("unknown style: %d", dsc->fill_dsc.style); + LV_LOG_WARN("unsupported style: %d", dsc->fill_dsc.style); break; } + LV_PROFILER_DRAW_END; +} + +static void draw_stroke(lv_draw_vg_lite_unit_t * u, + const lv_vector_path_t * path, + lv_vg_lite_path_t * lv_vg_path, + const lv_vector_draw_dsc_t * dsc, + vg_lite_matrix_t * matrix) +{ + LV_PROFILER_DRAW_BEGIN; + + vg_lite_path_t * vg_path = lv_vg_lite_path_get_path(lv_vg_path); + + LV_UNUSED(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"); + LV_PROFILER_DRAW_END; + return; + } + + vg_lite_path_t * vg_stroke_path = lv_vg_lite_path_get_path(lv_vg_lite_stroke_get_path(stroke_cache_entey)); + + /* set stroke params */ + vg_stroke_path->quality = vg_path->quality; + vg_stroke_path->stroke_color = lv_color32_to_vg(dsc->stroke_dsc.color, dsc->stroke_dsc.opa); + const vg_lite_color_t vg_color = 0; + + /* set stroke path bounding box */ + lv_memcpy(vg_stroke_path->bounding_box, vg_path->bounding_box, sizeof(vg_path->bounding_box)); + LV_VG_LITE_ASSERT_PATH(vg_stroke_path); + + const vg_lite_blend_t blend = lv_blend_to_vg(dsc->blend_mode); + + switch(dsc->stroke_dsc.style) { + case LV_VECTOR_DRAW_STYLE_SOLID: { + /* normal draw shape */ + lv_vg_lite_draw( + &u->target_buffer, + vg_stroke_path, + VG_LITE_FILL_NON_ZERO, + matrix, + blend, + vg_color); + } + break; + default: + LV_LOG_WARN("unsupported style: %d", dsc->stroke_dsc.style); + break; + } + + lv_vg_lite_stroke_drop(u, stroke_cache_entey); + LV_PROFILER_DRAW_END; +} + +static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc) +{ + LV_PROFILER_DRAW_BEGIN; + lv_draw_vg_lite_unit_t * u = ctx; + LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); + + vg_lite_matrix_t matrix = u->global_matrix; + + const lv_area_t scissor_area = lv_matrix_is_identity((lv_matrix_t *)&matrix) + ? dsc->scissor_area + : lv_matrix_transform_area((lv_matrix_t *)&matrix, &dsc->scissor_area); + + /* clear area */ + if(!path) { + /* clear color needs to ignore fill_dsc.opa */ + vg_lite_color_t c = lv_color32_to_vg(dsc->fill_dsc.color, dsc->fill_dsc.opa); + vg_lite_rectangle_t rect; + lv_vg_lite_rect(&rect, &scissor_area); + LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_clear"); + LV_VG_LITE_CHECK_ERROR(vg_lite_clear(&u->target_buffer, &rect, c), { + lv_vg_lite_buffer_dump_info(&u->target_buffer); + LV_LOG_ERROR("rect: X%d Y%d W%d H%d", rect.x, rect.y, rect.width, rect.height); + lv_vg_lite_color_dump_info(c); + }); + LV_PROFILER_DRAW_END_TAG("vg_lite_clear"); + LV_PROFILER_DRAW_END; + return; + } + + if(dsc->fill_dsc.opa == LV_OPA_TRANSP && dsc->stroke_dsc.opa == LV_OPA_TRANSP) { + LV_LOG_TRACE("Full transparent, no need to draw"); + LV_PROFILER_DRAW_END; + return; + } + + /* transform matrix */ + vg_lite_matrix_t dsc_matrix; + lv_vg_lite_matrix(&dsc_matrix, &dsc->matrix); + lv_vg_lite_matrix_multiply(&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_fpoint_t offset = {0, 0}; + lv_path_to_vg(lv_vg_path, path, &offset, dsc->stroke_dsc.opa ? dsc->stroke_dsc.width : 0); + + if(vg_lite_query_feature(gcFEATURE_BIT_VG_SCISSOR)) { + /* set scissor area */ + lv_vg_lite_set_scissor_area(&scissor_area); + LV_LOG_TRACE("Set scissor area: X1:%" LV_PRId32 ", Y1:%" LV_PRId32 ", X2:%" LV_PRId32 ", Y2:%" LV_PRId32, + scissor_area.x1, scissor_area.y1, scissor_area.x2, scissor_area.y2); + } + else { + /* calc inverse matrix */ + vg_lite_matrix_t result; + if(!lv_vg_lite_matrix_inverse(&result, &matrix)) { + LV_LOG_ERROR("no inverse matrix"); + lv_vg_lite_matrix_dump_info(&matrix); + lv_vg_lite_path_drop(u, lv_vg_path); + LV_PROFILER_DRAW_END; + return; + } + + /* Reverse the clip area on the source */ + lv_point_precise_t p1 = { scissor_area.x1, scissor_area.y1 }; + lv_point_precise_t p1_res = lv_vg_lite_matrix_transform_point(&result, &p1); + + /* vg-lite bounding_box will crop the pixels on the edge, so +1px is needed here */ + lv_point_precise_t p2 = { scissor_area.x2 + 1, scissor_area.y2 + 1 }; + lv_point_precise_t p2_res = lv_vg_lite_matrix_transform_point(&result, &p2); + + lv_vg_lite_path_set_bounding_box(lv_vg_path, p1_res.x, p1_res.y, p2_res.x, p2_res.y); + } + + if(dsc->fill_dsc.opa) { + draw_fill(u, lv_vg_path, dsc, &matrix, &offset); + } + + if(dsc->stroke_dsc.opa) { + draw_stroke(u, path, lv_vg_path, dsc, &matrix); + } + + /* drop path */ + lv_vg_lite_path_drop(u, lv_vg_path); + /* Flush in time to avoid accumulation of drawing commands */ lv_vg_lite_flush(u); - /* drop path */ - path_drop_func(u, path_drop_data); - - if(vg_lite_query_feature(gcFEATURE_BIT_VG_SCISSOR)) { - /* disable scissor */ - lv_vg_lite_disable_scissor(); - } - - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } static vg_lite_quality_t lv_quality_to_vg(lv_vector_path_quality_t quality) @@ -305,12 +344,12 @@ static vg_lite_quality_t lv_quality_to_vg(lv_vector_path_quality_t quality) } } -static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src) +static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src, lv_fpoint_t * offset, + float expand_bound) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; 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; @@ -324,74 +363,72 @@ static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src if((point)->y > max_y) max_y = (point)->y; \ } while(0) - uint32_t pidx = 0; - lv_vector_path_op_t * op = lv_array_front(&src->ops); - uint32_t size = lv_array_size(&src->ops); - for(uint32_t i = 0; i < size; i++) { - switch(op[i]) { +#define COPY_POINT_NEXT() \ + do { \ + CMP_BOUNDS(point); \ + *path_data++ = point->x; \ + *path_data++ = point->y; \ + point++; \ + } while(0) + + const lv_vector_path_op_t * ops = lv_array_front(&src->ops); + const lv_fpoint_t * point = lv_array_front(&src->points); + const uint32_t op_size = lv_array_size(&src->ops); + const uint32_t point_size = lv_array_size(&src->points); + const uint32_t path_length = (op_size + point_size * 2) * sizeof(float); + + /* Reserved memory for path data */ + lv_vg_lite_path_reserve_space(dest, path_length); + vg_lite_path_t * vg_path = lv_vg_lite_path_get_path(dest); + vg_path->path_length = path_length; + float * path_data = vg_path->path; + + for(uint32_t i = 0; i < op_size; i++) { + switch(ops[i]) { case LV_VECTOR_PATH_OP_MOVE_TO: { - const lv_fpoint_t * pt = lv_array_at(&src->points, pidx); - CMP_BOUNDS(pt); - lv_vg_lite_path_move_to(dest, pt->x, pt->y); - pidx += 1; + LV_VG_LITE_PATH_SET_OP_CODE(path_data++, uint32_t, VLC_OP_MOVE); + COPY_POINT_NEXT(); } break; case LV_VECTOR_PATH_OP_LINE_TO: { - const lv_fpoint_t * pt = lv_array_at(&src->points, pidx); - CMP_BOUNDS(pt); - lv_vg_lite_path_line_to(dest, pt->x, pt->y); - pidx += 1; + LV_VG_LITE_PATH_SET_OP_CODE(path_data++, uint32_t, VLC_OP_LINE); + COPY_POINT_NEXT(); } break; case LV_VECTOR_PATH_OP_QUAD_TO: { - const lv_fpoint_t * pt1 = lv_array_at(&src->points, pidx); - const lv_fpoint_t * pt2 = lv_array_at(&src->points, pidx + 1); - CMP_BOUNDS(pt1); - CMP_BOUNDS(pt2); - lv_vg_lite_path_quad_to(dest, pt1->x, pt1->y, pt2->x, pt2->y); - pidx += 2; + LV_VG_LITE_PATH_SET_OP_CODE(path_data++, uint32_t, VLC_OP_QUAD); + COPY_POINT_NEXT(); + COPY_POINT_NEXT(); } break; case LV_VECTOR_PATH_OP_CUBIC_TO: { - const lv_fpoint_t * pt1 = lv_array_at(&src->points, pidx); - const lv_fpoint_t * pt2 = lv_array_at(&src->points, pidx + 1); - const lv_fpoint_t * pt3 = lv_array_at(&src->points, pidx + 2); - CMP_BOUNDS(pt1); - CMP_BOUNDS(pt2); - CMP_BOUNDS(pt3); - lv_vg_lite_path_cubic_to(dest, pt1->x, pt1->y, pt2->x, pt2->y, pt3->x, pt3->y); - pidx += 3; + LV_VG_LITE_PATH_SET_OP_CODE(path_data++, uint32_t, VLC_OP_CUBIC); + COPY_POINT_NEXT(); + COPY_POINT_NEXT(); + COPY_POINT_NEXT(); } break; case LV_VECTOR_PATH_OP_CLOSE: { - lv_vg_lite_path_close(dest); + LV_VG_LITE_PATH_SET_OP_CODE(path_data++, uint32_t, VLC_OP_CLOSE); } break; + default: + LV_LOG_WARN("unknown op: %d", ops[i]); + break; } } - lv_vg_lite_path_set_bonding_box(dest, min_x, min_y, max_x, max_y); - LV_PROFILER_END; -} + LV_ASSERT_MSG((lv_uintptr_t)path_data - (lv_uintptr_t)vg_path->path == path_length, "path length overflow"); -static vg_lite_path_type_t lv_path_opa_to_path_type(const lv_vector_draw_dsc_t * dsc) -{ - lv_opa_t fill_opa = dsc->fill_dsc.opa; - lv_opa_t stroke_opa = dsc->stroke_dsc.opa; + lv_vg_lite_path_set_bounding_box(dest, + min_x - expand_bound, + min_y - expand_bound, + max_x + expand_bound + 1, + max_y + expand_bound + 1); - if(fill_opa > LV_OPA_0 && stroke_opa > LV_OPA_0) { - return VG_LITE_DRAW_FILL_STROKE_PATH; - } - - if(fill_opa == LV_OPA_0 && stroke_opa > LV_OPA_0) { - return VG_LITE_DRAW_STROKE_PATH; - } - - if(fill_opa > LV_OPA_0) { - return VG_LITE_DRAW_FILL_PATH; - } - - return VG_LITE_DRAW_ZERO; + offset->x = lroundf(min_x); + offset->y = lroundf(min_y); + LV_PROFILER_DRAW_END; } static vg_lite_blend_t lv_blend_to_vg(lv_vector_blend_t blend) @@ -433,3 +470,4 @@ static vg_lite_fill_t lv_fill_to_vg(lv_vector_fill_t fill_rule) } #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 bb7a784bb..97e8b4f7b 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 @@ -175,7 +175,10 @@ static lv_result_t decoder_open_variable(lv_image_decoder_t * decoder, lv_image_ LV_UNUSED(decoder); /*Unused*/ lv_draw_buf_t src_img_buf; - lv_draw_buf_from_image(&src_img_buf, dsc->src); + lv_result_t res = lv_draw_buf_from_image(&src_img_buf, dsc->src); + if(res != LV_RESULT_OK) { + return res; + } /* Since dsc->header.cf is uniformly set to I8, * the original format is obtained from src for conversion. 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 5158d057d..46d0c0507 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 @@ -33,10 +33,11 @@ **********************/ typedef enum { - GRAD_TYPE_UNKNOWN, + GRAD_TYPE_FREE, GRAD_TYPE_LINEAR, GRAD_TYPE_LINEAR_EXT, GRAD_TYPE_RADIAL, + GRAD_TYPE_UNKNOWN, } grad_type_t; typedef struct { @@ -49,20 +50,41 @@ typedef struct { } vg; } grad_item_t; +typedef grad_item_t * grad_item_ref_t; + +typedef struct _lv_vg_lite_grad_ctx_t { + struct _lv_draw_vg_lite_unit_t * unit; + lv_cache_t * cache; + struct _lv_vg_lite_pending_t * pending; + grad_item_t * item_pool; + uint32_t item_pool_size; + + /** + * Temporary reuse of data to reduce the use of + * large memory allocations on the heap and stack during runtime + */ + grad_item_t local_grad_item; + vg_lite_color_ramp_t local_color_ramp[VLC_MAX_COLOR_RAMP_STOPS]; +} lv_vg_lite_grad_ctx_t; + /********************** * STATIC PROTOTYPES **********************/ -static grad_item_t * grad_get(struct lv_draw_vg_lite_unit_t * u, const lv_vector_gradient_t * grad); +static grad_item_t * grad_get(lv_vg_lite_grad_ctx_t * ctx, 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 bool grad_create_cb(grad_item_ref_t * item_ref, void * user_data); +static void grad_free_cb(grad_item_ref_t * item_ref, void * user_data); +static lv_cache_compare_res_t grad_compare_cb(const grad_item_ref_t * lhs_ref, const grad_item_ref_t * rhs_ref); 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 void lv_vg_lite_linear_gradient_dump_info(const vg_lite_linear_gradient_t * grad); +static void lv_vg_lite_ext_linear_gradient_dump_info(const vg_lite_ext_linear_gradient_t * grad); +static void lv_vg_lite_radial_gradient_dump_info(const vg_lite_radial_gradient_t * grad); + /********************** * STATIC VARIABLES **********************/ @@ -75,9 +97,9 @@ static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t * GLOBAL FUNCTIONS **********************/ -void lv_vg_lite_grad_init(struct lv_draw_vg_lite_unit_t * u, uint32_t cache_cnt) +struct _lv_vg_lite_grad_ctx_t * lv_vg_lite_grad_ctx_create(uint32_t cache_cnt, struct _lv_draw_vg_lite_unit_t * unit) { - LV_ASSERT_NULL(u); + LV_ASSERT_MSG(cache_cnt > 0, "cache_cnt should be greater than 0"); lv_cache_ops_t ops = { .compare_cb = (lv_cache_compare_cb_t)grad_compare_cb, @@ -85,24 +107,41 @@ void lv_vg_lite_grad_init(struct lv_draw_vg_lite_unit_t * u, uint32_t cache_cnt) .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), 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); + lv_vg_lite_grad_ctx_t * ctx = lv_malloc_zeroed(sizeof(lv_vg_lite_grad_ctx_t)); + LV_ASSERT_MALLOC(ctx); + ctx->unit = unit; + + ctx->item_pool = lv_malloc_zeroed(cache_cnt * sizeof(grad_item_t)); + LV_ASSERT_MALLOC(ctx->item_pool); + ctx->item_pool_size = cache_cnt; + + ctx->cache = lv_cache_create(&lv_cache_class_lru_ll_count, sizeof(grad_item_ref_t), cache_cnt, ops); + lv_cache_set_name(ctx->cache, "VG_GRAD"); + ctx->pending = lv_vg_lite_pending_create(sizeof(lv_cache_entry_t *), 4); + lv_vg_lite_pending_set_free_cb(ctx->pending, grad_cache_release_cb, ctx->cache); + + return ctx; } -void lv_vg_lite_grad_deinit(struct lv_draw_vg_lite_unit_t * u) +void lv_vg_lite_grad_ctx_delete(struct _lv_vg_lite_grad_ctx_t * ctx) { - 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; + LV_ASSERT_NULL(ctx); + lv_vg_lite_pending_destroy(ctx->pending); + lv_cache_destroy(ctx->cache, NULL); + lv_free(ctx->item_pool); + + lv_memzero(ctx, sizeof(lv_vg_lite_grad_ctx_t)); + lv_free(ctx); +} + +struct _lv_vg_lite_pending_t * lv_vg_lite_grad_ctx_get_pending(struct _lv_vg_lite_grad_ctx_t * ctx) +{ + LV_ASSERT_NULL(ctx); + return ctx->pending; } bool lv_vg_lite_draw_grad( - struct lv_draw_vg_lite_unit_t * u, + struct _lv_vg_lite_grad_ctx_t * ctx, vg_lite_buffer_t * buffer, vg_lite_path_t * path, const lv_vector_gradient_t * grad, @@ -111,7 +150,7 @@ bool lv_vg_lite_draw_grad( vg_lite_fill_t fill, vg_lite_blend_t blend) { - LV_ASSERT_NULL(u); + LV_ASSERT_NULL(ctx); LV_VG_LITE_ASSERT_DEST_BUFFER(buffer); LV_VG_LITE_ASSERT_PATH(path); LV_ASSERT_NULL(grad); @@ -140,9 +179,7 @@ bool lv_vg_lite_draw_grad( } } - LV_PROFILER_BEGIN_TAG("grad_get"); - grad_item_t * grad_item = grad_get(u, grad); - LV_PROFILER_END_TAG("grad_get"); + grad_item_t * grad_item = grad_get(ctx, grad); if(!grad_item) { LV_LOG_WARN("Failed to get gradient, style: %d", grad->style); return false; @@ -158,17 +195,24 @@ bool lv_vg_lite_draw_grad( 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_PROFILER_DRAW_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"); + blend), + /*Error handler*/ + { + lv_vg_lite_buffer_dump_info(buffer); + lv_vg_lite_path_dump_info(path); + LV_LOG_ERROR("fill_rule: 0x%X", (int)fill); + lv_vg_lite_matrix_dump_info(matrix); + lv_vg_lite_linear_gradient_dump_info(linear_grad); + LV_LOG_ERROR("blend_mode: 0x%X", (int)blend); + }); + LV_PROFILER_DRAW_END_TAG("vg_lite_draw_grad"); } break; case GRAD_TYPE_LINEAR_EXT: { @@ -177,9 +221,7 @@ bool lv_vg_lite_draw_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_PROFILER_DRAW_BEGIN_TAG("vg_lite_draw_linear_grad"); LV_VG_LITE_CHECK_ERROR(vg_lite_draw_linear_grad( buffer, path, @@ -188,31 +230,47 @@ bool lv_vg_lite_draw_grad( linear_grad, 0, blend, - VG_LITE_FILTER_LINEAR)); - LV_PROFILER_END_TAG("vg_lite_draw_linear_grad"); + VG_LITE_FILTER_LINEAR), + /*Error handler*/ + { + lv_vg_lite_buffer_dump_info(buffer); + lv_vg_lite_path_dump_info(path); + LV_LOG_ERROR("fill_rule: 0x%X", (int)fill); + lv_vg_lite_matrix_dump_info(matrix); + lv_vg_lite_ext_linear_gradient_dump_info(linear_grad); + LV_LOG_ERROR("blend_mode: 0x%X", (int)blend); + }); + LV_PROFILER_DRAW_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); + vg_lite_radial_gradient_t * radial_gradient = &grad_item->vg.radial; + vg_lite_matrix_t * grad_mat_p = vg_lite_get_radial_grad_matrix(radial_gradient); 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_PROFILER_DRAW_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, + radial_gradient, 0, blend, - VG_LITE_FILTER_LINEAR)); - LV_PROFILER_END_TAG("vg_lite_draw_radial_grad"); + VG_LITE_FILTER_LINEAR), + /*Error handler*/ + { + lv_vg_lite_buffer_dump_info(buffer); + lv_vg_lite_path_dump_info(path); + LV_LOG_ERROR("fill_rule: 0x%X", (int)fill); + lv_vg_lite_matrix_dump_info(matrix); + lv_vg_lite_radial_gradient_dump_info(radial_gradient); + LV_LOG_ERROR("blend_mode: 0x%X", (int)blend); + }); + LV_PROFILER_DRAW_END_TAG("vg_lite_draw_radial_grad"); } break; @@ -225,7 +283,7 @@ bool lv_vg_lite_draw_grad( } bool lv_vg_lite_draw_grad_helper( - struct lv_draw_vg_lite_unit_t * u, + struct _lv_vg_lite_grad_ctx_t * ctx, vg_lite_buffer_t * buffer, vg_lite_path_t * path, const lv_area_t * area, @@ -234,7 +292,7 @@ bool lv_vg_lite_draw_grad_helper( vg_lite_fill_t fill, vg_lite_blend_t blend) { - LV_ASSERT_NULL(u); + LV_ASSERT_NULL(ctx); LV_VG_LITE_ASSERT_DEST_BUFFER(buffer); LV_VG_LITE_ASSERT_PATH(path); LV_ASSERT_NULL(area); @@ -246,7 +304,7 @@ bool lv_vg_lite_draw_grad_helper( 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); + lv_memcpy(grad.stops, grad_dsc->stops, sizeof(lv_grad_stop_t) * grad_dsc->stops_count); /*convert to spread mode*/ #if LV_USE_DRAW_SW_COMPLEX_GRADIENTS @@ -315,43 +373,68 @@ bool lv_vg_lite_draw_grad_helper( return false; } - return lv_vg_lite_draw_grad(u, buffer, path, &grad, matrix, matrix, fill, blend); + return lv_vg_lite_draw_grad(ctx, buffer, path, &grad, matrix, matrix, fill, blend); } /********************** * STATIC FUNCTIONS **********************/ -static grad_item_t * grad_get(struct lv_draw_vg_lite_unit_t * u, const lv_vector_gradient_t * grad) +static grad_item_t * grad_get(lv_vg_lite_grad_ctx_t * ctx, const lv_vector_gradient_t * grad) { - LV_ASSERT_NULL(u); + LV_PROFILER_DRAW_BEGIN; + LV_ASSERT_NULL(ctx); LV_ASSERT_NULL(grad); - grad_item_t search_key; - lv_memzero(&search_key, sizeof(search_key)); - search_key.type = lv_grad_style_to_type(grad->style); - search_key.lv = *grad; + grad_item_ref_t search_key = &ctx->local_grad_item; + lv_memzero(search_key, sizeof(ctx->local_grad_item)); + 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); + lv_cache_entry_t * cache_node_entry = lv_cache_acquire(ctx->cache, &search_key, ctx); if(cache_node_entry == NULL) { /* check if the cache is full */ - size_t free_size = lv_cache_get_free_size(u->grad_cache, NULL); + size_t free_size = lv_cache_get_free_size(ctx->cache, NULL); if(free_size == 0) { LV_LOG_INFO("grad cache is full, release all pending cache entries"); - lv_vg_lite_finish(u); + lv_vg_lite_finish(ctx->unit); } - cache_node_entry = lv_cache_acquire_or_create(u->grad_cache, &search_key, NULL); + cache_node_entry = lv_cache_acquire_or_create(ctx->cache, &search_key, ctx); if(cache_node_entry == NULL) { LV_LOG_ERROR("grad cache creating failed"); + LV_PROFILER_DRAW_END; return NULL; } } /* Add the new entry to the pending list */ - lv_vg_lite_pending_add(u->grad_pending, &cache_node_entry); + lv_vg_lite_pending_add(ctx->pending, &cache_node_entry); - return lv_cache_entry_get_data(cache_node_entry); + grad_item_ref_t * grad_item_ref = lv_cache_entry_get_data(cache_node_entry); + + LV_PROFILER_DRAW_END; + return *grad_item_ref; +} + +static grad_item_t * grad_item_pool_alloc(lv_vg_lite_grad_ctx_t * ctx, grad_type_t type) +{ + LV_ASSERT_NULL(ctx); + for(uint32_t i = 0; i < ctx->item_pool_size; i++) { + if(ctx->item_pool[i].type == GRAD_TYPE_FREE) { + ctx->item_pool[i].type = type; + return &ctx->item_pool[i]; + } + } + + LV_LOG_WARN("alloc grad item failed, no free slot"); + return NULL; +} + +static void grad_item_pool_free(grad_item_t * item) +{ + LV_ASSERT_NULL(item); + item->type = GRAD_TYPE_FREE; } static void grad_cache_release_cb(void * entry, void * user_data) @@ -361,17 +444,11 @@ static void grad_cache_release_cb(void * entry, void * 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) +static void convert_color_ramp(vg_lite_color_ramp_t * color_ramp, const lv_vector_gradient_t * grad) { + LV_ASSERT_NULL(color_ramp); 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; @@ -381,20 +458,20 @@ static vg_lite_color_ramp_t * grad_create_color_ramp(const lv_vector_gradient_t 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; + LV_PROFILER_DRAW_BEGIN; - 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)); + LV_VG_LITE_CHECK_ERROR( + vg_lite_init_grad(&item->vg.linear), + /* Error handler */ + { + lv_vg_lite_linear_gradient_dump_info(&item->vg.linear); + LV_PROFILER_DRAW_END; return false; - } + }); vg_lite_uint32_t colors[VLC_MAX_GRADIENT_STOPS]; vg_lite_uint32_t stops[VLC_MAX_GRADIENT_STOPS]; @@ -415,31 +492,35 @@ static bool linear_grad_create(grad_item_t * item) colors[i] = lv_vg_lite_color(grad_color, opa, true); } - LV_VG_LITE_CHECK_ERROR(vg_lite_set_grad(&item->vg.linear, item->lv.stops_count, colors, stops)); + LV_VG_LITE_CHECK_ERROR( + vg_lite_set_grad(&item->vg.linear, item->lv.stops_count, colors, stops), + /* Error handler */ + { + lv_vg_lite_linear_gradient_dump_info(&item->vg.linear); + }); - LV_PROFILER_BEGIN_TAG("vg_lite_update_grad"); - LV_VG_LITE_CHECK_ERROR(vg_lite_update_grad(&item->vg.linear)); - LV_PROFILER_END_TAG("vg_lite_update_grad"); + LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_update_grad"); + LV_VG_LITE_CHECK_ERROR( + vg_lite_update_grad(&item->vg.linear), + /* Error handler */ + { + lv_vg_lite_linear_gradient_dump_info(&item->vg.linear); + }); + LV_PROFILER_DRAW_END_TAG("vg_lite_update_grad"); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return true; } -static bool linear_ext_grad_create(grad_item_t * item) +static bool linear_ext_grad_create(grad_item_t * item, vg_lite_color_ramp_t * color_ramp) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_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, @@ -447,50 +528,46 @@ static bool linear_ext_grad_create(grad_item_t * item) .Y1 = item->lv.y2, }; - vg_lite_ext_linear_gradient_t linear_grad; - lv_memzero(&linear_grad, sizeof(linear_grad)); + convert_color_ramp(color_ramp, &item->lv); - LV_PROFILER_BEGIN_TAG("vg_lite_set_linear_grad"); + LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_set_linear_grad"); LV_VG_LITE_CHECK_ERROR( vg_lite_set_linear_grad( - &linear_grad, + &item->vg.linear_ext, 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"); + 1), + /* Error handler */ + { + lv_vg_lite_ext_linear_gradient_dump_info(&item->vg.linear_ext); + }); + LV_PROFILER_DRAW_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_PROFILER_DRAW_BEGIN_TAG("vg_lite_update_linear_grad"); + vg_lite_error_t err = vg_lite_update_linear_grad(&item->vg.linear_ext); + LV_PROFILER_DRAW_END_TAG("vg_lite_update_linear_grad"); + if(err != VG_LITE_SUCCESS) { + LV_LOG_ERROR("vg_lite_update_linear_grad error: %d", (int)err); + lv_vg_lite_error_dump_info(err); + lv_vg_lite_ext_linear_gradient_dump_info(&item->vg.linear_ext); } - lv_free(color_ramp); - - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return err == VG_LITE_SUCCESS; } -static bool radial_grad_create(grad_item_t * item) +static bool radial_grad_create(grad_item_t * item, vg_lite_color_ramp_t * color_ramp) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_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; - } + convert_color_ramp(color_ramp, &item->lv); const vg_lite_radial_gradient_parameter_t grad_param = { .cx = item->lv.cx, @@ -500,33 +577,31 @@ static bool radial_grad_create(grad_item_t * item) .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_PROFILER_DRAW_BEGIN_TAG("vg_lite_set_radial_grad"); LV_VG_LITE_CHECK_ERROR( vg_lite_set_radial_grad( - &radial_grad, + &item->vg.radial, 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"); + 1), + /* Error handler */ + { + lv_vg_lite_radial_gradient_dump_info(&item->vg.radial); + }); + LV_PROFILER_DRAW_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_PROFILER_DRAW_BEGIN_TAG("vg_lite_update_radial_grad"); + vg_lite_error_t err = vg_lite_update_radial_grad(&item->vg.radial); + LV_PROFILER_DRAW_END_TAG("vg_lite_update_radial_grad"); + if(err != VG_LITE_SUCCESS) { + LV_LOG_ERROR("vg_lite_update_radial_grad error: %d", (int)err); + lv_vg_lite_error_dump_info(err); + lv_vg_lite_radial_gradient_dump_info(&item->vg.radial); } - lv_free(color_ramp); - - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return err == VG_LITE_SUCCESS; } @@ -571,52 +646,97 @@ static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t return VG_LITE_GRADIENT_SPREAD_FILL; } -static bool grad_create_cb(grad_item_t * item, void * user_data) +static bool grad_create_cb(grad_item_ref_t * item_ref, void * user_data) { - LV_UNUSED(user_data); - item->type = lv_grad_style_to_type(item->lv.style); - switch(item->type) { + LV_PROFILER_DRAW_BEGIN; + const grad_type_t type = lv_grad_style_to_type((*item_ref)->lv.style); + if(type == GRAD_TYPE_UNKNOWN) { + LV_PROFILER_DRAW_END; + return false; + } + + grad_item_t * item = grad_item_pool_alloc(user_data, type); + if(item == NULL) { + /* Should not happen */ + LV_PROFILER_DRAW_END; + return false; + } + + /* Copy key information */ + item->lv = (*item_ref)->lv; + + bool is_success = false; + + lv_vg_lite_grad_ctx_t * ctx = user_data; + LV_ASSERT_NULL(ctx); + + switch(type) { case GRAD_TYPE_LINEAR: - return linear_grad_create(item); + is_success = linear_grad_create(item); + break; case GRAD_TYPE_LINEAR_EXT: - return linear_ext_grad_create(item); + is_success = linear_ext_grad_create(item, ctx->local_color_ramp); + break; case GRAD_TYPE_RADIAL: - return radial_grad_create(item); + is_success = radial_grad_create(item, ctx->local_color_ramp); + break; + + default: + LV_LOG_ERROR("unknown gradient type: %d", type); + break; + } + + if(is_success) { + *item_ref = item; + } + else { + grad_item_pool_free(item); + } + + LV_PROFILER_DRAW_END; + return is_success; +} + +static void grad_free_cb(grad_item_ref_t * item_ref, void * user_data) +{ + LV_UNUSED(user_data); + LV_PROFILER_DRAW_BEGIN; + grad_item_t * item = *item_ref; + switch(item->type) { + case GRAD_TYPE_LINEAR: + LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_clear_grad"); + LV_VG_LITE_CHECK_ERROR(vg_lite_clear_grad(&item->vg.linear), {}); + LV_PROFILER_DRAW_END_TAG("vg_lite_clear_grad"); + break; + + case GRAD_TYPE_LINEAR_EXT: + LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_clear_linear_grad"); + LV_VG_LITE_CHECK_ERROR(vg_lite_clear_linear_grad(&item->vg.linear_ext), {}); + LV_PROFILER_DRAW_END_TAG("vg_lite_clear_linear_grad"); + break; + + case GRAD_TYPE_RADIAL: + LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_clear_radial_grad"); + LV_VG_LITE_CHECK_ERROR(vg_lite_clear_radial_grad(&item->vg.radial), {}); + LV_PROFILER_DRAW_END_TAG("vg_lite_clear_radial_grad"); + break; default: LV_LOG_ERROR("unknown gradient type: %d", item->type); break; } - return false; + grad_item_pool_free(item); + LV_PROFILER_DRAW_END; } -static void grad_free_cb(grad_item_t * item, void * user_data) +static lv_cache_compare_res_t grad_compare_cb(const grad_item_ref_t * lhs_ref, const grad_item_ref_t * rhs_ref) { - LV_UNUSED(user_data); - switch(item->type) { - case GRAD_TYPE_LINEAR: - LV_VG_LITE_CHECK_ERROR(vg_lite_clear_grad(&item->vg.linear)); - break; + const grad_item_t * lhs = *lhs_ref; + const grad_item_t * rhs = *rhs_ref; - 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) -{ /* compare type first */ if(lhs->type != rhs->type) { return lhs->type > rhs->type ? 1 : -1; @@ -676,7 +796,7 @@ static lv_cache_compare_res_t grad_compare_cb(const grad_item_t * lhs, const gra } int cmp_res = lv_memcmp(lhs->lv.stops, rhs->lv.stops, - sizeof(lv_gradient_stop_t) * lhs->lv.stops_count); + sizeof(lv_grad_stop_t) * lhs->lv.stops_count); if(cmp_res != 0) { return cmp_res > 0 ? 1 : -1; } @@ -684,4 +804,61 @@ static lv_cache_compare_res_t grad_compare_cb(const grad_item_t * lhs, const gra return 0; } + +static void lv_vg_lite_linear_gradient_dump_info(const vg_lite_linear_gradient_t * grad) +{ + LV_LOG_USER("count: %d", (int)grad->count); + + for(vg_lite_uint32_t i = 0; i < grad->count; i++) { + LV_LOG_USER("[%d] color: 0x%08X, stop: 0x%08X", (int)i, grad->colors[i], grad->stops[i]); + } + + lv_vg_lite_matrix_dump_info(&grad->matrix); + lv_vg_lite_buffer_dump_info(&grad->image); +} + +static void lv_vg_lite_color_ramp_dump_info(const vg_lite_color_ramp_t * ramp, const vg_lite_uint32_t length) +{ + for(vg_lite_uint32_t i = 0; i < length; i++) { + LV_LOG_USER("[%d] stop: %f, red: %f, green: %f, blue: %f, alpha: %f", + (int)i, ramp[i].stop, ramp[i].red, ramp[i].green, ramp[i].blue, ramp[i].alpha); + } +} + +static void lv_vg_lite_ext_linear_gradient_dump_info(const vg_lite_ext_linear_gradient_t * grad) +{ + LV_LOG_USER("count: %d", (int)grad->count); + lv_vg_lite_matrix_dump_info(&grad->matrix); + lv_vg_lite_buffer_dump_info(&grad->image); + LV_LOG_USER("linear_grad: X0: %f, Y0: %f, X1: %f, Y1: %f", + grad->linear_grad.X0, grad->linear_grad.Y0, grad->linear_grad.X1, grad->linear_grad.Y1); + + LV_LOG_USER("ramp_length: %d", (int)grad->ramp_length); + lv_vg_lite_color_ramp_dump_info(grad->color_ramp, grad->ramp_length); + + LV_LOG_USER("converted_length: %d", (int)grad->converted_length); + lv_vg_lite_color_ramp_dump_info(grad->converted_ramp, grad->converted_length); + + LV_LOG_USER("pre_multiplied: %d", grad->pre_multiplied); + LV_LOG_USER("spread_mode: %d", (int)grad->spread_mode); +} + +static void lv_vg_lite_radial_gradient_dump_info(const vg_lite_radial_gradient_t * grad) +{ + LV_LOG_USER("count: %d", (int)grad->count); + lv_vg_lite_matrix_dump_info(&grad->matrix); + lv_vg_lite_buffer_dump_info(&grad->image); + LV_LOG_USER("radial_grad: cx: %f, cy: %f, r: %f, fx: %f, fy: %f", + grad->radial_grad.cx, grad->radial_grad.cy, grad->radial_grad.r, grad->radial_grad.fx, grad->radial_grad.fy); + + LV_LOG_USER("ramp_length: %d", (int)grad->ramp_length); + lv_vg_lite_color_ramp_dump_info(grad->color_ramp, grad->ramp_length); + + LV_LOG_USER("converted_length: %d", (int)grad->converted_length); + lv_vg_lite_color_ramp_dump_info(grad->converted_ramp, grad->converted_length); + + LV_LOG_USER("pre_multiplied: %d", grad->pre_multiplied); + LV_LOG_USER("spread_mode: %d", (int)grad->spread_mode); +} + #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 d8b9d1f97..7688bc530 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 @@ -32,12 +32,39 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ -void lv_vg_lite_grad_init(struct lv_draw_vg_lite_unit_t * u, uint32_t cache_cnt); +/** + * @brief Create a gradient context + * @param cache_cnt number of cache entries + * @param unit the draw unit + */ +struct _lv_vg_lite_grad_ctx_t * lv_vg_lite_grad_ctx_create(uint32_t cache_cnt, struct _lv_draw_vg_lite_unit_t * unit); -void lv_vg_lite_grad_deinit(struct lv_draw_vg_lite_unit_t * u); +/** + * @brief Delete a gradient context + * @param ctx the gradient context to delete + */ +void lv_vg_lite_grad_ctx_delete(struct _lv_vg_lite_grad_ctx_t * ctx); +/** + * @brief Get the pending list of gradient items + * @param ctx the gradient context + */ +struct _lv_vg_lite_pending_t * lv_vg_lite_grad_ctx_get_pending(struct _lv_vg_lite_grad_ctx_t * ctx); + +/** + * @brief Draw a gradient + * @param ctx the gradient context + * @param buffer the target buffer + * @param path the path to draw the gradient on + * @param grad the gradient descriptor + * @param grad_matrix the gradient matrix + * @param matrix the matrix to apply to the gradient + * @param fill the fill rule + * @param blend the blend mode + * @return true: success, false: failed + */ bool lv_vg_lite_draw_grad( - struct lv_draw_vg_lite_unit_t * u, + struct _lv_vg_lite_grad_ctx_t * ctx, vg_lite_buffer_t * buffer, vg_lite_path_t * path, const lv_vector_gradient_t * grad, @@ -46,8 +73,20 @@ bool lv_vg_lite_draw_grad( vg_lite_fill_t fill, vg_lite_blend_t blend); +/** + * @brief Draw a gradient helper + * @param ctx the gradient context + * @param buffer the target buffer + * @param path the path to draw the gradient on + * @param area the area to draw the gradient on + * @param grad_dsc the gradient descriptor + * @param matrix the matrix to apply to the gradient + * @param fill the fill rule + * @param blend the blend mode + * @return true: success, false: failed + */ bool lv_vg_lite_draw_grad_helper( - struct lv_draw_vg_lite_unit_t * u, + struct _lv_vg_lite_grad_ctx_t * ctx, vg_lite_buffer_t * buffer, vg_lite_path_t * path, const lv_area_t * area, 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 52b4bb950..25a416bf8 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 @@ -39,20 +39,14 @@ float math_fast_inv_sqrtf(float number) { - int32_t i; - float x2, y; - const float threehalfs = 1.5f; - - x2 = number * 0.5f; - y = number; - i = *(int32_t *)&y; /* evil floating point bit level hacking */ - 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 */ - - return y; + /* From https://en.wikipedia.org/wiki/Fast_inverse_square_root#Avoiding_undefined_behavior */ + union { + float f; + int32_t i; + } conv = { .f = number }; + conv.i = 0x5f3759df - (conv.i >> 1); + conv.f *= 1.5F - (number * 0.5F * conv.f * conv.f); + return conv.f; } /********************** 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 3b4b45d75..e2afc7937 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 @@ -36,6 +36,7 @@ extern "C" { #define MATH_SINF(x) sinf(x) #define MATH_COSF(x) cosf(x) #define MATH_ASINF(x) asinf(x) +#define MATH_ACOSF(x) acosf(x) #define MATH_FABSF(x) fabsf(x) #define MATH_SQRTF(x) sqrtf(x) 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 9a9346b8a..0a06485a0 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 @@ -24,17 +24,22 @@ /* Magic number from https://spencermortensen.com/articles/bezier-circle/ */ #define PATH_ARC_MAGIC 0.55191502449351f +#define PATH_MEM_SIZE_MIN 128 + #define SIGN(x) (math_zero(x) ? 0 : ((x) > 0 ? 1 : -1)) #define VLC_OP_ARG_LEN(OP, LEN) \ case VLC_OP_##OP: \ return (LEN) +#define PATH_CURRENT_PTR(PATH) ((uint8_t*)(PATH)->base.path + (PATH)->base.path_length) +#define PATH_LENGTH_INC(PATH, LENGTH) ((PATH)->base.path_length += (LENGTH)) + /********************** * TYPEDEFS **********************/ -struct lv_vg_lite_path_t { +struct _lv_vg_lite_path_t { vg_lite_path_t base; vg_lite_matrix_t matrix; size_t mem_size; @@ -65,14 +70,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); @@ -82,38 +87,38 @@ void lv_vg_lite_path_deinit(struct lv_draw_vg_lite_unit_t * unit) lv_vg_lite_path_t * lv_vg_lite_path_create(vg_lite_format_t data_format) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; lv_vg_lite_path_t * path = lv_malloc_zeroed(sizeof(lv_vg_lite_path_t)); LV_ASSERT_MALLOC(path); path->format_len = lv_vg_lite_path_format_len(data_format); LV_ASSERT(vg_lite_init_path( &path->base, data_format, - VG_LITE_MEDIUM, + VG_LITE_HIGH, 0, NULL, 0, 0, 0, 0) == VG_LITE_SUCCESS); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return path; } void lv_vg_lite_path_destroy(lv_vg_lite_path_t * path) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; LV_ASSERT_NULL(path); if(path->base.path != NULL) { lv_free(path->base.path); path->base.path = NULL; /* clear remaining path data */ - LV_VG_LITE_CHECK_ERROR(vg_lite_clear_path(&path->base)); + LV_VG_LITE_CHECK_ERROR(vg_lite_clear_path(&path->base), {}); } lv_free(path); - LV_PROFILER_END; + LV_PROFILER_DRAW_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); @@ -123,7 +128,7 @@ lv_vg_lite_path_t * lv_vg_lite_path_get(struct lv_draw_vg_lite_unit_t * unit, vg 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); @@ -137,7 +142,7 @@ void lv_vg_lite_path_reset(lv_vg_lite_path_t * path, vg_lite_format_t data_forma LV_ASSERT_NULL(path); path->base.path_length = 0; path->base.format = data_format; - path->base.quality = VG_LITE_MEDIUM; + path->base.quality = VG_LITE_HIGH; path->base.path_type = VG_LITE_DRAW_ZERO; path->format_len = lv_vg_lite_path_format_len(data_format); path->has_transform = false; @@ -149,9 +154,9 @@ vg_lite_path_t * lv_vg_lite_path_get_path(lv_vg_lite_path_t * path) return &path->base; } -void lv_vg_lite_path_set_bonding_box(lv_vg_lite_path_t * path, - float min_x, float min_y, - float max_x, float max_y) +void lv_vg_lite_path_set_bounding_box(lv_vg_lite_path_t * path, + float min_x, float min_y, + float max_x, float max_y) { LV_ASSERT_NULL(path); path->base.bounding_box[0] = min_x; @@ -160,16 +165,16 @@ void lv_vg_lite_path_set_bonding_box(lv_vg_lite_path_t * path, path->base.bounding_box[3] = max_y; } -void lv_vg_lite_path_set_bonding_box_area(lv_vg_lite_path_t * path, const lv_area_t * area) +void lv_vg_lite_path_set_bounding_box_area(lv_vg_lite_path_t * path, const lv_area_t * area) { LV_ASSERT_NULL(path); LV_ASSERT_NULL(area); - lv_vg_lite_path_set_bonding_box(path, area->x1, area->y1, area->x2 + 1, area->y2 + 1); + lv_vg_lite_path_set_bounding_box(path, area->x1, area->y1, area->x2 + 1, area->y2 + 1); } -void lv_vg_lite_path_get_bonding_box(lv_vg_lite_path_t * path, - float * min_x, float * min_y, - float * max_x, float * max_y) +void lv_vg_lite_path_get_bounding_box(lv_vg_lite_path_t * path, + float * min_x, float * min_y, + float * max_x, float * max_y) { LV_ASSERT_NULL(path); if(min_x) *min_x = path->base.bounding_box[0]; @@ -208,7 +213,7 @@ static void path_bounds_iter_cb(void * user_data, uint8_t op_code, const float * } } -bool lv_vg_lite_path_update_bonding_box(lv_vg_lite_path_t * path) +bool lv_vg_lite_path_update_bounding_box(lv_vg_lite_path_t * path) { LV_ASSERT_NULL(path); @@ -216,7 +221,7 @@ bool lv_vg_lite_path_update_bonding_box(lv_vg_lite_path_t * path) return false; } - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; lv_vg_lite_path_bounds_t bounds; @@ -230,9 +235,9 @@ bool lv_vg_lite_path_update_bonding_box(lv_vg_lite_path_t * path) lv_vg_lite_path_for_each_data(lv_vg_lite_path_get_path(path), path_bounds_iter_cb, &bounds); /* set bounds */ - lv_vg_lite_path_set_bonding_box(path, bounds.min_x, bounds.min_y, bounds.max_x, bounds.max_y); + lv_vg_lite_path_set_bounding_box(path, bounds.min_x, bounds.min_y, bounds.max_x, bounds.max_y); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return true; } @@ -253,32 +258,63 @@ void lv_vg_lite_path_set_quality(lv_vg_lite_path_t * path, vg_lite_quality_t qua path->base.quality = quality; } -static void lv_vg_lite_path_append_data(lv_vg_lite_path_t * path, const void * data, size_t len) +void lv_vg_lite_path_reserve_space(lv_vg_lite_path_t * path, size_t len) +{ + bool need_reallocated = false; + + /*Calculate new mem size until match the contidion*/ + while(path->base.path_length + len > path->mem_size) { + if(path->mem_size == 0) { + path->mem_size = LV_MAX(len, PATH_MEM_SIZE_MIN); + } + else { + /* Increase memory size by 1.5 times */ + path->mem_size = path->mem_size * 3 / 2; + } + need_reallocated = true; + } + + if(!need_reallocated) { + return; + } + + path->base.path = lv_realloc(path->base.path, path->mem_size); + LV_ASSERT_MALLOC(path->base.path); +} + +static inline void lv_vg_lite_path_append_data(lv_vg_lite_path_t * path, const void * data, size_t len) { LV_ASSERT_NULL(path); LV_ASSERT_NULL(data); - - if(path->base.path_length + len > path->mem_size) { - if(path->mem_size == 0) { - path->mem_size = len; - } - else { - path->mem_size *= 2; - } - path->base.path = lv_realloc(path->base.path, path->mem_size); - LV_ASSERT_MALLOC(path->base.path); - } - - lv_memcpy((uint8_t *)path->base.path + path->base.path_length, data, len); - path->base.path_length += len; + lv_vg_lite_path_reserve_space(path, len); + lv_memcpy(PATH_CURRENT_PTR(path), data, len); + PATH_LENGTH_INC(path, len); } -static void lv_vg_lite_path_append_op(lv_vg_lite_path_t * path, uint32_t op) +static inline void lv_vg_lite_path_append_op(lv_vg_lite_path_t * path, uint32_t op) { - lv_vg_lite_path_append_data(path, &op, path->format_len); + void * ptr = PATH_CURRENT_PTR(path); + switch(path->base.format) { + case VG_LITE_FP32: + case VG_LITE_S32: + LV_VG_LITE_PATH_SET_OP_CODE(ptr, uint32_t, op); + PATH_LENGTH_INC(path, sizeof(uint32_t)); + break; + case VG_LITE_S16: + LV_VG_LITE_PATH_SET_OP_CODE(ptr, uint16_t, op); + PATH_LENGTH_INC(path, sizeof(uint16_t)); + break; + case VG_LITE_S8: + LV_VG_LITE_PATH_SET_OP_CODE(ptr, uint8_t, op); + PATH_LENGTH_INC(path, sizeof(uint8_t)); + break; + default: + LV_ASSERT_FORMAT_MSG(false, "Invalid format: %d", path->base.format); + break; + } } -static void lv_vg_lite_path_append_point(lv_vg_lite_path_t * path, float x, float y) +static inline void lv_vg_lite_path_append_point(lv_vg_lite_path_t * path, float x, float y) { if(path->has_transform) { LV_VG_LITE_ASSERT_MATRIX(&path->matrix); @@ -289,22 +325,39 @@ static void lv_vg_lite_path_append_point(lv_vg_lite_path_t * path, float x, floa y = ori_x * path->matrix.m[1][0] + ori_y * path->matrix.m[1][1] + path->matrix.m[1][2]; } - if(path->base.format == VG_LITE_FP32) { - lv_vg_lite_path_append_data(path, &x, sizeof(x)); - lv_vg_lite_path_append_data(path, &y, sizeof(y)); - return; - } +#define PATH_APPEND_POINT_DATA(X, Y, TYPE) \ + do { \ + TYPE * data = ptr; \ + *data++ = (TYPE)(X); \ + *data++ = (TYPE)(Y); \ + PATH_LENGTH_INC(path, sizeof(TYPE) * 2); \ + } while(0) - int32_t ix = (int32_t)(x); - int32_t iy = (int32_t)(y); - lv_vg_lite_path_append_data(path, &ix, path->format_len); - lv_vg_lite_path_append_data(path, &iy, path->format_len); + void * ptr = PATH_CURRENT_PTR(path); + switch(path->base.format) { + case VG_LITE_FP32: + PATH_APPEND_POINT_DATA(x, y, float); + break; + case VG_LITE_S32: + PATH_APPEND_POINT_DATA(x, y, int32_t); + break; + case VG_LITE_S16: + PATH_APPEND_POINT_DATA(x, y, int16_t); + break; + case VG_LITE_S8: + PATH_APPEND_POINT_DATA(x, y, int8_t); + break; + default: + LV_ASSERT_FORMAT_MSG(false, "Invalid format: %d", path->base.format); + break; + } } void lv_vg_lite_path_move_to(lv_vg_lite_path_t * path, float x, float y) { LV_ASSERT_NULL(path); + lv_vg_lite_path_reserve_space(path, (1 + 2) * path->format_len); lv_vg_lite_path_append_op(path, VLC_OP_MOVE); lv_vg_lite_path_append_point(path, x, y); } @@ -313,6 +366,7 @@ void lv_vg_lite_path_line_to(lv_vg_lite_path_t * path, float x, float y) { LV_ASSERT_NULL(path); + lv_vg_lite_path_reserve_space(path, (1 + 2) * path->format_len); lv_vg_lite_path_append_op(path, VLC_OP_LINE); lv_vg_lite_path_append_point(path, x, y); } @@ -322,6 +376,7 @@ void lv_vg_lite_path_quad_to(lv_vg_lite_path_t * path, float x, float y) { LV_ASSERT_NULL(path); + lv_vg_lite_path_reserve_space(path, (1 + 4) * path->format_len); lv_vg_lite_path_append_op(path, VLC_OP_QUAD); lv_vg_lite_path_append_point(path, cx, cy); lv_vg_lite_path_append_point(path, x, y); @@ -333,6 +388,7 @@ void lv_vg_lite_path_cubic_to(lv_vg_lite_path_t * path, float x, float y) { LV_ASSERT_NULL(path); + lv_vg_lite_path_reserve_space(path, (1 + 6) * path->format_len); lv_vg_lite_path_append_op(path, VLC_OP_CUBIC); lv_vg_lite_path_append_point(path, cx1, cy1); lv_vg_lite_path_append_point(path, cx2, cy2); @@ -342,12 +398,14 @@ void lv_vg_lite_path_cubic_to(lv_vg_lite_path_t * path, void lv_vg_lite_path_close(lv_vg_lite_path_t * path) { LV_ASSERT_NULL(path); + lv_vg_lite_path_reserve_space(path, 1 * path->format_len); lv_vg_lite_path_append_op(path, VLC_OP_CLOSE); } void lv_vg_lite_path_end(lv_vg_lite_path_t * path) { LV_ASSERT_NULL(path); + lv_vg_lite_path_reserve_space(path, 1 * path->format_len); lv_vg_lite_path_append_op(path, VLC_OP_END); path->base.add_end = 1; } @@ -358,7 +416,7 @@ void lv_vg_lite_path_append_rect( float w, float h, float r) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; const float half_w = w / 2.0f; const float half_h = h / 2.0f; @@ -374,14 +432,14 @@ void lv_vg_lite_path_append_rect( lv_vg_lite_path_line_to(path, x + w, y + h); lv_vg_lite_path_line_to(path, x, y + h); lv_vg_lite_path_close(path); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return; } /*circle*/ 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; + LV_PROFILER_DRAW_END; return; } @@ -418,7 +476,7 @@ void lv_vg_lite_path_append_rect( /* Ending point */ lv_vg_lite_path_close(path); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } void lv_vg_lite_path_append_circle( @@ -426,7 +484,7 @@ void lv_vg_lite_path_append_circle( float cx, float cy, float rx, float ry) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; /* https://learn.microsoft.com/zh-cn/xamarin/xamarin-forms/user-interface/graphics/skiasharp/curves/beziers */ float rx_kappa = rx * PATH_KAPPA; float ry_kappa = ry * PATH_KAPPA; @@ -437,7 +495,7 @@ void lv_vg_lite_path_append_circle( lv_vg_lite_path_cubic_to(path, cx - rx_kappa, cy + ry, cx - rx, cy + ry_kappa, cx - rx, cy); lv_vg_lite_path_cubic_to(path, cx - rx, cy - ry_kappa, cx - rx_kappa, cy - ry, cx, cy - ry); lv_vg_lite_path_close(path); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } void lv_vg_lite_path_append_arc_right_angle(lv_vg_lite_path_t * path, @@ -445,7 +503,7 @@ void lv_vg_lite_path_append_arc_right_angle(lv_vg_lite_path_t * path, float center_x, float center_y, float end_x, float end_y) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; float dx1 = center_x - start_x; float dy1 = center_y - start_y; float dx2 = end_x - center_x; @@ -457,7 +515,7 @@ void lv_vg_lite_path_append_arc_right_angle(lv_vg_lite_path_t * path, start_x - c * dy1, start_y + c * dx1, end_x - c * dy2, end_y + c * dx2, end_x, end_y); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } void lv_vg_lite_path_append_arc(lv_vg_lite_path_t * path, @@ -467,11 +525,11 @@ void lv_vg_lite_path_append_arc(lv_vg_lite_path_t * path, float sweep, bool pie) { - LV_PROFILER_BEGIN; + LV_PROFILER_DRAW_BEGIN; /* just circle */ if(sweep >= 360.0f || sweep <= -360.0f) { lv_vg_lite_path_append_circle(path, cx, cy, radius, radius); - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return; } @@ -530,7 +588,7 @@ void lv_vg_lite_path_append_arc(lv_vg_lite_path_t * path, lv_vg_lite_path_close(path); } - LV_PROFILER_END; + LV_PROFILER_DRAW_END; } uint8_t lv_vg_lite_vlc_op_arg_len(uint8_t vlc_op) @@ -555,31 +613,29 @@ uint8_t lv_vg_lite_vlc_op_arg_len(uint8_t vlc_op) VLC_OP_ARG_LEN(LCWARC, 5); VLC_OP_ARG_LEN(LCWARC_REL, 5); default: + LV_ASSERT_FORMAT_MSG(false, "Invalid op code: %d", vlc_op); break; } - LV_LOG_ERROR("UNKNOW_VLC_OP: 0x%x", vlc_op); - LV_ASSERT(false); return 0; } uint8_t lv_vg_lite_path_format_len(vg_lite_format_t format) { switch(format) { - case VG_LITE_S8: - return 1; - case VG_LITE_S16: - return 2; - case VG_LITE_S32: - return 4; case VG_LITE_FP32: - return 4; + return sizeof(float); + case VG_LITE_S32: + return sizeof(int32_t); + case VG_LITE_S16: + return sizeof(int16_t); + case VG_LITE_S8: + return sizeof(int8_t); default: + LV_ASSERT_FORMAT_MSG(false, "Invalid format: %d", format); break; } - LV_LOG_ERROR("UNKNOW_FORMAT: %d", format); - LV_ASSERT(false); return 0; } @@ -595,7 +651,7 @@ void lv_vg_lite_path_for_each_data(const vg_lite_path_t * path, lv_vg_lite_path_ while(cur < end) { /* get op code */ - uint8_t op_code = VLC_GET_OP_CODE(cur); + uint8_t op_code = LV_VG_LITE_PATH_GET_OP_CODE(cur); /* get arguments length */ uint8_t arg_len = lv_vg_lite_vlc_op_arg_len(op_code); @@ -619,8 +675,7 @@ void lv_vg_lite_path_for_each_data(const vg_lite_path_t * path, lv_vg_lite_path_ tmp_data[i] = *((float *)cur); break; default: - LV_LOG_ERROR("UNKNOW_FORMAT(%d)", path->format); - LV_ASSERT(false); + LV_ASSERT_FORMAT_MSG(false, "Invalid format: %d", path->format); break; } 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 b1ef3f894..a9ffee3dc 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 @@ -17,20 +17,38 @@ extern "C" { #include "lv_vg_lite_utils.h" #if LV_USE_DRAW_VG_LITE +#include /********************* * 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; +#if LV_USE_VG_LITE_THORVG +/** +* It is found that thorvg cannot handle large coordinates well. +* When the coordinates are larger than 4096, the calculation of tvgSwRle module will overflow in 32-bit system. +* So we use FLT_MAX and FLT_MIN to write the mark to bounding_box to tell vg_lite_tvg not to add clip path to the current path. +*/ +#define PATH_COORD_MAX FLT_MAX +#define PATH_COORD_MIN FLT_MIN +#else +/* 18 bits is enough to represent the coordinates of path bounding box */ +#define PATH_COORD_MAX (1 << 18) +#define PATH_COORD_MIN (-PATH_COORD_MAX) +#endif -typedef void (*lv_vg_lite_path_iter_cb_t)(void * user_data, uint8_t op_code, const float * data, uint32_t len); +#define LV_VG_LITE_PATH_SET_OP_CODE(PTR, TYPE, OP_CODE) (*((TYPE*)PTR) = (OP_CODE)) +#define LV_VG_LITE_PATH_GET_OP_CODE(PTR) (*((uint8_t*)PTR)) /********************** * TYPEDEFS **********************/ +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); + /********************** * GLOBAL PROTOTYPES **********************/ @@ -49,17 +67,17 @@ void lv_vg_lite_path_drop(lv_draw_vg_lite_unit_t * unit, lv_vg_lite_path_t * pat void lv_vg_lite_path_reset(lv_vg_lite_path_t * path, vg_lite_format_t data_format); -void lv_vg_lite_path_set_bonding_box_area(lv_vg_lite_path_t * path, const lv_area_t * area); +void lv_vg_lite_path_set_bounding_box_area(lv_vg_lite_path_t * path, const lv_area_t * area); -void lv_vg_lite_path_set_bonding_box(lv_vg_lite_path_t * path, - float min_x, float min_y, - float max_x, float max_y); +void lv_vg_lite_path_set_bounding_box(lv_vg_lite_path_t * path, + float min_x, float min_y, + float max_x, float max_y); -void lv_vg_lite_path_get_bonding_box(lv_vg_lite_path_t * path, - float * min_x, float * min_y, - float * max_x, float * max_y); +void lv_vg_lite_path_get_bounding_box(lv_vg_lite_path_t * path, + float * min_x, float * min_y, + float * max_x, float * max_y); -bool lv_vg_lite_path_update_bonding_box(lv_vg_lite_path_t * path); +bool lv_vg_lite_path_update_bounding_box(lv_vg_lite_path_t * path); void lv_vg_lite_path_set_transform(lv_vg_lite_path_t * path, const vg_lite_matrix_t * matrix); @@ -67,6 +85,8 @@ void lv_vg_lite_path_set_quality(lv_vg_lite_path_t * path, vg_lite_quality_t qua vg_lite_path_t * lv_vg_lite_path_get_path(lv_vg_lite_path_t * path); +void lv_vg_lite_path_reserve_space(lv_vg_lite_path_t * path, size_t len); + void lv_vg_lite_path_move_to(lv_vg_lite_path_t * path, float x, float y); 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 b8429f0f5..141701a21 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,8 +19,10 @@ * TYPEDEFS **********************/ -struct lv_vg_lite_pending_t { - lv_array_t objs; +struct _lv_vg_lite_pending_t { + lv_array_t * arr_act; + lv_array_t arr_1; + lv_array_t arr_2; lv_vg_lite_pending_free_cb_t free_cb; void * user_data; }; @@ -29,6 +31,8 @@ struct lv_vg_lite_pending_t { * STATIC PROTOTYPES **********************/ +static inline void lv_vg_lite_pending_array_clear(lv_vg_lite_pending_t * pending, lv_array_t * arr); + /********************** * STATIC VARIABLES **********************/ @@ -45,7 +49,9 @@ lv_vg_lite_pending_t * lv_vg_lite_pending_create(size_t obj_size, uint32_t capac { lv_vg_lite_pending_t * pending = lv_malloc_zeroed(sizeof(lv_vg_lite_pending_t)); LV_ASSERT_MALLOC(pending); - lv_array_init(&pending->objs, capacity_default, obj_size); + lv_array_init(&pending->arr_1, capacity_default, obj_size); + lv_array_init(&pending->arr_2, capacity_default, obj_size); + pending->arr_act = &pending->arr_1; return pending; } @@ -53,7 +59,8 @@ void lv_vg_lite_pending_destroy(lv_vg_lite_pending_t * pending) { LV_ASSERT_NULL(pending); lv_vg_lite_pending_remove_all(pending); - lv_array_deinit(&pending->objs); + lv_array_deinit(&pending->arr_1); + lv_array_deinit(&pending->arr_2); lv_memzero(pending, sizeof(lv_vg_lite_pending_t)); lv_free(pending); } @@ -71,29 +78,42 @@ void lv_vg_lite_pending_add(lv_vg_lite_pending_t * pending, void * obj) { LV_ASSERT_NULL(pending); LV_ASSERT_NULL(obj); - lv_array_push_back(&pending->objs, obj); + lv_array_push_back(pending->arr_act, obj); } void lv_vg_lite_pending_remove_all(lv_vg_lite_pending_t * pending) { LV_ASSERT_NULL(pending); - LV_ASSERT_NULL(pending->free_cb); - uint32_t size = lv_array_size(&pending->objs); - if(size == 0) { - return; - } + lv_vg_lite_pending_array_clear(pending, &pending->arr_1); + lv_vg_lite_pending_array_clear(pending, &pending->arr_2); +} - /* remove all the pending objects */ - for(uint32_t i = 0; i < size; i++) { - pending->free_cb(lv_array_at(&pending->objs, i), pending->user_data); - } - - lv_array_clear(&pending->objs); +void lv_vg_lite_pending_swap(lv_vg_lite_pending_t * pending) +{ + pending->arr_act = (pending->arr_act == &pending->arr_1) ? &pending->arr_2 : &pending->arr_1; + lv_vg_lite_pending_array_clear(pending, pending->arr_act); } /********************** * STATIC FUNCTIONS **********************/ +static inline void lv_vg_lite_pending_array_clear(lv_vg_lite_pending_t * pending, lv_array_t * arr) +{ + LV_ASSERT_NULL(pending->free_cb); + + uint32_t size = lv_array_size(arr); + if(size == 0) { + return; + } + + /* remove all the pending objects */ + for(uint32_t i = 0; i < size; i++) { + pending->free_cb(lv_array_at(arr, i), pending->user_data); + } + + lv_array_clear(arr); +} + #endif /*LV_USE_DRAW_VG_LITE*/ 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 bf439b74d..22aba1455 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); @@ -65,11 +65,17 @@ void lv_vg_lite_pending_set_free_cb(lv_vg_lite_pending_t * pending, lv_vg_lite_p void lv_vg_lite_pending_add(lv_vg_lite_pending_t * pending, void * obj); /** - * Remove all objects from the pending list + * Remove all objects from the active pending list * @param pending pointer to the pending list */ void lv_vg_lite_pending_remove_all(lv_vg_lite_pending_t * pending); +/** + * Remove all old objects reference and swap new objects reference + * @param pending pointer to the pending list + */ +void lv_vg_lite_pending_swap(lv_vg_lite_pending_t * pending); + /********************** * MACROS **********************/ 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 index 1b8a20248..de0a210a6 100644 --- 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 @@ -24,16 +24,41 @@ * 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; +/** + * Since the key-value data structure of lv_cache is integrated, the kv data structure + * will be saved at the same time when the cache is successfully created. + * In order to pursue efficiency during the matching process, the primary key (lv) used for matching + * will not dup the dash_pattern secondary pointer, so when the creation is successful, dash_pattern needs + * to be dup to the child key (vg), so type is added here to distinguish where the real data of dash_pattern exists. + */ +typedef enum { + DASH_PATTERN_TYPE_LV, + DASH_PATTERN_TYPE_VG +} dash_pattern_type_t; + +typedef struct { + dash_pattern_type_t dash_pattern_type; + + struct { + /* path data */ + 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; + } lv; + + struct { + /* stroke path */ + lv_vg_lite_path_t * path; + + /* dash pattern, for comparison only */ + lv_array_t dash_pattern; + } vg; } stroke_item_t; /********************** @@ -56,7 +81,7 @@ static lv_cache_compare_res_t stroke_compare_cb(const stroke_item_t * lhs, const * GLOBAL FUNCTIONS **********************/ -void lv_vg_lite_stroke_init(struct lv_draw_vg_lite_unit_t * unit, uint32_t cache_cnt) +void lv_vg_lite_stroke_init(struct _lv_draw_vg_lite_unit_t * unit, uint32_t cache_cnt) { LV_ASSERT_NULL(unit); @@ -70,7 +95,7 @@ void lv_vg_lite_stroke_init(struct lv_draw_vg_lite_unit_t * unit, uint32_t cache lv_cache_set_name(unit->stroke_cache, "VG_STROKE"); } -void lv_vg_lite_stroke_deinit(struct lv_draw_vg_lite_unit_t * unit) +void lv_vg_lite_stroke_deinit(struct _lv_draw_vg_lite_unit_t * unit) { LV_ASSERT_NULL(unit); LV_ASSERT_NULL(unit->stroke_cache); @@ -106,8 +131,8 @@ static vg_lite_join_style_t lv_stroke_join_to_vg(lv_vector_stroke_join_t join) } } -lv_cache_entry_t * lv_vg_lite_stroke_get(struct lv_draw_vg_lite_unit_t * unit, - struct lv_vg_lite_path_t * path, +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); @@ -124,21 +149,21 @@ lv_cache_entry_t * lv_vg_lite_stroke_get(struct lv_draw_vg_lite_unit_t * unit, /* 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; + search_key.lv.cap = dsc->cap; + search_key.lv.join = dsc->join; + search_key.lv.width = dsc->width; + search_key.lv.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; + search_key.lv.dash_pattern = dsc->dash_pattern; + search_key.lv.path = path; - lv_cache_entry_t * cache_node_entry = lv_cache_acquire(unit->stroke_cache, &search_key, &search_key); + lv_cache_entry_t * cache_node_entry = lv_cache_acquire(unit->stroke_cache, &search_key, NULL); if(cache_node_entry) { return cache_node_entry; } - cache_node_entry = lv_cache_acquire_or_create(unit->stroke_cache, &search_key, &search_key); + cache_node_entry = lv_cache_acquire_or_create(unit->stroke_cache, &search_key, NULL); if(cache_node_entry == NULL) { LV_LOG_ERROR("stroke cache creating failed"); return NULL; @@ -147,16 +172,22 @@ lv_cache_entry_t * lv_vg_lite_stroke_get(struct lv_draw_vg_lite_unit_t * unit, return cache_node_entry; } -struct lv_vg_lite_path_t * lv_vg_lite_stroke_get_path(lv_cache_entry_t * cache_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; + + if(lv_array_size(&stroke_item->vg.dash_pattern)) { + /* check if dash pattern must be duped */ + LV_ASSERT(stroke_item->dash_pattern_type == DASH_PATTERN_TYPE_VG); + } + + return stroke_item->vg.path; } -void lv_vg_lite_stroke_drop(struct lv_draw_vg_lite_unit_t * unit, +void lv_vg_lite_stroke_drop(struct _lv_draw_vg_lite_unit_t * unit, lv_cache_entry_t * cache_entry) { LV_ASSERT_NULL(unit); @@ -170,47 +201,55 @@ void lv_vg_lite_stroke_drop(struct lv_draw_vg_lite_unit_t * unit, static bool stroke_create_cb(stroke_item_t * item, void * user_data) { + LV_UNUSED(user_data); LV_ASSERT_NULL(item); - stroke_item_t * src = user_data; - LV_ASSERT_NULL(src); + /* Check if stroke width is valid */ + if(item->lv.width <= 0) { + LV_LOG_WARN("stroke width error: %f", item->lv.width); + return false; + } - lv_memzero(item, sizeof(stroke_item_t)); + /* Reset the dash pattern type */ + item->dash_pattern_type = DASH_PATTERN_TYPE_LV; - /* copy path */ - item->path = lv_vg_lite_path_create(VG_LITE_FP32); - lv_vg_lite_path_append_path(item->path, src->path); + /* dup the path */ + item->vg.path = lv_vg_lite_path_create(VG_LITE_FP32); + lv_vg_lite_path_append_path(item->vg.path, item->lv.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); + /* dup the dash pattern */ + vg_lite_float_t * vg_dash_pattern = NULL; + const uint32_t size = lv_array_size(&item->lv.dash_pattern); if(size) { - lv_array_init(&item->dash_pattern, size, sizeof(float)); - lv_array_copy(&item->dash_pattern, &src->dash_pattern); + /* Only support float dash pattern */ + LV_ASSERT(item->lv.dash_pattern.element_size == sizeof(float)); + lv_array_init(&item->vg.dash_pattern, size, sizeof(float)); + lv_array_copy(&item->vg.dash_pattern, &item->lv.dash_pattern); + + /* mark dash pattern has been duped */ + item->dash_pattern_type = DASH_PATTERN_TYPE_VG; + vg_dash_pattern = lv_array_front(&item->vg.dash_pattern); + LV_ASSERT_NULL(vg_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_path_t * vg_path = lv_vg_lite_path_get_path(item->vg.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), + lv_stroke_cap_to_vg(item->lv.cap), + lv_stroke_join_to_vg(item->lv.join), + item->lv.width, + item->lv.miter_limit, + vg_dash_pattern, size, - item->width / 2, + item->lv.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)); + LV_LOG_ERROR("vg_lite_set_stroke error: %d", (int)error); + lv_vg_lite_error_dump_info(error); stroke_free_cb(item, NULL); return false; } @@ -218,16 +257,17 @@ static bool stroke_create_cb(stroke_item_t * item, void * user_data) 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"); + LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_update_stroke"); error = vg_lite_update_stroke(vg_path); - LV_PROFILER_END_TAG("vg_lite_update_stroke"); + LV_PROFILER_DRAW_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)); + LV_LOG_ERROR("vg_lite_update_stroke error: %d", (int)error); + lv_vg_lite_error_dump_info(error); stroke_free_cb(item, NULL); return false; } @@ -240,24 +280,73 @@ 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; + if(item->vg.path) { + lv_vg_lite_path_destroy(item->vg.path); + item->vg.path = NULL; } - int cmp_res = lv_memcmp(lhs->path, rhs->path, lhs->path_length); + if(item->dash_pattern_type == DASH_PATTERN_TYPE_VG) { + lv_array_deinit(&item->vg.dash_pattern); + item->dash_pattern_type = DASH_PATTERN_TYPE_LV; + } +} + +static lv_cache_compare_res_t dash_pattern_compare(const stroke_item_t * lhs, const stroke_item_t * rhs) +{ + /* Select the dash pattern to compare */ + const lv_array_t * lhs_dash_pattern = lhs->dash_pattern_type == DASH_PATTERN_TYPE_LV ? + &lhs->lv.dash_pattern : + &lhs->vg.dash_pattern; + const lv_array_t * rhs_dash_pattern = rhs->dash_pattern_type == DASH_PATTERN_TYPE_LV ? + &rhs->lv.dash_pattern : + &rhs->vg.dash_pattern; + + const uint32_t lhs_dash_pattern_size = lv_array_size(lhs_dash_pattern); + const 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) { + return 0; + } + + /* Both dash pattern has the same size, compare them */ + LV_ASSERT(lhs_dash_pattern->element_size == sizeof(float)); + LV_ASSERT(rhs_dash_pattern->element_size == sizeof(float)); + + /* compare dash pattern data */ + int cmp_res = lv_memcmp( + lv_array_front(lhs_dash_pattern), + lv_array_front(rhs_dash_pattern), + lhs_dash_pattern_size * sizeof(float)); + + if(cmp_res != 0) { + return cmp_res > 0 ? 1 : -1; + } + + return 0; +} + +static lv_cache_compare_res_t path_compare(const stroke_item_t * lhs, const stroke_item_t * rhs) +{ + /* Give priority to using dup vg.path */ + const vg_lite_path_t * lhs_path = lhs->vg.path ? + lv_vg_lite_path_get_path(lhs->vg.path) : + lv_vg_lite_path_get_path(lhs->lv.path); + const vg_lite_path_t * rhs_path = rhs->vg.path ? + lv_vg_lite_path_get_path(rhs->vg.path) : + lv_vg_lite_path_get_path(rhs->lv.path); + + LV_ASSERT(lhs_path->format == VG_LITE_FP32); + LV_ASSERT(rhs_path->format == VG_LITE_FP32); + + if(lhs_path->path_length != rhs_path->path_length) { + return lhs_path->path_length > rhs_path->path_length ? 1 : -1; + } + + int cmp_res = lv_memcmp(lhs_path->path, rhs_path->path, lhs_path->path_length); if(cmp_res != 0) { return cmp_res > 0 ? 1 : -1; } @@ -267,44 +356,28 @@ static lv_cache_compare_res_t path_compare(const vg_lite_path_t * lhs, const vg_ 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->lv.width != rhs->lv.width) { + return lhs->lv.width > rhs->lv.width ? 1 : -1; } - if(lhs->cap != rhs->cap) { - return lhs->cap > rhs->cap ? 1 : -1; + if(lhs->lv.cap != rhs->lv.cap) { + return lhs->lv.cap > rhs->lv.cap ? 1 : -1; } - if(lhs->join != rhs->join) { - return lhs->join > rhs->join ? 1 : -1; + if(lhs->lv.join != rhs->lv.join) { + return lhs->lv.join > rhs->lv.join ? 1 : -1; } - if(lhs->miter_limit != rhs->miter_limit) { - return lhs->miter_limit > rhs->miter_limit ? 1 : -1; + if(lhs->lv.miter_limit != rhs->lv.miter_limit) { + return lhs->lv.miter_limit > rhs->lv.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; + lv_cache_compare_res_t dash_pattern_res = dash_pattern_compare(lhs, rhs); + if(dash_pattern_res != 0) { + return dash_pattern_res; } - 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)); + return path_compare(lhs, rhs); } #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 index 4a0602d62..81c7e510d 100644 --- 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 @@ -26,9 +26,9 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_vg_lite_path_t; +struct _lv_vg_lite_path_t; -struct lv_draw_vg_lite_unit_t; +struct _lv_draw_vg_lite_unit_t; /********************** * GLOBAL PROTOTYPES @@ -38,13 +38,13 @@ struct lv_draw_vg_lite_unit_t; * 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); +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); +void lv_vg_lite_stroke_deinit(struct _lv_draw_vg_lite_unit_t * unit); /** * Get the stroke cache entry @@ -53,8 +53,8 @@ void lv_vg_lite_stroke_deinit(struct lv_draw_vg_lite_unit_t * unit); * @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, +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); /** @@ -62,14 +62,14 @@ lv_cache_entry_t * lv_vg_lite_stroke_get(struct lv_draw_vg_lite_unit_t * unit, * @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); +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); +void lv_vg_lite_stroke_drop(struct _lv_draw_vg_lite_unit_t * unit, lv_cache_entry_t * cache_entry); /********************** * MACROS 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 116cbde3e..56c2da4d1 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 @@ -90,9 +90,54 @@ void lv_vg_lite_dump_info(void) ret ? "YES" : "NO"); } - vg_lite_uint32_t mem_avail = 0; - vg_lite_get_mem_size(&mem_avail); - LV_LOG_USER("Memory Available: %" LV_PRId32 " Bytes", (uint32_t)mem_avail); + vg_lite_uint32_t mem_size = 0; + vg_lite_get_mem_size(&mem_size); + LV_LOG_USER("Memory size: %" LV_PRId32 " Bytes", (uint32_t)mem_size); +} + +void lv_vg_lite_error_dump_info(vg_lite_error_t error) +{ + LV_LOG_USER("Error code: %d(%s)", (int)error, lv_vg_lite_error_string(error)); + switch(error) { + case VG_LITE_SUCCESS: + LV_LOG_USER("No error"); + break; + + case VG_LITE_NOT_ALIGNED: + case VG_LITE_INVALID_ARGUMENT: + break; + + case VG_LITE_OUT_OF_MEMORY: + case VG_LITE_OUT_OF_RESOURCES: { + vg_lite_uint32_t mem_size = 0; + vg_lite_error_t ret = vg_lite_get_mem_size(&mem_size); + if(ret != VG_LITE_SUCCESS) { + LV_LOG_ERROR("vg_lite_get_mem_size error: %d(%s)", + (int)ret, lv_vg_lite_error_string(ret)); + return; + } + + LV_LOG_USER("Memory size: %" LV_PRId32 " Bytes", (uint32_t)mem_size); + } + break; + + case VG_LITE_TIMEOUT: + case VG_LITE_FLEXA_TIME_OUT: { + vg_lite_error_t ret = vg_lite_dump_command_buffer(); + if(ret != VG_LITE_SUCCESS) { + LV_LOG_ERROR("vg_lite_dump_command_buffer error: %d(%s)", + (int)ret, lv_vg_lite_error_string(ret)); + return; + } + + LV_LOG_USER("Command buffer finished"); + } + break; + + default: + lv_vg_lite_dump_info(); + break; + } } const char * lv_vg_lite_error_string(vg_lite_error_t error) @@ -260,12 +305,33 @@ const char * lv_vg_lite_vlc_op_string(uint8_t vlc_op) static void path_data_print_cb(void * user_data, uint8_t op_code, const float * data, uint32_t len) { LV_UNUSED(user_data); + const char * op_str = lv_vg_lite_vlc_op_string(op_code); - LV_LOG("%s, ", lv_vg_lite_vlc_op_string(op_code)); - for(uint32_t i = 0; i < len; i++) { - LV_LOG("%0.2f, ", data[i]); + switch(len) { + case 0: + LV_LOG("%s,\n", op_str); + break; + case 2: + LV_LOG("%s, %f, %f,\n", op_str, data[0], data[1]); + break; + case 4: + LV_LOG("%s, %f, %f, %f, %f,\n", op_str, data[0], data[1], data[2], data[3]); + break; + case 5: + LV_LOG("%s, %f, %f, %f, %f, %f,\n", op_str, data[0], data[1], data[2], data[3], data[4]); + break; + case 6: + LV_LOG("%s, %f, %f, %f, %f, %f, %f,\n", op_str, data[0], data[1], data[2], data[3], data[4], data[5]); + break; + default: { + LV_LOG("%s, ", op_str); + for(uint32_t i = 0; i < len; i++) { + LV_LOG("%f, ", data[i]); + } + LV_LOG("\n"); + } + break; } - LV_LOG("\n"); } void lv_vg_lite_path_dump_info(const vg_lite_path_t * path) @@ -279,7 +345,7 @@ void lv_vg_lite_path_dump_info(const vg_lite_path_t * 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)", + LV_LOG_USER("bounding 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); @@ -395,12 +461,27 @@ void lv_vg_lite_matrix_dump_info(const vg_lite_matrix_t * matrix) } } +void lv_vg_lite_color_dump_info(const vg_lite_color_t color) +{ + LV_LOG_USER("0x%08X (A%d, B%d, G%d, R%d)", + (int)color, + (int)((color >> 24) & 0xFF), + (int)((color >> 16) & 0xFF), + (int)((color >> 8) & 0xFF), + (int)((color >> 0) & 0xFF)); +} + bool lv_vg_lite_is_dest_cf_supported(lv_color_format_t cf) { switch(cf) { + case LV_COLOR_FORMAT_A8: + case LV_COLOR_FORMAT_L8: case LV_COLOR_FORMAT_RGB565: case LV_COLOR_FORMAT_ARGB8888: case LV_COLOR_FORMAT_XRGB8888: + case LV_COLOR_FORMAT_ARGB1555: + case LV_COLOR_FORMAT_ARGB4444: + case LV_COLOR_FORMAT_ARGB2222: return true; case LV_COLOR_FORMAT_ARGB8565: @@ -419,14 +500,20 @@ bool lv_vg_lite_is_src_cf_supported(lv_color_format_t cf) switch(cf) { case LV_COLOR_FORMAT_A4: case LV_COLOR_FORMAT_A8: + case LV_COLOR_FORMAT_L8: case LV_COLOR_FORMAT_RGB565: case LV_COLOR_FORMAT_ARGB8888: case LV_COLOR_FORMAT_XRGB8888: + case LV_COLOR_FORMAT_ARGB1555: + case LV_COLOR_FORMAT_ARGB4444: + case LV_COLOR_FORMAT_ARGB2222: return true; case LV_COLOR_FORMAT_I1: case LV_COLOR_FORMAT_I2: case LV_COLOR_FORMAT_I4: + return vg_lite_query_feature(gcFEATURE_BIT_VG_INDEX_ENDIAN) ? true : false; + case LV_COLOR_FORMAT_I8: return vg_lite_query_feature(gcFEATURE_BIT_VG_IM_INDEX_FORMAT) ? true : false; @@ -437,6 +524,9 @@ bool lv_vg_lite_is_src_cf_supported(lv_color_format_t cf) case LV_COLOR_FORMAT_NV12: return vg_lite_query_feature(gcFEATURE_BIT_VG_YUV_INPUT) ? true : false; + case LV_COLOR_FORMAT_YUY2: + return vg_lite_query_feature(gcFEATURE_BIT_VG_YUY2_INPUT) ? true : false; + default: break; } @@ -468,9 +558,21 @@ vg_lite_buffer_format_t lv_vg_lite_vg_fmt(lv_color_format_t cf) case LV_COLOR_FORMAT_I8: return VG_LITE_INDEX_8; + case LV_COLOR_FORMAT_ARGB1555: + return VG_LITE_BGRA5551; + + case LV_COLOR_FORMAT_ARGB4444: + return VG_LITE_BGRA4444; + + case LV_COLOR_FORMAT_ARGB2222: + return VG_LITE_BGRA2222; + case LV_COLOR_FORMAT_RGB565: return VG_LITE_BGR565; + case LV_COLOR_FORMAT_RGB565_SWAPPED: + return VG_LITE_RGB565; + case LV_COLOR_FORMAT_ARGB8565: return VG_LITE_BGRA5658; @@ -479,6 +581,8 @@ vg_lite_buffer_format_t lv_vg_lite_vg_fmt(lv_color_format_t cf) case LV_COLOR_FORMAT_ARGB8888: return VG_LITE_BGRA8888; + case LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED: + return VG_sBGRA_8888_PRE; case LV_COLOR_FORMAT_XRGB8888: return VG_LITE_BGRX8888; @@ -486,6 +590,9 @@ vg_lite_buffer_format_t lv_vg_lite_vg_fmt(lv_color_format_t cf) case LV_COLOR_FORMAT_NV12: return VG_LITE_NV12; + case LV_COLOR_FORMAT_YUY2: + return VG_LITE_YUY2; + default: LV_LOG_ERROR("unsupported color format: %d", cf); break; @@ -538,6 +645,7 @@ void lv_vg_lite_buffer_format_bytes( case VG_LITE_BGRX8888: case VG_LITE_XBGR8888: case VG_LITE_XRGB8888: + case VG_sBGRA_8888_PRE: *mul = 4; break; case VG_LITE_NV12: @@ -713,6 +821,35 @@ void lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix, int32_t x, int32_t y, co } } +vg_lite_color_t lv_vg_lite_image_recolor(vg_lite_buffer_t * buffer, const lv_draw_image_dsc_t * dsc) +{ + LV_ASSERT_NULL(buffer); + LV_ASSERT_NULL(dsc); + + /* alpha image and image recolor */ + if(buffer->format == VG_LITE_A4 || buffer->format == VG_LITE_A8) { + /*Alpha only image ignore recolor opa*/ + buffer->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; + return lv_vg_lite_color(dsc->recolor, dsc->opa, true); + } + else if(dsc->recolor_opa > LV_OPA_TRANSP) { + buffer->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; + /** The 0xff value in a color channel (R/G/B) maintains that channel's maximum intensity, + * effectively preserving its original color contribution when used in blending operations.*/ + lv_color_t recolor = lv_color_mix(dsc->recolor, lv_color_make(0xff, 0xff, 0xff), dsc->recolor_opa); + return lv_vg_lite_color(recolor, dsc->opa, true); + } + else if(dsc->opa < LV_OPA_COVER) { + /* normal image opa */ + buffer->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE; + vg_lite_color_t color; + lv_memset(&color, dsc->opa, sizeof(color)); + return color; + } + + return 0; +} + 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, bool premultiply) { @@ -726,7 +863,10 @@ 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; + + /** For images output by the GPU itself (such as draw layer), + * there is no need to flush the cache */ + args.flush_cache = !no_cache; lv_result_t res = lv_image_decoder_open(decoder_dsc, src, &args); if(res != LV_RESULT_OK) { @@ -749,22 +889,22 @@ bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_ds if(LV_COLOR_FORMAT_IS_INDEXED(decoded->header.cf)) { uint32_t palette_size = LV_COLOR_INDEXED_PALETTE_SIZE(decoded->header.cf); - LV_PROFILER_BEGIN_TAG("vg_lite_set_CLUT"); - LV_VG_LITE_CHECK_ERROR(vg_lite_set_CLUT(palette_size, (vg_lite_uint32_t *)decoded->data)); - LV_PROFILER_END_TAG("vg_lite_set_CLUT"); + LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_set_CLUT"); + LV_VG_LITE_CHECK_ERROR(vg_lite_set_CLUT(palette_size, (vg_lite_uint32_t *)decoded->data), {}); + LV_PROFILER_DRAW_END_TAG("vg_lite_set_CLUT"); } lv_vg_lite_buffer_from_draw_buf(buffer, decoded); 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; @@ -778,11 +918,6 @@ void lv_vg_lite_rect(vg_lite_rectangle_t * rect, const lv_area_t * area) rect->height = lv_area_get_height(area); } -void lv_vg_lite_matrix(vg_lite_matrix_t * dest, const lv_matrix_t * src) -{ - lv_memcpy(dest, src, sizeof(lv_matrix_t)); -} - uint32_t lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format) { uint32_t size = 0; @@ -963,7 +1098,7 @@ bool lv_vg_lite_path_check(const vg_lite_path_t * path) while(cur < end) { /* get op code */ - uint8_t op_code = VLC_GET_OP_CODE(cur); + uint8_t op_code = LV_VG_LITE_PATH_GET_OP_CODE(cur); /* get arguments length */ uint8_t arg_len = lv_vg_lite_vlc_op_arg_len(op_code); @@ -987,7 +1122,7 @@ bool lv_vg_lite_path_check(const vg_lite_path_t * path) 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); + uint8_t end_op_code = LV_VG_LITE_PATH_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; @@ -1044,7 +1179,7 @@ bool lv_vg_lite_16px_align(void) void lv_vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_matrix_t * mult) { - vg_lite_matrix_t temp; + lv_matrix_t temp; int row, column; vg_lite_float_t (*m)[3] = matrix->m; @@ -1059,8 +1194,8 @@ void lv_vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_matrix_ } } - /* Copy temporary matrix into result. */ - lv_memcpy(matrix, &temp, sizeof(temp)); + /* Copy temporary 3x3 matrix into result. */ + *(lv_matrix_t *)matrix = temp; } bool lv_vg_lite_matrix_inverse(vg_lite_matrix_t * result, const vg_lite_matrix_t * matrix) @@ -1129,6 +1264,7 @@ lv_point_precise_t lv_vg_lite_matrix_transform_point(const vg_lite_matrix_t * ma void lv_vg_lite_set_scissor_area(const lv_area_t * area) { + LV_PROFILER_DRAW_BEGIN; #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 @@ -1139,69 +1275,97 @@ void lv_vg_lite_set_scissor_area(const lv_area_t * area) * 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()); + LV_VG_LITE_CHECK_ERROR(vg_lite_enable_scissor(), {}); #endif LV_VG_LITE_CHECK_ERROR(vg_lite_set_scissor( area->x1, area->y1, area->x2 + 1, - area->y2 + 1)); + area->y2 + 1), + /* Error handler */ + { + LV_LOG_ERROR("area: %d, %d, %d, %d", + (int)area->x1, (int)area->y1, (int)area->x2, (int)area->y2); + }); + LV_PROFILER_DRAW_END; } void lv_vg_lite_disable_scissor(void) { + LV_PROFILER_DRAW_BEGIN; /* Restore full screen scissor */ LV_VG_LITE_CHECK_ERROR(vg_lite_set_scissor( 0, 0, LV_HOR_RES, - LV_VER_RES)); + LV_VER_RES), + /* Error handler */ + { + LV_LOG_ERROR("hor_res: %d, ver_res: %d", (int)LV_HOR_RES, (int)LV_VER_RES); + }); + LV_PROFILER_DRAW_END; } -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; + LV_PROFILER_DRAW_BEGIN; u->flush_count++; + u->letter_count = 0; #if LV_VG_LITE_FLUSH_MAX_COUNT if(u->flush_count < LV_VG_LITE_FLUSH_MAX_COUNT) { /* Do not flush too often */ - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return; } #else vg_lite_uint32_t is_gpu_idle = 0; - LV_VG_LITE_CHECK_ERROR(vg_lite_get_parameter(VG_LITE_GPU_IDLE_STATE, 1, (vg_lite_pointer)&is_gpu_idle)); + LV_VG_LITE_CHECK_ERROR(vg_lite_get_parameter(VG_LITE_GPU_IDLE_STATE, 1, (vg_lite_pointer)&is_gpu_idle), {}); if(!is_gpu_idle) { /* Do not flush if GPU is busy */ - LV_PROFILER_END; + LV_PROFILER_DRAW_END; return; } #endif - LV_VG_LITE_CHECK_ERROR(vg_lite_flush()); + LV_VG_LITE_CHECK_ERROR(vg_lite_flush(), {}); + + /* Remove all old caches reference and swap new caches reference */ +#if LV_USE_VECTOR_GRAPHIC + lv_vg_lite_pending_swap(lv_vg_lite_grad_ctx_get_pending(u->grad_ctx)); +#endif + + lv_vg_lite_pending_swap(u->image_dsc_pending); + + lv_vg_lite_pending_swap(u->bitmap_font_pending); + u->flush_count = 0; - LV_PROFILER_END; + LV_PROFILER_DRAW_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; + LV_PROFILER_DRAW_BEGIN; - LV_VG_LITE_CHECK_ERROR(vg_lite_finish()); + LV_VG_LITE_CHECK_ERROR(vg_lite_finish(), {}); +#if LV_USE_VECTOR_GRAPHIC /* Clear all gradient caches reference */ - if(u->grad_pending) { - lv_vg_lite_pending_remove_all(u->grad_pending); - } + lv_vg_lite_pending_remove_all(lv_vg_lite_grad_ctx_get_pending(u->grad_ctx)); +#endif /* Clear image decoder dsc reference */ lv_vg_lite_pending_remove_all(u->image_dsc_pending); + + /* Clear bitmap font dsc reference */ + lv_vg_lite_pending_remove_all(u->bitmap_font_pending); + u->flush_count = 0; - LV_PROFILER_END; + u->letter_count = 0; + LV_PROFILER_DRAW_END; } /********************** 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 becbce893..425050fc5 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 @@ -31,22 +31,19 @@ extern "C" { * DEFINES *********************/ -#define LV_VG_LITE_IS_ERROR(err) (err > 0) - -#define VLC_GET_OP_CODE(ptr) (*((uint8_t*)ptr)) - #if LV_VG_LITE_USE_ASSERT #define LV_VG_LITE_ASSERT(expr) LV_ASSERT(expr) #else #define LV_VG_LITE_ASSERT(expr) #endif -#define LV_VG_LITE_CHECK_ERROR(expr) \ +#define LV_VG_LITE_CHECK_ERROR(expr, error_handler) \ do { \ vg_lite_error_t error = expr; \ - if (LV_VG_LITE_IS_ERROR(error)) { \ - LV_LOG_ERROR("Execute '" #expr "' error(%d): %s", \ - (int)error, lv_vg_lite_error_string(error)); \ + if (error != VG_LITE_SUCCESS) { \ + LV_LOG_ERROR("Execute '" #expr "' error: %d", (int)error); \ + lv_vg_lite_error_dump_info(error); \ + error_handler; \ LV_VG_LITE_ASSERT(false); \ } \ } while (0) @@ -71,7 +68,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_draw_vg_lite_unit_t; +struct _lv_draw_vg_lite_unit_t; /********************** * GLOBAL PROTOTYPES @@ -81,6 +78,8 @@ struct lv_draw_vg_lite_unit_t; void lv_vg_lite_dump_info(void); +void lv_vg_lite_error_dump_info(vg_lite_error_t error); + const char * lv_vg_lite_error_string(vg_lite_error_t error); const char * lv_vg_lite_feature_string(vg_lite_feature_t feature); @@ -97,6 +96,8 @@ 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); +void lv_vg_lite_color_dump_info(const vg_lite_color_t color); + bool lv_vg_lite_is_dest_cf_supported(lv_color_format_t cf); bool lv_vg_lite_is_src_cf_supported(lv_color_format_t cf); @@ -128,14 +129,14 @@ void lv_vg_lite_buffer_from_draw_buf(vg_lite_buffer_t * buffer, const lv_draw_bu void lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix, int32_t x, int32_t y, const lv_draw_image_dsc_t * dsc); -void lv_vg_lite_image_dec_init(vg_lite_matrix_t * matrix, int32_t x, int32_t y, const lv_draw_image_dsc_t * dsc); +vg_lite_color_t lv_vg_lite_image_recolor(vg_lite_buffer_t * buffer, const lv_draw_image_dsc_t * dsc); 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, bool premultiply); -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, bool has_pre_mul); @@ -145,7 +146,10 @@ 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); -void lv_vg_lite_matrix(vg_lite_matrix_t * dest, const lv_matrix_t * src); +static inline void lv_vg_lite_matrix(vg_lite_matrix_t * dest, const lv_matrix_t * src) +{ + *(lv_matrix_t *)dest = *src; +} /* Param checker */ @@ -171,9 +175,123 @@ 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); + +static inline void lv_vg_lite_draw(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * matrix, + vg_lite_blend_t blend, + vg_lite_color_t color) +{ + LV_VG_LITE_ASSERT_DEST_BUFFER(target); + LV_VG_LITE_ASSERT_PATH(path); + LV_VG_LITE_ASSERT_MATRIX(matrix); + + LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_draw"); + LV_VG_LITE_CHECK_ERROR(vg_lite_draw( + target, + path, + fill_rule, + matrix, + blend, + color), + /*Error handler*/ + { + lv_vg_lite_buffer_dump_info(target); + lv_vg_lite_path_dump_info(path); + LV_LOG_ERROR("fill_rule: 0x%X,", (int)fill_rule); + lv_vg_lite_matrix_dump_info(matrix); + LV_LOG_ERROR("blend: 0x%X,", (int)blend); + lv_vg_lite_color_dump_info(color); + }); + LV_PROFILER_DRAW_END_TAG("vg_lite_draw"); +} + +static inline void lv_vg_lite_draw_pattern(vg_lite_buffer_t * target, + vg_lite_path_t * path, + vg_lite_fill_t fill_rule, + vg_lite_matrix_t * path_matrix, + vg_lite_buffer_t * pattern_image, + vg_lite_matrix_t * pattern_matrix, + vg_lite_blend_t blend, + vg_lite_pattern_mode_t pattern_mode, + vg_lite_color_t pattern_color, + vg_lite_color_t color, + vg_lite_filter_t filter) +{ + LV_VG_LITE_ASSERT_DEST_BUFFER(target); + LV_VG_LITE_ASSERT_PATH(path); + LV_VG_LITE_ASSERT_MATRIX(path_matrix); + LV_VG_LITE_ASSERT_SRC_BUFFER(pattern_image); + LV_VG_LITE_ASSERT_MATRIX(pattern_matrix); + + LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_draw_pattern"); + LV_VG_LITE_CHECK_ERROR(vg_lite_draw_pattern( + target, + path, + fill_rule, + path_matrix, + pattern_image, + pattern_matrix, + blend, + pattern_mode, + pattern_color, + color, + filter), + /*Error handler*/ + { + lv_vg_lite_buffer_dump_info(target); + lv_vg_lite_path_dump_info(path); + LV_LOG_ERROR("fill_rule: 0x%X,", (int)fill_rule); + lv_vg_lite_matrix_dump_info(path_matrix); + lv_vg_lite_buffer_dump_info(pattern_image); + lv_vg_lite_matrix_dump_info(pattern_matrix); + LV_LOG_ERROR("blend: 0x%X,", (int)blend); + LV_LOG_ERROR("pattern_mode: 0x%X,", (int)pattern_mode); + lv_vg_lite_color_dump_info(pattern_color); + lv_vg_lite_color_dump_info(color); + LV_LOG_ERROR("filter: 0x%X,", (int)filter); + }); + LV_PROFILER_DRAW_END_TAG("vg_lite_draw_pattern"); +} + +static inline void lv_vg_lite_blit_rect(vg_lite_buffer_t * target, + vg_lite_buffer_t * source, + vg_lite_rectangle_t * rect, + vg_lite_matrix_t * matrix, + vg_lite_blend_t blend, + vg_lite_color_t color, + vg_lite_filter_t filter) +{ + LV_VG_LITE_ASSERT_DEST_BUFFER(target); + LV_VG_LITE_ASSERT_SRC_BUFFER(source); + LV_VG_LITE_ASSERT_MATRIX(matrix); + + LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_blit_rect"); + LV_VG_LITE_CHECK_ERROR(vg_lite_blit_rect( + target, + source, + rect, + matrix, + blend, + color, + filter), + /*Error handler*/ + { + lv_vg_lite_buffer_dump_info(target); + lv_vg_lite_buffer_dump_info(source); + LV_LOG_ERROR("rect: X%d Y%d W%d H%d", + (int)rect->x, (int)rect->y, (int)rect->width, (int)rect->height); + lv_vg_lite_matrix_dump_info(matrix); + LV_LOG_ERROR("blend: 0x%X", (int)blend); + lv_vg_lite_color_dump_info(color); + LV_LOG_ERROR("filter: 0x%X", (int)filter); + }); + LV_PROFILER_DRAW_END_TAG("vg_lite_blit_rect"); +} /********************** * 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 29e0168d9..2bb6cb518 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 @@ -22,6 +22,17 @@ #include #include +#include "../../../stdlib/lv_sprintf.h" +#include "../../../draw/lv_draw_buf.h" + +#if LV_LINUX_DRM_GBM_BUFFERS + + #include + #include + #include + +#endif + /********************* * DEFINES *********************/ @@ -33,6 +44,8 @@ #error LV_COLOR_DEPTH not supported #endif +#define BUFFER_CNT 2 + /********************** * TYPEDEFS **********************/ @@ -65,7 +78,8 @@ typedef struct { drmModePropertyPtr plane_props[128]; drmModePropertyPtr crtc_props[128]; drmModePropertyPtr conn_props[128]; - drm_buffer_t drm_bufs[2]; /*DUMB buffers*/ + drm_buffer_t drm_bufs[BUFFER_CNT]; + drm_buffer_t * act_buf; } drm_dev_t; /********************** @@ -92,13 +106,26 @@ static int drm_allocate_dumb(drm_dev_t * drm_dev, drm_buffer_t * buf); 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 void drm_dmabuf_set_active_buf(lv_event_t * event); static uint32_t tick_get_cb(void); +#if LV_LINUX_DRM_GBM_BUFFERS + + static int create_gbm_buffer(drm_dev_t * drm_dev, drm_buffer_t * buf); + +#endif + /********************** * STATIC VARIABLES **********************/ +#if LV_LINUX_DRM_GBM_BUFFERS + + static struct gbm_device * gbm_device; + +#endif + /********************** * MACROS **********************/ @@ -128,9 +155,56 @@ lv_display_t * lv_linux_drm_create(void) lv_display_set_flush_wait_cb(disp, drm_flush_wait); lv_display_set_flush_cb(disp, drm_flush); + return disp; } +/* Called by LVGL when there is something that needs redrawing + * it sets the active buffer. if GBM buffers are used, it issues a DMA_BUF_SYNC + * ioctl call to lock the buffer for CPU access, the buffer is unlocked just + * before the atomic commit */ +static void drm_dmabuf_set_active_buf(lv_event_t * event) +{ + + drm_dev_t * drm_dev; + lv_display_t * disp; + lv_draw_buf_t * act_buf; + int i; + + disp = (lv_display_t *) lv_event_get_current_target(event); + drm_dev = (drm_dev_t *) lv_display_get_driver_data(disp); + act_buf = lv_display_get_buf_active(disp); + + if(drm_dev->act_buf == NULL) { + + for(i = 0; i < BUFFER_CNT; i++) { + if(act_buf->unaligned_data == drm_dev->drm_bufs[i].map) { + drm_dev->act_buf = &drm_dev->drm_bufs[i]; + LV_LOG_TRACE("Set active buffer idx: %d", i); + break; + } + } + + +#if LV_LINUX_DRM_GBM_BUFFERS + + struct dma_buf_sync sync_req; + sync_req.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW; + int res; + + if((res = ioctl(drm_dev->act_buf->handle, DMA_BUF_IOCTL_SYNC, &sync_req)) != 0) { + LV_LOG_ERROR("Failed to start DMA-BUF R/W SYNC res: %d", res); + } +#endif + + } + else { + + LV_LOG_TRACE("active buffer already set"); + } + +} + void lv_linux_drm_set_file(lv_display_t * disp, const char * file, int64_t connector_id) { drm_dev_t * drm_dev = lv_display_get_driver_data(disp); @@ -165,6 +239,11 @@ void lv_linux_drm_set_file(lv_display_t * disp, const char * file, int64_t conne lv_display_set_buffers(disp, drm_dev->drm_bufs[1].map, drm_dev->drm_bufs[0].map, buf_size, LV_DISPLAY_RENDER_MODE_DIRECT); + + /* Set the handler that is called before a redraw occurs to set the active buffer/plane + * when GBM buffers are used the DMA_BUF_SYNC_START is issued there */ + lv_display_add_event_cb(disp, drm_dmabuf_set_active_buf, LV_EVENT_REFR_START, drm_dev); + if(width) { lv_display_set_dpi(disp, DIV_ROUND_UP(hor_res * 25400, width * 1000)); } @@ -363,6 +442,17 @@ static int drm_dmabuf_set_plane(drm_dev_t * drm_dev, drm_buffer_t * buf) static int first = 1; uint32_t flags = DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK; +#if LV_LINUX_DRM_GBM_BUFFERS + + struct dma_buf_sync sync_req; + + sync_req.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW; + if(ioctl(buf->handle, DMA_BUF_IOCTL_SYNC, &sync_req) != 0) { + LV_LOG_ERROR("Failed to end DMA-BUF R/W SYNC"); + } + +#endif + drm_dev->req = drmModeAtomicAlloc(); /* On first Atomic commit, do a modeset */ @@ -716,6 +806,21 @@ static int drm_setup(drm_dev_t * drm_dev, const char * device_path, int64_t conn drm_dev->width, drm_dev->height, drm_dev->mmWidth, drm_dev->mmHeight, (fourcc >> 0) & 0xff, (fourcc >> 8) & 0xff, (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff); + +#if LV_LINUX_DRM_GBM_BUFFERS + + /* Create GBM device and buffer */ + gbm_device = gbm_create_device(drm_dev->fd); + + if(gbm_device == NULL) { + LV_LOG_ERROR("Failed to create GBM device"); + goto err; + } + + LV_LOG_INFO("GBM device backend: %s", gbm_device_get_backend_name(gbm_device)); + +#endif + return 0; err: @@ -781,11 +886,117 @@ static int drm_allocate_dumb(drm_dev_t * drm_dev, drm_buffer_t * buf) return 0; } +#if LV_LINUX_DRM_GBM_BUFFERS + +static int create_gbm_buffer(drm_dev_t * drm_dev, drm_buffer_t * buf) +{ + + struct gbm_bo * gbm_bo; + int prime_fd; + uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0}; + uint32_t w, h, format; + uint32_t n_planes; + char * drm_format_name; + int res; + + /* gbm_bo_format does not define anything other than ARGB8888 or XRGB8888 */ + if(LV_COLOR_DEPTH != 32) { + LV_LOG_ERROR("Unsupported color format"); + return -1; + } + + /* Create a linear GBM buffer object - best practice when modifiers are not used */ + if(!(gbm_bo = gbm_bo_create(gbm_device, + drm_dev->width, drm_dev->height, GBM_BO_FORMAT_XRGB8888, + GBM_BO_USE_SCANOUT | GBM_BO_USE_LINEAR))) { + + LV_LOG_ERROR("Unable to create gbm buffer object"); + return -1; + } + + /* Currently only, one plane per dma-buf/prime fd is supported - but some GPUs feature + * several planes (multiple fds or sometimes a single fd for multiple planes). + * current implementation is kept simple for now */ + + n_planes = gbm_bo_get_plane_count(gbm_bo); + + if(n_planes != 1) { + LV_LOG_ERROR("The current implementation only supports a single plane per fd"); + return -1; + } + + w = gbm_bo_get_width(gbm_bo); + h = gbm_bo_get_height(gbm_bo); + format = gbm_bo_get_format(gbm_bo); + pitches[0] = buf->pitch = gbm_bo_get_stride_for_plane(gbm_bo, 0); + offsets[0] = buf->offset = gbm_bo_get_offset(gbm_bo, 0); + buf->size = h * buf->pitch; + drm_format_name = drmGetFormatName(format); + + LV_LOG_INFO("Created GBM BO of size: %lu pitch: %u offset: %u format: %s", + buf->size, buf->pitch, buf->offset, drm_format_name); + + prime_fd = gbm_bo_get_fd_for_plane(gbm_bo, 0); + + if(prime_fd < 0) { + LV_LOG_ERROR("Failed to get prime fd for plane 0"); + return -1; + + } + + buf->map = mmap(NULL, buf->size, PROT_READ | PROT_WRITE, MAP_SHARED, prime_fd, 0); + + if(buf->map == MAP_FAILED) { + LV_LOG_ERROR("Failed to mmap dma-buf fd."); + return -1; + } + + /* Used to perform DMA_BUF_SYNC ioctl calls during the rendering cycle */ + buf->handle = prime_fd; + + /* Convert prime fd to a libdrm buffer handle */ + drmPrimeFDToHandle(drm_dev->fd, buf->handle, &handles[0]); + + /* create libdrm framebuffer */ + res = drmModeAddFB2(drm_dev->fd, drm_dev->width, drm_dev->height, drm_dev->fourcc, + handles, pitches, offsets, &buf->fb_handle, 0); + + if(res) { + LV_LOG_ERROR("drmModeAddFB2 failed"); + return -1; + } + + if(drmCloseBufferHandle(drm_dev->fd, handles[0]) != 0) { + LV_LOG_ERROR("drmCloseBufferHandle failed"); + return -1; + } + + return 0; + +} + +#endif /* END LV_LINUX_DRM_GBM_BUFFERS */ + + static int drm_setup_buffers(drm_dev_t * drm_dev) { int ret; - /*Allocate DUMB buffers*/ +#if LV_LINUX_DRM_GBM_BUFFERS + + ret = create_gbm_buffer(drm_dev, &drm_dev->drm_bufs[0]); + if(ret < 0) { + return ret; + } + + ret = create_gbm_buffer(drm_dev, &drm_dev->drm_bufs[1]); + if(ret < 0) { + return ret; + } + +#else + + /* Use dumb buffers */ ret = drm_allocate_dumb(drm_dev, &drm_dev->drm_bufs[0]); if(ret) return ret; @@ -794,6 +1005,8 @@ static int drm_setup_buffers(drm_dev_t * drm_dev) if(ret) return ret; +#endif + return 0; } @@ -822,23 +1035,22 @@ static void drm_flush_wait(lv_display_t * disp) static void drm_flush(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) { + if(!lv_display_flush_is_last(disp)) return; LV_UNUSED(area); LV_UNUSED(px_map); drm_dev_t * drm_dev = lv_display_get_driver_data(disp); - for(int idx = 0; idx < 2; idx++) { - if(drm_dev->drm_bufs[idx].map == px_map) { - /*Request buffer swap*/ - if(drm_dmabuf_set_plane(drm_dev, &drm_dev->drm_bufs[idx])) { - LV_LOG_ERROR("Flush fail"); - return; - } - else - LV_LOG_TRACE("Flush done"); - } + LV_ASSERT(drm_dev->act_buf != NULL); + + if(drm_dmabuf_set_plane(drm_dev, drm_dev->act_buf)) { + LV_LOG_ERROR("Flush fail"); + return; } + + drm_dev->act_buf = NULL; + } static uint32_t tick_get_cb(void) 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 076ada41a..1b9ddc02b 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 @@ -59,7 +59,9 @@ typedef struct { struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; #endif /* LV_LINUX_FBDEV_BSD */ +#if LV_LINUX_FBDEV_MMAP char * fbp; +#endif uint8_t * rotated_buf; size_t rotated_buf_size; long int screensize; @@ -116,10 +118,9 @@ lv_display_t * lv_linux_fbdev_create(void) void lv_linux_fbdev_set_file(lv_display_t * disp, const char * file) { - char * devname = lv_malloc(lv_strlen(file) + 1); + char * devname = lv_strdup(file); LV_ASSERT_MALLOC(devname); if(devname == NULL) return; - lv_strcpy(devname, file); lv_linux_fb_t * dsc = lv_display_get_driver_data(disp); dsc->devname = devname; @@ -183,12 +184,14 @@ void lv_linux_fbdev_set_file(lv_display_t * disp, const char * file) /* Figure out the size of the screen in bytes*/ dsc->screensize = dsc->finfo.smem_len;/*finfo.line_length * vinfo.yres;*/ +#if LV_LINUX_FBDEV_MMAP /* Map the device to memory*/ dsc->fbp = (char *)mmap(0, dsc->screensize, PROT_READ | PROT_WRITE, MAP_SHARED, dsc->fbfd, 0); if((intptr_t)dsc->fbp == -1) { perror("Error: failed to map framebuffer device to memory"); return; } +#endif /* Don't initialise the memory to retain what's currently displayed / avoid clearing the screen. * This is important for applications that only draw to a subsection of the full framebuffer.*/ @@ -250,14 +253,27 @@ void lv_linux_fbdev_set_force_refresh(lv_display_t * disp, bool enabled) * STATIC FUNCTIONS **********************/ +static void write_to_fb(lv_linux_fb_t * dsc, uint32_t fb_pos, const void * data, size_t sz) +{ +#if LV_LINUX_FBDEV_MMAP + uint8_t * fbp = (uint8_t *)dsc->fbp; + lv_memcpy(&fbp[fb_pos], data, sz); +#else + if(pwrite(dsc->fbfd, data, sz, fb_pos) < 0) + LV_LOG_ERROR("write failed: %d", errno); +#endif +} + static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p) { lv_linux_fb_t * dsc = lv_display_get_driver_data(disp); +#if LV_LINUX_FBDEV_MMAP if(dsc->fbp == NULL) { lv_display_flush_ready(disp); return; } +#endif int32_t w = lv_area_get_width(area); int32_t h = lv_area_get_height(area); @@ -316,7 +332,6 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * colo (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 = @@ -324,7 +339,7 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * colo 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); + write_to_fb(dsc, fb_pos, &color_p[color_pos], w * px_size); fb_pos += dsc->finfo.line_length; color_pos += disp->hor_res * px_size; } @@ -332,7 +347,7 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * colo 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); + write_to_fb(dsc, fb_pos, color_p, w * px_size); fb_pos += dsc->finfo.line_length; color_p += w * px_size; } diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/ft81x/lv_ft81x.c b/lib/libesp32_lvgl/lvgl/src/drivers/display/ft81x/lv_ft81x.c new file mode 100644 index 000000000..2013d4a1c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/ft81x/lv_ft81x.c @@ -0,0 +1,399 @@ +/** + * @file lv_ft81x.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_ft81x.h" +#if LV_USE_FT81X + +#include "lv_ft81x_defines.h" + +#include "../../../stdlib/lv_mem.h" +#include "../../../stdlib/lv_sprintf.h" +#include "../../../stdlib/lv_string.h" +#include "../../../misc/lv_types.h" +#include "../../../misc/lv_utils.h" + +/********************* + * DEFINES + *********************/ + +/* Increase as functionality is added if needed. */ +#define LV_FT81X_CMD_BUF_SIZE 63 + +/* The PWM value that corresponds to the backlight being "on". + 0x80 was found to work on at least two boards but should + be changed as needed. */ +#define PWM_DUTY_BACKLIGHT_ON 0x80 + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_ft81x_spi_cb_t spi_cb; + void * user_data; + uint16_t cmd_offset; +} lv_ft81x_driver_data_t; + +typedef struct { + uint32_t buf_len; + uint8_t buf[LV_FT81X_CMD_BUF_SIZE]; +} lv_ft81x_cmd_list_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static lv_result_t initialize(lv_display_t * disp, const lv_ft81x_parameters_t * params); +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); +static void delete_cb(lv_event_t * e); +static void lv_ft81x_cmd(lv_display_t * disp, uint8_t command, uint8_t parameter); +static uint8_t lv_ft81x_read_8(lv_display_t * disp, uint32_t address); +static uint16_t lv_ft81x_read_16(lv_display_t * disp, uint32_t address); +/* static uint32_t lv_ft81x_read_32(lv_display_t * disp, uint32_t address); */ +static void lv_ft81x_write_8(lv_display_t * disp, uint32_t address, uint8_t val); +static void lv_ft81x_write_16(lv_display_t * disp, uint32_t address, uint16_t val); +static void lv_ft81x_write_32(lv_display_t * disp, uint32_t address, uint32_t val); +static void lv_ft81x_cmd_list_init(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list); +static void lv_ft81x_cmd_list_add_16(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list, uint16_t value); +static void lv_ft81x_cmd_list_add_32(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list, uint32_t value); +static void lv_ft81x_cmd_list_send(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list); +static void lv_ft81x_encode_read_address(void * dst_4_bytes, uint32_t address); +static void lv_ft81x_encode_write_address(void * dst_3_bytes, uint32_t address); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +#if LV_BIG_ENDIAN_SYSTEM + #define BE_TO_OR_FROM_NATIVE_32(x) ((uint32_t)(x)) + #define BE_TO_OR_FROM_NATIVE_16(x) ((uint16_t)(x)) + #define LE_TO_OR_FROM_NATIVE_32(x) lv_swap_bytes_32(x) + #define LE_TO_OR_FROM_NATIVE_16(x) lv_swap_bytes_16(x) +#else + #define BE_TO_OR_FROM_NATIVE_32(x) lv_swap_bytes_32(x) + #define BE_TO_OR_FROM_NATIVE_16(x) lv_swap_bytes_16(x) + #define LE_TO_OR_FROM_NATIVE_32(x) ((uint32_t)(x)) + #define LE_TO_OR_FROM_NATIVE_16(x) ((uint16_t)(x)) +#endif + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_display_t * lv_ft81x_create(const lv_ft81x_parameters_t * params, void * partial_buf, uint32_t buf_size, + lv_ft81x_spi_cb_t spi_cb, void * user_data) +{ + LV_ASSERT_NULL(spi_cb); + + lv_display_t * disp = lv_display_create(params->hor_res, params->ver_res); + + lv_ft81x_driver_data_t * drv = lv_malloc_zeroed(sizeof(lv_ft81x_driver_data_t)); + LV_ASSERT_MALLOC(drv); + drv->spi_cb = spi_cb; + drv->user_data = user_data; + drv->cmd_offset = 0; + lv_display_set_driver_data(disp, drv); + lv_display_set_flush_cb(disp, flush_cb); + lv_display_set_color_format(disp, LV_COLOR_FORMAT_RGB565); + lv_display_set_buffers(disp, partial_buf, NULL, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL); + lv_display_add_event_cb(disp, delete_cb, LV_EVENT_DELETE, NULL); + + lv_result_t init_res = initialize(disp, params); + if(init_res != LV_RESULT_OK) { + lv_display_delete(disp); + return NULL; + } + + return disp; +} + +void * lv_ft81x_get_user_data(lv_display_t * disp) +{ + lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp); + return drv->user_data; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_result_t initialize(lv_display_t * disp, const lv_ft81x_parameters_t * params) +{ + lv_ft81x_cmd(disp, params->has_crystal ? EVE_CLKEXT : EVE_CLKINT, 0); + if(params->is_bt81x) lv_ft81x_cmd(disp, EVE_CLKSEL, 0x46); + lv_ft81x_cmd(disp, EVE_ACTIVE, 0); + + /* at least 40 ms is needed for EVE to become ready. */ + lv_delay_ms(40); + + uint32_t start_millis = lv_tick_get(); + while(lv_ft81x_read_8(disp, REG_ID) != 0x7c) { + if(lv_tick_get() - start_millis > 1000) { + LV_LOG_ERROR("failed to read 0x7C from the ID register 1000 ms after activation."); + return LV_RESULT_INVALID; + } + lv_delay_ms(1); + }; + + start_millis = lv_tick_get(); + while(lv_ft81x_read_8(disp, REG_CPURESET) & 0x03) { + if(lv_tick_get() - start_millis > 1000) { + LV_LOG_ERROR("CPURESET register coprocessor and touch engines not in \"working status\" 1000 ms after activation."); + return LV_RESULT_INVALID; + } + lv_delay_ms(1); + }; + + if(params->is_bt81x) lv_ft81x_write_32(disp, REG_FREQUENCY, 72000000); + + lv_ft81x_write_8(disp, REG_PWM_DUTY, PWM_DUTY_BACKLIGHT_ON); + + lv_ft81x_write_16(disp, REG_HSIZE, params->hor_res); /* active display width */ + lv_ft81x_write_16(disp, REG_HCYCLE, params->hcycle); /* total number of clocks per line, incl front/back porch */ + lv_ft81x_write_16(disp, REG_HOFFSET, params->hoffset); /* start of active line */ + lv_ft81x_write_16(disp, REG_HSYNC0, params->hsync0); /* start of horizontal sync pulse */ + lv_ft81x_write_16(disp, REG_HSYNC1, params->hsync1); /* end of horizontal sync pulse */ + lv_ft81x_write_16(disp, REG_VSIZE, params->ver_res); /* active display height */ + lv_ft81x_write_16(disp, REG_VCYCLE, params->vcycle); /* total number of lines per screen, including pre/post */ + lv_ft81x_write_16(disp, REG_VOFFSET, params->voffset); /* start of active screen */ + lv_ft81x_write_16(disp, REG_VSYNC0, params->vsync0); /* start of vertical sync pulse */ + lv_ft81x_write_16(disp, REG_VSYNC1, params->vsync1); /* end of vertical sync pulse */ + lv_ft81x_write_8(disp, REG_SWIZZLE, params->swizzle); /* FT8xx output to LCD - pin order */ + lv_ft81x_write_8(disp, REG_PCLK_POL, params->pclkpol); /* LCD data is clocked in on this PCLK edge */ + lv_ft81x_write_8(disp, REG_CSPREAD, + params->cspread); /* helps with noise, when set to 1 fewer signals are changed simultaneously, reset-default: 1 */ + + /* write a basic display-list to get things started */ + lv_ft81x_write_32(disp, EVE_RAM_DL, DL_CLEAR_RGB); + lv_ft81x_write_32(disp, EVE_RAM_DL + 4, (DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG)); + lv_ft81x_write_32(disp, EVE_RAM_DL + 8, DL_DISPLAY); /* end of display list */ + lv_ft81x_write_32(disp, REG_DLSWAP, EVE_DLSWAP_FRAME); + + /* nothing is being displayed yet... the pixel clock is still 0x00 */ + lv_ft81x_write_8(disp, REG_GPIO, + 0x80); /* enable the DISP signal to the LCD panel, it is set to output in REG_GPIO_DIR by default */ + lv_ft81x_write_8(disp, REG_PCLK, params->pclk); /* now start clocking data to the LCD panel */ + + LV_ASSERT(lv_ft81x_read_16(disp, REG_CMD_READ) != 0xfff); + + LV_ASSERT(0 == lv_ft81x_read_16(disp, REG_CMD_WRITE)); + + + lv_ft81x_cmd_list_t cmd_list; + lv_ft81x_cmd_list_init(disp, &cmd_list); + lv_ft81x_cmd_list_add_32(disp, &cmd_list, CMD_MEMSET); + lv_ft81x_cmd_list_add_32(disp, &cmd_list, 0); /* address */ + lv_ft81x_cmd_list_add_32(disp, &cmd_list, 0x00); /* val */ + lv_ft81x_cmd_list_add_32(disp, &cmd_list, 2 * params->hor_res * params->ver_res); /* count */ + lv_ft81x_cmd_list_send(disp, &cmd_list); + + lv_ft81x_cmd_list_init(disp, &cmd_list); + + lv_ft81x_cmd_list_add_32(disp, &cmd_list, CMD_DLSTART); + + lv_ft81x_cmd_list_add_32(disp, &cmd_list, DL_CLEAR_RGB | 0); /* clear to black */ + lv_ft81x_cmd_list_add_32(disp, &cmd_list, DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG); + + lv_ft81x_cmd_list_add_32(disp, &cmd_list, TAG(0)); + + lv_ft81x_cmd_list_add_32(disp, &cmd_list, TAG(20)); + lv_ft81x_cmd_list_add_32(disp, &cmd_list, CMD_SETBITMAP); + lv_ft81x_cmd_list_add_32(disp, &cmd_list, 0); /* address */ + lv_ft81x_cmd_list_add_16(disp, &cmd_list, EVE_RGB565); + lv_ft81x_cmd_list_add_16(disp, &cmd_list, params->hor_res); + lv_ft81x_cmd_list_add_16(disp, &cmd_list, params->ver_res); + lv_ft81x_cmd_list_add_16(disp, &cmd_list, 0); + + lv_ft81x_cmd_list_add_32(disp, &cmd_list, DL_BEGIN | EVE_BITMAPS); + lv_ft81x_cmd_list_add_32(disp, &cmd_list, VERTEX2F(0, 0)); + lv_ft81x_cmd_list_add_32(disp, &cmd_list, DL_END); + + lv_ft81x_cmd_list_add_32(disp, &cmd_list, TAG(0)); + + lv_ft81x_cmd_list_add_32(disp, &cmd_list, DL_DISPLAY); + + lv_ft81x_cmd_list_add_32(disp, &cmd_list, CMD_SWAP); + + lv_ft81x_cmd_list_send(disp, &cmd_list); + + + return LV_RESULT_OK; +} + +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) +{ + lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp); + + if(drv->spi_cb == NULL) { + LV_LOG_ERROR("The SPI callback is NULL."); + return; + } + + int32_t hor_res = lv_display_get_horizontal_resolution(disp); + uint32_t disp_row_bytes = hor_res * 2; + + uint32_t address = disp_row_bytes * area->y1 + area->x1 * 2; + uint8_t encoded_address[3]; + + if(lv_area_get_width(area) == hor_res) { + lv_ft81x_encode_write_address(encoded_address, address); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, encoded_address, sizeof(encoded_address)); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, px_map, lv_area_get_size(area) * 2); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0); + } + else { + uint32_t area_height = lv_area_get_height(area); + uint32_t area_row_bytes = lv_area_get_width(area) * 2; + for(uint32_t i = 0; i < area_height; i++) { + lv_ft81x_encode_write_address(encoded_address, address); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, encoded_address, sizeof(encoded_address)); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, px_map, area_row_bytes); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0); + address += disp_row_bytes; + px_map += area_row_bytes; + } + } + + lv_display_flush_ready(disp); +} + +static void delete_cb(lv_event_t * e) +{ + lv_display_t * disp = lv_event_get_target(e); + lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp); + lv_free(drv); +} + +static void lv_ft81x_cmd(lv_display_t * disp, uint8_t command, uint8_t parameter) +{ + lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp); + uint8_t data[3] = {command, parameter, 0x00}; + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, data, sizeof(data)); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0); +} + +static uint8_t lv_ft81x_read_8(lv_display_t * disp, uint32_t address) +{ + lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp); + lv_ft81x_encode_read_address(&address, address); + uint8_t val; + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, &address, sizeof(address)); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_RECEIVE, &val, sizeof(val)); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0); + return val; +} + +static uint16_t lv_ft81x_read_16(lv_display_t * disp, uint32_t address) +{ + lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp); + lv_ft81x_encode_read_address(&address, address); + uint16_t val; + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, &address, sizeof(address)); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_RECEIVE, &val, sizeof(val)); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0); + val = LE_TO_OR_FROM_NATIVE_16(val); + return val; +} + +static void lv_ft81x_write_8(lv_display_t * disp, uint32_t address, uint8_t val) +{ + lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp); + uint8_t data[4]; + lv_ft81x_encode_write_address(data, address); + data[3] = val; + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, data, sizeof(data)); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0); +} + +static void lv_ft81x_write_16(lv_display_t * disp, uint32_t address, uint16_t val) +{ + lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp); + val = LE_TO_OR_FROM_NATIVE_16(val); + uint8_t data[5]; + lv_ft81x_encode_write_address(data, address); + lv_memcpy(data + 3, &val, 2); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, data, sizeof(data)); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0); +} + +static void lv_ft81x_write_32(lv_display_t * disp, uint32_t address, uint32_t val) +{ + lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp); + val = LE_TO_OR_FROM_NATIVE_32(val); + uint8_t data[7]; + lv_ft81x_encode_write_address(data, address); + lv_memcpy(data + 3, &val, 4); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, data, sizeof(data)); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0); +} + +static void lv_ft81x_cmd_list_init(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list) +{ + lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp); + LV_ASSERT_MSG(LV_FT81X_CMD_BUF_SIZE >= 3, "increase LV_FT81X_CMD_BUF_SIZE as needed"); + lv_ft81x_encode_write_address(cmd_list->buf, EVE_RAM_CMD + drv->cmd_offset); + cmd_list->buf_len = 3; +} + +static void lv_ft81x_cmd_list_add_16(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list, uint16_t value) +{ + lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp); + uint8_t * buf_dst = &cmd_list->buf[cmd_list->buf_len]; + cmd_list->buf_len += 2; + LV_ASSERT_MSG(cmd_list->buf_len <= LV_FT81X_CMD_BUF_SIZE, "increase LV_FT81X_CMD_BUF_SIZE as needed"); + value = LE_TO_OR_FROM_NATIVE_16(value); + lv_memcpy(buf_dst, &value, 2); + drv->cmd_offset = (drv->cmd_offset + 2) & 0xfff; /* circular */ +} + +static void lv_ft81x_cmd_list_add_32(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list, uint32_t value) +{ + lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp); + uint8_t * buf_dst = &cmd_list->buf[cmd_list->buf_len]; + cmd_list->buf_len += 4; + LV_ASSERT_MSG(cmd_list->buf_len <= LV_FT81X_CMD_BUF_SIZE, "increase LV_FT81X_CMD_BUF_SIZE as needed"); + value = LE_TO_OR_FROM_NATIVE_32(value); + lv_memcpy(buf_dst, &value, 4); + drv->cmd_offset = (drv->cmd_offset + 4) & 0xfff; /* circular */ +} + +static void lv_ft81x_cmd_list_send(lv_display_t * disp, lv_ft81x_cmd_list_t * cmd_list) +{ + lv_ft81x_driver_data_t * drv = lv_display_get_driver_data(disp); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_ASSERT, NULL, 0); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_SEND, cmd_list->buf, cmd_list->buf_len); + drv->spi_cb(disp, LV_FT81X_SPI_OPERATION_CS_DEASSERT, NULL, 0); + lv_ft81x_write_16(disp, REG_CMD_WRITE, drv->cmd_offset); +} + +static void lv_ft81x_encode_read_address(void * dst_4_bytes, uint32_t address) +{ + address = BE_TO_OR_FROM_NATIVE_32(address << 8); + lv_memcpy(dst_4_bytes, &address, 4); +} + +static void lv_ft81x_encode_write_address(void * dst_3_bytes, uint32_t address) +{ + address = BE_TO_OR_FROM_NATIVE_32((address | 0x800000) << 8); + lv_memcpy(dst_3_bytes, &address, 3); +} + +#endif /*LV_USE_FT81X*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/ft81x/lv_ft81x.h b/lib/libesp32_lvgl/lvgl/src/drivers/display/ft81x/lv_ft81x.h new file mode 100644 index 000000000..0995d4a47 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/ft81x/lv_ft81x.h @@ -0,0 +1,93 @@ +/** + * @file lv_ft81x.h + * + */ + +#ifndef LV_FT81X_H +#define LV_FT81X_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" +#if LV_USE_FT81X + +#include "../../../display/lv_display.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + uint16_t hor_res; + uint16_t ver_res; + + uint16_t hcycle; + uint16_t hoffset; + uint16_t hsync0; + uint16_t hsync1; + uint16_t vcycle; + uint16_t voffset; + uint16_t vsync0; + uint16_t vsync1; + uint8_t swizzle; + uint8_t pclkpol; + uint8_t cspread; + uint8_t pclk; + + bool has_crystal; + bool is_bt81x; +} lv_ft81x_parameters_t; + +typedef enum { + LV_FT81X_SPI_OPERATION_CS_ASSERT, + LV_FT81X_SPI_OPERATION_CS_DEASSERT, + LV_FT81X_SPI_OPERATION_SEND, + LV_FT81X_SPI_OPERATION_RECEIVE +} lv_ft81x_spi_operation; + +typedef void (*lv_ft81x_spi_cb_t)(lv_display_t * disp, lv_ft81x_spi_operation operation, void * data, uint32_t length); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a framebuffer-based ft81x driver display. + * @param params pointer to a struct of display panel properties. does not need to be static. + * @param partial_buf a single partial buffer + * @param buf_size size of the partial buffer + * @param spi_cb a callback called by the driver to perform SPI operations + * @param user_data use `lv_ft81x_get_user_data` to get this pointer inside the SPI callback + * @return pointer to the display + */ +lv_display_t * lv_ft81x_create(const lv_ft81x_parameters_t * params, void * partial_buf, uint32_t buf_size, + lv_ft81x_spi_cb_t spi_cb, void * user_data); + +/** + * Get the `user_data` parameter that was passed to `lv_ft81x_create`. Useful in the SPI callback. + * @param disp pointer to the ft81x display + * @return the `user_data` pointer + */ +void * lv_ft81x_get_user_data(lv_display_t * disp); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_FT81X*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FT81X_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/ft81x/lv_ft81x_defines.h b/lib/libesp32_lvgl/lvgl/src/drivers/display/ft81x/lv_ft81x_defines.h new file mode 100644 index 000000000..ae9a51109 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/ft81x/lv_ft81x_defines.h @@ -0,0 +1,846 @@ +/** + * @file lv_ft81x_defines.h + * + * Copied from https://github.com/lvgl/lvgl_esp32_drivers/blob/9fed1cc47b5a45fec6bae08b55d2147d3b50260c/lvgl_tft/EVE.h + */ + +#ifndef LV_FT81X_DEFINES_H +#define LV_FT81X_DEFINES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/* ft81x and ft80x each define exclusive + * definitions. Define ft81x for now. + * + * bt81x is a superset of ft81x and ft80x. + * Don't define it since its special + * definitions are not required to use it. + */ +#define FT81X_ENABLE +/* #define BT81X_ENABLE */ + + +#define DL_CLEAR 0x26000000UL /* requires OR'd arguments */ +#define DL_CLEAR_RGB 0x02000000UL /* requires OR'd arguments */ +#define DL_COLOR_RGB 0x04000000UL /* requires OR'd arguments */ +#define DL_POINT_SIZE 0x0D000000UL /* requires OR'd arguments */ +#define DL_END 0x21000000UL +#define DL_BEGIN 0x1F000000UL /* requires OR'd arguments */ +#define DL_DISPLAY 0x00000000UL + +#define CLR_COL 0x4 +#define CLR_STN 0x2 +#define CLR_TAG 0x1 + +/* SPI SIO/DIO/QIO tranfer widths */ +#define SPI_WIDTH_SIO 0x0 +#define SPI_WIDTH_DIO 0x1 +#define SPI_WIDTH_QIO 0x2 + + +/* Host commands */ +#define EVE_ACTIVE 0x00 /* place FT8xx in active state */ +#define EVE_STANDBY 0x41 /* place FT8xx in Standby (clk running) */ +#define EVE_SLEEP 0x42 /* place FT8xx in Sleep (clk off) */ +#define EVE_PWRDOWN 0x50 /* place FT8xx in Power Down (core off) */ +#define EVE_CLKEXT 0x44 /* select external clock source */ +#define EVE_CLKINT 0x48 /* select internal clock source */ +#define EVE_CORERST 0x68 /* reset core - all registers default and processors reset */ +#define EVE_CLK48M 0x62 /* select 48MHz PLL output */ +#define EVE_CLK36M 0x61 /* select 36MHz PLL output */ + + +/* defines used for graphics commands */ +#define EVE_NEVER 0UL +#define EVE_LESS 1UL +#define EVE_LEQUAL 2UL +#define EVE_GREATER 3UL +#define EVE_GEQUAL 4UL +#define EVE_EQUAL 5UL +#define EVE_NOTEQUAL 6UL +#define EVE_ALWAYS 7UL + + +/* Bitmap formats */ +#define EVE_ARGB1555 0UL +#define EVE_L1 1UL +#define EVE_L4 2UL +#define EVE_L8 3UL +#define EVE_RGB332 4UL +#define EVE_ARGB2 5UL +#define EVE_ARGB4 6UL +#define EVE_RGB565 7UL +#define EVE_PALETTED 8UL +#define EVE_TEXT8X8 9UL +#define EVE_TEXTVGA 10UL +#define EVE_BARGRAPH 11UL + + +/* Bitmap filter types */ +#define EVE_NEAREST 0UL +#define EVE_BILINEAR 1UL + + +/* Bitmap wrap types */ +#define EVE_BORDER 0UL +#define EVE_REPEAT 1UL + + +/* Stencil defines */ +#define EVE_KEEP 1UL +#define EVE_REPLACE 2UL +#define EVE_INCR 3UL +#define EVE_DECR 4UL +#define EVE_INVERT 5UL + + +/* Graphics display list swap defines */ +#define EVE_DLSWAP_DONE 0UL +#define EVE_DLSWAP_LINE 1UL +#define EVE_DLSWAP_FRAME 2UL + + +/* Interrupt bits */ +#define EVE_INT_SWAP 0x01 +#define EVE_INT_TOUCH 0x02 +#define EVE_INT_TAG 0x04 +#define EVE_INT_SOUND 0x08 +#define EVE_INT_PLAYBACK 0x10 +#define EVE_INT_CMDEMPTY 0x20 +#define EVE_INT_CMDFLAG 0x40 +#define EVE_INT_CONVCOMPLETE 0x80 + + +/* Touch mode */ +#define EVE_TMODE_OFF 0 +#define EVE_TMODE_ONESHOT 1 +#define EVE_TMODE_FRAME 2 +#define EVE_TMODE_CONTINUOUS 3 + + +/* Alpha blending */ +#define EVE_ZERO 0UL +#define EVE_ONE 1UL +#define EVE_SRC_ALPHA 2UL +#define EVE_DST_ALPHA 3UL +#define EVE_ONE_MINUS_SRC_ALPHA 4UL +#define EVE_ONE_MINUS_DST_ALPHA 5UL + + +/* Graphics primitives */ +#define EVE_BITMAPS 1UL +#define EVE_POINTS 2UL +#define EVE_LINES 3UL +#define EVE_LINE_STRIP 4UL +#define EVE_EDGE_STRIP_R 5UL +#define EVE_EDGE_STRIP_L 6UL +#define EVE_EDGE_STRIP_A 7UL +#define EVE_EDGE_STRIP_B 8UL +#define EVE_RECTS 9UL + + +/* Widget command */ +#define EVE_OPT_MONO 1 +#define EVE_OPT_NODL 2 +#define EVE_OPT_FLAT 256 +#define EVE_OPT_CENTERX 512 +#define EVE_OPT_CENTERY 1024 +#define EVE_OPT_CENTER (EVE_OPT_CENTERX | EVE_OPT_CENTERY) +#define EVE_OPT_NOBACK 4096 +#define EVE_OPT_NOTICKS 8192 +#define EVE_OPT_NOHM 16384 +#define EVE_OPT_NOPOINTER 16384 +#define EVE_OPT_NOSECS 32768 +#define EVE_OPT_NOHANDS 49152 +#define EVE_OPT_RIGHTX 2048 +#define EVE_OPT_SIGNED 256 + + +/* Defines related to inbuilt font */ +#define EVE_NUMCHAR_PERFONT (128L) /* number of font characters per bitmap handle */ +#define EVE_FONT_TABLE_SIZE (148L) /* size of the font table - utilized for loopup by the graphics engine */ +#define EVE_FONT_TABLE_POINTER (0xFFFFCUL) /* pointer to the inbuilt font tables starting from bitmap handle 16 */ + + +/* Audio sample type defines */ +#define EVE_LINEAR_SAMPLES 0UL /* 8bit signed samples */ +#define EVE_ULAW_SAMPLES 1UL /* 8bit ulaw samples */ +#define EVE_ADPCM_SAMPLES 2UL /* 4bit ima adpcm samples */ + + +/* Synthesized sound */ +#define EVE_SILENCE 0x00 +#define EVE_SQUAREWAVE 0x01 +#define EVE_SINEWAVE 0x02 +#define EVE_SAWTOOTH 0x03 +#define EVE_TRIANGLE 0x04 +#define EVE_BEEPING 0x05 +#define EVE_ALARM 0x06 +#define EVE_WARBLE 0x07 +#define EVE_CAROUSEL 0x08 +#define EVE_PIPS(n) (0x0F + (n)) +#define EVE_HARP 0x40 +#define EVE_XYLOPHONE 0x41 +#define EVE_TUBA 0x42 +#define EVE_GLOCKENSPIEL 0x43 +#define EVE_ORGAN 0x44 +#define EVE_TRUMPET 0x45 +#define EVE_PIANO 0x46 +#define EVE_CHIMES 0x47 +#define EVE_MUSICBOX 0x48 +#define EVE_BELL 0x49 +#define EVE_CLICK 0x50 +#define EVE_SWITCH 0x51 +#define EVE_COWBELL 0x52 +#define EVE_NOTCH 0x53 +#define EVE_HIHAT 0x54 +#define EVE_KICKDRUM 0x55 +#define EVE_POP 0x56 +#define EVE_CLACK 0x57 +#define EVE_CHACK 0x58 +#define EVE_MUTE 0x60 +#define EVE_UNMUTE 0x61 + + +/* Synthesized sound frequencies, midi note */ +#define EVE_MIDI_A0 21 +#define EVE_MIDI_A_0 22 +#define EVE_MIDI_B0 23 +#define EVE_MIDI_C1 24 +#define EVE_MIDI_C_1 25 +#define EVE_MIDI_D1 26 +#define EVE_MIDI_D_1 27 +#define EVE_MIDI_E1 28 +#define EVE_MIDI_F1 29 +#define EVE_MIDI_F_1 30 +#define EVE_MIDI_G1 31 +#define EVE_MIDI_G_1 32 +#define EVE_MIDI_A1 33 +#define EVE_MIDI_A_1 34 +#define EVE_MIDI_B1 35 +#define EVE_MIDI_C2 36 +#define EVE_MIDI_C_2 37 +#define EVE_MIDI_D2 38 +#define EVE_MIDI_D_2 39 +#define EVE_MIDI_E2 40 +#define EVE_MIDI_F2 41 +#define EVE_MIDI_F_2 42 +#define EVE_MIDI_G2 43 +#define EVE_MIDI_G_2 44 +#define EVE_MIDI_A2 45 +#define EVE_MIDI_A_2 46 +#define EVE_MIDI_B2 47 +#define EVE_MIDI_C3 48 +#define EVE_MIDI_C_3 49 +#define EVE_MIDI_D3 50 +#define EVE_MIDI_D_3 51 +#define EVE_MIDI_E3 52 +#define EVE_MIDI_F3 53 +#define EVE_MIDI_F_3 54 +#define EVE_MIDI_G3 55 +#define EVE_MIDI_G_3 56 +#define EVE_MIDI_A3 57 +#define EVE_MIDI_A_3 58 +#define EVE_MIDI_B3 59 +#define EVE_MIDI_C4 60 +#define EVE_MIDI_C_4 61 +#define EVE_MIDI_D4 62 +#define EVE_MIDI_D_4 63 +#define EVE_MIDI_E4 64 +#define EVE_MIDI_F4 65 +#define EVE_MIDI_F_4 66 +#define EVE_MIDI_G4 67 +#define EVE_MIDI_G_4 68 +#define EVE_MIDI_A4 69 +#define EVE_MIDI_A_4 70 +#define EVE_MIDI_B4 71 +#define EVE_MIDI_C5 72 +#define EVE_MIDI_C_5 73 +#define EVE_MIDI_D5 74 +#define EVE_MIDI_D_5 75 +#define EVE_MIDI_E5 76 +#define EVE_MIDI_F5 77 +#define EVE_MIDI_F_5 78 +#define EVE_MIDI_G5 79 +#define EVE_MIDI_G_5 80 +#define EVE_MIDI_A5 81 +#define EVE_MIDI_A_5 82 +#define EVE_MIDI_B5 83 +#define EVE_MIDI_C6 84 +#define EVE_MIDI_C_6 85 +#define EVE_MIDI_D6 86 +#define EVE_MIDI_D_6 87 +#define EVE_MIDI_E6 88 +#define EVE_MIDI_F6 89 +#define EVE_MIDI_F_6 90 +#define EVE_MIDI_G6 91 +#define EVE_MIDI_G_6 92 +#define EVE_MIDI_A6 93 +#define EVE_MIDI_A_6 94 +#define EVE_MIDI_B6 95 +#define EVE_MIDI_C7 96 +#define EVE_MIDI_C_7 97 +#define EVE_MIDI_D7 98 +#define EVE_MIDI_D_7 99 +#define EVE_MIDI_E7 100 +#define EVE_MIDI_F7 101 +#define EVE_MIDI_F_7 102 +#define EVE_MIDI_G7 103 +#define EVE_MIDI_G_7 104 +#define EVE_MIDI_A7 105 +#define EVE_MIDI_A_7 106 +#define EVE_MIDI_B7 107 +#define EVE_MIDI_C8 108 + + +/* GPIO bits */ +#define EVE_GPIO0 0 +#define EVE_GPIO1 1 /* default gpio pin for audio shutdown, 1 - enable, 0 - disable */ +#define EVE_GPIO7 7 /* default gpio pin for display enable, 1 - enable, 0 - disable */ + + +/* Display rotation */ +#define EVE_DISPLAY_0 0 /* 0 degrees rotation */ +#define EVE_DISPLAY_180 1 /* 180 degrees rotation */ + + +/* commands common to EVE/EVE2/EVE3 */ +#define CMD_APPEND 0xFFFFFF1E +#define CMD_BGCOLOR 0xFFFFFF09 +#define CMD_BUTTON 0xFFFFFF0D +#define CMD_CALIBRATE 0xFFFFFF15 +#define CMD_CLOCK 0xFFFFFF14 +#define CMD_COLDSTART 0xFFFFFF32 +#define CMD_DIAL 0xFFFFFF2D +#define CMD_DLSTART 0xFFFFFF00 +#define CMD_FGCOLOR 0xFFFFFF0A +#define CMD_GAUGE 0xFFFFFF13 +#define CMD_GETMATRIX 0xFFFFFF33 +#define CMD_GETPROPS 0xFFFFFF25 +#define CMD_GETPTR 0xFFFFFF23 +#define CMD_GRADCOLOR 0xFFFFFF34 +#define CMD_GRADIENT 0xFFFFFF0B +#define CMD_INFLATE 0xFFFFFF22 +#define CMD_INTERRUPT 0xFFFFFF02 +#define CMD_KEYS 0xFFFFFF0E +#define CMD_LOADIDENTITY 0xFFFFFF26 +#define CMD_LOADIMAGE 0xFFFFFF24 +#define CMD_LOGO 0xFFFFFF31 +#define CMD_MEMCPY 0xFFFFFF1D +#define CMD_MEMCRC 0xFFFFFF18 +#define CMD_MEMSET 0xFFFFFF1B +#define CMD_MEMWRITE 0xFFFFFF1A +#define CMD_MEMZERO 0xFFFFFF1C +#define CMD_NUMBER 0xFFFFFF2E +#define CMD_PROGRESS 0xFFFFFF0F +#define CMD_REGREAD 0xFFFFFF19 +#define CMD_ROTATE 0xFFFFFF29 +#define CMD_SCALE 0xFFFFFF28 +#define CMD_SCREENSAVER 0xFFFFFF2F +#define CMD_SCROLLBAR 0xFFFFFF11 +#define CMD_SETFONT 0xFFFFFF2B +#define CMD_SETMATRIX 0xFFFFFF2A +#define CMD_SKETCH 0xFFFFFF30 +#define CMD_SLIDER 0xFFFFFF10 +#define CMD_SNAPSHOT 0xFFFFFF1F +#define CMD_SPINNER 0xFFFFFF16 +#define CMD_STOP 0xFFFFFF17 +#define CMD_SWAP 0xFFFFFF01 +#define CMD_TEXT 0xFFFFFF0C +#define CMD_TOGGLE 0xFFFFFF12 +#define CMD_TRACK 0xFFFFFF2C +#define CMD_TRANSLATE 0xFFFFFF27 + + +/* the following are undocumented commands that therefore should not be used */ +#if 0 +#define CMD_CRC 0xFFFFFF03 +#define CMD_HAMMERAUX 0xFFFFFF04 +#define CMD_MARCH 0xFFFFFF05 +#define CMD_IDCT 0xFFFFFF06 +#define CMD_EXECUTE 0xFFFFFF07 +#define CMD_GETPOINT 0xFFFFFF08 +#define CMD_TOUCH_TRANSFORM 0xFFFFFF20 +#endif + + +/* FT8xx graphics engine specific macros useful for static display list generation */ +#define ALPHA_FUNC(func,ref) ((9UL<<24)|(((func)&7UL)<<8)|(((ref)&255UL)<<0)) +#define BEGIN(prim) ((31UL<<24)|(((prim)&15UL)<<0)) +#define BITMAP_HANDLE(handle) ((5UL<<24)|(((handle)&31UL)<<0)) +#define BITMAP_LAYOUT(format,linestride,height) ((7UL<<24)|(((format)&31UL)<<19)|(((linestride)&1023UL)<<9)|(((height)&511UL)<<0)) +#define BITMAP_SIZE(filter,wrapx,wrapy,width,height) ((8UL<<24)|(((filter)&1UL)<<20)|(((wrapx)&1UL)<<19)|(((wrapy)&1UL)<<18)|(((width)&511UL)<<9)|(((height)&511UL)<<0)) +#define BITMAP_TRANSFORM_A(a) ((21UL<<24)|(((a)&131071UL)<<0)) +#define BITMAP_TRANSFORM_B(b) ((22UL<<24)|(((b)&131071UL)<<0)) +#define BITMAP_TRANSFORM_C(c) ((23UL<<24)|(((c)&16777215UL)<<0)) +#define BITMAP_TRANSFORM_D(d) ((24UL<<24)|(((d)&131071UL)<<0)) +#define BITMAP_TRANSFORM_E(e) ((25UL<<24)|(((e)&131071UL)<<0)) +#define BITMAP_TRANSFORM_F(f) ((26UL<<24)|(((f)&16777215UL)<<0)) +#define BLEND_FUNC(src,dst) ((11UL<<24)|(((src)&7UL)<<3)|(((dst)&7UL)<<0)) +#define CALL(dest) ((29UL<<24)|(((dest)&65535UL)<<0)) +#define CELL(cell) ((6UL<<24)|(((cell)&127UL)<<0)) +#define CLEAR(c,s,t) ((38UL<<24)|(((c)&1UL)<<2)|(((s)&1UL)<<1)|(((t)&1UL)<<0)) +#define CLEAR_COLOR_A(alpha) ((15UL<<24)|(((alpha)&255UL)<<0)) +#define CLEAR_COLOR_RGB(red,green,blue) ((2UL<<24)|(((red)&255UL)<<16)|(((green)&255UL)<<8)|(((blue)&255UL)<<0)) +#define CLEAR_STENCIL(s) ((17UL<<24)|(((s)&255UL)<<0)) +#define CLEAR_TAG(s) ((18UL<<24)|(((s)&255UL)<<0)) +#define COLOR_A(alpha) ((16UL<<24)|(((alpha)&255UL)<<0)) +#define COLOR_MASK(r,g,b,a) ((32UL<<24)|(((r)&1UL)<<3)|(((g)&1UL)<<2)|(((b)&1UL)<<1)|(((a)&1UL)<<0)) +#define COLOR_RGB(red,green,blue) ((4UL<<24)|(((red)&255UL)<<16)|(((green)&255UL)<<8)|(((blue)&255UL)<<0)) +/* #define DISPLAY() ((0UL<<24)) */ +#define END() ((33UL<<24)) +#define JUMP(dest) ((30UL<<24)|(((dest)&65535UL)<<0)) +#define LINE_WIDTH(width) ((14UL<<24)|(((width)&4095UL)<<0)) +#define MACRO(m) ((37UL<<24)|(((m)&1UL)<<0)) +#define POINT_SIZE(size) ((13UL<<24)|(((size)&8191UL)<<0)) +#define RESTORE_CONTEXT() ((35UL<<24)) +#define RETURN() ((36UL<<24)) +#define SAVE_CONTEXT() ((34UL<<24)) +#define STENCIL_FUNC(func,ref,mask) ((10UL<<24)|(((func)&7UL)<<16)|(((ref)&255UL)<<8)|(((mask)&255UL)<<0)) +#define STENCIL_MASK(mask) ((19UL<<24)|(((mask)&255UL)<<0)) +#define STENCIL_OP(sfail,spass) ((12UL<<24)|(((sfail)&7UL)<<3)|(((spass)&7UL)<<0)) +#define TAG(s) ((3UL<<24)|(((s)&255UL)<<0)) +#define TAG_MASK(mask) ((20UL<<24)|(((mask)&1UL)<<0)) +#define VERTEX2F(x,y) ((1UL<<30)|(((x)&32767UL)<<15)|(((y)&32767UL)<<0)) +#define VERTEX2II(x,y,handle,cell) ((2UL<<30)|(((x)&511UL)<<21)|(((y)&511UL)<<12)|(((handle)&31UL)<<7)|(((cell)&127UL)<<0)) + + +/* ----------------- BT81x exclusive definitions -----------------*/ +#if defined (BT81X_ENABLE) + +#define EVE_GLFORMAT 31UL /* used with BITMAP_LAYOUT to indicate bitmap-format is specified by BITMAP_EXT_FORMAT */ + +#define DL_BITMAP_EXT_FORMAT 0x2E000000 /* requires OR'd arguments */ + +/* extended Bitmap formats */ +#define EVE_COMPRESSED_RGBA_ASTC_4x4_KHR 37808UL +#define EVE_COMPRESSED_RGBA_ASTC_5x4_KHR 37809UL +#define EVE_COMPRESSED_RGBA_ASTC_5x5_KHR 37810UL +#define EVE_COMPRESSED_RGBA_ASTC_6x5_KHR 37811UL +#define EVE_COMPRESSED_RGBA_ASTC_6x6_KHR 37812UL +#define EVE_COMPRESSED_RGBA_ASTC_8x5_KHR 37813UL +#define EVE_COMPRESSED_RGBA_ASTC_8x6_KHR 37814UL +#define EVE_COMPRESSED_RGBA_ASTC_8x8_KHR 37815UL +#define EVE_COMPRESSED_RGBA_ASTC_10x5_KHR 37816UL +#define EVE_COMPRESSED_RGBA_ASTC_10x6_KHR 37817UL +#define EVE_COMPRESSED_RGBA_ASTC_10x8_KHR 37818UL +#define EVE_COMPRESSED_RGBA_ASTC_10x10_KHR 37819UL +#define EVE_COMPRESSED_RGBA_ASTC_12x10_KHR 37820UL +#define EVE_COMPRESSED_RGBA_ASTC_12x12_KHR 37821UL + + +#define EVE_RAM_ERR_REPORT 0x309800UL /* max 128 bytes null terminated string */ +#define EVE_RAM_FLASH 0x800000UL +#define EVE_RAM_FLASH_POSTBLOB 0x801000UL + +#define EVE_OPT_FLASH 64UL +#define EVE_OPT_FORMAT 4096UL +#define EVE_OPT_FILL 8192UL + + +/* additional commands for BT81x */ +#define CMD_BITMAP_TRANSFORM 0xFFFFFF21 +#define CMD_SYNC 0xFFFFFF42 /* does not need a dedicated function, just use EVE_cmd_dl(CMD_SYNC) */ +#define CMD_FLASHERASE 0xFFFFFF44 /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHERASE) */ +#define CMD_FLASHWRITE 0xFFFFFF45 +#define CMD_FLASHREAD 0xFFFFFF46 +#define CMD_FLASHUPDATE 0xFFFFFF47 +#define CMD_FLASHDETACH 0xFFFFFF48 /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHDETACH) */ +#define CMD_FLASHATTACH 0xFFFFFF49 /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHATTACH) */ +#define CMD_FLASHFAST 0xFFFFFF4A +#define CMD_FLASHSPIDESEL 0xFFFFFF4B /* does not need a dedicated function, just use EVE_cmd_dl(CMD_FLASHSPIDESEL) */ +#define CMD_FLASHSPITX 0xFFFFFF4C +#define CMD_FLASHSPIRX 0xFFFFFF4D +#define CMD_FLASHSOURCE 0xFFFFFF4E +#define CMD_CLEARCACHE 0xFFFFFF4F /* does not need a dedicated function, just use EVE_cmd_dl(CMD_CLEARCACHE) */ +#define CMD_INFLATE2 0xFFFFFF50 +#define CMD_ROTATEAROUND 0xFFFFFF51 +#define CMD_RESETFONTS 0xFFFFFF52 /* does not need a dedicated function, just use EVE_cmd_dl(CMD_RESETFONTS) */ +#define CMD_ANIMSTART 0xFFFFFF53 +#define CMD_ANIMSTOP 0xFFFFFF54 +#define CMD_ANIMXY 0xFFFFFF55 +#define CMD_ANIMDRAW 0xFFFFFF56 +#define CMD_GRADIENTA 0xFFFFFF57 +#define CMD_FILLWIDTH 0xFFFFFF58 +#define CMD_APPENDF 0xFFFFFF59 +#define CMD_ANIMFRAME 0xFFFFFF5A +#define CMD_VIDEOSTARTF 0xFFFFFF5F /* does not need a dedicated function, just use EVE_cmd_dl(CMD_VIDEOSTARTF) */ + +#if 0 +/* some undocumented commands for BT81x */ +#define CMD_NOP 0xFFFFFF5B +#define CMD_SHA1 0xFFFFFF5C +#define CMD_HMAC 0xFFFFFF5D +#define CMD_LAST_ 0xFFFFFF5E + +#endif + + +/* additional registers for BT81x */ +#define REG_ADAPTIVE_FRAMERATE 0x30257cUL +#define REG_PLAYBACK_PAUSE 0x3025ecUL +#define REG_FLASH_STATUS 0x3025f0UL +#define REG_FLASH_SIZE 0x309024UL +#define REG_PLAY_CONTROL 0x30914eUL +#define REG_COPRO_PATCH_DTR 0x309162UL + + +/* BT81x graphics engine specific macros */ +#define BITMAP_EXT_FORMAT(format) ((46UL<<24)|(((format)&65535UL)<<0)) +#define BITMAP_SWIZZLE(r,g,b,a) ((47UL<<24)|(((r)&7UL)<<9)|(((g)&7UL)<<6)|(((b)&7UL)<<3)|(((a)&7UL)<<0)) +#define BITMAP_SOURCE2(flash_or_ram, addr) ((1UL<<24)|((flash_or_ram) << 23)|(((addr)&8388607UL)<<0)) +#define INT_FRR() ((48UL<<24)) + +#undef BITMAP_TRANSFORM_A +#undef BITMAP_TRANSFORM_B +#undef BITMAP_TRANSFORM_D +#undef BITMAP_TRANSFORM_E + +#define BITMAP_TRANSFORM_A_EXT(p,v) ((21UL<<24)|(((p)&1UL)<<17)|(((v)&131071UL)<<0)) +#define BITMAP_TRANSFORM_B_EXT(p,v) ((22UL<<24)|(((p)&1UL)<<17)|(((v)&131071UL)<<0)) +#define BITMAP_TRANSFORM_D_EXT(p,v) ((24UL<<24)|(((p)&1UL)<<17)|(((v)&131071UL)<<0)) +#define BITMAP_TRANSFORM_E_EXT(p,v) ((25UL<<24)|(((p)&1UL)<<17)|(((v)&131071UL)<<0)) + +#define BITMAP_TRANSFORM_A(a) BITMAP_TRANSFORM_A_EXT(0,a) +#define BITMAP_TRANSFORM_B(b) BITMAP_TRANSFORM_B_EXT(0,b) +#define BITMAP_TRANSFORM_D(d) BITMAP_TRANSFORM_D_EXT(0,d) +#define BITMAP_TRANSFORM_E(e) BITMAP_TRANSFORM_E_EXT(0,e) + +#endif + +/* ----------------- FT81x / BT81x exclusive definitions -----------------*/ +#if defined (FT81X_ENABLE) + + +/* Host commands */ +#define EVE_CLKSEL 0x61 /* configure system clock */ +#define EVE_RST_PULSE 0x68 /* reset core - all registers default and processors reset */ +#define EVE_PINDRIVE 0x70 /* setup drive strength for various pins */ +#define EVE_PIN_PD_STATE 0x71 /* setup how pins behave during power down */ + + +/* Memory definitions */ +#define EVE_RAM_G 0x000000UL +#define EVE_ROM_CHIPID 0x0C0000UL +#define EVE_ROM_FONT 0x1E0000UL +#define EVE_ROM_FONT_ADDR 0x2FFFFCUL +#define EVE_RAM_DL 0x300000UL +#define EVE_RAM_REG 0x302000UL +#define EVE_RAM_CMD 0x308000UL + + +/* Memory buffer sizes */ +#define EVE_RAM_G_SIZE 1024*1024L +#define EVE_CMDFIFO_SIZE 4*1024L +#define EVE_RAM_DL_SIZE 8*1024L + + +/* various additional defines for FT81x */ +#define EVE_ADC_DIFFERENTIAL 1UL +#define EVE_ADC_SINGLE_ENDED 0UL + +#define EVE_INT_G8 18UL +#define EVE_INT_L8C 12UL +#define EVE_INT_VGA 13UL + +#define EVE_OPT_MEDIAFIFO 16UL +#define EVE_OPT_FULLSCREEN 8UL +#define EVE_OPT_NOTEAR 4UL +#define EVE_OPT_SOUND 32UL + +#define EVE_PALETTED565 14UL +#define EVE_PALETTED4444 15UL +#define EVE_PALETTED8 16UL +#define EVE_L2 17UL + + +/* additional commands for FT81x */ +#define CMD_MEDIAFIFO 0xFFFFFF39 +#define CMD_PLAYVIDEO 0xFFFFFF3A +#define CMD_ROMFONT 0xFFFFFF3F +#define CMD_SETBASE 0xFFFFFF38 +#define CMD_SETBITMAP 0xFFFFFF43 +#define CMD_SETFONT2 0xFFFFFF3B +#define CMD_SETROTATE 0xFFFFFF36 +#define CMD_SETSCRATCH 0xFFFFFF3C +#define CMD_SNAPSHOT2 0xFFFFFF37 +#define CMD_VIDEOFRAME 0xFFFFFF41 +#define CMD_VIDEOSTART 0xFFFFFF40 + + +/* the following are undocumented commands that therefore should not be used */ +#if 0 +#define CMD_CSKETCH 0xFFFFFF35 +#define CMD_INT_RAMSHARED 0xFFFFFF3D +#define CMD_INT_SWLOADIMAGE 0xFFFFFF3E +#endif + + +/* Register definitions */ +#define REG_ANA_COMP 0x302184UL /* only listed in datasheet */ +#define REG_BIST_EN 0x302174UL /* only listed in datasheet */ +#define REG_CLOCK 0x302008UL +#define REG_CMDB_SPACE 0x302574UL +#define REG_CMDB_WRITE 0x302578UL +#define REG_CMD_DL 0x302100UL +#define REG_CMD_READ 0x3020f8UL +#define REG_CMD_WRITE 0x3020fcUL +#define REG_CPURESET 0x302020UL +#define REG_CSPREAD 0x302068UL +#define REG_CTOUCH_EXTENDED 0x302108UL +#define REG_CTOUCH_TOUCH0_XY 0x302124UL /* only listed in datasheet */ +#define REG_CTOUCH_TOUCH4_X 0x30216cUL +#define REG_CTOUCH_TOUCH4_Y 0x302120UL +#define REG_CTOUCH_TOUCH1_XY 0x30211cUL +#define REG_CTOUCH_TOUCH2_XY 0x30218cUL +#define REG_CTOUCH_TOUCH3_XY 0x302190UL +#define REG_TOUCH_CONFIG 0x302168UL +#define REG_DATESTAMP 0x302564UL /* only listed in datasheet */ +#define REG_DITHER 0x302060UL +#define REG_DLSWAP 0x302054UL +#define REG_FRAMES 0x302004UL +#define REG_FREQUENCY 0x30200cUL +#define REG_GPIO 0x302094UL +#define REG_GPIOX 0x30209cUL +#define REG_GPIOX_DIR 0x302098UL +#define REG_GPIO_DIR 0x302090UL +#define REG_HCYCLE 0x30202cUL +#define REG_HOFFSET 0x302030UL +#define REG_HSIZE 0x302034UL +#define REG_HSYNC0 0x302038UL +#define REG_HSYNC1 0x30203cUL +#define REG_ID 0x302000UL +#define REG_INT_EN 0x3020acUL +#define REG_INT_FLAGS 0x3020a8UL +#define REG_INT_MASK 0x3020b0UL +#define REG_MACRO_0 0x3020d8UL +#define REG_MACRO_1 0x3020dcUL +#define REG_MEDIAFIFO_READ 0x309014UL /* only listed in programmers guide */ +#define REG_MEDIAFIFO_WRITE 0x309018UL /* only listed in programmers guide */ +#define REG_OUTBITS 0x30205cUL +#define REG_PCLK 0x302070UL +#define REG_PCLK_POL 0x30206cUL +#define REG_PLAY 0x30208cUL +#define REG_PLAYBACK_FORMAT 0x3020c4UL +#define REG_PLAYBACK_FREQ 0x3020c0UL +#define REG_PLAYBACK_LENGTH 0x3020b8UL +#define REG_PLAYBACK_LOOP 0x3020c8UL +#define REG_PLAYBACK_PLAY 0x3020ccUL +#define REG_PLAYBACK_READPTR 0x3020bcUL +#define REG_PLAYBACK_START 0x3020b4UL +#define REG_PWM_DUTY 0x3020d4UL +#define REG_PWM_HZ 0x3020d0UL +#define REG_RENDERMODE 0x302010UL /* only listed in datasheet */ +#define REG_ROTATE 0x302058UL +#define REG_SNAPFORMAT 0x30201cUL /* only listed in datasheet */ +#define REG_SNAPSHOT 0x302018UL /* only listed in datasheet */ +#define REG_SNAPY 0x302014UL /* only listed in datasheet */ +#define REG_SOUND 0x302088UL +#define REG_SPI_WIDTH 0x302188UL /* listed with false offset in programmers guide V1.1 */ +#define REG_SWIZZLE 0x302064UL +#define REG_TAG 0x30207cUL +#define REG_TAG_X 0x302074UL +#define REG_TAG_Y 0x302078UL +#define REG_TAP_CRC 0x302024UL /* only listed in datasheet */ +#define REG_TAP_MASK 0x302028UL /* only listed in datasheet */ +#define REG_TOUCH_ADC_MODE 0x302108UL +#define REG_TOUCH_CHARGE 0x30210cUL +#define REG_TOUCH_DIRECT_XY 0x30218cUL +#define REG_TOUCH_DIRECT_Z1Z2 0x302190UL +#define REG_TOUCH_MODE 0x302104UL +#define REG_TOUCH_OVERSAMPLE 0x302114UL +#define REG_TOUCH_RAW_XY 0x30211cUL +#define REG_TOUCH_RZ 0x302120UL +#define REG_TOUCH_RZTHRESH 0x302118UL +#define REG_TOUCH_SCREEN_XY 0x302124UL +#define REG_TOUCH_SETTLE 0x302110UL +#define REG_TOUCH_TAG 0x30212cUL +#define REG_TOUCH_TAG1 0x302134UL /* only listed in datasheet */ +#define REG_TOUCH_TAG1_XY 0x302130UL /* only listed in datasheet */ +#define REG_TOUCH_TAG2 0x30213cUL /* only listed in datasheet */ +#define REG_TOUCH_TAG2_XY 0x302138UL /* only listed in datasheet */ +#define REG_TOUCH_TAG3 0x302144UL /* only listed in datasheet */ +#define REG_TOUCH_TAG3_XY 0x302140UL /* only listed in datasheet */ +#define REG_TOUCH_TAG4 0x30214cUL /* only listed in datasheet */ +#define REG_TOUCH_TAG4_XY 0x302148UL /* only listed in datasheet */ +#define REG_TOUCH_TAG_XY 0x302128UL +#define REG_TOUCH_TRANSFORM_A 0x302150UL +#define REG_TOUCH_TRANSFORM_B 0x302154UL +#define REG_TOUCH_TRANSFORM_C 0x302158UL +#define REG_TOUCH_TRANSFORM_D 0x30215cUL +#define REG_TOUCH_TRANSFORM_E 0x302160UL +#define REG_TOUCH_TRANSFORM_F 0x302164UL +#define REG_TRACKER 0x309000UL /* only listed in programmers guide */ +#define REG_TRACKER_1 0x309004UL /* only listed in programmers guide */ +#define REG_TRACKER_2 0x309008UL /* only listed in programmers guide */ +#define REG_TRACKER_3 0x30900cUL /* only listed in programmers guide */ +#define REG_TRACKER_4 0x309010UL /* only listed in programmers guide */ +#define REG_TRIM 0x302180UL +#define REG_VCYCLE 0x302040UL +#define REG_VOFFSET 0x302044UL +#define REG_VOL_PB 0x302080UL +#define REG_VOL_SOUND 0x302084UL +#define REG_VSIZE 0x302048UL +#define REG_VSYNC0 0x30204cUL +#define REG_VSYNC1 0x302050UL + +#if 0 +#define REG_BUSYBITS 0x3020e8UL /* only listed as "reserved" in datasheet */ +#define REG_CRC 0x302178UL /* only listed as "reserved" in datasheet */ +#define REG_SPI_EARLY_TX 0x30217cUL /* only listed as "reserved" in datasheet */ +#define REG_ROMSUB_SEL 0x3020f0UL /* only listed as "reserved" in datasheet */ +#define REG_TOUCH_FAULT 0x302170UL /* only listed as "reserved" in datasheet */ +#endif + + +/* FT81x graphics engine specific macros useful for static display list generation */ + +/* beware, these are different to FTDIs implementation as these take the original values as parameters and not only the upper bits */ +#define BITMAP_LAYOUT_H(linestride,height) ((40UL<<24)|((((linestride&0xC00)>>10)&3UL)<<2)|((((height&0x600)>>9)&3UL)<<0)) +#define BITMAP_SIZE_H(width,height) ((41UL<<24)|((((width&0x600)>>9)&3UL)<<2)|((((height&0x600)>>9)&3UL)<<0)) + +#define BITMAP_SOURCE(addr) ((1UL<<24)|(((addr)&4194303UL)<<0)) +//#define NOP() ((45UL<<24)) +#define PALETTE_SOURCE(addr) ((42UL<<24)|(((addr)&4194303UL)<<0)) +#define SCISSOR_SIZE(width,height) ((28UL<<24)|(((width)&4095UL)<<12)|(((height)&4095UL)<<0)) +#define SCISSOR_XY(x,y) ((27UL<<24)|(((x)&2047UL)<<11)|(((y)&2047UL)<<0)) +#define VERTEX_FORMAT(frac) ((39UL<<24)|(((frac)&7UL)<<0)) +#define VERTEX_TRANSLATE_X(x) ((43UL<<24)|(((x)&131071UL)<<0)) +#define VERTEX_TRANSLATE_Y(y) ((44UL<<24)|(((y)&131071UL)<<0)) + + + +/* ----------------- FT80x exclusive definitions -----------------*/ +#else + +/* Memory definitions */ +#define EVE_RAM_G 0x000000UL +#define EVE_ROM_CHIPID 0x0C0000UL +#define EVE_ROM_FONT 0x0BB23CUL +#define EVE_ROM_FONT_ADDR 0x0FFFFCUL +#define EVE_RAM_DL 0x100000UL +#define EVE_RAM_PAL 0x102000UL +#define EVE_RAM_CMD 0x108000UL +#define EVE_RAM_SCREENSHOT 0x1C2000UL + + +/* Memory buffer sizes */ +#define EVE_RAM_G_SIZE 256*1024L +#define EVE_CMDFIFO_SIZE 4*1024L +#define EVE_RAM_DL_SIZE 8*1024L +#define EVE_RAM_PAL_SIZE 1*1024L + + +/* Register definitions */ +#define REG_ID 0x102400UL +#define REG_FRAMES 0x102404UL +#define REG_CLOCK 0x102408UL +#define REG_FREQUENCY 0x10240CUL +#define REG_SCREENSHOT_EN 0x102410UL +#define REG_SCREENSHOT_Y 0x102414UL +#define REG_SCREENSHOT_START 0x102418UL +#define REG_CPURESET 0x10241CUL +#define REG_TAP_CRC 0x102420UL +#define REG_TAP_MASK 0x102424UL +#define REG_HCYCLE 0x102428UL +#define REG_HOFFSET 0x10242CUL +#define REG_HSIZE 0x102430UL +#define REG_HSYNC0 0x102434UL +#define REG_HSYNC1 0x102438UL +#define REG_VCYCLE 0x10243CUL +#define REG_VOFFSET 0x102440UL +#define REG_VSIZE 0x102444UL +#define REG_VSYNC0 0x102448UL +#define REG_VSYNC1 0x10244CUL +#define REG_DLSWAP 0x102450UL +#define REG_ROTATE 0x102454UL +#define REG_OUTBITS 0x102458UL +#define REG_DITHER 0x10245CUL +#define REG_SWIZZLE 0x102460UL +#define REG_CSPREAD 0x102464UL +#define REG_PCLK_POL 0x102468UL +#define REG_PCLK 0x10246CUL +#define REG_TAG_X 0x102470UL +#define REG_TAG_Y 0x102474UL +#define REG_TAG 0x102478UL +#define REG_VOL_PB 0x10247CUL +#define REG_VOL_SOUND 0x102480UL +#define REG_SOUND 0x102484UL +#define REG_PLAY 0x102488UL +#define REG_GPIO_DIR 0x10248CUL +#define REG_GPIO 0x102490UL +#define REG_INT_FLAGS 0x102498UL +#define REG_INT_EN 0x10249CUL +#define REG_INT_MASK 0x1024A0UL +#define REG_PLAYBACK_START 0x1024A4UL +#define REG_PLAYBACK_LENGTH 0x1024A8UL +#define REG_PLAYBACK_READPTR 0x1024ACUL +#define REG_PLAYBACK_FREQ 0x1024B0UL +#define REG_PLAYBACK_FORMAT 0x1024B4UL +#define REG_PLAYBACK_LOOP 0x1024B8UL +#define REG_PLAYBACK_PLAY 0x1024BCUL +#define REG_PWM_HZ 0x1024C0UL +#define REG_PWM_DUTY 0x1024C4UL +#define REG_MACRO_0 0x1024C8UL +#define REG_MACRO_1 0x1024CCUL +#define REG_SCREENSHOT_BUSY 0x1024D8UL +#define REG_CMD_READ 0x1024E4UL +#define REG_CMD_WRITE 0x1024E8UL +#define REG_CMD_DL 0x1024ECUL +#define REG_TOUCH_MODE 0x1024F0UL +#define REG_TOUCH_ADC_MODE 0x1024F4UL +#define REG_TOUCH_CHARGE 0x1024F8UL +#define REG_TOUCH_SETTLE 0x1024FCUL +#define REG_TOUCH_OVERSAMPLE 0x102500UL +#define REG_TOUCH_RZTHRESH 0x102504UL +#define REG_TOUCH_RAW_XY 0x102508UL +#define REG_TOUCH_RZ 0x10250CUL +#define REG_TOUCH_SCREEN_XY 0x102510UL +#define REG_TOUCH_TAG_XY 0x102514UL +#define REG_TOUCH_TAG 0x102518UL +#define REG_TOUCH_TRANSFORM_A 0x10251CUL +#define REG_TOUCH_TRANSFORM_B 0x102520UL +#define REG_TOUCH_TRANSFORM_C 0x102524UL +#define REG_TOUCH_TRANSFORM_D 0x102528UL +#define REG_TOUCH_TRANSFORM_E 0x10252CUL +#define REG_TOUCH_TRANSFORM_F 0x102530UL +#define REG_SCREENSHOT_READ 0x102554UL +#define REG_TRIM 0x10256CUL +#define REG_TOUCH_DIRECT_XY 0x102574UL +#define REG_TOUCH_DIRECT_Z1Z2 0x102578UL +#define REG_TRACKER 0x109000UL + +/* FT80x graphics engine specific macros useful for static display list generation */ +#define BITMAP_SOURCE(addr) ((1UL<<24)|(((addr)&1048575UL)<<0)) +#define SCISSOR_SIZE(width,height) ((28UL<<24)|(((width)&1023UL)<<10)|(((height)&1023UL)<<0)) +#define SCISSOR_XY(x,y) ((27UL<<24)|(((x)&511UL)<<9)|(((y)&511UL)<<0)) + +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_FT81X_DEFINES_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 78e90306b..90fe5dafa 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 @@ -84,10 +84,11 @@ void lv_ili9341_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list); * MACROS **********************/ + +#endif /*LV_USE_ILI9341*/ + #ifdef __cplusplus } /*extern "C"*/ #endif -#endif /*LV_USE_ILI9341*/ - -#endif /* LV_ILI9341_H */ +#endif /*LV_ILI9341_H*/ 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 e27e4c860..f589ce9df 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 @@ -160,6 +160,7 @@ static void send_color(lv_lcd_generic_mipi_driver_t * drv, uint8_t cmd, uint8_t { uint8_t cmdbuf = cmd; /* MIPI uses 8 bit commands */ drv->send_color(drv->disp, &cmdbuf, 1, param, param_size); + /* note: LVGL waits for your callback to call `lv_display_flush_ready` to know when the transfer has finished. */ } /** 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 8daa5e044..4c1422b52 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 @@ -179,7 +179,8 @@ typedef struct { * @param ver_res vertical resolution * @param flags default configuration settings (mirror, RGB ordering, etc.) * @param send_cmd platform-dependent function to send a command to the LCD controller (usually uses polling transfer) - * @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer: must implement a 'ready' callback) + * @param send_color platform-dependent function to send pixel data to the LCD controller (usually uses DMA transfer). + * `lv_display_flush_ready` must be called after the transfer has finished. * @return pointer to the created display */ lv_display_t * lv_lcd_generic_mipi_create(uint32_t hor_res, uint32_t ver_res, lv_lcd_flag_t flags, @@ -232,10 +233,11 @@ void lv_lcd_generic_mipi_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_ * MACROS **********************/ + +#endif /*LV_USE_GENERIC_MIPI*/ + #ifdef __cplusplus } /*extern "C"*/ #endif -#endif /*LV_USE_GENERIC_MIPI*/ - -#endif /* LV_LCD_GENERIC_MIPI_H */ +#endif /*LV_LCD_GENERIC_MIPI_H*/ 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 index 15b67846d..7e55799ad 100644 --- 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 @@ -14,8 +14,9 @@ #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 + #define DISPLAY_HSIZE_INPUT0 LCD_CH0_IN_GR2_HSIZE + #define DISPLAY_VSIZE_INPUT0 LCD_CH0_IN_GR2_VSIZE + #define DISPLAY_BUFFER_STRIDE_BYTES_INPUT0 LCD_CH0_IN_GR2_LINEOFFSET #endif /*_RENESAS_RA_*/ /********************* @@ -165,7 +166,7 @@ static lv_display_t * glcdc_create(void * buf1, void * buf2, uint32_t buf_size, LV_ASSERT(0); } - lv_display_set_buffers(display, buf1, buf2, buf_size, render_mode); + lv_display_set_buffers_with_stride(display, buf1, buf2, buf_size, DISPLAY_BUFFER_STRIDE_BYTES_INPUT0, render_mode); return display; } 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 index 0558614e5..bb8abefc5 100644 --- 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 @@ -30,13 +30,13 @@ extern "C" { **********************/ /** - * Create a display using Renesas' GLCDC peripherial in DIRECT render mode + * Create a display using Renesas' GLCDC peripheral 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 + * Create a display using Renesas' GLCDC peripheral in PARTIAL render mode * @param buf1 first buffer * @param buf2 second buffer (can be `NULL`) * @param buf_size buffer size in byte 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 72dd1a94c..c19e9fad1 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 @@ -90,4 +90,4 @@ void lv_st7735_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list); } /*extern "C"*/ #endif -#endif /* LV_ST7735_H */ +#endif /*LV_ST7735_H*/ 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 5f1acada7..9770432a1 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 @@ -84,10 +84,11 @@ void lv_st7789_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list); * MACROS **********************/ + +#endif /*LV_USE_ST7789*/ + #ifdef __cplusplus } /*extern "C"*/ #endif -#endif /*LV_USE_ST7789*/ - -#endif //LV_ST7789_H +#endif /*LV_ST7789_H*/ 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 924eecb43..79d7a8834 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 @@ -84,10 +84,10 @@ void lv_st7796_send_cmd_list(lv_display_t * disp, const uint8_t * cmd_list); * MACROS **********************/ +#endif /*LV_USE_ST7796*/ + #ifdef __cplusplus } /*extern "C"*/ #endif -#endif /*LV_USE_ST7796*/ - -#endif /* LV_ST7796_H */ +#endif /*LV_ST7796_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/st_ltdc/lv_st_ltdc.c b/lib/libesp32_lvgl/lvgl/src/drivers/display/st_ltdc/lv_st_ltdc.c new file mode 100644 index 000000000..0b167f14b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/st_ltdc/lv_st_ltdc.c @@ -0,0 +1,290 @@ +/** + * @file lv_st_ltdc.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" +#if LV_USE_ST_LTDC + +#include "lv_st_ltdc.h" +#include "../../../display/lv_display_private.h" +#include "../../../draw/sw/lv_draw_sw.h" +#include "ltdc.h" + +#if LV_ST_LTDC_USE_DMA2D_FLUSH + #if LV_USE_DRAW_DMA2D + #error cannot use LV_ST_LTDC_USE_DMA2D_FLUSH with LV_USE_DRAW_DMA2D + #endif /*LV_USE_DRAW_DMA2D*/ + + #include "dma2d.h" +#endif /*LV_ST_LTDC_USE_DMA2D_FLUSH*/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +#if LV_USE_OS != LV_OS_NONE + typedef lv_thread_sync_t sync_t; +#else + typedef volatile bool sync_t; +#endif + +/********************** + * STATIC PROTOTYPES + **********************/ + +static lv_display_t * create(void * buf1, void * buf2, uint32_t buf_size, uint32_t layer_idx, + lv_display_render_mode_t mode); +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map); +static void flush_wait_cb(lv_display_t * disp); +static lv_color_format_t get_lv_cf_from_layer_cf(uint32_t cf); +static void reload_event_callback(LTDC_HandleTypeDef * hltdc); + +#if LV_ST_LTDC_USE_DMA2D_FLUSH + static void transfer_complete_callback(DMA2D_HandleTypeDef * hdma2d); + static uint32_t get_dma2d_output_cf_from_layer_cf(uint32_t cf); + static uint32_t get_dma2d_input_cf_from_lv_cf(uint32_t cf); +#endif + +/********************** + * STATIC VARIABLES + **********************/ + +static struct { + bool disp_flushed_in_flush_cb[MAX_LAYER]; + sync_t sync[MAX_LAYER]; + volatile bool layer_interrupt_is_owned[MAX_LAYER]; +#if LV_ST_LTDC_USE_DMA2D_FLUSH + volatile uint32_t dma2d_interrupt_owner; /*layer_idx + 1, or 0 for none*/ +#endif +} g_data; + +/********************** + * MACROS + **********************/ + +#if LV_USE_OS != LV_OS_NONE + #define SYNC_INIT(layer_idx) lv_thread_sync_init(&g_data.sync[layer_idx]) + #define SYNC_WAIT(layer_idx) lv_thread_sync_wait(&g_data.sync[layer_idx]) + #define SYNC_SIGNAL_ISR(layer_idx) lv_thread_sync_signal_isr(&g_data.sync[layer_idx]) +#else + #define SYNC_INIT(layer_idx) do { g_data.sync[layer_idx] = false; } while(0) + #define SYNC_WAIT(layer_idx) do { while(!g_data.sync[layer_idx]); g_data.sync[layer_idx] = false; } while(0) + #define SYNC_SIGNAL_ISR(layer_idx) do { g_data.sync[layer_idx] = true; } while(0) +#endif + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_display_t * lv_st_ltdc_create_direct(void * fb_adr_1, void * fb_adr_2, uint32_t layer_idx) +{ + return create(fb_adr_1, fb_adr_2, 0, layer_idx, LV_DISPLAY_RENDER_MODE_DIRECT); +} + +lv_display_t * lv_st_ltdc_create_partial(void * render_buf_1, void * render_buf_2, uint32_t buf_size, + uint32_t layer_idx) +{ + return create(render_buf_1, render_buf_2, buf_size, layer_idx, LV_DISPLAY_RENDER_MODE_PARTIAL); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_display_t * create(void * buf1, void * buf2, uint32_t buf_size, uint32_t layer_idx, + lv_display_render_mode_t mode) +{ + LTDC_LayerCfgTypeDef * layer_cfg = &hltdc.LayerCfg[layer_idx]; + uint32_t layer_width = layer_cfg->ImageWidth; + uint32_t layer_height = layer_cfg->ImageHeight; + uint32_t layer_cf = layer_cfg->PixelFormat; + lv_color_format_t cf = get_lv_cf_from_layer_cf(layer_cf); + + lv_display_t * disp = lv_display_create(layer_width, layer_height); + lv_display_set_color_format(disp, cf); + lv_display_set_flush_cb(disp, flush_cb); + lv_display_set_flush_wait_cb(disp, flush_wait_cb); + lv_display_set_driver_data(disp, (void *)(uintptr_t)layer_idx); + + if(mode == LV_DISPLAY_RENDER_MODE_DIRECT) { + uint32_t cf_size = lv_color_format_get_size(cf); + lv_display_set_buffers(disp, buf1, buf2, layer_width * layer_height * cf_size, LV_DISPLAY_RENDER_MODE_DIRECT); + + if(buf1 != NULL && buf2 != NULL) { + HAL_LTDC_RegisterCallback(&hltdc, HAL_LTDC_RELOAD_EVENT_CB_ID, reload_event_callback); + SYNC_INIT(layer_idx); + } + } + else { + lv_display_set_buffers(disp, buf1, buf2, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL); + +#if LV_ST_LTDC_USE_DMA2D_FLUSH + hdma2d.XferCpltCallback = transfer_complete_callback; + SYNC_INIT(layer_idx); +#endif + } + + return disp; +} + +static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map) +{ + uint32_t layer_idx = (uint32_t)(uintptr_t)lv_display_get_driver_data(disp); + g_data.disp_flushed_in_flush_cb[layer_idx] = false; + + if(disp->render_mode == LV_DISPLAY_RENDER_MODE_DIRECT) { + if(lv_display_is_double_buffered(disp) && lv_display_flush_is_last(disp)) { + HAL_LTDC_SetAddress_NoReload(&hltdc, (uint32_t)px_map, layer_idx); + g_data.layer_interrupt_is_owned[layer_idx] = true; + HAL_LTDC_Reload(&hltdc, LTDC_RELOAD_VERTICAL_BLANKING); + } + else { + g_data.disp_flushed_in_flush_cb[layer_idx] = true; + } + } + else { + LTDC_LayerCfgTypeDef * layer_cfg = &hltdc.LayerCfg[layer_idx]; + + lv_color_format_t cf = lv_display_get_color_format(disp); + int32_t disp_width = disp->hor_res; + + uint8_t * fb = (uint8_t *) layer_cfg->FBStartAdress; + uint32_t px_size = lv_color_format_get_size(cf); + uint32_t fb_stride = px_size * disp_width; + lv_area_t rotated_area = *area; + lv_display_rotate_area(disp, &rotated_area); + uint8_t * first_pixel = fb + fb_stride * rotated_area.y1 + px_size * rotated_area.x1; + + int32_t area_width = lv_area_get_width(area); + int32_t area_height = lv_area_get_height(area); + + lv_display_rotation_t rotation = lv_display_get_rotation(disp); + if(rotation == LV_DISPLAY_ROTATION_0) { +#if LV_ST_LTDC_USE_DMA2D_FLUSH + uint32_t dma2d_input_cf = get_dma2d_input_cf_from_lv_cf(cf); + uint32_t dma2d_output_cf = get_dma2d_output_cf_from_layer_cf(layer_cfg->PixelFormat); + + while(DMA2D->CR & DMA2D_CR_START); + DMA2D->FGPFCCR = dma2d_input_cf; + DMA2D->FGMAR = (uint32_t)px_map; + DMA2D->FGOR = 0; + DMA2D->OPFCCR = dma2d_output_cf; + DMA2D->OMAR = (uint32_t)first_pixel; + DMA2D->OOR = disp_width - area_width; + DMA2D->NLR = (area_width << DMA2D_NLR_PL_Pos) | (area_height << DMA2D_NLR_NL_Pos); + g_data.dma2d_interrupt_owner = layer_idx + 1; + DMA2D->CR = DMA2D_CR_START | DMA2D_CR_TCIE | (0x1U << DMA2D_CR_MODE_Pos); /* memory-to-memory with PFC */ +#else + uint32_t area_stride = px_size * area_width; + uint8_t * fb_p = first_pixel; + uint8_t * px_map_p = px_map; + for(int i = 0; i < area_height; i++) { + lv_memcpy(fb_p, px_map_p, area_stride); + fb_p += fb_stride; + px_map_p += area_stride; + } + g_data.disp_flushed_in_flush_cb[layer_idx] = true; +#endif + } + else { + uint32_t area_stride = px_size * area_width; + lv_draw_sw_rotate(px_map, first_pixel, area_width, area_height, area_stride, fb_stride, rotation, cf); + g_data.disp_flushed_in_flush_cb[layer_idx] = true; + } + } +} + +static void flush_wait_cb(lv_display_t * disp) +{ + uint32_t layer_idx = (uint32_t)(uintptr_t)lv_display_get_driver_data(disp); + if(!g_data.disp_flushed_in_flush_cb[layer_idx]) { + SYNC_WAIT(layer_idx); + } +} + +static lv_color_format_t get_lv_cf_from_layer_cf(uint32_t cf) +{ + switch(cf) { + case LTDC_PIXEL_FORMAT_ARGB8888: + return LV_COLOR_FORMAT_ARGB8888; + case LTDC_PIXEL_FORMAT_RGB888: + return LV_COLOR_FORMAT_RGB888; + case LTDC_PIXEL_FORMAT_RGB565: + return LV_COLOR_FORMAT_RGB565; + case LTDC_PIXEL_FORMAT_L8: + return LV_COLOR_FORMAT_L8; + case LTDC_PIXEL_FORMAT_AL88: + return LV_COLOR_FORMAT_AL88; + default: + LV_ASSERT_MSG(0, "the LTDC color format is not supported"); + } +} + +static void reload_event_callback(LTDC_HandleTypeDef * hltdc) +{ + uint32_t i; + for(i = 0; i < MAX_LAYER; i++) { + if(g_data.layer_interrupt_is_owned[i]) { + g_data.layer_interrupt_is_owned[i] = false; + SYNC_SIGNAL_ISR(i); + } + } +} + +#if LV_ST_LTDC_USE_DMA2D_FLUSH +static void transfer_complete_callback(DMA2D_HandleTypeDef * hdma2d) +{ + DMA2D->IFCR = 0x3FU; + uint32_t owner = g_data.dma2d_interrupt_owner; + if(owner) { + g_data.dma2d_interrupt_owner = 0; + owner -= 1; + SYNC_SIGNAL_ISR(owner); + } +} + +static uint32_t get_dma2d_output_cf_from_layer_cf(uint32_t cf) +{ + switch(cf) { + case LTDC_PIXEL_FORMAT_ARGB8888: + return DMA2D_OUTPUT_ARGB8888; + case LTDC_PIXEL_FORMAT_RGB888: + return DMA2D_OUTPUT_RGB888; + case LTDC_PIXEL_FORMAT_RGB565: + return DMA2D_OUTPUT_RGB565; + default: + LV_ASSERT_MSG(0, "DMA2D cannot output to the LTDC color format"); + } +} + +static uint32_t get_dma2d_input_cf_from_lv_cf(uint32_t cf) +{ + switch(cf) { + case LV_COLOR_FORMAT_ARGB8888: + return DMA2D_INPUT_ARGB8888; + case LV_COLOR_FORMAT_RGB888: + return DMA2D_INPUT_RGB888; + case LV_COLOR_FORMAT_RGB565: + return DMA2D_INPUT_RGB565; + case LV_COLOR_FORMAT_L8: + return DMA2D_INPUT_L8; + case LV_COLOR_FORMAT_AL88: + return DMA2D_INPUT_AL88; + case LV_COLOR_FORMAT_A8: + return DMA2D_INPUT_A8; + default: + LV_ASSERT_MSG(0, "the LVGL color format is not a DMA2D input color format"); + } +} +#endif /*LV_ST_LTDC_USE_DMA2D_FLUSH*/ + +#endif /*LV_USE_ST_LTDC*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/display/st_ltdc/lv_st_ltdc.h b/lib/libesp32_lvgl/lvgl/src/drivers/display/st_ltdc/lv_st_ltdc.h new file mode 100644 index 000000000..69a0e7b71 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/display/st_ltdc/lv_st_ltdc.h @@ -0,0 +1,65 @@ +/** + * @file lv_st_ltdc.h + * + */ + +#ifndef LV_ST_LTDC_H +#define LV_ST_LTDC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../../lv_conf_internal.h" +#if LV_USE_ST_LTDC + +#include "../../../display/lv_display.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a direct render mode display bound to a LTDC layer. + * @param fb_adr_1 The LTDC layer's framebuffer memory address. + * @param fb_adr_2 An additional framebuffer-sized buffer to use for double buffering, or `NULL`. + * @param layer_idx The LTDC layer number to bind the display to. Typically 0 or 1. + * @return The display. + */ +lv_display_t * lv_st_ltdc_create_direct(void * fb_adr_1, void * fb_adr_2, uint32_t layer_idx); + +/** + * Create a partial render mode display bound to a LTDC layer. The layer's framebuffer is flushed to internally. + * Enable `LV_ST_LTDC_USE_DMA2D_FLUSH` for parallel flushing. + * @param render_buf_1 A render buffer. + * @param render_buf_2 An additional render buffer for double-buffering, or `NULL`. + * @param buf_size The size of the buffer(s) in bytes. + * @param layer_idx The LTDC layer number to bind the display to. Typically 0 or 1. + * @return The display. + */ +lv_display_t * lv_st_ltdc_create_partial(void * render_buf_1, void * render_buf_2, uint32_t buf_size, + uint32_t layer_idx); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_ST_LTDC*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ST_LTDC_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 e7d31ecff..a1c954beb 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/evdev/lv_evdev.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/evdev/lv_evdev.c @@ -6,24 +6,43 @@ /********************** * INCLUDES **********************/ -#include "lv_evdev.h" +#include "lv_evdev_private.h" #if LV_USE_EVDEV #include #include #include #include +#include +#include +#include #include /*To detect BSD*/ #ifdef BSD #include #else #include + #include #endif /*BSD*/ +#include "../../core/lv_global.h" +#include "../../misc/lv_types.h" #include "../../misc/lv_assert.h" #include "../../misc/lv_math.h" +#include "../../misc/lv_async.h" #include "../../stdlib/lv_mem.h" #include "../../stdlib/lv_string.h" #include "../../display/lv_display.h" +#include "../../display/lv_display_private.h" +#include "../../widgets/image/lv_image.h" + +/********************* + * DEFINES + *********************/ + +#define evdev_discovery LV_GLOBAL_DEFAULT()->evdev_discovery +#define EVDEV_DISCOVERY_PATH "/dev/input/" +#define EVDEV_DISCOVERY_PATH_BUF_SIZE 32 +#define REL_XY_MASK ((1 << REL_X) | (1 << REL_Y)) +#define ABS_XY_MASK ((1 << ABS_X) | (1 << ABS_Y)) /********************** * TYPEDEFS @@ -32,6 +51,9 @@ typedef struct { /*Device*/ int fd; + dev_t st_dev; + ino_t st_ino; + lv_evdev_type_t type; /*Config*/ bool swap_axes; int min_x; @@ -43,8 +65,19 @@ typedef struct { int root_y; int key; lv_indev_state_t state; + bool deleting; } lv_evdev_t; +#ifndef BSD +struct _lv_evdev_discovery_t { + lv_evdev_discovery_cb_t cb; + void * cb_user_data; + int inotify_fd; + bool inotify_watch_active; + lv_timer_t * timer; +}; +#endif + /********************** * STATIC FUNCTIONS **********************/ @@ -97,10 +130,10 @@ static lv_point_t _evdev_process_pointer(lv_indev_t * indev, int x, int y) int swapped_x = dsc->swap_axes ? y : x; int swapped_y = dsc->swap_axes ? x : y; - int offset_x = lv_display_get_offset_x(disp); - int offset_y = lv_display_get_offset_y(disp); - int width = lv_display_get_horizontal_resolution(disp); - int height = lv_display_get_vertical_resolution(disp); + int offset_x = disp->offset_x; + int offset_y = disp->offset_y; + int width = disp->hor_res; + int height = disp->ver_res; lv_point_t p; p.x = _evdev_calibrate(swapped_x, dsc->min_x, dsc->max_x, offset_x, offset_x + width - 1); @@ -108,6 +141,12 @@ static lv_point_t _evdev_process_pointer(lv_indev_t * indev, int x, int y) return p; } +static void _evdev_async_delete_cb(void * user_data) +{ + lv_indev_t * indev = user_data; + lv_indev_delete(indev); +} + static void _evdev_read(lv_indev_t * indev, lv_indev_data_t * data) { lv_evdev_t * dsc = lv_indev_get_driver_data(indev); @@ -115,7 +154,8 @@ static void _evdev_read(lv_indev_t * indev, lv_indev_data_t * data) /*Update dsc with buffered events*/ struct input_event in = { 0 }; - while(read(dsc->fd, &in, sizeof(in)) > 0) { + ssize_t br; + while((br = read(dsc->fd, &in, sizeof(in))) > 0) { if(in.type == EV_REL) { if(in.code == REL_X) dsc->root_x += in.value; else if(in.code == REL_Y) dsc->root_y += in.value; @@ -143,6 +183,16 @@ static void _evdev_read(lv_indev_t * indev, lv_indev_data_t * data) } } } + if(!dsc->deleting && br == -1 && errno != EAGAIN) { + if(errno == ENODEV) { + LV_LOG_INFO("evdev device was removed"); + } + else { + LV_LOG_ERROR("read failed: %s", strerror(errno)); + } + lv_async_call(_evdev_async_delete_cb, indev); + dsc->deleting = true; + } /*Process and store in data*/ switch(lv_indev_get_type(indev)) { @@ -159,6 +209,132 @@ static void _evdev_read(lv_indev_t * indev, lv_indev_data_t * data) } } +static void _evdev_indev_delete_cb(lv_event_t * e) +{ + lv_indev_t * indev = lv_event_get_target(e); + lv_evdev_t * dsc = lv_indev_get_driver_data(indev); + LV_ASSERT_NULL(dsc); + lv_async_call_cancel(_evdev_async_delete_cb, indev); + close(dsc->fd); + lv_free(dsc); +} + +#ifndef BSD +static void _evdev_discovery_indev_try_create(const char * file_name) +{ + if(0 != lv_strncmp(file_name, "event", 5)) { + return; + } + + char dev_path[EVDEV_DISCOVERY_PATH_BUF_SIZE]; + lv_snprintf(dev_path, sizeof(dev_path), EVDEV_DISCOVERY_PATH "%s", file_name); + + lv_indev_t * indev = lv_evdev_create(LV_INDEV_TYPE_NONE, dev_path); + if(indev == NULL) return; + + lv_evdev_t * dsc = lv_indev_get_driver_data(indev); + + /* Compare this new evdev's unique identity with the already registered ones. + * If a match is found, it means the user has already added it and a duplicate + * should not be added automatically -- although it is valid for `lv_evdev_create` + * to be explicitly called with the same path by the user -- or an edge case + * has occurred where discoverey has just been started and a new device was + * connected between the creation of the inotify watcher and the initial full + * scan of the directory with `readdir`. + */ + lv_indev_t * ex_indev = NULL; + while(NULL != (ex_indev = lv_indev_get_next(ex_indev))) { + if(ex_indev == indev || lv_indev_get_read_cb(ex_indev) != _evdev_read) continue; + lv_evdev_t * ex_dsc = lv_indev_get_driver_data(ex_indev); + if(!ex_dsc->deleting && dsc->st_dev == ex_dsc->st_dev && dsc->st_ino == ex_dsc->st_ino) { + /* an indev for this exact device instance already exists */ + lv_indev_delete(indev); + return; + } + } + + lv_evdev_discovery_t * ed = evdev_discovery; + if(ed->cb) { + ed->cb(indev, dsc->type, ed->cb_user_data); + } +} + +static bool _evdev_discovery_inotify_try_init_watcher(int inotify_fd) +{ + int inotify_wd = inotify_add_watch(inotify_fd, EVDEV_DISCOVERY_PATH, IN_CREATE); + if(inotify_wd == -1) { + if(errno != ENOENT) { + LV_LOG_ERROR("inotify_add_watch failed: %s", strerror(errno)); + } + return false; + } + + DIR * dir = opendir(EVDEV_DISCOVERY_PATH); + if(dir == NULL) { + if(errno != ENOENT) { + LV_LOG_ERROR("opendir failed: %s", strerror(errno)); + } + inotify_rm_watch(inotify_fd, inotify_wd); + return false; + } + while(1) { + struct dirent * dirent = readdir(dir); + if(dirent == NULL) break; /* only possible error is EBADF, so no errno check needed */ + _evdev_discovery_indev_try_create(dirent->d_name); + if(evdev_discovery == NULL) { + /* was stopped by the callback. cleanup was already done */ + closedir(dir); + return false; + } + } + closedir(dir); + + return true; +} + +static void _evdev_discovery_timer_cb(lv_timer_t * tim) +{ + LV_UNUSED(tim); + lv_evdev_discovery_t * ed = evdev_discovery; + LV_ASSERT_NULL(ed); + + if(!ed->inotify_watch_active) { + ed->inotify_watch_active = _evdev_discovery_inotify_try_init_watcher(ed->inotify_fd); + return; + } + + union { + struct inotify_event in_ev; + uint8_t buf[sizeof(struct inotify_event) + NAME_MAX + 1]; + } in_data; + ssize_t br; + while((br = read(ed->inotify_fd, &in_data, sizeof(in_data))) > 0) { + struct inotify_event * in_ev_p; + for(uint8_t * in_data_buf_p = in_data.buf; + in_data_buf_p < in_data.buf + br; + in_data_buf_p += sizeof(struct inotify_event) + in_ev_p->len) { + in_ev_p = (struct inotify_event *)in_data_buf_p; + if(in_ev_p->mask & IN_IGNORED) { + /* /dev/input/ was deleted because the last device was removed. + * The watch was removed implicitly. It will try to be + * recreated the next time the timer runs. + */ + ed->inotify_watch_active = false; + return; + } + if(!(in_ev_p->mask & IN_ISDIR) && in_ev_p->len) { + _evdev_discovery_indev_try_create(in_ev_p->name); + if(evdev_discovery == NULL) return; /* was stopped by the callback */ + } + } + } + if(br == -1 && errno != EAGAIN) { + LV_LOG_ERROR("inotify read failed: %s", strerror(errno)); + lv_evdev_discovery_stop(); + } +} +#endif /*BSD*/ + /********************** * GLOBAL FUNCTIONS **********************/ @@ -171,10 +347,67 @@ lv_indev_t * lv_evdev_create(lv_indev_type_t indev_type, const char * dev_path) dsc->fd = open(dev_path, O_RDONLY | O_NOCTTY | O_CLOEXEC); if(dsc->fd < 0) { - LV_LOG_ERROR("open failed: %s", strerror(errno)); + LV_LOG_WARN("open failed: %s", strerror(errno)); goto err_after_malloc; } + struct stat sb; + if(0 != fstat(dsc->fd, &sb)) { + LV_LOG_ERROR("fstat failed: %s", strerror(errno)); + goto err_after_open; + } + dsc->st_dev = sb.st_dev; + dsc->st_ino = sb.st_ino; + + if(indev_type == LV_INDEV_TYPE_NONE) { + uint32_t rel_bits = 0; + if(ioctl(dsc->fd, EVIOCGBIT(EV_REL, sizeof(rel_bits)), &rel_bits) >= 0) { + /* if this device can emit relative X and Y events, it shall be a pointer indev */ + if((rel_bits & REL_XY_MASK) == REL_XY_MASK) { + indev_type = LV_INDEV_TYPE_POINTER; + dsc->type = LV_EVDEV_TYPE_REL; + } + } + else { + LV_LOG_WARN("ioctl EVIOCGBIT(EV_REL, ...) failed: %s", strerror(errno)); + } + } + + if(indev_type == LV_INDEV_TYPE_NONE) { + uint32_t abs_bits = 0; + if(ioctl(dsc->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), &abs_bits) >= 0) { + /* if this device can emit absolute X and Y events, it shall be a pointer indev */ + if((abs_bits & ABS_XY_MASK) == ABS_XY_MASK) { + indev_type = LV_INDEV_TYPE_POINTER; + dsc->type = LV_EVDEV_TYPE_ABS; + } + } + else { + LV_LOG_WARN("ioctl EVIOCGBIT(EV_ABS, ...) failed: %s", strerror(errno)); + } + } + + if(indev_type == LV_INDEV_TYPE_NONE) { + uint32_t key_bits[KEY_MAX / 32 + 1] = {0}; + if(ioctl(dsc->fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), key_bits) >= 0) { + /* if this device can emit any key events, it shall be a keypad indev */ + for(int32_t i = 0; i < (int32_t)(sizeof(key_bits) / sizeof(uint32_t)); i++) { + if(key_bits[i]) { + indev_type = LV_INDEV_TYPE_KEYPAD; + dsc->type = LV_EVDEV_TYPE_KEY; + break; + } + } + } + else { + LV_LOG_WARN("ioctl EVIOCGBIT(EV_KEY, ...) failed: %s", strerror(errno)); + } + } + + if(indev_type == LV_INDEV_TYPE_NONE) { + goto err_after_open; + } + if(fcntl(dsc->fd, F_SETFL, O_NONBLOCK) < 0) { LV_LOG_ERROR("fcntl failed: %s", strerror(errno)); goto err_after_open; @@ -189,14 +422,14 @@ lv_indev_t * lv_evdev_create(lv_indev_type_t indev_type, const char * dev_path) dsc->max_x = absinfo.maximum; } else { - LV_LOG_ERROR("ioctl EVIOCGABS(ABS_X) failed: %s", strerror(errno)); + LV_LOG_INFO("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_LOG_INFO("ioctl EVIOCGABS(ABS_Y) failed: %s", strerror(errno)); } } @@ -205,6 +438,8 @@ lv_indev_t * lv_evdev_create(lv_indev_type_t indev_type, const char * dev_path) lv_indev_set_type(indev, indev_type); lv_indev_set_read_cb(indev, _evdev_read); lv_indev_set_driver_data(indev, dsc); + lv_indev_add_event_cb(indev, _evdev_indev_delete_cb, LV_EVENT_DELETE, NULL); + return indev; err_after_open: @@ -214,6 +449,66 @@ err_after_malloc: return NULL; } +lv_result_t lv_evdev_discovery_start(lv_evdev_discovery_cb_t cb, void * user_data) +{ +#ifndef BSD + lv_evdev_discovery_t * ed = NULL; + int inotify_fd = -1; + lv_timer_t * timer = NULL; + + ed = lv_malloc_zeroed(sizeof(lv_evdev_discovery_t)); + LV_ASSERT_MALLOC(ed); + if(ed == NULL) return LV_RESULT_INVALID; + evdev_discovery = ed; + + ed->cb = cb; + ed->cb_user_data = user_data; + + inotify_fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); + if(inotify_fd == -1) { + LV_LOG_ERROR("inotify_init1 failed: %s", strerror(errno)); + goto err_out; + } + ed->inotify_fd = inotify_fd; + + ed->inotify_watch_active = _evdev_discovery_inotify_try_init_watcher(inotify_fd); + if(evdev_discovery == NULL) return LV_RESULT_OK; /* was stopped by the callback. cleanup was already done */ + + timer = lv_timer_create(_evdev_discovery_timer_cb, LV_DEF_REFR_PERIOD, NULL); + if(timer == NULL) goto err_out; + ed->timer = timer; + + return LV_RESULT_OK; + +err_out: + if(timer != NULL) lv_timer_delete(timer); + if(inotify_fd != -1) close(inotify_fd); + lv_free(ed); + evdev_discovery = NULL; + return LV_RESULT_INVALID; + +#else /*BSD*/ + return LV_RESULT_INVALID; +#endif +} + +lv_result_t lv_evdev_discovery_stop(void) +{ +#ifndef BSD + lv_evdev_discovery_t * ed = evdev_discovery; + if(ed == NULL) return LV_RESULT_INVALID; + + if(ed->timer) lv_timer_delete(ed->timer); + close(ed->inotify_fd); + lv_free(ed); + + evdev_discovery = NULL; + return LV_RESULT_OK; +#else + return LV_RESULT_INVALID; +#endif +} + void lv_evdev_set_swap_axes(lv_indev_t * indev, bool swap_axes) { lv_evdev_t * dsc = lv_indev_get_driver_data(indev); @@ -233,12 +528,12 @@ void lv_evdev_set_calibration(lv_indev_t * indev, int min_x, int min_y, int max_ void lv_evdev_delete(lv_indev_t * indev) { - lv_evdev_t * dsc = lv_indev_get_driver_data(indev); - LV_ASSERT_NULL(dsc); - close(dsc->fd); - lv_free(dsc); - lv_indev_delete(indev); } +void lv_evdev_deinit(void) +{ + lv_evdev_discovery_stop(); +} + #endif /*LV_USE_EVDEV*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/evdev/lv_evdev.h b/lib/libesp32_lvgl/lvgl/src/drivers/evdev/lv_evdev.h index 95ab1544c..091de6717 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/evdev/lv_evdev.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/evdev/lv_evdev.h @@ -18,6 +18,23 @@ extern "C" { #if LV_USE_EVDEV +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_EVDEV_TYPE_REL, /**< mice */ + LV_EVDEV_TYPE_ABS, /**< touch screens, mousepads */ + LV_EVDEV_TYPE_KEY /**< keyboards, keypads, buttons */ +} lv_evdev_type_t; + +/** + * @param indev the indev created for the newly discovered evdev + * @param type the type of the evdev + * @param user_data a custom parameter + */ +typedef void (*lv_evdev_discovery_cb_t)(lv_indev_t * indev, lv_evdev_type_t type, void * user_data); + /********************** * GLOBAL PROTOTYPES **********************/ @@ -30,6 +47,23 @@ extern "C" { */ lv_indev_t * lv_evdev_create(lv_indev_type_t indev_type, const char * dev_path); +/** + * Begin automatically creating evdev indevs for all new and existing + * evdev devices found in /dev/input/ + * @param cb function to call when a new evdev indev is discovered, or `NULL` + * @param user_data parameter to pass to the callback + * @return the success or failure status. It will fail if it's + * already running or resources could not be initialized. + */ +lv_result_t lv_evdev_discovery_start(lv_evdev_discovery_cb_t cb, void * user_data); + +/** + * Stop automatically creating evdev indevs. Safe to call from the + * discovery callback. + * @return the success or failure status. It will fail if it's already running. + */ +lv_result_t lv_evdev_discovery_stop(void); + /** * Set whether coordinates of pointer device should be swapped. Defaults to * false. diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/evdev/lv_evdev_private.h b/lib/libesp32_lvgl/lvgl/src/drivers/evdev/lv_evdev_private.h new file mode 100644 index 000000000..d9b3352d4 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/evdev/lv_evdev_private.h @@ -0,0 +1,45 @@ +/** + * @file lv_evdev_private.h + * + */ + +#ifndef LV_EVDEV_PRIVATE_H +#define LV_EVDEV_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_evdev.h" + +#if LV_USE_EVDEV + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_evdev_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_EVDEV*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_EVDEV_PRIVATE_H*/ 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 index 849cbf58b..6b4c19575 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window.c @@ -110,7 +110,7 @@ void lv_glfw_window_delete(lv_glfw_window_t * window) if(window->use_indev) { lv_glfw_texture_t * texture; LV_LL_READ(&window->textures, texture) { - lv_indev_delete(texture->indev); + if(texture->indev != NULL) lv_indev_delete(texture->indev); } } lv_ll_clear(&window->textures); @@ -122,6 +122,11 @@ void lv_glfw_window_delete(lv_glfw_window_t * window) } } +void * lv_glfw_window_get_glfw_window(lv_glfw_window_t * window) +{ + return (void *)(window->window); +} + 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); @@ -300,7 +305,14 @@ static void window_update_handler(lv_timer_t * t) lv_refr_now(texture_disp); } - lv_opengles_render_texture(texture->texture_id, &texture->area, texture->opa, window->hor_res, window->ver_res); + lv_area_t clip_area = texture->area; +#if LV_USE_DRAW_OPENGLES + lv_opengles_render_texture(texture->texture_id, &texture->area, texture->opa, window->hor_res, window->ver_res, + &clip_area, texture_disp == NULL); +#else + lv_opengles_render_texture(texture->texture_id, &texture->area, texture->opa, window->hor_res, window->ver_res, + &clip_area, true); +#endif } /* Swap front and back buffers */ 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 index e8e516101..81c289e7c 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_glfw_window.h @@ -47,6 +47,13 @@ lv_glfw_window_t * lv_glfw_window_create(int32_t hor_res, int32_t ver_res, bool */ void lv_glfw_window_delete(lv_glfw_window_t * window); +/** + * Get the GLFW window handle for an lv_glfw_window + * @param window GLFW window to return the handle of + * @return the GLFW window handle + */ +void * lv_glfw_window_get_glfw_window(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 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 index a8149c292..cc6cac09e 100644 --- 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 @@ -32,7 +32,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_glfw_window_t { +struct _lv_glfw_window_t { GLFWwindow * window; int32_t hor_res; int32_t ver_res; @@ -43,7 +43,7 @@ struct lv_glfw_window_t { uint8_t closing : 1; }; -struct lv_glfw_texture_t { +struct _lv_glfw_texture_t { lv_glfw_window_t * window; unsigned int texture_id; lv_area_t area; 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 index 5bf6d0227..1b098be6b 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_debug.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_debug.c @@ -41,14 +41,12 @@ void GLClearError() while(glGetError() != GL_NO_ERROR); } -bool GLLogCall(const char * function, const char * file, int line) +void 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; } /********************** 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 index ddde0eb53..aa8bbebe9 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_debug.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_debug.h @@ -19,12 +19,14 @@ extern "C" { void GLClearError(void); -bool GLLogCall(const char * function, const char * file, int line); +void GLLogCall(const char * function, const char * file, int line); #if LV_USE_OPENGLES_DEBUG -#define GL_CALL(x) GLClearError();\ - x;\ - GLLogCall(#x, __FILE__, __LINE__) +#define GL_CALL(x) do {\ + GLClearError();\ + x;\ + GLLogCall(#x, __FILE__, __LINE__);\ + } while(0) #else #define GL_CALL(x) x #endif 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 index 110e7140f..1f46f63b8 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_driver.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_driver.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ #include "../../display/lv_display.h" +#include "../../misc/lv_area_private.h" #if LV_USE_OPENGLES @@ -17,6 +18,8 @@ * DEFINES *********************/ +#define LV_OPENGLES_VERTEX_BUFFER_LEN 16 + /********************** * TYPEDEFS **********************/ @@ -24,6 +27,8 @@ /********************** * STATIC PROTOTYPES **********************/ +static void lv_opengles_render_internal(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, + int32_t disp_w, int32_t disp_h, const lv_area_t * texture_clip_area, bool flip, lv_color_t fill_color); 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); @@ -49,7 +54,9 @@ 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_shader_set_uniform3f(const char * name, float value_0, float value_1, float value_2); static void lv_opengles_render_draw(void); +static float lv_opengles_map_float(float x, float min_in, float max_in, float min_out, float max_out); /*********************** * GLOBAL PROTOTYPES @@ -69,8 +76,8 @@ 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 * shader_names[] = { "u_Texture", "u_ColorDepth", "u_VertexTransform", "u_Opa", "u_IsFill", "u_FillColor" }; +static int shader_location[] = { 0, 0, 0, 0, 0, 0 }; static const char * vertex_shader = "#version 300 es\n" @@ -91,7 +98,7 @@ static const char * vertex_shader = static const char * fragment_shader = "#version 300 es\n" "\n" - "precision mediump float;\n" + "precision lowp float;\n" "\n" "layout(location = 0) out vec4 color;\n" "\n" @@ -100,15 +107,23 @@ static const char * fragment_shader = "uniform sampler2D u_Texture;\n" "uniform int u_ColorDepth;\n" "uniform float u_Opa;\n" + "uniform bool u_IsFill;\n" + "uniform vec3 u_FillColor;\n" "\n" "void main()\n" "{\n" - " vec4 texColor = texture(u_Texture, v_TexCoord);\n" + " vec4 texColor;\n" + " if (u_IsFill) {\n" + " texColor = vec4(u_FillColor, 1.0f);\n" + " } else {\n" + " texColor = texture(u_Texture, v_TexCoord);\n" + " }\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" + " float combinedAlpha = texColor.a * u_Opa;\n" + " color = vec4(texColor.rgb * combinedAlpha, combinedAlpha);\n" " }\n" "};\n"; @@ -126,19 +141,12 @@ void lv_opengles_init(void) 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_buffer_init(NULL, sizeof(float) * LV_OPENGLES_VERTEX_BUFFER_LEN); lv_opengles_vertex_array_init(); lv_opengles_vertex_array_add_buffer(); @@ -170,27 +178,14 @@ void lv_opengles_deinit(void) } 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) + int32_t disp_h, const lv_area_t * texture_clip_area, bool flip) { - GL_CALL(glActiveTexture(GL_TEXTURE0)); - GL_CALL(glBindTexture(GL_TEXTURE_2D, texture)); + lv_opengles_render_internal(texture, texture_area, opa, disp_w, disp_h, texture_clip_area, flip, lv_color_black()); +} - 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_fill(lv_color_t color, const lv_area_t * area, lv_opa_t opa, int32_t disp_w, int32_t disp_h) +{ + lv_opengles_render_internal(0, area, opa, disp_w, disp_h, area, false, color); } void lv_opengles_render_clear(void) @@ -207,22 +202,79 @@ void lv_opengles_viewport(int32_t x, int32_t y, int32_t w, int32_t h) * STATIC FUNCTIONS **********************/ +static void lv_opengles_render_internal(unsigned int texture, const lv_area_t * texture_area, lv_opa_t opa, + int32_t disp_w, int32_t disp_h, const lv_area_t * texture_clip_area, bool flip, lv_color_t fill_color) +{ + lv_area_t intersection; + if(!lv_area_intersect(&intersection, texture_area, texture_clip_area)) return; + + GL_CALL(glActiveTexture(GL_TEXTURE0)); + GL_CALL(glBindTexture(GL_TEXTURE_2D, texture)); + + float tex_w = (float)lv_area_get_width(&intersection); + float tex_h = (float)lv_area_get_height(&intersection); + + float hor_scale = tex_w / (float)disp_w; + float ver_scale = tex_h / (float)disp_h; + float hor_translate = (float)intersection.x1 / (float)disp_w * 2.0f - (1.0f - hor_scale); + float ver_translate = -((float)intersection.y1 / (float)disp_h * 2.0f - (1.0f - ver_scale)); + if(flip) ver_scale = -ver_scale; + float matrix[9] = { + hor_scale, 0.0f, hor_translate, + 0.0f, ver_scale, ver_translate, + 0.0f, 0.0f, 1.0f + }; + + if(texture != 0) { + float x_coef = 1.0f / (float)(2 * lv_area_get_width(texture_area)); + float y_coef = 1.0f / (float)(2 * lv_area_get_height(texture_area)); + float tex_clip_x1 = lv_opengles_map_float(texture_clip_area->x1, texture_area->x1, texture_area->x2, x_coef, + 1.0f - x_coef); + float tex_clip_x2 = lv_opengles_map_float(texture_clip_area->x2, texture_area->x1, texture_area->x2, x_coef, + 1.0f - x_coef); + float tex_clip_y1 = lv_opengles_map_float(texture_clip_area->y1, texture_area->y1, texture_area->y2, y_coef, + 1.0f - y_coef); + float tex_clip_y2 = lv_opengles_map_float(texture_clip_area->y2, texture_area->y1, texture_area->y2, y_coef, + 1.0f - y_coef); + + float positions[LV_OPENGLES_VERTEX_BUFFER_LEN] = { + -1.0f, 1.0f, tex_clip_x1, tex_clip_y2, + 1.0f, 1.0f, tex_clip_x2, tex_clip_y2, + 1.0f, -1.0f, tex_clip_x2, tex_clip_y1, + -1.0f, -1.0f, tex_clip_x1, tex_clip_y1 + }; + lv_opengles_vertex_buffer_init(positions, sizeof(positions)); + } + + 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_shader_set_uniform1i("u_IsFill", texture == 0); + lv_opengles_shader_set_uniform3f("u_FillColor", (float)fill_color.red / 255.0f, (float)fill_color.green / 255.0f, + (float)fill_color.blue / 255.0f); + lv_opengles_render_draw(); +} + static void lv_opengles_enable_blending(void) { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFunc(GL_ONE, 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)); + if(vertex_buffer_id == 0) 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)); + GL_CALL(glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW)); } static void lv_opengles_vertex_buffer_deinit(void) { + if(vertex_buffer_id == 0) return; GL_CALL(glDeleteBuffers(1, &vertex_buffer_id)); + vertex_buffer_id = 0; } static void lv_opengles_vertex_buffer_bind(void) @@ -237,12 +289,14 @@ static void lv_opengles_vertex_buffer_unbind(void) static void lv_opengles_vertex_array_init(void) { - GL_CALL(glGenVertexArrays(1, &vertex_array_id)); + if(vertex_array_id == 0) GL_CALL(glGenVertexArrays(1, &vertex_array_id)); } static void lv_opengles_vertex_array_deinit(void) { + if(vertex_array_id == 0) return; GL_CALL(glDeleteVertexArrays(1, &vertex_array_id)); + vertex_array_id = 0; } static void lv_opengles_vertex_array_bind(void) @@ -271,7 +325,7 @@ static void lv_opengles_vertex_array_add_buffer(void) 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)); + if(index_buffer_id == 0) GL_CALL(glGenBuffers(1, &index_buffer_id)); GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id)); @@ -280,7 +334,9 @@ static void lv_opengles_index_buffer_init(const unsigned int * data, unsigned in static void lv_opengles_index_buffer_deinit(void) { + if(index_buffer_id == 0) return; GL_CALL(glDeleteBuffers(1, &index_buffer_id)); + index_buffer_id = 0; } static unsigned int lv_opengles_index_buffer_get_count(void) @@ -300,7 +356,8 @@ static void lv_opengles_index_buffer_unbind(void) static unsigned int lv_opengles_shader_compile(unsigned int type, const char * source) { - GL_CALL(unsigned int id = glCreateShader(type)); + unsigned int id; + GL_CALL(id = glCreateShader(type)); const char * src = source; GL_CALL(glShaderSource(id, 1, &src, NULL)); GL_CALL(glCompileShader(id)); @@ -323,7 +380,8 @@ static unsigned int lv_opengles_shader_compile(unsigned int type, const char * s static unsigned int lv_opengles_shader_create(const char * vertexShader, const char * fragmentShader) { - GL_CALL(unsigned int program = glCreateProgram()); + unsigned int program; + GL_CALL(program = glCreateProgram()); unsigned int vs = lv_opengles_shader_compile(GL_VERTEX_SHADER, vertexShader); unsigned int fs = lv_opengles_shader_compile(GL_FRAGMENT_SHADER, fragmentShader); @@ -340,12 +398,14 @@ static unsigned int lv_opengles_shader_create(const char * vertexShader, const c static void lv_opengles_shader_init(void) { - shader_id = lv_opengles_shader_create(vertex_shader, fragment_shader); + if(shader_id == 0) shader_id = lv_opengles_shader_create(vertex_shader, fragment_shader); } static void lv_opengles_shader_deinit(void) { + if(shader_id == 0) return; GL_CALL(glDeleteProgram(shader_id)); + shader_id = 0; } static void lv_opengles_shader_bind(void) @@ -374,7 +434,8 @@ static int lv_opengles_shader_get_uniform_location(const char * name) return shader_location[id]; } - GL_CALL(int location = glGetUniformLocation(shader_id, name)); + int location; + GL_CALL(location = glGetUniformLocation(shader_id, name)); if(location == -1) LV_LOG_WARN("Warning: uniform '%s' doesn't exist!", name); @@ -397,6 +458,11 @@ 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_shader_set_uniform3f(const char * name, float value_0, float value_1, float value_2) +{ + GL_CALL(glUniform3f(lv_opengles_shader_get_uniform_location(name), value_0, value_1, value_2)); +} + static void lv_opengles_render_draw(void) { lv_opengles_shader_bind(); @@ -406,4 +472,28 @@ static void lv_opengles_render_draw(void) GL_CALL(glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, NULL)); } +/** + * Copied from `lv_map` in lv_math.h to operate on floats + */ +static float lv_opengles_map_float(float x, float min_in, float max_in, float min_out, float max_out) +{ + if(max_in >= min_in && x >= max_in) return max_out; + if(max_in >= min_in && x <= min_in) return min_out; + + if(max_in <= min_in && x <= max_in) return max_out; + if(max_in <= min_in && x >= min_in) return min_out; + + /** + * The equation should be: + * ((x - min_in) * delta_out) / delta in) + min_out + * To avoid rounding error reorder the operations: + * (x - min_in) * (delta_out / delta_min) + min_out + */ + + float delta_in = max_in - min_in; + float delta_out = max_out - min_out; + + return ((x - min_in) * delta_out) / delta_in + min_out; +} + #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 index e539febb9..34bda861d 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_driver.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_driver.h @@ -49,11 +49,21 @@ void lv_opengles_deinit(void); * @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 + * @param disp_w width of the window/framebuffer being rendered to + * @param disp_h height of the window/framebuffer 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); + int32_t disp_h, const lv_area_t * texture_clip_area, bool flip); + +/** + * Render a fill + * @param color the color of the fill + * @param area the area in the window to render the fill + * @param opa opacity to blend the fill with existing contents + * @param disp_w width of the window/framebuffer being rendered to + * @param disp_h height of the window/framebuffer being rendered to + */ +void lv_opengles_render_fill(lv_color_t color, const lv_area_t * area, lv_opa_t opa, int32_t disp_w, int32_t disp_h); /** * Clear the window/display 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 index 02c9dfa7d..a719a7846 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_texture.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/glfw/lv_opengles_texture.c @@ -71,12 +71,32 @@ lv_display_t * lv_opengles_texture_create(int32_t w, int32_t h) 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_MIN_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); 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)); + /* set the dimensions and format to complete the texture */ + /* Color depth: 8 (L8), 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, NULL)); +#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, + NULL)); +#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, NULL)); +#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, NULL)); +#else +#error("Unsupported color format") +#endif + + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 20); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + 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); @@ -115,14 +135,18 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_m LV_UNUSED(area); LV_UNUSED(px_map); +#if !LV_USE_DRAW_OPENGLES if(lv_display_flush_is_last(disp)) { lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp); + lv_color_format_t cf = lv_display_get_color_format(disp); + uint32_t stride = lv_draw_buf_width_to_stride(lv_display_get_horizontal_resolution(disp), cf); 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)*/ + GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / lv_color_format_get_size(cf))); + /*Color depth: 8 (L8), 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 @@ -136,6 +160,7 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_m #error("Unsupported color format") #endif } +#endif /* !LV_USE_DRAW_OPENGLES */ lv_display_flush_ready(disp); } @@ -145,6 +170,7 @@ 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); + GL_CALL(glDeleteTextures(1, &dsc->texture_id)); lv_free(dsc); } 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 7410f40fd..50b1bd6ed 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput.c @@ -39,7 +39,7 @@ * TYPEDEFS **********************/ -struct lv_libinput_device { +struct _lv_libinput_device { lv_libinput_capability capabilities; char * path; }; @@ -71,7 +71,7 @@ static void _delete(lv_libinput_t * dsc); * STATIC VARIABLES **********************/ -static struct lv_libinput_device * devices = NULL; +static struct _lv_libinput_device * devices = NULL; static size_t num_devices = 0; static const int timeout = 100; // ms @@ -270,7 +270,7 @@ static bool _add_scanned_device(char * path, lv_libinput_capability capabilities { /* Double array size every 2^n elements */ if((num_devices & (num_devices + 1)) == 0) { - struct lv_libinput_device * tmp = realloc(devices, (2 * num_devices + 1) * sizeof(struct lv_libinput_device)); + struct _lv_libinput_device * tmp = realloc(devices, (2 * num_devices + 1) * sizeof(struct _lv_libinput_device)); if(!tmp) { perror("could not reallocate memory for devices array"); return false; @@ -595,6 +595,9 @@ static void _read_keypad(lv_libinput_t * dsc, struct libinput_event * event) case KEY_END: evt->key_val = LV_KEY_END; break; + case KEY_ESC: + evt->key_val = LV_KEY_ESC; + break; default: evt->key_val = 0; break; 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 index bced3e219..2856bbefe 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput_private.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_libinput_private.h @@ -30,13 +30,13 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_libinput_event_t { +struct _lv_libinput_event_t { lv_indev_state_t pressed; int key_val; lv_point_t point; }; -struct lv_libinput_t { +struct _lv_libinput_t { int fd; struct pollfd fds[1]; 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 index 315762541..97aad7498 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb_private.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/libinput/lv_xkb_private.h @@ -30,7 +30,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_xkb_t { +struct _lv_xkb_t { struct xkb_keymap * keymap; struct xkb_state * state; }; diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/lv_drivers.h b/lib/libesp32_lvgl/lvgl/src/drivers/lv_drivers.h index 08c76e777..085010813 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/lv_drivers.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/lv_drivers.h @@ -25,6 +25,16 @@ extern "C" { #include "display/tft_espi/lv_tft_espi.h" +#include "display/lcd/lv_lcd_generic_mipi.h" +#include "display/ili9341/lv_ili9341.h" +#include "display/st7735/lv_st7735.h" +#include "display/st7789/lv_st7789.h" +#include "display/st7796/lv_st7796.h" + +#include "display/renesas_glcdc/lv_renesas_glcdc.h" +#include "display/st_ltdc/lv_st_ltdc.h" +#include "display/ft81x/lv_ft81x.h" + #include "nuttx/lv_nuttx_entry.h" #include "nuttx/lv_nuttx_fbdev.h" #include "nuttx/lv_nuttx_touchscreen.h" @@ -45,6 +55,10 @@ extern "C" { #include "wayland/lv_wayland.h" +#include "uefi/lv_uefi_context.h" +#include "uefi/lv_uefi_indev.h" +#include "uefi/lv_uefi_display.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 273f49ef8..ec1833c1a 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 @@ -13,11 +13,14 @@ #if LV_USE_NUTTX #include "../../draw/lv_draw_buf_private.h" +#include "../../core/lv_global.h" #include /********************* * DEFINES *********************/ +#define image_cache_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers) +#define font_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->font_draw_buf_handlers) /********************** * TYPEDEFS @@ -47,6 +50,14 @@ 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; + + handlers = image_cache_draw_buf_handlers; + handlers->invalidate_cache_cb = invalidate_cache; + handlers->flush_cache_cb = flush_cache; + + handlers = font_draw_buf_handlers; + handlers->invalidate_cache_cb = invalidate_cache; + handlers->flush_cache_cb = flush_cache; } void lv_nuttx_cache_deinit(void) @@ -54,6 +65,14 @@ 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; + + handlers = image_cache_draw_buf_handlers; + handlers->invalidate_cache_cb = NULL; + handlers->flush_cache_cb = NULL; + + handlers = font_draw_buf_handlers; + handlers->invalidate_cache_cb = NULL; + handlers->flush_cache_cb = NULL; } /********************** 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 57a4d289d..3f70308cd 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 @@ -66,6 +66,8 @@ static void check_stack_size(void); #if LV_ENABLE_GLOBAL_CUSTOM +static int lv_nuttx_tlskey = -1; + static void lv_global_free(void * data) { if(data) { @@ -75,18 +77,17 @@ static void lv_global_free(void * data) lv_global_t * lv_global_default(void) { - static int index = -1; lv_global_t * data = NULL; - if(index < 0) { - index = task_tls_alloc(lv_global_free); + if(lv_nuttx_tlskey < 0) { + lv_nuttx_tlskey = task_tls_alloc(lv_global_free); } - if(index >= 0) { - data = (lv_global_t *)task_tls_get_value(index); + if(lv_nuttx_tlskey >= 0) { + data = (lv_global_t *)task_tls_get_value(lv_nuttx_tlskey); if(data == NULL) { data = (lv_global_t *)calloc(1, sizeof(lv_global_t)); - task_tls_set_value(index, (uintptr_t)data); + task_tls_set_value(lv_nuttx_tlskey, (uintptr_t)data); } } return data; @@ -121,7 +122,7 @@ void lv_nuttx_init(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result) lv_nuttx_cache_init(); - lv_nuttx_image_cache_init(); + lv_nuttx_image_cache_init(LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP); #if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN lv_nuttx_profiler_init(); @@ -185,6 +186,8 @@ void lv_nuttx_run(lv_nuttx_result_t * result) /* Minimum sleep of 1ms */ idle = idle ? idle : 1; + /* Handle LV_DEF_REFR_PERIOD */ + idle = idle != LV_NO_TIMER_READY ? idle : LV_DEF_REFR_PERIOD; usleep(idle * 1000); } #endif 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 64ece994e..049e741e5 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,7 +43,7 @@ typedef struct { lv_indev_t * utouch_indev; } lv_nuttx_result_t; -typedef struct lv_nuttx_ctx_t { +typedef struct _lv_nuttx_ctx_t { void * image_cache; } lv_nuttx_ctx_t; 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 5ff500e28..1057c3bee 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,11 +39,14 @@ typedef struct { void * mem; void * mem2; + void * mem3; void * mem_off_screen; uint32_t mem2_yoffset; + uint32_t mem3_yoffset; lv_draw_buf_t buf1; lv_draw_buf_t buf2; + lv_draw_buf_t buf3; } lv_nuttx_fb_t; /********************** @@ -54,6 +57,7 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * colo 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 int fbdev_init_mem3(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) @@ -143,7 +147,7 @@ int lv_nuttx_fbdev_set_file(lv_display_t * disp, const char * file) 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); + bool double_buffer = dsc->pinfo.yres_virtual >= (dsc->vinfo.yres * 2); if(double_buffer) { if((ret = fbdev_init_mem2(dsc)) < 0) { goto errout; @@ -151,6 +155,16 @@ int lv_nuttx_fbdev_set_file(lv_display_t * disp, const char * file) 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); + + bool triple_buffer = dsc->pinfo.yres_virtual >= (dsc->vinfo.yres * 3); + if(triple_buffer) { + if((ret = fbdev_init_mem3(dsc)) < 0) { + goto errout; + } + + lv_draw_buf_init(&dsc->buf3, w, h, color_format, stride, dsc->mem3, data_size); + lv_display_set_3rd_draw_buffer(disp, &dsc->buf3); + } } else { dsc->mem_off_screen = malloc(data_size); @@ -171,6 +185,10 @@ int lv_nuttx_fbdev_set_file(lv_display_t * disp, const char * file) lv_display_set_resolution(disp, dsc->vinfo.xres, dsc->vinfo.yres); lv_timer_set_cb(disp->refr_timer, display_refr_timer_cb); +#if LV_DRAW_TRANSFORM_USE_MATRIX + lv_display_set_matrix_rotation(disp, true); +#endif + LV_LOG_USER("Resolution is set to %dx%d at %" LV_PRId32 "dpi", dsc->vinfo.xres, dsc->vinfo.yres, lv_display_get_dpi(disp)); return 0; @@ -254,9 +272,13 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * colo #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; - + int yoffset = 0; + if(disp->buf_act == disp->buf_2) { + yoffset = dsc->mem2_yoffset; + } + else if(disp->buf_act == disp->buf_3) { + yoffset = dsc->mem3_yoffset; + } /* Join the areas to update */ lv_area_t final_inv_area; lv_memzero(&final_inv_area, sizeof(final_inv_area)); @@ -278,9 +300,12 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * colo if(disp->buf_act == disp->buf_1) { dsc->pinfo.yoffset = 0; } - else { + else if(disp->buf_act == disp->buf_2) { dsc->pinfo.yoffset = dsc->mem2_yoffset; } + else if(disp->buf_act == disp->buf_3) { + dsc->pinfo.yoffset = dsc->mem3_yoffset; + } if(ioctl(dsc->fd, FBIOPAN_DISPLAY, (unsigned long)((uintptr_t) & (dsc->pinfo))) < 0) { LV_LOG_ERROR("ioctl(FBIOPAN_DISPLAY) failed: %d", errno); @@ -327,6 +352,71 @@ static int fbdev_get_pinfo(int fd, FAR struct fb_planeinfo_s * pinfo) } static int fbdev_init_mem2(lv_nuttx_fb_t * dsc) +{ + struct fb_planeinfo_s pinfo; + void * phy_mem1; + void * phy_mem2; + + int ret; + + /* Get display[0] planeinfo */ + lv_memzero(&pinfo, sizeof(pinfo)); + pinfo.display = dsc->pinfo.display; + if((ret = fbdev_get_pinfo(dsc->fd, &pinfo)) < 0) return ret; + phy_mem1 = pinfo.fbmem; + + /* Get display[1] planeinfo */ + lv_memzero(&pinfo, sizeof(pinfo)); + pinfo.display = dsc->pinfo.display + 1; + if((ret = fbdev_get_pinfo(dsc->fd, &pinfo)) < 0) return ret; + phy_mem2 = pinfo.fbmem; + + lv_uintptr_t offset = (lv_uintptr_t)phy_mem2 - (lv_uintptr_t)phy_mem1; + bool is_consecutive = offset == 0; + + /* Check bpp */ + + if(pinfo.bpp != dsc->pinfo.bpp) { + LV_LOG_WARN("mem2 is incorrect"); + return -EINVAL; + } + + /* Check the buffer address offset, + * It needs to be divisible by pinfo.stride + */ + + if((offset % dsc->pinfo.stride) != 0) { + LV_LOG_WARN("It is detected that buf_offset(%" PRIuPTR ") " + "and stride(%d) are not divisible, please ensure " + "that the driver handles the address offset by itself.", + offset, dsc->pinfo.stride); + } + + /* Calculate the address and yoffset of mem2 */ + + if(is_consecutive) { + dsc->mem2_yoffset = dsc->vinfo.yres; + offset = dsc->vinfo.yres * pinfo.stride; + } + else { + dsc->mem2_yoffset = offset / dsc->pinfo.stride; + } + + uint32_t fblen = is_consecutive ? pinfo.fblen / 2 : pinfo.fblen; + void * mem2 = mmap(NULL, fblen, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FILE, dsc->fd, offset); + if(mem2 == MAP_FAILED) { + LV_LOG_ERROR("ERROR: mmap failed: %d, offset: %" PRIuPTR, errno, offset); + return -errno; + } + dsc->mem2 = mem2; + + LV_LOG_USER("Use of %sconsecutive mem2 = %p, yoffset = %" LV_PRIu32, is_consecutive ? "" : "non-", dsc->mem2, + dsc->mem2_yoffset); + + return 0; +} + +static int fbdev_init_mem3(lv_nuttx_fb_t * dsc) { uintptr_t buf_offset; struct fb_planeinfo_s pinfo; @@ -334,9 +424,9 @@ static int fbdev_init_mem2(lv_nuttx_fb_t * dsc) lv_memzero(&pinfo, sizeof(pinfo)); - /* Get display[1] planeinfo */ + /* Get display[2] planeinfo */ - pinfo.display = dsc->pinfo.display + 1; + pinfo.display = dsc->pinfo.display + 2; if((ret = fbdev_get_pinfo(dsc->fd, &pinfo)) < 0) { return ret; @@ -345,7 +435,7 @@ static int fbdev_init_mem2(lv_nuttx_fb_t * dsc) /* Check bpp */ if(pinfo.bpp != dsc->pinfo.bpp) { - LV_LOG_WARN("mem2 is incorrect"); + LV_LOG_WARN("mem3 is incorrect"); return -EINVAL; } @@ -362,19 +452,19 @@ static int fbdev_init_mem2(lv_nuttx_fb_t * dsc) buf_offset, dsc->pinfo.stride); } - /* Calculate the address and yoffset of mem2 */ + /* Calculate the address and yoffset of mem3 */ if(buf_offset == 0) { - dsc->mem2_yoffset = dsc->vinfo.yres; - dsc->mem2 = pinfo.fbmem + dsc->mem2_yoffset * pinfo.stride; - LV_LOG_USER("Use consecutive mem2 = %p, yoffset = %" LV_PRIu32, - dsc->mem2, dsc->mem2_yoffset); + dsc->mem3_yoffset = dsc->vinfo.yres * 2; + dsc->mem3 = pinfo.fbmem + dsc->mem3_yoffset * pinfo.stride; + LV_LOG_USER("Use consecutive mem3 = %p, yoffset = %" LV_PRIu32, + dsc->mem3, dsc->mem3_yoffset); } else { - dsc->mem2_yoffset = buf_offset / dsc->pinfo.stride; - dsc->mem2 = pinfo.fbmem; - LV_LOG_USER("Use non-consecutive mem2 = %p, yoffset = %" LV_PRIu32, - dsc->mem2, dsc->mem2_yoffset); + dsc->mem3_yoffset = buf_offset / dsc->pinfo.stride; + dsc->mem3 = pinfo.fbmem; + LV_LOG_USER("Use non-consecutive mem3 = %p, yoffset = %" LV_PRIu32, + dsc->mem3, dsc->mem3_yoffset); } return 0; 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 93f59ed9a..b295850d0 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 @@ -40,6 +40,15 @@ typedef struct { uint32_t heap_size; bool initialized; + bool independent_image_heap; + + lv_draw_buf_malloc_cb malloc_cb; + lv_draw_buf_free_cb free_cb; + +#if LV_NUTTX_DEFAULT_DRAW_BUF_USE_INDEPENDENT_IMAGE_HEAP + lv_draw_buf_malloc_cb malloc_cb_default; + lv_draw_buf_free_cb free_cb_default; +#endif } lv_nuttx_ctx_image_cache_t; /********************** * STATIC PROTOTYPES @@ -60,26 +69,52 @@ static void free_cb(void * draw_buf); * GLOBAL FUNCTIONS **********************/ -void lv_nuttx_image_cache_init(void) +void lv_nuttx_image_cache_init(bool use_independent_image_heap) { 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->malloc_cb = handlers->buf_malloc_cb; + ctx->free_cb = handlers->buf_free_cb; + + handlers->buf_malloc_cb = malloc_cb; + handlers->buf_free_cb = free_cb; + +#if LV_NUTTX_DEFAULT_DRAW_BUF_USE_INDEPENDENT_IMAGE_HEAP + handlers = lv_draw_buf_get_handlers(); + ctx->malloc_cb_default = handlers->buf_malloc_cb; + ctx->free_cb_default = handlers->buf_free_cb; + + handlers->buf_malloc_cb = malloc_cb; + handlers->buf_free_cb = free_cb; +#endif + ctx->initialized = false; + ctx->independent_image_heap = use_independent_image_heap; } void lv_nuttx_image_cache_deinit(void) { + lv_draw_buf_handlers_t * handlers = image_cache_draw_buf_handlers; + + if(ctx->independent_image_heap == false) goto FREE_CONTEXT; if(ctx->initialized == false) goto FREE_CONTEXT; mm_uninitialize(ctx->heap); free(ctx->mem); FREE_CONTEXT: + handlers->buf_malloc_cb = ctx->malloc_cb; + handlers->buf_free_cb = ctx->free_cb; + +#if LV_NUTTX_DEFAULT_DRAW_BUF_USE_INDEPENDENT_IMAGE_HEAP + handlers = lv_draw_buf_get_handlers(); + handlers->buf_malloc_cb = ctx->malloc_cb_default; + handlers->buf_free_cb = ctx->free_cb_default; +#endif + lv_free(ctx); ctx = NULL; @@ -136,11 +171,23 @@ static bool defer_init(void) return true; } +static void heap_memdump(struct mm_heap_s * heap) +{ + struct mm_memdump_s dump = { + PID_MM_ALLOC, +#if CONFIG_MM_BACKTRACE >= 0 + 0, + ULONG_MAX +#endif + }; + + mm_memdump(heap, &dump); +} + static void * malloc_cb(size_t size_bytes, lv_color_format_t color_format) { LV_UNUSED(color_format); - - if(ctx->initialized == false) { + if(ctx->independent_image_heap == true && ctx->initialized == false) { if(defer_init() == false) return NULL; } @@ -148,7 +195,7 @@ static void * malloc_cb(size_t size_bytes, lv_color_format_t color_format) size_bytes += LV_DRAW_BUF_ALIGN - 1; uint32_t cache_max_size = lv_cache_get_max_size(img_cache_p, NULL); - if(size_bytes > cache_max_size) { + if(lv_cache_is_enabled(img_cache_p) && size_bytes > cache_max_size) { LV_LOG_ERROR("data size (%" LV_PRIu32 ") is larger than max size (%" LV_PRIu32 ")", (uint32_t)size_bytes, cache_max_size); @@ -156,13 +203,20 @@ static void * malloc_cb(size_t size_bytes, lv_color_format_t color_format) } while(1) { - void * mem = mm_malloc(ctx->heap, size_bytes); + void * mem = NULL; + if(ctx->independent_image_heap) { + mem = mm_malloc(ctx->heap, size_bytes); + } + else if((!lv_cache_is_enabled(img_cache_p)) || (lv_cache_get_size(img_cache_p, NULL) + size_bytes < cache_max_size)) { + mem = ctx->malloc_cb(size_bytes, color_format); + } if(mem) return mem; LV_LOG_INFO("appears to be out of memory. attempting to evict one cache entry. with allocated size %" LV_PRIu32, (uint32_t)size_bytes); bool evict_res = lv_cache_evict_one(img_cache_p, NULL); if(evict_res == false) { LV_LOG_ERROR("failed to evict one cache entry"); + heap_memdump(ctx->heap); return NULL; } } @@ -170,7 +224,12 @@ static void * malloc_cb(size_t size_bytes, lv_color_format_t color_format) static void free_cb(void * draw_buf) { - mm_free(ctx->heap, draw_buf); + if(ctx->independent_image_heap == true) { + mm_free(ctx->heap, draw_buf); + } + else { + ctx->free_cb(draw_buf); + } } #endif /* LV_USE_NUTTX */ 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 105779fa6..0e056b4ab 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 @@ -15,6 +15,7 @@ extern "C" { *********************/ #include "../../lv_conf_internal.h" +#include LV_STDBOOL_INCLUDE /********************* * DEFINES @@ -28,7 +29,7 @@ extern "C" { * GLOBAL PROTOTYPES **********************/ -void lv_nuttx_image_cache_init(void); +void lv_nuttx_image_cache_init(bool use_independent_image_heap); void lv_nuttx_image_cache_deinit(void); 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 af49cd44d..43385b051 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 @@ -138,20 +138,23 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area_p, uint8_t * color_p) { lv_nuttx_lcd_t * lcd = disp->driver_data; + lv_color_format_t cf = lv_display_get_color_format(disp); lcd->area.row_start = area_p->y1; lcd->area.row_end = area_p->y2; lcd->area.col_start = area_p->x1; lcd->area.col_end = area_p->x2; - lcd->area.data = (uint8_t *)color_p; + lcd->area.stride = lv_draw_buf_width_to_stride(lcd->area.col_end - lcd->area.col_start + 1, cf); + lcd->area.data = (uint8_t *)color_p + (LV_COLOR_FORMAT_IS_INDEXED(cf) ? + LV_COLOR_INDEXED_PALETTE_SIZE(cf) * 4 : 0); ioctl(lcd->fd, LCDDEVIO_PUTAREA, (unsigned long) & (lcd->area)); lv_display_flush_ready(disp); } static lv_display_t * lcd_init(int fd, int hor_res, int ver_res) { - uint8_t * draw_buf = NULL; - uint8_t * draw_buf_2 = NULL; + lv_draw_buf_t * draw_buf = NULL; + lv_draw_buf_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) { @@ -165,28 +168,26 @@ static lv_display_t * lcd_init(int fd, int hor_res, int ver_res) return NULL; } - uint32_t px_size = lv_color_format_get_size(lv_display_get_color_format(disp)); + lv_color_format_t cf = lv_display_get_color_format(disp); /* Use default cf */ #if LV_NUTTX_LCD_BUFFER_COUNT > 0 - uint32_t buf_size = hor_res * ver_res * px_size; lv_display_render_mode_t render_mode = LV_DISPLAY_RENDER_MODE_FULL; #else - uint32_t buf_size = hor_res * LV_NUTTX_LCD_BUFFER_SIZE * px_size; lv_display_render_mode_t render_mode = LV_DISPLAY_RENDER_MODE_PARTIAL; #endif - draw_buf = lv_malloc(buf_size); + draw_buf = lv_draw_buf_create(hor_res, ver_res, cf, LV_STRIDE_AUTO); if(draw_buf == NULL) { - LV_LOG_ERROR("display draw_buf malloc failed"); + LV_LOG_ERROR("display draw_buf create failed"); lv_free(lcd); return NULL; } #if LV_NUTTX_LCD_BUFFER_COUNT == 2 - draw_buf_2 = lv_malloc(buf_size); + draw_buf_2 = lv_draw_buf_create(hor_res, ver_res, cf, LV_STRIDE_AUTO); if(draw_buf_2 == NULL) { LV_LOG_ERROR("display draw_buf_2 malloc failed"); lv_free(lcd); - lv_free(draw_buf); + lv_draw_buf_destroy(draw_buf); return NULL; } #endif @@ -197,7 +198,8 @@ static lv_display_t * lcd_init(int fd, int hor_res, int ver_res) } lcd->disp = disp; - lv_display_set_buffers(lcd->disp, draw_buf, draw_buf_2, buf_size, render_mode); + lv_display_set_draw_buffers(lcd->disp, draw_buf, draw_buf_2); + lv_display_set_render_mode(lcd->disp, render_mode); lv_display_set_flush_cb(lcd->disp, flush_cb); lv_display_add_event_cb(lcd->disp, rounder_cb, LV_EVENT_INVALIDATE_AREA, lcd); lv_display_add_event_cb(lcd->disp, display_release_cb, LV_EVENT_DELETE, lcd->disp); @@ -216,11 +218,11 @@ static void display_release_cb(lv_event_t * e) /* clear display buffer */ if(disp->buf_1) { - lv_free(disp->buf_1->data); + lv_draw_buf_destroy(disp->buf_1); disp->buf_1 = NULL; } if(disp->buf_2) { - lv_free(disp->buf_2->data); + lv_draw_buf_destroy(disp->buf_2); disp->buf_2 = 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 12b8c439c..7d25fa29b 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 @@ -7,7 +7,7 @@ *********************/ #include "lv_nuttx_libuv.h" -#include "../../../lvgl.h" +#include "../../lvgl.h" #include "../../lvgl_private.h" #if LV_USE_NUTTX @@ -29,6 +29,7 @@ typedef struct { bool polling; uv_poll_t fb_poll; uv_poll_t vsync_poll; + int32_t vsync_req_count; } lv_nuttx_uv_fb_ctx_t; typedef struct { @@ -190,7 +191,7 @@ static void lv_nuttx_uv_vsync_poll_cb(uv_poll_t * handle, int status, int events lv_display_t * d; d = lv_display_get_next(NULL); while(d) { - lv_display_send_event(d, LV_EVENT_VSYNC, NULL); + lv_display_send_vsync_event(d, NULL); d = lv_display_get_next(d); } } @@ -217,6 +218,27 @@ static void lv_nuttx_uv_disp_refr_req_cb(lv_event_t * e) uv_poll_start(&fb_ctx->fb_poll, UV_WRITABLE, lv_nuttx_uv_disp_poll_cb); } +static void lv_nuttx_uv_disp_vsync_request_cb(lv_event_t * e) +{ + lv_nuttx_uv_fb_ctx_t * fb_ctx = lv_event_get_user_data(e); + void * param = lv_event_get_param(e); + + if(param) { + if(fb_ctx->vsync_req_count == 0) { + LV_LOG_INFO("enabled"); + uv_poll_start(&fb_ctx->vsync_poll, UV_PRIORITIZED, lv_nuttx_uv_vsync_poll_cb); + } + fb_ctx->vsync_req_count++; + } + else { + fb_ctx->vsync_req_count--; + if(fb_ctx->vsync_req_count == 0) { + LV_LOG_INFO("disabled"); + uv_poll_stop(&fb_ctx->vsync_poll); + } + } +} + static int lv_nuttx_uv_fb_init(lv_nuttx_uv_t * uv_info, lv_nuttx_uv_ctx_t * uv_ctx) { uv_loop_t * loop = uv_info->loop; @@ -234,15 +256,13 @@ static int lv_nuttx_uv_fb_init(lv_nuttx_uv_t * uv_info, lv_nuttx_uv_ctx_t * uv_c return 0; } - if(!disp->refr_timer) { - LV_LOG_ERROR("disp->refr_timer is NULL"); + if(!lv_display_get_refr_timer(disp)) { + LV_LOG_ERROR("disp refr_timer is NULL"); return -EINVAL; } /* Remove default refr timer. */ - - lv_timer_delete(disp->refr_timer); - disp->refr_timer = NULL; + lv_display_delete_refr_timer(disp); fb_ctx->fb_poll.data = uv_ctx; uv_poll_init(loop, &fb_ctx->fb_poll, fb_ctx->fd); @@ -252,13 +272,12 @@ static int lv_nuttx_uv_fb_init(lv_nuttx_uv_t * uv_info, lv_nuttx_uv_ctx_t * uv_c fb_ctx->vsync_poll.data = uv_ctx; uv_poll_init(loop, &fb_ctx->vsync_poll, fb_ctx->fd); uv_ctx->ref_count++; - uv_poll_start(&fb_ctx->vsync_poll, UV_PRIORITIZED, lv_nuttx_uv_vsync_poll_cb); + lv_display_add_event_cb(disp, lv_nuttx_uv_disp_vsync_request_cb, LV_EVENT_VSYNC_REQUEST, fb_ctx); LV_LOG_USER("lvgl fb loop start OK"); /* Register for the invalidate area event */ - - lv_event_add(&disp->event_list, lv_nuttx_uv_disp_refr_req_cb, LV_EVENT_REFR_REQUEST, fb_ctx); + lv_display_add_event_cb(disp, lv_nuttx_uv_disp_refr_req_cb, LV_EVENT_REFR_REQUEST, fb_ctx); return 0; } diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_profiler.c b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_profiler.c index a17c3a566..63c1a5374 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_profiler.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/nuttx/lv_nuttx_profiler.c @@ -19,7 +19,7 @@ * DEFINES *********************/ -#define TICK_TO_USEC(tick) ((tick) / cpu_freq) +#define TICK_TO_NSEC(tick) ((tick) * 1000 / cpu_freq) /********************** * TYPEDEFS @@ -35,7 +35,7 @@ static uint32_t cpu_freq = 0; /* MHz */ * STATIC VARIABLES **********************/ -static uint32_t tick_get_cb(void); +static uint64_t tick_get_cb(void); static void flush_cb(const char * buf); /********************** @@ -57,7 +57,7 @@ void lv_nuttx_profiler_init(void) lv_profiler_builtin_config_t config; lv_profiler_builtin_config_init(&config); - config.tick_per_sec = 1000000; /* 1 sec = 1000000 usec */ + config.tick_per_sec = 1000000000; /* 1 sec = 1000000000 nsec */ config.tick_get_cb = tick_get_cb; config.flush_cb = flush_cb; lv_profiler_builtin_init(&config); @@ -67,12 +67,12 @@ void lv_nuttx_profiler_init(void) * STATIC FUNCTIONS **********************/ -static uint32_t tick_get_cb(void) +static uint64_t tick_get_cb(void) { static uint32_t prev_tick = 0; - static uint32_t cur_tick_us = 0; + static uint64_t cur_tick_ns = 0; uint32_t act_time = up_perf_gettime(); - uint32_t elaps; + uint64_t elaps; /*If there is no overflow in sys_time simple subtract*/ if(act_time >= prev_tick) { @@ -83,9 +83,9 @@ static uint32_t tick_get_cb(void) elaps += act_time; } - cur_tick_us += TICK_TO_USEC(elaps); + cur_tick_ns += TICK_TO_NSEC(elaps); prev_tick = act_time; - return cur_tick_us; + return cur_tick_ns; } static void flush_cb(const char * buf) 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 d49f765a3..b34e71021 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 @@ -43,6 +43,7 @@ typedef struct { /********************** * STATIC PROTOTYPES **********************/ +static void indev_set_cursor(lv_indev_t * indev, int32_t size); static void touchscreen_read(lv_indev_t * drv, lv_indev_data_t * data); static void touchscreen_delete_cb(lv_event_t * e); static lv_indev_t * touchscreen_init(int fd); @@ -80,6 +81,8 @@ lv_indev_t * lv_nuttx_touchscreen_create(const char * dev_path) close(fd); } + indev_set_cursor(indev, LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE); + return indev; } @@ -87,6 +90,32 @@ lv_indev_t * lv_nuttx_touchscreen_create(const char * dev_path) * STATIC FUNCTIONS **********************/ +static void indev_set_cursor(lv_indev_t * indev, int32_t size) +{ + lv_obj_t * cursor_obj = lv_indev_get_cursor(indev); + if(size <= 0) { + if(cursor_obj) { + lv_obj_delete(cursor_obj); + lv_indev_set_cursor(indev, NULL); + } + } + else { + if(cursor_obj == NULL) { + cursor_obj = lv_obj_create(lv_layer_sys()); + lv_obj_remove_style_all(cursor_obj); + lv_obj_set_style_radius(cursor_obj, LV_RADIUS_CIRCLE, 0); + lv_obj_set_style_bg_opa(cursor_obj, LV_OPA_50, 0); + lv_obj_set_style_bg_color(cursor_obj, lv_color_black(), 0); + lv_obj_set_style_border_width(cursor_obj, 2, 0); + lv_obj_set_style_border_color(cursor_obj, lv_palette_main(LV_PALETTE_GREY), 0); + } + lv_obj_set_size(cursor_obj, size, size); + lv_obj_set_style_translate_x(cursor_obj, -size / 2, 0); + lv_obj_set_style_translate_y(cursor_obj, -size / 2, 0); + lv_indev_set_cursor(indev, cursor_obj); + } +} + static void conv_touch_sample(lv_indev_t * drv, lv_indev_data_t * data, struct touch_sample_s * sample) @@ -163,7 +192,7 @@ static void touchscreen_delete_cb(lv_event_t * e) if(touchscreen) { lv_indev_set_driver_data(indev, NULL); lv_indev_set_read_cb(indev, NULL); - + indev_set_cursor(indev, -1); if(touchscreen->fd >= 0) { close(touchscreen->fd); touchscreen->fd = -1; 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 0bb94d6e3..ac12b7f7c 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 @@ -118,7 +118,7 @@ void lv_sdl_keyboard_handler(SDL_Event * event) /*Find a suitable indev*/ lv_indev_t * indev = lv_indev_get_next(NULL); while(indev) { - if(lv_indev_get_type(indev) == LV_INDEV_TYPE_KEYPAD) { + if(lv_indev_get_read_cb(indev) == sdl_keyboard_read) { /*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; } @@ -143,7 +143,7 @@ void lv_sdl_keyboard_handler(SDL_Event * event) case SDL_TEXTINPUT: { /*Text input*/ const size_t len = lv_strlen(dsc->buf) + lv_strlen(event->text.text); if(len < KEYBOARD_BUFFER_SIZE - 1) - strcat(dsc->buf, event->text.text); + lv_strcat(dsc->buf, event->text.text); } break; default: 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 98b4f695f..e9e1b0387 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 @@ -132,7 +132,7 @@ void lv_sdl_mouse_handler(SDL_Event * event) /*Find a suitable indev*/ lv_indev_t * indev = lv_indev_get_next(NULL); while(indev) { - if(lv_indev_get_type(indev) == LV_INDEV_TYPE_POINTER) { + if(lv_indev_get_read_cb(indev) == sdl_mouse_read) { /*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; } @@ -145,7 +145,7 @@ void lv_sdl_mouse_handler(SDL_Event * event) int32_t hor_res = lv_display_get_horizontal_resolution(disp); int32_t ver_res = lv_display_get_vertical_resolution(disp); - uint8_t zoom = lv_sdl_window_get_zoom(disp); + float zoom = lv_sdl_window_get_zoom(disp); switch(event->type) { case SDL_WINDOWEVENT: @@ -163,13 +163,13 @@ void lv_sdl_mouse_handler(SDL_Event * event) case SDL_MOUSEBUTTONDOWN: if(event->button.button == SDL_BUTTON_LEFT) { indev_dev->left_button_down = true; - indev_dev->last_x = event->motion.x / zoom; - indev_dev->last_y = event->motion.y / zoom; + indev_dev->last_x = (int16_t)((float)(event->motion.x) / zoom); + indev_dev->last_y = (int16_t)((float)(event->motion.y) / zoom); } break; case SDL_MOUSEMOTION: - indev_dev->last_x = event->motion.x / zoom; - indev_dev->last_y = event->motion.y / zoom; + indev_dev->last_x = (int16_t)((float)(event->motion.x) / zoom); + indev_dev->last_y = (int16_t)((float)(event->motion.y) / zoom); break; case SDL_FINGERUP: 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 b31a72309..f0b5f7d96 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 @@ -103,7 +103,7 @@ void lv_sdl_mousewheel_handler(SDL_Event * event) /*Find a suitable indev*/ lv_indev_t * indev = lv_indev_get_next(NULL); while(indev) { - if(lv_indev_get_type(indev) == LV_INDEV_TYPE_ENCODER) { + if(lv_indev_get_read_cb(indev) == sdl_mousewheel_read) { /*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; } 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 df8a28e4e..4429c943e 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 @@ -3,6 +3,10 @@ * */ +/** + * Modified by NXP in 2025 + */ + /********************* * INCLUDES *********************/ @@ -20,11 +24,19 @@ #ifndef __USE_ISOC11 #define __USE_ISOC11 #endif -#include +#ifndef _WIN32 + #include +#else + #include +#endif /* _WIN32 */ #define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/ #include "lv_sdl_private.h" +#if LV_COLOR_DEPTH == 1 && LV_SDL_RENDER_MODE != LV_DISPLAY_RENDER_MODE_PARTIAL + #error SDL LV_COLOR_DEPTH 1 requires LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL +#endif + /********************* * DEFINES *********************/ @@ -46,7 +58,7 @@ typedef struct { uint8_t * rotated_buf; size_t rotated_buf_size; #endif - uint8_t zoom; + float zoom; uint8_t ignore_size_chg; } lv_sdl_window_t; @@ -87,6 +99,7 @@ lv_display_t * lv_sdl_window_create(int32_t hor_res, int32_t ver_res) SDL_StartTextInput(); event_handler_timer = lv_timer_create(sdl_event_handler, 5, NULL); lv_tick_set_cb(SDL_GetTicks); + lv_delay_set_cb(SDL_Delay); inited = true; } @@ -108,12 +121,13 @@ lv_display_t * lv_sdl_window_create(int32_t hor_res, int32_t ver_res) #if LV_USE_DRAW_SDL == 0 if(sdl_render_mode() == LV_DISPLAY_RENDER_MODE_PARTIAL) { - dsc->buf1 = sdl_draw_buf_realloc_aligned(NULL, 32 * 1024); + uint32_t palette_size = LV_COLOR_INDEXED_PALETTE_SIZE(lv_display_get_color_format(disp)) * 4; + uint32_t buffer_size_bytes = 32 * 1024 + palette_size; + dsc->buf1 = sdl_draw_buf_realloc_aligned(NULL, buffer_size_bytes); #if LV_SDL_BUF_COUNT == 2 - dsc->buf2 = sdl_draw_buf_realloc_aligned(NULL, 32 * 1024); + dsc->buf2 = sdl_draw_buf_realloc_aligned(NULL, buffer_size_bytes); #endif - lv_display_set_buffers(disp, dsc->buf1, dsc->buf2, - 32 * 1024, LV_DISPLAY_RENDER_MODE_PARTIAL); + lv_display_set_buffers(disp, dsc->buf1, dsc->buf2, buffer_size_bytes, LV_DISPLAY_RENDER_MODE_PARTIAL); } /*LV_DISPLAY_RENDER_MODE_DIRECT or FULL */ else { @@ -132,7 +146,6 @@ lv_display_t * lv_sdl_window_create(int32_t hor_res, int32_t ver_res) 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); @@ -145,7 +158,7 @@ void lv_sdl_window_set_resizeable(lv_display_t * disp, bool value) SDL_SetWindowResizable(dsc->window, value); } -void lv_sdl_window_set_zoom(lv_display_t * disp, uint8_t zoom) +void lv_sdl_window_set_zoom(lv_display_t * disp, float zoom) { lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); dsc->zoom = zoom; @@ -153,7 +166,7 @@ void lv_sdl_window_set_zoom(lv_display_t * disp, uint8_t zoom) lv_refr_now(disp); } -uint8_t lv_sdl_window_get_zoom(lv_display_t * disp) +float lv_sdl_window_get_zoom(lv_display_t * disp) { lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); return dsc->zoom; @@ -180,6 +193,15 @@ void lv_sdl_window_set_title(lv_display_t * disp, const char * title) SDL_SetWindowTitle(dsc->window, title); } +void lv_sdl_window_set_icon(lv_display_t * disp, void * icon, int32_t width, int32_t height) +{ + lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); + SDL_Surface * iconSurface = SDL_CreateRGBSurfaceWithFormatFrom(icon, width, height, 32, width * 4, + SDL_PIXELFORMAT_ARGB8888); + SDL_SetWindowIcon(dsc->window, iconSurface); + SDL_FreeSurface(iconSurface); +} + void * lv_sdl_window_get_renderer(lv_display_t * disp) { lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); @@ -208,72 +230,73 @@ static inline int sdl_render_mode(void) 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); lv_color_format_t cf = lv_display_get_color_format(disp); + uint32_t * argb_px_map = NULL; 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; + if(cf == LV_COLOR_FORMAT_RGB565_SWAPPED) { + uint32_t width = lv_area_get_width(area); + uint32_t height = lv_area_get_height(area); + lv_draw_sw_rgb565_swap(px_map, width * height); + } + /*Update values in a special OLED I1 --> ARGB8888 case + We render everything in I1, but display it in ARGB8888*/ + if(cf == LV_COLOR_FORMAT_I1) { + /*I1 uses 1 bit wide pixels, ARGB8888 uses 4 byte wide pixels*/ + cf = LV_COLOR_FORMAT_ARGB8888; + uint32_t width = lv_area_get_width(area); + uint32_t height = lv_area_get_height(area); + uint32_t argb_px_map_size = width * height * 4; + argb_px_map = malloc(argb_px_map_size); + if(argb_px_map == NULL) { + LV_LOG_ERROR("malloc failed"); + lv_display_flush_ready(disp); + return; } - - 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; + /* skip the palette */ + px_map += LV_COLOR_INDEXED_PALETTE_SIZE(LV_COLOR_FORMAT_I1) * 4; + lv_draw_sw_i1_to_argb8888(px_map, argb_px_map, width, height, width / 8, width * 4, 0xFF000000u, 0xFFFFFFFFu); + px_map = (uint8_t *)argb_px_map; } + lv_area_t rotated_area = *area; + lv_display_rotate_area(disp, &rotated_area); + + int32_t px_map_w = lv_area_get_width(area); + int32_t px_map_h = lv_area_get_height(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; + uint32_t px_size = lv_color_format_get_size(cf); - uint8_t * fb_tmp = dsc->fb_act; - uint32_t fb_stride = disp->hor_res * px_size; - fb_tmp += area->y1 * fb_stride; - fb_tmp += area->x1 * px_size; + int32_t fb_stride = lv_draw_buf_width_to_stride(disp->hor_res, cf); + uint8_t * fb_start = dsc->fb_act; + fb_start += rotated_area.y1 * fb_stride + rotated_area.x1 * px_size; + lv_display_rotation_t rotation = lv_display_get_rotation(disp); - int32_t y; - for(y = area->y1; y <= area->y2; y++) { - lv_memcpy(fb_tmp, px_map, px_map_line_bytes); - px_map += px_map_stride; - fb_tmp += fb_stride; + if(rotation == LV_DISPLAY_ROTATION_0) { + uint32_t px_map_line_bytes = lv_area_get_width(area) * px_size; + + int32_t y; + for(y = area->y1; y <= area->y2; y++) { + lv_memcpy(fb_start, px_map, px_map_line_bytes); + px_map += px_map_stride; + fb_start += fb_stride; + } + } + else { + lv_draw_sw_rotate(px_map, fb_start, px_map_w, px_map_h, px_map_stride, fb_stride, rotation, cf); } } - /* 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(sdl_render_mode() != LV_DISPLAY_RENDER_MODE_PARTIAL) { dsc->fb_act = px_map; } + window_update(disp); } + free(argb_px_map); #else LV_UNUSED(area); LV_UNUSED(px_map); @@ -316,7 +339,9 @@ static void sdl_event_handler(lv_timer_t * t) break; case SDL_WINDOWEVENT_RESIZED: dsc->ignore_size_chg = 1; - lv_display_set_resolution(disp, event.window.data1 / dsc->zoom, event.window.data2 / dsc->zoom); + int32_t hres = (int32_t)((float)(event.window.data1) / dsc->zoom); + int32_t vres = (int32_t)((float)(event.window.data2) / dsc->zoom); + lv_display_set_resolution(disp, hres, vres); dsc->ignore_size_chg = 0; lv_refr_now(disp); break; @@ -341,18 +366,18 @@ static void sdl_event_handler(lv_timer_t * t) static void window_create(lv_display_t * disp) { lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); - dsc->zoom = 1; + dsc->zoom = 1.0; int flag = SDL_WINDOW_RESIZABLE; #if LV_SDL_FULLSCREEN flag |= SDL_WINDOW_FULLSCREEN; #endif - int32_t hor_res = disp->hor_res; - int32_t ver_res = disp->ver_res; + int32_t hor_res = (int32_t)((float)(disp->hor_res) * dsc->zoom); + int32_t ver_res = (int32_t)((float)(disp->ver_res) * dsc->zoom); 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*/ + hor_res, ver_res, flag); /*last param. SDL_WINDOW_BORDERLESS to hide borders*/ dsc->renderer = SDL_CreateRenderer(dsc->window, -1, LV_SDL_ACCELERATED ? SDL_RENDERER_ACCELERATED : SDL_RENDERER_SOFTWARE); @@ -361,12 +386,11 @@ static void window_create(lv_display_t * disp) uint32_t px_size = lv_color_format_get_size(lv_display_get_color_format(disp)); lv_memset(dsc->fb1, 0xff, hor_res * ver_res * px_size); -#if LV_SDL_BUF_COUNT == 2 - lv_memset(dsc->fb2, 0xff, hor_res * ver_res * px_size); -#endif + if(dsc->fb2) lv_memset(dsc->fb2, 0xff, hor_res * ver_res * px_size); + #endif /*LV_USE_DRAW_SDL == 0*/ /*Some platforms (e.g. Emscripten) seem to require setting the size again */ - SDL_SetWindowSize(dsc->window, hor_res * dsc->zoom, ver_res * dsc->zoom); + SDL_SetWindowSize(dsc->window, hor_res, ver_res); #if LV_USE_DRAW_SDL == 0 texture_resize(disp); #endif /*LV_USE_DRAW_SDL == 0*/ @@ -377,7 +401,11 @@ 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 = disp->hor_res; - uint32_t stride = lv_draw_buf_width_to_stride(hor_res, lv_display_get_color_format(disp)); + lv_color_format_t cf = lv_display_get_color_format(disp); + if(cf == LV_COLOR_FORMAT_I1) { + cf = LV_COLOR_FORMAT_ARGB8888; + } + uint32_t stride = lv_draw_buf_width_to_stride(hor_res, cf); SDL_UpdateTexture(dsc->texture, NULL, dsc->fb_act, stride); SDL_RenderClear(dsc->renderer); @@ -391,7 +419,14 @@ static void window_update(lv_display_t * disp) #if LV_USE_DRAW_SDL == 0 static void texture_resize(lv_display_t * disp) { - uint32_t stride = lv_draw_buf_width_to_stride(disp->hor_res, lv_display_get_color_format(disp)); + lv_color_format_t cf = lv_display_get_color_format(disp); + /*In some cases SDL stride might be different than LVGL render stride, like in I1 format. + SDL still uses ARGB8888 as the color format, but LVGL renders in I1, thus causing a mismatch + This ensures correct stride for SDL buffers in this case.*/ + if(cf == LV_COLOR_FORMAT_I1) { + cf = LV_COLOR_FORMAT_ARGB8888; + } + uint32_t stride = lv_draw_buf_width_to_stride(disp->hor_res, cf); lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); dsc->fb1 = sdl_draw_buf_realloc_aligned(dsc->fb1, stride * disp->ver_res); @@ -409,7 +444,7 @@ static void texture_resize(lv_display_t * disp) } if(dsc->texture) SDL_DestroyTexture(dsc->texture); -#if LV_COLOR_DEPTH == 32 +#if LV_COLOR_DEPTH == 32 || LV_COLOR_DEPTH == 1 SDL_PixelFormatEnum px_format = SDL_PIXELFORMAT_RGB888; /*same as SDL_PIXELFORMAT_RGB888, but it's not supported in older versions*/ #elif LV_COLOR_DEPTH == 24 @@ -419,7 +454,6 @@ static void texture_resize(lv_display_t * disp) #else #error("Unsupported color format") #endif - // px_format = SDL_PIXELFORMAT_BGR24; dsc->texture = SDL_CreateTexture(dsc->renderer, px_format, SDL_TEXTUREACCESS_STATIC, disp->hor_res, disp->ver_res); @@ -460,7 +494,8 @@ static void res_chg_event_cb(lv_event_t * e) lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); if(dsc->ignore_size_chg == false) { - SDL_SetWindowSize(dsc->window, disp->hor_res * dsc->zoom, disp->ver_res * dsc->zoom); + SDL_SetWindowSize(dsc->window, + (int)((float)(disp->hor_res)*dsc->zoom), (int)((float)(disp->ver_res)*dsc->zoom)); } #if LV_USE_DRAW_SDL == 0 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 f2e243cdd..eb78d9b30 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,6 +3,10 @@ * */ +/** + * Modified by NXP in 2025 + */ + #ifndef LV_SDL_WINDOW_H #define LV_SDL_WINDOW_H @@ -39,12 +43,14 @@ lv_display_t * lv_sdl_window_create(int32_t hor_res, int32_t ver_res); void lv_sdl_window_set_resizeable(lv_display_t * disp, bool value); -void lv_sdl_window_set_zoom(lv_display_t * disp, uint8_t zoom); +void lv_sdl_window_set_zoom(lv_display_t * disp, float zoom); -uint8_t lv_sdl_window_get_zoom(lv_display_t * disp); +float lv_sdl_window_get_zoom(lv_display_t * disp); void lv_sdl_window_set_title(lv_display_t * disp, const char * title); +void lv_sdl_window_set_icon(lv_display_t * disp, void * icon, int32_t width, int32_t height); + void * lv_sdl_window_get_renderer(lv_display_t * disp); void lv_sdl_quit(void); @@ -53,6 +59,7 @@ void lv_sdl_quit(void); * MACROS **********************/ + #endif /* LV_DRV_SDL */ #ifdef __cplusplus diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi.h b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi.h new file mode 100644 index 000000000..6302555c1 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi.h @@ -0,0 +1,106 @@ +/** + * @file lv_uefi.h + * + */ + +#ifndef LV_UEFI_H +#define LV_UEFI_H + +#if LV_USE_UEFI + + #include LV_USE_UEFI_INCLUDE + + #if defined(__clang__) || defined(__GNUC__) + #if defined(__x86_64__) + #define __LV_UEFI_ARCH_X64__ + #define __LV_UEFI_64BIT__ + #elif defined(__i386__) + #define __LV_UEFI_ARCH_X86__ + #define __LV_UEFI_32BIT__ + #elif defined(__aarch64__) + #define __LV_UEFI_ARCH_AARCH64__ + #define __LV_UEFI_64BIT__ + #else + #error Architecture is not supported + #endif + #define LV_UEFI_STATIC_ASSERT _Static_assert + #elif defined(_MSC_VER) + #if defined(_M_AMD64) && !defined(_M_ARM64) + #define __LV_UEFI_ARCH_X64__ + #define __LV_UEFI_64BIT__ + #elif defined(_M_IX86) + #define __LV_UEFI_ARCH_X86__ + #define __LV_UEFI_32BIT__ + #elif defined(_M_ARM64) + #define __LV_UEFI_ARCH_AARCH64__ + #define __LV_UEFI_64BIT__ + #else + #error Architecture is not supported + #endif + #define LV_UEFI_STATIC_ASSERT static_assert + #else + #error Your compiler is not supported + #endif + + #ifdef LV_USE_UEFI_INCLUDE + #include LV_USE_UEFI_INCLUDE + #else + #error No UEFI headers available + #endif + + // Verify that all required protocols are known + #if !defined(EFI_LOADED_IMAGE_PROTOCOL_GUID) + #error Missing support for EFI_LOADED_IMAGE_PROTOCOL + #endif + #if !defined(EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID) + #error Missing support for EFI_SIMPLE_FILE_SYSTEM_PROTOCOL + #endif + #if !defined(EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID) + #error Missing support for EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL + #endif + #if !defined(EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID) + #error Missing support for EFI_SIMPLE_TEXT_INPUT_PROTOCOL + #endif + #if !defined(EFI_SIMPLE_POINTER_PROTOCOL_GUID) + #error Missing support for EFI_SIMPLE_POINTER_PROTOCOL + #endif + #if !defined(EFI_ABSOLUTE_POINTER_PROTOCOL_GUID) + #error Missing support for EFI_ABSOLUTE_POINTER_PROTOCOL + #endif + #if !defined(EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID) + #error Missing support for EFI_GRAPHICS_OUTPUT_PROTOCOL + #endif + #if !defined(EFI_EDID_ACTIVE_PROTOCOL_GUID) + #error Missing support for EFI_EDID_ACTIVE_PROTOCOL + #endif + #if !defined(EFI_FILE_INFO_ID) + #error Missing support for EFI_FILE_INFO + #endif + #if !defined(EFI_TIMESTAMP_PROTOCOL_GUID) + #error Missing support for EFI_TIMESTAMP_PROTOCOL_GUID + #endif + + // Verify that all types have the correct size + LV_UEFI_STATIC_ASSERT(sizeof(BOOLEAN) == 1, "Size check for 'BOOLEAN' failed."); + LV_UEFI_STATIC_ASSERT(sizeof(INT8) == 1, "Size check for 'INT8' failed."); + LV_UEFI_STATIC_ASSERT(sizeof(UINT8) == 1, "Size check for 'UINT8' failed."); + LV_UEFI_STATIC_ASSERT(sizeof(INT16) == 2, "Size check for 'INT16' failed."); + LV_UEFI_STATIC_ASSERT(sizeof(UINT16) == 2, "Size check for 'UINT16' failed."); + LV_UEFI_STATIC_ASSERT(sizeof(INT32) == 4, "Size check for 'INT32' failed."); + LV_UEFI_STATIC_ASSERT(sizeof(UINT32) == 4, "Size check for 'UINT32' failed."); + LV_UEFI_STATIC_ASSERT(sizeof(INT64) == 8, "Size check for 'INT64' failed."); + LV_UEFI_STATIC_ASSERT(sizeof(UINT64) == 8, "Size check for 'UINT64' failed."); + LV_UEFI_STATIC_ASSERT(sizeof(CHAR8) == 1, "Size check for 'CHAR8' failed."); + LV_UEFI_STATIC_ASSERT(sizeof(CHAR16) == 2, "Size check for 'CHAR16' failed."); + + #ifdef __LV_UEFI_32BIT__ + LV_UEFI_STATIC_ASSERT(sizeof(INTN) == 4, "Size check for 'INTN' failed."); + LV_UEFI_STATIC_ASSERT(sizeof(UINTN) == 4, "Size check for 'UINTN' failed."); + #else + LV_UEFI_STATIC_ASSERT(sizeof(INTN) == 8, "Size check for 'INTN' failed."); + LV_UEFI_STATIC_ASSERT(sizeof(UINTN) == 8, "Size check for 'UINTN' failed."); + #endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_context.c b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_context.c new file mode 100644 index 000000000..03d89cef1 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_context.c @@ -0,0 +1,91 @@ +/** + * @file lv_uefi_context.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "../../lvgl.h" + +#if LV_USE_UEFI + +#include "lv_uefi_context.h" +#include "lv_uefi_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * GOLBAL VARIABLES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * @brief Initialize the UEFI cache variables. + * @param image_handle The handle of the current image + * @param system_table Pointer to the system table + * @remark This has to be called before lv_init(). +*/ +void lv_uefi_init(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * system_table) +{ + LV_ASSERT_NULL(image_handle); + LV_ASSERT_NULL(system_table); + + gLvEfiImageHandle = image_handle; + gLvEfiST = system_table; + gLvEfiBS = gLvEfiST->BootServices; + gLvEfiRT = gLvEfiST->RuntimeServices; +} + +/** + * @brief Initialize the LVGL UEFI backend. + * @remark This is a private API which is used for LVGL UEFI backend + * implementation. LVGL users shouldn't use that because the + * LVGL has already used it in lv_init. + */ +void lv_uefi_platform_init(void) +{ + LV_ASSERT_NULL(gLvEfiImageHandle); + LV_ASSERT_NULL(gLvEfiST); + LV_ASSERT_NULL(gLvEfiBS); + LV_ASSERT_NULL(gLvEfiRT); +} + +/** + * @brief Cleanup the LVGL UEFI backend. + * @remark This is a private API which is used for LVGL UEFI backend + * implementation. LVGL users shouldn't use that because the + * LVGL has already used it in lv_deinit. +*/ +void lv_uefi_platform_deinit(void) +{ + ; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_context.h b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_context.h new file mode 100644 index 000000000..392d339b2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_context.h @@ -0,0 +1,71 @@ +/** + * @file lv_uefi_context.h + * + */ + +#ifndef __LV_UEFI_CONTEXT_H__ +#define __LV_UEFI_CONTEXT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lvgl.h" + +#if LV_USE_UEFI + +#include "lv_uefi.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * @brief Initialize the UEFI cache variables. + * @param image_handle The handle of the current image + * @param system_table Pointer to the system table + * @remark This has to be called before lv_init(). +*/ +void lv_uefi_init( + EFI_HANDLE image_handle, + EFI_SYSTEM_TABLE * system_table); + +/** + * @brief Initialize the LVGL UEFI backend. + * @remark This is a private API which is used for LVGL UEFI backend + * implementation. LVGL users shouldn't use that because the + * LVGL has already used it in lv_init. +*/ +void lv_uefi_platform_init(void); + +/** + * @brief Cleanup the LVGL UEFI backend. + * @remark This is a private API which is used for LVGL UEFI backend + * implementation. LVGL users shouldn't use that because the + * LVGL has already used it in lv_deinit. +*/ +void lv_uefi_platform_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif //__LV_UEFI_CONTEXT_H__ \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_display.c b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_display.c new file mode 100644 index 000000000..8fa807ee8 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_display.c @@ -0,0 +1,284 @@ +/** + * @file lv_uefi_display.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "../../lvgl.h" + +#if LV_USE_UEFI + +#include "lv_uefi_display.h" +#include "lv_uefi_private.h" + +#if LV_COLOR_DEPTH != 32 + #error [lv_uefi] Unsupported LV_COLOR_DEPTH. +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef struct _lv_uefi_display_context_t { + EFI_HANDLE handle; + EFI_GRAPHICS_OUTPUT_PROTOCOL * gop_protocol; + void * buffer; + size_t buffer_size; +} lv_uefi_display_context_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void _display_event_cb(lv_event_t * e); +static void _display_flush_cb(lv_display_t * display, const lv_area_t * area, uint8_t * px_map); + +static void _display_ctx_free(lv_uefi_display_context_t * display_ctx); +static bool _display_interface_is_valid(const EFI_GRAPHICS_OUTPUT_PROTOCOL * interface); + +/********************** + * GOLBAL VARIABLES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +static EFI_GUID _uefi_guid_graphics_output = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; +static EFI_GUID _uefi_guid_edid_active = EFI_EDID_ACTIVE_PROTOCOL_GUID; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * @brief Create a LVGL display object. + * @param handle The handle on which an instance of the EFI_GRAPHICS_OUTPUT_PROTOCOL protocol is installed. + * @return The created LVGL display object. + */ +lv_display_t * lv_uefi_display_create(void * handle) +{ + lv_display_t * display = NULL; + lv_uefi_display_context_t * display_ctx; + + if(!lv_uefi_protocol_test(handle, &_uefi_guid_graphics_output)) return NULL; + + display_ctx = lv_calloc(1, sizeof(lv_uefi_display_context_t)); + LV_ASSERT_MALLOC(display_ctx); + + display_ctx->handle = handle; + display_ctx->gop_protocol = (EFI_GRAPHICS_OUTPUT_PROTOCOL *)lv_uefi_protocol_open(handle, &_uefi_guid_graphics_output); + if(!_display_interface_is_valid(display_ctx->gop_protocol)) { + LV_LOG_WARN("[lv_uefi] The GOP interface is not valid."); + goto error; + } + + // 4 bytes per pixel + display_ctx->buffer_size = 4 * display_ctx->gop_protocol->Mode->Info->HorizontalResolution * + display_ctx->gop_protocol->Mode->Info->VerticalResolution; + display_ctx->buffer = lv_malloc(display_ctx->buffer_size); + LV_ASSERT_MALLOC(display_ctx->buffer); + + display = lv_display_create(display_ctx->gop_protocol->Mode->Info->HorizontalResolution, + display_ctx->gop_protocol->Mode->Info->VerticalResolution); + lv_display_add_event_cb(display, _display_event_cb, LV_EVENT_DELETE, display); + lv_display_set_flush_cb(display, _display_flush_cb); + lv_display_set_buffers(display, display_ctx->buffer, NULL, (uint32_t)display_ctx->buffer_size, + LV_DISPLAY_RENDER_MODE_DIRECT); + lv_display_set_user_data(display, display_ctx); + + goto finish; + +error: + if(display != NULL) { + lv_display_set_user_data(display, NULL); + lv_display_delete(display); + display = NULL; + } + + if(display_ctx != NULL) _display_ctx_free(display_ctx); + +finish: + return display; +} + +/** + * @brief Try to find the active display handle. + * @return The handle or NULL if not found. + * @remark The active display need interfaces for EFI_GRAPHICS_OUTPUT_PROTOCOL and EFI_EDID_ACTIVE_PROTOCOL +*/ +void * lv_uefi_display_get_active(void) +{ + EFI_STATUS status; + EFI_HANDLE active_handle = NULL; + EFI_HANDLE * handles = NULL; + UINTN no_handles; + UINTN index; + + status = gLvEfiBS->LocateHandleBuffer( + ByProtocol, + &_uefi_guid_graphics_output, + NULL, + &no_handles, + &handles); + if(status != EFI_SUCCESS) goto error; + + for(index = 0; index < no_handles; index++) { + if(!lv_uefi_protocol_test(handles[index], &_uefi_guid_edid_active)) continue; + if(!lv_uefi_protocol_test(handles[index], &_uefi_guid_graphics_output)) continue; + active_handle = handles[index]; + break; + } + + goto finish; + +error: + +finish: + if(handles != NULL) gLvEfiBS->FreePool(handles); + + return active_handle; +} + +/** + * @brief Try to find any display handle. + * @return The handle or NULL if not found. +*/ +void * lv_uefi_display_get_any(void) +{ + EFI_STATUS status; + EFI_HANDLE active_handle = NULL; + EFI_HANDLE * handles = NULL; + UINTN no_handles; + UINTN index; + + status = gLvEfiBS->LocateHandleBuffer( + ByProtocol, + &_uefi_guid_graphics_output, + NULL, + &no_handles, + &handles); + if(status != EFI_SUCCESS) goto error; + + for(index = 0; index < no_handles; index++) { + if(!lv_uefi_protocol_test(handles[index], &_uefi_guid_graphics_output)) continue; + active_handle = handles[index]; + break; + } + + goto finish; + +error: + +finish: + if(handles != NULL) gLvEfiBS->FreePool(handles); + + return active_handle; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void _display_event_cb(lv_event_t * e) +{ + lv_display_t * display; + lv_uefi_display_context_t * display_ctx; + + if(lv_event_get_code(e) != LV_EVENT_DELETE) return; + + display = (lv_display_t *)lv_event_get_user_data(e); + if(display == NULL) return; + + display_ctx = (lv_uefi_display_context_t *)lv_display_get_user_data(display); + lv_display_set_user_data(display, NULL); + + if(display_ctx != NULL) _display_ctx_free(display_ctx); +} + +static void _display_flush_cb(lv_display_t * display, const lv_area_t * area, uint8_t * px_map) +{ + EFI_STATUS status; + int32_t w; + int32_t h; + + lv_uefi_display_context_t * display_ctx = (lv_uefi_display_context_t *)lv_display_get_user_data(display); + LV_ASSERT_NULL(display_ctx); + + w = (int32_t)area->x2 - (int32_t)area->x1 + 1; + h = (int32_t)area->y2 - (int32_t)area->y1 + 1; + + if(w < 0 || h < 0) { + LV_LOG_ERROR("[lv_uefi] Invalid lv_display_flush_cb call (invalid rect)."); + goto error; + } + + if((uint32_t)(area->x1 + w) > display_ctx->gop_protocol->Mode->Info->HorizontalResolution) { + LV_LOG_ERROR("[lv_uefi] Invalid lv_display_flush_cb call (invalid width)."); + goto error; + } + + if((uint32_t)(area->y1 + h) > display_ctx->gop_protocol->Mode->Info->HorizontalResolution) { + LV_LOG_ERROR("[lv_uefi] Invalid lv_display_flush_cb call (invalid height)."); + goto error; + } + + status = display_ctx->gop_protocol->Blt( + display_ctx->gop_protocol, + (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)px_map, + EfiBltBufferToVideo, + area->x1, + area->y1, + area->x1, + area->y1, + w, + h, + display_ctx->gop_protocol->Mode->Info->HorizontalResolution * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + if(status != EFI_SUCCESS) { + LV_LOG_ERROR("[lv_uefi] Blt failed with error code: %llx.", status); + goto error; + } + + goto finish; + +error: + +finish: + lv_display_flush_ready(display); +} + +static void _display_ctx_free(lv_uefi_display_context_t * display_ctx) +{ + if(display_ctx == NULL) { + return; + } + + if(display_ctx->gop_protocol != NULL) lv_uefi_protocol_close(display_ctx->handle, &_uefi_guid_graphics_output); + if(display_ctx->buffer != NULL) lv_free(display_ctx->buffer); + + lv_free(display_ctx); +} + +static bool _display_interface_is_valid(const EFI_GRAPHICS_OUTPUT_PROTOCOL * interface) +{ + if(interface == NULL) return FALSE; + if(interface->Mode == NULL) return FALSE; + if(interface->Mode->Info == NULL) return FALSE; + if(interface->Mode->Info->HorizontalResolution == 0) return FALSE; + if(interface->Mode->Info->HorizontalResolution >= 32767) return FALSE; + if(interface->Mode->Info->VerticalResolution == 0) return FALSE; + if(interface->Mode->Info->VerticalResolution >= 32767) return FALSE; + + return TRUE; +} +#endif \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_display.h b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_display.h new file mode 100644 index 000000000..e56fb2ee2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_display.h @@ -0,0 +1,65 @@ +/** + * @file lv_uefi_display.h + * + */ + +#ifndef __LV_UEFI_DISPLAY_H__ +#define __LV_UEFI_DISPLAY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" + +#if LV_USE_UEFI + +#include "lv_uefi.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * @brief Create a LVGL display object. + * @param handle The handle on which an instance of the EFI_GRAPHICS_OUTPUT_PROTOCOL protocol is installed. + * @return The created LVGL display object. +*/ +lv_display_t * lv_uefi_display_create(void * handle); + +/** + * @brief Try to find the active display handle. + * @return The handle or NULL if not found. + * @remark The active display need interfaces for EFI_GRAPHICS_OUTPUT_PROTOCOL and EFI_EDID_ACTIVE_PROTOCOL +*/ +void * lv_uefi_display_get_active(void); + +/** + * @brief Try to find any display handle. + * @return The handle or NULL if not found. +*/ +void * lv_uefi_display_get_any(void); + +/********************** + * MACROS + **********************/ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif //__LV_UEFI_DISPLAY_H__ \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_edk2.h b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_edk2.h new file mode 100644 index 000000000..870b99782 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_edk2.h @@ -0,0 +1,28 @@ +/** + * @file lv_uefi_edk2.h + * + */ + +#ifndef LV_UEFI_EDK2_H +#define LV_UEFI_EDK2_H + +#if LV_USE_UEFI + + #define LV_UEFI_EDK2_HEADERS 1 + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_gnu_efi.h b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_gnu_efi.h new file mode 100644 index 000000000..23e9e4955 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_gnu_efi.h @@ -0,0 +1,17 @@ +/** + * @file lv_uefi_gnu_efi.h + * + */ + +#ifndef LV_UEFI_GNU_EFI_H +#define LV_UEFI_GNU_EFI_H + +#if LV_USE_UEFI + + #define LV_UEFI_GNU_EFI_HEADERS 1 + + #include + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev.h b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev.h new file mode 100644 index 000000000..69dee2fc2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev.h @@ -0,0 +1,108 @@ +/** + * @file lv_uefi_indev.h + * + */ + +#ifndef __LV_UEFI_INDEV_H__ +#define __LV_UEFI_INDEV_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../indev/lv_indev.h" + +#if LV_USE_UEFI + +#include "lv_uefi.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * @brief Create an indev object. + * @param display_res The resolution of the display in pixels, needed to scale the input. + * If NULL the resolution of the current default display will be used. + * @return The created LVGL indev object. +*/ +lv_indev_t * lv_uefi_simple_pointer_indev_create(lv_point_t * display_res); + +/** + * @brief Add an EFI_SIMPLE_POINTER_PROTOCOL interface to the indev. + * @param indev Indev that was created with lv_uefi_simple_pointer_indev_create. + * @param handle The handle on which an instance of the EFI_SIMPLE_POINTER_PROTOCOL protocol is installed. + * @return True if the interface was added. +*/ +bool lv_uefi_simple_pointer_indev_add_handle(lv_indev_t * indev, EFI_HANDLE handle); + +/** + * @brief Add all available EFI_SIMPLE_POINTER_PROTOCOL interfaces to the indev. + * @param indev Indev that was created with lv_uefi_simple_pointer_indev_create. +*/ +void lv_uefi_simple_pointer_indev_add_all(lv_indev_t * indev); + +/** + * @brief Create a LVGL indev object. + * @param display_res The resolution of the display in pixels, needed to scale the input. + * @return The created LVGL indev object. +*/ +lv_indev_t * lv_uefi_absolute_pointer_indev_create(lv_point_t * display_res); + +/** + * @brief Add an EFI_ABSOLUTE_POINTER_PROTOCOL interface to the indev. + * @param indev Indev that was created with lv_uefi_absolute_pointer_indev_create. + * @param handle The handle on which an instance of the EFI_ABSOLUTE_POINTER_PROTOCOL protocol is installed. + * @return True if the interface was added. +*/ +bool lv_uefi_absolute_pointer_indev_add_handle(lv_indev_t * indev, EFI_HANDLE handle); + +/** + * @brief Add all available EFI_ABSOLUTE_POINTER_PROTOCOL interfaces to the indev. + * @param indev Indev that was created with lv_uefi_absolute_pointer_indev_create. +*/ +void lv_uefi_absolute_pointer_indev_add_all(lv_indev_t * indev); + +/** + * @brief Create an indev object. + * @return The created LVGL indev object. +*/ +lv_indev_t * lv_uefi_simple_text_input_indev_create(void); + +/** + * @brief Add an EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL interface to the indev. + * @param indev Indev that was created with lv_uefi_simple_text_input_indev_create. + * @param handle The handle on which an instance of the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL protocol is installed. + * @return True if the interface was added. +*/ +bool lv_uefi_simple_text_input_indev_add_handle(lv_indev_t * indev, EFI_HANDLE handle); + +/** + * @brief Add all available EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL interfaces to the indev. + * @param indev Indev that was created with lv_uefi_simple_text_input_indev_create. +*/ +void lv_uefi_simple_text_input_indev_add_all(lv_indev_t * indev); + +/********************** + * MACROS + **********************/ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif //__LV_UEFI_INDEV_H__ \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev_keyboard.c b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev_keyboard.c new file mode 100644 index 000000000..83e99b58f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev_keyboard.c @@ -0,0 +1,346 @@ +/** + * @file lv_uefi_indev.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "../../lvgl.h" +#include "../../stdlib/lv_mem.h" +#include "../../misc/lv_types.h" +#include "../../misc/lv_text.h" + +#if LV_USE_UEFI + +#include "lv_uefi_indev.h" +#include "lv_uefi_private.h" + +/********************* + * DEFINES + *********************/ + +#define SIMPLE_TEXT_INPUT_INDEV_SIGNATURE 0x53495449 + +/********************** + * TYPEDEFS + **********************/ + +typedef struct _lv_uefi_simple_text_input_key_cache_t { + uint32_t key; /**< Key code*/ + bool pressed; /**< If true this is a pressed entry if false this is a release entry*/ +} lv_uefi_simple_text_input_key_cache_t; + +typedef struct _lv_uefi_simple_text_input_handle_context_t { + EFI_HANDLE handle; + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL * interface; +} lv_uefi_simple_text_input_handle_context_t; + +typedef struct _lv_uefi_simple_text_input_context_t { + uint32_t signature; /**< Has to be checked to avoid access to a different indev*/ + lv_ll_t handles; + lv_ll_t key_cache; +} lv_uefi_simple_text_input_context_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void _simple_text_input_event_cb(lv_event_t * e); +static void _simple_text_input_read_cb(lv_indev_t * indev, lv_indev_data_t * data); + +static void _simple_text_input_handle_context_free(void * ptr); +static void _simple_text_input_context_free(lv_uefi_simple_text_input_context_t * indev_ctx); + +static bool _simple_text_input_interface_is_valid(const EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL * interface); + +static void _simple_text_input_read(lv_uefi_simple_text_input_context_t * indev_ctx, + lv_uefi_simple_text_input_handle_context_t * handle_ctx); + +static uint32_t _utf8_from_unicode(UINT32 unicode); +static uint32_t _key_from_uefi_key(const EFI_KEY_DATA * key); + +/********************** + * STATIC VARIABLES + **********************/ + +static EFI_GUID _uefi_guid_simple_text_input = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * @brief Create an indev object. + * @return The created LVGL indev object. +*/ +lv_indev_t * lv_uefi_simple_text_input_indev_create(void) +{ + lv_indev_t * indev = NULL; + lv_uefi_simple_text_input_context_t * indev_ctx = NULL; + + indev_ctx = lv_calloc(1, sizeof(lv_uefi_simple_text_input_context_t)); + LV_ASSERT_MALLOC(indev_ctx); + + indev_ctx->signature = SIMPLE_TEXT_INPUT_INDEV_SIGNATURE; + + lv_ll_init(&indev_ctx->handles, sizeof(lv_uefi_simple_text_input_handle_context_t)); + lv_ll_init(&indev_ctx->key_cache, sizeof(lv_uefi_simple_text_input_key_cache_t)); + + indev = lv_indev_create(); + lv_indev_set_type(indev, LV_INDEV_TYPE_KEYPAD); + lv_indev_set_user_data(indev, indev_ctx); + lv_indev_add_event_cb(indev, _simple_text_input_event_cb, LV_EVENT_DELETE, indev); + lv_indev_set_read_cb(indev, _simple_text_input_read_cb); + + return indev; +} + +/** + * @brief Add an EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL interface to the indev. + * @param indev Indev that was created with lv_uefi_simple_text_input_indev_create. + * @param handle The handle on which an instance of the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL protocol is installed. + * @return True if the interface was added. +*/ +bool lv_uefi_simple_text_input_indev_add_handle(lv_indev_t * indev, EFI_HANDLE handle) +{ + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL * interface = NULL; + lv_uefi_simple_text_input_handle_context_t * handle_ctx = NULL; + + lv_uefi_simple_text_input_context_t * indev_ctx = (lv_uefi_simple_text_input_context_t *)lv_indev_get_user_data(indev); + LV_ASSERT_NULL(indev_ctx); + + if(indev_ctx->signature != SIMPLE_TEXT_INPUT_INDEV_SIGNATURE) return false; + + interface = (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *)lv_uefi_protocol_open(handle, &_uefi_guid_simple_text_input); + if(!_simple_text_input_interface_is_valid(interface)) { + lv_uefi_protocol_close(handle, &_uefi_guid_simple_text_input); + LV_LOG_WARN("[lv_uefi] The SIMPLE_TEXT_INPUT interface is not valid."); + return false; + } + + handle_ctx = (lv_uefi_simple_text_input_handle_context_t *) lv_ll_ins_head(&indev_ctx->handles); + LV_ASSERT_MALLOC(handle_ctx); + + handle_ctx->handle = handle; + handle_ctx->interface = interface; + + return true; +} + +/** + * @brief Add all available EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL interfaces to the indev. + * @param indev Indev that was created with lv_uefi_simple_text_input_indev_create. +*/ +void lv_uefi_simple_text_input_indev_add_all(lv_indev_t * indev) +{ + EFI_STATUS status; + EFI_HANDLE * handles = NULL; + UINTN no_handles; + UINTN index; + + lv_uefi_simple_text_input_context_t * indev_ctx = (lv_uefi_simple_text_input_context_t *)lv_indev_get_user_data(indev); + LV_ASSERT_NULL(indev_ctx); + + if(indev_ctx->signature != SIMPLE_TEXT_INPUT_INDEV_SIGNATURE) return; + + status = gLvEfiBS->LocateHandleBuffer(ByProtocol, &_uefi_guid_simple_text_input, NULL, &no_handles, &handles); + if(status != EFI_SUCCESS) { + LV_LOG_ERROR("[lv_uefi] LocateHandleBuffer(SIMPLE_TEXT_INPUT_EX) failed with error code %llx.", status); + return; + } + + for(index = 0; index < no_handles; index++) { + lv_uefi_simple_text_input_indev_add_handle(indev, handles[index]); + } + + if(handles != NULL) gLvEfiBS->FreePool(handles); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void _simple_text_input_event_cb(lv_event_t * e) +{ + lv_indev_t * indev; + lv_uefi_simple_text_input_context_t * indev_ctx; + + if(lv_event_get_code(e) != LV_EVENT_DELETE) return; + + indev = (lv_indev_t *)lv_event_get_user_data(e); + if(indev == NULL) return; + + indev_ctx = (lv_uefi_simple_text_input_context_t *)lv_indev_get_user_data(indev); + lv_indev_set_user_data(indev, NULL); + + if(indev_ctx != NULL) _simple_text_input_context_free(indev_ctx); +} + +static void _simple_text_input_read_cb(lv_indev_t * indev, lv_indev_data_t * data) +{ + lv_uefi_simple_text_input_handle_context_t * handle_ctx = NULL; + lv_uefi_simple_text_input_key_cache_t * key_cache = NULL; + void * node = NULL; + + lv_uefi_simple_text_input_context_t * indev_ctx = (lv_uefi_simple_text_input_context_t *)lv_indev_get_user_data(indev); + LV_ASSERT_NULL(indev_ctx); + + /* Empty the buffer before reading new values */ + if(lv_ll_is_empty(&indev_ctx->key_cache)) { + // Read from all registered devices + for(node = lv_ll_get_head(&indev_ctx->handles); node != NULL; node = lv_ll_get_next(&indev_ctx->handles, node)) { + handle_ctx = (lv_uefi_simple_text_input_handle_context_t *) node; + _simple_text_input_read(indev_ctx, handle_ctx); + } + } + + /* Return the first value */ + node = lv_ll_get_head(&indev_ctx->key_cache); + if(node != NULL) { + key_cache = (lv_uefi_simple_text_input_key_cache_t *)node; + data->state = key_cache->pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; + data->key = key_cache->key; + lv_ll_remove(&indev_ctx->key_cache, node); + lv_free(key_cache); + } + + /* Continue reading if there are more values in the buffer */ + data->continue_reading = !lv_ll_is_empty(&indev_ctx->key_cache); +} + +static void _simple_text_input_context_free(lv_uefi_simple_text_input_context_t * indev_ctx) +{ + if(indev_ctx == NULL) return; + lv_ll_clear_custom(&indev_ctx->handles, _simple_text_input_handle_context_free); + lv_ll_clear(&indev_ctx->key_cache); + lv_free(indev_ctx); +} + +static bool _simple_text_input_interface_is_valid(const EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL * interface) +{ + if(interface == NULL) return FALSE; + return TRUE; +} + +static void _simple_text_input_handle_context_free(void * ptr) +{ + lv_uefi_simple_text_input_handle_context_t * handle_ctx = (lv_uefi_simple_text_input_handle_context_t *)ptr; + + if(handle_ctx == NULL) return; + if(handle_ctx->interface) lv_uefi_protocol_close(handle_ctx->handle, &_uefi_guid_simple_text_input); + lv_free(handle_ctx); +} + +static void _simple_text_input_read(lv_uefi_simple_text_input_context_t * indev_ctx, + lv_uefi_simple_text_input_handle_context_t * handle_ctx) +{ + EFI_STATUS status; + EFI_KEY_DATA state; + uint32_t key; + lv_uefi_simple_text_input_key_cache_t * cache = NULL; + + LV_ASSERT_NULL(indev_ctx); + LV_ASSERT_NULL(handle_ctx); + + status = handle_ctx->interface->ReadKeyStrokeEx( + handle_ctx->interface, + &state); + if(status == EFI_NOT_READY) return; + if(status != EFI_SUCCESS) { + LV_LOG_ERROR("[lv_uefi] ReadKeyStrokeEx failed."); + return; + } + + key = _key_from_uefi_key(&state); + + /* insert the press */ + cache = (lv_uefi_simple_text_input_key_cache_t *) lv_ll_ins_tail(&indev_ctx->key_cache); + LV_ASSERT_MALLOC(cache); + cache->key = key; + cache->pressed = true; + + /* insert the release */ + cache = (lv_uefi_simple_text_input_key_cache_t *) lv_ll_ins_tail(&indev_ctx->key_cache); + LV_ASSERT_MALLOC(cache); + cache->key = key; + cache->pressed = false; +} + +static uint32_t _utf8_from_unicode(UINT32 unicode) +{ + uint8_t bytes[4] = {0, 0, 0, 0}; + + /* unicode < 128 -> 1 byte */ + if(unicode < 128) { + bytes[0] |= unicode; + } + /* unicode < 2048 -> 2 byte */ + else if(unicode < 2048) { + bytes[0] = 0xC0; + bytes[0] |= unicode >> 6; + bytes[1] = 0x80; + bytes[1] |= (unicode & 0x003F); + } + /* unicode < 65536 -> 3 byte */ + else if(unicode < 65536) { + bytes[0] = 0xE0; + bytes[0] |= unicode >> 12; + bytes[1] = 0x80; + bytes[1] |= ((unicode >> 6) & 0x003F); + bytes[2] = 0x80; + bytes[2] |= (unicode & 0x003F); + } + + return *((uint32_t *)bytes); +} + +static uint32_t _key_from_uefi_key(const EFI_KEY_DATA * key) +{ + LV_ASSERT_NULL(key); + + switch(key->Key.ScanCode) { + case 0x01: + return LV_KEY_UP; + case 0x02: + return LV_KEY_DOWN; + case 0x04: + return LV_KEY_LEFT; + case 0x03: + return LV_KEY_RIGHT; + case 0x08: + return LV_KEY_DEL; + case 0x05: + return LV_KEY_HOME; + case 0x06: + return LV_KEY_END; + case 0x17: + return LV_KEY_ESC; + /* ignore all other scan codes */ + default: + break; + } + + switch(key->Key.UnicodeChar) { + case 0x09: + return (key->KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) && + (key->KeyState.KeyShiftState & (EFI_RIGHT_SHIFT_PRESSED | EFI_LEFT_SHIFT_PRESSED)) ? + LV_KEY_PREV : + LV_KEY_NEXT; + case 0x08: + return LV_KEY_BACKSPACE; + case 0x0D: + return LV_KEY_ENTER; + case 0x18: + return LV_KEY_ESC; + default: + return _utf8_from_unicode(key->Key.UnicodeChar); + } +} + +#endif \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev_pointer.c b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev_pointer.c new file mode 100644 index 000000000..a00b3a03e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev_pointer.c @@ -0,0 +1,285 @@ +/** + * @file lv_uefi_indev.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "../../lvgl.h" +#include "../../stdlib/lv_mem.h" +#include "../../misc/lv_types.h" +#include "../../misc/lv_text.h" + +#if LV_USE_UEFI + +#include "lv_uefi_indev.h" +#include "lv_uefi_private.h" + +/********************* + * DEFINES + *********************/ + +#define SIMPLE_POINTER_INDEV_SIGNATURE 0x53505449 + +/********************** + * TYPEDEFS + **********************/ + +typedef struct _lv_uefi_simple_pointer_handle_context_t { + EFI_HANDLE handle; + EFI_SIMPLE_POINTER_PROTOCOL * interface; + lv_point_t pixel_per_step_8; /**< How many pixels does the mouse cursor move in one step*/ +} lv_uefi_simple_pointer_handle_context_t; + +typedef struct _lv_uefi_simple_pointer_context_t { + uint32_t signature; /**< Has to be checked to avoid access to a different indev*/ + lv_point_t display_res; + lv_point_t position; + lv_ll_t handles; +} lv_uefi_simple_pointer_context_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void _simple_pointer_indev_event_cb(lv_event_t * e); +static void _simple_pointer_read_cb(lv_indev_t * indev, lv_indev_data_t * data); +static void _simple_pointer_handle_context_free(void * ptr); +static void _simple_pointer_context_free(lv_uefi_simple_pointer_context_t * indev_ctx); +static bool _simple_pointer_interface_is_valid(const EFI_SIMPLE_POINTER_PROTOCOL * interface); +static void _simple_pointer_read(lv_uefi_simple_pointer_context_t * indev_ctx, + lv_uefi_simple_pointer_handle_context_t * handle_ctx, bool * was_pressed); + +/********************** + * STATIC VARIABLES + **********************/ + +static EFI_GUID _uefi_guid_simple_pointer = EFI_SIMPLE_POINTER_PROTOCOL_GUID; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * @brief Create an indev object. + * @param display_res The resolution of the display in pixels, needed to scale the input. + * If NULL the resolution of the current default display will be used. + * @return The created LVGL indev object. +*/ +lv_indev_t * lv_uefi_simple_pointer_indev_create(lv_point_t * display_res) +{ + lv_indev_t * indev = NULL; + lv_uefi_simple_pointer_context_t * indev_ctx = NULL; + + indev_ctx = lv_calloc(1, sizeof(lv_uefi_simple_pointer_context_t)); + LV_ASSERT_MALLOC(indev_ctx); + + indev_ctx->signature = SIMPLE_POINTER_INDEV_SIGNATURE; + + if(display_res != NULL) { + indev_ctx->display_res.x = display_res->x; + indev_ctx->display_res.y = display_res->y; + } + else { + indev_ctx->display_res.x = lv_display_get_horizontal_resolution(lv_display_get_default()); + indev_ctx->display_res.y = lv_display_get_vertical_resolution(lv_display_get_default()); + } + + lv_ll_init(&indev_ctx->handles, sizeof(lv_uefi_simple_pointer_handle_context_t)); + + indev = lv_indev_create(); + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_user_data(indev, indev_ctx); + lv_indev_add_event_cb(indev, _simple_pointer_indev_event_cb, LV_EVENT_DELETE, indev); + lv_indev_set_read_cb(indev, _simple_pointer_read_cb); + + return indev; +} + +/** + * @brief Add an EFI_SIMPLE_POINTER_PROTOCOL interface to the indev. + * @param indev Indev that was created with lv_uefi_simple_pointer_indev_create. + * @param handle The handle on which an instance of the EFI_SIMPLE_POINTER_PROTOCOL protocol is installed. + * @return True if the interface was added. +*/ +bool lv_uefi_simple_pointer_indev_add_handle(lv_indev_t * indev, EFI_HANDLE handle) +{ + EFI_SIMPLE_POINTER_PROTOCOL * interface = NULL; + lv_uefi_simple_pointer_handle_context_t * handle_ctx = NULL; + + lv_uefi_simple_pointer_context_t * indev_ctx = (lv_uefi_simple_pointer_context_t *)lv_indev_get_user_data(indev); + LV_ASSERT_NULL(indev_ctx); + + if(indev_ctx->signature != SIMPLE_POINTER_INDEV_SIGNATURE) return false; + + interface = (EFI_SIMPLE_POINTER_PROTOCOL *)lv_uefi_protocol_open(handle, &_uefi_guid_simple_pointer); + if(!_simple_pointer_interface_is_valid(interface)) { + lv_uefi_protocol_close(handle, &_uefi_guid_simple_pointer); + LV_LOG_WARN("[lv_uefi] The SIMPLE_POINTER interface is not valid."); + return false; + } + + handle_ctx = (lv_uefi_simple_pointer_handle_context_t *) lv_ll_ins_head(&indev_ctx->handles); + LV_ASSERT_MALLOC(handle_ctx); + + handle_ctx->handle = handle; + handle_ctx->interface = interface; + handle_ctx->pixel_per_step_8.x = (((indev_ctx->display_res.x) << 8) / 50) / + interface->Mode->ResolutionX; + handle_ctx->pixel_per_step_8.y = (((indev_ctx->display_res.y) << 8) / 50) / + interface->Mode->ResolutionY; + + return true; +} + +/** + * @brief Add all available EFI_SIMPLE_POINTER_PROTOCOL interfaces to the indev. + * @param indev Indev that was created with lv_uefi_simple_pointer_indev_create. +*/ +void lv_uefi_simple_pointer_indev_add_all(lv_indev_t * indev) +{ + EFI_STATUS status; + EFI_HANDLE * handles = NULL; + UINTN no_handles; + UINTN index; + + lv_uefi_simple_pointer_context_t * indev_ctx = (lv_uefi_simple_pointer_context_t *)lv_indev_get_user_data(indev); + LV_ASSERT_NULL(indev_ctx); + + if(indev_ctx->signature != SIMPLE_POINTER_INDEV_SIGNATURE) return; + + status = gLvEfiBS->LocateHandleBuffer(ByProtocol, &_uefi_guid_simple_pointer, NULL, &no_handles, &handles); + if(status != EFI_SUCCESS) { + LV_LOG_ERROR("[lv_uefi] LocateHandleBuffer(SIMPLE_POINTER) failed with error code %llx.", status); + return; + } + + for(index = 0; index < no_handles; index++) { + lv_uefi_simple_pointer_indev_add_handle(indev, handles[index]); + } + + if(handles != NULL) gLvEfiBS->FreePool(handles); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void _simple_pointer_indev_event_cb(lv_event_t * e) +{ + lv_indev_t * indev; + lv_uefi_simple_pointer_context_t * indev_ctx; + + if(lv_event_get_code(e) != LV_EVENT_DELETE) return; + + indev = (lv_indev_t *)lv_event_get_user_data(e); + if(indev == NULL) return; + + indev_ctx = (lv_uefi_simple_pointer_context_t *)lv_indev_get_user_data(indev); + lv_indev_set_user_data(indev, NULL); + + if(indev_ctx != NULL) _simple_pointer_context_free(indev_ctx); +} + +static void _simple_pointer_read_cb(lv_indev_t * indev, lv_indev_data_t * data) +{ + void * node = NULL; + + lv_uefi_simple_pointer_context_t * indev_ctx = (lv_uefi_simple_pointer_context_t *)lv_indev_get_user_data(indev); + LV_ASSERT_NULL(indev_ctx); + + /* Read from all registered devices */ + for(node = lv_ll_get_head(&indev_ctx->handles); node != NULL; node = lv_ll_get_next(&indev_ctx->handles, node)) { + lv_uefi_simple_pointer_handle_context_t * handle_ctx = (lv_uefi_simple_pointer_handle_context_t *) node; + bool was_pressed = false; + + _simple_pointer_read(indev_ctx, handle_ctx, &was_pressed); + + data->state |= was_pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; + } + + /* Sanitize the events position */ + if(indev_ctx->position.x < 0) { + indev_ctx->position.x = 0; + } + else if(indev_ctx->position.x > indev_ctx->display_res.x - 1) { + indev_ctx->position.x = indev_ctx->display_res.x - 1; + } + + if(indev_ctx->position.y < 0) { + indev_ctx->position.y = 0; + } + else if(indev_ctx->position.y > indev_ctx->display_res.y - 1) { + indev_ctx->position.y = indev_ctx->display_res.y - 1; + } + + data->point.x = indev_ctx->position.x; + data->point.y = indev_ctx->position.y; + + data->continue_reading = FALSE; +} + +static void _simple_pointer_context_free(lv_uefi_simple_pointer_context_t * indev_ctx) +{ + if(indev_ctx == NULL) return; + lv_ll_clear_custom(&indev_ctx->handles, _simple_pointer_handle_context_free); + lv_free(indev_ctx); +} + +static bool _simple_pointer_interface_is_valid(const EFI_SIMPLE_POINTER_PROTOCOL * interface) +{ + if(interface == NULL) return FALSE; + if(interface->Mode == NULL) return FALSE; + if(interface->Mode->ResolutionX == 0) return FALSE; + if(interface->Mode->ResolutionX >= 256) return FALSE; + if(interface->Mode->ResolutionY == 0) return FALSE; + if(interface->Mode->ResolutionY >= 256) return FALSE; + return TRUE; +} + +static void _simple_pointer_handle_context_free(void * ptr) +{ + lv_uefi_simple_pointer_handle_context_t * handle_ctx = (lv_uefi_simple_pointer_handle_context_t *)ptr; + + if(handle_ctx == NULL) return; + if(handle_ctx->interface) lv_uefi_protocol_close(handle_ctx->handle, &_uefi_guid_simple_pointer); + lv_free(handle_ctx); +} + +static void _simple_pointer_read(lv_uefi_simple_pointer_context_t * indev_ctx, + lv_uefi_simple_pointer_handle_context_t * handle_ctx, bool * was_pressed) +{ + EFI_STATUS status; + EFI_SIMPLE_POINTER_STATE state; + lv_point_t pointer_mov; + + LV_ASSERT_NULL(indev_ctx); + LV_ASSERT_NULL(handle_ctx); + LV_ASSERT_NULL(was_pressed); + + status = handle_ctx->interface->GetState( + handle_ctx->interface, + &state); + if(status == EFI_NOT_READY) return; + if(status != EFI_SUCCESS) { + LV_LOG_ERROR("[lv_uefi] GetState failed."); + return; + } + + pointer_mov.x = (state.RelativeMovementX * handle_ctx->pixel_per_step_8.x) >> 8; + pointer_mov.y = (state.RelativeMovementY * handle_ctx->pixel_per_step_8.y) >> 8; + + indev_ctx->position.x += pointer_mov.x; + indev_ctx->position.y += pointer_mov.y; + + /* Set the state to pressed if one of the interfaces reports a press */ + *was_pressed = state.LeftButton; +} + +#endif \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev_touch.c b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev_touch.c new file mode 100644 index 000000000..3fad4f087 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_indev_touch.c @@ -0,0 +1,290 @@ +/** + * @file lv_uefi_indev.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "../../lvgl.h" +#include "../../stdlib/lv_mem.h" +#include "../../misc/lv_types.h" +#include "../../misc/lv_text.h" + +#if LV_USE_UEFI + +#include "lv_uefi_indev.h" +#include "lv_uefi_private.h" + +/********************* + * DEFINES + *********************/ + +#define ABSOLUTE_POINTER_INDEV_SIGNATURE 0x41505449 + +/********************** + * TYPEDEFS + **********************/ + +typedef struct _lv_uefi_absolute_pointer_handle_context_t { + EFI_HANDLE handle; + EFI_ABSOLUTE_POINTER_PROTOCOL * interface; + lv_point_t range; /**< The touchscreen resolution*/ + lv_point_t factor_8; /**< The scaling factor between the touchscreen and the display resolution*/ +} lv_uefi_absolute_pointer_handle_context_t; + +typedef struct _lv_uefi_absolute_pointer_context_t { + uint32_t signature; /**< Has to be checked to avoid access to a different indev*/ + lv_point_t display_res; + lv_point_t position; + lv_ll_t handles; +} lv_uefi_absolute_pointer_context_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void _absolute_pointer_indev_event_cb(lv_event_t * e); +static void _absolute_pointer_read_cb(lv_indev_t * indev, lv_indev_data_t * data); +static void _absolute_pointer_handle_context_free(void * ptr); +static void _absolute_pointer_context_free(lv_uefi_absolute_pointer_context_t * indev_ctx); +static bool _absolute_pointer_interface_is_valid(const EFI_ABSOLUTE_POINTER_PROTOCOL * interface); +static void _absolute_pointer_read(lv_uefi_absolute_pointer_context_t * indev_ctx, + lv_uefi_absolute_pointer_handle_context_t * handle_ctx, bool * was_pressed); + +/********************** + * STATIC VARIABLES + **********************/ + +static EFI_GUID _uefi_guid_absolute_pointer = EFI_ABSOLUTE_POINTER_PROTOCOL_GUID; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * @brief Create a LVGL indev object. + * @param display_res The resolution of the display in pixels, needed to scale the input. + * @return The created LVGL indev object. +*/ +lv_indev_t * lv_uefi_absolute_pointer_indev_create(lv_point_t * display_res) +{ + lv_indev_t * indev = NULL; + lv_uefi_absolute_pointer_context_t * indev_ctx = NULL; + + indev_ctx = lv_calloc(1, sizeof(lv_uefi_absolute_pointer_context_t)); + LV_ASSERT_MALLOC(indev_ctx); + + indev_ctx->signature = ABSOLUTE_POINTER_INDEV_SIGNATURE; + + if(display_res != NULL) { + indev_ctx->display_res.x = display_res->x; + indev_ctx->display_res.y = display_res->y; + } + else { + indev_ctx->display_res.x = lv_display_get_horizontal_resolution(lv_display_get_default()); + indev_ctx->display_res.y = lv_display_get_vertical_resolution(lv_display_get_default()); + } + + lv_ll_init(&indev_ctx->handles, sizeof(lv_uefi_absolute_pointer_handle_context_t)); + + indev = lv_indev_create(); + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_user_data(indev, indev_ctx); + lv_indev_add_event_cb(indev, _absolute_pointer_indev_event_cb, LV_EVENT_DELETE, indev); + lv_indev_set_read_cb(indev, _absolute_pointer_read_cb); + + return indev; +} + +/** + * @brief Add an EFI_ABSOLUTE_POINTER_PROTOCOL interface to the indev. + * @param indev Indev that was created with lv_uefi_absolute_pointer_indev_create. + * @param handle The handle on which an instance of the EFI_ABSOLUTE_POINTER_PROTOCOL protocol is installed. + * @return True if the interface was added. +*/ +bool lv_uefi_absolute_pointer_indev_add_handle(lv_indev_t * indev, EFI_HANDLE handle) +{ + EFI_ABSOLUTE_POINTER_PROTOCOL * interface = NULL; + lv_uefi_absolute_pointer_handle_context_t * handle_ctx = NULL; + + lv_uefi_absolute_pointer_context_t * indev_ctx = (lv_uefi_absolute_pointer_context_t *)lv_indev_get_user_data(indev); + LV_ASSERT_NULL(indev_ctx); + + if(indev_ctx->signature != ABSOLUTE_POINTER_INDEV_SIGNATURE) return false; + + interface = (EFI_ABSOLUTE_POINTER_PROTOCOL *)lv_uefi_protocol_open(handle, &_uefi_guid_absolute_pointer); + if(!_absolute_pointer_interface_is_valid(interface)) { + lv_uefi_protocol_close(handle, &_uefi_guid_absolute_pointer); + LV_LOG_WARN("[lv_uefi] The ABSOLUTE_POINTER interface is not valid."); + return false; + } + + handle_ctx = (lv_uefi_absolute_pointer_handle_context_t *) lv_ll_ins_head(&indev_ctx->handles); + LV_ASSERT_MALLOC(handle_ctx); + + handle_ctx->handle = handle; + handle_ctx->interface = interface; + handle_ctx->range.x = handle_ctx->interface->Mode->AbsoluteMaxX - + handle_ctx->interface->Mode->AbsoluteMinX; + handle_ctx->range.y = handle_ctx->interface->Mode->AbsoluteMaxY - + handle_ctx->interface->Mode->AbsoluteMinY; + + handle_ctx->factor_8.x = (indev_ctx->display_res.x << 8) / handle_ctx->range.x; + handle_ctx->factor_8.y = (indev_ctx->display_res.y << 8) / handle_ctx->range.y; + + return true; +} + +/** + * @brief Add all available EFI_ABSOLUTE_POINTER_PROTOCOL interfaces to the indev. + * @param indev Indev that was created with lv_uefi_absolute_pointer_indev_create. +*/ +void lv_uefi_absolute_pointer_indev_add_all(lv_indev_t * indev) +{ + EFI_STATUS status; + EFI_HANDLE * handles = NULL; + UINTN no_handles; + UINTN index; + + lv_uefi_absolute_pointer_context_t * indev_ctx = (lv_uefi_absolute_pointer_context_t *)lv_indev_get_user_data(indev); + LV_ASSERT_NULL(indev_ctx); + + if(indev_ctx->signature != ABSOLUTE_POINTER_INDEV_SIGNATURE) return; + + status = gLvEfiBS->LocateHandleBuffer(ByProtocol, &_uefi_guid_absolute_pointer, NULL, &no_handles, &handles); + if(status != EFI_SUCCESS) { + LV_LOG_ERROR("[lv_uefi] LocateHandleBuffer(ABSOLUTE_POINTER) failed with error code %llx.", status); + return; + } + + for(index = 0; index < no_handles; index++) { + lv_uefi_absolute_pointer_indev_add_handle(indev, handles[index]); + } + + if(handles != NULL) gLvEfiBS->FreePool(handles); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void _absolute_pointer_indev_event_cb(lv_event_t * e) +{ + lv_indev_t * indev; + lv_uefi_absolute_pointer_context_t * indev_ctx; + + if(lv_event_get_code(e) != LV_EVENT_DELETE) return; + + indev = (lv_indev_t *)lv_event_get_user_data(e); + if(indev == NULL) return; + + indev_ctx = (lv_uefi_absolute_pointer_context_t *)lv_indev_get_user_data(indev); + lv_indev_set_user_data(indev, NULL); + + if(indev_ctx != NULL) _absolute_pointer_context_free(indev_ctx); +} + +static void _absolute_pointer_read_cb(lv_indev_t * indev, lv_indev_data_t * data) +{ + void * node = NULL; + + lv_uefi_absolute_pointer_context_t * indev_ctx = (lv_uefi_absolute_pointer_context_t *)lv_indev_get_user_data(indev); + LV_ASSERT_NULL(indev_ctx); + + /* Read from all registered devices */ + for(node = lv_ll_get_head(&indev_ctx->handles); node != NULL; node = lv_ll_get_next(&indev_ctx->handles, node)) { + lv_uefi_absolute_pointer_handle_context_t * handle_ctx = (lv_uefi_absolute_pointer_handle_context_t *) node; + bool was_pressed = false; + + _absolute_pointer_read(indev_ctx, handle_ctx, &was_pressed); + + data->state |= was_pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; + } + + /* Sanitize the events position */ + if(indev_ctx->position.x < 0) { + indev_ctx->position.x = 0; + } + else if(indev_ctx->position.x > indev_ctx->display_res.x - 1) { + indev_ctx->position.x = indev_ctx->display_res.x - 1; + } + + if(indev_ctx->position.y < 0) { + indev_ctx->position.y = 0; + } + else if(indev_ctx->position.y > indev_ctx->display_res.y - 1) { + indev_ctx->position.y = indev_ctx->display_res.y - 1; + } + + data->point.x = indev_ctx->position.x; + data->point.y = indev_ctx->position.y; + + data->continue_reading = FALSE; +} + +static void _absolute_pointer_context_free(lv_uefi_absolute_pointer_context_t * indev_ctx) +{ + if(indev_ctx == NULL) return; + lv_ll_clear_custom(&indev_ctx->handles, _absolute_pointer_handle_context_free); + lv_free(indev_ctx); +} + +static bool _absolute_pointer_interface_is_valid(const EFI_ABSOLUTE_POINTER_PROTOCOL * interface) +{ + if(interface == NULL) return FALSE; + if(interface->Mode == NULL) return FALSE; + if(interface->Mode->AbsoluteMaxX <= interface->Mode->AbsoluteMinX) return FALSE; + if(interface->Mode->AbsoluteMaxY <= interface->Mode->AbsoluteMinY) return FALSE; + return TRUE; +} + +static void _absolute_pointer_handle_context_free(void * ptr) +{ + lv_uefi_absolute_pointer_handle_context_t * handle_ctx = (lv_uefi_absolute_pointer_handle_context_t *) ptr; + + if(handle_ctx == NULL) return; + if(handle_ctx->interface) lv_uefi_protocol_close(handle_ctx->handle, &_uefi_guid_absolute_pointer); + lv_free(handle_ctx); +} + +static void _absolute_pointer_read(lv_uefi_absolute_pointer_context_t * indev_ctx, + lv_uefi_absolute_pointer_handle_context_t * handle_ctx, bool * was_pressed) +{ + EFI_STATUS status; + EFI_ABSOLUTE_POINTER_STATE state; + lv_point_t pointer_pos; + + LV_ASSERT_NULL(indev_ctx); + LV_ASSERT_NULL(handle_ctx); + LV_ASSERT_NULL(was_pressed); + + status = handle_ctx->interface->GetState( + handle_ctx->interface, + &state); + if(status == EFI_NOT_READY) return; + if(status != EFI_SUCCESS) { + LV_LOG_ERROR("[lv_uefi] GetState failed."); + return; + } + + /* verify the state */ + if(state.CurrentX < handle_ctx->interface->Mode->AbsoluteMinX) return; + if(state.CurrentY < handle_ctx->interface->Mode->AbsoluteMinY) return; + + pointer_pos.x = state.CurrentX - handle_ctx->interface->Mode->AbsoluteMinX; + pointer_pos.y = state.CurrentY - handle_ctx->interface->Mode->AbsoluteMinY; + + indev_ctx->position.x = (pointer_pos.x * handle_ctx->factor_8.x) >> 8; + indev_ctx->position.y = (pointer_pos.y * handle_ctx->factor_8.y) >> 8; + + /* Set the state to pressed if one of the interfaces reports a press */ + *was_pressed = (state.ActiveButtons & EFI_ABSP_TouchActive) != 0; +} + +#endif \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_private.c b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_private.c new file mode 100644 index 000000000..2d06a90fb --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_private.c @@ -0,0 +1,225 @@ +/** + * @file lv_uefi_private.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "../../lvgl.h" + +#if LV_USE_UEFI + +#include "lv_uefi_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * GOLBAL VARIABLES + **********************/ +EFI_HANDLE gLvEfiImageHandle = NULL; +EFI_SYSTEM_TABLE * gLvEfiST = NULL; +EFI_BOOT_SERVICES * gLvEfiBS = NULL; +EFI_RUNTIME_SERVICES * gLvEfiRT = NULL; + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * @brief Test if a protocol is installed at a handle. + * @param handle The handle on which the protocol might be installed. + * @param protocol The guid of the protocol. + * @return TRUE if the protocol is installed, FALSE if not. +*/ +bool lv_uefi_protocol_test(EFI_HANDLE handle, EFI_GUID * protocol) +{ + EFI_STATUS status; + void * interface = NULL; + + if(handle == NULL) return false; + if(protocol == NULL) return false; + + status = gLvEfiBS->OpenProtocol( + handle, + protocol, + &interface, + gLvEfiImageHandle, + NULL, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL); + if(status != EFI_SUCCESS && status != EFI_UNSUPPORTED) { + LV_LOG_WARN("couldn't test protocol"); + return FALSE; + } + else if(status == EFI_UNSUPPORTED) { + return FALSE; + } + + return TRUE; +} + +/** + * @brief Open a protocol. + * @param handle The handle on which the protocol is installed. + * @param protocol The guid of the protocol. + * @return A pointer to the interface, NULL if the protocol couldn't be opened. +*/ +void * lv_uefi_protocol_open(EFI_HANDLE handle, EFI_GUID * protocol) +{ + EFI_STATUS status; + void * interface = NULL; + + if(handle == NULL) return NULL; + if(protocol == NULL) return NULL; + + status = gLvEfiBS->OpenProtocol( + handle, + protocol, + &interface, + gLvEfiImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if(status != EFI_SUCCESS) { + LV_LOG_ERROR("[lv_uefi] Couldn't open protocol %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X, error code: %llx.", + protocol->Data1, + protocol->Data2, + protocol->Data3, + protocol->Data4[0], + protocol->Data4[1], + protocol->Data4[2], + protocol->Data4[3], + protocol->Data4[4], + protocol->Data4[5], + protocol->Data4[6], + protocol->Data4[7], + status); + interface = NULL; + } + + return interface; +} + +/** + * @brief Close a protocol. + * @param handle The handle on which the protocol is installed. + * @param protocol The guid of the protocol. +*/ +void lv_uefi_protocol_close(EFI_HANDLE handle, EFI_GUID * protocol) +{ + EFI_STATUS status; + + if(handle == NULL) return; + if(protocol == NULL) return; + + status = gLvEfiBS->CloseProtocol( + handle, + protocol, + gLvEfiImageHandle, + NULL); + if(status != EFI_SUCCESS) { + LV_LOG_WARN("[lv_uefi] Couldn't close protocol %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X, error code: %llx.", + protocol->Data1, + protocol->Data2, + protocol->Data3, + protocol->Data4[0], + protocol->Data4[1], + protocol->Data4[2], + protocol->Data4[3], + protocol->Data4[4], + protocol->Data4[5], + protocol->Data4[6], + protocol->Data4[7], + status); + } +} + +/** + * @brief Convert an UCS-2 string to an ASCII string. + * The string must contain only characters >= 0x20 and <= 0X7E. + * @param ucs2 The UCS-2 string. + * @param ascii The buffer to store the ASCII string. + * @param ascii_len The size of the buffer in ASCII characters. + * @return The number of characters written to the buffer or 0 if + * there was an error. +*/ +size_t lv_uefi_ucs2_to_ascii(const CHAR16 * ucs2, char * ascii, size_t ascii_len) +{ + size_t invalid_character_count; + size_t string_index; + + if(ucs2 == NULL || ascii == NULL || ascii_len == 0) { + return 0; + } + + invalid_character_count = 0; + + for(string_index = 0; ucs2[string_index] != 0x0000 && string_index < ascii_len - 1; string_index++) { + if(ucs2[string_index] < 0x20 || ucs2[string_index] > 0x7E) { + invalid_character_count++; + } + ascii[string_index] = (char) ucs2[string_index]; + } + + /* terminate the string even if there was an error */ + ascii[string_index] = 0x00; + + return invalid_character_count == 0 ? string_index : 0; +} + +/** + * @brief Convert an ASCII string to an UCS-2 string. + * The string must contain only characters >= 0x20 and <= 0X7E. + * @param ascii The ASCII string. + * @param ucs2 The buffer to store the UCS-2 string. + * @param ucs2_len The size of the buffer in UCS-2 characters. + * @return The number of bytes written to the buffer or 0 if + * there was an error. +*/ +size_t lv_uefi_ascii_to_ucs2(const char * ascii, CHAR16 * ucs2, size_t ucs2_len) +{ + size_t invalid_character_count; + size_t string_index; + + if(ascii == NULL || ucs2 == NULL || ucs2_len == 0) { + return 0; + } + + invalid_character_count = 0; + + for(string_index = 0; ascii[string_index] != 0x0000 && string_index < ucs2_len - 1; string_index++) { + if(ascii[string_index] < 0x20 || ascii[string_index] > 0x7E) { + invalid_character_count++; + } + ucs2[string_index] = (CHAR16) ascii[string_index]; + } + + /* terminate the string even if there was an error */ + ucs2[string_index] = 0x0000; + + return invalid_character_count == 0 ? string_index : 0; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_private.h b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_private.h new file mode 100644 index 000000000..7f917ce40 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_private.h @@ -0,0 +1,107 @@ +/** + * @file lv_uefi_private.h + * + */ + +#ifndef __LV_UEFI_PRIVATE_H__ +#define __LV_UEFI_PRIVATE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lvgl.h" + +#if LV_USE_UEFI + +#include "lv_uefi.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Internal cache for the image handle (source: application entry point) + */ +extern EFI_HANDLE gLvEfiImageHandle; +/** + * Internal cache for the system table (source: application entry point) + */ +extern EFI_SYSTEM_TABLE * gLvEfiST; +/** + * Internal cache for the boot services table (source: gLvEfiST) + */ +extern EFI_BOOT_SERVICES * gLvEfiBS; +/** + * Internal cache for the boot runtime service table (source: gLvEfiST) + */ +extern EFI_RUNTIME_SERVICES * gLvEfiRT; + +/** + * @brief Test if a protocol is installed at a handle. + * @param handle The handle on which the protocol might be installed. + * @param protocol The guid of the protocol. + * @return TRUE if the protocol is installed, FALSE if not. +*/ +bool lv_uefi_protocol_test(EFI_HANDLE handle, EFI_GUID * protocol); + +/** + * @brief Open a protocol. + * @param handle The handle on which the protocol is installed. + * @param protocol The guid of the protocol. + * @return A pointer to the interface, NULL if the protocol couldn't be opened. +*/ +void * lv_uefi_protocol_open(EFI_HANDLE handle, EFI_GUID * protocol); + +/** + * @brief Close a protocol. + * @param handle The handle on which the protocol is installed. + * @param protocol The guid of the protocol. +*/ +void lv_uefi_protocol_close(EFI_HANDLE handle, EFI_GUID * protocol); + +/** + * @brief Convert an UCS-2 string to an ASCII string. + * The string must contain only characters >= 0x20 and <= 0X7E. + * @param ucs2 The UCS-2 string. + * @param ascii The buffer to store the ASCII string. + * @param ascii_len The size of the buffer in ASCII characters. + * @return The number of characters written to the buffer or 0 if + * there was an error. +*/ +size_t lv_uefi_ucs2_to_ascii(const CHAR16 * ucs2, char * ascii, size_t ascii_len); + +/** + * @brief Convert an ASCII string to an UCS-2 string. + * The string must contain only characters >= 0x20 and <= 0X7E. + * @param ascii The ASCII string. + * @param ucs2 The buffer to store the UCS-2 string. + * @param ucs2_len The size of the buffer in UCS-2 characters. + * @return The number of bytes written to the buffer or 0 if + * there was an error. +*/ +size_t lv_uefi_ascii_to_ucs2(const char * ascii, CHAR16 * ucs2, size_t ucs2_len); + +/********************** + * MACROS + **********************/ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif //__LV_UEFI_PRIVATE_H__ \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_std_wrapper.h b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_std_wrapper.h new file mode 100644 index 000000000..c5fb5cc8b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/uefi/lv_uefi_std_wrapper.h @@ -0,0 +1,155 @@ +/** + * @file lv_uefi_std_wrapper.h + * + */ + +#ifndef LV_UEFI_STD_WRAPPER_H +#define LV_UEFI_STD_WRAPPER_H + +#if LV_USE_UEFI + + #include LV_USE_UEFI_INCLUDE + + /************************************* + * TYPES + *************************************/ + typedef UINT8 uint8_t; + typedef UINT16 uint16_t; + typedef UINT32 uint32_t; + typedef UINT64 uint64_t; + typedef INT8 int8_t; + typedef INT16 int16_t; + typedef INT32 int32_t; + typedef INT64 int64_t; + + typedef uint32_t uint_fast32_t; + typedef UINTN uintptr_t; + typedef UINTN size_t; + typedef INTN intptr_t; + typedef INTN intmax_t; + typedef INTN ptrdiff_t; + + typedef UINT8 bool; + + /************************************* + * DEFINES + *************************************/ + #define false 0 + #define true 1 + + #define PRId8 "d" + #define PRId16 "d" + #define PRId32 "d" + #define PRId64 "d" + + #define PRIu8 "u" + #define PRIu16 "u" + #define PRIu32 "u" + #define PRIu64 "u" + + #define PRIx8 "x" + #define PRIx16 "x" + #define PRIx32 "x" + #define PRIx64 "x" + + #define PRIX8 "X" + #define PRIX16 "X" + #define PRIX32 "X" + #define PRIX64 "X" + + /************************************* + * LIMITS + *************************************/ + #ifndef INT8_MAX + #define INT8_MAX (0x7F) + #endif + + #ifndef UINT8_MAX + #define UINT8_MAX (0xFF) + #endif + + #ifndef INT16_MAX + #define INT16_MAX (0x7FFF) + #endif + + #ifndef UINT16_MAX + #define UINT16_MAX (0xFFFF) + #endif + + #ifndef INT32_MAX + #define INT32_MAX (0x7FFFFFFF) + #endif + + #ifndef UINT32_MAX + #define UINT32_MAX (0xFFFFFFFF) + #endif + + #ifndef INT64_MAX + #define INT64_MAX (0x7FFFFFFFFFFFFFFFULL) + #endif + + #ifndef UINT64_MAX + #define UINT64_MAX (0xFFFFFFFFFFFFFFFFULL) + #endif + + #ifndef INT_MAX + #define INT_MAX (0x7FFFFFFFFFFFFFFFULL) + #endif + + #ifndef UINT_MAX + #define UINT_MAX (0xFFFFFFFFFFFFFFFFULL) + #endif + + /// + /// Minimum values for the signed UEFI Data Types + /// + #ifndef INT8_MIN + #define INT8_MIN (( -127) - 1) + #endif + + #ifndef INT16_MIN + #define INT16_MIN (( -32767) - 1) + #endif + + #ifndef INT32_MIN + #define INT32_MIN (( -2147483647) - 1) + #endif + + #ifndef INT64_MIN + #define INT64_MIN (( -9223372036854775807LL) - 1) + #endif + + #ifndef SIZE_MAX + #define SIZE_MAX (0xFFFFFFFF) + #endif + + #ifndef LONG_MAX + #define LONG_MAX (0x7FFFFFFF) + #endif + + #ifndef ULONG_MAX + #define ULONG_MAX (0xFFFFFFFF) + #endif + + #ifndef USHRT_MAX + #define USHRT_MAX (0xFFFF) + #endif + + #ifndef CHAR_BIT + #define CHAR_BIT 8 + #endif + + /************************************* + * VA_ARG + *************************************/ + #if LV_UEFI_EDK2_HEADERS + #define va_list VA_LIST + #define va_start(Marker, Parameter) VA_START(Marker, Parameter) + #define va_arg(Marker, TYPE) VA_ARG(Marker, TYPE) + #define va_end(Marker) VA_END(Marker) + #define va_copy(Dest, Start) VA_COPY(Dest, Start) + #endif + +#endif + +#endif \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland.c b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland.c index dc71f6677..3f6bdfe2f 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland.c @@ -1,29 +1,51 @@ -/******************************************************************* - * - * @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 +/** + * @file lv_wayland.c + */ /********************* * INCLUDES *********************/ + #include "lv_wayland.h" -#include "lv_wayland_smm.h" #if LV_USE_WAYLAND -#include +#if LV_WAYLAND_BUF_COUNT < 1 || LV_WAYLAND_BUF_COUNT > 2 + #error "Invalid LV_WAYLAND_BUF_COUNT. Expected either 1 or 2" +#endif + +#if !LV_WAYLAND_USE_DMABUF && LV_WAYLAND_BUF_COUNT != 1 + #error "Wayland doesn't support more than 1 LV_WAYLAND_BUF_COUNT without DMABUF" +#endif + +#if LV_WAYLAND_USE_DMABUF && !LV_USE_DRAW_G2D + #error "LV_WAYLAND_USE_DMABUF requires LV_USE_DRAW_G2D" +#endif + +#if LV_WAYLAND_USE_DMABUF && LV_WAYLAND_WINDOW_DECORATIONS + #error "LV_WAYLAND_USE_DMABUF doesn't support LV_WAYLAND_WINDOW_DECORATIONS" +#endif + +#ifndef LV_DISPLAY_RENDER_MODE_PARTIAL + /* FIXME: Hacky fix else building fails with -Wundef=error*/ + #define LV_DISPLAY_RENDER_MODE_PARTIAL 0 + #define LV_DISPLAY_RENDER_MODE_DIRECT 1 + #define LV_DISPLAY_RENDER_MODE_FULL 2 +#endif + +#if LV_WAYLAND_USE_DMABUF && LV_WAYLAND_RENDER_MODE == LV_DISPLAY_RENDER_MODE_PARTIAL + #error "LV_WAYLAND_USE_DMABUF doesn't support LV_DISPLAY_RENDER_MODE_PARTIAL" +#endif + +#if !LV_WAYLAND_USE_DMABUF && LV_WAYLAND_RENDER_MODE != LV_DISPLAY_RENDER_MODE_PARTIAL + #error "Wayland without DMABUF only supports LV_DISPLAY_RENDER_MODE_PARTIAL" +#endif + +#if (LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1) + #error[wayland] Unsupported LV_COLOR_DEPTH +#endif + +#include "lv_wayland_private.h" #include #include #include @@ -41,1185 +63,263 @@ typedef int dummy_t; /* Make GCC on windows happy, avoid empty translation un #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 +#if LV_WAYLAND_USE_DMABUF + #include #endif +#include "lvgl.h" /********************* * 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, -}; +struct lv_wayland_context lv_wl_ctx; -#define FIRST_DECORATION (OBJECT_TITLEBAR) -#define LAST_DECORATION (OBJECT_BORDER_RIGHT) -#define NUM_DECORATIONS (LAST_DECORATION-FIRST_DECORATION+1) +/********************** + * STATIC PROTOTYPES + **********************/ -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 void handle_global(void * data, struct wl_registry * registry, uint32_t name, const char * interface, + uint32_t version); +static void handle_global_remove(void * data, struct wl_registry * registry, uint32_t name); +static void handle_input(void); +static void handle_output(void); static uint32_t tick_get_cb(void); -static void wayland_init(void); -static void wayland_deinit(void); +/********************** + * STATIC VARIABLES + **********************/ + +static bool is_wayland_initialized = false; +static const struct wl_registry_listener registry_listener = {.global = handle_global, + .global_remove = handle_global_remove +}; + +/********************** + * GLOBAL FUNCTIONS + **********************/ /** - * 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) + * Get Wayland display file descriptor + * @return Wayland display file descriptor */ -static void graphic_obj_frame_done(void * data, struct wl_callback * cb, uint32_t time) +int lv_wayland_get_fd(void) +{ + return wl_display_get_fd(lv_wl_ctx.display); +} + +uint32_t lv_wayland_timer_handler(void) { - struct graphic_object * obj; struct window * window; - LV_UNUSED(time); + /* Wayland input handling - it will also trigger the frame done handler */ + handle_input(); - wl_callback_destroy(cb); + /* Ready input timers (to probe for any input received) */ + LV_LL_READ(&lv_wl_ctx.window_ll, window) { + LV_LOG_TRACE("handle timer frame: %d", window->frame_counter); - obj = (struct graphic_object *)data; - window = obj->window; - window->frame_counter++; + if(window != NULL && window->resize_pending) { + if(lv_wayland_window_resize(window, window->resize_width, window->resize_height) == LV_RESULT_OK) { + window->resize_width = window->width; + window->resize_height = window->height; + window->resize_pending = false; - 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; + LV_LOG_TRACE("Failed to resize window frame: %d", window->frame_counter); } - - 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--; - } - } -} + else if(window->shall_close == true) { -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; + /* Destroy graphical context and execute close_cb */ + handle_output(); + lv_wayland_deinit(); + return 0; } } - return key; -} + /* LVGL handling */ + uint32_t idle_time = lv_timer_handler(); -static void keyboard_handle_keymap(void * data, struct wl_keyboard * keyboard, - uint32_t format, int fd, uint32_t size) -{ - struct application * app = data; + /* Wayland output handling */ + handle_output(); - 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. + /* 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(&lv_wl_ctx.window_ll, window) { + if(window->flush_pending) { + errno = EAGAIN; + break; + } + } + + return idle_time; } -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 -}; +/********************** + * PRIVATE FUNCTIONS + **********************/ -static void xdg_wm_base_ping(void * data, struct xdg_wm_base * xdg_wm_base, uint32_t serial) +void lv_wayland_init(void) { - LV_UNUSED(data); - xdg_wm_base_pong(xdg_wm_base, serial); + if(is_wayland_initialized) { + return; + } - return; -} + // Create XKB context + lv_wl_ctx.xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + LV_ASSERT_MSG(lv_wl_ctx.xkb_context, "failed to create XKB context"); + if(lv_wl_ctx.xkb_context == NULL) { + return; + } -static const struct xdg_wm_base_listener xdg_wm_base_listener = { - .ping = xdg_wm_base_ping -}; + // Connect to Wayland display + lv_wl_ctx.display = wl_display_connect(NULL); + LV_ASSERT_MSG(lv_wl_ctx.display, "failed to connect to Wayland server"); + if(lv_wl_ctx.display == NULL) { + return; + } + +#if LV_WAYLAND_USE_DMABUF + lv_wayland_dmabuf_initalize_context(&lv_wl_ctx.dmabuf_ctx); +#endif + lv_wayland_shm_initalize_context(&lv_wl_ctx.shm_ctx); + + /* Add registry listener and wait for registry reception */ + lv_wl_ctx.registry = wl_display_get_registry(lv_wl_ctx.display); + wl_registry_add_listener(lv_wl_ctx.registry, ®istry_listener, &lv_wl_ctx); + wl_display_dispatch(lv_wl_ctx.display); + wl_display_roundtrip(lv_wl_ctx.display); + + LV_ASSERT_MSG(lv_wl_ctx.compositor, "Wayland compositor not available"); + if(lv_wl_ctx.compositor == NULL) { + return; + } + + bool shm_ready = lv_wayland_shm_is_ready(&lv_wl_ctx.shm_ctx); + LV_ASSERT_MSG(shm_ready, "Couldn't initialize wayland SHM"); + if(!shm_ready) { + LV_LOG_ERROR("Couldn't initialize wayland SHM"); + return; + } + lv_wl_ctx.cursor_theme = lv_wayland_shm_load_cursor_theme(&lv_wl_ctx.shm_ctx); + if(!lv_wl_ctx.cursor_theme) { + LV_LOG_WARN("Failed to initialize the cursor theme"); + } + +#if LV_WAYLAND_USE_DMABUF + bool dmabuf_ready = lv_wayland_dmabuf_is_ready(&lv_wl_ctx.dmabuf_ctx); + LV_ASSERT_MSG(dmabuf_ready, "Couldn't initialize wayland DMABUF"); + if(!dmabuf_ready) { + LV_LOG_ERROR("Couldn't initialize wayland DMABUF"); + return; + } #endif +#ifdef LV_WAYLAND_WINDOW_DECORATIONS + const char * env_disable_decorations = getenv("LV_WAYLAND_DISABLE_WINDOWDECORATION"); + lv_wl_ctx.opt_disable_decorations = ((env_disable_decorations != NULL) && (env_disable_decorations[0] != '0')); +#endif -static void handle_global(void * data, struct wl_registry * registry, - uint32_t name, const char * interface, uint32_t version) + lv_ll_init(&lv_wl_ctx.window_ll, sizeof(struct window)); + + lv_tick_set_cb(tick_get_cb); + + /* Used to wait for events when the window is minimized or hidden */ + lv_wl_ctx.wayland_pfd.fd = wl_display_get_fd(lv_wl_ctx.display); + lv_wl_ctx.wayland_pfd.events = POLLIN; + + is_wayland_initialized = true; +} + +void lv_wayland_deinit(void) { - struct application * app = data; + struct window * window = NULL; + + LV_LL_READ(&lv_wl_ctx.window_ll, window) { + if(!window->closed) { + lv_wayland_window_destroy(window); + } + + /* TODO: This should probably be moved inside lv_wayland_window_destroy but not sure about the if condition */ +#if LV_WAYLAND_USE_DMABUF + lv_wayland_dmabuf_destroy_draw_buffers(&lv_wl_ctx.dmabuf_ctx, window); +#else + lv_wayland_shm_delete_draw_buffers(&lv_wl_ctx.shm_ctx, window); +#endif + lv_display_delete(window->lv_disp); + } + + lv_wayland_shm_deinit(&lv_wl_ctx.shm_ctx); +#if LV_WAYLAND_USE_DMABUF + lv_wayland_dmabuf_deinit(&lv_wl_ctx.dmabuf_ctx); +#endif + +#if LV_WAYLAND_WL_SHELL + lv_wayland_wl_shell_deinit(); +#elif LV_WAYLAND_XDG_SHELL + lv_wayland_xdg_shell_deinit(); +#endif + + if(lv_wl_ctx.wl_seat) { + wl_seat_destroy(lv_wl_ctx.wl_seat); + } + + if(lv_wl_ctx.subcompositor) { + wl_subcompositor_destroy(lv_wl_ctx.subcompositor); + } + + if(lv_wl_ctx.compositor) { + wl_compositor_destroy(lv_wl_ctx.compositor); + } + + wl_registry_destroy(lv_wl_ctx.registry); + wl_display_flush(lv_wl_ctx.display); + wl_display_disconnect(lv_wl_ctx.display); + + lv_ll_clear(&lv_wl_ctx.window_ll); +} + +void lv_wayland_wait_flush_cb(lv_display_t * disp) +{ + struct window * window = lv_display_get_user_data(disp); + /* TODO: Figure out why we need this */ + if(window->frame_counter == 0) { + return; + } + uint32_t initial_frame_counter = window->frame_counter; + while(initial_frame_counter == window->frame_counter) { + poll(&lv_wl_ctx.wayland_pfd, 1, -1); + handle_input(); + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +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; +} +static void handle_global(void * data, struct wl_registry * registry, uint32_t name, const char * interface, + uint32_t version) +{ + struct lv_wayland_context * app = data; LV_UNUSED(version); LV_UNUSED(data); @@ -1231,13 +331,13 @@ static void handle_global(void * data, struct wl_registry * registry, 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); + + lv_wayland_shm_set_interface(&app->shm_ctx, app->registry, name, interface, version); + } 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); + wl_seat_add_listener(app->wl_seat, lv_wayland_seat_get_listener(), app); } #if LV_WAYLAND_WL_SHELL else if(strcmp(interface, wl_shell_interface.name) == 0) { @@ -1246,9 +346,16 @@ static void handle_global(void * data, struct wl_registry * registry, #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); + /* supporting version 2 of the XDG protocol - ensures greater compatibility */ + app->xdg_wm = wl_registry_bind(app->registry, name, &xdg_wm_base_interface, 2); + xdg_wm_base_add_listener(app->xdg_wm, lv_wayland_xdg_shell_get_wm_base_listener(), app); + } +#endif +#if LV_WAYLAND_USE_DMABUF + else if(strcmp(interface, zwp_linux_dmabuf_v1_interface.name) == 0) { + lv_wayland_dmabuf_set_interface(&app->dmabuf_ctx, app->registry, name, interface, version); + + wl_display_roundtrip(app->display); } #endif } @@ -1259,984 +366,26 @@ static void handle_global_remove(void * data, struct wl_registry * registry, uin 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) +static void handle_input(void) { - const struct smm_buffer_properties * props; - struct graphic_object * obj; - struct window * window; - smm_buffer_t * buf; + int prepare_read = -1; - 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_dispatch_pending(lv_wl_ctx.display); + prepare_read = wl_display_prepare_read(lv_wl_ctx.display); } - - wl_display_read_events(application.display); - wl_display_dispatch_pending(application.display); + wl_display_read_events(lv_wl_ctx.display); + wl_display_dispatch_pending(lv_wl_ctx.display); } -static void _lv_wayland_handle_output(void) +static void handle_output(void) { struct window * window; - bool shall_flush = application.cursor_flush_pending; + bool shall_flush = lv_wl_ctx.cursor_flush_pending; - LV_LL_READ(&application.window_ll, window) { + LV_LL_READ(&lv_wl_ctx.window_ll, window) { if((window->shall_close) && (window->close_cb != NULL)) { window->shall_close = window->close_cb(window->lv_disp); } @@ -2245,616 +394,45 @@ static void _lv_wayland_handle_output(void) continue; } else if(window->shall_close) { - window->closed = true; + window->closed = true; window->shall_close = false; - shall_flush = true; + 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.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.pointer.wheel_diff = 0; + if(window->wl_ctx->pointer_obj == window->body) { + window->wl_ctx->pointer_obj = NULL; } - window->body->input.keyboard.key = 0; + 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; + if(window->wl_ctx->keyboard_obj == window->body) { + window->wl_ctx->keyboard_obj = NULL; } - destroy_window(window); + lv_wayland_window_destroy(window); } shall_flush |= window->flush_pending; } if(shall_flush) { - if(wl_display_flush(application.display) == -1) { + if(wl_display_flush(lv_wl_ctx.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) { + lv_wl_ctx.cursor_flush_pending = false; + LV_LL_READ(&lv_wl_ctx.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 index f3d340b0d..9d6ebf240 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland.h @@ -1,22 +1,10 @@ -/******************************************************************* - * - * @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) - * - ******************************************************************/ +/** + * @file lv_wayland.h + */ + #ifndef LV_WAYLAND_H #define LV_WAYLAND_H -#ifndef _WIN32 - #ifdef __cplusplus extern "C" { #endif @@ -25,11 +13,16 @@ extern "C" { * INCLUDES *********************/ -#include "../../display/lv_display.h" -#include "../../indev/lv_indev.h" +#include "../../lv_conf_internal.h" #if LV_USE_WAYLAND +#include "lv_wl_keyboard.h" +#include "lv_wl_pointer.h" +#include "lv_wl_touch.h" +#include "lv_wl_window.h" +#include "lv_wl_pointer_axis.h" + /********************* * DEFINES *********************/ @@ -38,95 +31,22 @@ extern "C" { * 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 + * @return time till it needs to be run next (in ms) */ -bool lv_wayland_timer_handler(void); +uint32_t lv_wayland_timer_handler(void); + +/** + * Retrieves the file descriptor of the wayland socket + */ +int lv_wayland_get_fd(void); /********************** * MACROS @@ -138,5 +58,4 @@ bool lv_wayland_timer_handler(void); } /* extern "C" */ #endif -#endif /* _WIN32 */ #endif /* WAYLAND_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_private.h b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_private.h new file mode 100644 index 000000000..374eb0bab --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_private.h @@ -0,0 +1,374 @@ +/** + * @file lv_wayland_private.h + * + */ + +#ifndef LV_WAYLAND_PRIVATE_H +#define LV_WAYLAND_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_wayland.h" +#if LV_USE_WAYLAND + + +#include "lv_wayland_smm.h" +#include +#include +#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 LV_WAYLAND_DEFAULT_CURSOR_NAME "left_ptr" + +#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 +#else +#define TITLE_BAR_HEIGHT 0 +#define BORDER_SIZE 0 +#endif + +#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)) + +#ifndef LV_WAYLAND_CYCLE_PERIOD +#define LV_WAYLAND_CYCLE_PERIOD LV_MIN(LV_DEF_REFR_PERIOD, 1) +#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; + +#if LV_USE_GESTURE_RECOGNITION + lv_indev_touch_data_t touches[10]; + uint8_t touch_event_cnt; + uint8_t primary_id; +#endif +}; + +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; + struct wl_subsurface * subsurface; + smm_buffer_t * pending_buffer; + smm_group_t * buffer_group; + struct input input; + enum object_type type; + int width; + int height; +}; + +typedef struct { + struct buffer * buffers; + struct zwp_linux_dmabuf_v1 * handler; + uint32_t format; +} dmabuf_ctx_t; + +typedef struct { + lv_draw_buf_t * lv_draw_buf; + struct wl_shm * handler; + uint32_t format; +} shm_ctx_t; + +struct lv_wayland_context { + struct wl_display * display; + struct wl_registry * registry; + struct wl_compositor * compositor; + struct wl_subcompositor * subcompositor; + struct wl_seat * wl_seat; + struct wl_cursor_theme * cursor_theme; + struct wl_surface * cursor_surface; + shm_ctx_t shm_ctx; + +#if LV_WAYLAND_USE_DMABUF + dmabuf_ctx_t dmabuf_ctx; +#endif + +#if LV_WAYLAND_WL_SHELL + struct wl_shell * wl_shell; +#endif + +#if LV_WAYLAND_XDG_SHELL + struct xdg_wm_base * xdg_wm; +#endif + +#ifdef LV_WAYLAND_WINDOW_DECORATIONS + bool opt_disable_decorations; +#endif + + 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_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 lv_wayland_context * wl_ctx; + +#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; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +extern struct lv_wayland_context lv_wl_ctx; + +/********************** + * Driver + **********************/ + +void lv_wayland_init(void); +void lv_wayland_deinit(void); +void lv_wayland_wait_flush_cb(lv_display_t * disp); +/********************** + * Window + **********************/ + +const struct wl_callback_listener * lv_wayland_window_get_wl_surface_frame_listener(void); + +void lv_wayland_window_draw(struct window * window, uint32_t width, uint32_t height); +lv_result_t lv_wayland_window_resize(struct window * window, int width, int height); +void lv_wayland_window_destroy(struct window * window); +#if LV_WAYLAND_WINDOW_DECORATIONS +uint32_t lv_wayland_window_decoration_create_all(struct window * window); +void lv_wayland_window_decoration_detach_all(struct window * window); +bool lv_wayland_window_decoration_create(struct window * window, struct graphic_object * decoration, int window_width, + int window_height); +bool lv_wayland_window_decoration_attach(struct window * window, struct graphic_object * decoration, + smm_buffer_t * decoration_buffer, struct graphic_object * parent); +void lv_wayland_window_decoration_detach(struct window * window, struct graphic_object * decoration); +#endif + +/********************** + * Window Management + **********************/ + +#if LV_WAYLAND_WL_SHELL +lv_result_t lv_wayland_wl_shell_create_window(struct lv_wayland_context * app, struct window * window, + const char * title); +const struct wl_shell_surface_listener * lv_wayland_wl_shell_get_listener(void); +void lv_wayland_wl_shell_handle_pointer_event(struct lv_wayland_context * app, uint32_t serial, uint32_t button, + uint32_t state); +lv_result_t lv_wayland_wl_shell_set_maximized(struct window * window, bool maximized); +lv_result_t lv_wayland_wl_shell_set_minimized(struct window * window); +lv_result_t lv_wayland_wl_shell_set_fullscreen(struct window * window, bool fullscreen); +lv_result_t lv_wayland_wl_shell_destroy_window(struct window * window); +void lv_wayland_wl_shell_deinit(void); +#elif LV_WAYLAND_XDG_SHELL + +const struct xdg_surface_listener * lv_wayland_xdg_shell_get_surface_listener(void); +const struct xdg_toplevel_listener * lv_wayland_xdg_shell_get_toplevel_listener(void); +const struct xdg_wm_base_listener * lv_wayland_xdg_shell_get_wm_base_listener(void); +lv_result_t lv_wayland_xdg_shell_set_maximized(struct window * window, bool maximized); +lv_result_t lv_wayland_xdg_shell_set_minimized(struct window * window); +lv_result_t lv_wayland_xdg_shell_set_fullscreen(struct window * window, bool fullscreen); +lv_result_t lv_wayland_xdg_shell_create_window(struct lv_wayland_context * app, struct window * window, + const char * title); +lv_result_t lv_wayland_xdg_shell_destroy_window_toplevel(struct window * window); +lv_result_t lv_wayland_xdg_shell_destroy_window_surface(struct window * window); +void lv_wayland_xdg_shell_handle_pointer_event(struct lv_wayland_context * app, uint32_t serial, uint32_t button, + uint32_t state); + +const char * lv_wayland_xdg_shell_get_cursor_name(const struct lv_wayland_context * app); +void lv_wayland_xdg_shell_deinit(void); +#endif + +/********************** + * SHM + **********************/ + +void lv_wayland_shm_set_interface(shm_ctx_t * context, struct wl_registry * registry, uint32_t name, + const char * interface, uint32_t version); + +struct graphic_object * lv_wayland_shm_on_graphical_object_creation(shm_ctx_t * context, struct graphic_object * obj); +void lv_wayland_shm_on_graphical_object_destruction(shm_ctx_t * context, struct graphic_object * obj); +lv_result_t lv_wayland_shm_set_draw_buffers(shm_ctx_t * context, lv_display_t * display); +lv_result_t lv_wayland_shm_create_draw_buffers(shm_ctx_t * context, struct window * window); +lv_result_t lv_wayland_shm_resize_window(shm_ctx_t * context, struct window * window, int32_t width, int32_t height); +lv_result_t lv_wayland_shm_is_ready(shm_ctx_t * context); + +void lv_wayland_shm_delete_draw_buffers(shm_ctx_t * context, struct window * window); +void lv_wayland_shm_initalize_context(shm_ctx_t * context); +void lv_wayland_shm_deinit(shm_ctx_t * context); +void lv_wayland_shm_flush_partial_mode(lv_display_t * disp, const lv_area_t * area, unsigned char * color_p); + +struct wl_cursor_theme * lv_wayland_shm_load_cursor_theme(shm_ctx_t * context); + +/********************** + * DMABUF + **********************/ + +void lv_wayland_dmabuf_set_interface(dmabuf_ctx_t * context, struct wl_registry * registry, uint32_t name, + const char * interface, uint32_t version); + +struct graphic_object * lv_wayland_dmabuf_on_graphical_object_creation(dmabuf_ctx_t * context, + struct graphic_object * obj); + +void lv_wayland_dmabuf_on_graphical_object_destruction(dmabuf_ctx_t * context, struct graphic_object * obj); +lv_result_t lv_wayland_dmabuf_set_draw_buffers(dmabuf_ctx_t * context, lv_display_t * display); +lv_result_t lv_wayland_dmabuf_create_draw_buffers(dmabuf_ctx_t * context, struct window * window); +lv_result_t lv_wayland_dmabuf_resize_window(dmabuf_ctx_t * context, struct window * window); +lv_result_t lv_wayland_dmabuf_is_ready(dmabuf_ctx_t * context); + +void lv_wayland_dmabuf_destroy_draw_buffers(dmabuf_ctx_t * context, struct window * window); +void lv_wayland_dmabuf_initalize_context(dmabuf_ctx_t * context); +void lv_wayland_dmabuf_deinit(dmabuf_ctx_t * context); +void lv_wayland_dmabuf_flush_full_mode(lv_display_t * disp, const lv_area_t * area, unsigned char * color_p); + +/********************** + * SME + **********************/ + +const struct smm_events * lv_wayland_sme_get_events(void); + +/********************** + * Seat + **********************/ + +const struct wl_seat_listener * lv_wayland_seat_get_listener(void); + +/********************** + * Input + **********************/ + +const struct wl_keyboard_listener * lv_wayland_keyboard_get_listener(void); +const struct wl_pointer_listener * lv_wayland_pointer_get_listener(void); +const struct wl_touch_listener * lv_wayland_touch_get_listener(void); + +/********************** + * Cache + **********************/ + +void lv_wayland_cache_add_area(struct window * window, smm_buffer_t * buf, const lv_area_t * area); +void lv_wayland_cache_clear(struct window * window); +void lv_wayland_cache_apply_areas(struct window * window, void * dest, void * src, smm_buffer_t * src_buf); +void lv_wayland_cache_purge(struct window * window, smm_buffer_t * buf); + +#endif /* LV_USE_WAYLAND */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_WAYLAND_PRIVATE_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 index 7cb982a0f..168e45de8 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_smm.c +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_smm.c @@ -8,7 +8,6 @@ typedef int dummy_t; /* Make GCC on windows happy, avoid empty translation u #ifndef _WIN32 #include "lv_wayland_smm.h" -#include "../../display/lv_display.h" #if LV_USE_WAYLAND @@ -144,7 +143,7 @@ static struct { } smm_instance; -void smm_init(struct smm_events * evs) +void smm_init(const struct smm_events * evs) { memcpy(&smm_instance.cbs, evs, sizeof(struct smm_events)); srand((unsigned int)clock()); @@ -175,7 +174,7 @@ smm_group_t * smm_create(void) { struct smm_group * grp; - /* Allocate and intialize a new buffer group */ + /* Allocate and initialize a new buffer group */ grp = malloc(sizeof(struct smm_group)); if(grp != NULL) { grp->size = smm_instance.page_sz; @@ -406,7 +405,7 @@ size_t calc_buffer_size(struct smm_buffer * buf) struct smm_buffer * get_from_pool(struct smm_group * grp) { int ret; - size_t buf_sz; + size_t buf_sz = 0; struct smm_buffer * buf; struct smm_buffer * last = NULL; @@ -644,7 +643,7 @@ struct smm_buffer * alloc_buffer(struct smm_buffer * last, size_t offset) offset }; - /* Allocate and intialize a new buffer (including linking in to pool) */ + /* Allocate and initialize 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)); 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 index 617244f17..f3a16e9e2 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_smm.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wayland_smm.h @@ -69,7 +69,7 @@ struct smm_group_properties { void * tag[SMM_GROUP_TAGS]; }; -void smm_init(struct smm_events * evs); +void smm_init(const struct smm_events * evs); void smm_setctx(void * ctx); void smm_deinit(void); smm_group_t * smm_create(void); diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_cache.c b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_cache.c new file mode 100644 index 000000000..5d810516f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_cache.c @@ -0,0 +1,133 @@ +/** + * @file lv_wl_cache.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_wayland.h" + +#if LV_USE_WAYLAND + +#include "lv_wayland_private.h" +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * PRIVATE FUNCTIONS + **********************/ + +void lv_wayland_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; + } +} + +void lv_wayland_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 */ + return; + } + + 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 + */ + lv_wayland_cache_clear(window); + SMM_TAG(buf, TAG_BUFFER_DAMAGE, NULL); + return; + } + + /* 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++; +} + +void lv_wayland_cache_clear(struct window * window) +{ + window->dmg_cache.start = window->dmg_cache.end; + window->dmg_cache.size = 0; +} + +void lv_wayland_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) { + lv_wayland_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 FUNCTIONS + **********************/ + +#endif /* LV_USE_WAYLAND */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_dmabuf.c b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_dmabuf.c new file mode 100644 index 000000000..ce6cb9bb8 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_dmabuf.c @@ -0,0 +1,360 @@ +/** + * @file lv_wl_dmabuf.c + * + */ + +#include "lv_wayland.h" + +#if LV_WAYLAND_USE_DMABUF + +#include "lv_wayland_private.h" +#include +#include +#include +#include +#include +#include "../../draw/nxp/g2d/lv_g2d_utils.h" + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +#define MAX_BUFFER_PLANES 4 + +struct buffer { + int busy; + +#if LV_WAYLAND_USE_DMABUF + struct window * window; + int plane_count; + + int dmabuf_fds[MAX_BUFFER_PLANES]; + uint32_t strides[MAX_BUFFER_PLANES]; + uint32_t offsets[MAX_BUFFER_PLANES]; + struct wl_buffer * buffer; +#endif + + void * buf_base[MAX_BUFFER_PLANES]; + lv_draw_buf_t * lv_draw_buf; +}; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void dmabuf_modifiers(void * data, struct zwp_linux_dmabuf_v1 * zwp_linux_dmabuf, uint32_t format, + uint32_t modifier_hi, uint32_t modifier_lo); +static void dmabuf_format(void * data, struct zwp_linux_dmabuf_v1 * zwp_linux_dmabuf, uint32_t format); +static struct buffer * dmabuf_acquire_buffer(dmabuf_ctx_t * context, unsigned char * color_p); +static struct buffer * lv_wayland_dmabuf_create_draw_buffers_internal(struct window * window); +static void buffer_free(struct buffer * buf); + +/********************** + * STATIC VARIABLES + **********************/ + +static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener_v3 = {.format = dmabuf_format, + .modifier = dmabuf_modifiers +}; +static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = {.format = dmabuf_format}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * PRIVATE FUNCTIONS + **********************/ + +void lv_wayland_dmabuf_initalize_context(dmabuf_ctx_t * context) +{ + memset(context, 0, sizeof(*context)); + context->format = DRM_FORMAT_INVALID; +} +lv_result_t lv_wayland_dmabuf_set_draw_buffers(dmabuf_ctx_t * context, lv_display_t * display) +{ + if(LV_WAYLAND_BUF_COUNT == 2) { + lv_display_set_draw_buffers(display, context->buffers[0].lv_draw_buf, context->buffers[1].lv_draw_buf); + return LV_RESULT_OK; + } + else if(LV_WAYLAND_BUF_COUNT == 1) { + lv_display_set_draw_buffers(display, context->buffers[0].lv_draw_buf, NULL); + return LV_RESULT_OK; + } + return LV_RESULT_INVALID; +} + +void lv_wayland_dmabuf_set_interface(dmabuf_ctx_t * context, struct wl_registry * registry, uint32_t name, + const char * interface, uint32_t version) +{ + LV_UNUSED(interface); + if(version > 3) { + LV_LOG_WARN("Unsupported DMABUF version %d. Using version 3 instead", version); + version = 3; + } + + context->handler = wl_registry_bind(registry, name, &zwp_linux_dmabuf_v1_interface, version); + if(version < 3) { + zwp_linux_dmabuf_v1_add_listener(context->handler, &dmabuf_listener, context); + } + else if(version == 3) { + zwp_linux_dmabuf_v1_add_listener(context->handler, &dmabuf_listener_v3, context); + } +} + +lv_result_t lv_wayland_dmabuf_is_ready(dmabuf_ctx_t * context) +{ + return (context->handler && context->format != DRM_FORMAT_INVALID) ? LV_RESULT_OK : LV_RESULT_INVALID; +} + +void lv_wayland_dmabuf_destroy_window(dmabuf_ctx_t * context, struct window * window) +{ + LV_UNUSED(context); + LV_ASSERT_NULL(window); +} + +void lv_wayland_dmabuf_deinit(dmabuf_ctx_t * context) +{ + LV_UNUSED(context); +} + +struct graphic_object * lv_wayland_dmabuf_on_graphical_object_creation(dmabuf_ctx_t * context, + struct graphic_object * obj) +{ + LV_UNUSED(context); + return obj; +} + +void lv_wayland_dmabuf_on_graphical_object_destruction(dmabuf_ctx_t * context, struct graphic_object * obj) +{ + + LV_UNUSED(context); + LV_UNUSED(obj); +} + +void lv_wayland_dmabuf_flush_full_mode(lv_display_t * disp, const lv_area_t * area, unsigned char * color_p) +{ + struct window * window = lv_display_get_user_data(disp); + struct buffer * buf = dmabuf_acquire_buffer(&window->wl_ctx->dmabuf_ctx, color_p); + if(!buf) { + LV_LOG_ERROR("Failed to acquire a wayland window body buffer"); + return; + } + + int32_t src_width = lv_area_get_width(area); + int32_t src_height = lv_area_get_height(area); + + lv_draw_buf_invalidate_cache(buf->lv_draw_buf, NULL); + + /* Mark surface damage */ + wl_surface_damage(window->body->surface, area->x1, area->y1, src_width, src_height); + + if(lv_display_flush_is_last(disp)) { + /* Finally, attach buffer and commit to surface */ + wl_surface_attach(window->body->surface, buf->buffer, 0, 0); + wl_surface_commit(window->body->surface); + + struct wl_callback * cb = wl_surface_frame(window->body->surface); + wl_callback_add_listener(cb, lv_wayland_window_get_wl_surface_frame_listener(), window->body); + + buf->busy = 1; + window->flush_pending = true; + } + + return; +} +/********************** + * STATIC FUNCTIONS + **********************/ + +static void buffer_release(void * data, struct wl_buffer * buffer) +{ + LV_UNUSED(buffer); + struct buffer * buf = data; + buf->busy = 0; +} + +static const struct wl_buffer_listener buffer_listener = {.release = buffer_release}; + +static void create_succeeded(void * data, struct zwp_linux_buffer_params_v1 * params, struct wl_buffer * new_buffer) +{ + struct buffer * buffer = data; + buffer->buffer = new_buffer; + /* When not using explicit synchronization listen to wl_buffer.release + * for release notifications, otherwise we are going to use + * zwp_linux_buffer_release_v1. */ + wl_buffer_add_listener(buffer->buffer, &buffer_listener, buffer); + + zwp_linux_buffer_params_v1_destroy(params); +} + +static void create_failed(void * data, struct zwp_linux_buffer_params_v1 * params) +{ + struct buffer * buffer = data; + + buffer->buffer = NULL; + zwp_linux_buffer_params_v1_destroy(params); + LV_LOG_ERROR("Failed to create dmabuf buffer\n"); +} + +static const struct zwp_linux_buffer_params_v1_listener params_listener = {.created = create_succeeded, + .failed = create_failed +}; + +lv_result_t lv_wayland_dmabuf_resize_window(dmabuf_ctx_t * context, struct window * window) +{ + struct buffer * buffers = lv_wayland_dmabuf_create_draw_buffers_internal(window); + if(!buffers) { + return LV_RESULT_INVALID; + } + lv_wayland_dmabuf_destroy_draw_buffers(context, window); + + context->buffers = buffers; + lv_wayland_dmabuf_set_draw_buffers(context, window->lv_disp); + return LV_RESULT_OK; +} + +lv_result_t lv_wayland_dmabuf_create_draw_buffers(dmabuf_ctx_t * context, struct window * window) +{ + struct buffer * buffers = lv_wayland_dmabuf_create_draw_buffers_internal(window); + if(!buffers) { + return LV_RESULT_INVALID; + } + + context->buffers = buffers; + return LV_RESULT_OK; +} + +void lv_wayland_dmabuf_destroy_draw_buffers(dmabuf_ctx_t * context, struct window * window) +{ + LV_UNUSED(window); + if(context->buffers == NULL) { + return; + } + for(int i = 0; i < LV_WAYLAND_BUF_COUNT; i++) { + buffer_free(&context->buffers[i]); + return; + } + free(context->buffers); + context->buffers = NULL; +} + +static struct buffer * lv_wayland_dmabuf_create_draw_buffers_internal(struct window * window) +{ + const uint32_t flags = 0; + struct zwp_linux_buffer_params_v1 * params; + const int stride = lv_draw_buf_width_to_stride(window->width, lv_display_get_color_format(window->lv_disp)); + struct buffer * buffers = (struct buffer *)calloc(LV_WAYLAND_BUF_COUNT, sizeof(struct buffer)); + LV_ASSERT_MALLOC(buffers); + + for(int i = 0; i < LV_WAYLAND_BUF_COUNT; i++) { + uint32_t drmcf = 0; + + buffers[i].window = window; + buffers[i].lv_draw_buf = + lv_draw_buf_create(window->width, window->height, lv_display_get_color_format(window->lv_disp), stride); + buffers[i].strides[0] = stride; + buffers[i].dmabuf_fds[0] = g2d_get_buf_fd(buffers[i].lv_draw_buf); + buffers[i].buf_base[0] = buffers[i].lv_draw_buf->data; + params = zwp_linux_dmabuf_v1_create_params(window->wl_ctx->dmabuf_ctx.handler); + + switch(lv_display_get_color_format(window->lv_disp)) { + case LV_COLOR_FORMAT_XRGB8888: + drmcf = DRM_FORMAT_XRGB8888; + break; + case LV_COLOR_FORMAT_ARGB8888: + drmcf = DRM_FORMAT_ARGB8888; + break; + case LV_COLOR_FORMAT_RGB565: + drmcf = DRM_FORMAT_RGB565; + break; + default: + drmcf = DRM_FORMAT_ARGB8888; + } + + zwp_linux_buffer_params_v1_add(params, buffers[i].dmabuf_fds[0], 0, buffers[i].offsets[0], buffers[i].strides[0], 0, + 0); + + zwp_linux_buffer_params_v1_add_listener(params, ¶ms_listener, &buffers[i]); + zwp_linux_buffer_params_v1_create(params, window->width, window->height, drmcf, flags); + } + + wl_display_roundtrip(lv_wl_ctx.display); + + return buffers; +} + +static void buffer_free(struct buffer * buf) +{ + if(buf->buffer) wl_buffer_destroy(buf->buffer); + + if(buf->lv_draw_buf) lv_draw_buf_destroy(buf->lv_draw_buf); +} + +static void dmabuf_modifiers(void * data, struct zwp_linux_dmabuf_v1 * zwp_linux_dmabuf, uint32_t format, + uint32_t modifier_hi, uint32_t modifier_lo) +{ + LV_UNUSED(modifier_hi); + LV_UNUSED(modifier_lo); + dmabuf_format(data, zwp_linux_dmabuf, format); +} + +static void dmabuf_format(void * data, struct zwp_linux_dmabuf_v1 * zwp_linux_dmabuf, uint32_t format) +{ + dmabuf_ctx_t * ctx = data; + + LV_UNUSED(zwp_linux_dmabuf); + + if(LV_COLOR_DEPTH == 32 && format == DRM_FORMAT_ARGB8888) { + + /* Wayland compositors MUST support ARGB8888 */ + ctx->format = format; + + } + else if(LV_COLOR_DEPTH == 32 && format == DRM_FORMAT_XRGB8888 && ctx->format != DRM_FORMAT_ARGB8888) { + /* Select XRGB only if the compositor doesn't support transprancy */ + ctx->format = format; + + } + else if(LV_COLOR_DEPTH == 16 && format == DRM_FORMAT_RGB565) { + ctx->format = format; + } +} + +static struct buffer * dmabuf_acquire_buffer(dmabuf_ctx_t * context, unsigned char * color_p) +{ + + for(int i = 0; i < LV_WAYLAND_BUF_COUNT; i++) { + struct buffer * buffer = &context->buffers[i]; + if(buffer->buf_base[0] == color_p && buffer->busy == 0) { + return buffer; + } + } + + while(1) { + wl_display_roundtrip(lv_wl_ctx.display); + + for(int i = 0; i < LV_WAYLAND_BUF_COUNT; i++) { + struct buffer * buffer = &context->buffers[i]; + if(buffer->buf_base[0] == color_p && buffer->busy == 0) { + return buffer; + } + } + } + + return NULL; +} + +#endif /* LV_WAYLAND_DMABUF */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_keyboard.c b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_keyboard.c new file mode 100644 index 000000000..27b589271 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_keyboard.c @@ -0,0 +1,301 @@ +/** + * @file lv_wl_keyboard.c + * + */ + +#include "lv_wl_keyboard.h" + +#if LV_USE_WAYLAND + +#include "lv_wayland_private.h" +#include +#include +#include +#include +#include "../../misc/lv_log.h" + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void keyboard_read(lv_indev_t * drv, lv_indev_data_t * data); + +static void keyboard_handle_keymap(void * data, struct wl_keyboard * keyboard, uint32_t format, int fd, uint32_t size); +static void keyboard_handle_enter(void * data, struct wl_keyboard * keyboard, uint32_t serial, + struct wl_surface * surface, struct wl_array * keys); +static void keyboard_handle_leave(void * data, struct wl_keyboard * keyboard, uint32_t serial, + struct wl_surface * surface); + +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); + +static void keyboard_handle_key(void * data, struct wl_keyboard * keyboard, uint32_t serial, uint32_t time, + uint32_t key, uint32_t state); + +static lv_key_t keycode_xkb_to_lv(xkb_keysym_t xkb_key); + +/********************** + * STATIC VARIABLES + **********************/ + +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, +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_indev_t * lv_wayland_keyboard_create(void) +{ + + lv_indev_t * keyboard = lv_indev_create(); + lv_indev_set_type(keyboard, LV_INDEV_TYPE_KEYPAD); + lv_indev_set_read_cb(keyboard, keyboard_read); + + return keyboard; +} + +lv_indev_t * lv_wayland_get_keyboard(lv_display_t * display) +{ + struct window * window = lv_display_get_user_data(display); + if(!window) { + return NULL; + } + return window->lv_indev_keyboard; +} + +/********************** + * PRIVATE FUNCTIONS + **********************/ + +const struct wl_keyboard_listener * lv_wayland_keyboard_get_listener(void) +{ + return &keyboard_listener; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void 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 keyboard_handle_keymap(void * data, struct wl_keyboard * keyboard, uint32_t format, int fd, uint32_t size) +{ + struct lv_wayland_context * 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 lv_wayland_context * 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 lv_wayland_context * 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 lv_wayland_context * 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 lv_wayland_context * 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 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; +} + +#endif /* LV_WAYLAND */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_keyboard.h b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_keyboard.h new file mode 100644 index 000000000..86296d448 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_keyboard.h @@ -0,0 +1,52 @@ +/** + * @file lv_wl_keyboard.h + * + */ + +#ifndef LV_WL_KEYBOARD_H +#define LV_WL_KEYBOARD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../indev/lv_indev.h" +#include "../../indev/lv_indev_gesture.h" +#if LV_USE_WAYLAND + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_indev_t * lv_wayland_keyboard_create(void); + +/** + * Get keyboard input device for given LVGL display + * @param display LVGL display + * @return input device connected to keyboard, or NULL on error + */ +lv_indev_t * lv_wayland_get_keyboard(lv_display_t * display); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_WAYLAND */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_WL_KEYBOARD_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer.c b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer.c new file mode 100644 index 000000000..e406d47e2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer.c @@ -0,0 +1,245 @@ +/** + * @file lv_wl_pointer.c + * + */ + +#include "lv_wl_pointer.h" + +#if LV_USE_WAYLAND + +#include +#include +#include +#include +#include +#include +#include "lv_wayland_private.h" + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void _lv_wayland_pointer_read(lv_indev_t * drv, lv_indev_data_t * data); + +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); + +static void pointer_handle_leave(void * data, struct wl_pointer * pointer, uint32_t serial, + struct wl_surface * surface); + +static void pointer_handle_motion(void * data, struct wl_pointer * pointer, uint32_t time, wl_fixed_t sx, + wl_fixed_t sy); + +static void pointer_handle_button(void * data, struct wl_pointer * wl_pointer, uint32_t serial, uint32_t time, + uint32_t button, uint32_t state); + +static void pointer_handle_axis(void * data, struct wl_pointer * wl_pointer, uint32_t time, uint32_t axis, + wl_fixed_t value); + +/********************** + * STATIC VARIABLES + **********************/ + +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, +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_indev_t * lv_wayland_pointer_create(void) +{ + lv_indev_t * indev = lv_indev_create(); + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, _lv_wayland_pointer_read); + return indev; +} + +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; +} + +/********************** + * PRIVATE FUNCTIONS + **********************/ + +const struct wl_pointer_listener * lv_wayland_pointer_get_listener(void) +{ + return &pointer_listener; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +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 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 lv_wayland_context * app = data; + const char * cursor = LV_WAYLAND_DEFAULT_CURSOR_NAME; + 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_XDG_SHELL + cursor = lv_wayland_xdg_shell_get_cursor_name(app); +#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 lv_wayland_context * 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 lv_wayland_context * 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 lv_wayland_context * 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; + } + struct window * window = app->pointer_obj->window; + +#if LV_WAYLAND_WL_SHELL + lv_wayland_wl_shell_handle_pointer_event(app, serial, button, state); +#elif LV_WAYLAND_XDG_SHELL + lv_wayland_xdg_shell_handle_pointer_event(app, serial, button, state); +#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; + case OBJECT_BUTTON_CLOSE: + if((button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_RELEASED)) { + window->shall_close = true; + } + break; + 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 lv_wayland_context * 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--; + } + } +} + +#endif /* LV_USE_WAYLAND */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer.h b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer.h new file mode 100644 index 000000000..265394c77 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer.h @@ -0,0 +1,54 @@ + +/** + * @file lv_wl_pointer.h + * + */ + +#ifndef LV_WL_POINTER_H +#define LV_WL_POINTER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../indev/lv_indev.h" +#include "../../indev/lv_indev_gesture.h" +#if LV_USE_WAYLAND + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_indev_t * lv_wayland_pointer_create(void); + +/** + * 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); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_WAYLAND */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_WL_POINTER_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer_axis.c b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer_axis.c new file mode 100644 index 000000000..f61bbe794 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer_axis.c @@ -0,0 +1,79 @@ +/** + * @file lv_wl_pointer_axis.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_wl_pointer_axis.h" + +#if LV_USE_WAYLAND + +#include "lv_wayland_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void pointeraxis_read(lv_indev_t * drv, lv_indev_data_t * data); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_indev_t * lv_wayland_pointer_axis_create(void) +{ + + lv_indev_t * indev = lv_indev_create(); + lv_indev_set_type(indev, LV_INDEV_TYPE_ENCODER); + lv_indev_set_read_cb(indev, pointeraxis_read); + + return indev; +} + +lv_indev_t * lv_wayland_get_pointeraxis(lv_display_t * display) +{ + struct window * window = lv_display_get_user_data(display); + if(!window) { + return NULL; + } + return window->lv_indev_pointeraxis; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void 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; +} + +#endif /* LV_USE_WAYLAND */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer_axis.h b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer_axis.h new file mode 100644 index 000000000..d3564a504 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_pointer_axis.h @@ -0,0 +1,54 @@ +/** + * @file lv_wl_pointer_axis.h + * + */ + +#ifndef LV_WL_POINTER_AXIS_H +#define LV_WL_POINTER_AXIS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../indev/lv_indev.h" +#include "../../indev/lv_indev_gesture.h" + +#if LV_USE_WAYLAND + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_indev_t * lv_wayland_pointer_axis_create(void); + +/** + * Obtains the input device of the encoder + * @note It is used to create an input group on application start + * @param display Reference to the LVGL display associated to the window + * @return The input device + */ +lv_indev_t * lv_wayland_get_pointeraxis(lv_display_t * display); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_WAYLAND */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_WL_POINTER_AXIS_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_seat.c b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_seat.c new file mode 100644 index 000000000..e4176553c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_seat.c @@ -0,0 +1,100 @@ +/** + * @file lv_wl_seat.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_wayland.h" + +#if LV_USE_WAYLAND + +#include "lv_wayland_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void seat_handle_capabilities(void * data, struct wl_seat * wl_seat, enum wl_seat_capability caps); + +/********************** + * STATIC VARIABLES + **********************/ + +static const struct wl_seat_listener seat_listener = { + .capabilities = seat_handle_capabilities, +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * PRIVATE FUNCTIONS + **********************/ + +const struct wl_seat_listener * lv_wayland_seat_get_listener(void) +{ + return &seat_listener; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void seat_handle_capabilities(void * data, struct wl_seat * wl_seat, enum wl_seat_capability caps) +{ + struct lv_wayland_context * 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, lv_wayland_pointer_get_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, lv_wayland_keyboard_get_listener(), app); + } + else if(!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && seat->wl_keyboard) { + wl_keyboard_destroy(seat->wl_keyboard); + seat->wl_keyboard = NULL; + } + +#if LV_USE_GESTURE_RECOGNITION + 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, lv_wayland_touch_get_listener(), app); + } +#endif + else if(!(caps & WL_SEAT_CAPABILITY_TOUCH) && seat->wl_touch) { + wl_touch_destroy(seat->wl_touch); + seat->wl_touch = NULL; + } +} + +#endif /* LV_USE_WAYLAND */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_shell.c b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_shell.c new file mode 100644 index 000000000..5f3b24941 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_shell.c @@ -0,0 +1,184 @@ +/** + * @file lv_wl_shell.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_wayland.h" + +#if LV_WAYLAND_WL_SHELL + +/* WL_SHELL has been deprecated for 3 years now */ +#warning LV_WAYLAND_WL_SHELL is deprecated and will be removed in a future release + +#include "lv_wayland_private.h" +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void wl_shell_handle_ping(void * data, struct wl_shell_surface * shell_surface, uint32_t serial); +static void wl_shell_handle_configure(void * data, struct wl_shell_surface * shell_surface, uint32_t edges, + int32_t width, int32_t height); + +/********************** + * STATIC VARIABLES + **********************/ + +static const struct wl_shell_surface_listener shell_surface_listener = { + .ping = wl_shell_handle_ping, + .configure = wl_shell_handle_configure, +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * PRIVATE FUNCTIONS + **********************/ + +void lv_wayland_wl_shell_deinit(void) +{ + if(lv_wl_ctx.wl_shell) { + wl_shell_destroy(lv_wl_ctx.wl_shell); + } +} + +const struct wl_shell_surface_listener * lv_wayland_wl_shell_get_listener(void) +{ + return &shell_surface_listener; +} + +lv_result_t lv_wayland_wl_shell_create_window(struct lv_wayland_context * ctx, struct window * window, + const char * title) +{ + if(!ctx->wl_shell) { + return LV_RESULT_INVALID; + } + + window->wl_shell_surface = wl_shell_get_shell_surface(ctx->wl_shell, window->body->surface); + if(!window->wl_shell_surface) { + LV_LOG_ERROR("cannot create WL shell surface"); + return LV_RESULT_INVALID; + } + + wl_shell_surface_add_listener(window->wl_shell_surface, lv_wayland_wl_shell_get_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 */ + lv_wayland_window_draw(window, window->width, window->height); + return LV_RESULT_OK; +} + +lv_result_t lv_wayland_wl_shell_set_maximized(struct window * window, bool maximized) +{ + + if(!window->wl_shell_surface) { + return LV_RESULT_INVALID; + } + if(maximized) { + LV_LOG_ERROR("WL_SHELL - Unsupported operation - Maximization"); + return LV_RESULT_INVALID; + } + else { + wl_shell_surface_set_toplevel(window->wl_shell_surface); + } + return LV_RESULT_OK; +} + +lv_result_t lv_wayland_wl_shell_set_minimized(struct window * window) +{ + LV_LOG_ERROR("WL_SHELL - Unsupported operation - Minization"); + return LV_RESULT_INVALID; +} +lv_result_t lv_wayland_wl_shell_set_fullscreen(struct window * window, bool fullscreen) +{ + if(!window->wl_shell_surface) { + return LV_RESULT_INVALID; + } + 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); + } + return LV_RESULT_OK; +} + +lv_result_t lv_wayland_wl_shell_destroy_window(struct window * window) +{ + if(!window->wl_shell_surface) { + return LV_RESULT_INVALID; + } + wl_shell_surface_destroy(window->wl_shell_surface); + return LV_RESULT_OK; +} + +void lv_wayland_wl_shell_handle_pointer_event(struct lv_wayland_context * ctx, uint32_t serial, uint32_t button, + uint32_t state) +{ + struct window * window = ctx->pointer_obj->window; + switch(ctx->pointer_obj->type) { + case OBJECT_TITLEBAR: + if((button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_PRESSED)) { + if(window->wl_shell_surface) { + wl_shell_surface_move(window->wl_shell_surface, ctx->wl_seat, serial); + window->flush_pending = true; + } + } + break; + case OBJECT_BUTTON_CLOSE: + case OBJECT_BORDER_TOP: + case OBJECT_BORDER_BOTTOM: + case OBJECT_BORDER_LEFT: + case OBJECT_BORDER_RIGHT: + case OBJECT_WINDOW: + break; + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +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; + } +} + +#endif /* LV_WAYLAND_WL_SHELL */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_shm.c b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_shm.c new file mode 100644 index 000000000..87eb547c6 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_shm.c @@ -0,0 +1,468 @@ +/** + * @file lv_wl_shm.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_wayland.h" +#if LV_USE_WAYLAND + +#include "lv_wayland_private.h" +#include +#include +#include +#include +#include + +/********************* + * DEFINES + *********************/ + +#define SHM_FORMAT_UNKNOWN 0xFFFFFF + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +/* + * 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); +static void handle_wl_buffer_release(void * data, struct wl_buffer * wl_buffer); +static bool sme_new_pool(void * ctx, smm_pool_t * pool); +static void sme_expand_pool(void * ctx, smm_pool_t * pool); +static void sme_free_pool(void * ctx, smm_pool_t * pool); +static bool sme_new_buffer(void * ctx, smm_buffer_t * buf); +static bool sme_init_buffer(void * ctx, smm_buffer_t * buf); +static void sme_free_buffer(void * ctx, smm_buffer_t * buf); + +/********************** + * STATIC VARIABLES + **********************/ + +static const struct smm_events sme_events = {NULL, sme_new_pool, sme_expand_pool, sme_free_pool, + sme_new_buffer, sme_init_buffer, sme_free_buffer +}; + +static const struct wl_shm_listener shm_listener = {.format = shm_format}; + +static const struct wl_buffer_listener wl_buffer_listener = { + .release = handle_wl_buffer_release, +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * PRIVATE FUNCTIONS + **********************/ + +void lv_wayland_shm_initalize_context(shm_ctx_t * context) +{ + memset(context, 0, sizeof(*context)); + context->format = SHM_FORMAT_UNKNOWN; + smm_init(&sme_events); + smm_setctx(context); +} + +void lv_wayland_shm_set_interface(shm_ctx_t * context, struct wl_registry * registry, uint32_t name, + const char * interface, uint32_t version) +{ + LV_UNUSED(version); + LV_UNUSED(interface); + context->handler = wl_registry_bind(registry, name, &wl_shm_interface, 1); + wl_shm_add_listener(context->handler, &shm_listener, context); +} + +lv_result_t lv_wayland_shm_is_ready(shm_ctx_t * context) +{ + return (context->handler && context->format != SHM_FORMAT_UNKNOWN) ? LV_RESULT_OK : LV_RESULT_INVALID; +} + +/* TODO: Move all cursor functions to a lv_wl_cursor file*/ +struct wl_cursor_theme * lv_wayland_shm_load_cursor_theme(shm_ctx_t * context) +{ + return wl_cursor_theme_load(NULL, 32, context->handler); +} + +void lv_wayland_shm_deinit(shm_ctx_t * context) +{ + smm_deinit(); + wl_shm_destroy(context->handler); +} + +struct graphic_object * lv_wayland_shm_on_graphical_object_creation(shm_ctx_t * context, struct graphic_object * obj) +{ + LV_UNUSED(context); + obj->pending_buffer = NULL; + obj->buffer_group = smm_create(); + if(obj->buffer_group == NULL) { + LV_LOG_ERROR("Failed to create buffer group for graphic object"); + lv_free(obj); + return NULL; + } + SMM_TAG(obj->buffer_group, TAG_LOCAL, obj); + return obj; +} +void lv_wayland_shm_on_graphical_object_destruction(shm_ctx_t * context, struct graphic_object * obj) +{ + LV_UNUSED(context); + smm_destroy(obj->buffer_group); +} + +lv_result_t lv_wayland_shm_resize_window(shm_ctx_t * context, struct window * window, int32_t width, int32_t height) +{ + const uint8_t 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 */ + struct smm_buffer_t * body_buf1 = smm_acquire(window->body->buffer_group); + struct smm_buffer_t * 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 LV_RESULT_INVALID; + } + + /* Moves the buffers to the the unused list of the group */ + smm_release(body_buf1); + smm_release(body_buf2); + + LV_LOG_TRACE("resize window:%dx%d body:%dx%d frame: %d", window->width, window->height, window->body->width, + window->body->height, window->frame_counter); + + width = window->body->width; + height = window->body->height; + + if(window->lv_disp != NULL) { + /* Resize draw buffer */ + const uint32_t stride = lv_draw_buf_width_to_stride(width, lv_display_get_color_format(window->lv_disp)); + context->lv_draw_buf = lv_draw_buf_reshape(context->lv_draw_buf, lv_display_get_color_format(window->lv_disp), + width, height / LVGL_DRAW_BUFFER_DIV, stride); + } + + return LV_RESULT_OK; +} +lv_result_t lv_wayland_shm_create_draw_buffers(shm_ctx_t * context, struct window * window) +{ + + const uint32_t stride = lv_draw_buf_width_to_stride(window->width, lv_display_get_color_format(window->lv_disp)); + + context->lv_draw_buf = lv_draw_buf_create(window->width, window->height / LVGL_DRAW_BUFFER_DIV, + lv_display_get_color_format(window->lv_disp), stride); + return LV_RESULT_OK; +} + +lv_result_t lv_wayland_shm_set_draw_buffers(shm_ctx_t * context, lv_display_t * display) +{ + if(LV_WAYLAND_BUF_COUNT != 1) { + LV_LOG_ERROR("Wayland without dmabuf only supports 1 drawbuffer for now."); + return LV_RESULT_INVALID; + } + lv_display_set_draw_buffers(display, context->lv_draw_buf, NULL); + return LV_RESULT_OK; +} + +void lv_wayland_shm_delete_draw_buffers(shm_ctx_t * context, struct window * window) +{ + LV_UNUSED(window); + lv_draw_buf_destroy(context->lv_draw_buf); +} +void lv_wayland_shm_flush_partial_mode(lv_display_t * disp, const lv_area_t * area, unsigned char * color_p) +{ + struct window * window = lv_display_get_user_data(disp); + uint32_t format = window->wl_ctx->shm_ctx.format; + smm_buffer_t * buf = window->body->pending_buffer; + int32_t src_width = lv_area_get_width(area); + int32_t src_height = lv_area_get_height(area); + uint8_t bpp = lv_color_format_get_size(LV_COLOR_FORMAT_NATIVE); + lv_display_rotation_t rot = lv_display_get_rotation(disp); + int32_t w = lv_display_get_horizontal_resolution(disp); + int32_t h = lv_display_get_vertical_resolution(disp); + + /* TODO actually test what happens if the rotation is 90 or 270 or 180 ? */ + int32_t hres = (rot == LV_DISPLAY_ROTATION_0) ? w : h; + int32_t 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); + } + + void * 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(int32_t y = 0; y < src_height; ++y) { + if(format == WL_SHM_FORMAT_ARGB8888) { + for(int32_t x = 0; x < src_width; ++x) { + lv_color_premultiply((lv_color32_t *)color_p + x); + } + } + memcpy(((char *)buf_base) + ((((area->y1 + y) * hres) + area->x1) * bpp), 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); + + lv_wayland_cache_add_area(window, buf, area); + + if(lv_display_flush_is_last(disp)) { + /* Finally, attach buffer and commit to surface */ + struct wl_buffer * 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; + + struct wl_callback * cb = wl_surface_frame(window->body->surface); + wl_callback_add_listener(cb, lv_wayland_window_get_wl_surface_frame_listener(), window->body); + LV_LOG_TRACE("last flush frame: %d", window->frame_counter); + + window->flush_pending = true; + /* Return early here, the lv_display_flush_ready will get called in the frame_listener callback */ + return; + } + 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) + */ + lv_wayland_cache_clear(window); + SMM_TAG(buf, TAG_BUFFER_DAMAGE, NULL); + smm_release(buf); + window->body->pending_buffer = NULL; + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void shm_format(void * data, struct wl_shm * wl_shm, uint32_t format) +{ + shm_ctx_t * shm_ctx = (shm_ctx_t *)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) { + LV_LOG_TRACE("Found WL_SHM_FORMAT_ARGB8888"); + + /* Wayland compositors MUST support ARGB8888 */ + shm_ctx->format = format; + + } + else if(LV_COLOR_DEPTH == 32 && format == WL_SHM_FORMAT_XRGB8888 && shm_ctx->format != WL_SHM_FORMAT_ARGB8888) { + + LV_LOG_TRACE("Found WL_SHM_FORMAT_XRGB8888"); + /* Select XRGB only if the compositor doesn't support transprancy */ + shm_ctx->format = format; + + } + else if(LV_COLOR_DEPTH == 16 && format == WL_SHM_FORMAT_RGB565) { + + shm_ctx->format = format; + } +} + +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; + /* window is unused when LV_LOG level is not set to trace */ + LV_UNUSED(window); + LV_UNUSED(wl_buffer); + + 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 bool sme_new_pool(void * ctx, smm_pool_t * pool) +{ + struct wl_shm_pool * wl_pool; + shm_ctx_t * shm_ctx = ctx; + const struct smm_pool_properties * props = SMM_POOL_PROPERTIES(pool); + + LV_UNUSED(ctx); + + wl_pool = wl_shm_create_pool(shm_ctx->handler, 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]; + shm_ctx_t * shm_ctx = (shm_ctx_t *)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, shm_ctx->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; + } + + lv_wayland_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) { + lv_wayland_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); +} + +#endif /* LV_USE_WAYLAND */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_touch.c b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_touch.c new file mode 100644 index 000000000..ee18ec3dd --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_touch.c @@ -0,0 +1,275 @@ +/** + * @file lv_wl_touch.c + * + */ + +#include "lv_wl_touch.h" + +#if LV_USE_WAYLAND && LV_USE_GESTURE_RECOGNITION + +#include "lv_wayland_private.h" + +#include +#include + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void _lv_wayland_touch_read(lv_indev_t * drv, lv_indev_data_t * data); + +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); + +static void touch_handle_up(void * data, struct wl_touch * wl_touch, uint32_t serial, uint32_t time, int32_t id); + +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); + +static void touch_handle_frame(void * data, struct wl_touch * wl_touch); + +static void touch_handle_cancel(void * data, struct wl_touch * wl_touch); + +/********************** + * STATIC VARIABLES + **********************/ + +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, +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_indev_t * lv_wayland_touch_create(void) +{ + + lv_indev_t * indev = lv_indev_create(); + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, _lv_wayland_touch_read); + + return indev; +} + +lv_indev_t * lv_wayland_get_touchscreen(lv_display_t * display) +{ + struct window * window = lv_display_get_user_data(display); + if(!window) { + return NULL; + } + return window->lv_indev_touch; +} + +/********************** + * PRIVATE FUNCTIONS + **********************/ + +const struct wl_touch_listener * lv_wayland_touch_get_listener(void) +{ + return &touch_listener; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +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; + } + + /* Collect touches if there are any - send them to the gesture recognizer */ + lv_indev_gesture_recognizers_update(drv, &window->body->input.touches[0], window->body->input.touch_event_cnt); + + LV_LOG_TRACE("collected touch events: %d", window->body->input.touch_event_cnt); + + window->body->input.touch_event_cnt = 0; + + /* Set the gesture information, before returning to LVGL */ + lv_indev_gesture_recognizers_set_data(drv, data); +} + +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 lv_wayland_context * app = data; + uint8_t i; + + LV_UNUSED(id); + LV_UNUSED(time); + LV_UNUSED(serial); + LV_UNUSED(wl_touch); + + if(!surface) { + app->touch_obj = NULL; + return; + } + + /* Create the touch down event */ + app->touch_obj = wl_surface_get_user_data(surface); + i = app->touch_obj->input.touch_event_cnt; + + app->touch_obj->input.touches[i].point.x = wl_fixed_to_int(x_w); + app->touch_obj->input.touches[i].point.y = wl_fixed_to_int(y_w); + app->touch_obj->input.touches[i].id = id; + app->touch_obj->input.touches[i].timestamp = time; + app->touch_obj->input.touches[i].state = LV_INDEV_STATE_PRESSED; + app->touch_obj->input.touch_event_cnt++; + +#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 lv_wayland_context * app = data; + uint8_t i; + + LV_UNUSED(serial); + LV_UNUSED(time); + LV_UNUSED(id); + LV_UNUSED(wl_touch); + +#if LV_USE_GESTURE_RECOGNITION + /* Create a released event */ + i = app->touch_obj->input.touch_event_cnt; + + app->touch_obj->input.touches[i].point.x = 0; + app->touch_obj->input.touches[i].point.y = 0; + app->touch_obj->input.touches[i].id = id; + app->touch_obj->input.touches[i].timestamp = time; + app->touch_obj->input.touches[i].state = LV_INDEV_STATE_RELEASED; + + app->touch_obj->input.touch_event_cnt++; +#endif + +#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 */ +} + +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 lv_wayland_context * app = data; + lv_indev_touch_data_t * touch; + lv_indev_touch_data_t * cur; + uint8_t i; + + LV_UNUSED(time); + LV_UNUSED(id); + LV_UNUSED(wl_touch); + + /* Update the contact point of the corresponding id with the latest coordinate */ + touch = &app->touch_obj->input.touches[0]; + cur = NULL; + + for(i = 0; i < app->touch_obj->input.touch_event_cnt; i++) { + if(touch->id == id) { + cur = touch; + } + touch++; + } + + if(cur == NULL) { + + i = app->touch_obj->input.touch_event_cnt; + app->touch_obj->input.touches[i].point.x = wl_fixed_to_int(x_w); + app->touch_obj->input.touches[i].point.y = wl_fixed_to_int(y_w); + app->touch_obj->input.touches[i].id = id; + app->touch_obj->input.touches[i].timestamp = time; + app->touch_obj->input.touches[i].state = LV_INDEV_STATE_PRESSED; + app->touch_obj->input.touch_event_cnt++; + + } + else { + + cur->point.x = wl_fixed_to_int(x_w); + cur->point.y = wl_fixed_to_int(y_w); + cur->id = id; + cur->timestamp = time; + } +} + +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); +} + +#endif /* LV_USE_WAYLAND && LV_USE_GESTURE_RECOGNITION */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_touch.h b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_touch.h new file mode 100644 index 000000000..eab444346 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_touch.h @@ -0,0 +1,54 @@ + + +/** + * @file lv_wl_touch.h + * + */ + +#ifndef LV_WL_TOUCH_H +#define LV_WL_TOUCH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../indev/lv_indev.h" +#include "../../indev/lv_indev_gesture.h" +#if LV_USE_WAYLAND && LV_USE_GESTURE_RECOGNITION + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_indev_t * lv_wayland_touch_create(void); + +/** + * Get touchscreen input device for given LVGL display + * @param display LVGL display + * @return input device connected to touchscreen, or NULL on error + */ +lv_indev_t * lv_wayland_get_touchscreen(lv_display_t * display); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_WAYLAND */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_WL_TOUCH_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_window.c b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_window.c new file mode 100644 index 000000000..1e9df6406 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_window.c @@ -0,0 +1,489 @@ +/** + * @file lv_wl_window.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_wl_window.h" + +#if LV_USE_WAYLAND + +#include +#include "lv_wayland_private.h" +#include "lv_wayland_private.h" +#include "lv_wl_pointer.h" +#include "lv_wl_pointer_axis.h" +#include "lv_wl_touch.h" +#include "lv_wl_keyboard.h" + +#include "../../core/lv_refr.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static struct graphic_object * create_graphic_obj(struct window * window, enum object_type type, + struct graphic_object * parent); +static void destroy_graphic_obj(struct window * window, struct graphic_object * obj); + +/* 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 lv_wayland_context * app, int width, int height, const char * title); + +/** + * 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 lv_window_graphic_obj_flush_done(void * data, struct wl_callback * cb, uint32_t time); + +/********************** + * STATIC VARIABLES + **********************/ + +static const struct wl_callback_listener wl_surface_frame_listener = { + .done = lv_window_graphic_obj_flush_done, +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +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; + + lv_wayland_init(); + + window_width = hor_res; + window_height = ver_res; + +#if LV_WAYLAND_WINDOW_DECORATIONS + if(!lv_wl_ctx.opt_disable_decorations) { + window_width = hor_res + (2 * BORDER_SIZE); + window_height = ver_res + (TITLE_BAR_HEIGHT + (2 * BORDER_SIZE)); + } +#endif + + window = create_window(&lv_wl_ctx, 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; + } + +#if LV_WAYLAND_USE_DMABUF + if(lv_wayland_dmabuf_create_draw_buffers(&lv_wl_ctx.dmabuf_ctx, window) != LV_RESULT_OK) { + LV_LOG_ERROR("Failed to create draw buffers"); + return NULL; + } +#else + if(lv_wayland_shm_create_draw_buffers(&lv_wl_ctx.shm_ctx, window) != LV_RESULT_OK) { + LV_LOG_ERROR("Failed to create window buffers"); + return NULL; + } +#endif + + lv_display_set_user_data(window->lv_disp, window); + + lv_display_set_render_mode(window->lv_disp, LV_WAYLAND_RENDER_MODE); + lv_display_set_flush_wait_cb(window->lv_disp, lv_wayland_wait_flush_cb); + +#if LV_WAYLAND_USE_DMABUF + lv_wayland_dmabuf_set_draw_buffers(&lv_wl_ctx.dmabuf_ctx, window->lv_disp); + lv_display_set_flush_cb(window->lv_disp, lv_wayland_dmabuf_flush_full_mode); +#else + lv_wayland_shm_set_draw_buffers(&lv_wl_ctx.shm_ctx, window->lv_disp); + lv_display_set_flush_cb(window->lv_disp, lv_wayland_shm_flush_partial_mode); +#endif + + /* Register input */ + window->lv_indev_pointer = lv_wayland_pointer_create(); + + 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_wayland_pointer_axis_create(); + lv_indev_set_display(window->lv_indev_pointeraxis, window->lv_disp); + + if(!window->lv_indev_pointeraxis) { + LV_LOG_ERROR("failed to register pointeraxis indev"); + } + +#if LV_USE_GESTURE_RECOGNITION + + window->lv_indev_touch = lv_wayland_touch_create(); + lv_indev_set_display(window->lv_indev_touch, window->lv_disp); + + if(!window->lv_indev_touch) { + LV_LOG_ERROR("failed to register touch indev"); + } + +#endif /* END LV_USE_GESTURE_RECOGNITION */ + + window->lv_indev_keyboard = lv_wayland_keyboard_create(); + 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; +} + +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; + lv_wayland_deinit(); +} + +bool lv_wayland_window_is_open(lv_display_t * disp) +{ + struct window * window; + bool open = false; + + if(disp == NULL) { + LV_LL_READ(&lv_wl_ctx.window_ll, window) { + if(!window->closed) { + open = true; + break; + } + } + } + else { + window = lv_display_get_user_data(disp); + open = (!window->closed); + } + + return open; +} + +void lv_wayland_window_set_maximized(lv_display_t * disp, bool maximized) +{ + struct window * window = lv_display_get_user_data(disp); + lv_result_t err = LV_RESULT_INVALID; + if(!window || window->closed) { + return; + } + + if(window->maximized != maximized) { +#if LV_WAYLAND_WL_SHELL + err = lv_wayland_wl_shell_set_maximized(window, maximized); +#elif LV_WAYLAND_XDG_SHELL + err = lv_wayland_xdg_shell_set_maximized(window, maximized); +#endif + } + + if(err == LV_RESULT_INVALID) { + LV_LOG_WARN("Failed to maximize wayland window"); + return; + } + + window->maximized = maximized; + window->flush_pending = true; +} + +void lv_wayland_window_set_fullscreen(lv_display_t * disp, bool fullscreen) +{ + struct window * window = lv_display_get_user_data(disp); + lv_result_t err = LV_RESULT_INVALID; + if(!window || window->closed) { + return; + } + + if(window->fullscreen == fullscreen) { + return; + } +#if LV_WAYLAND_WL_SHELL + err = lv_wayland_wl_shell_set_fullscreen(window, fullscreen); +#elif LV_WAYLAND_XDG_SHELL + err = lv_wayland_xdg_shell_set_fullscreen(window, fullscreen); +#endif + + if(err == LV_RESULT_INVALID) { + LV_LOG_WARN("Failed to set wayland window to fullscreen"); + return; + } + + window->fullscreen = fullscreen; + window->flush_pending = true; +} + +/********************** + * PRIVATE FUNCTIONS + **********************/ + +void lv_wayland_window_draw(struct window * window, uint32_t width, uint32_t height) +{ + +#if LV_WAYLAND_WINDOW_DECORATIONS + if(lv_wl_ctx.opt_disable_decorations == false) { + for(size_t i = 0; i < NUM_DECORATIONS; i++) { + window->decoration[i] = create_graphic_obj(window, (FIRST_DECORATION + i), window->body); + if(!window->decoration[i]) { + LV_LOG_ERROR("Failed to create decoration %zu", i); + } + } + } +#endif + + LV_LOG_TRACE("Resizing to %d %d", width, height); + /* First resize */ + if(lv_wayland_window_resize(window, width, height) != LV_RESULT_OK) { + LV_LOG_ERROR("Failed to resize window"); +#if LV_WAYLAND_XDG_SHELL + lv_wayland_xdg_shell_destroy_window_toplevel(window); +#endif + } + + lv_refr_now(window->lv_disp); +} + +lv_result_t lv_wayland_window_resize(struct window * window, int width, int height) +{ + + +#if LV_WAYLAND_WINDOW_DECORATIONS + if(!window->wl_ctx->opt_disable_decorations && !window->fullscreen) { + width -= (2 * BORDER_SIZE); + height -= (TITLE_BAR_HEIGHT + (2 * BORDER_SIZE)); + } +#endif + +#if LV_WAYLAND_USE_DMABUF + { + lv_result_t err = lv_wayland_dmabuf_resize_window(&window->wl_ctx->dmabuf_ctx, window); + if(err != LV_RESULT_OK) { + return err; + } + } +#else + { + lv_result_t err = lv_wayland_shm_resize_window(&window->wl_ctx->shm_ctx, window, width, height); + if(err != LV_RESULT_OK) { + return err; + } + } +#endif + +#if LV_WAYLAND_WINDOW_DECORATIONS + if(!window->wl_ctx->opt_disable_decorations && !window->fullscreen) { + lv_wayland_window_decoration_create_all(window); + } + else if(!window->wl_ctx->opt_disable_decorations) { + /* Entering fullscreen, detach decorations to prevent xdg_wm_base error 4 */ + /* requested geometry larger than the configured fullscreen state */ + lv_wayland_window_decoration_detach_all(window); + } +#endif + + if(window->lv_disp) { + 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)); + } + window->width = width; + window->height = height; + return LV_RESULT_OK; +} + +void lv_wayland_window_destroy(struct window * window) +{ + if(!window) { + return; + } + +#if LV_WAYLAND_WL_SHELL + lv_wayland_wl_shell_destroy_window(window); +#elif LV_WAYLAND_XDG_SHELL + lv_wayland_xdg_shell_destroy_window_toplevel(window); + lv_wayland_xdg_shell_destroy_window_surface(window); +#endif + +#if LV_WAYLAND_WINDOW_DECORATIONS + for(size_t i = 0; i < NUM_DECORATIONS; i++) { + if(window->decoration[i]) { + destroy_graphic_obj(window, window->decoration[i]); + window->decoration[i] = NULL; + } + } +#endif + + destroy_graphic_obj(window, window->body); +} + +const struct wl_callback_listener * lv_wayland_window_get_wl_surface_frame_listener(void) +{ + return &wl_surface_frame_listener; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static struct window * create_window(struct lv_wayland_context * 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->wl_ctx = app; + + // Create wayland buffer and surface + window->body = create_graphic_obj(window, OBJECT_WINDOW, NULL); + window->width = width; + window->height = height; + + if(!window->body) { + LV_LOG_ERROR("cannot create window body"); + goto err_free_window; + } + +#if LV_WAYLAND_WL_SHELL + if(lv_wayland_wl_shell_create_window(app, window, title) != LV_RESULT_OK) { + LV_LOG_ERROR("Failed to create wl shell window"); + goto err_destroy_surface; + } +#elif LV_WAYLAND_XDG_SHELL + if(lv_wayland_xdg_shell_create_window(app, window, title) != LV_RESULT_OK) { + goto err_destroy_surface; + } +#endif + + return window; + +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 struct graphic_object * create_graphic_obj(struct window * window, enum object_type type, + struct graphic_object * parent) +{ + + /* For now creating a graphical object is similar enough for both shm and dmabuf + * so the heavylifting is done in this function directly but we still + * call the shm and dmabuf specific functions at the end to make sure they can add additional + * attributes if needed + */ + struct graphic_object * obj = NULL; + + LV_UNUSED(parent); + + obj = lv_malloc(sizeof(*obj)); + LV_ASSERT_MALLOC(obj); + if(!obj) { + LV_LOG_ERROR("Failed to create graphic object"); + return NULL; + } + + lv_memset(obj, 0, sizeof(*obj)); + + obj->surface = wl_compositor_create_surface(window->wl_ctx->compositor); + if(!obj->surface) { + LV_LOG_ERROR("Failed to create surface for graphic object"); + lv_free(obj); + return NULL; + } + wl_surface_set_user_data(obj->surface, obj); + + obj->window = window; + obj->type = type; + +#if LV_WAYLAND_USE_DMABUF + return lv_wayland_dmabuf_on_graphical_object_creation(&window->wl_ctx->dmabuf_ctx, obj); +#else + return lv_wayland_shm_on_graphical_object_creation(&window->wl_ctx->shm_ctx, obj); +#endif +} + +static void destroy_graphic_obj(struct window * window, struct graphic_object * obj) +{ + if(obj->subsurface) { + wl_subsurface_destroy(obj->subsurface); + } + + wl_surface_destroy(obj->surface); + +#if LV_WAYLAND_USE_DMABUF + lv_wayland_dmabuf_on_graphical_object_destruction(&window->wl_ctx->dmabuf_ctx, obj); +#else + lv_wayland_shm_on_graphical_object_destruction(&window->wl_ctx->shm_ctx, obj); +#endif + lv_free(obj); +} + +static void lv_window_graphic_obj_flush_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); + + lv_display_flush_ready(window->lv_disp); +} + +#endif /* LV_USE_WAYLAND */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_window.h b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_window.h new file mode 100644 index 000000000..733398565 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_window.h @@ -0,0 +1,84 @@ + +/** + * @file lv_wl_display.h + * + */ + +#ifndef LV_WL_WINDOW_H +#define LV_WL_WINDOW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../display/lv_display.h" + +#if LV_USE_WAYLAND + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef bool (*lv_wayland_display_close_f_t)(lv_display_t * disp); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * 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); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_WAYLAND */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_WL_WINDOW_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_window_decorations.c b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_window_decorations.c new file mode 100644 index 000000000..314043643 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_window_decorations.c @@ -0,0 +1,361 @@ +/** + * @file lv_wl_window_decorations.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_wayland.h" + +#if LV_WAYLAND_WINDOW_DECORATIONS + +#include "lv_wayland_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/* + * 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); +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 VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +bool lv_wayland_window_decoration_attach(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->wl_ctx->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; +} + +uint32_t lv_wayland_window_decoration_create_all(struct window * window) +{ + uint32_t created = 0; + for(size_t i = 0; i < NUM_DECORATIONS; i++) { + if(lv_wayland_window_decoration_create(window, window->decoration[i], window->body->width, + window->body->height)) { + created++; + continue; + } + LV_LOG_ERROR("failed to create decoration %zu", i); + } + return created; +} + +void lv_wayland_window_decoration_detach_all(struct window * window) +{ + for(int i = 0; i < NUM_DECORATIONS; i++) { + lv_wayland_window_decoration_detach(window, window->decoration[i]); + } +} + +bool lv_wayland_window_decoration_create(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 lv_wayland_window_decoration_attach(window, decoration, buf, window->body); +} + +void lv_wayland_window_decoration_detach(struct window * window, struct graphic_object * decoration) +{ + + LV_UNUSED(window); + + if(decoration->subsurface) { + wl_subsurface_destroy(decoration->subsurface); + decoration->subsurface = NULL; + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void color_fill(void * pixels, lv_color_t color, uint32_t width, uint32_t height) +{ + + switch(lv_wl_ctx.shm_ctx.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); + } +} + +#endif /* LV_WAYLAND_WINDOW_DECORATIONS */ diff --git a/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_xdg_shell.c b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_xdg_shell.c new file mode 100644 index 000000000..43848544e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/drivers/wayland/lv_wl_xdg_shell.c @@ -0,0 +1,467 @@ +/** + * @file lv_wl_xdg_shell.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_wayland.h" + +#if LV_USE_WAYLAND +/* + * LV_WAYLAND_XDG_SHELL is automatically defined if LV_WAYLAND_WL_SHELL is not set + * inside lv_wayland_private.h so we need include this header file before checking + * for LV_WAYLAND_XDG_SHELL + */ +#include "lv_wayland_private.h" + +#if LV_WAYLAND_XDG_SHELL + +#include +#include "wayland_xdg_shell.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void xdg_surface_handle_configure(void * data, struct xdg_surface * xdg_surface, uint32_t serial); +static void xdg_toplevel_handle_configure(void * data, struct xdg_toplevel * xdg_toplevel, int32_t width, + int32_t height, struct wl_array * states); +static void xdg_toplevel_handle_close(void * data, struct xdg_toplevel * xdg_toplevel); +static void xdg_wm_base_ping(void * data, struct xdg_wm_base * xdg_wm_base, uint32_t serial); + +/********************** + * STATIC VARIABLES + **********************/ + +static const struct xdg_surface_listener xdg_surface_listener = { + .configure = xdg_surface_handle_configure, +}; + +static const struct xdg_toplevel_listener xdg_toplevel_listener = { + .configure = xdg_toplevel_handle_configure, + .close = xdg_toplevel_handle_close, +}; + +static const struct xdg_wm_base_listener xdg_wm_base_listener = {.ping = xdg_wm_base_ping}; +static bool is_window_configured = false; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * PRIVATE FUNCTIONS + **********************/ + +/********************** + * Shell + **********************/ + +void lv_wayland_xdg_shell_deinit(void) +{ + + if(lv_wl_ctx.xdg_wm) { + xdg_wm_base_destroy(lv_wl_ctx.xdg_wm); + } +} + +/********************** + * Listeners + **********************/ + +const struct xdg_wm_base_listener * lv_wayland_xdg_shell_get_wm_base_listener(void) +{ + return &xdg_wm_base_listener; +} + +const struct xdg_surface_listener * lv_wayland_xdg_shell_get_surface_listener(void) +{ + return &xdg_surface_listener; +} + +const struct xdg_toplevel_listener * lv_wayland_xdg_shell_get_toplevel_listener(void) +{ + return &xdg_toplevel_listener; +} + +/********************** + * Shell Window + **********************/ + +lv_result_t lv_wayland_xdg_shell_set_fullscreen(struct window * window, bool fullscreen) +{ + + if(!window->xdg_toplevel) { + return LV_RESULT_INVALID; + } + if(fullscreen) { + xdg_toplevel_set_fullscreen(window->xdg_toplevel, NULL); + } + else { + xdg_toplevel_unset_fullscreen(window->xdg_toplevel); + } + return LV_RESULT_OK; +} + +lv_result_t lv_wayland_xdg_shell_set_maximized(struct window * window, bool maximized) +{ + if(!window->xdg_toplevel) { + return LV_RESULT_INVALID; + } + + if(maximized) { + xdg_toplevel_set_maximized(window->xdg_toplevel); + } + else { + xdg_toplevel_unset_maximized(window->xdg_toplevel); + } + + return LV_RESULT_OK; +} + +lv_result_t lv_wayland_xdg_shell_set_minimized(struct window * window) +{ + if(!window->xdg_toplevel) { + return LV_RESULT_INVALID; + } + + xdg_toplevel_set_minimized(window->xdg_toplevel); + return LV_RESULT_OK; +} + +lv_result_t lv_wayland_xdg_shell_create_window(struct lv_wayland_context * app, struct window * window, + const char * title) +{ + if(!app->xdg_wm) { + return LV_RESULT_INVALID; + } + + 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"); + return LV_RESULT_INVALID; + } + + xdg_surface_add_listener(window->xdg_surface, lv_wayland_xdg_shell_get_surface_listener(), window); + + window->xdg_toplevel = xdg_surface_get_toplevel(window->xdg_surface); + if(!window->xdg_toplevel) { + xdg_surface_destroy(window->xdg_surface); + LV_LOG_ERROR("cannot get XDG toplevel surface"); + return LV_RESULT_INVALID; + } + + xdg_toplevel_add_listener(window->xdg_toplevel, lv_wayland_xdg_shell_get_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 + is_window_configured = false; + wl_surface_commit(window->body->surface); + wl_display_roundtrip(lv_wl_ctx.display); + LV_ASSERT_MSG(is_window_configured, "Failed to receive the xdg_surface configuration event"); + return LV_RESULT_OK; +} + +lv_result_t lv_wayland_xdg_shell_destroy_window_surface(struct window * window) +{ + + if(!window->xdg_surface) { + return LV_RESULT_INVALID; + } + xdg_surface_destroy(window->xdg_surface); + return LV_RESULT_OK; +} + +lv_result_t lv_wayland_xdg_shell_destroy_window_toplevel(struct window * window) +{ + + if(!window->xdg_toplevel) { + return LV_RESULT_INVALID; + } + xdg_toplevel_destroy(window->xdg_toplevel); + return LV_RESULT_OK; +} + +/********************** + * Shell Input + **********************/ + +void lv_wayland_xdg_shell_handle_pointer_event(struct lv_wayland_context * app, uint32_t serial, uint32_t button, + uint32_t state) +{ + struct window * window = app->pointer_obj->window; + int pos_x = (int)app->pointer_obj->input.pointer.x; + int pos_y = (int)app->pointer_obj->input.pointer.y; + + switch(app->pointer_obj->type) { + case OBJECT_TITLEBAR: + if((button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_PRESSED)) { + if(window->xdg_toplevel) { + xdg_toplevel_move(window->xdg_toplevel, app->wl_seat, serial); + window->flush_pending = true; + } + } + break; + case OBJECT_BUTTON_MAXIMIZE: + if((button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_RELEASED)) { + if(lv_wayland_xdg_shell_set_maximized(window, !window->maximized) == LV_RESULT_OK) { + window->maximized = !window->maximized; + window->flush_pending = true; + } + } + break; + case OBJECT_BUTTON_MINIMIZE: + if((button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_RELEASED)) { + if(lv_wayland_xdg_shell_set_minimized(window) == LV_RESULT_OK) { + 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->wl_ctx->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->wl_ctx->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->wl_ctx->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->wl_ctx->wl_seat, serial, edge); + window->flush_pending = true; + } + } + break; + case OBJECT_BUTTON_CLOSE: + case OBJECT_WINDOW: + /* These events are handled in the main pointer callback */ + break; + } +} + +const char * lv_wayland_xdg_shell_get_cursor_name(const struct lv_wayland_context * app) +{ + + if(!app->pointer_obj->window->xdg_toplevel || app->opt_disable_decorations) { + return LV_WAYLAND_DEFAULT_CURSOR_NAME; + } + int pos_x = (int)app->pointer_obj->input.pointer.x; + int pos_y = (int)app->pointer_obj->input.pointer.y; + + 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)) { + return "top_left_corner"; + } + else if(pos_x >= (window->width + BORDER_SIZE - (BORDER_SIZE * 5))) { + return "top_right_corner"; + } + else { + return "top_side"; + } + break; + case OBJECT_BORDER_BOTTOM: + if(window->maximized) { + // do nothing + } + else if(pos_x < (BORDER_SIZE * 5)) { + return "bottom_left_corner"; + } + else if(pos_x >= (window->width + BORDER_SIZE - (BORDER_SIZE * 5))) { + return "bottom_right_corner"; + } + else { + return "bottom_side"; + } + break; + case OBJECT_BORDER_LEFT: + if(window->maximized) { + // do nothing + } + else if(pos_y < (BORDER_SIZE * 5)) { + return "top_left_corner"; + } + else if(pos_y >= (window->height + BORDER_SIZE - (BORDER_SIZE * 5))) { + return "bottom_left_corner"; + } + else { + return "left_side"; + } + break; + case OBJECT_BORDER_RIGHT: + if(window->maximized) { + // do nothing + } + else if(pos_y < (BORDER_SIZE * 5)) { + return "top_right_corner"; + } + else if(pos_y >= (window->height + BORDER_SIZE - (BORDER_SIZE * 5))) { + return "bottom_right_corner"; + } + else { + return "right_side"; + } + break; + default: + break; + } + + return LV_WAYLAND_DEFAULT_CURSOR_NAME; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +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(!is_window_configured) { + /* This branch is executed at launch */ + if(!window->resize_pending) { + /* Use the size passed to the create_window function */ + lv_wayland_window_draw(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 */ + lv_wayland_window_draw(window, window->resize_width, window->resize_height); + window->width = window->resize_width; + window->height = window->resize_height; + window->resize_pending = false; + } + } + is_window_configured = true; +} + +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_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_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; +} + +#endif /* LV_WAYLAND_XDG_SHELL */ +#endif /* LV_USE_WAYLAND */ 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 7bf20385a..a79b7852f 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 @@ -1,4 +1,4 @@ -/** +/** * @file lv_windows_context.c * */ @@ -16,6 +16,7 @@ #include "lv_windows_display.h" #include "lv_windows_input_private.h" +#include "../../osal/lv_os.h" /********************* * DEFINES 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 c4fc9417a..d080ca565 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 * */ @@ -41,31 +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 { +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; @@ -86,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 d3b781646..3b7ae1ca8 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 * */ 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 7daabe3ef..bb98b51f9 100644 --- a/lib/libesp32_lvgl/lvgl/src/drivers/x11/lv_x11.h +++ b/lib/libesp32_lvgl/lvgl/src/drivers/x11/lv_x11.h @@ -16,6 +16,7 @@ extern "C" { #include "../../display/lv_display.h" #include "../../indev/lv_indev.h" +#include "../../draw/lv_image_dsc.h" #if LV_USE_X11 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 1a2b83cad..09da0626a 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 @@ -209,6 +209,7 @@ static void x11_disp_delete_evt_cb(lv_event_t * e) XUnmapWindow(xd->hdr.display, xd->window); XDestroyWindow(xd->hdr.display, xd->window); XFlush(xd->hdr.display); + XCloseDisplay(xd->hdr.display); lv_free(xd); #if LV_X11_DIRECT_EXIT 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 4746026f5..a39e2bc64 100644 --- a/lib/libesp32_lvgl/lvgl/src/font/lv_binfont_loader.c +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_binfont_loader.c @@ -69,10 +69,26 @@ int32_t load_kern(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t f static int read_bits_signed(bit_iterator_t * it, int n_bits, lv_fs_res_t * res); static unsigned int read_bits(bit_iterator_t * it, int n_bits, lv_fs_res_t * res); +static lv_font_t * binfont_font_create_cb(const lv_font_info_t * info, const void * src); +static void binfont_font_delete_cb(lv_font_t * font); +static void * binfont_font_dup_src_cb(const void * src); +static void binfont_font_free_src_cb(void * src); + /********************** * MACROS **********************/ +/********************** + * GLOBAL VARIABLES + **********************/ + +const lv_font_class_t lv_binfont_font_class = { + .create_cb = binfont_font_create_cb, + .delete_cb = binfont_font_delete_cb, + .dup_src_cb = binfont_font_dup_src_cb, + .free_src_cb = binfont_font_free_src_cb, +}; + /********************** * GLOBAL FUNCTIONS **********************/ @@ -656,3 +672,53 @@ int32_t load_kern(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t f return kern_length; } + +static lv_font_t * binfont_font_create_cb(const lv_font_info_t * info, const void * src) +{ + const lv_binfont_font_src_t * font_src = src; + + if(info->size == font_src->font_size) { + if(font_src->path) { + return lv_binfont_create(font_src->path); + } +#if LV_USE_FS_MEMFS + return lv_binfont_create_from_buffer((void *)font_src->buffer, font_src->buffer_size); +#else + LV_LOG_WARN("LV_USE_FS_MEMFS not enabled"); + return NULL; +#endif + } + + return NULL; +} + +static void binfont_font_delete_cb(lv_font_t * font) +{ + lv_binfont_destroy(font); +} + +static void * binfont_font_dup_src_cb(const void * src) +{ + const lv_binfont_font_src_t * font_src = src; + + lv_binfont_font_src_t * new_src = lv_malloc_zeroed(sizeof(lv_binfont_font_src_t)); + LV_ASSERT_MALLOC(new_src); + *new_src = *font_src; + + if(font_src->path) { + new_src->path = lv_strdup(font_src->path); + } + + return new_src; +} + +static void binfont_font_free_src_cb(void * src) +{ + lv_binfont_font_src_t * font_src = src; + if(font_src->path) { + lv_free((char *)font_src->path); + font_src->path = NULL; + } + + lv_free(font_src); +} 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 25e7b8374..a8b447dd2 100644 --- a/lib/libesp32_lvgl/lvgl/src/font/lv_binfont_loader.h +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_binfont_loader.h @@ -22,6 +22,16 @@ extern "C" { * TYPEDEFS **********************/ + +typedef struct { + uint32_t font_size; /**< Size of the font in pixels*/ + const char * path; /**< Path to font file*/ + const void * buffer; /**< Address of the font file in the memory*/ + uint32_t buffer_size; /**< Size of the font file buffer*/ +} lv_binfont_font_src_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_font_class_t lv_binfont_font_class; + /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/font/lv_font.c b/lib/libesp32_lvgl/lvgl/src/font/lv_font.c index 35ae352e3..26199fc73 100644 --- a/lib/libesp32_lvgl/lvgl/src/font/lv_font.c +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_font.c @@ -30,6 +30,10 @@ * STATIC VARIABLES **********************/ +/********************** + * GLOBAL VARIABLES + **********************/ + /********************** * GLOBAL PROTOTYPES **********************/ @@ -46,11 +50,40 @@ const void * lv_font_get_glyph_bitmap(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t { const lv_font_t * font_p = g_dsc->resolved_font; LV_ASSERT_NULL(font_p); - return font_p->get_glyph_bitmap(g_dsc, draw_buf); + + const uint8_t save_req = g_dsc->req_raw_bitmap; + g_dsc->req_raw_bitmap = 0; + const void * bitmap = font_p->get_glyph_bitmap(g_dsc, draw_buf); + g_dsc->req_raw_bitmap = save_req; + + return bitmap; +} + +const void * lv_font_get_glyph_static_bitmap(lv_font_glyph_dsc_t * g_dsc) +{ + const lv_font_t * font_p = g_dsc->resolved_font; + LV_ASSERT_NULL(font_p); + + if(font_p->static_bitmap == 0) { + LV_LOG_WARN("Requesting static bitmap of a non-static bitmap of %p font", (void *)font_p); + return NULL; + } + + const uint8_t save_req = g_dsc->req_raw_bitmap; + g_dsc->req_raw_bitmap = 1; + const void * bitmap = font_p->get_glyph_bitmap(g_dsc, NULL); + g_dsc->req_raw_bitmap = save_req; + + return bitmap; } void lv_font_glyph_release_draw_data(lv_font_glyph_dsc_t * g_dsc) { + LV_ASSERT_NULL(g_dsc); + if(!g_dsc->entry) { + return; + } + const lv_font_t * font = g_dsc->resolved_font; if(font != NULL && font->release_glyph) { @@ -71,7 +104,7 @@ bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_o const lv_font_t * f = font_p; - dsc_out->resolved_font = NULL; + lv_memzero(dsc_out, sizeof(lv_font_glyph_dsc_t)); while(f) { bool found = f->get_glyph_dsc(f, dsc_out, letter, f->kerning == LV_FONT_KERNING_NONE ? 0 : letter_next); @@ -106,6 +139,7 @@ bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_o dsc_out->adv_w = 0; #endif + dsc_out->stride = 0; dsc_out->resolved_font = NULL; dsc_out->box_h = font_p->line_height; dsc_out->ofs_x = 0; @@ -113,6 +147,7 @@ bool lv_font_get_glyph_dsc(const lv_font_t * font_p, lv_font_glyph_dsc_t * dsc_o dsc_out->format = LV_FONT_GLYPH_FORMAT_A1; dsc_out->is_placeholder = true; + return false; } @@ -139,11 +174,31 @@ int32_t lv_font_get_line_height(const lv_font_t * font) return font->line_height; } -const lv_font_t * lv_font_default(void) + +const lv_font_t * lv_font_get_default(void) { return LV_FONT_DEFAULT; } +bool lv_font_info_is_equal(const lv_font_info_t * ft_info_1, const lv_font_info_t * ft_info_2) +{ + LV_ASSERT_NULL(ft_info_1); + LV_ASSERT_NULL(ft_info_2); + + bool is_equal = (ft_info_1->size == ft_info_2->size + && ft_info_1->style == ft_info_2->style + && ft_info_1->render_mode == ft_info_2->render_mode + && ft_info_1->kerning == ft_info_2->kerning + && lv_strcmp(ft_info_1->name, ft_info_2->name) == 0); + + return is_equal; +} + +bool lv_font_has_static_bitmap(const lv_font_t * font) +{ + return font->static_bitmap; +} + /********************** * 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 2f172b9f8..180891832 100644 --- a/lib/libesp32_lvgl/lvgl/src/font/lv_font.h +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_font.h @@ -19,7 +19,6 @@ extern "C" { #include "lv_symbol_def.h" #include "../draw/lv_draw_buf.h" #include "../misc/lv_area.h" -#include "../misc/cache/lv_cache.h" /********************* * DEFINES @@ -37,17 +36,18 @@ extern "C" { typedef enum { LV_FONT_GLYPH_FORMAT_NONE = 0, /**< Maybe not visible*/ - /**< Legacy simple formats*/ + /**< Legacy simple formats with no byte padding at end of the lines*/ LV_FONT_GLYPH_FORMAT_A1 = 0x01, /**< 1 bit per pixel*/ LV_FONT_GLYPH_FORMAT_A2 = 0x02, /**< 2 bit per pixel*/ + LV_FONT_GLYPH_FORMAT_A3 = 0x03, /**< 3 bit per pixel*/ LV_FONT_GLYPH_FORMAT_A4 = 0x04, /**< 4 bit per pixel*/ LV_FONT_GLYPH_FORMAT_A8 = 0x08, /**< 8 bit per pixel*/ - LV_FONT_GLYPH_FORMAT_IMAGE = 0x09, /**< Image format*/ + LV_FONT_GLYPH_FORMAT_IMAGE = 0x19, /**< Image format*/ /**< Advanced formats*/ - LV_FONT_GLYPH_FORMAT_VECTOR = 0x0A, /**< Vectorial format*/ - LV_FONT_GLYPH_FORMAT_SVG = 0x0B, /**< SVG format*/ + LV_FONT_GLYPH_FORMAT_VECTOR = 0x1A, /**< Vectorial format*/ + LV_FONT_GLYPH_FORMAT_SVG = 0x1B, /**< SVG format*/ LV_FONT_GLYPH_FORMAT_CUSTOM = 0xFF, /**< Custom format*/ } lv_font_glyph_format_t; @@ -60,9 +60,16 @@ typedef struct { 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*/ + uint16_t stride;/**< Bytes in each line. If 0 than there is no padding at the end of the line. */ 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*/ + /** 0: Get bitmap should return an A8 or ARGB8888 image. + * 1: return the bitmap as it is (Maybe A1/2/4 or any proprietary formats). */ + uint8_t req_raw_bitmap: 1; + + int32_t outline_stroke_width; /**< used with freetype vector fonts - width of the letter outline */ + union { uint32_t index; /**< Unicode code point*/ const void * src; /**< Pointer to the source data used by image fonts*/ @@ -85,7 +92,7 @@ typedef enum { } 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); @@ -100,6 +107,7 @@ struct lv_font_t { 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`*/ + uint8_t static_bitmap : 1; /**< The font will be used as static bitmap */ int8_t underline_position; /**< Distance between the top of the underline and base line (< 0 means below the base line)*/ int8_t underline_thickness; /**< Thickness of the underline*/ @@ -109,19 +117,50 @@ struct lv_font_t { void * user_data; /**< Custom user data for font.*/ }; +struct _lv_font_class_t { + lv_font_t * (*create_cb)(const lv_font_info_t * info, const void * src); /**< Font creation callback function*/ + void (*delete_cb)(lv_font_t * font); /**< Font deletion callback function*/ + void * (*dup_src_cb)(const void * src); /**< Font source duplication callback function*/ + void (*free_src_cb)(void * src); /**< Font source free callback function*/ +}; + +struct _lv_font_info_t { + const char * name; /**< Font name, used to distinguish different font resources*/ + const lv_font_class_t * class_p; /**< Font backend implementation*/ + uint32_t size; /**< Font size in pixel*/ + uint32_t render_mode; /**< Font rendering mode, see `lv_freetype_font_render_mode_t`*/ + uint32_t style; /**< Font style, see `lv_freetype_font_style_t`*/ + lv_font_kerning_t kerning; /**< Font kerning, see `lv_font_kerning_t`*/ +}; + /********************** * GLOBAL PROTOTYPES **********************/ /** * Return with 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. - * @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. + * It always converts the normal fonts to A8 format in a draw_buf with + * LV_DRAW_BUF_ALIGN and LV_DRAW_BUF_STRIDE_ALIGN + * @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. + * @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, lv_draw_buf_t * draw_buf); + +/** + * Return the bitmap as it is. It works only if the font stores the bitmap in + * a non-volitile memory. + * @param g_dsc the glyph descriptor including which font to use, which supply the glyph_index + * and the format. + * @return the bitmap as it is + */ +const void * lv_font_get_glyph_static_bitmap(lv_font_glyph_dsc_t * g_dsc); + /** * Get the descriptor of a glyph * @param font pointer to font @@ -164,6 +203,27 @@ 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); +/** + * Get the default font, defined by LV_FONT_DEFAULT + * @return return pointer to the default font + */ +const lv_font_t * lv_font_get_default(void); + +/** + * Compare font information. + * @param ft_info_1 font information 1. + * @param ft_info_2 font information 2. + * @return return true if the fonts are equal. + */ +bool lv_font_info_is_equal(const lv_font_info_t * ft_info_1, const lv_font_info_t * ft_info_2); + +/** + * Checks if a font has a static rendering bitmap. + * @param font pointer to a font + * @return return true if the font has a bitmap generated for static rendering. + */ +bool lv_font_has_static_bitmap(const lv_font_t * font); + /********************** * MACROS **********************/ @@ -270,6 +330,14 @@ LV_FONT_DECLARE(lv_font_simsun_14_cjk) LV_FONT_DECLARE(lv_font_simsun_16_cjk) #endif +#if LV_FONT_SOURCE_HAN_SANS_SC_14_CJK +LV_FONT_DECLARE(lv_font_source_han_sans_sc_14_cjk) +#endif + +#if LV_FONT_SOURCE_HAN_SANS_SC_16_CJK +LV_FONT_DECLARE(lv_font_source_han_sans_sc_16_cjk) +#endif + #if LV_FONT_UNSCII_8 LV_FONT_DECLARE(lv_font_unscii_8) #endif @@ -283,12 +351,6 @@ LV_FONT_DECLARE(lv_font_unscii_16) LV_FONT_CUSTOM_DECLARE #endif -/** - * 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 - */ -const lv_font_t * lv_font_default(void); - #ifdef __cplusplus } /*extern "C"*/ #endif 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 5d0130454..7dbdfb578 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 @@ -47,6 +47,11 @@ static int kern_pair_16_compare(const void * ref, const void * element); static inline uint8_t rle_next(void); #endif /*LV_USE_FONT_COMPRESSED*/ +static lv_font_t * builtin_font_create_cb(const lv_font_info_t * info, const void * src); +static void builtin_font_delete_cb(lv_font_t * font); +static void * builtin_font_dup_src_cb(const void * src); +static void builtin_font_free_src_cb(void * src); + /********************** * STATIC VARIABLES **********************/ @@ -63,6 +68,13 @@ static const uint8_t opa3_table[8] = {0, 36, 73, 109, 146, 182, 218, 255}; static const uint8_t opa2_table[4] = {0, 85, 170, 255}; +const lv_font_class_t lv_builtin_font_class = { + .create_cb = builtin_font_create_cb, + .delete_cb = builtin_font_delete_cb, + .dup_src_cb = builtin_font_dup_src_cb, + .free_src_cb = builtin_font_free_src_cb, +}; + /********************** * GLOBAL PROTOTYPES **********************/ @@ -78,7 +90,6 @@ static const uint8_t opa2_table[4] = {0, 85, 170, 255}; 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; lv_font_fmt_txt_dsc_t * fdsc = (lv_font_fmt_txt_dsc_t *)font->dsc; uint32_t gid = g_dsc->gid.index; @@ -86,18 +97,23 @@ const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid]; + if(g_dsc->req_raw_bitmap) return &fdsc->glyph_bitmap[gdsc->bitmap_index]; + + uint8_t * bitmap_out = draw_buf->data; int32_t gsize = (int32_t) gdsc->box_w * gdsc->box_h; if(gsize == 0) return NULL; + uint16_t stride_in = g_dsc->stride; + if(fdsc->bitmap_format == LV_FONT_FMT_TXT_PLAIN) { const uint8_t * bitmap_in = &fdsc->glyph_bitmap[gdsc->bitmap_index]; uint8_t * bitmap_out_tmp = bitmap_out; int32_t i = 0; int32_t x, y; - uint32_t stride = lv_draw_buf_width_to_stride(gdsc->box_w, LV_COLOR_FORMAT_A8); - + uint32_t stride_out = lv_draw_buf_width_to_stride(gdsc->box_w, LV_COLOR_FORMAT_A8); if(fdsc->bpp == 1) { for(y = 0; y < gdsc->box_h; y ++) { + uint16_t line_rem = stride_in != 0 ? stride_in : gdsc->box_w; for(x = 0; x < gdsc->box_w; x++, i++) { i = i & 0x7; if(i == 0) bitmap_out_tmp[x] = (*bitmap_in) & 0x80 ? 0xff : 0x00; @@ -109,14 +125,21 @@ const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf else if(i == 6) bitmap_out_tmp[x] = (*bitmap_in) & 0x02 ? 0xff : 0x00; else if(i == 7) { bitmap_out_tmp[x] = (*bitmap_in) & 0x01 ? 0xff : 0x00; + line_rem--; bitmap_in++; } } - bitmap_out_tmp += stride; + /*Handle stride*/ + if(stride_in) { + i = 0; /*If there is a stride start from the next byte in the next line*/ + bitmap_in += line_rem; + } + bitmap_out_tmp += stride_out; } } else if(fdsc->bpp == 2) { for(y = 0; y < gdsc->box_h; y ++) { + uint16_t line_rem = stride_in != 0 ? stride_in : gdsc->box_w; for(x = 0; x < gdsc->box_w; x++, i++) { i = i & 0x3; if(i == 0) bitmap_out_tmp[x] = opa2_table[(*bitmap_in) >> 6]; @@ -124,15 +147,23 @@ const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf else if(i == 2) bitmap_out_tmp[x] = opa2_table[((*bitmap_in) >> 2) & 0x3]; else if(i == 3) { bitmap_out_tmp[x] = opa2_table[((*bitmap_in) >> 0) & 0x3]; + line_rem--; bitmap_in++; } } - bitmap_out_tmp += stride; + + /*Handle stride*/ + if(stride_in) { + i = 0; /*If there is a stride start from the next byte in the next line*/ + bitmap_in += line_rem; + } + bitmap_out_tmp += stride_out; } } else if(fdsc->bpp == 4) { for(y = 0; y < gdsc->box_h; y ++) { + uint16_t line_rem = stride_in != 0 ? stride_in : gdsc->box_w; for(x = 0; x < gdsc->box_w; x++, i++) { i = i & 0x1; if(i == 0) { @@ -140,12 +171,33 @@ const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf } else if(i == 1) { bitmap_out_tmp[x] = opa4_table[(*bitmap_in) & 0xF]; + line_rem--; bitmap_in++; } } - bitmap_out_tmp += stride; + + /*Handle stride*/ + if(stride_in) { + i = 0; /*If there is a stride start from the next byte in the next line*/ + bitmap_in += line_rem; + } + bitmap_out_tmp += stride_out; } } + else if(fdsc->bpp == 8) { + for(y = 0; y < gdsc->box_h; y ++) { + uint16_t line_rem = stride_in != 0 ? stride_in : gdsc->box_w; + for(x = 0; x < gdsc->box_w; x++, i++) { + bitmap_out_tmp[x] = *bitmap_in; + line_rem--; + bitmap_in++; + } + bitmap_out_tmp += stride_out; + bitmap_in += line_rem; + } + } + + lv_draw_buf_flush_cache(draw_buf, NULL); return draw_buf; } /*Handle compressed bitmap*/ @@ -154,6 +206,7 @@ const void * lv_font_get_bitmap_fmt_txt(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf bool prefilter = fdsc->bitmap_format == LV_FONT_FMT_TXT_COMPRESSED; decompress(&fdsc->glyph_bitmap[gdsc->bitmap_index], bitmap_out, gdsc->box_w, gdsc->box_h, (uint8_t)fdsc->bpp, prefilter); + lv_draw_buf_flush_cache(draw_buf, NULL); return draw_buf; #else /*!LV_USE_FONT_COMPRESSED*/ LV_LOG_WARN("Compressed fonts is used but LV_USE_FONT_COMPRESSED is not enabled in lv_conf.h"); @@ -201,6 +254,14 @@ bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out->box_w = gdsc->box_w; dsc_out->ofs_x = gdsc->ofs_x; dsc_out->ofs_y = gdsc->ofs_y; + + if(fdsc->stride == 0) dsc_out->stride = 0; + else { + /*e.g. font_dsc stride == 4 means align to 4 byte boundary. + *In glyph_dsc store the actual line length in bytes*/ + dsc_out->stride = LV_ROUND_UP(dsc_out->box_w, fdsc->stride); + } + dsc_out->format = (uint8_t)fdsc->bpp; dsc_out->is_placeholder = false; dsc_out->gid.index = gid; @@ -232,6 +293,10 @@ 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_FORMAT0_FULL) { const uint8_t * gid_ofs_8 = fdsc->cmaps[i].glyph_id_ofs_list; + /* The first character is always valid and should have offset = 0 + * However if a character is missing it also has offset=0. + * So if there is a 0 not on the first position then it's a missing character */ + if(gid_ofs_8[rcp] == 0 && letter != fdsc->cmaps[i].range_start) continue; glyph_id = fdsc->cmaps[i].glyph_id_start + gid_ofs_8[rcp]; } else if(fdsc->cmaps[i].type == LV_FONT_FMT_TXT_CMAP_SPARSE_TINY) { @@ -553,3 +618,61 @@ static int unicode_list_compare(const void * ref, const void * element) { return (*(uint16_t *)ref) - (*(uint16_t *)element); } + +static lv_font_t * builtin_font_create_cb(const lv_font_info_t * info, const void * src) +{ + const lv_builtin_font_src_t * font_src = src; + + /** + * If a crash occurs here, please check whether the last font in + * the lv_builtin_font_src array is set to NULL as required to mark the end of the array. + */ + while(font_src->font_p) { + if(info->size == font_src->size) { + return (lv_font_t *)font_src->font_p; + } + font_src++; + } + + LV_LOG_WARN("No built-in font found with size: %" LV_PRIu32, info->size); + return NULL; +} + +static void builtin_font_delete_cb(lv_font_t * font) +{ + /*Nothing to delete*/ + LV_UNUSED(font); +} + +static void * builtin_font_dup_src_cb(const void * src) +{ + const lv_builtin_font_src_t * font_src = src; + uint32_t len = 0; + + /*Measure the size of the source data*/ + + /** + * If a crash occurs here, please check whether the last font in + * the lv_builtin_font_src array is set to NULL as required to mark the end of the array. + */ + while(font_src->font_p) { + len++; + font_src++; + } + + if(len == 0) { + LV_LOG_WARN("No source data found"); + return NULL; + } + + lv_builtin_font_src_t * new_src = lv_malloc_zeroed(sizeof(lv_builtin_font_src_t) * (len + 1)); + LV_ASSERT_MALLOC(new_src); + lv_memcpy(new_src, src, sizeof(lv_builtin_font_src_t) * len); + + return new_src; +} + +static void builtin_font_free_src_cb(void * src) +{ + lv_free(src); +} 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 4eeb0c6e1..4dae27b7d 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 @@ -144,7 +144,7 @@ typedef struct { typedef enum { LV_FONT_FMT_TXT_PLAIN = 0, LV_FONT_FMT_TXT_COMPRESSED = 1, - LV_FONT_FMT_TXT_COMPRESSED_NO_PREFILTER = 1, + LV_FONT_FMT_TXT_COMPRESSED_NO_PREFILTER = 2, } lv_font_fmt_txt_bitmap_format_t; /** Describe store for additional data for fonts */ @@ -183,8 +183,23 @@ typedef struct { * from `lv_font_fmt_txt_bitmap_format_t` */ uint16_t bitmap_format : 2; + + /** + * Bytes to which each line is padded. + * 0: means no align and padding + * 1: e.g. with bpp=4 lines are aligned to 1 byte, so there can be a 4 bits of padding + * 4, 8, 16, 32, 64: each line is padded to the given byte boundaries + */ + uint8_t stride; } lv_font_fmt_txt_dsc_t; +typedef struct { + const lv_font_t * font_p; /**< Pointer to built-in font*/ + uint32_t size; /** < Size of the built-in font*/ +} lv_builtin_font_src_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_font_class_t lv_builtin_font_class; + /********************** * GLOBAL PROTOTYPES **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/font/lv_font_montserrat_14.c b/lib/libesp32_lvgl/lvgl/src/font/lv_font_montserrat_14.c index 2ba984ee0..7c8608c74 100644 --- a/lib/libesp32_lvgl/lvgl/src/font/lv_font_montserrat_14.c +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_font_montserrat_14.c @@ -2187,5 +2187,4 @@ lv_font_t lv_font_montserrat_14 = { #endif .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ }; - #endif /*#if LV_FONT_MONTSERRAT_14*/ diff --git a/lib/libesp32_lvgl/lvgl/src/font/lv_font_montserrat_14_aligned.c b/lib/libesp32_lvgl/lvgl/src/font/lv_font_montserrat_14_aligned.c new file mode 100644 index 000000000..c364e0181 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_font_montserrat_14_aligned.c @@ -0,0 +1,4179 @@ +/******************************************************************************* + * Size: 14 px + * Bpp: 8 + * Opts: --no-compress --no-prefilter --bpp 8 --stride 16 --align 16 --size 14 --font Montserrat-Medium.ttf -r 0x20-0x7F,0xB0,0x2022 --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 --format lvgl -o lv_font_montserrat_14_aligned.c --force-fast-kern-format + ******************************************************************************/ + +#ifdef __has_include + #if __has_include("lvgl.h") + #ifndef LV_LVGL_H_INCLUDE_SIMPLE + #define LV_LVGL_H_INCLUDE_SIMPLE + #endif + #endif +#endif + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE + #include "lvgl.h" +#else + #include "lvgl/lvgl.h" +#endif + +#if !LV_VERSION_CHECK(9, 3, 0) + #error "At least LVGL v9.3 is required to use the stride attribute of the fonts" +#endif + +#ifndef LV_FONT_MONTSERRAT_14_ALIGNED + #define LV_FONT_MONTSERRAT_14_ALIGNED 1 +#endif + +#if LV_FONT_MONTSERRAT_14_ALIGNED + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + + /* U+0021 "!" */ + 0x0, 0xe4, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xdb, 0x9d, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd2, 0x93, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc9, 0x8a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb7, 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xae, 0x6d, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1a, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xbe, 0x81, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd2, 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0022 "\"" */ + 0x1e, 0xff, 0xc, 0x92, 0x94, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x18, 0xff, 0x5, 0x8d, 0x8f, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x12, 0xfe, 0x0, 0x88, 0x89, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xf7, 0x0, 0x83, 0x83, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x0, 0x4, 0x4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0023 "#" */ + 0x0, 0x0, 0x0, 0xdd, 0x23, 0x0, 0x3d, 0xc3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xf5, 0x3, 0x0, 0x64, 0x9b, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x78, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0x18, 0x57, 0xc0, 0x18, 0x18, 0xad, 0x69, + 0x18, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x62, 0x9d, 0x0, 0x0, 0xc0, 0x3d, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x80, 0x80, 0x0, 0x0, 0xdd, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x98, 0xf4, 0xfa, 0xf9, 0xf4, 0xf4, 0xff, 0xf4, + 0xf4, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x16, 0x24, 0xc5, 0x5b, 0x24, 0x39, 0xe8, 0x24, + 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd7, 0x27, 0x0, 0x33, 0xcb, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf2, 0xd, 0x0, 0x4e, 0xb1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0024 "$" */ + 0x0, 0x0, 0x0, 0x4, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x17, 0x9f, 0xe7, 0xff, 0xe5, 0xae, 0x33, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcb, 0xdc, 0x67, 0xe9, 0x64, 0xad, 0x75, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x20, 0xff, 0x44, 0x8, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x12, 0xfa, 0x87, 0xa, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6c, 0xf9, 0xe7, 0xf0, 0x58, 0xc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x19, 0x6e, 0xf9, 0xf3, 0xef, 0x51, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xe0, 0xb, 0xa4, 0xf2, + 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x1b, 0x0, 0x8, 0xe0, 0x0, 0x52, 0xff, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x40, 0xf1, 0x8d, 0x59, 0xe8, 0x66, 0xe0, 0xba, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5d, 0xc6, 0xf5, 0xff, 0xe7, 0x97, 0x12, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0025 "%" */ + 0x0, 0x8d, 0xd9, 0xd1, 0x3e, 0x0, 0x0, 0x0, + 0xa2, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x49, 0xb4, 0x2, 0x25, 0xd7, 0x0, 0x0, 0x4d, + 0xc4, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x71, 0x74, 0x0, 0x0, 0xdc, 0x6, 0x11, 0xdc, + 0x25, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x40, 0xbe, 0x7, 0x30, 0xd0, 0x0, 0xa3, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x79, 0xd4, 0xc5, 0x31, 0x4e, 0xc2, 0x41, + 0xcb, 0xcc, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x12, 0xdd, 0x2c, 0xd9, + 0x20, 0x22, 0xdb, 0x9, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa5, 0x6e, 0x32, 0xb0, + 0x0, 0x0, 0xb1, 0x35, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x50, 0xc2, 0x1, 0x34, 0xaa, + 0x0, 0x0, 0xab, 0x37, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x12, 0xdd, 0x23, 0x0, 0xa, 0xd3, + 0xc, 0xf, 0xd7, 0xb, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa6, 0x6d, 0x0, 0x0, 0x0, 0x4d, + 0xc9, 0xca, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0026 "&" */ + 0x0, 0x0, 0x4a, 0xd4, 0xf6, 0xce, 0x35, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0xf6, 0x72, 0x15, 0x86, 0xcd, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0xff, 0x2c, 0x0, 0x5c, 0xd4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xbe, 0xba, 0x67, 0xee, 0x4b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x50, 0xff, 0xf9, 0x37, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x71, 0xe9, 0x61, 0xd3, 0xb5, 0x7, 0x36, + 0x85, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x28, 0xfe, 0x32, 0x0, 0x14, 0xd0, 0xba, 0xa0, + 0xa8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x55, 0xfd, 0x9, 0x0, 0x0, 0x12, 0xd0, 0xff, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0xf5, 0xb7, 0x49, 0x44, 0x80, 0xf4, 0xe0, + 0xc2, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x35, 0xbb, 0xf3, 0xf6, 0xc5, 0x4e, 0xf, + 0xbe, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0027 "'" */ + 0x1e, 0xff, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x18, 0xff, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x12, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0028 "(" */ + 0x0, 0x3d, 0xf6, 0x13, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb3, 0x9a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0xf9, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4b, 0xfa, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x79, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x96, 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa5, 0xaa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa5, 0xaa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x96, 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x79, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4b, 0xfa, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0xf9, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb2, 0x9a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3d, 0xf6, 0x14, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0029 ")" */ + 0x53, 0xea, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xe0, 0x6d, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8e, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x49, 0xfd, 0x9, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1c, 0xff, 0x34, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xfc, 0x52, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xef, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xef, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xfc, 0x52, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1c, 0xff, 0x34, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x49, 0xfd, 0xa, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8e, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xdf, 0x6d, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x53, 0xeb, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+002A "*" */ + 0x0, 0x0, 0xa0, 0x36, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x89, 0xa7, 0x62, 0xc6, 0x23, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x92, 0xff, 0xef, 0x4c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4c, 0xdb, 0xdf, 0xd6, 0xb3, 0x16, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x42, 0x26, 0x9e, 0x35, 0x5b, 0xc, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5e, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+002B "+" */ + 0x0, 0x0, 0x0, 0x4a, 0x5e, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x84, 0xa8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x84, 0xa8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x34, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x30, 0x30, 0x9b, 0xb8, 0x30, 0x30, 0x9, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x84, 0xa8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x84, 0xa8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+002C "," */ + 0x0, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x39, 0xff, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1b, 0xea, 0x65, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe7, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x26, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+002D "-" */ + 0x1, 0x8, 0x8, 0x8, 0x4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x34, 0xff, 0xff, 0xff, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x38, 0x38, 0x38, 0x1f, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+002E "." */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x33, 0xf8, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0xee, 0x4f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+002F "/" */ + 0x0, 0x0, 0x0, 0x0, 0x3, 0xeb, 0x49, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x43, 0xef, 0x5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x98, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xe9, 0x4b, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x41, 0xf0, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x95, 0xa2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xe7, 0x4d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3f, 0xf1, 0x7, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x93, 0xa4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xe5, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3c, 0xf3, 0x8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x91, 0xa7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe3, 0x52, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3a, 0xf4, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0030 "0" */ + 0x0, 0x0, 0x48, 0xc9, 0xf5, 0xe0, 0x7d, 0x3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4b, 0xfd, 0xb2, 0x63, 0x88, 0xf9, 0x9c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xda, 0xb1, 0x0, 0x0, 0x0, 0x5b, 0xff, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x29, 0xff, 0x46, 0x0, 0x0, 0x0, 0x2, 0xeb, + 0x7f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x49, 0xff, 0x22, 0x0, 0x0, 0x0, 0x0, 0xca, + 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x49, 0xff, 0x21, 0x0, 0x0, 0x0, 0x0, 0xcb, + 0x9f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x29, 0xff, 0x46, 0x0, 0x0, 0x0, 0x3, 0xec, + 0x7f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd9, 0xb3, 0x1, 0x0, 0x0, 0x5d, 0xff, + 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4a, 0xfc, 0xb6, 0x67, 0x8b, 0xfa, 0x9a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x48, 0xc9, 0xf6, 0xe0, 0x7d, 0x3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0031 "1" */ + 0xe4, 0xff, 0xff, 0xb4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x43, 0x4c, 0xc4, 0xb4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xac, 0xb4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xac, 0xb4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xac, 0xb4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xac, 0xb4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xac, 0xb4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xac, 0xb4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xac, 0xb4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xac, 0xb4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0032 "2" */ + 0x5, 0x74, 0xd3, 0xf7, 0xe7, 0xa2, 0x19, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x87, 0xed, 0x83, 0x5a, 0x79, 0xec, 0xc7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x1e, 0x0, 0x0, 0x0, 0x60, 0xff, 0x14, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x67, 0xfa, 0xb, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe, 0xd7, 0x9b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xc5, 0xc6, 0xb, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x13, 0xcd, 0xc3, 0xe, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0xd4, 0xbc, 0xa, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0xdb, 0xe5, 0x54, 0x4c, 0x4c, 0x4c, 0x2a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0033 "3" */ + 0x7c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x24, 0x4c, 0x4c, 0x4c, 0x5e, 0xf7, 0x97, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xbd, 0xc2, 0x5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x94, 0xe1, 0x15, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x32, 0xff, 0xdf, 0x8e, 0x15, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0x46, 0x63, 0xd2, 0xdb, 0xa, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0xff, 0x49, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0x4, 0x0, 0x0, 0x0, 0x2b, 0xff, 0x4c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xbb, 0xd8, 0x7f, 0x5e, 0x76, 0xdf, 0xdf, 0x9, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0x96, 0xdf, 0xfa, 0xeb, 0xa5, 0x1e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0034 "4" */ + 0x0, 0x0, 0x0, 0x0, 0xb, 0xd1, 0xa7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xaa, 0xcf, 0xa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7b, 0xeb, 0x1f, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4c, 0xf9, 0x40, 0x0, 0x1b, 0x9, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x28, 0xf1, 0x6c, 0x0, 0x0, 0xfc, 0x58, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0xd9, 0xa7, 0xc, 0xc, 0xc, 0xfc, 0x5f, + 0xc, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x74, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x34, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3f, 0xff, 0x7f, + 0x3c, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, 0x58, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, 0x58, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0035 "5" */ + 0x0, 0x95, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xae, 0xb8, 0x4c, 0x4c, 0x4c, 0x4c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc7, 0x84, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe0, 0x72, 0x9, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf8, 0xff, 0xff, 0xf8, 0xc4, 0x43, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x3c, 0x3c, 0x43, 0x5d, 0xc1, 0xf6, 0x28, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xf3, 0x75, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x13, 0xd, 0x0, 0x0, 0x0, 0xd, 0xf5, 0x76, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8f, 0xe7, 0x8a, 0x5f, 0x6d, 0xce, 0xf2, 0x1f, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x83, 0xd6, 0xf8, 0xf0, 0xb7, 0x32, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0036 "6" */ + 0x0, 0x0, 0x28, 0xa6, 0xe7, 0xf7, 0xd7, 0x5c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x31, 0xf2, 0xd1, 0x6d, 0x50, 0x77, 0x44, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc8, 0xc9, 0x6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x21, 0xff, 0x4f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x45, 0xff, 0x54, 0xbf, 0xf9, 0xf3, 0xac, 0x1d, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4e, 0xff, 0xee, 0x81, 0x41, 0x58, 0xd8, 0xd5, + 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x33, 0xff, 0x86, 0x0, 0x0, 0x0, 0x36, 0xff, + 0x34, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xea, 0x87, 0x0, 0x0, 0x0, 0x39, 0xff, + 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x67, 0xfb, 0x84, 0x45, 0x5a, 0xda, 0xc5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5d, 0xd1, 0xf9, 0xeb, 0x9c, 0x13, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0037 "7" */ + 0x94, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x94, 0xd5, 0x4c, 0x4c, 0x4c, 0x4d, 0xee, 0x98, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x94, 0xc4, 0x0, 0x0, 0x0, 0x4a, 0xfe, 0x29, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xf, 0x0, 0x0, 0x0, 0xbc, 0xb6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2f, 0xff, 0x45, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa1, 0xd4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x19, 0xf9, 0x63, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x86, 0xea, 0x8, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0xed, 0x81, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6b, 0xf8, 0x17, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0038 "8" */ + 0x0, 0x13, 0x98, 0xe5, 0xfa, 0xe5, 0x99, 0x14, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xbe, 0xe5, 0x63, 0x3f, 0x63, 0xe4, 0xc2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xfd, 0x6c, 0x0, 0x0, 0x0, 0x65, 0xfe, + 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc6, 0xc2, 0x20, 0x0, 0x20, 0xbe, 0xc7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x25, 0xee, 0xff, 0xfd, 0xff, 0xee, 0x26, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xd9, 0xcc, 0x4f, 0x2f, 0x4f, 0xcc, 0xd9, + 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x51, 0xff, 0x20, 0x0, 0x0, 0x0, 0x1d, 0xff, + 0x54, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x52, 0xff, 0x29, 0x0, 0x0, 0x0, 0x26, 0xff, + 0x54, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xe1, 0xd7, 0x5e, 0x3f, 0x5f, 0xd7, 0xe2, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0xa1, 0xe7, 0xfb, 0xe7, 0xa1, 0x1e, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0039 "9" */ + 0x0, 0x36, 0xbe, 0xf5, 0xef, 0xaf, 0x27, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x24, 0xf4, 0xad, 0x47, 0x4c, 0xb6, 0xec, 0x1b, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x83, 0xe1, 0x3, 0x0, 0x0, 0x4, 0xe2, 0x92, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x90, 0xd4, 0x0, 0x0, 0x0, 0x0, 0xd6, 0xd6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x49, 0xff, 0x7b, 0x14, 0x20, 0x90, 0xfc, 0xf1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x77, 0xf5, 0xff, 0xff, 0xc3, 0x96, 0xe7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x2c, 0x1c, 0x0, 0xa6, 0xc2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2a, 0xfa, 0x68, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7a, 0x62, 0x57, 0x84, 0xf2, 0xbf, 0x3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xa1, 0xe8, 0xf8, 0xd9, 0x7e, 0x6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+003A ":" */ + 0x2f, 0xee, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x33, 0xf7, 0x55, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 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, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x33, 0xf8, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0xee, 0x4f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+003B ";" */ + 0x2f, 0xee, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x33, 0xf7, 0x55, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 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, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2b, 0xef, 0x51, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x29, 0xf4, 0x6f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xde, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1b, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+003C "<" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x19, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x62, 0xce, 0xf3, 0x27, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0x89, 0xec, 0xd4, 0x6c, 0xe, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0xfd, 0xc4, 0x3f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xa5, 0xf7, 0xb6, 0x4c, 0x2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x17, 0x7d, 0xe4, 0xe0, 0x79, 0xb, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4, 0x55, 0xc1, 0x33, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+003D "=" */ + 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x34, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x9, + 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, + 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x34, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x9, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+003E ">" */ + 0x8, 0x4a, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xeb, 0xdc, 0x71, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x5c, 0xc5, 0xf4, 0x98, 0x2c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2f, 0xad, 0xff, 0x2f, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3c, 0xa6, 0xf7, 0xb4, 0x17, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x6a, 0xd3, 0xed, 0x8c, 0x22, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0xcf, 0x64, 0x9, 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, + + /* U+003F "?" */ + 0x7, 0x7a, 0xd6, 0xf8, 0xe8, 0xa7, 0x1d, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x96, 0xe7, 0x74, 0x4b, 0x6a, 0xe9, 0xca, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x1a, 0x0, 0x0, 0x0, 0x6a, 0xfe, 0x5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9c, 0xce, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x89, 0xec, 0x2f, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6e, 0xf2, 0x2c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8b, 0x7a, 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, 0xb4, 0x84, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc7, 0x98, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0040 "@" */ + 0x0, 0x0, 0x0, 0xd, 0x6c, 0xc4, 0xe8, 0xf6, + 0xdd, 0xa5, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x30, 0xdb, 0xa8, 0x41, 0x13, 0x4, + 0x1e, 0x64, 0xd5, 0xa0, 0x6, 0x0, 0x0, 0x0, + 0x0, 0x19, 0xe6, 0x57, 0xd, 0x9c, 0xef, 0xef, + 0x99, 0x83, 0xc7, 0xa5, 0x9b, 0x0, 0x0, 0x0, + 0x0, 0xa3, 0x84, 0x0, 0xb9, 0xd8, 0x4d, 0x35, + 0xa0, 0xf6, 0xc0, 0x7, 0xd6, 0x31, 0x0, 0x0, + 0xe, 0xf1, 0x13, 0x34, 0xfc, 0x26, 0x0, 0x0, + 0x1, 0xc9, 0xc0, 0x0, 0x6a, 0x90, 0x0, 0x0, + 0x37, 0xcd, 0x0, 0x67, 0xda, 0x0, 0x0, 0x0, + 0x0, 0x7e, 0xc0, 0x0, 0x38, 0xb7, 0x0, 0x0, + 0x4c, 0xb7, 0x0, 0x67, 0xd9, 0x0, 0x0, 0x0, + 0x0, 0x7d, 0xc0, 0x0, 0x2b, 0xc1, 0x0, 0x0, + 0x36, 0xcc, 0x0, 0x33, 0xfc, 0x26, 0x0, 0x0, + 0x0, 0xc7, 0xc0, 0x0, 0x4c, 0xa6, 0x0, 0x0, + 0xd, 0xf0, 0x13, 0x0, 0xb8, 0xd7, 0x4a, 0x31, + 0x9d, 0xe4, 0xe9, 0x38, 0xc0, 0x55, 0x0, 0x0, + 0x0, 0xa1, 0x83, 0x0, 0xd, 0x9d, 0xef, 0xef, + 0x99, 0x18, 0xc2, 0xf6, 0x9a, 0x2, 0x0, 0x0, + 0x0, 0x19, 0xe6, 0x57, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x31, 0xde, 0xa7, 0x42, 0x14, 0xa, + 0x2c, 0x82, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0x70, 0xc7, 0xeb, 0xf7, + 0xdb, 0x93, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0041 "A" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd, 0xf5, 0x12, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3f, 0xf7, 0xdb, 0x7a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb0, 0x98, 0x61, 0xe6, + 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x24, 0xfb, 0x26, 0x6, 0xe5, + 0x5e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x94, 0xae, 0x0, 0x0, 0x77, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0xf4, 0x3a, 0x0, 0x0, 0xf, + 0xf2, 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x77, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xe3, 0x77, 0x30, 0x30, 0x30, 0x30, + 0x4a, 0xfe, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5a, 0xf3, 0xb, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc8, 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcb, 0x9d, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x65, 0xf6, 0x14, 0x0, 0x0, 0x0, 0x0, + + /* U+0042 "B" */ + 0x88, 0xff, 0xff, 0xff, 0xff, 0xee, 0xc0, 0x43, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe6, 0x34, 0x34, 0x34, 0x4a, 0xb3, 0xf8, + 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x14, 0xff, + 0x55, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x15, 0x87, 0xf4, + 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x82, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe6, 0x30, 0x30, 0x30, 0x3b, 0x79, 0xfb, + 0x65, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, + 0xcd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe7, 0x38, 0x38, 0x38, 0x42, 0x7d, 0xfb, + 0x7e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xd5, 0x75, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0043 "C" */ + 0x0, 0x0, 0x6, 0x73, 0xcf, 0xf4, 0xf0, 0xbc, + 0x49, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xcd, 0xf6, 0x99, 0x60, 0x63, 0xaa, + 0xfd, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa5, 0xed, 0x2b, 0x0, 0x0, 0x0, 0x0, + 0x38, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x18, 0xfc, 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x44, 0xff, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x45, 0xff, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x18, 0xfc, 0x69, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa5, 0xed, 0x2c, 0x0, 0x0, 0x0, 0x0, + 0x3e, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, 0xcf, 0xf6, 0x9a, 0x64, 0x67, 0xaf, + 0xfe, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8, 0x79, 0xd2, 0xf5, 0xf0, 0xbb, + 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0044 "D" */ + 0x88, 0xff, 0xff, 0xff, 0xfd, 0xe6, 0xaf, 0x41, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe9, 0x4c, 0x4c, 0x4f, 0x6b, 0xc0, 0xfe, + 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7a, + 0xfe, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd2, 0xa7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x93, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x93, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd2, 0xa7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7b, + 0xfe, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe9, 0x4c, 0x4c, 0x4f, 0x6a, 0xbf, 0xfe, + 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xff, 0xff, 0xff, 0xfd, 0xe7, 0xaf, 0x41, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0045 "E" */ + 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x64, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe9, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x1d, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe1, 0x8, 0x8, 0x8, 0x8, 0x6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe7, 0x38, 0x38, 0x38, 0x38, 0x2b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe9, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x2b, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x94, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0046 "F" */ + 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x64, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe9, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x1d, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe1, 0xc, 0xc, 0xc, 0xc, 0x9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe7, 0x3c, 0x3c, 0x3c, 0x3c, 0x2e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0047 "G" */ + 0x0, 0x0, 0x7, 0x74, 0xce, 0xf3, 0xf2, 0xc1, + 0x56, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xce, 0xf6, 0x9a, 0x61, 0x61, 0xa0, + 0xfa, 0x69, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa5, 0xee, 0x2c, 0x0, 0x0, 0x0, 0x0, + 0x2f, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x18, 0xfc, 0x6a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x44, 0xff, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x45, 0xff, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xbc, 0x9c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x18, 0xfc, 0x6c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xbc, 0x9c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa5, 0xef, 0x30, 0x0, 0x0, 0x0, 0x0, + 0xbc, 0x9c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xcc, 0xf8, 0x9d, 0x65, 0x68, 0xa1, + 0xf8, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0x75, 0xd0, 0xf4, 0xf2, 0xc3, + 0x60, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0048 "H" */ + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe1, 0xc, 0xc, 0xc, 0xc, 0xc, 0x86, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe7, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x9e, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0049 "I" */ + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+004A "J" */ + 0x0, 0x20, 0xff, 0xff, 0xff, 0xff, 0xcc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x4c, 0x4c, 0x4c, 0xb6, 0xcc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x98, 0xcc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x98, 0xcc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x98, 0xcc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x98, 0xcc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x99, 0xca, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2b, 0x0, 0x0, 0x0, 0xb9, 0xaf, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xe4, 0xb0, 0x56, 0x81, 0xfe, 0x64, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x35, 0xc2, 0xf6, 0xe2, 0x81, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+004B "K" */ + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0xf8, + 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x45, 0xf7, 0x63, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x3c, 0xf5, 0x74, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x34, 0xf1, 0x86, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x2c, 0xec, 0xcf, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xef, 0xe7, 0xc2, 0xfe, 0x66, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xff, 0xb3, 0x4, 0x7e, 0xfa, 0x3c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xeb, 0x9, 0x0, 0x0, 0xa9, 0xe8, 0x1c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x9, 0xcc, 0xcc, + 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0xe6, + 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+004C "L" */ + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe9, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0xd, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+004D "M" */ + 0x88, 0xe0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8e, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xff, 0x7e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x26, 0xfa, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xfb, 0xf5, 0x1d, 0x0, 0x0, 0x0, 0x0, + 0xb3, 0xf9, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0xc1, 0xa7, 0x0, 0x0, 0x0, 0x46, + 0xf7, 0x93, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x2e, 0xfb, 0x3c, 0x0, 0x3, 0xd4, + 0x81, 0x73, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x0, 0x95, 0xcd, 0x2, 0x6b, 0xe2, + 0xa, 0x73, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x0, 0x12, 0xec, 0x75, 0xec, 0x56, + 0x0, 0x72, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x0, 0x0, 0x67, 0xff, 0xc1, 0x0, + 0x0, 0x72, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x0, 0x0, 0x2, 0xaf, 0x2f, 0x0, + 0x0, 0x71, 0xe7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x70, 0xe7, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+004E "N" */ + 0x88, 0xe8, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x80, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xff, 0xc7, 0x6, 0x0, 0x0, 0x0, 0x80, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xf4, 0xf7, 0x98, 0x0, 0x0, 0x0, 0x80, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x60, 0xff, 0x61, 0x0, 0x0, 0x80, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x96, 0xf7, 0x33, 0x0, 0x80, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x6, 0xc6, 0xe1, 0x14, 0x80, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x1a, 0xe8, 0xbb, 0x83, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x3d, 0xfb, 0xeb, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xff, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa4, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+004F "O" */ + 0x0, 0x0, 0x6, 0x71, 0xce, 0xf3, 0xed, 0xbd, + 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0xcb, 0xf6, 0x98, 0x60, 0x67, 0xb0, + 0xff, 0x9f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa3, 0xed, 0x2b, 0x0, 0x0, 0x0, 0x0, + 0x59, 0xfe, 0x69, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x17, 0xfb, 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa8, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x44, 0xff, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x60, 0xff, 0x9, 0x0, 0x0, 0x0, 0x0, + 0x45, 0xff, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x60, 0xfe, 0x8, 0x0, 0x0, 0x0, 0x0, + 0x18, 0xfc, 0x69, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa8, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa5, 0xed, 0x2c, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0xfe, 0x69, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xcc, 0xf6, 0x99, 0x63, 0x6a, 0xb0, + 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0x75, 0xd0, 0xf4, 0xee, 0xbf, + 0x57, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0050 "P" */ + 0x88, 0xff, 0xff, 0xff, 0xf6, 0xd3, 0x78, 0x7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe9, 0x4c, 0x4c, 0x55, 0x85, 0xf1, 0xb7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x51, 0xff, + 0x35, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x10, 0xff, + 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x35, 0xff, + 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe1, 0xc, 0xc, 0x15, 0x45, 0xd5, 0xda, + 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb5, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe7, 0x3c, 0x3c, 0x33, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0051 "Q" */ + 0x0, 0x0, 0x5, 0x71, 0xce, 0xf3, 0xed, 0xbd, + 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0xc9, 0xf6, 0x98, 0x60, 0x67, 0xb1, + 0xff, 0x9f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa1, 0xee, 0x2c, 0x0, 0x0, 0x0, 0x0, + 0x5c, 0xff, 0x69, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x16, 0xfb, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xaa, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x43, 0xff, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x61, 0xfe, 0x8, 0x0, 0x0, 0x0, 0x0, + 0x46, 0xff, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5f, 0xff, 0xb, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0xfd, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa4, 0xdb, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xad, 0xea, 0x25, 0x0, 0x0, 0x0, 0x0, + 0x52, 0xfd, 0x6e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x15, 0xd8, 0xf2, 0x8d, 0x57, 0x5e, 0xa6, + 0xfe, 0xa8, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x87, 0xdc, 0xfb, 0xff, 0xcf, + 0x5f, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0xe0, 0xc9, + 0x2c, 0x19, 0x9a, 0x42, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xba, + 0xff, 0xff, 0xcb, 0x1e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x19, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0052 "R" */ + 0x88, 0xff, 0xff, 0xff, 0xf6, 0xd3, 0x78, 0x7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe9, 0x4c, 0x4c, 0x55, 0x85, 0xf1, 0xb7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x51, 0xff, + 0x35, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x10, 0xff, + 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x35, 0xff, + 0x3f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe1, 0x8, 0x8, 0x11, 0x42, 0xd4, 0xd7, + 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe7, 0x38, 0x38, 0x36, 0xd3, 0xab, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x28, 0xf4, 0x6c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x5c, 0xf8, + 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0053 "S" */ + 0x0, 0x15, 0x99, 0xe4, 0xf8, 0xdc, 0xa1, 0x2c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xcd, 0xe2, 0x6c, 0x4c, 0x67, 0xb8, 0x78, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x24, 0xff, 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x11, 0xfa, 0x85, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x67, 0xf7, 0xdd, 0x94, 0x50, 0xa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x14, 0x61, 0xa4, 0xe9, 0xee, 0x52, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x9a, 0xf2, + 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x23, 0x0, 0x0, 0x0, 0x0, 0x56, 0xff, + 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3e, 0xf7, 0xa0, 0x5e, 0x4e, 0x73, 0xe7, 0xbd, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4e, 0xb7, 0xed, 0xfa, 0xe1, 0x91, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0054 "T" */ + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x47, 0x4c, 0x4c, 0xb4, 0xdb, 0x4c, 0x4c, 0x4c, + 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x94, 0xcc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x94, 0xcc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x94, 0xcc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x94, 0xcc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x94, 0xcc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x94, 0xcc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x94, 0xcc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x94, 0xcc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0055 "U" */ + 0x9c, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb0, + 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9c, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb0, + 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9c, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb0, + 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9c, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb0, + 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9c, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb0, + 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9a, 0xcb, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb4, + 0xaa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8a, 0xe7, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd1, + 0x99, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4f, 0xff, 0x48, 0x0, 0x0, 0x0, 0x34, 0xfe, + 0x5e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xc9, 0xf5, 0x8a, 0x62, 0x83, 0xf0, 0xd2, + 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x92, 0xe3, 0xfb, 0xe6, 0x98, 0x12, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0056 "V" */ + 0x0, 0xcd, 0xb6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa4, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5f, 0xfe, 0x26, 0x0, 0x0, 0x0, 0x0, + 0x18, 0xf9, 0x56, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xe9, 0x92, 0x0, 0x0, 0x0, 0x0, + 0x80, 0xe4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x82, 0xf2, 0xd, 0x0, 0x0, 0x6, + 0xe8, 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x19, 0xfa, 0x6e, 0x0, 0x0, 0x5d, + 0xf7, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa5, 0xda, 0x1, 0x0, 0xcb, + 0x9e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x36, 0xff, 0x4a, 0x3a, 0xff, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc8, 0xb8, 0xa9, 0xc2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x5a, 0xfe, 0xfb, 0x54, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x5, 0xe5, 0xe2, 0x3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0057 "W" */ + 0x63, 0xfb, 0x12, 0x0, 0x0, 0x0, 0x0, 0xdf, + 0xbd, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xff, 0x25, + 0x13, 0xfb, 0x60, 0x0, 0x0, 0x0, 0x37, 0xff, + 0xfc, 0x16, 0x0, 0x0, 0x0, 0x83, 0xd2, 0x0, + 0x0, 0xbb, 0xb3, 0x0, 0x0, 0x0, 0x8e, 0xbf, + 0xed, 0x67, 0x0, 0x0, 0x0, 0xd7, 0x7e, 0x0, + 0x0, 0x68, 0xf8, 0xe, 0x0, 0x1, 0xe3, 0x64, + 0x9d, 0xbc, 0x0, 0x0, 0x2d, 0xff, 0x2b, 0x0, + 0x0, 0x16, 0xfd, 0x59, 0x0, 0x3c, 0xfb, 0x13, + 0x48, 0xfc, 0x14, 0x0, 0x81, 0xd7, 0x0, 0x0, + 0x0, 0x0, 0xc1, 0xad, 0x0, 0x93, 0xb9, 0x0, + 0x4, 0xec, 0x65, 0x0, 0xd6, 0x83, 0x0, 0x0, + 0x0, 0x0, 0x6d, 0xf5, 0xd, 0xe7, 0x63, 0x0, + 0x0, 0x9c, 0xba, 0x2b, 0xff, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x1a, 0xfe, 0x95, 0xfb, 0x13, 0x0, + 0x0, 0x47, 0xfb, 0x92, 0xdc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc6, 0xfe, 0xb8, 0x0, 0x0, + 0x0, 0x4, 0xec, 0xfd, 0x89, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x72, 0xff, 0x62, 0x0, 0x0, + 0x0, 0x0, 0x9b, 0xff, 0x35, 0x0, 0x0, 0x0, + + /* U+0058 "X" */ + 0x40, 0xfd, 0x5b, 0x0, 0x0, 0x0, 0xa, 0xd8, + 0x9f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x88, 0xf1, 0x21, 0x0, 0x0, 0x98, 0xdc, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xcd, 0xc5, 0x3, 0x4d, 0xfa, 0x36, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x28, 0xf5, 0x93, 0xea, 0x7a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6b, 0xff, 0xc6, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x97, 0xfd, 0xea, 0x18, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4e, 0xfd, 0x4a, 0xd5, 0xb8, 0x1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x19, 0xeb, 0x8c, 0x0, 0x2f, 0xf8, 0x71, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xbb, 0xd1, 0x7, 0x0, 0x0, 0x72, 0xf8, + 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x74, 0xf8, 0x2d, 0x0, 0x0, 0x0, 0x1, 0xba, + 0xd6, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0059 "Y" */ + 0x0, 0xc2, 0xbb, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x91, 0xcd, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0xfc, 0x54, 0x0, 0x0, 0x0, 0x2e, + 0xfa, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x91, 0xe2, 0xa, 0x0, 0x0, 0xc2, + 0x9f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0xe8, 0x86, 0x0, 0x5d, 0xf0, + 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5e, 0xf9, 0x34, 0xe7, 0x6f, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc3, 0xf5, 0xd3, 0x4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3c, 0xff, 0x4e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x28, 0xff, 0x38, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x28, 0xff, 0x38, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x28, 0xff, 0x38, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+005A "Z" */ + 0x4c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x9c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x16, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0xa9, 0xfb, + 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x39, 0xf9, 0x6d, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x19, 0xe6, 0xa1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xc6, 0xcc, 0x8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9a, 0xea, 0x1e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x67, 0xfb, 0x41, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3a, 0xf9, 0x71, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x19, 0xe6, 0xd5, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, + 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xcc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+005B "[" */ + 0x88, 0xff, 0xff, 0x64, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd9, 0x30, 0x12, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xd9, 0x30, 0x12, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xff, 0xff, 0x64, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+005C "\\" */ + 0x5e, 0xd9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf, 0xf9, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb5, 0x83, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x60, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x11, 0xfa, 0x2c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb7, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x63, 0xd5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x12, 0xfb, 0x2a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb9, 0x7e, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x65, 0xd3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x14, 0xfb, 0x27, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xbc, 0x7c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x67, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x15, 0xfc, 0x25, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+005D "]" */ + 0xbc, 0xff, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x23, 0x50, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x28, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x28, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x28, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x28, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x28, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x28, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x28, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x28, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x28, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x28, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x23, 0x50, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xbc, 0xff, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+005E "^" */ + 0x0, 0x0, 0xae, 0xd7, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1b, 0xe7, 0xc8, 0x41, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x82, 0x8a, 0x5e, 0xaa, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xe5, 0x24, 0x8, 0xe9, 0x19, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x56, 0xbb, 0x0, 0x0, 0x92, 0x7d, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xbf, 0x53, 0x0, 0x0, 0x2b, 0xe3, 0x3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+005F "_" */ + 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0060 "`" */ + 0xe, 0xb8, 0xc5, 0xb, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x96, 0xbd, 0x8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0061 "a" */ + 0x0, 0x4e, 0xc6, 0xf6, 0xeb, 0xaa, 0x1a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xb4, 0x7d, 0x4a, 0x56, 0xd4, 0xbe, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0xff, 0xd, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x43, 0xc0, 0xe4, 0xec, 0xef, 0xff, 0x27, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x16, 0xf5, 0x88, 0x24, 0x1c, 0x46, 0xff, 0x28, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x40, 0xff, 0x12, 0x0, 0x0, 0x48, 0xff, 0x28, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x17, 0xf6, 0x79, 0xe, 0x34, 0xd9, 0xff, 0x28, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4b, 0xd5, 0xf9, 0xd9, 0x74, 0xff, 0x28, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0062 "b" */ + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa2, 0x82, 0xe6, 0xf5, 0xc1, 0x3b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xf7, 0xd0, 0x5a, 0x4f, 0xb7, 0xfa, 0x33, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xed, 0x11, 0x0, 0x0, 0x2, 0xcb, 0xaf, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xaa, 0x0, 0x0, 0x0, 0x0, 0x74, 0xe6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xab, 0x0, 0x0, 0x0, 0x0, 0x75, 0xe5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xee, 0x13, 0x0, 0x0, 0x3, 0xcd, 0xaf, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xf1, 0xd3, 0x5e, 0x53, 0xba, 0xfa, 0x33, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0x92, 0x81, 0xe7, 0xf5, 0xc1, 0x3b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0063 "c" */ + 0x0, 0x2, 0x72, 0xd9, 0xf8, 0xd9, 0x69, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x94, 0xf5, 0x79, 0x48, 0x80, 0xf9, 0x49, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x21, 0xfe, 0x5a, 0x0, 0x0, 0x0, 0x28, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x59, 0xfd, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x59, 0xfd, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x20, 0xfe, 0x5b, 0x0, 0x0, 0x0, 0x2b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x93, 0xf5, 0x7b, 0x4b, 0x83, 0xfa, 0x48, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x72, 0xda, 0xf8, 0xd8, 0x63, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0064 "d" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0x81, 0xe1, 0xf7, 0xc6, 0x47, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa4, 0xf5, 0x77, 0x48, 0x84, 0xf2, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x26, 0xff, 0x5c, 0x0, 0x0, 0x0, 0x78, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5b, 0xfd, 0x6, 0x0, 0x0, 0x0, 0x20, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0xfc, 0x4, 0x0, 0x0, 0x0, 0x1d, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x26, 0xff, 0x52, 0x0, 0x0, 0x0, 0x6e, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa4, 0xee, 0x63, 0x34, 0x70, 0xed, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0x82, 0xe2, 0xf9, 0xcb, 0x42, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0065 "e" */ + 0x0, 0x4, 0x80, 0xe1, 0xf7, 0xcb, 0x4d, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa0, 0xdc, 0x5c, 0x3f, 0x83, 0xfb, 0x4c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x24, 0xfe, 0x27, 0x0, 0x0, 0x0, 0x88, 0xc7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0xfe, 0xec, 0xec, 0xec, 0xec, 0xf2, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0xfe, 0x29, 0x1c, 0x1c, 0x1c, 0x1c, 0x1a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x22, 0xfe, 0x71, 0x0, 0x0, 0x0, 0x18, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x98, 0xfb, 0x8e, 0x4e, 0x6e, 0xea, 0x47, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x76, 0xd9, 0xf9, 0xe1, 0x83, 0x5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0066 "f" */ + 0x0, 0x3, 0x97, 0xee, 0xe7, 0x3a, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5b, 0xf5, 0x4b, 0x49, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x85, 0xca, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xcc, 0xff, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x26, 0x9e, 0xd9, 0x30, 0x2d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0067 "g" */ + 0x0, 0x4, 0x7f, 0xe0, 0xf8, 0xcd, 0x48, 0xe8, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa0, 0xf6, 0x7f, 0x4c, 0x7e, 0xf2, 0xfa, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x24, 0xff, 0x5d, 0x0, 0x0, 0x0, 0x5c, 0xff, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0xfe, 0x9, 0x0, 0x0, 0x0, 0x7, 0xfc, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0xfd, 0x6, 0x0, 0x0, 0x0, 0x5, 0xfb, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x23, 0xff, 0x67, 0x0, 0x0, 0x0, 0x67, 0xff, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9d, 0xfb, 0x7f, 0x4b, 0x7e, 0xf6, 0xfe, + 0x5f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0x7f, 0xe0, 0xf9, 0xcf, 0x4b, 0xfc, + 0x55, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x3a, 0xff, + 0x2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc4, 0xb3, 0x69, 0x4c, 0x6e, 0xe3, 0xbe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x33, 0xa8, 0xe7, 0xf9, 0xdb, 0x8d, 0xd, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0068 "h" */ + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa5, 0x8b, 0xe8, 0xf2, 0xb8, 0x24, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xfb, 0xc7, 0x5d, 0x61, 0xdd, 0xd3, 0x3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xe8, 0xc, 0x0, 0x0, 0x3e, 0xff, 0x2e, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xae, 0x0, 0x0, 0x0, 0xd, 0xff, 0x4c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x8, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x8, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x8, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x8, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0069 "i" */ + 0xbf, 0xab, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa2, 0x8d, 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, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+006A "j" */ + 0x0, 0x0, 0x0, 0xac, 0xbb, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x91, 0x9a, 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, 0xa8, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa8, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa8, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa8, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa8, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa8, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa8, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa8, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xae, 0xa8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x62, 0x4d, 0xee, 0x76, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0xdb, 0xf4, 0xab, 0xb, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+006B "k" */ + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0xf, 0xc9, 0xc4, 0xa, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x11, 0xcb, 0xcf, 0xf, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x12, 0xcd, 0xd9, 0x16, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xb3, 0xcf, 0xff, 0x63, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xff, 0xd7, 0xb5, 0xed, 0x1c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xdc, 0x18, 0x10, 0xde, 0xc1, 0x3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x35, 0xfa, 0x7f, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x70, 0xfc, 0x3d, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+006C "l" */ + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+006D "m" */ + 0xb8, 0x99, 0x96, 0xec, 0xf4, 0xad, 0x17, 0x5e, + 0xd4, 0xf7, 0xd3, 0x4c, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xfb, 0xb4, 0x49, 0x5e, 0xea, 0xde, 0xef, + 0x6b, 0x45, 0xa6, 0xfa, 0x26, 0x0, 0x0, 0x0, + 0xb8, 0xe3, 0x6, 0x0, 0x0, 0x6c, 0xff, 0x66, + 0x0, 0x0, 0x6, 0xea, 0x76, 0x0, 0x0, 0x0, + 0xb8, 0xac, 0x0, 0x0, 0x0, 0x40, 0xff, 0x28, + 0x0, 0x0, 0x0, 0xc4, 0x94, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x3c, 0xff, 0x1c, + 0x0, 0x0, 0x0, 0xc0, 0x98, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x3c, 0xff, 0x1c, + 0x0, 0x0, 0x0, 0xc0, 0x98, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x3c, 0xff, 0x1c, + 0x0, 0x0, 0x0, 0xc0, 0x98, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x3c, 0xff, 0x1c, + 0x0, 0x0, 0x0, 0xc0, 0x98, 0x0, 0x0, 0x0, + + /* U+006E "n" */ + 0xb8, 0x98, 0x92, 0xe9, 0xf2, 0xb8, 0x24, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xfb, 0xbb, 0x4d, 0x51, 0xd5, 0xd3, 0x3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xe5, 0x8, 0x0, 0x0, 0x39, 0xff, 0x2e, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xad, 0x0, 0x0, 0x0, 0xc, 0xff, 0x4c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x8, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x8, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x8, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x8, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+006F "o" */ + 0x0, 0x2, 0x77, 0xdc, 0xf7, 0xd5, 0x66, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x99, 0xf4, 0x77, 0x48, 0x82, 0xfa, 0x7a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x22, 0xff, 0x5a, 0x0, 0x0, 0x0, 0x76, 0xf5, + 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0xfd, 0x5, 0x0, 0x0, 0x0, 0x1f, 0xff, + 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0xfd, 0x6, 0x0, 0x0, 0x0, 0x20, 0xff, + 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x22, 0xfe, 0x5d, 0x0, 0x0, 0x0, 0x78, 0xf5, + 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x98, 0xf6, 0x7b, 0x4b, 0x86, 0xfb, 0x7a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x77, 0xdc, 0xf8, 0xd6, 0x66, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0070 "p" */ + 0xb8, 0x94, 0x89, 0xe8, 0xf5, 0xc1, 0x3b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xf7, 0xca, 0x4c, 0x3f, 0xa9, 0xfa, 0x33, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xec, 0x10, 0x0, 0x0, 0x1, 0xc6, 0xaf, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa9, 0x0, 0x0, 0x0, 0x0, 0x72, 0xe6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xac, 0x0, 0x0, 0x0, 0x0, 0x76, 0xe5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xef, 0x14, 0x0, 0x0, 0x3, 0xcf, 0xaf, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xf5, 0xd4, 0x5e, 0x53, 0xbb, 0xfa, 0x33, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa1, 0x7f, 0xe6, 0xf5, 0xc1, 0x3b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0071 "q" */ + 0x0, 0x5, 0x81, 0xe1, 0xf7, 0xc6, 0x3b, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa4, 0xf4, 0x77, 0x48, 0x84, 0xef, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x26, 0xff, 0x5a, 0x0, 0x0, 0x0, 0x77, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5b, 0xfd, 0x5, 0x0, 0x0, 0x0, 0x1f, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0xfd, 0x6, 0x0, 0x0, 0x0, 0x20, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x26, 0xff, 0x5d, 0x0, 0x0, 0x0, 0x79, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa4, 0xf6, 0x7b, 0x4c, 0x88, 0xf1, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0x82, 0xe2, 0xf8, 0xc5, 0x43, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0xff, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0072 "r" */ + 0xb8, 0x94, 0x8a, 0xe8, 0x43, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xf1, 0xd8, 0x74, 0x1a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xef, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0073 "s" */ + 0x0, 0x5a, 0xd2, 0xf6, 0xe2, 0xac, 0x1f, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x33, 0xfe, 0x7d, 0x3f, 0x56, 0xa7, 0xd, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x61, 0xf8, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0xe7, 0xe3, 0x9a, 0x63, 0x18, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x12, 0x6c, 0xa0, 0xe0, 0xf5, 0x39, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, 0x0, 0x0, 0x3, 0xd9, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x62, 0xc1, 0x67, 0x47, 0x6b, 0xf6, 0x60, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0xaa, 0xea, 0xf9, 0xdc, 0x78, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0074 "t" */ + 0x0, 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xcc, 0xff, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x26, 0x9e, 0xd9, 0x30, 0x2d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x88, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x84, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x59, 0xfc, 0x5e, 0x58, 0x17, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x9e, 0xf1, 0xe1, 0x37, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0075 "u" */ + 0xcc, 0x8c, 0x0, 0x0, 0x0, 0x28, 0xff, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xcc, 0x8c, 0x0, 0x0, 0x0, 0x28, 0xff, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xcc, 0x8c, 0x0, 0x0, 0x0, 0x28, 0xff, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xcc, 0x8c, 0x0, 0x0, 0x0, 0x28, 0xff, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc8, 0x90, 0x0, 0x0, 0x0, 0x35, 0xff, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xaa, 0xbc, 0x0, 0x0, 0x0, 0x75, 0xff, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x51, 0xff, 0x83, 0x3f, 0x71, 0xef, 0xff, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6a, 0xda, 0xf8, 0xcc, 0x52, 0xff, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0076 "v" */ + 0x0, 0xd4, 0x92, 0x0, 0x0, 0x0, 0x0, 0xad, + 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6d, 0xee, 0x9, 0x0, 0x0, 0x19, 0xfb, + 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xf5, 0x5d, 0x0, 0x0, 0x7d, 0xd3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9d, 0xc3, 0x0, 0x2, 0xe1, 0x6b, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x34, 0xff, 0x29, 0x4d, 0xf4, 0xe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xcc, 0x8e, 0xb5, 0x9b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x65, 0xf0, 0xfd, 0x33, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0xf1, 0xcb, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0077 "w" */ + 0xc0, 0x86, 0x0, 0x0, 0x0, 0x6d, 0xfb, 0x14, + 0x0, 0x0, 0x0, 0xdf, 0x53, 0x0, 0x0, 0x0, + 0x68, 0xdd, 0x0, 0x0, 0x0, 0xc7, 0xff, 0x68, + 0x0, 0x0, 0x39, 0xf2, 0x8, 0x0, 0x0, 0x0, + 0x14, 0xfb, 0x34, 0x0, 0x21, 0xfc, 0x9c, 0xc0, + 0x0, 0x0, 0x91, 0xa2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb7, 0x8a, 0x0, 0x7a, 0xbc, 0x27, 0xfd, + 0x1a, 0x2, 0xe6, 0x49, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5e, 0xe0, 0x0, 0xd3, 0x60, 0x0, 0xcd, + 0x70, 0x41, 0xec, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0xf7, 0x65, 0xf6, 0xe, 0x0, 0x72, + 0xc8, 0x99, 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xad, 0xf3, 0xa9, 0x0, 0x0, 0x1a, + 0xfc, 0xf2, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x54, 0xff, 0x4d, 0x0, 0x0, 0x0, + 0xbd, 0xe5, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0078 "x" */ + 0x4d, 0xf9, 0x33, 0x0, 0x0, 0x72, 0xeb, 0x19, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x97, 0xd8, 0xa, 0x2d, 0xf7, 0x4d, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xd7, 0x9e, 0xd2, 0x95, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x31, 0xfb, 0xd7, 0x9, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4d, 0xfe, 0xe9, 0x17, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0xea, 0x77, 0xbd, 0xb8, 0x1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xb8, 0xbe, 0x2, 0x1d, 0xef, 0x72, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x71, 0xee, 0x1c, 0x0, 0x0, 0x59, 0xf9, 0x31, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0079 "y" */ + 0x0, 0xd3, 0x93, 0x0, 0x0, 0x0, 0x0, 0xac, + 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6a, 0xf0, 0xa, 0x0, 0x0, 0x17, 0xfa, + 0x39, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0xf3, 0x63, 0x0, 0x0, 0x79, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x97, 0xcb, 0x0, 0x1, 0xdd, 0x67, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0xff, 0x33, 0x46, 0xf1, 0xc, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc4, 0x9b, 0xad, 0x94, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5b, 0xf5, 0xfa, 0x2c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0xea, 0xc2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc, 0xef, 0x58, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x92, 0x48, 0xa4, 0xdb, 0x4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x18, 0xbd, 0xf5, 0xcd, 0x2d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+007A "z" */ + 0x5c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x11, 0x30, 0x30, 0x30, 0x7b, 0xfd, 0x42, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1d, 0xec, 0x7f, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0xc4, 0xbe, 0x2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x88, 0xe9, 0x18, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x47, 0xfc, 0x44, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0xea, 0xa9, 0x30, 0x30, 0x30, 0x25, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+007B "{" */ + 0x0, 0x0, 0x6a, 0xeb, 0xa3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xf8, 0x9a, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x13, 0xff, 0x45, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x14, 0xff, 0x44, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x14, 0xff, 0x44, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x30, 0xff, 0x3d, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x34, 0xff, 0xcd, 0x5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x60, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x14, 0xff, 0x43, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x14, 0xff, 0x44, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x14, 0xff, 0x44, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x12, 0xff, 0x46, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xf0, 0xa0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5e, 0xe9, 0xa3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+007C "|" */ + 0x88, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+007D "}" */ + 0xbb, 0xe6, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x26, 0xa8, 0xeb, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x55, 0xff, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x54, 0xff, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x54, 0xff, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4d, 0xff, 0x1f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xdd, 0xff, 0x1c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x42, 0xff, 0x52, 0x5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x53, 0xff, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x54, 0xff, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x54, 0xff, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x57, 0xfe, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x26, 0xad, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xbb, 0xe4, 0x4f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+007E "~" */ + 0x0, 0x7f, 0xe7, 0xc3, 0x45, 0x1, 0xb7, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x16, 0xe6, 0x27, 0x5c, 0xdb, 0xf7, 0xc1, 0x5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0x10, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+00B0 "°" */ + 0x0, 0x4e, 0xc7, 0xc3, 0x36, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x24, 0xbb, 0xa, 0x17, 0xcc, 0xc, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x58, 0x72, 0x0, 0x0, 0x9b, 0x33, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x25, 0xbe, 0xb, 0x17, 0xce, 0xd, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x51, 0xce, 0xc9, 0x39, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+2022 "•" */ + 0x0, 0x6e, 0xa3, 0x11, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xfe, 0xff, 0x67, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb1, 0xe7, 0x29, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F001 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x27, 0x72, 0xbe, 0xfa, 0xb9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x44, + 0x90, 0xdc, 0xff, 0xff, 0xff, 0xff, 0xd4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x35, 0xae, 0xf3, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa8, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xd3, 0xf9, 0xd4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xac, 0xff, 0xff, 0xff, + 0xf6, 0xb4, 0x69, 0x1e, 0x0, 0xec, 0xd4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xac, 0xff, 0x9a, 0x4a, + 0x8, 0x0, 0x0, 0x0, 0x0, 0xec, 0xd4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xac, 0xff, 0x14, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xec, 0xd4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xac, 0xff, 0x14, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xec, 0xd4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xac, 0xff, 0x14, 0x0, + 0x0, 0x0, 0x8, 0x4b, 0x58, 0xf1, 0xd4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xac, 0xff, 0x14, 0x0, + 0x0, 0x1c, 0xe1, 0xff, 0xff, 0xff, 0xd4, 0x0, + 0x0, 0x18, 0x7c, 0x9b, 0xda, 0xff, 0x14, 0x0, + 0x0, 0x58, 0xff, 0xff, 0xff, 0xff, 0xc4, 0x0, + 0x9, 0xe4, 0xff, 0xff, 0xff, 0xff, 0x14, 0x0, + 0x0, 0x9, 0xa5, 0xfc, 0xff, 0xda, 0x39, 0x0, + 0x11, 0xf9, 0xff, 0xff, 0xff, 0xee, 0x5, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x11, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0xb6, 0xd4, 0xaf, 0x32, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F008 "" */ + 0x51, 0x0, 0x1e, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x42, 0x0, 0x51, 0x0, 0x0, + 0xf8, 0xa2, 0xbe, 0xff, 0xd9, 0xd0, 0xd0, 0xd0, + 0xd0, 0xd0, 0xfb, 0xd7, 0xa1, 0xf7, 0x0, 0x0, + 0xed, 0x42, 0x74, 0xff, 0x14, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xcc, 0xa9, 0x41, 0xec, 0x0, 0x0, + 0xe5, 0x2, 0x43, 0xff, 0x14, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xcc, 0x8a, 0x1, 0xe4, 0x0, 0x0, + 0xff, 0xe2, 0xed, 0xff, 0x16, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xce, 0xf5, 0xe1, 0xff, 0x0, 0x0, + 0xe1, 0x0, 0x3d, 0xff, 0xee, 0xe8, 0xe8, 0xe8, + 0xe8, 0xe8, 0xfe, 0x85, 0x0, 0xe1, 0x0, 0x0, + 0xf1, 0x62, 0x8d, 0xff, 0x7a, 0x68, 0x68, 0x68, + 0x68, 0x68, 0xe7, 0xb8, 0x61, 0xf0, 0x0, 0x0, + 0xf5, 0x82, 0xa5, 0xff, 0x14, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xcc, 0xc8, 0x81, 0xf4, 0x0, 0x0, + 0xe0, 0x0, 0x3c, 0xff, 0x14, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xcc, 0x84, 0x0, 0xe0, 0x0, 0x0, + 0xfd, 0xc2, 0xd6, 0xff, 0x64, 0x50, 0x50, 0x50, + 0x50, 0x50, 0xe2, 0xe6, 0xc1, 0xfc, 0x0, 0x0, + 0xc9, 0x22, 0x5c, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x99, 0x21, 0xc9, 0x0, 0x0, + + /* U+F00B "" */ + 0x56, 0x74, 0x74, 0x5e, 0x0, 0x5c, 0x74, 0x74, + 0x74, 0x74, 0x74, 0x74, 0x74, 0x56, 0x0, 0x0, + 0xfd, 0xff, 0xff, 0xff, 0x1b, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0x20, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xe7, 0xff, 0xff, 0xf0, 0xf, 0xee, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0x0, 0x0, + 0x9, 0x18, 0x18, 0xb, 0x0, 0xa, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x9, 0x0, 0x0, + 0xe6, 0xff, 0xff, 0xef, 0xe, 0xec, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe5, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0x20, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0x1e, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0x6b, 0x8c, 0x8c, 0x75, 0x0, 0x72, 0x8c, 0x8c, + 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x6b, 0x0, 0x0, + 0x6d, 0x8c, 0x8c, 0x76, 0x0, 0x73, 0x8c, 0x8c, + 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x6c, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0x1e, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0x20, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xd4, 0xf4, 0xf4, 0xde, 0xc, 0xdb, 0xf4, 0xf4, + 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xd4, 0x0, 0x0, + + /* U+F00C "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x16, 0x54, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x18, 0xd7, 0xff, 0x8c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0xd7, 0xff, 0xff, 0xd9, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x18, 0xd7, 0xff, 0xff, 0xe3, 0x23, 0x0, 0x0, + 0x28, 0xd4, 0x6d, 0x0, 0x0, 0x0, 0x0, 0x18, + 0xd7, 0xff, 0xff, 0xe2, 0x23, 0x0, 0x0, 0x0, + 0xde, 0xff, 0xff, 0x6f, 0x0, 0x0, 0x18, 0xd7, + 0xff, 0xff, 0xe2, 0x22, 0x0, 0x0, 0x0, 0x0, + 0x83, 0xff, 0xff, 0xff, 0x6f, 0x18, 0xd7, 0xff, + 0xff, 0xe1, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x84, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, + 0xe1, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x82, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x80, 0xff, 0xff, 0xe0, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x79, 0xd0, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F00D "" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x72, 0xf3, 0x64, 0x0, 0x0, 0x0, 0x9, 0xb4, + 0xe3, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe5, 0xff, 0xfe, 0x64, 0x0, 0x9, 0xba, 0xff, + 0xff, 0x84, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4b, 0xf9, 0xff, 0xfe, 0x6c, 0xba, 0xff, 0xff, + 0xd0, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4b, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xd0, + 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x54, 0xff, 0xff, 0xff, 0xe0, 0x13, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xba, 0xff, 0xff, 0xff, 0xfe, 0x64, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xba, 0xff, 0xff, 0xd9, 0xf9, 0xff, 0xfe, + 0x64, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb0, 0xff, 0xff, 0xd0, 0x13, 0x4b, 0xf9, 0xff, + 0xfe, 0x51, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xcf, 0xff, 0xd0, 0x13, 0x0, 0x0, 0x4b, 0xf9, + 0xff, 0x6f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0x76, 0x12, 0x0, 0x0, 0x0, 0x0, 0x3c, + 0x66, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F011 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0x16, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0x0, 0xe, 0xfb, 0xfb, + 0xe, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6e, 0xf5, 0x2d, 0x18, 0xff, 0xff, + 0x18, 0x2d, 0xf5, 0x78, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x64, 0xff, 0xff, 0x65, 0x18, 0xff, 0xff, + 0x18, 0x68, 0xff, 0xff, 0x64, 0x0, 0x0, 0x0, + 0x13, 0xf3, 0xff, 0x99, 0x1, 0x18, 0xff, 0xff, + 0x18, 0x1, 0x9d, 0xff, 0xf2, 0x12, 0x0, 0x0, + 0x6f, 0xff, 0xe2, 0x7, 0x0, 0x18, 0xff, 0xff, + 0x18, 0x0, 0x9, 0xe5, 0xff, 0x6c, 0x0, 0x0, + 0xad, 0xff, 0x8f, 0x0, 0x0, 0x18, 0xff, 0xff, + 0x18, 0x0, 0x0, 0x8f, 0xff, 0xa8, 0x0, 0x0, + 0xc1, 0xff, 0x6e, 0x0, 0x0, 0x18, 0xff, 0xff, + 0x18, 0x0, 0x0, 0x6f, 0xff, 0xc0, 0x0, 0x0, + 0xa9, 0xff, 0x85, 0x0, 0x0, 0x4, 0xa9, 0xa9, + 0x4, 0x0, 0x0, 0x87, 0xff, 0xb1, 0x0, 0x0, + 0x78, 0xff, 0xd8, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xd9, 0xff, 0x7a, 0x0, 0x0, + 0x17, 0xfa, 0xff, 0x83, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x86, 0xff, 0xf8, 0x1f, 0x0, 0x0, + 0x0, 0x76, 0xff, 0xff, 0x9e, 0x1f, 0x0, 0x0, + 0x20, 0xa1, 0xff, 0xff, 0x7c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x91, 0xff, 0xff, 0xff, 0xe7, 0xe7, + 0xff, 0xff, 0xff, 0x95, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x50, 0xcb, 0xff, 0xff, 0xff, + 0xff, 0xd8, 0x57, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x44, 0x49, + 0x26, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F013 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa0, 0xf9, 0xf9, + 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0xc9, 0xff, 0xff, + 0xc9, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3e, 0xd0, 0x68, 0xd5, 0xff, 0xff, 0xff, + 0xff, 0xd6, 0x68, 0xd3, 0x3f, 0x0, 0x0, 0x0, + 0x7, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe3, 0x7, 0x0, 0x0, + 0x5d, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xaa, 0xaa, + 0xfa, 0xff, 0xff, 0xff, 0xff, 0x5d, 0x0, 0x0, + 0x12, 0xa0, 0xff, 0xff, 0xff, 0x46, 0x0, 0x0, + 0x46, 0xff, 0xff, 0xff, 0xa0, 0x12, 0x0, 0x0, + 0x0, 0x39, 0xff, 0xff, 0xdf, 0x0, 0x0, 0x0, + 0x0, 0xdf, 0xff, 0xff, 0x39, 0x0, 0x0, 0x0, + 0x0, 0x44, 0xff, 0xff, 0xf3, 0xb, 0x0, 0x0, + 0xb, 0xf3, 0xff, 0xff, 0x43, 0x0, 0x0, 0x0, + 0x4c, 0xf7, 0xff, 0xff, 0xff, 0xb4, 0x29, 0x29, + 0xb4, 0xff, 0xff, 0xff, 0xf7, 0x4c, 0x0, 0x0, + 0x29, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x29, 0x0, 0x0, + 0x0, 0x98, 0xff, 0xe4, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe4, 0xff, 0x9a, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x53, 0x1, 0x57, 0xe9, 0xff, 0xff, + 0xe9, 0x57, 0x1, 0x51, 0x9, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xff, 0xff, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x7c, 0x7c, + 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F015 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32, + 0x1f, 0x0, 0x0, 0x38, 0x4c, 0x12, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x90, 0xff, + 0xf6, 0x57, 0x0, 0xd7, 0xff, 0x57, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x11, 0xba, 0xff, 0xdd, + 0xf0, 0xff, 0x83, 0xd9, 0xff, 0x58, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x28, 0xda, 0xff, 0xb2, 0x1d, + 0x2c, 0xd9, 0xff, 0xff, 0xff, 0x58, 0x0, 0x0, + 0x0, 0x0, 0x49, 0xf0, 0xff, 0x89, 0x36, 0xe5, + 0xc3, 0x26, 0xba, 0xff, 0xff, 0x5c, 0x0, 0x0, + 0x0, 0x74, 0xfd, 0xf8, 0x5c, 0x58, 0xf6, 0xff, + 0xff, 0xe0, 0x32, 0x92, 0xff, 0xeb, 0x40, 0x0, + 0x9f, 0xff, 0xe7, 0x39, 0x84, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf4, 0x50, 0x65, 0xfa, 0xfb, 0x62, + 0xa3, 0xcd, 0x28, 0xaf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x7b, 0x3f, 0xeb, 0x63, + 0x3, 0x7, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xa, 0x0, + 0x0, 0x0, 0x60, 0xff, 0xff, 0xff, 0xd0, 0x74, + 0x76, 0xf0, 0xff, 0xff, 0xff, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x60, 0xff, 0xff, 0xff, 0x90, 0x0, + 0x0, 0xd0, 0xff, 0xff, 0xff, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x60, 0xff, 0xff, 0xff, 0x90, 0x0, + 0x0, 0xd0, 0xff, 0xff, 0xff, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x4d, 0xf3, 0xf4, 0xf4, 0x7b, 0x0, + 0x0, 0xb8, 0xf4, 0xf4, 0xef, 0x15, 0x0, 0x0, + + /* U+F019 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x30, 0x30, + 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb4, 0xff, 0xff, + 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xff, 0xff, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xff, 0xff, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xff, 0xff, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xff, 0xff, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8d, 0xf0, 0xf0, 0xfc, 0xff, 0xff, + 0xfc, 0xf0, 0xf0, 0x8c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x21, 0xe1, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe3, 0x23, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x21, 0xe0, 0xff, 0xff, 0xff, + 0xff, 0xe2, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x20, 0xdf, 0xff, 0xff, + 0xe1, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x71, 0x90, 0x90, 0x90, 0x82, 0x26, 0xde, 0xe0, + 0x28, 0x82, 0x90, 0x90, 0x90, 0x70, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xb8, 0x21, 0x22, + 0xb9, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xf3, + 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xa1, 0xbb, 0x3d, 0xcd, 0xff, 0x0, 0x0, + 0xa4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, + 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xa4, 0x0, 0x0, + + /* U+F01C "" */ + 0x0, 0x0, 0x0, 0x67, 0xb2, 0xb4, 0xb4, 0xb4, + 0xb4, 0xb4, 0xb4, 0xab, 0x3d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x47, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xef, 0x19, 0x0, 0x0, + 0x0, 0xd, 0xe1, 0xfa, 0x33, 0xc, 0xc, 0xc, + 0xc, 0xc, 0xc, 0x67, 0xff, 0xb0, 0x0, 0x0, + 0x0, 0x97, 0xff, 0x85, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xc2, 0xff, 0x58, 0x0, + 0x40, 0xfe, 0xdc, 0x8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2a, 0xf9, 0xeb, 0x14, + 0xd1, 0xff, 0x82, 0x40, 0x40, 0x21, 0x0, 0x0, + 0x0, 0x0, 0x32, 0x40, 0x40, 0xb2, 0xff, 0x91, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x2, 0x0, + 0x0, 0x1e, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xbf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9b, 0x80, + 0x80, 0xbc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbd, + 0x9e, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x61, + + /* U+F021 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, + 0x0, 0x0, 0x0, 0x0, 0x34, 0x39, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x18, 0x89, 0xd8, 0xfb, 0xfa, + 0xcc, 0x6a, 0x9, 0x0, 0xea, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x4a, 0xed, 0xff, 0xff, 0xfa, 0xfc, + 0xff, 0xff, 0xe8, 0x48, 0xdf, 0xff, 0x0, 0x0, + 0x0, 0x44, 0xfa, 0xff, 0xb7, 0x38, 0x2, 0x6, + 0x45, 0xc2, 0xff, 0xfb, 0xf5, 0xff, 0x0, 0x0, + 0x9, 0xe5, 0xff, 0x97, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x3, 0x8c, 0xff, 0xff, 0xff, 0x0, 0x0, + 0x62, 0xff, 0xcf, 0x2, 0x0, 0x0, 0x0, 0x1c, + 0xff, 0xfe, 0xf6, 0xff, 0xff, 0xff, 0x0, 0x0, + 0x86, 0xe0, 0x54, 0x0, 0x0, 0x0, 0x0, 0x16, + 0xdd, 0xe0, 0xe0, 0xe0, 0xe0, 0xd8, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x21, 0x28, 0x28, 0x28, 0x28, 0x25, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0x28, 0x14, 0x0, 0x0, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x0, + 0x0, 0x0, 0x0, 0x81, 0xff, 0x8e, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xba, 0xb7, 0xc1, 0x13, 0x0, + 0x0, 0x0, 0x17, 0xea, 0xff, 0x41, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xc2, 0x17, 0x0, 0x0, 0x0, + 0x0, 0x17, 0xd1, 0xff, 0xc1, 0x0, 0x0, 0x0, + 0xff, 0xea, 0xe0, 0xff, 0xee, 0x8a, 0x49, 0x44, + 0x81, 0xec, 0xff, 0xe2, 0x1e, 0x0, 0x0, 0x0, + 0xff, 0xe1, 0x19, 0xab, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xc1, 0x1e, 0x0, 0x0, 0x0, 0x0, + 0xf1, 0xde, 0x0, 0x0, 0x2b, 0x83, 0xb0, 0xb6, + 0x92, 0x43, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F026 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x73, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x21, 0xe1, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x20, 0xe0, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd4, 0xf4, 0xf4, 0xfa, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x33, 0x4c, 0x4c, 0x72, 0xfd, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x5d, 0xfd, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d, 0xcd, 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, + + /* U+F027 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x73, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x21, 0xe1, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x20, 0xe0, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd4, 0xf4, 0xf4, 0xfa, 0xff, 0xff, 0xff, 0x0, + 0x2d, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x8d, 0xea, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x4, 0xe6, 0x73, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x33, 0xf8, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x8d, 0x9b, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x33, 0x4c, 0x4c, 0x72, 0xfd, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x5b, 0xfd, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, 0xcc, 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, + + /* U+F028 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7b, 0x7b, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x73, 0x0, + 0x0, 0x0, 0x0, 0x50, 0xf8, 0xa2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x21, 0xe1, 0xff, 0x0, + 0x0, 0xd, 0x84, 0x11, 0x40, 0xfb, 0x69, 0x0, + 0x0, 0x0, 0x0, 0x20, 0xe0, 0xff, 0xff, 0x0, + 0x0, 0x12, 0xdf, 0xd8, 0xd, 0x7f, 0xf1, 0xb, + 0xd4, 0xf4, 0xf4, 0xfa, 0xff, 0xff, 0xff, 0x0, + 0x32, 0x28, 0x1b, 0xe9, 0x8f, 0xf, 0xf5, 0x61, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x8c, 0xed, 0x21, 0x73, 0xef, 0x1, 0xb5, 0x9c, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x3, 0xe5, 0x74, 0x3d, 0xff, 0x16, 0x96, 0xba, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x38, 0xf9, 0x56, 0x4f, 0xff, 0x9, 0x9d, 0xac, + 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x88, 0x96, 0x1, 0xae, 0xc6, 0x0, 0xd2, 0x87, + 0x33, 0x4c, 0x4c, 0x72, 0xfd, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x78, 0xfe, 0x48, 0x34, 0xff, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x5d, 0xfd, 0xff, 0x0, + 0x0, 0x20, 0xfa, 0x6c, 0x7, 0xc8, 0xbe, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d, 0xcd, 0x0, + 0x0, 0x0, 0xa, 0xc, 0xbd, 0xf0, 0x1f, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9f, 0xe5, 0x34, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x22, 0x16, 0x0, 0x0, 0x0, + + /* U+F03E "" */ + 0x32, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7d, 0x30, 0x0, 0x0, + 0xea, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe9, 0x0, 0x0, + 0xff, 0xe6, 0x32, 0x26, 0xd4, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xff, 0x94, 0x0, 0x0, 0x74, 0xff, 0xff, 0xff, + 0xff, 0xd5, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xff, 0xda, 0x16, 0xd, 0xc4, 0xff, 0xff, 0xff, + 0xab, 0x4, 0x71, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xff, 0xff, 0xfb, 0xf1, 0xfd, 0xff, 0xff, 0xab, + 0x4, 0x0, 0x0, 0x71, 0xff, 0xff, 0x0, 0x0, + 0xff, 0xff, 0xf3, 0x3c, 0x55, 0xfb, 0xab, 0x4, + 0x0, 0x0, 0x0, 0x0, 0xc4, 0xff, 0x0, 0x0, + 0xff, 0xf4, 0x3c, 0x0, 0x0, 0x3b, 0x4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc0, 0xff, 0x0, 0x0, + 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc0, 0xff, 0x0, 0x0, + 0xfd, 0xf0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, + 0xc0, 0xc0, 0xc0, 0xc0, 0xf0, 0xfd, 0x0, 0x0, + 0xa1, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfd, 0x9e, 0x0, 0x0, + + /* U+F043 "" */ + 0x0, 0x0, 0x0, 0x0, 0x21, 0xd, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x11, 0xf4, 0xa6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x69, 0xff, 0xf8, 0x11, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xda, 0xff, 0xff, 0x7f, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x67, 0xff, 0xff, 0xff, 0xf1, 0x18, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0xee, 0xff, 0xff, 0xff, 0xff, 0xac, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x62, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x53, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xed, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x63, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf5, 0xec, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x94, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf1, 0xdb, 0x41, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb7, 0xfe, 0x41, 0x9d, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x56, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3d, 0xfd, 0xec, 0x5b, 0x24, 0xe0, 0xff, 0xff, + 0xd4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x63, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xdb, + 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x28, 0x8e, 0xb8, 0xaf, 0x6e, 0xa, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F048 "" */ + 0x1, 0x49, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x30, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x13, 0xff, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x6a, + 0xfd, 0x9e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0xff, 0xe4, 0x0, 0x0, 0x0, 0x7d, 0xff, + 0xff, 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0xff, 0xe4, 0x0, 0x1, 0x91, 0xff, 0xff, + 0xff, 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0xff, 0xe4, 0x4, 0xa3, 0xff, 0xff, 0xff, + 0xff, 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0xff, 0xe9, 0xb3, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0xff, 0xe4, 0x68, 0xfd, 0xff, 0xff, 0xff, + 0xff, 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0xff, 0xe4, 0x0, 0x55, 0xf9, 0xff, 0xff, + 0xff, 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0xff, 0xe4, 0x0, 0x0, 0x44, 0xf3, 0xff, + 0xff, 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0xff, 0xe4, 0x0, 0x0, 0x0, 0x35, 0xeb, + 0xff, 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0xf1, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x28, + 0xd6, 0x74, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F04B "" */ + 0xb, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xce, 0xff, 0xbe, 0x2c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xfb, 0x90, 0xf, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe9, 0x62, 0x1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, + 0x35, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0x9c, 0x15, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xef, 0x65, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x2a, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xdb, 0xe, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf8, 0x86, 0xa, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xb4, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x4b, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xf4, 0x7a, 0x7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf5, 0xff, 0xff, 0xa9, 0x1c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x60, 0xac, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F04C "" */ + 0x12, 0x49, 0x4c, 0x4b, 0x22, 0x0, 0x0, 0x12, + 0x49, 0x4c, 0x4b, 0x22, 0x0, 0x0, 0x0, 0x0, + 0xd6, 0xff, 0xff, 0xff, 0xf7, 0x1d, 0x0, 0xd6, + 0xff, 0xff, 0xff, 0xf7, 0x1d, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x3f, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xfd, 0xff, 0xff, 0xff, 0xff, 0x3c, 0x0, 0xfd, + 0xff, 0xff, 0xff, 0xff, 0x3c, 0x0, 0x0, 0x0, + 0x95, 0xf1, 0xf4, 0xf3, 0xc4, 0xa, 0x0, 0x95, + 0xf1, 0xf4, 0xf3, 0xc4, 0xa, 0x0, 0x0, 0x0, + + /* U+F04D "" */ + 0x12, 0x49, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, + 0x4c, 0x4c, 0x4b, 0x22, 0x0, 0x0, 0x0, 0x0, + 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf7, 0x1d, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x3f, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x3c, 0x0, 0x0, 0x0, + 0x95, 0xf1, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, + 0xf4, 0xf4, 0xf3, 0xc4, 0xa, 0x0, 0x0, 0x0, + + /* U+F051 "" */ + 0x0, 0x2b, 0x15, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x4b, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xf7, 0xe3, 0x29, 0x0, 0x0, 0x0, 0x3f, + 0xff, 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xff, 0xff, 0xec, 0x37, 0x0, 0x0, 0x40, + 0xff, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xff, 0xff, 0xff, 0xf4, 0x46, 0x0, 0x40, + 0xff, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x57, 0x40, + 0xff, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xa6, + 0xff, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0xff, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xde, 0x63, + 0xff, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x19, 0x40, + 0xff, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xff, 0xff, 0xff, 0xc6, 0x11, 0x0, 0x40, + 0xff, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xff, 0xff, 0xb8, 0xa, 0x0, 0x0, 0x40, + 0xff, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xcb, 0xa1, 0x5, 0x0, 0x0, 0x0, 0x36, + 0xf3, 0xa8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F052 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x2f, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x34, 0xf2, 0xfe, + 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x27, 0xeb, 0xff, 0xff, + 0xfd, 0x55, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1c, 0xe1, 0xff, 0xff, 0xff, + 0xff, 0xf9, 0x43, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x12, 0xd5, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf3, 0x34, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xeb, 0x27, 0x0, 0x0, 0x0, + 0x0, 0xab, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe0, 0xa, 0x0, 0x0, + 0x0, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x28, 0x0, 0x0, + 0x0, 0x3c, 0x90, 0x94, 0x94, 0x94, 0x94, 0x94, + 0x94, 0x94, 0x94, 0x93, 0x5e, 0x0, 0x0, 0x0, + 0x0, 0x5e, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, + 0x8c, 0x8c, 0x8c, 0x8c, 0x7c, 0x6, 0x0, 0x0, + 0x0, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0x0, 0x0, + 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, + 0x0, 0xbc, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, + 0xf4, 0xf4, 0xf4, 0xf4, 0xdf, 0x1d, 0x0, 0x0, + + /* U+F053 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0xf1, 0x99, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3a, 0xf2, 0xff, 0xcd, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3b, 0xf2, 0xff, 0xd4, 0x16, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3b, 0xf3, 0xff, 0xd4, 0x16, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3c, 0xf3, 0xff, 0xd3, 0x15, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0xf3, 0xff, 0xda, 0x15, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xc8, 0xff, 0xf8, 0x48, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xc8, 0xff, 0xf8, 0x49, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0xc7, 0xff, 0xf8, 0x49, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0xc7, 0xff, 0xf8, 0x4a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe, 0xc6, 0xff, 0xe6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xa5, 0x4c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F054 "" */ + 0x0, 0x5, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xce, 0xd4, 0x16, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0xf1, 0xff, 0xd5, 0x17, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x37, 0xf1, 0xff, 0xd5, 0x17, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x37, 0xf1, 0xff, 0xd6, 0x17, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x37, 0xf1, 0xff, 0xd6, 0x18, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x37, 0xf8, 0xff, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7f, 0xff, 0xff, 0x91, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7f, 0xff, 0xff, 0x95, 0x1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7f, 0xff, 0xff, 0x95, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7f, 0xff, 0xff, 0x94, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x25, 0xff, 0xff, 0x94, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7b, 0x83, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F067 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4b, 0x5a, 0x8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x22, 0xff, 0xff, 0x67, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x30, 0xff, 0xff, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x30, 0xff, 0xff, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x30, 0xff, 0xff, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x61, 0x90, 0x90, 0x90, 0xa5, 0xff, 0xff, 0xc1, + 0x90, 0x90, 0x90, 0x80, 0x6, 0x0, 0x0, 0x0, + 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x3d, 0x0, 0x0, 0x0, + 0xd4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf4, 0x24, 0x0, 0x0, 0x0, + 0x3, 0x10, 0x10, 0x10, 0x3d, 0xff, 0xff, 0x79, + 0x10, 0x10, 0x10, 0x7, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x30, 0xff, 0xff, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x30, 0xff, 0xff, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x30, 0xff, 0xff, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb, 0xc6, 0xd6, 0x38, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F068 "" */ + 0x65, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, + 0x94, 0x94, 0x94, 0x84, 0x7, 0x0, 0x0, 0x0, + 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x3d, 0x0, 0x0, 0x0, + 0xd1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf2, 0x23, 0x0, 0x0, 0x0, + 0x2, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, + 0xc, 0xc, 0xc, 0x5, 0x0, 0x0, 0x0, 0x0, + + /* U+F06E "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x53, 0x6c, + 0x68, 0x47, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x39, 0xbc, 0xfe, 0xff, 0xe5, + 0xed, 0xff, 0xf7, 0x9e, 0x1d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x73, 0xfd, 0xff, 0xaa, 0x1f, 0x0, + 0x0, 0x39, 0xd2, 0xff, 0xed, 0x42, 0x0, 0x0, + 0x0, 0x8f, 0xff, 0xff, 0xae, 0x0, 0x0, 0x96, + 0xbf, 0x41, 0x12, 0xe0, 0xff, 0xfb, 0x53, 0x0, + 0x4e, 0xff, 0xff, 0xff, 0x29, 0x0, 0x0, 0xbc, + 0xff, 0xf7, 0x25, 0x6a, 0xff, 0xff, 0xef, 0x1e, + 0xe6, 0xff, 0xff, 0xf7, 0x0, 0x9a, 0xcc, 0xff, + 0xff, 0xff, 0x6d, 0x37, 0xff, 0xff, 0xff, 0xa6, + 0xb4, 0xff, 0xff, 0xfd, 0x8, 0x9a, 0xff, 0xff, + 0xff, 0xff, 0x52, 0x46, 0xff, 0xff, 0xff, 0x6e, + 0x1e, 0xec, 0xff, 0xff, 0x58, 0x1c, 0xdf, 0xff, + 0xff, 0xb5, 0x2, 0x9b, 0xff, 0xff, 0xbb, 0x1, + 0x0, 0x37, 0xef, 0xff, 0xe9, 0x29, 0xc, 0x4c, + 0x3f, 0x1, 0x59, 0xfe, 0xff, 0xc5, 0x15, 0x0, + 0x0, 0x0, 0x21, 0xc1, 0xff, 0xf5, 0x91, 0x58, + 0x60, 0xac, 0xfe, 0xfe, 0x9b, 0x7, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x45, 0x9f, 0xdc, 0xf6, + 0xf5, 0xd4, 0x94, 0x2f, 0x0, 0x0, 0x0, 0x0, + + /* U+F070 "" */ + 0xc, 0xc, 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, + 0xc6, 0xdb, 0x2e, 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, + 0x80, 0xfe, 0xf6, 0x5f, 0x0, 0x0, 0x16, 0x4e, + 0x6b, 0x67, 0x43, 0xb, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4a, 0xed, 0xff, 0xa5, 0xc1, 0xff, 0xff, + 0xeb, 0xf0, 0xff, 0xf3, 0x95, 0x16, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1f, 0xcb, 0xff, 0xff, 0xac, 0x1f, + 0x0, 0x1, 0x41, 0xdb, 0xff, 0xe6, 0x37, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x3, 0x6, 0x96, 0xff, 0xf1, 0x52, + 0xae, 0xb8, 0x32, 0x19, 0xe8, 0xff, 0xf8, 0x47, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7c, 0xbf, 0x17, 0x0, 0x5a, 0xf4, 0xff, + 0xf3, 0xff, 0xed, 0x14, 0x76, 0xff, 0xff, 0xea, + 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf, 0xf9, 0xff, 0xe5, 0x3c, 0x0, 0x2a, 0xd7, + 0xff, 0xff, 0xff, 0x51, 0x44, 0xff, 0xff, 0xff, + 0x9b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xca, 0xff, 0xff, 0xed, 0x0, 0x0, 0xc, + 0xa7, 0xff, 0xff, 0x64, 0x58, 0xff, 0xff, 0xff, + 0x69, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x25, 0xf4, 0xff, 0xff, 0x43, 0x0, 0x0, + 0x0, 0x6c, 0xf9, 0xfd, 0xe0, 0xff, 0xff, 0xb3, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x46, 0xf0, 0xff, 0xdd, 0x1c, 0x0, + 0x0, 0x0, 0x37, 0xe1, 0xff, 0xff, 0xc8, 0xd, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x28, 0xd3, 0xff, 0xee, 0x8a, + 0x59, 0x44, 0x0, 0x13, 0xb7, 0xff, 0xe0, 0x35, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x57, 0xaf, 0xe5, + 0xfb, 0xf2, 0x62, 0x0, 0x1, 0x7e, 0xfd, 0xf9, + 0x6c, 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, 0x44, 0xea, + 0xff, 0x6e, 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, 0x1c, + 0xa1, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F071 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 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, 0x31, + 0xed, 0xd1, 0xf, 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, 0x1, 0xc9, + 0xff, 0xff, 0x8f, 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, 0x61, 0xff, + 0xff, 0xff, 0xfb, 0x29, 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, 0xe, 0xe8, 0xff, + 0xff, 0xff, 0xff, 0xba, 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, 0x8c, 0xff, 0xf3, + 0xc4, 0xc7, 0xff, 0xff, 0x4f, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x27, 0xfa, 0xff, 0xb2, + 0x0, 0x0, 0xf2, 0xff, 0xdd, 0x7, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb7, 0xff, 0xff, 0xc1, + 0x0, 0x2, 0xfe, 0xff, 0xff, 0x7a, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4d, 0xff, 0xff, 0xff, 0xd0, + 0x0, 0x11, 0xff, 0xff, 0xff, 0xf4, 0x1b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0xdb, 0xff, 0xff, 0xff, 0xe3, + 0x1, 0x25, 0xff, 0xff, 0xff, 0xff, 0xa6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x78, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0x99, 0xb7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1a, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xb2, + 0x0, 0x3, 0xec, 0xff, 0xff, 0xff, 0xff, 0xce, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1, + 0x27, 0x47, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x65, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xaf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x67, 0xc1, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, + 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xba, + 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F074 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x30, 0x69, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7f, 0xff, 0x86, 0x0, 0x0, 0x0, + 0xd1, 0xd8, 0xd8, 0xb4, 0xc, 0x0, 0x0, 0x0, + 0x88, 0xd8, 0xec, 0xff, 0xff, 0x83, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xbc, 0x7, 0x0, 0x79, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xd9, 0x0, 0x0, + 0x51, 0x58, 0x6c, 0xfa, 0xff, 0x48, 0x60, 0xff, + 0xff, 0x8f, 0xac, 0xff, 0xe3, 0x24, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5b, 0x7e, 0x4a, 0xfb, 0xff, + 0x94, 0x0, 0x70, 0xe3, 0x24, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x37, 0xf5, 0xff, 0xab, + 0x2, 0x0, 0x1, 0x7, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x27, 0xec, 0xff, 0xc0, 0x23, + 0x52, 0x0, 0x4c, 0xa1, 0x7, 0x0, 0x0, 0x0, + 0xc, 0x10, 0x23, 0xe0, 0xff, 0xd1, 0x1b, 0xd0, + 0xf9, 0x48, 0x88, 0xff, 0xb7, 0x7, 0x0, 0x0, + 0xfc, 0xff, 0xff, 0xff, 0xe0, 0x19, 0x7, 0xbe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, 0x0, 0x0, + 0xfe, 0xff, 0xff, 0xeb, 0x27, 0x0, 0x0, 0xc, + 0xca, 0xff, 0xff, 0xff, 0xff, 0xbc, 0x0, 0x0, + 0x1a, 0x20, 0x20, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x20, 0x90, 0xff, 0xc3, 0xc, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x55, 0xb2, 0xc, 0x0, 0x0, 0x0, + + /* U+F077 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7b, 0xa9, 0x8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x82, 0xff, 0xff, 0xb9, + 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x81, 0xff, 0xff, 0xff, 0xff, + 0xb9, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x81, 0xff, 0xff, 0x96, 0x56, 0xfb, + 0xff, 0xb8, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x81, 0xff, 0xff, 0x95, 0x1, 0x0, 0x55, + 0xfb, 0xff, 0xb8, 0x8, 0x0, 0x0, 0x0, 0x0, + 0x76, 0xff, 0xff, 0x94, 0x0, 0x0, 0x0, 0x0, + 0x56, 0xfc, 0xff, 0xb5, 0x0, 0x0, 0x0, 0x0, + 0x9b, 0xff, 0x94, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x57, 0xfc, 0xd8, 0x4, 0x0, 0x0, 0x0, + 0x5, 0x44, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x35, 0x15, 0x0, 0x0, 0x0, 0x0, + + /* U+F078 "" */ + 0x40, 0xc5, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0xb3, 0x6f, 0x0, 0x0, 0x0, 0x0, + 0xb7, 0xff, 0xea, 0x2c, 0x0, 0x0, 0x0, 0x0, + 0xe, 0xc7, 0xff, 0xf4, 0x5, 0x0, 0x0, 0x0, + 0x20, 0xe0, 0xff, 0xea, 0x2c, 0x0, 0x0, 0xd, + 0xc6, 0xff, 0xf8, 0x48, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x20, 0xe0, 0xff, 0xea, 0x2c, 0xc, 0xc4, + 0xff, 0xf8, 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x21, 0xe1, 0xff, 0xea, 0xc9, 0xff, + 0xf8, 0x49, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x21, 0xe1, 0xff, 0xff, 0xf8, + 0x49, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x22, 0xe1, 0xf8, 0x4a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0x31, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F079 "" */ + 0x0, 0x0, 0x6, 0x84, 0x34, 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, 0x6, 0xb2, 0xff, 0xf1, 0x39, 0x0, 0x87, + 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0x9f, 0x2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xb4, 0xff, 0xff, 0xff, 0xf2, 0x3b, 0x95, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x14, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8c, 0xff, 0xc7, 0xff, 0xcf, 0xf8, 0xf2, 0xb, + 0xa, 0xc, 0xc, 0xc, 0xc, 0xaf, 0xff, 0x14, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x38, 0x8c, 0x2e, 0xff, 0x98, 0x4a, 0x81, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, 0xff, 0x14, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x28, 0xff, 0x98, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, 0xff, 0x14, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x28, 0xff, 0x98, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x34, 0xe, 0xac, 0xff, 0x14, + 0x3a, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x28, 0xff, 0x98, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1b, 0xfe, 0xca, 0xb9, 0xff, 0x84, + 0xff, 0x83, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x28, 0xff, 0xe1, 0xb4, 0xb4, 0xb4, + 0xb4, 0xb0, 0x3f, 0x96, 0xff, 0xff, 0xff, 0xff, + 0xe0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x17, 0xf8, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xb8, 0x1, 0x95, 0xff, 0xff, 0xdf, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xc, 0xc, 0xc, 0xc, + 0xc, 0xc, 0x3, 0x0, 0x0, 0x8f, 0xd5, 0x1e, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F07B "" */ + 0x32, 0x7d, 0x80, 0x80, 0x80, 0x73, 0x4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xea, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0x4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd3, + 0xc0, 0xc0, 0xc0, 0xc0, 0xbd, 0x62, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x0, 0x0, + 0xa1, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfd, 0x9e, 0x0, 0x0, + + /* U+F093 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xb, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x15, 0xd2, 0xd4, + 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x15, 0xd2, 0xff, 0xff, + 0xd4, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x15, 0xd2, 0xff, 0xff, 0xff, + 0xff, 0xd4, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x15, 0xd2, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xd4, 0x16, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x98, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x97, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0x10, 0x10, 0xc4, 0xff, 0xff, + 0xc4, 0x10, 0x10, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xff, 0xff, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xff, 0xff, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0xff, 0xff, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x71, 0x90, 0x90, 0x90, 0x38, 0xb8, 0xff, 0xff, + 0xb8, 0x39, 0x90, 0x90, 0x90, 0x70, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xb4, 0x24, 0x48, 0x48, + 0x24, 0xb4, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xdc, 0xdc, + 0xef, 0xff, 0xff, 0xfe, 0xff, 0xff, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xa1, 0xbb, 0x3d, 0xcd, 0xff, 0x0, 0x0, + 0xa4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, + 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xa4, 0x0, 0x0, + + /* U+F095 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2c, 0x9, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x40, 0xff, 0xfa, 0xc9, 0x7e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xaf, 0xff, 0xff, 0xff, 0xf5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0xfc, 0xff, 0xff, 0xff, 0xdd, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x60, 0xff, 0xff, 0xff, 0xff, 0xc1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x8e, 0xff, 0xff, 0xff, 0x7e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc5, 0xff, 0xff, 0x32, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x41, 0xff, 0xff, 0xc2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1b, 0xe5, 0xff, 0xff, 0x38, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x41, 0xa2, 0x37, 0x0, 0x0, + 0x20, 0xd4, 0xff, 0xff, 0x8d, 0x0, 0x0, 0x0, + 0x0, 0x5c, 0xd3, 0xff, 0xff, 0xe9, 0x1e, 0x5b, + 0xea, 0xff, 0xff, 0xb5, 0x2, 0x0, 0x0, 0x0, + 0x0, 0xec, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, + 0xff, 0xff, 0xad, 0xa, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf9, 0x7f, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7b, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xa4, + 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x29, 0xb6, 0xa4, 0x8c, 0x53, 0xd, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F0C4 "" */ + 0x0, 0x47, 0x8a, 0x60, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x1a, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x69, 0xff, 0xff, 0xff, 0xa1, 0x0, 0x0, 0x0, + 0x20, 0xd3, 0xff, 0xda, 0x17, 0x0, 0x0, 0x0, + 0xe2, 0xf2, 0x3d, 0xc7, 0xff, 0x1b, 0x0, 0x1b, + 0xde, 0xff, 0xff, 0xa1, 0x1, 0x0, 0x0, 0x0, + 0xee, 0xe1, 0x4, 0xa4, 0xff, 0x2b, 0x16, 0xd8, + 0xff, 0xff, 0xa6, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x9a, 0xff, 0xef, 0xff, 0xff, 0x6d, 0xd2, 0xff, + 0xff, 0xab, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x8f, 0xd4, 0xfd, 0xff, 0xff, 0xff, 0xff, + 0xb0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6e, 0xff, 0xff, 0xff, 0xd5, + 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x47, 0x8c, 0xe7, 0xff, 0xff, 0xff, 0xff, + 0x6f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x69, 0xff, 0xff, 0xff, 0xff, 0xb0, 0xf2, 0xff, + 0xff, 0x6a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe2, 0xf2, 0x3d, 0xc7, 0xff, 0x20, 0x3e, 0xf6, + 0xff, 0xfe, 0x65, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xee, 0xe1, 0x4, 0xa4, 0xff, 0x28, 0x0, 0x46, + 0xf8, 0xff, 0xfe, 0x61, 0x0, 0x0, 0x0, 0x0, + 0x9a, 0xff, 0xef, 0xff, 0xcf, 0x2, 0x0, 0x0, + 0x4e, 0xf7, 0xff, 0xf8, 0x1a, 0x0, 0x0, 0x0, + 0xa, 0x8f, 0xd2, 0xa8, 0x1c, 0x0, 0x0, 0x0, + 0x0, 0x26, 0x63, 0x2a, 0x0, 0x0, 0x0, 0x0, + + /* U+F0C5 "" */ + 0x0, 0x0, 0x0, 0x0, 0xb, 0xc, 0xc, 0xc, + 0x7, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6c, 0xff, 0xff, 0xff, 0xff, + 0x98, 0x88, 0x6f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x84, 0xff, 0xff, 0xff, 0xff, + 0x98, 0x8c, 0xff, 0x6f, 0x0, 0x0, 0x0, 0x0, + 0x80, 0xa0, 0x64, 0x84, 0xff, 0xff, 0xff, 0xff, + 0x9f, 0x50, 0x94, 0x91, 0x5, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xa0, 0x84, 0xff, 0xff, 0xff, 0xff, + 0xf9, 0xc3, 0xc0, 0xc0, 0xf, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xa0, 0x84, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x14, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xa0, 0x84, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x14, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xa0, 0x84, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x14, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xa0, 0x84, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x14, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xa0, 0x84, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x14, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xa0, 0x84, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x14, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xa6, 0x74, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf9, 0xb, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xee, 0x34, 0x1f, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x12, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xbf, + 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F0C7 "" */ + 0x41, 0x95, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, + 0x96, 0x51, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x6a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xd1, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x48, 0xff, 0xfe, 0x69, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0xff, 0xff, 0xfe, 0x3c, 0x0, 0x0, 0x0, + 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0xff, 0xff, 0xff, 0x6b, 0x0, 0x0, 0x0, + 0xff, 0xca, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, + 0x26, 0xff, 0xff, 0xff, 0x6c, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x6c, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xde, 0xc4, 0xfd, + 0xff, 0xff, 0xff, 0xff, 0x6c, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xb8, 0x4, 0x0, 0x50, + 0xff, 0xff, 0xff, 0xff, 0x6c, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0x6c, 0x0, 0x0, 0x3, + 0xfd, 0xff, 0xff, 0xff, 0x6c, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xc3, 0xb, 0x0, 0x62, + 0xff, 0xff, 0xff, 0xff, 0x6c, 0x0, 0x0, 0x0, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0xee, 0xdb, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x68, 0x0, 0x0, 0x0, + 0x90, 0xf1, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, + 0xf4, 0xf4, 0xf4, 0xd5, 0x1e, 0x0, 0x0, 0x0, + + /* U+F0C9 "" */ + 0xc6, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, + 0xd4, 0xd4, 0xd4, 0xd2, 0x28, 0x0, 0x0, 0x0, + 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x3b, 0x0, 0x0, 0x0, + 0x1a, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, + 0x24, 0x24, 0x24, 0x22, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, + 0xc, 0xc, 0xc, 0xa, 0x0, 0x0, 0x0, 0x0, + 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x36, 0x0, 0x0, 0x0, + 0xde, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, + 0xec, 0xec, 0xec, 0xea, 0x2e, 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, + 0xde, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, + 0xec, 0xec, 0xec, 0xea, 0x2e, 0x0, 0x0, 0x0, + 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x36, 0x0, 0x0, 0x0, + 0x7, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, + 0xc, 0xc, 0xc, 0xa, 0x0, 0x0, 0x0, 0x0, + + /* U+F0E0 "" */ + 0x32, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7d, 0x30, 0x0, 0x0, + 0xea, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe9, 0x0, 0x0, + 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1, 0x0, 0x0, + 0x1f, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xc7, 0x1f, 0x0, 0x0, + 0xd2, 0x2d, 0x88, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe, 0x8b, 0x2c, 0xd0, 0x0, 0x0, + 0xff, 0xf5, 0x61, 0x48, 0xe9, 0xff, 0xff, 0xff, + 0xff, 0xea, 0x49, 0x5f, 0xf4, 0xff, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xa6, 0x27, 0xbc, 0xff, 0xff, + 0xba, 0x27, 0xa5, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xdc, 0x35, 0x56, 0x55, + 0x34, 0xdb, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xb9, 0xb8, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x0, 0x0, + 0xa1, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfd, 0x9e, 0x0, 0x0, + + /* U+F0E7 "" */ + 0x0, 0x0, 0x6, 0xc, 0xc, 0xc, 0x6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x17, 0xf7, 0xff, 0xff, 0xff, 0xf8, 0xe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x42, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x64, 0xff, 0xff, 0xff, 0xff, 0x89, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x86, 0xff, 0xff, 0xff, 0xff, 0x37, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa8, 0xff, 0xff, 0xff, 0xff, 0xad, 0xac, + 0xac, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xca, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x8c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xeb, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb8, 0xd4, 0xd4, 0xd9, 0xff, 0xff, 0xff, + 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x41, 0xff, 0xff, 0xd0, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7d, 0xff, 0xff, 0x3f, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb9, 0xff, 0xab, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xf2, 0xf7, 0x1f, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x32, 0xff, 0x82, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3f, 0xcf, 0xa, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F0EA "" */ + 0x0, 0x0, 0x0, 0xa, 0x2b, 0x3, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x41, 0x5c, 0x5e, 0xe1, 0xf3, 0xb9, 0x5c, 0x5c, + 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xfb, 0xff, 0xff, 0xd3, 0x14, 0xff, 0xff, 0xff, + 0xbb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xf2, 0x5c, 0x34, 0x34, 0x34, + 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0x90, 0x77, 0xf3, 0xf4, 0xf4, + 0xb7, 0x59, 0x7e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0x80, 0xa0, 0xff, 0xff, 0xff, + 0xc0, 0x60, 0xff, 0x82, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0x80, 0xa0, 0xff, 0xff, 0xff, + 0xc0, 0x40, 0xac, 0xac, 0x1d, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0x80, 0xa0, 0xff, 0xff, 0xff, + 0xe3, 0x35, 0x2c, 0x2c, 0xb, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0x80, 0xa0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0x80, 0xa0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0xfa, 0xff, 0xff, 0x80, 0xa0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0x39, 0x54, 0x54, 0x2a, 0xa0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x78, 0xf3, 0xf4, 0xf4, + 0xf4, 0xf4, 0xf4, 0xeb, 0x25, 0x0, 0x0, 0x0, + + /* U+F0F3 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x1f, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xab, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x17, 0x84, 0xf0, 0xff, 0xa4, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x25, 0xe1, 0xff, 0xff, 0xff, 0xff, + 0xfa, 0x52, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xbe, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x5e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x54, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x93, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xde, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfd, 0x26, 0x0, 0x0, 0x0, 0x0, + 0x9b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xd4, 0x6, 0x0, 0x0, 0x0, + 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfb, 0x20, 0x0, 0x0, 0x0, + 0xb, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x81, 0xff, 0xff, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd, 0x95, 0xaa, 0x27, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F11C "" */ + 0x59, 0xb1, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, + 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xab, 0x30, + 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb5, + 0xff, 0xc9, 0xc, 0xc1, 0x3a, 0xe, 0xe7, 0x14, + 0x1c, 0xdf, 0xd, 0xdf, 0x1c, 0x14, 0xff, 0xc0, + 0xff, 0xc6, 0x0, 0xbe, 0x30, 0x2, 0xe6, 0x8, + 0x10, 0xdd, 0x1, 0xdd, 0x10, 0x8, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xe7, 0xf0, 0xfa, 0xe0, 0xf5, + 0xf4, 0xe1, 0xfd, 0xe1, 0xef, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x12, 0x5a, 0xa6, 0x0, 0x82, + 0x7e, 0x0, 0xac, 0x0, 0x52, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x3c, 0x79, 0xba, 0x28, 0x9c, + 0x98, 0x28, 0xc3, 0x29, 0x73, 0xff, 0xff, 0xc0, + 0xff, 0xf3, 0xb8, 0xf0, 0xc9, 0xb8, 0xb8, 0xb8, + 0xb8, 0xb8, 0xb9, 0xf9, 0xc1, 0xbe, 0xff, 0xc0, + 0xff, 0xc0, 0x0, 0xb8, 0x28, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd8, 0x8, 0x0, 0xff, 0xc0, + 0xfd, 0xf4, 0xc0, 0xf3, 0xcf, 0xc0, 0xc0, 0xc0, + 0xc0, 0xc0, 0xc1, 0xfa, 0xc8, 0xc6, 0xff, 0xbd, + 0x9e, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x61, + + /* U+F124 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x2b, 0x6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5, 0x5f, 0xd3, 0xff, 0xbf, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x74, 0xe4, 0xff, 0xff, 0xff, 0xde, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0x89, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x77, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2a, 0x9e, 0xf9, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xf, 0x0, + 0x0, 0x0, 0x3e, 0xb3, 0xfe, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x8c, 0x0, 0x0, + 0x0, 0xa2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfa, 0x1c, 0x0, 0x0, + 0x0, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xa1, 0x0, 0x0, 0x0, + 0x0, 0x4d, 0x9d, 0xa0, 0xa0, 0xa0, 0xa0, 0xf4, + 0xff, 0xff, 0xff, 0xff, 0x2d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, + 0xff, 0xff, 0xff, 0xb6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, + 0xff, 0xff, 0xff, 0x41, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, + 0xff, 0xff, 0xcb, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, + 0xff, 0xff, 0x56, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd8, + 0xff, 0xdd, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4a, + 0xb5, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F15B "" */ + 0x3a, 0x54, 0x54, 0x54, 0x54, 0x54, 0xa, 0x2c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0xf8, + 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0xff, + 0xf8, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0xff, + 0xff, 0xf8, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x38, 0x2c, + 0x2c, 0x2c, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xf4, + 0xf4, 0xf4, 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8c, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, + 0xac, 0xaa, 0x37, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F1EB "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x2a, 0x4f, + 0x5e, 0x57, 0x3f, 0x11, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3d, 0xa4, 0xf0, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xcc, 0x74, 0xf, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x24, 0xbc, 0xff, 0xff, 0xff, 0xfe, 0xec, + 0xd7, 0xe1, 0xf7, 0xff, 0xff, 0xff, 0xf1, 0x6d, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x51, 0xf4, 0xff, 0xff, 0xb8, 0x57, 0x12, 0x0, + 0x0, 0x0, 0x1, 0x34, 0x80, 0xeb, 0xff, 0xff, + 0xb5, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd4, 0xff, 0xdb, 0x3a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x8b, 0xfe, + 0xff, 0x54, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0x8c, 0xe, 0x0, 0x2, 0x56, 0xac, 0xe3, + 0xf8, 0xef, 0xcc, 0x87, 0x1e, 0x0, 0x0, 0x4c, + 0x6c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2c, 0xd2, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfa, 0x80, 0x3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xcd, 0xff, 0xf9, 0x9e, 0x54, + 0x37, 0x40, 0x73, 0xd5, 0xff, 0xff, 0x4d, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x24, 0xaa, 0x27, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2, 0x76, 0x7e, 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, 0x24, + 0x90, 0x66, 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, 0xd6, + 0xff, 0xff, 0x54, 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, 0xeb, + 0xff, 0xff, 0x6a, 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, 0x51, + 0xd1, 0xa8, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +}; + + +/*--------------------- + * 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 = 60, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 0, .adv_w = 60, .box_w = 3, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 160, .adv_w = 88, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 240, .adv_w = 157, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 400, .adv_w = 139, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 640, .adv_w = 189, .box_w = 12, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 800, .adv_w = 154, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 976, .adv_w = 47, .box_w = 3, .box_h = 5, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 1056, .adv_w = 75, .box_w = 4, .box_h = 14, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 1280, .adv_w = 76, .box_w = 4, .box_h = 14, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 1504, .adv_w = 90, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 1600, .adv_w = 130, .box_w = 8, .box_h = 7, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 1712, .adv_w = 51, .box_w = 3, .box_h = 5, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1792, .adv_w = 86, .box_w = 5, .box_h = 3, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 1840, .adv_w = 51, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1888, .adv_w = 79, .box_w = 7, .box_h = 14, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 2112, .adv_w = 149, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2272, .adv_w = 83, .box_w = 4, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2432, .adv_w = 129, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2592, .adv_w = 128, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2752, .adv_w = 150, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2912, .adv_w = 129, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3072, .adv_w = 138, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3232, .adv_w = 134, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3392, .adv_w = 144, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3552, .adv_w = 138, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3712, .adv_w = 51, .box_w = 3, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3840, .adv_w = 51, .box_w = 3, .box_h = 11, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 4016, .adv_w = 130, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 4144, .adv_w = 130, .box_w = 8, .box_h = 6, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 4240, .adv_w = 130, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 4368, .adv_w = 128, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4528, .adv_w = 232, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 4736, .adv_w = 164, .box_w = 12, .box_h = 10, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 4896, .adv_w = 170, .box_w = 9, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 5056, .adv_w = 162, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 5216, .adv_w = 185, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 5376, .adv_w = 150, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 5536, .adv_w = 142, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 5696, .adv_w = 173, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 5856, .adv_w = 182, .box_w = 9, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 6016, .adv_w = 69, .box_w = 2, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 6176, .adv_w = 115, .box_w = 7, .box_h = 10, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 6336, .adv_w = 161, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 6496, .adv_w = 133, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 6656, .adv_w = 214, .box_w = 11, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 6816, .adv_w = 182, .box_w = 9, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 6976, .adv_w = 188, .box_w = 12, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 7136, .adv_w = 162, .box_w = 9, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 7296, .adv_w = 188, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 7504, .adv_w = 163, .box_w = 9, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 7664, .adv_w = 139, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 7824, .adv_w = 131, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 7984, .adv_w = 177, .box_w = 9, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 8144, .adv_w = 159, .box_w = 11, .box_h = 10, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 8304, .adv_w = 252, .box_w = 16, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 8464, .adv_w = 151, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 8624, .adv_w = 145, .box_w = 11, .box_h = 10, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 8784, .adv_w = 147, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 8944, .adv_w = 75, .box_w = 4, .box_h = 14, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 9168, .adv_w = 79, .box_w = 7, .box_h = 14, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 9392, .adv_w = 75, .box_w = 4, .box_h = 14, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 9616, .adv_w = 131, .box_w = 7, .box_h = 6, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 9712, .adv_w = 112, .box_w = 7, .box_h = 1, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 9728, .adv_w = 134, .box_w = 5, .box_h = 2, .ofs_x = 1, .ofs_y = 9}, + {.bitmap_index = 9760, .adv_w = 134, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 9888, .adv_w = 153, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 10064, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 10192, .adv_w = 153, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 10368, .adv_w = 137, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 10496, .adv_w = 79, .box_w = 6, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 10672, .adv_w = 155, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 10848, .adv_w = 153, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 11024, .adv_w = 62, .box_w = 2, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 11200, .adv_w = 64, .box_w = 5, .box_h = 14, .ofs_x = -2, .ofs_y = -3}, + {.bitmap_index = 11424, .adv_w = 138, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 11600, .adv_w = 62, .box_w = 2, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 11776, .adv_w = 237, .box_w = 13, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 11904, .adv_w = 153, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 12032, .adv_w = 142, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 12160, .adv_w = 153, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 12336, .adv_w = 153, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 12512, .adv_w = 92, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 12640, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 12768, .adv_w = 93, .box_w = 6, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 12928, .adv_w = 152, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 13056, .adv_w = 125, .box_w = 9, .box_h = 8, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 13184, .adv_w = 201, .box_w = 13, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 13312, .adv_w = 124, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 13440, .adv_w = 125, .box_w = 9, .box_h = 11, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 13616, .adv_w = 117, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 13744, .adv_w = 79, .box_w = 5, .box_h = 14, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 13968, .adv_w = 67, .box_w = 2, .box_h = 14, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 14192, .adv_w = 79, .box_w = 5, .box_h = 14, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 14416, .adv_w = 130, .box_w = 8, .box_h = 3, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 14464, .adv_w = 94, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 6}, + {.bitmap_index = 14544, .adv_w = 70, .box_w = 4, .box_h = 3, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 14592, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 14832, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 15008, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 15216, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 15392, .adv_w = 154, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 15568, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 15808, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 16048, .adv_w = 252, .box_w = 16, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 16256, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 16496, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 16672, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 16912, .adv_w = 112, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 17104, .adv_w = 168, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 17296, .adv_w = 252, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17520, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 17696, .adv_w = 154, .box_w = 10, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17936, .adv_w = 196, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 18160, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18400, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 18608, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 18816, .adv_w = 196, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 19040, .adv_w = 196, .box_w = 14, .box_h = 13, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 19248, .adv_w = 140, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 19456, .adv_w = 140, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 19664, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 19872, .adv_w = 196, .box_w = 13, .box_h = 4, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 19936, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 20112, .adv_w = 280, .box_w = 18, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20592, .adv_w = 252, .box_w = 17, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 21072, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 21280, .adv_w = 196, .box_w = 13, .box_h = 8, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 21408, .adv_w = 196, .box_w = 13, .box_h = 8, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 21536, .adv_w = 280, .box_w = 18, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 21888, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 22064, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22304, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 22544, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 22752, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22992, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 23200, .adv_w = 196, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 23392, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 23568, .adv_w = 140, .box_w = 10, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 23808, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24048, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24288, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 24464, .adv_w = 224, .box_w = 16, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 24704, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24944, .adv_w = 280, .box_w = 18, .box_h = 13, .ofs_x = 0, .ofs_y = -1} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + +static const uint16_t unicode_list_1[] = { + 0x0, 0x1f72, 0xef51, 0xef58, 0xef5b, 0xef5c, 0xef5d, 0xef61, + 0xef63, 0xef65, 0xef69, 0xef6c, 0xef71, 0xef76, 0xef77, 0xef78, + 0xef8e, 0xef93, 0xef98, 0xef9b, 0xef9c, 0xef9d, 0xefa1, 0xefa2, + 0xefa3, 0xefa4, 0xefb7, 0xefb8, 0xefbe, 0xefc0, 0xefc1, 0xefc4, + 0xefc7, 0xefc8, 0xefc9, 0xefcb, 0xefe3, 0xefe5, 0xf014, 0xf015, + 0xf017, 0xf019, 0xf030, 0xf037, 0xf03a, 0xf043, 0xf06c, 0xf074, + 0xf0ab, 0xf13b +}; + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = { + { + .range_start = 32, .range_length = 95, .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 = 176, .range_length = 61756, .glyph_id_start = 96, + .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 50, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + } +}; + +/*----------------- + * KERNING + *----------------*/ + + +/*Map glyph_ids to kern left classes*/ +static const uint8_t kern_left_class_mapping[] = { + 0, 0, 1, 2, 0, 3, 4, 5, + 2, 6, 7, 8, 9, 10, 9, 10, + 11, 12, 0, 13, 14, 15, 16, 17, + 18, 19, 12, 20, 20, 0, 0, 0, + 21, 22, 23, 24, 25, 22, 26, 27, + 28, 29, 29, 30, 31, 32, 29, 29, + 22, 33, 34, 35, 3, 36, 30, 37, + 37, 38, 39, 40, 41, 42, 43, 0, + 44, 0, 45, 46, 47, 48, 49, 50, + 51, 45, 52, 52, 53, 48, 45, 45, + 46, 46, 54, 55, 56, 57, 51, 58, + 58, 59, 58, 60, 41, 0, 0, 9, + 61, 9, 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 +}; + +/*Map glyph_ids to kern right classes*/ +static const uint8_t kern_right_class_mapping[] = { + 0, 0, 1, 2, 0, 3, 4, 5, + 2, 6, 7, 8, 9, 10, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 12, + 18, 19, 20, 21, 21, 0, 0, 0, + 22, 23, 24, 25, 23, 25, 25, 25, + 23, 25, 25, 26, 25, 25, 25, 25, + 23, 25, 23, 25, 3, 27, 28, 29, + 29, 30, 31, 32, 33, 34, 35, 0, + 36, 0, 37, 38, 39, 39, 39, 0, + 39, 38, 40, 41, 38, 38, 42, 42, + 39, 42, 39, 42, 43, 44, 45, 46, + 46, 47, 46, 48, 0, 0, 35, 9, + 49, 9, 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 +}; + +/*Kern values between classes*/ +static const int8_t kern_class_values[] = { + 0, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 2, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 10, 0, 6, -5, 0, 0, + 0, 0, -12, -13, 2, 11, 5, 4, + -9, 2, 11, 1, 9, 2, 7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 13, 2, -2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 0, -7, 0, 0, 0, 0, + 0, -4, 4, 4, 0, 0, -2, 0, + -2, 2, 0, -2, 0, -2, -1, -4, + 0, 0, 0, 0, -2, 0, 0, -3, + -3, 0, 0, -2, 0, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -2, + -2, 0, -3, 0, -6, 0, -27, 0, + 0, -4, 0, 4, 7, 0, 0, -4, + 2, 2, 7, 4, -4, 4, 0, 0, + -13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -6, -3, -11, 0, -9, + -2, 0, 0, 0, 0, 0, 9, 0, + -7, -2, -1, 1, 0, -4, 0, 0, + -2, -17, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -18, -2, 9, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, + 0, 2, 0, 0, -4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 2, + 1, 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, + -8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, + 4, 2, 7, -2, 0, 0, 4, -2, + -7, -31, 2, 6, 4, 0, -3, 0, + 8, 0, 7, 0, 7, 0, -21, 0, + -3, 7, 0, 7, -2, 4, 2, 0, + 0, 1, -2, 0, 0, -4, 18, 0, + 18, 0, 7, 0, 9, 3, 4, 7, + 0, 0, 0, -8, 0, 0, 0, 0, + 1, -2, 0, 2, -4, -3, -4, 2, + 0, -2, 0, 0, 0, -9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -15, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, -12, 0, -14, 0, 0, 0, + 0, -2, 0, 22, -3, -3, 2, 2, + -2, 0, -3, 2, 0, 0, -12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -22, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -14, 0, 13, 0, 0, -8, 0, + 7, 0, -15, -22, -15, -4, 7, 0, + 0, -15, 0, 3, -5, 0, -3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 7, -27, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 11, 0, 2, 0, 0, 0, + 0, 0, 2, 2, -3, -4, 0, -1, + -1, -2, 0, 0, -2, 0, 0, 0, + -4, 0, -2, 0, -5, -4, 0, -6, + -7, -7, -4, 0, -4, 0, -4, 0, + 0, 0, 0, -2, 0, 0, 2, 0, + 2, -2, 0, 1, 0, 0, 0, 2, + -2, 0, 0, 0, -2, 2, 2, -1, + 0, 0, 0, -4, 0, -1, 0, 0, + 0, 0, 0, 1, 0, 3, -2, 0, + -3, 0, -4, 0, 0, -2, 0, 7, + 0, 0, -2, 0, 0, 0, 0, 0, + -1, 1, -2, -2, 0, 0, -2, 0, + -2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -1, -1, 0, -2, -3, 0, + 0, 0, 0, 0, 1, 0, 0, -2, + 0, -2, -2, -2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -1, 0, 0, + 0, 0, -2, -3, 0, -3, 0, -7, + -2, -7, 4, 0, 0, -4, 2, 4, + 6, 0, -6, -1, -3, 0, -1, -11, + 2, -2, 2, -12, 2, 0, 0, 1, + -12, 0, -12, -2, -19, -2, 0, -11, + 0, 4, 6, 0, 3, 0, 0, 0, + 0, 0, 0, -4, -3, 0, -7, 0, + 0, 0, -2, 0, 0, 0, -2, 0, + 0, 0, 0, 0, -1, -1, 0, -1, + -3, 0, 0, 0, 0, 0, 0, 0, + -2, -2, 0, -2, -3, -2, 0, 0, + -2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, -2, 0, -3, + 0, -2, 0, -4, 2, 0, 0, -3, + 1, 2, 2, 0, 0, 0, 0, 0, + 0, -2, 0, 0, 0, 0, 0, 2, + 0, 0, -2, 0, -2, -2, -3, 0, + 0, 0, 0, 0, 0, 0, 2, 0, + -2, 0, 0, 0, 0, -2, -3, 0, + -4, 0, 7, -2, 1, -7, 0, 0, + 6, -11, -12, -9, -4, 2, 0, -2, + -15, -4, 0, -4, 0, -4, 3, -4, + -14, 0, -6, 0, 0, 1, -1, 2, + -2, 0, 2, 0, -7, -9, 0, -11, + -5, -5, -5, -7, -3, -6, 0, -4, + -6, 1, 0, 1, 0, -2, 0, 0, + 0, 2, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -2, + 0, -1, 0, -1, -2, 0, -4, -5, + -5, -1, 0, -7, 0, 0, 0, 0, + 0, 0, -2, 0, 0, 0, 0, 1, + -1, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 11, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, + -2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, 0, 0, + -4, 0, 0, 0, 0, -11, -7, 0, + 0, 0, -3, -11, 0, 0, -2, 2, + 0, -6, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, 0, 0, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, -4, 0, + 0, 0, 0, 3, 0, 2, -4, -4, + 0, -2, -2, -3, 0, 0, 0, 0, + 0, 0, -7, 0, -2, 0, -3, -2, + 0, -5, -6, -7, -2, 0, -4, 0, + -7, 0, 0, 0, 0, 18, 0, 0, + 1, 0, 0, -3, 0, 2, 0, -10, + 0, 0, 0, 0, 0, -21, -4, 7, + 7, -2, -9, 0, 2, -3, 0, -11, + -1, -3, 2, -16, -2, 3, 0, 3, + -8, -3, -8, -7, -9, 0, 0, -13, + 0, 13, 0, 0, -1, 0, 0, 0, + -1, -1, -2, -6, -7, 0, -21, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -2, 0, -1, -2, -3, 0, 0, + -4, 0, -2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -1, 0, -4, 0, 0, 4, + -1, 3, 0, -5, 2, -2, -1, -6, + -2, 0, -3, -2, -2, 0, -3, -4, + 0, 0, -2, -1, -2, -4, -3, 0, + 0, -2, 0, 2, -2, 0, -5, 0, + 0, 0, -4, 0, -4, 0, -4, -4, + 2, 0, 0, 0, 0, 0, 0, 0, + 0, -4, 2, 0, -3, 0, -2, -3, + -7, -2, -2, -2, -1, -2, -3, -1, + 0, 0, 0, 0, 0, -2, -2, -2, + 0, 0, 0, 0, 3, -2, 0, -2, + 0, 0, 0, -2, -3, -2, -2, -3, + -2, 0, 2, 9, -1, 0, -6, 0, + -2, 4, 0, -2, -9, -3, 3, 0, + 0, -11, -4, 2, -4, 2, 0, -2, + -2, -7, 0, -3, 1, 0, 0, -4, + 0, 0, 0, 2, 2, -4, -4, 0, + -4, -2, -3, -2, -2, 0, -4, 1, + -4, -4, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, 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, + -2, 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, -2, -2, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -3, 0, 0, -3, + 0, 0, -2, -2, 0, 0, 0, 0, + -2, 0, 0, 0, 0, -1, 0, 0, + 0, 0, 0, -2, 0, 0, 0, 0, + -3, 0, -4, 0, 0, 0, -7, 0, + 2, -5, 4, 0, -2, -11, 0, 0, + -5, -2, 0, -9, -6, -6, 0, 0, + -10, -2, -9, -9, -11, 0, -6, 0, + 2, 15, -3, 0, -5, -2, -1, -2, + -4, -6, -4, -8, -9, -5, -2, 0, + 0, -2, 0, 1, 0, 0, -16, -2, + 7, 5, -5, -8, 0, 1, -7, 0, + -11, -2, -2, 4, -21, -3, 1, 0, + 0, -15, -3, -12, -2, -16, 0, 0, + -16, 0, 13, 1, 0, -2, 0, 0, + 0, 0, -1, -2, -9, -2, 0, -15, + 0, 0, 0, 0, -7, 0, -2, 0, + -1, -6, -11, 0, 0, -1, -3, -7, + -2, 0, -2, 0, 0, 0, 0, -10, + -2, -7, -7, -2, -4, -6, -2, -4, + 0, -4, -2, -7, -3, 0, -3, -4, + -2, -4, 0, 1, 0, -2, -7, 0, + 4, 0, -4, 0, 0, 0, 0, 3, + 0, 2, -4, 9, 0, -2, -2, -3, + 0, 0, 0, 0, 0, 0, -7, 0, + -2, 0, -3, -2, 0, -5, -6, -7, + -2, 0, -4, 2, 9, 0, 0, 0, + 0, 18, 0, 0, 1, 0, 0, -3, + 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -2, -4, 0, 0, 0, 0, 0, -1, + 0, 0, 0, -2, -2, 0, 0, -4, + -2, 0, 0, -4, 0, 4, -1, 0, + 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 3, 4, 2, -2, 0, -7, + -4, 0, 7, -7, -7, -4, -4, 9, + 4, 2, -19, -2, 4, -2, 0, -2, + 2, -2, -8, 0, -2, 2, -3, -2, + -7, -2, 0, 0, 7, 4, 0, -6, + 0, -12, -3, 6, -3, -9, 1, -3, + -7, -7, -2, 9, 2, 0, -3, 0, + -6, 0, 2, 7, -5, -8, -9, -6, + 7, 0, 1, -16, -2, 2, -4, -2, + -5, 0, -5, -8, -3, -3, -2, 0, + 0, -5, -5, -2, 0, 7, 5, -2, + -12, 0, -12, -3, 0, -8, -13, -1, + -7, -4, -7, -6, 6, 0, 0, -3, + 0, -4, -2, 0, -2, -4, 0, 4, + -7, 2, 0, 0, -12, 0, -2, -5, + -4, -2, -7, -6, -7, -5, 0, -7, + -2, -5, -4, -7, -2, 0, 0, 1, + 11, -4, 0, -7, -2, 0, -2, -4, + -5, -6, -6, -9, -3, -4, 4, 0, + -3, 0, -11, -3, 1, 4, -7, -8, + -4, -7, 7, -2, 1, -21, -4, 4, + -5, -4, -8, 0, -7, -9, -3, -2, + -2, -2, -5, -7, -1, 0, 0, 7, + 6, -2, -15, 0, -13, -5, 5, -9, + -15, -4, -8, -9, -11, -7, 4, 0, + 0, 0, 0, -3, 0, 0, 2, -3, + 4, 2, -4, 4, 0, 0, -7, -1, + 0, -1, 0, 1, 1, -2, 0, 0, + 0, 0, 0, 0, -2, 0, 0, 0, + 0, 2, 7, 0, 0, -3, 0, 0, + 0, 0, -2, -2, -3, 0, 0, 0, + 1, 2, 0, 0, 0, 0, 2, 0, + -2, 0, 9, 0, 4, 1, 1, -3, + 0, 4, 0, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7, 0, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -13, 0, -2, 4, 0, 7, + 0, 0, 22, 3, -4, -4, 2, 2, + -2, 1, -11, 0, 0, 11, -13, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -15, 9, 31, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -13, 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, -4, 0, 0, -4, + -2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, -6, 0, + 0, 1, 0, 0, 2, 29, -4, -2, + 7, 6, -6, 2, 0, 0, 2, 2, + -3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -29, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -6, + 0, 0, 0, -6, 0, 0, 0, 0, + -5, -1, 0, 0, 0, -5, 0, -3, + 0, -11, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -15, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, + 0, -2, 0, 0, -4, 0, -3, 0, + -6, 0, 0, 0, -4, 2, -3, 0, + 0, -6, -2, -5, 0, 0, -6, 0, + -2, 0, -11, 0, -2, 0, 0, -18, + -4, -9, -2, -8, 0, 0, -15, 0, + -6, -1, 0, 0, 0, 0, 0, 0, + 0, 0, -3, -4, -2, -4, 0, 0, + 0, 0, -5, 0, -5, 3, -2, 4, + 0, -2, -5, -2, -4, -4, 0, -3, + -1, -2, 2, -6, -1, 0, 0, 0, + -20, -2, -3, 0, -5, 0, -2, -11, + -2, 0, 0, -2, -2, 0, 0, 0, + 0, 2, 0, -2, -4, -2, 4, 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, 3, 0, 0, 0, 0, 0, + 0, -5, 0, -2, 0, 0, 0, -4, + 2, 0, 0, 0, -6, -2, -4, 0, + 0, -6, 0, -2, 0, -11, 0, 0, + 0, 0, -22, 0, -4, -8, -11, 0, + 0, -15, 0, -2, -3, 0, 0, 0, + 0, 0, 0, 0, 0, -2, -3, -1, + -3, 1, 0, 0, 4, -3, 0, 7, + 11, -2, -2, -7, 3, 11, 4, 5, + -6, 3, 9, 3, 6, 5, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 14, 11, -4, -2, 0, -2, + 18, 10, 18, 0, 0, 0, 2, 0, + 0, 8, 0, 0, -4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -2, 0, + 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 0, -19, -3, -2, -9, + -11, 0, 0, -15, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -2, + 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, -19, -3, -2, + -9, -11, 0, 0, -9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -2, 0, 0, 0, -5, 2, 0, -2, + 2, 4, 2, -7, 0, 0, -2, 2, + 0, 2, 0, 0, 0, 0, -6, 0, + -2, -2, -4, 0, -2, -9, 0, 14, + -2, 0, -5, -2, 0, -2, -4, 0, + -2, -6, -4, -3, 0, 0, 0, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -2, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, -19, + -3, -2, -9, -11, 0, 0, -15, 0, + 0, 0, 0, 0, 0, 11, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -4, 0, -7, -3, -2, 7, -2, -2, + -9, 1, -1, 1, -2, -6, 0, 5, + 0, 2, 1, 2, -5, -9, -3, 0, + -9, -4, -6, -9, -9, 0, -4, -4, + -3, -3, -2, -2, -3, -2, 0, -2, + -1, 3, 0, 3, -2, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -2, -2, -2, 0, 0, + -6, 0, -1, 0, -4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, -2, 0, -3, + 0, 0, 0, 0, -2, 0, 0, -4, + -2, 2, 0, -4, -4, -2, 0, -6, + -2, -5, -2, -3, 0, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -15, 0, 7, 0, 0, -4, 0, + 0, 0, 0, -3, 0, -2, 0, 0, + -1, 0, 0, -2, 0, -5, 0, 0, + 9, -3, -7, -7, 2, 2, 2, 0, + -6, 2, 3, 2, 7, 2, 7, -2, + -6, 0, 0, -9, 0, 0, -7, -6, + 0, 0, -4, 0, -3, -4, 0, -3, + 0, -3, 0, -2, 3, 0, -2, -7, + -2, 8, 0, 0, -2, 0, -4, 0, + 0, 3, -5, 0, 2, -2, 2, 0, + 0, -7, 0, -2, -1, 0, -2, 2, + -2, 0, 0, 0, -9, -3, -5, 0, + -7, 0, 0, -11, 0, 8, -2, 0, + -4, 0, 1, 0, -2, 0, -2, -7, + 0, -2, 2, 0, 0, 0, 0, -2, + 0, 0, 2, -3, 1, 0, 0, -3, + -2, 0, -3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -14, 0, 5, 0, + 0, -2, 0, 0, 0, 0, 0, 0, + -2, -2, 0, 0, 0, 4, 0, 5, + 0, 0, 0, 0, 0, -14, -13, 1, + 10, 7, 4, -9, 2, 9, 0, 8, + 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 12, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 +}; + + +/*Collect the kern class' data in one place*/ +static const lv_font_fmt_txt_kern_classes_t kern_classes = { + .class_pair_values = kern_class_values, + .left_class_mapping = kern_left_class_mapping, + .right_class_mapping = kern_right_class_mapping, + .left_class_cnt = 61, + .right_class_cnt = 49, +}; + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LVGL_VERSION_MAJOR == 8 + /*Store all the custom data of the font*/ + static lv_font_fmt_txt_glyph_cache_t cache; +#endif + +#if LVGL_VERSION_MAJOR >= 8 +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 = &kern_classes, + .kern_scale = 16, + .cmap_num = 2, + .bpp = 8, + .kern_classes = 1, + .bitmap_format = 0, +#if LVGL_VERSION_MAJOR == 8 + .cache = &cache +#endif + .stride = 16 +}; + + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LVGL_VERSION_MAJOR >= 8 +const lv_font_t lv_font_montserrat_14_aligned = { +#else +lv_font_t lv_font_montserrat_14_aligned = { +#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 = 16, /*The maximum line height required by the font*/ + .base_line = 3, /*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 = -1, + .underline_thickness = 1, +#endif + .static_bitmap = 1, + .dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +#if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9 + .fallback = NULL, +#endif + .user_data = NULL, +}; + + + +#endif /*#if LV_FONT_MONTSERRAT_14_ALIGNED*/ 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 index 4cd687f94..81f1fa7f6 100644 --- 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 @@ -20760,6 +20760,12 @@ static lv_font_fmt_txt_dsc_t font_dsc = { * PUBLIC FONT *----------------*/ +#ifdef _MSC_VER + #pragma deprecated(lv_font_simsun_14_cjk) +#else + #warning "LV_FONT_SIMSUN_14_CJK is deprecated, use LV_FONT_SOURCE_HAN_SANS_SC_14_CJK instead." +#endif + /*Initialize a public general font descriptor*/ #if LVGL_VERSION_MAJOR >= 8 const lv_font_t 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 e8b2f28ae..041f30e9e 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 @@ -24125,6 +24125,12 @@ static lv_font_fmt_txt_dsc_t font_dsc = { * PUBLIC FONT *----------------*/ +#ifdef _MSC_VER + #pragma deprecated(lv_font_simsun_16_cjk) +#else + #warning "LV_FONT_SIMSUN_16_CJK is deprecated, use LV_FONT_SOURCE_HAN_SANS_SC_16_CJK instead." +#endif + /*Initialize a public general font descriptor*/ #if LVGL_VERSION_MAJOR >= 8 const lv_font_t lv_font_simsun_16_cjk = { diff --git a/lib/libesp32_lvgl/lvgl/src/font/lv_font_source_han_sans_sc_14_cjk.c b/lib/libesp32_lvgl/lvgl/src/font/lv_font_source_han_sans_sc_14_cjk.c new file mode 100644 index 000000000..a03b4c388 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_font_source_han_sans_sc_14_cjk.c @@ -0,0 +1,23898 @@ +/******************************************************************************* + * Size: 14 px + * Bpp: 4 + * Opts: --no-compress --no-prefilter --bpp 4 --size 14 --font SourceHanSansSC-Normal.otf -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_source_han_sans_sc_14_cjk.c --force-fast-kern-format + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE + #include "lvgl.h" +#else + #include "../../lvgl.h" +#endif + +#ifndef LV_FONT_SOURCE_HAN_SANS_SC_14_CJK + #define LV_FONT_SOURCE_HAN_SANS_SC_14_CJK 1 +#endif + +#if LV_FONT_SOURCE_HAN_SANS_SC_14_CJK + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + + /* U+0021 "!" */ + 0x5c, 0x5, 0xb0, 0x5b, 0x4, 0xb0, 0x4a, 0x3, + 0xa0, 0x39, 0x2, 0x60, 0x0, 0x5, 0xa0, 0x7c, + 0x0, + + /* U+0022 "\"" */ + 0xb7, 0x1f, 0x1b, 0x71, 0xf0, 0x95, 0xf, 0x8, + 0x40, 0xc0, + + /* U+0023 "#" */ + 0x0, 0x65, 0x7, 0x40, 0x0, 0x83, 0x9, 0x20, + 0x0, 0xa1, 0xb, 0x0, 0x1d, 0xfd, 0xdf, 0xd2, + 0x0, 0xb0, 0xc, 0x0, 0x0, 0xb0, 0xb, 0x0, + 0x0, 0xb0, 0x2a, 0x0, 0x5d, 0xec, 0xde, 0xb0, + 0x4, 0x70, 0x56, 0x0, 0x6, 0x50, 0x74, 0x0, + 0x8, 0x30, 0x92, 0x0, + + /* U+0024 "$" */ + 0x0, 0x8, 0x50, 0x0, 0x1, 0xa8, 0x0, 0x2, + 0xeb, 0xae, 0x30, 0x9a, 0x0, 0x31, 0xb, 0x70, + 0x0, 0x0, 0x6d, 0x20, 0x0, 0x0, 0x7f, 0x80, + 0x0, 0x0, 0x3c, 0xc1, 0x0, 0x0, 0xc, 0x80, + 0x0, 0x0, 0x7b, 0x6, 0x0, 0xa, 0x90, 0x9e, + 0xac, 0xe1, 0x0, 0x1a, 0x80, 0x0, 0x0, 0x85, + 0x0, + + /* U+0025 "%" */ + 0x6, 0xcc, 0x20, 0x0, 0x75, 0x0, 0x1, 0xc0, + 0x2c, 0x0, 0xc, 0x0, 0x0, 0x58, 0x0, 0xd0, + 0x7, 0x50, 0x0, 0x6, 0x70, 0xc, 0x20, 0xb0, + 0x0, 0x0, 0x58, 0x0, 0xd0, 0x84, 0x3b, 0xb2, + 0x0, 0xd0, 0x3b, 0x1b, 0xd, 0x12, 0xc0, 0x4, + 0xba, 0x18, 0x43, 0x90, 0xc, 0x10, 0x0, 0x1, + 0xb0, 0x58, 0x0, 0xa3, 0x0, 0x0, 0x93, 0x4, + 0x90, 0xb, 0x10, 0x0, 0x1b, 0x0, 0xd, 0x1, + 0xd0, 0x0, 0x9, 0x30, 0x0, 0x5c, 0xc3, 0x0, + + /* U+0026 "&" */ + 0x0, 0x4d, 0xe7, 0x0, 0x0, 0x0, 0xe4, 0x1e, + 0x0, 0x0, 0x1, 0xf0, 0xe, 0x0, 0x0, 0x0, + 0xf2, 0x99, 0x0, 0x0, 0x0, 0x9e, 0x90, 0x0, + 0x0, 0x2, 0xdf, 0x10, 0x3, 0xc0, 0xe, 0x58, + 0xb0, 0x8, 0x80, 0x6c, 0x0, 0xc9, 0x1e, 0x10, + 0x6b, 0x0, 0xc, 0xe7, 0x0, 0x1f, 0x50, 0x2b, + 0xed, 0x40, 0x3, 0xcf, 0xd7, 0x6, 0xc0, + + /* U+0027 "'" */ + 0xb7, 0xb7, 0x95, 0x84, + + /* U+0028 "(" */ + 0x0, 0x80, 0x3, 0xa0, 0xa, 0x40, 0x1d, 0x0, + 0x59, 0x0, 0x87, 0x0, 0xa5, 0x0, 0xa4, 0x0, + 0xa5, 0x0, 0x87, 0x0, 0x59, 0x0, 0x1d, 0x0, + 0xa, 0x30, 0x3, 0xa0, 0x0, 0x80, + + /* U+0029 ")" */ + 0x35, 0x0, 0x1c, 0x0, 0xa, 0x40, 0x3, 0xb0, + 0x0, 0xf0, 0x0, 0xd2, 0x0, 0xc4, 0x0, 0xa4, + 0x0, 0xb4, 0x0, 0xd2, 0x0, 0xf0, 0x3, 0xb0, + 0x9, 0x40, 0x1d, 0x0, 0x35, 0x0, + + /* U+002A "*" */ + 0x0, 0x29, 0x0, 0x8, 0x8c, 0x73, 0x3, 0xdf, + 0x60, 0x1, 0xd9, 0x80, 0x1, 0x20, 0x40, + + /* U+002B "+" */ + 0x0, 0x2, 0x10, 0x0, 0x0, 0x9, 0x40, 0x0, + 0x0, 0x9, 0x40, 0x0, 0x0, 0x9, 0x40, 0x0, + 0x6d, 0xdf, 0xed, 0xd2, 0x0, 0x9, 0x40, 0x0, + 0x0, 0x9, 0x40, 0x0, 0x0, 0x9, 0x40, 0x0, + + /* U+002C "," */ + 0x7, 0x60, 0xbe, 0x1, 0xd0, 0xa5, 0x14, 0x0, + + /* U+002D "-" */ + 0x5e, 0xee, 0x20, + + /* U+002E "." */ + 0x96, 0xc8, + + /* U+002F "/" */ + 0x0, 0x0, 0xa2, 0x0, 0x0, 0xc0, 0x0, 0x4, + 0x80, 0x0, 0x9, 0x30, 0x0, 0xd, 0x0, 0x0, + 0x39, 0x0, 0x0, 0x85, 0x0, 0x0, 0xc0, 0x0, + 0x2, 0xb0, 0x0, 0x7, 0x60, 0x0, 0xc, 0x10, + 0x0, 0x1c, 0x0, 0x0, 0x67, 0x0, 0x0, 0xb2, + 0x0, 0x0, + + /* U+0030 "0" */ + 0x0, 0x8e, 0xd5, 0x0, 0x7c, 0x13, 0xe2, 0xd, + 0x30, 0x8, 0x81, 0xf0, 0x0, 0x4c, 0x3e, 0x0, + 0x3, 0xe4, 0xd0, 0x0, 0x2f, 0x3e, 0x0, 0x3, + 0xe1, 0xf0, 0x0, 0x4c, 0xd, 0x30, 0x9, 0x80, + 0x7c, 0x13, 0xe2, 0x0, 0x8e, 0xd4, 0x0, + + /* U+0031 "1" */ + 0x17, 0xda, 0x0, 0x28, 0xba, 0x0, 0x0, 0x6a, + 0x0, 0x0, 0x6a, 0x0, 0x0, 0x6a, 0x0, 0x0, + 0x6a, 0x0, 0x0, 0x6a, 0x0, 0x0, 0x6a, 0x0, + 0x0, 0x6a, 0x0, 0x0, 0x6a, 0x0, 0xbf, 0xff, + 0xfc, + + /* U+0032 "2" */ + 0x4, 0xbe, 0xc4, 0x2, 0xd4, 0x5, 0xf1, 0x1, + 0x0, 0xd, 0x60, 0x0, 0x0, 0xb6, 0x0, 0x0, + 0xe, 0x30, 0x0, 0x5, 0xd0, 0x0, 0x0, 0xd5, + 0x0, 0x0, 0xb9, 0x0, 0x0, 0x9c, 0x0, 0x0, + 0x8d, 0x10, 0x0, 0x5f, 0xff, 0xff, 0xf0, + + /* U+0033 "3" */ + 0x3, 0xbe, 0xd6, 0x0, 0xc4, 0x4, 0xf3, 0x0, + 0x0, 0xb, 0x70, 0x0, 0x0, 0xc6, 0x0, 0x1, + 0x7c, 0x0, 0x7, 0xfe, 0x20, 0x0, 0x0, 0x5d, + 0x40, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x5, 0xd5, + 0xc3, 0x3, 0xd7, 0x6, 0xbf, 0xd7, 0x0, + + /* U+0034 "4" */ + 0x0, 0x0, 0xad, 0x0, 0x0, 0x4, 0xed, 0x0, + 0x0, 0xd, 0x7d, 0x0, 0x0, 0x7a, 0x3d, 0x0, + 0x2, 0xe1, 0x3d, 0x0, 0xb, 0x60, 0x3d, 0x0, + 0x4c, 0x0, 0x3d, 0x0, 0xbf, 0xee, 0xff, 0xe3, + 0x0, 0x0, 0x3d, 0x0, 0x0, 0x0, 0x3d, 0x0, + 0x0, 0x0, 0x3d, 0x0, + + /* U+0035 "5" */ + 0x7, 0xff, 0xff, 0x60, 0x88, 0x0, 0x0, 0x9, + 0x60, 0x0, 0x0, 0xa5, 0x0, 0x0, 0xb, 0xbd, + 0xd7, 0x0, 0x53, 0x3, 0xe6, 0x0, 0x0, 0x6, + 0xc0, 0x0, 0x0, 0x4e, 0x0, 0x0, 0x7, 0xb5, + 0xb3, 0x4, 0xe4, 0x6, 0xcf, 0xd5, 0x0, + + /* U+0036 "6" */ + 0x0, 0x3c, 0xfc, 0x40, 0x2, 0xe5, 0x4, 0x60, + 0x9, 0x70, 0x0, 0x0, 0xf, 0x10, 0x0, 0x0, + 0xf, 0x3b, 0xd9, 0x0, 0x2f, 0xb1, 0xa, 0x90, + 0x1f, 0x0, 0x2, 0xe0, 0xf, 0x0, 0x0, 0xf0, + 0xc, 0x50, 0x3, 0xe0, 0x4, 0xd2, 0xb, 0x70, + 0x0, 0x5d, 0xe8, 0x0, + + /* U+0037 "7" */ + 0x4f, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x9, 0x80, + 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, 0xa6, 0x0, + 0x0, 0x1, 0xf1, 0x0, 0x0, 0x6, 0xb0, 0x0, + 0x0, 0xa, 0x70, 0x0, 0x0, 0xd, 0x40, 0x0, + 0x0, 0xf, 0x20, 0x0, 0x0, 0x1f, 0x10, 0x0, + 0x0, 0x2f, 0x0, 0x0, + + /* U+0038 "8" */ + 0x0, 0x9e, 0xd8, 0x0, 0x8, 0xb1, 0xc, 0x50, + 0xc, 0x40, 0x6, 0xa0, 0x9, 0x70, 0x7, 0x70, + 0x2, 0xe8, 0x2d, 0x10, 0x1, 0xbc, 0xf8, 0x0, + 0xc, 0x40, 0x4d, 0x60, 0x4d, 0x0, 0x3, 0xe0, + 0x4c, 0x0, 0x1, 0xf0, 0xe, 0x60, 0x9, 0xa0, + 0x2, 0xbe, 0xd9, 0x0, + + /* U+0039 "9" */ + 0x1, 0xbe, 0xc3, 0x0, 0xc6, 0x4, 0xe1, 0x3d, + 0x0, 0x9, 0x85, 0xc0, 0x0, 0x5b, 0x3f, 0x0, + 0x4, 0xd0, 0xe6, 0x4, 0xdd, 0x2, 0xbd, 0x95, + 0xc0, 0x0, 0x0, 0x6a, 0x0, 0x0, 0xc, 0x40, + 0x82, 0x18, 0xc0, 0x7, 0xde, 0xa1, 0x0, + + /* U+003A ":" */ + 0xb8, 0xa7, 0x0, 0x0, 0x0, 0x0, 0x96, 0xc8, + + /* U+003B ";" */ + 0xb, 0x80, 0xa7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x60, 0xbe, 0x1, 0xd0, 0xa5, 0x14, + 0x0, + + /* U+003C "<" */ + 0x0, 0x0, 0x0, 0x41, 0x0, 0x1, 0x7d, 0xc1, + 0x3, 0xad, 0x82, 0x0, 0x7f, 0x50, 0x0, 0x0, + 0x18, 0xd9, 0x30, 0x0, 0x0, 0x5, 0xbd, 0x70, + 0x0, 0x0, 0x2, 0x82, + + /* U+003D "=" */ + 0x6e, 0xee, 0xee, 0xe2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6d, 0xdd, 0xdd, 0xd2, + + /* U+003E ">" */ + 0x32, 0x0, 0x0, 0x0, 0x4d, 0xb5, 0x0, 0x0, + 0x0, 0x4a, 0xd8, 0x10, 0x0, 0x0, 0x19, 0xf2, + 0x0, 0x5, 0xbc, 0x60, 0x29, 0xe9, 0x30, 0x0, + 0x56, 0x10, 0x0, 0x0, + + /* U+003F "?" */ + 0x6, 0xdf, 0xa1, 0x2a, 0x22, 0xc8, 0x0, 0x0, + 0x6b, 0x0, 0x0, 0xa8, 0x0, 0x4, 0xe1, 0x0, + 0xe, 0x40, 0x0, 0x5b, 0x0, 0x0, 0x56, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0x9a, + 0x0, + + /* U+0040 "@" */ + 0x0, 0x0, 0x4b, 0xdd, 0xc7, 0x0, 0x0, 0x0, + 0x9b, 0x20, 0x1, 0x8c, 0x0, 0x0, 0xa7, 0x0, + 0x0, 0x0, 0x78, 0x0, 0x4b, 0x0, 0x5b, 0xab, + 0x0, 0xd0, 0xc, 0x20, 0x4b, 0x4, 0xd0, 0xb, + 0x20, 0xe0, 0xc, 0x20, 0x3a, 0x0, 0x94, 0x2c, + 0x0, 0xe0, 0x5, 0x80, 0xa, 0x22, 0xb0, 0x1c, + 0x0, 0x86, 0x0, 0xc0, 0xd, 0x0, 0xd1, 0x2d, + 0x70, 0x86, 0x0, 0xc3, 0x4, 0xb8, 0x9, 0xa5, + 0x0, 0x3, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xd4, 0x0, 0x16, 0x0, 0x0, 0x0, 0x2, + 0x9c, 0xcb, 0x60, 0x0, 0x0, + + /* U+0041 "A" */ + 0x0, 0x9, 0xf0, 0x0, 0x0, 0x0, 0xeb, 0x50, + 0x0, 0x0, 0x3c, 0x6a, 0x0, 0x0, 0x8, 0x82, + 0xf0, 0x0, 0x0, 0xd4, 0xe, 0x40, 0x0, 0x3f, + 0x0, 0x99, 0x0, 0x8, 0xb0, 0x5, 0xe0, 0x0, + 0xdf, 0xee, 0xff, 0x30, 0x2f, 0x10, 0x0, 0xb8, + 0x7, 0xb0, 0x0, 0x6, 0xe0, 0xc6, 0x0, 0x0, + 0x1f, 0x30, + + /* U+0042 "B" */ + 0x9f, 0xff, 0xd8, 0x0, 0x99, 0x0, 0x2c, 0x80, + 0x99, 0x0, 0x5, 0xd0, 0x99, 0x0, 0x5, 0xb0, + 0x99, 0x0, 0x3d, 0x50, 0x9f, 0xef, 0xfb, 0x0, + 0x99, 0x0, 0x17, 0xe1, 0x99, 0x0, 0x0, 0xc6, + 0x99, 0x0, 0x0, 0xc5, 0x99, 0x0, 0x18, 0xe1, + 0x9f, 0xff, 0xea, 0x20, + + /* U+0043 "C" */ + 0x0, 0x8, 0xde, 0xb3, 0x0, 0xc, 0xb3, 0x16, + 0xc0, 0x7, 0xc0, 0x0, 0x0, 0x0, 0xd5, 0x0, + 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, 0x2, 0xf0, + 0x0, 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, 0x0, + 0xe5, 0x0, 0x0, 0x0, 0x7, 0xc0, 0x0, 0x1, + 0x0, 0xd, 0xb3, 0x15, 0xe2, 0x0, 0x9, 0xde, + 0xb3, 0x0, + + /* U+0044 "D" */ + 0x9f, 0xfe, 0xb4, 0x0, 0x99, 0x1, 0x5e, 0x70, + 0x99, 0x0, 0x3, 0xf1, 0x99, 0x0, 0x0, 0xc7, + 0x99, 0x0, 0x0, 0x99, 0x99, 0x0, 0x0, 0x7b, + 0x99, 0x0, 0x0, 0x99, 0x99, 0x0, 0x0, 0xc7, + 0x99, 0x0, 0x3, 0xf1, 0x99, 0x1, 0x6f, 0x70, + 0x9f, 0xfe, 0xb4, 0x0, + + /* U+0045 "E" */ + 0x9f, 0xff, 0xff, 0x49, 0x90, 0x0, 0x0, 0x99, + 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x99, 0x0, + 0x0, 0x9, 0xff, 0xff, 0x80, 0x99, 0x0, 0x0, + 0x9, 0x90, 0x0, 0x0, 0x99, 0x0, 0x0, 0x9, + 0x90, 0x0, 0x0, 0x9f, 0xff, 0xff, 0x60, + + /* U+0046 "F" */ + 0x9f, 0xff, 0xff, 0x39, 0x90, 0x0, 0x0, 0x99, + 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x99, 0x0, + 0x0, 0x9, 0xfe, 0xee, 0x70, 0x9a, 0x11, 0x10, + 0x9, 0x90, 0x0, 0x0, 0x99, 0x0, 0x0, 0x9, + 0x90, 0x0, 0x0, 0x99, 0x0, 0x0, 0x0, + + /* U+0047 "G" */ + 0x0, 0x7, 0xcf, 0xc6, 0x0, 0xc, 0xc4, 0x14, + 0xc2, 0x6, 0xd0, 0x0, 0x0, 0x0, 0xd5, 0x0, + 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, 0x2, 0xf0, + 0x0, 0xcf, 0xf8, 0xf, 0x20, 0x0, 0x8, 0x80, + 0xd5, 0x0, 0x0, 0x88, 0x7, 0xc0, 0x0, 0x8, + 0x80, 0xc, 0xc4, 0x14, 0xd7, 0x0, 0x8, 0xdf, + 0xc7, 0x0, + + /* U+0048 "H" */ + 0x99, 0x0, 0x0, 0x7a, 0x99, 0x0, 0x0, 0x7a, + 0x99, 0x0, 0x0, 0x7a, 0x99, 0x0, 0x0, 0x7a, + 0x99, 0x0, 0x0, 0x7a, 0x9f, 0xee, 0xee, 0xfa, + 0x9a, 0x11, 0x11, 0x8a, 0x99, 0x0, 0x0, 0x7a, + 0x99, 0x0, 0x0, 0x7a, 0x99, 0x0, 0x0, 0x7a, + 0x99, 0x0, 0x0, 0x7a, + + /* U+0049 "I" */ + 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, + 0x99, 0x99, 0x99, + + /* U+004A "J" */ + 0x0, 0x0, 0x1f, 0x0, 0x0, 0x1, 0xf0, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x1, 0xf0, 0x0, 0x0, + 0x1f, 0x0, 0x0, 0x1, 0xf0, 0x0, 0x0, 0x1f, + 0x0, 0x0, 0x2, 0xf0, 0x1, 0x0, 0x3e, 0x3, + 0xe3, 0x1b, 0xa0, 0x6, 0xcf, 0xa1, 0x0, + + /* U+004B "K" */ + 0x99, 0x0, 0x5, 0xe1, 0x99, 0x0, 0x2e, 0x30, + 0x99, 0x0, 0xd6, 0x0, 0x99, 0xa, 0xa0, 0x0, + 0x99, 0x7f, 0x50, 0x0, 0x9d, 0xf8, 0xd0, 0x0, + 0x9f, 0x50, 0xd6, 0x0, 0x9a, 0x0, 0x4e, 0x0, + 0x99, 0x0, 0xc, 0x80, 0x99, 0x0, 0x3, 0xf1, + 0x99, 0x0, 0x0, 0xb9, + + /* U+004C "L" */ + 0x99, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x99, + 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x99, 0x0, + 0x0, 0x9, 0x90, 0x0, 0x0, 0x99, 0x0, 0x0, + 0x9, 0x90, 0x0, 0x0, 0x99, 0x0, 0x0, 0x9, + 0x90, 0x0, 0x0, 0x9f, 0xff, 0xff, 0x10, + + /* U+004D "M" */ + 0x9f, 0x0, 0x0, 0xc, 0xd9, 0xe5, 0x0, 0x1, + 0xed, 0x9a, 0xa0, 0x0, 0x6a, 0xd9, 0x7e, 0x0, + 0xc, 0x5d, 0x97, 0x95, 0x1, 0xd3, 0xd9, 0x74, + 0xa0, 0x67, 0x3d, 0x97, 0xe, 0xc, 0x23, 0xd9, + 0x70, 0x96, 0xc0, 0x3d, 0x97, 0x4, 0xe7, 0x3, + 0xd9, 0x70, 0xd, 0x20, 0x3d, 0x97, 0x0, 0x0, + 0x3, 0xd0, + + /* U+004E "N" */ + 0x9d, 0x0, 0x0, 0x79, 0x9f, 0x70, 0x0, 0x79, + 0x98, 0xe0, 0x0, 0x79, 0x97, 0x98, 0x0, 0x79, + 0x98, 0x2e, 0x10, 0x79, 0x98, 0x8, 0x90, 0x79, + 0x98, 0x1, 0xe2, 0x79, 0x98, 0x0, 0x7b, 0x69, + 0x98, 0x0, 0xe, 0x89, 0x98, 0x0, 0x6, 0xf9, + 0x98, 0x0, 0x0, 0xd9, + + /* U+004F "O" */ + 0x0, 0x9, 0xde, 0xb3, 0x0, 0x0, 0xda, 0x32, + 0x7f, 0x40, 0x7, 0xc0, 0x0, 0x7, 0xc0, 0xe, + 0x50, 0x0, 0x0, 0xf3, 0xf, 0x20, 0x0, 0x0, + 0xd5, 0x2f, 0x0, 0x0, 0x0, 0xb7, 0xf, 0x20, + 0x0, 0x0, 0xd5, 0xe, 0x50, 0x0, 0x0, 0xf2, + 0x7, 0xc0, 0x0, 0x7, 0xc0, 0x0, 0xdb, 0x32, + 0x7f, 0x30, 0x0, 0x9, 0xde, 0xb2, 0x0, + + /* U+0050 "P" */ + 0x9f, 0xff, 0xd7, 0x0, 0x99, 0x0, 0x3c, 0x90, + 0x99, 0x0, 0x3, 0xe0, 0x99, 0x0, 0x1, 0xf0, + 0x99, 0x0, 0x4, 0xe0, 0x99, 0x0, 0x3d, 0x70, + 0x9f, 0xff, 0xd6, 0x0, 0x99, 0x0, 0x0, 0x0, + 0x99, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0, 0x0, + 0x99, 0x0, 0x0, 0x0, + + /* U+0051 "Q" */ + 0x0, 0x19, 0xde, 0xb3, 0x0, 0x1, 0xda, 0x32, + 0x7f, 0x40, 0x8, 0xb0, 0x0, 0x6, 0xd0, 0xe, + 0x40, 0x0, 0x0, 0xf3, 0xf, 0x10, 0x0, 0x0, + 0xc5, 0x2f, 0x0, 0x0, 0x0, 0xb7, 0xf, 0x20, + 0x0, 0x0, 0xd5, 0xc, 0x60, 0x0, 0x1, 0xf2, + 0x5, 0xe1, 0x0, 0xa, 0xa0, 0x0, 0x8e, 0x76, + 0xbc, 0x10, 0x0, 0x3, 0xaf, 0x50, 0x0, 0x0, + 0x0, 0xd, 0xb3, 0x0, 0x0, 0x0, 0x1, 0x9e, + 0xf8, + + /* U+0052 "R" */ + 0x9f, 0xff, 0xe9, 0x10, 0x99, 0x0, 0x2a, 0xb0, + 0x99, 0x0, 0x2, 0xf0, 0x99, 0x0, 0x2, 0xf0, + 0x99, 0x0, 0x2c, 0xa0, 0x9f, 0xff, 0xf6, 0x0, + 0x99, 0x3, 0xf1, 0x0, 0x99, 0x0, 0xb8, 0x0, + 0x99, 0x0, 0x3f, 0x10, 0x99, 0x0, 0xb, 0x90, + 0x99, 0x0, 0x3, 0xf2, + + /* U+0053 "S" */ + 0x0, 0x7d, 0xfb, 0x40, 0x7, 0xd4, 0x15, 0xd1, + 0xc, 0x60, 0x0, 0x0, 0xa, 0xa0, 0x0, 0x0, + 0x2, 0xec, 0x40, 0x0, 0x0, 0x19, 0xfd, 0x30, + 0x0, 0x0, 0x19, 0xf3, 0x0, 0x0, 0x0, 0xa9, + 0x2, 0x0, 0x0, 0x98, 0x1e, 0x93, 0x15, 0xf3, + 0x1, 0x9d, 0xfc, 0x40, + + /* U+0054 "T" */ + 0x8f, 0xff, 0xff, 0xfd, 0x0, 0x7, 0xc0, 0x0, + 0x0, 0x6, 0xb0, 0x0, 0x0, 0x6, 0xb0, 0x0, + 0x0, 0x6, 0xb0, 0x0, 0x0, 0x6, 0xb0, 0x0, + 0x0, 0x6, 0xb0, 0x0, 0x0, 0x6, 0xb0, 0x0, + 0x0, 0x6, 0xb0, 0x0, 0x0, 0x6, 0xb0, 0x0, + 0x0, 0x6, 0xb0, 0x0, + + /* U+0055 "U" */ + 0x98, 0x0, 0x0, 0x7a, 0x98, 0x0, 0x0, 0x7a, + 0x98, 0x0, 0x0, 0x7a, 0x98, 0x0, 0x0, 0x7a, + 0x98, 0x0, 0x0, 0x7a, 0x98, 0x0, 0x0, 0x7a, + 0x99, 0x0, 0x0, 0x79, 0x7a, 0x0, 0x0, 0x97, + 0x4e, 0x0, 0x0, 0xd5, 0xc, 0xa2, 0x29, 0xd0, + 0x1, 0xae, 0xea, 0x10, + + /* U+0056 "V" */ + 0xd6, 0x0, 0x0, 0x6c, 0x8a, 0x0, 0x0, 0xa7, + 0x3e, 0x0, 0x0, 0xe2, 0xe, 0x30, 0x3, 0xd0, + 0xa, 0x80, 0x8, 0x90, 0x5, 0xc0, 0xc, 0x40, + 0x0, 0xf1, 0x1f, 0x0, 0x0, 0xb5, 0x5a, 0x0, + 0x0, 0x6a, 0xa6, 0x0, 0x0, 0x2e, 0xe1, 0x0, + 0x0, 0xd, 0xc0, 0x0, + + /* U+0057 "W" */ + 0x8a, 0x0, 0x8, 0xc0, 0x0, 0x6b, 0x5d, 0x0, + 0xc, 0xf0, 0x0, 0x97, 0x1f, 0x0, 0xd, 0xb4, + 0x0, 0xc4, 0xe, 0x30, 0x3a, 0x78, 0x0, 0xf1, + 0xb, 0x60, 0x77, 0x4b, 0x2, 0xe0, 0x8, 0x90, + 0xb3, 0xf, 0x5, 0xb0, 0x5, 0xc0, 0xe0, 0xc, + 0x38, 0x80, 0x1, 0xe2, 0xc0, 0x8, 0x6a, 0x50, + 0x0, 0xe7, 0x80, 0x5, 0xad, 0x20, 0x0, 0xbd, + 0x40, 0x1, 0xee, 0x0, 0x0, 0x8f, 0x10, 0x0, + 0xdb, 0x0, + + /* U+0058 "X" */ + 0x4e, 0x0, 0x1, 0xe3, 0xc, 0x70, 0x8, 0xa0, + 0x3, 0xe0, 0x1e, 0x20, 0x0, 0xb7, 0x79, 0x0, + 0x0, 0x2e, 0xe1, 0x0, 0x0, 0xe, 0xc0, 0x0, + 0x0, 0x5b, 0xe3, 0x0, 0x0, 0xd3, 0x6c, 0x0, + 0x6, 0xb0, 0xe, 0x40, 0xe, 0x30, 0x6, 0xd0, + 0x7b, 0x0, 0x0, 0xd5, + + /* U+0059 "Y" */ + 0xc7, 0x0, 0x1, 0xf1, 0x4d, 0x0, 0x8, 0x90, + 0xd, 0x40, 0xe, 0x20, 0x6, 0xb0, 0x6b, 0x0, + 0x0, 0xe2, 0xd3, 0x0, 0x0, 0x7c, 0xc0, 0x0, + 0x0, 0x1f, 0x50, 0x0, 0x0, 0xe, 0x30, 0x0, + 0x0, 0xe, 0x30, 0x0, 0x0, 0xe, 0x30, 0x0, + 0x0, 0xe, 0x30, 0x0, + + /* U+005A "Z" */ + 0xc, 0xff, 0xff, 0xfa, 0x0, 0x0, 0x1, 0xf3, + 0x0, 0x0, 0xa, 0x90, 0x0, 0x0, 0x3e, 0x10, + 0x0, 0x0, 0xd6, 0x0, 0x0, 0x6, 0xc0, 0x0, + 0x0, 0x1e, 0x30, 0x0, 0x0, 0x9a, 0x0, 0x0, + 0x3, 0xf1, 0x0, 0x0, 0xc, 0x70, 0x0, 0x0, + 0x4f, 0xff, 0xff, 0xfb, + + /* U+005B "[" */ + 0x8c, 0xb2, 0x85, 0x0, 0x85, 0x0, 0x85, 0x0, + 0x85, 0x0, 0x85, 0x0, 0x85, 0x0, 0x85, 0x0, + 0x85, 0x0, 0x85, 0x0, 0x85, 0x0, 0x85, 0x0, + 0x85, 0x0, 0x6b, 0xa1, + + /* U+005C "\\" */ + 0xa2, 0x0, 0x0, 0x57, 0x0, 0x0, 0x1c, 0x0, + 0x0, 0xb, 0x10, 0x0, 0x6, 0x60, 0x0, 0x1, + 0xb0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x85, 0x0, + 0x0, 0x3a, 0x0, 0x0, 0xd, 0x0, 0x0, 0x9, + 0x40, 0x0, 0x4, 0x90, 0x0, 0x0, 0xd0, 0x0, + 0x0, 0xa2, + + /* U+005D "]" */ + 0x6b, 0xe2, 0x0, 0xb2, 0x0, 0xb2, 0x0, 0xb2, + 0x0, 0xb2, 0x0, 0xb2, 0x0, 0xb2, 0x0, 0xb2, + 0x0, 0xb2, 0x0, 0xb2, 0x0, 0xb2, 0x0, 0xb2, + 0x0, 0xb2, 0x5a, 0xc2, + + /* U+005E "^" */ + 0x0, 0xd, 0x80, 0x0, 0x4, 0xad, 0x0, 0x0, + 0xa4, 0x95, 0x0, 0x1d, 0x3, 0xb0, 0x7, 0x80, + 0xd, 0x20, 0xd2, 0x0, 0x78, + + /* U+005F "_" */ + 0xac, 0xcc, 0xcc, 0xc7, + + /* U+0060 "`" */ + 0x20, 0x0, 0x9b, 0x0, 0xb, 0x80, 0x0, 0x80, + + /* U+0061 "a" */ + 0x2, 0xad, 0xe9, 0x0, 0x75, 0x12, 0xe5, 0x0, + 0x0, 0x9, 0x90, 0x4, 0x9c, 0xea, 0x9, 0xb3, + 0x7, 0xa1, 0xf0, 0x0, 0x7a, 0xf, 0x50, 0x4e, + 0xa0, 0x6e, 0xe9, 0x5a, + + /* U+0062 "b" */ + 0xa7, 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, 0xa7, + 0x0, 0x0, 0xa, 0x79, 0xed, 0x60, 0xae, 0x50, + 0x4e, 0x4a, 0x70, 0x0, 0x8a, 0xa7, 0x0, 0x5, + 0xca, 0x70, 0x0, 0x6c, 0xa7, 0x0, 0xa, 0x9a, + 0xd3, 0x6, 0xf1, 0xa6, 0xbf, 0xc3, 0x0, + + /* U+0063 "c" */ + 0x0, 0x6d, 0xfb, 0x20, 0x7d, 0x30, 0x52, 0xf, + 0x40, 0x0, 0x2, 0xf0, 0x0, 0x0, 0x3f, 0x0, + 0x0, 0x0, 0xf3, 0x0, 0x0, 0x8, 0xd3, 0x5, + 0x50, 0x7, 0xde, 0xb2, + + /* U+0064 "d" */ + 0x0, 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, 0xd4, + 0x0, 0x0, 0x0, 0xd4, 0x0, 0x7d, 0xe8, 0xd4, + 0x7, 0xd3, 0x6, 0xf4, 0xf, 0x40, 0x0, 0xd4, + 0x2f, 0x0, 0x0, 0xd4, 0x3f, 0x0, 0x0, 0xd4, + 0xf, 0x30, 0x0, 0xd4, 0xa, 0xc2, 0x18, 0xf4, + 0x0, 0x9e, 0xd6, 0xa4, + + /* U+0065 "e" */ + 0x0, 0x7d, 0xea, 0x10, 0x7, 0xb1, 0x8, 0xa0, + 0xe, 0x0, 0x0, 0xf0, 0x2f, 0xdd, 0xdd, 0xe1, + 0x2f, 0x0, 0x0, 0x0, 0xf, 0x40, 0x0, 0x0, + 0x7, 0xd3, 0x2, 0x40, 0x0, 0x6d, 0xfc, 0x50, + + /* U+0066 "f" */ + 0x0, 0x9e, 0x90, 0x5e, 0x11, 0x7, 0xa0, 0x0, + 0x79, 0x0, 0x8f, 0xff, 0x40, 0x79, 0x0, 0x7, + 0x90, 0x0, 0x79, 0x0, 0x7, 0x90, 0x0, 0x79, + 0x0, 0x7, 0x90, 0x0, 0x79, 0x0, + + /* U+0067 "g" */ + 0x1, 0xae, 0xff, 0xe7, 0xb, 0x90, 0x1e, 0x40, + 0xe, 0x30, 0x9, 0x70, 0x9, 0x90, 0x2d, 0x40, + 0x3, 0xdc, 0xc5, 0x0, 0xa, 0x30, 0x0, 0x0, + 0xb, 0x70, 0x0, 0x0, 0x5, 0xff, 0xff, 0xc2, + 0xd, 0x10, 0x1, 0xb8, 0x2e, 0x20, 0x2, 0xd4, + 0x6, 0xde, 0xcb, 0x40, + + /* U+0068 "h" */ + 0xa7, 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, 0xa7, + 0x0, 0x0, 0xa, 0x78, 0xde, 0x50, 0xae, 0x61, + 0x6f, 0xa, 0x80, 0x0, 0xf3, 0xa7, 0x0, 0xe, + 0x4a, 0x70, 0x0, 0xd4, 0xa7, 0x0, 0xd, 0x4a, + 0x70, 0x0, 0xd4, 0xa7, 0x0, 0xd, 0x40, + + /* U+0069 "i" */ + 0xb8, 0x54, 0x0, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, + 0xa7, 0xa7, 0xa7, + + /* U+006A "j" */ + 0x0, 0xb7, 0x0, 0x63, 0x0, 0x0, 0x0, 0xa7, + 0x0, 0xa7, 0x0, 0xa7, 0x0, 0xa7, 0x0, 0xa7, + 0x0, 0xa7, 0x0, 0xa7, 0x0, 0xa7, 0x0, 0xb7, + 0x1, 0xe5, 0x6f, 0xb0, + + /* U+006B "k" */ + 0xa7, 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, 0xa7, + 0x0, 0x0, 0xa, 0x70, 0x8, 0xb0, 0xa7, 0x5, + 0xd1, 0xa, 0x72, 0xe2, 0x0, 0xa7, 0xdc, 0x0, + 0xa, 0xf8, 0xc5, 0x0, 0xab, 0x3, 0xe0, 0xa, + 0x70, 0xa, 0x80, 0xa7, 0x0, 0x1f, 0x20, + + /* U+006C "l" */ + 0xa7, 0xa, 0x70, 0xa7, 0xa, 0x70, 0xa7, 0xa, + 0x70, 0xa7, 0xa, 0x70, 0xa7, 0xa, 0x80, 0x5e, + 0x20, + + /* U+006D "m" */ + 0xa4, 0x8e, 0xc3, 0x2b, 0xfa, 0xa, 0xe6, 0x19, + 0xdb, 0x32, 0xd6, 0xa8, 0x0, 0x2f, 0x10, 0x8, + 0x9a, 0x70, 0x1, 0xf0, 0x0, 0x7a, 0xa7, 0x0, + 0x1f, 0x0, 0x7, 0xaa, 0x70, 0x1, 0xf0, 0x0, + 0x7a, 0xa7, 0x0, 0x1f, 0x0, 0x7, 0xaa, 0x70, + 0x1, 0xf0, 0x0, 0x7a, + + /* U+006E "n" */ + 0xa4, 0x8d, 0xe5, 0xa, 0xe6, 0x16, 0xf0, 0xa8, + 0x0, 0xf, 0x3a, 0x70, 0x0, 0xe4, 0xa7, 0x0, + 0xd, 0x4a, 0x70, 0x0, 0xd4, 0xa7, 0x0, 0xd, + 0x4a, 0x70, 0x0, 0xd4, + + /* U+006F "o" */ + 0x0, 0x7d, 0xea, 0x10, 0x7, 0xd2, 0x18, 0xd0, + 0xf, 0x30, 0x0, 0xc6, 0x2f, 0x0, 0x0, 0x89, + 0x2f, 0x0, 0x0, 0x89, 0xf, 0x30, 0x0, 0xc6, + 0x7, 0xd2, 0x7, 0xe0, 0x0, 0x7d, 0xea, 0x10, + + /* U+0070 "p" */ + 0xa5, 0x9e, 0xd6, 0xa, 0xe5, 0x4, 0xe4, 0xa7, + 0x0, 0x8, 0xaa, 0x70, 0x0, 0x5c, 0xa7, 0x0, + 0x6, 0xca, 0x70, 0x0, 0xa9, 0xad, 0x30, 0x6f, + 0x2a, 0x9b, 0xfc, 0x30, 0xa7, 0x0, 0x0, 0xa, + 0x70, 0x0, 0x0, 0xa7, 0x0, 0x0, 0x0, + + /* U+0071 "q" */ + 0x0, 0x7d, 0xe9, 0xb4, 0x7, 0xd3, 0x6, 0xf4, + 0xf, 0x40, 0x0, 0xd4, 0x2f, 0x0, 0x0, 0xd4, + 0x3f, 0x0, 0x0, 0xd4, 0xf, 0x30, 0x0, 0xd4, + 0xa, 0xc2, 0x18, 0xf4, 0x0, 0x9e, 0xd6, 0xc4, + 0x0, 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, 0xd4, + 0x0, 0x0, 0x0, 0xd4, + + /* U+0072 "r" */ + 0xa4, 0x8f, 0x3a, 0xc7, 0x20, 0xaa, 0x0, 0xa, + 0x70, 0x0, 0xa7, 0x0, 0xa, 0x70, 0x0, 0xa7, + 0x0, 0xa, 0x70, 0x0, + + /* U+0073 "s" */ + 0x4, 0xde, 0xc4, 0xf, 0x50, 0x33, 0xf, 0x20, + 0x0, 0x6, 0xe9, 0x20, 0x0, 0x18, 0xe6, 0x0, + 0x0, 0x4e, 0x38, 0x10, 0x8c, 0x8, 0xde, 0xb2, + + /* U+0074 "t" */ + 0x5, 0xa0, 0x0, 0x6a, 0x0, 0x9f, 0xff, 0xb0, + 0x7a, 0x0, 0x7, 0xa0, 0x0, 0x7a, 0x0, 0x7, + 0xa0, 0x0, 0x7b, 0x0, 0x4, 0xe2, 0x10, 0xa, + 0xfb, + + /* U+0075 "u" */ + 0xc5, 0x0, 0xf, 0x1c, 0x50, 0x0, 0xf1, 0xc5, + 0x0, 0xf, 0x1c, 0x50, 0x0, 0xf1, 0xc5, 0x0, + 0xf, 0x1b, 0x60, 0x1, 0xf1, 0x8c, 0x13, 0xbf, + 0x11, 0xbf, 0xb2, 0xd1, + + /* U+0076 "v" */ + 0xa8, 0x0, 0x4, 0xc4, 0xd0, 0x0, 0x97, 0xe, + 0x20, 0xe, 0x20, 0x97, 0x4, 0xc0, 0x4, 0xc0, + 0x97, 0x0, 0xe, 0x1e, 0x10, 0x0, 0x99, 0xc0, + 0x0, 0x3, 0xf6, 0x0, + + /* U+0077 "w" */ + 0x7a, 0x0, 0x2f, 0x40, 0x8, 0x93, 0xe0, 0x6, + 0xc8, 0x0, 0xc5, 0xf, 0x20, 0xa5, 0xc0, 0xf, + 0x10, 0xb6, 0xd, 0xe, 0x3, 0xc0, 0x6, 0xa2, + 0xb0, 0xa4, 0x78, 0x0, 0x2e, 0x67, 0x6, 0x8b, + 0x40, 0x0, 0xeb, 0x30, 0x2c, 0xe0, 0x0, 0x9, + 0xf0, 0x0, 0xec, 0x0, + + /* U+0078 "x" */ + 0x4e, 0x0, 0x1e, 0x20, 0xb8, 0x9, 0x80, 0x1, + 0xe4, 0xd0, 0x0, 0x7, 0xf5, 0x0, 0x0, 0xae, + 0x60, 0x0, 0x4c, 0x2e, 0x10, 0xd, 0x30, 0x8a, + 0x7, 0xa0, 0x0, 0xe4, + + /* U+0079 "y" */ + 0x98, 0x0, 0x4, 0xc3, 0xe0, 0x0, 0xa7, 0xd, + 0x40, 0xe, 0x20, 0x6a, 0x4, 0xc0, 0x1, 0xe0, + 0x96, 0x0, 0xa, 0x6e, 0x10, 0x0, 0x3d, 0xb0, + 0x0, 0x0, 0xd6, 0x0, 0x0, 0x1e, 0x10, 0x0, + 0x1b, 0x70, 0x0, 0x5f, 0xa0, 0x0, 0x0, + + /* U+007A "z" */ + 0x1f, 0xff, 0xff, 0x0, 0x0, 0xc, 0x70, 0x0, + 0x6, 0xc0, 0x0, 0x1, 0xe3, 0x0, 0x0, 0xb8, + 0x0, 0x0, 0x5d, 0x0, 0x0, 0x1e, 0x40, 0x0, + 0x7, 0xff, 0xff, 0xf2, + + /* U+007B "{" */ + 0x0, 0xac, 0x20, 0x3c, 0x0, 0x3, 0xa0, 0x0, + 0x3b, 0x0, 0x2, 0xc0, 0x0, 0x5a, 0x0, 0x5f, + 0x20, 0x0, 0x69, 0x0, 0x2, 0xb0, 0x0, 0x2b, + 0x0, 0x3, 0xb0, 0x0, 0x4b, 0x0, 0x2, 0xd0, + 0x0, 0x8, 0xb1, + + /* U+007C "|" */ + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, + + /* U+007D "}" */ + 0x6c, 0x60, 0x0, 0x2d, 0x0, 0x0, 0xd0, 0x0, + 0x1d, 0x0, 0x1, 0xc0, 0x0, 0xe, 0x0, 0x0, + 0x8e, 0x10, 0xe, 0x10, 0x1, 0xc0, 0x0, 0x1c, + 0x0, 0x1, 0xd0, 0x0, 0x1d, 0x0, 0x4, 0xc0, + 0x5, 0xc4, 0x0, + + /* U+007E "~" */ + 0x9, 0xd9, 0x30, 0x50, 0x14, 0x5, 0xcd, 0x60, + + /* U+3001 "、" */ + 0x0, 0x0, 0x0, 0xd4, 0x0, 0x5, 0xf4, 0x0, + 0x4, 0xf4, 0x0, 0x5, 0x30, + + /* U+3002 "。" */ + 0x4, 0x94, 0x4, 0xa2, 0x94, 0x82, 0x1, 0x96, + 0x60, 0x57, 0xa, 0xba, 0x0, + + /* U+3005 "々" */ + 0x0, 0x0, 0x39, 0x0, 0x0, 0x0, 0x0, 0x9, + 0x70, 0x0, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0x0, 0x7f, 0xee, 0xee, 0xf7, 0x0, 0x1e, + 0x20, 0x0, 0xe, 0x20, 0xa, 0x80, 0x0, 0x7, + 0xa0, 0x6, 0xd0, 0x0, 0x1, 0xe2, 0x3, 0xe1, + 0x2d, 0x40, 0xa7, 0x0, 0x1, 0x0, 0x3d, 0xdd, + 0x0, 0x0, 0x0, 0x0, 0x6, 0xe6, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xe5, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x0, + + /* U+300C "「" */ + 0xed, 0xdd, 0x6e, 0x0, 0x0, 0xe0, 0x0, 0xe, + 0x0, 0x0, 0xe0, 0x0, 0xe, 0x0, 0x0, 0xe0, + 0x0, 0xe, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, + 0x0, + + /* U+300D "」" */ + 0x0, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0xe0, + 0x0, 0xe, 0x0, 0x0, 0xe0, 0x0, 0xe, 0x0, + 0x0, 0xe0, 0x0, 0xe, 0x0, 0x0, 0xe6, 0xdd, + 0xde, + + /* U+3041 "ぁ" */ + 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x6, 0x70, + 0x2, 0x10, 0x2c, 0xbd, 0xdd, 0xdb, 0x40, 0x0, + 0xa, 0x30, 0x34, 0x0, 0x0, 0xb, 0xbb, 0xeb, + 0x20, 0x0, 0x9e, 0x31, 0xc3, 0xd2, 0xb, 0x4a, + 0x29, 0x40, 0x69, 0x57, 0x8, 0xaa, 0x0, 0x59, + 0x85, 0xa, 0xc0, 0x0, 0xc4, 0x3c, 0xc8, 0x82, + 0x7d, 0x70, 0x0, 0x0, 0x3, 0x61, 0x0, + + /* U+3042 "あ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0x0, 0x0, 0x0, 0x2, 0x11, 0x78, 0x34, + 0x69, 0x40, 0x8, 0xcc, 0xec, 0xa9, 0x75, 0x10, + 0x0, 0x0, 0x93, 0x0, 0x92, 0x0, 0x0, 0x0, + 0xcc, 0xdd, 0xfa, 0x20, 0x0, 0x2c, 0xe4, 0x8, + 0x64, 0xd2, 0x2, 0xd4, 0xb2, 0x1d, 0x0, 0x5a, + 0xb, 0x40, 0x94, 0xb5, 0x0, 0x3c, 0x1d, 0x0, + 0x7e, 0x70, 0x0, 0x6a, 0x1d, 0x14, 0xdb, 0x0, + 0x2, 0xe2, 0x8, 0xda, 0x5a, 0x5, 0x9e, 0x40, + 0x0, 0x0, 0x0, 0x8, 0x50, 0x0, + + /* U+3043 "ぃ" */ + 0x1, 0x0, 0x0, 0x0, 0x0, 0x4b, 0x0, 0x0, + 0x8, 0x10, 0x3b, 0x0, 0x0, 0x7, 0x90, 0x3b, + 0x0, 0x0, 0x0, 0xe1, 0x2c, 0x0, 0x0, 0x0, + 0x96, 0xe, 0x0, 0x0, 0x0, 0x5a, 0xd, 0x10, + 0x76, 0x0, 0x2d, 0x8, 0x90, 0xd2, 0x0, 0x4, + 0x1, 0xdf, 0x80, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, + + /* U+3044 "い" */ + 0x1b, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1e, 0x0, + 0x0, 0x0, 0x4d, 0x0, 0x1e, 0x0, 0x0, 0x0, + 0xb, 0x60, 0xf, 0x0, 0x0, 0x0, 0x4, 0xd0, + 0xf, 0x0, 0x0, 0x0, 0x0, 0xe2, 0xe, 0x10, + 0x0, 0x0, 0x0, 0xb5, 0xb, 0x40, 0x5, 0x30, + 0x0, 0x79, 0x7, 0x90, 0xc, 0x50, 0x0, 0x49, + 0x1, 0xf5, 0x6d, 0x0, 0x0, 0x0, 0x0, 0x5f, + 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+3046 "う" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcc, 0xa8, + 0x76, 0x0, 0x0, 0x2, 0x46, 0x79, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x48, 0xac, 0xb6, + 0x0, 0x7f, 0xa6, 0x42, 0x4c, 0x90, 0x10, 0x0, + 0x0, 0x1, 0xf1, 0x0, 0x0, 0x0, 0x0, 0xe2, + 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0xc, 0x80, 0x0, 0x0, 0x4, 0xca, 0x0, 0x0, + 0x4a, 0xed, 0x40, 0x0, 0x0, 0x15, 0x10, 0x0, + 0x0, + + /* U+3047 "ぇ" */ + 0x0, 0x1a, 0x75, 0x31, 0x0, 0x0, 0x3, 0x58, + 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, + 0xbc, 0xdd, 0xf7, 0x0, 0x1, 0x21, 0xa, 0x80, + 0x0, 0x0, 0x0, 0x97, 0x0, 0x0, 0x0, 0x9, + 0xdd, 0x10, 0x0, 0x0, 0x98, 0x8, 0x60, 0x0, + 0x9, 0xa0, 0x3, 0xd3, 0x34, 0x18, 0x0, 0x0, + 0x6b, 0xa7, + + /* U+3048 "え" */ + 0x0, 0x8, 0x96, 0x42, 0x0, 0x0, 0x0, 0x2, + 0x57, 0xac, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x12, 0x45, 0x60, 0x0, + 0x6, 0xfd, 0xcb, 0xaf, 0x90, 0x0, 0x0, 0x0, + 0x0, 0xa7, 0x0, 0x0, 0x0, 0x0, 0xa, 0x50, + 0x0, 0x0, 0x0, 0x0, 0xae, 0xb0, 0x0, 0x0, + 0x0, 0xa, 0x70, 0xa6, 0x0, 0x0, 0x0, 0xa8, + 0x0, 0x5b, 0x0, 0x0, 0xa, 0xa0, 0x0, 0xe, + 0x64, 0x55, 0x8, 0x0, 0x0, 0x3, 0x9b, 0xa5, + + /* U+304A "お" */ + 0x0, 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf, 0x0, 0x30, 0x81, 0x0, 0xa, 0xbb, 0xfd, + 0xc8, 0x5, 0xe6, 0x0, 0x23, 0x3e, 0x0, 0x0, + 0x1, 0xc2, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x7b, 0xdc, 0x81, 0x0, 0x0, + 0x2b, 0xf6, 0x20, 0x28, 0xc0, 0x0, 0x6c, 0x3e, + 0x0, 0x0, 0xd, 0x20, 0x1d, 0x0, 0xe0, 0x0, + 0x0, 0xe1, 0x1, 0xe3, 0xe, 0x0, 0x3, 0xbb, + 0x0, 0x4, 0xdf, 0xb0, 0x5e, 0xe8, 0x0, 0x0, + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + + /* U+304B "か" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x79, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x97, + 0x11, 0x0, 0xd4, 0x0, 0xc, 0xdd, 0xfd, 0xce, + 0xa0, 0x3d, 0x0, 0x3, 0x11, 0xe0, 0x0, 0xe2, + 0xb, 0x50, 0x0, 0x5, 0xa0, 0x0, 0xc3, 0x4, + 0xd0, 0x0, 0xa, 0x50, 0x0, 0xd2, 0x0, 0xb1, + 0x0, 0x1e, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x1, 0xd0, + 0x0, 0x8, 0x90, 0x0, 0x0, 0x8, 0x80, 0x4e, + 0xdd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, 0x0, + + /* U+304C "が" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x80, 0x0, + 0x0, 0x5b, 0x0, 0x0, 0x85, 0xa3, 0x0, 0x0, + 0x79, 0x0, 0x0, 0x1a, 0x12, 0x0, 0x0, 0x97, + 0x10, 0x0, 0xe2, 0x0, 0xc, 0xcd, 0xfe, 0xdf, + 0x90, 0x5b, 0x0, 0x3, 0x21, 0xe0, 0x0, 0xe1, + 0xc, 0x40, 0x0, 0x5, 0xa0, 0x0, 0xc3, 0x5, + 0xc0, 0x0, 0xa, 0x50, 0x0, 0xd1, 0x0, 0xd1, + 0x0, 0x1e, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x1, 0xe1, + 0x0, 0x7, 0x90, 0x0, 0x0, 0x9, 0x80, 0x4d, + 0xde, 0x10, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, + 0x0, 0x0, 0x0, + + /* U+304D "き" */ + 0x0, 0x0, 0x1d, 0x0, 0x0, 0x1, 0x43, 0x22, + 0xe6, 0x8c, 0x20, 0x29, 0xab, 0xbd, 0xc6, 0x20, + 0x0, 0x0, 0x0, 0x3b, 0x0, 0x0, 0x45, 0x44, + 0x45, 0xe8, 0xbe, 0x4, 0x89, 0x99, 0x89, 0xc3, + 0x0, 0x0, 0x0, 0x0, 0xd, 0x20, 0x0, 0x81, + 0x0, 0x49, 0xbc, 0x0, 0x2d, 0x0, 0x0, 0x35, + 0x50, 0x2, 0xd0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0xa4, 0x22, 0x35, 0x10, 0x0, 0x6, 0xac, 0xcb, + 0x92, 0x0, + + /* U+304E "ぎ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x32, 0x0, 0x0, + 0x0, 0xa4, 0x0, 0xb3, 0xb0, 0x5, 0x32, 0x29, + 0xa7, 0xa8, 0x85, 0x10, 0x9a, 0xbb, 0xbf, 0x73, + 0x1, 0x0, 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, + 0x1, 0x54, 0x33, 0x4b, 0xaa, 0xd5, 0x0, 0x29, + 0x9a, 0xa9, 0x8f, 0x51, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x87, 0x0, 0x0, 0x4, 0x30, 0x1, 0x87, + 0xe2, 0x0, 0x0, 0xc3, 0x0, 0x4, 0x68, 0x0, + 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8b, 0x30, 0x0, 0x12, 0x0, 0x0, 0x0, 0x7c, + 0xef, 0xed, 0x70, 0x0, 0x0, + + /* U+304F "く" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x70, 0x0, 0x0, 0xb, 0xb0, 0x0, 0x0, 0x1d, + 0x80, 0x0, 0x0, 0x3e, 0x50, 0x0, 0x0, 0x5e, + 0x30, 0x0, 0x0, 0xf, 0x40, 0x0, 0x0, 0x0, + 0x9c, 0x10, 0x0, 0x0, 0x0, 0x8e, 0x30, 0x0, + 0x0, 0x0, 0x5e, 0x40, 0x0, 0x0, 0x0, 0x4e, + 0x60, 0x0, 0x0, 0x0, 0x3e, 0x70, 0x0, 0x0, + 0x0, 0x39, 0x0, + + /* U+3050 "ぐ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xd4, 0x0, 0x0, 0x0, 0x1d, 0x80, 0x0, 0x0, + 0x3, 0xe6, 0x0, 0x50, 0x0, 0x6e, 0x30, 0x72, + 0xa3, 0x8, 0xd1, 0x0, 0x2b, 0x16, 0x2f, 0x10, + 0x0, 0x3, 0x0, 0xb, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x10, 0x0, 0x0, 0x0, 0x8, 0xe3, + 0x0, 0x0, 0x0, 0x0, 0x6e, 0x40, 0x0, 0x0, + 0x0, 0x5, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x57, + 0x0, + + /* U+3051 "け" */ + 0x7, 0x70, 0x0, 0x0, 0x5b, 0x0, 0x0, 0xa5, + 0x0, 0x0, 0x4, 0xb0, 0x0, 0xd, 0x20, 0x0, + 0x0, 0x4b, 0x24, 0x0, 0xe0, 0x4, 0xff, 0xef, + 0xfd, 0xb0, 0xd, 0x0, 0x0, 0x0, 0x3b, 0x0, + 0x1, 0xd0, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x1c, + 0x21, 0x0, 0x0, 0x4a, 0x0, 0x0, 0xe8, 0x10, + 0x0, 0x6, 0x80, 0x0, 0xe, 0xb0, 0x0, 0x0, + 0xb5, 0x0, 0x0, 0xc8, 0x0, 0x0, 0x4d, 0x0, + 0x0, 0x8, 0x60, 0x0, 0x7e, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x6, 0x20, 0x0, 0x0, + + /* U+3052 "げ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0x0, 0xb2, + 0x0, 0x0, 0xc, 0x4a, 0x73, 0xf, 0x0, 0x0, + 0x0, 0xc3, 0x91, 0x22, 0xc0, 0x0, 0x0, 0xc, + 0x31, 0x20, 0x4a, 0x0, 0xae, 0xdd, 0xff, 0xe8, + 0x6, 0x80, 0x0, 0x11, 0x1b, 0x30, 0x0, 0x77, + 0x0, 0x0, 0x0, 0xb3, 0x0, 0x7, 0x73, 0x0, + 0x0, 0xc, 0x20, 0x0, 0x68, 0xa0, 0x0, 0x0, + 0xe0, 0x0, 0x5, 0xd7, 0x0, 0x0, 0x2d, 0x0, + 0x0, 0x3f, 0x30, 0x0, 0xb, 0x60, 0x0, 0x0, + 0xe0, 0x0, 0x1b, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x80, 0x0, 0x0, 0x0, + + /* U+3053 "こ" */ + 0xd, 0xed, 0xdd, 0xde, 0x80, 0x0, 0x12, 0x22, + 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, 0x96, 0x0, + 0x0, 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, + 0x6d, 0x30, 0x0, 0x0, 0x22, 0x7, 0xdf, 0xee, + 0xff, 0xd5, 0x0, 0x0, 0x21, 0x0, 0x0, + + /* U+3054 "ご" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x83, 0xc1, 0x5, 0x43, 0x33, 0x45, + 0x5b, 0x34, 0x9, 0xbc, 0xcc, 0xba, 0x51, 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, + 0x96, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8c, 0x10, 0x0, 0x0, + 0x11, 0x0, 0x9, 0xfd, 0xcc, 0xde, 0xf5, 0x0, + 0x0, 0x2, 0x33, 0x21, 0x0, 0x0, + + /* U+3055 "さ" */ + 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x96, 0x0, 0x0, 0x0, 0x0, 0x4, 0xb0, 0x47, + 0x9, 0xec, 0xcc, 0xdf, 0xeb, 0x70, 0x1, 0x12, + 0x21, 0x87, 0x0, 0x0, 0x0, 0x0, 0x1, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0x70, 0x0, 0x62, + 0x0, 0x49, 0x9f, 0x20, 0xe, 0x0, 0x1, 0x46, + 0x81, 0x2, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x1e, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8d, 0x64, 0x34, + 0x55, 0x0, 0x0, 0x39, 0xbb, 0xb9, 0x50, 0x0, + + /* U+3056 "ざ" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x80, 0x0, 0x0, + 0x8, 0x30, 0x67, 0x85, 0x0, 0x0, 0x7, 0x80, + 0xa, 0x13, 0x45, 0x43, 0x36, 0xd8, 0xbe, 0x10, + 0x69, 0xab, 0xaa, 0xd9, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x30, 0x0, 0x2, 0x0, 0x2, 0x46, 0xc0, 0x0, + 0xe, 0x20, 0x3, 0x9a, 0xc2, 0x0, 0x2c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0xb5, 0x22, 0x34, 0x40, 0x0, + 0x0, 0x5a, 0xcc, 0xca, 0x50, 0x0, + + /* U+3057 "し" */ + 0xc6, 0x0, 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0xb4, + 0x0, 0x0, 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, + 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0xc3, 0x0, + 0x0, 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x0, + 0xd2, 0x0, 0x0, 0x0, 0xb1, 0xb4, 0x0, 0x0, + 0xb, 0xb0, 0x7d, 0x30, 0x26, 0xda, 0x0, 0x7, + 0xdf, 0xda, 0x40, 0x0, + + /* U+3058 "じ" */ + 0x82, 0x0, 0x0, 0x0, 0x0, 0xd3, 0x0, 0x12, + 0x76, 0x0, 0xd2, 0x0, 0x2c, 0xd, 0x10, 0xe1, + 0x0, 0x9, 0x53, 0x10, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0xe1, 0x0, 0x0, 0x0, 0x0, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0xf0, 0x0, 0x0, 0x0, 0x90, 0xe2, 0x0, 0x0, + 0x1b, 0xa0, 0xab, 0x20, 0x26, 0xe9, 0x0, 0x9, + 0xef, 0xda, 0x30, 0x0, + + /* U+3059 "す" */ + 0x0, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xd0, 0x0, 0x0, 0x5d, 0xee, 0xdd, + 0xef, 0xdd, 0xee, 0x30, 0x0, 0x0, 0x1, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x9d, 0xee, 0x0, 0x0, + 0x0, 0x0, 0x7a, 0x3, 0xf0, 0x0, 0x0, 0x0, + 0xa, 0x50, 0xf, 0x0, 0x0, 0x0, 0x0, 0x7b, + 0x16, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x8c, 0xac, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x5d, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x6a, 0x20, 0x0, 0x0, 0x0, + + /* U+305A "ず" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, + 0x0, 0x0, 0xf1, 0x58, 0x76, 0x0, 0x0, 0x0, + 0xe, 0x10, 0xa1, 0x42, 0xde, 0xee, 0xee, 0xfe, + 0xee, 0xe6, 0x1, 0x0, 0x0, 0xd, 0x10, 0x0, + 0x0, 0x0, 0x2, 0xbc, 0xf1, 0x0, 0x0, 0x0, + 0x0, 0xd5, 0x1d, 0x20, 0x0, 0x0, 0x0, 0x1e, + 0x0, 0xa6, 0x0, 0x0, 0x0, 0x0, 0xe5, 0x1e, + 0x70, 0x0, 0x0, 0x0, 0x3, 0xbb, 0xe4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xbd, 0x10, 0x0, 0x0, 0x0, 0x0, + 0xa7, 0x0, 0x0, 0x0, 0x0, + + /* U+305B "せ" */ + 0x0, 0x0, 0x50, 0x0, 0x8, 0x40, 0x0, 0x0, + 0x1e, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0xe0, + 0x0, 0x9, 0x40, 0x0, 0x1, 0x3e, 0x57, 0x8a, + 0xed, 0xee, 0x1f, 0xdb, 0xf8, 0x65, 0x3b, 0x40, + 0x0, 0x0, 0xe, 0x0, 0x0, 0xb3, 0x0, 0x0, + 0x0, 0xe0, 0x1, 0xd, 0x10, 0x0, 0x0, 0xe, + 0x0, 0x8d, 0xb0, 0x0, 0x0, 0x0, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5e, 0xed, 0xde, 0xf6, 0x0, + 0x0, 0x0, 0x1, 0x21, 0x10, 0x0, + + /* U+305C "ぜ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x4, 0x10, 0x0, 0x2a, 0x53, 0xb0, 0x0, 0xc, + 0x30, 0x0, 0x2c, 0x19, 0x72, 0x0, 0xc, 0x30, + 0x0, 0x2b, 0x2, 0x0, 0x0, 0x1c, 0x76, 0x79, + 0xbe, 0xcd, 0x50, 0xcf, 0xdf, 0xb8, 0x75, 0x6b, + 0x11, 0x0, 0x10, 0xc, 0x20, 0x0, 0x3a, 0x0, + 0x0, 0x0, 0xc, 0x20, 0x0, 0x59, 0x0, 0x0, + 0x0, 0xc, 0x20, 0x4d, 0xe5, 0x0, 0x0, 0x0, + 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, + 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xde, + 0xcc, 0xde, 0xd0, 0x0, 0x0, 0x0, 0x1, 0x22, + 0x21, 0x0, 0x0, + + /* U+305D "そ" */ + 0x0, 0x2, 0x23, 0x34, 0x60, 0x0, 0x0, 0x3c, + 0xba, 0x9d, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x7c, + 0x10, 0x0, 0x0, 0x0, 0xa, 0x90, 0x0, 0x0, + 0x0, 0x2, 0xc7, 0x0, 0x1, 0x10, 0x26, 0x8e, + 0xec, 0xee, 0xcc, 0xc3, 0x48, 0x64, 0x3b, 0x50, + 0x0, 0x0, 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0x94, + 0x41, 0x0, 0x0, 0x0, 0x2, 0x7a, 0xb3, 0x0, + + /* U+305E "ぞ" */ + 0x0, 0x59, 0x9a, 0xbc, 0xc0, 0x0, 0x0, 0x34, + 0x43, 0x4e, 0x60, 0x70, 0x0, 0x0, 0x2, 0xd4, + 0x1a, 0x58, 0x0, 0x0, 0x3d, 0x30, 0xa, 0x35, + 0x0, 0x5, 0xd2, 0x0, 0x2, 0x20, 0x47, 0xaf, + 0xdd, 0xed, 0xcb, 0xc0, 0x67, 0x53, 0x4b, 0x30, + 0x0, 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8d, 0x84, + 0x40, 0x0, 0x0, 0x0, 0x3, 0x9b, 0xb0, 0x0, + + /* U+305F "た" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x90, 0x20, + 0x0, 0x0, 0x8a, 0xad, 0xee, 0xd2, 0x0, 0x0, + 0x34, 0x4e, 0x30, 0x0, 0x0, 0x0, 0x0, 0x1e, + 0x0, 0x8c, 0xcc, 0xc5, 0x0, 0x6a, 0x0, 0x22, + 0x11, 0x21, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf1, 0x3, 0x30, 0x0, 0x0, 0x5, 0xb0, + 0x8, 0x60, 0x0, 0x0, 0xc, 0x60, 0x8, 0x90, + 0x0, 0x0, 0x3f, 0x0, 0x1, 0xbe, 0xdd, 0xfa, + 0x3, 0x0, 0x0, 0x0, 0x11, 0x0, + + /* U+3060 "だ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x89, 0x0, 0x0, 0x45, 0x60, 0x0, 0x9, 0x60, + 0x20, 0xb, 0x2c, 0x19, 0x99, 0xed, 0xed, 0x0, + 0x25, 0x0, 0x55, 0x6f, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xb0, 0x9, 0xbc, 0xbb, 0x0, 0x0, + 0x97, 0x0, 0x33, 0x22, 0x30, 0x0, 0xe, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x3, 0xd0, 0x3, 0x10, + 0x0, 0x0, 0x0, 0x88, 0x0, 0xb3, 0x0, 0x0, + 0x0, 0xe, 0x30, 0xb, 0x50, 0x0, 0x0, 0x6, + 0xd0, 0x0, 0x3d, 0xdb, 0xde, 0x40, 0x23, 0x0, + 0x0, 0x2, 0x32, 0x10, 0x0, + + /* U+3061 "ち" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4b, + 0x0, 0x0, 0x0, 0x0, 0x6, 0x80, 0x13, 0x58, + 0x5, 0xee, 0xfe, 0xdc, 0xb9, 0x60, 0x0, 0xc, + 0x20, 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x59, 0x29, 0xbd, 0xb5, 0x0, 0xb, + 0xdb, 0x52, 0x3, 0xd6, 0x1, 0xf6, 0x0, 0x0, + 0x4, 0xc0, 0x2, 0x0, 0x0, 0x0, 0x4c, 0x0, + 0x0, 0x0, 0x0, 0x3d, 0x50, 0x0, 0x48, 0x89, + 0xce, 0x50, 0x0, 0x2, 0x66, 0x63, 0x0, 0x0, + + /* U+3063 "っ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x27, 0xad, + 0xed, 0x60, 0x6d, 0xd7, 0x30, 0x1, 0xc6, 0x22, + 0x0, 0x0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, + 0x4b, 0x0, 0x0, 0x0, 0x0, 0xb7, 0x0, 0x0, + 0x0, 0x5c, 0xa0, 0x0, 0x8, 0xde, 0xb4, 0x0, + 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+3064 "つ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0x8b, 0xee, 0xea, 0x20, 0x49, 0xec, 0x73, 0x0, + 0x7, 0xe1, 0x78, 0x20, 0x0, 0x0, 0x0, 0x98, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5b, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7a, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x80, + 0x0, 0x0, 0x34, 0x7c, 0xe7, 0x0, 0x0, 0x0, + 0xdb, 0x95, 0x0, 0x0, + + /* U+3065 "づ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x95, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x94, 0x80, 0x0, 0x0, 0x15, + 0x9b, 0xb9, 0x41, 0x0, 0x3, 0x7c, 0xd9, 0x53, + 0x26, 0xe6, 0x0, 0x1e, 0x93, 0x0, 0x0, 0x0, + 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5, 0xe4, 0x0, 0x0, 0x0, + 0x2, 0x47, 0xdd, 0x30, 0x0, 0x0, 0x0, 0x7e, + 0xc9, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+3066 "て" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x35, 0x68, + 0x9b, 0xce, 0xff, 0xe3, 0xaa, 0x86, 0x43, 0xb9, + 0x10, 0x0, 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x96, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa7, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5d, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xd6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4b, + 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + + /* U+3067 "で" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x23, 0x56, + 0x89, 0xbc, 0xdf, 0xf3, 0xbb, 0x97, 0x54, 0xbb, + 0x30, 0x0, 0x0, 0x0, 0x9, 0x90, 0x1, 0x81, + 0x0, 0x0, 0x2d, 0x0, 0x2b, 0x3a, 0x0, 0x0, + 0x86, 0x0, 0x7, 0x22, 0x0, 0x0, 0xb4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa7, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5d, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d, + 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, + + /* U+3068 "と" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x70, 0x0, + 0x0, 0x0, 0x3, 0xd0, 0x0, 0x0, 0x30, 0x0, + 0xc5, 0x0, 0x2a, 0xd1, 0x0, 0x4c, 0x19, 0xd6, + 0x0, 0x0, 0xd, 0xe7, 0x0, 0x0, 0x0, 0xab, + 0x10, 0x0, 0x0, 0x8, 0xa0, 0x0, 0x0, 0x0, + 0xf, 0x10, 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x91, 0x0, 0x0, 0x13, 0x1, + 0x9e, 0xed, 0xef, 0xfa, 0x0, 0x0, 0x12, 0x10, + 0x0, + + /* U+3069 "ど" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x10, + 0x0, 0x0, 0x32, 0xb1, 0xa, 0x70, 0x0, 0x0, + 0x2b, 0x48, 0x3, 0xe0, 0x0, 0x2, 0x56, 0x0, + 0x0, 0xb5, 0x1, 0x9d, 0x50, 0x0, 0x0, 0x3d, + 0x8d, 0x60, 0x0, 0x0, 0x0, 0x3f, 0x80, 0x0, + 0x0, 0x0, 0x3, 0xe4, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x30, 0x0, 0x0, 0x0, 0x0, 0x3d, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0xd7, 0x44, 0x56, 0x86, 0x0, + 0x0, 0x49, 0xbb, 0xba, 0x84, 0x0, + + /* U+306A "な" */ + 0x0, 0x0, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf3, + 0x61, 0x1, 0x0, 0x5, 0xee, 0xee, 0xb7, 0x14, + 0xe6, 0x0, 0x0, 0xa, 0x50, 0x0, 0x1, 0xbb, + 0x0, 0x1, 0xe0, 0x0, 0x15, 0x0, 0x50, 0x0, + 0x88, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x1e, 0x10, + 0x0, 0x1c, 0x0, 0x0, 0x9, 0x90, 0x0, 0x11, + 0xd0, 0x0, 0x2, 0xe1, 0x6, 0xdb, 0xdf, 0x50, + 0x0, 0x0, 0x1, 0xe0, 0x0, 0xeb, 0xd2, 0x0, + 0x0, 0x1e, 0x20, 0x5c, 0x7, 0x70, 0x0, 0x0, + 0x6c, 0xed, 0x30, 0x0, 0x0, + + /* U+306B "に" */ + 0x4, 0x40, 0x0, 0x0, 0x0, 0x0, 0x9, 0x60, + 0x3, 0x43, 0x33, 0x40, 0xb, 0x30, 0x5, 0xbb, + 0xbb, 0xa1, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2b, 0x91, 0xa, 0x0, 0x0, 0x0, + 0x1d, 0xb0, 0x3b, 0x0, 0x0, 0x0, 0xf, 0x70, + 0x1e, 0x62, 0x24, 0x64, 0xd, 0x30, 0x3, 0xac, + 0xdc, 0xb5, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, + + /* U+306C "ぬ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x7, 0x0, 0x0, + 0xf0, 0x0, 0x0, 0x0, 0xc3, 0x7, 0xcf, 0xdc, + 0x40, 0x0, 0x7, 0xac, 0x65, 0xa0, 0x2c, 0x50, + 0x0, 0x5f, 0x10, 0x77, 0x0, 0x2e, 0x0, 0xd, + 0xb5, 0xc, 0x30, 0x0, 0xc2, 0x7, 0x73, 0xd3, + 0xd0, 0x0, 0xc, 0x20, 0xb2, 0xa, 0xe6, 0x29, + 0x95, 0xe0, 0xd, 0x10, 0x7c, 0xd, 0x43, 0x9f, + 0x20, 0x99, 0x9d, 0x10, 0xe0, 0x1b, 0x9d, 0x11, + 0x87, 0x10, 0x7, 0xdd, 0x70, 0x40, + + /* U+306D "ね" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd6, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x40, + 0x0, 0x0, 0x0, 0x4, 0x79, 0xf8, 0x7, 0xdd, + 0xc1, 0x0, 0x57, 0x4f, 0x4c, 0x60, 0x6, 0xb0, + 0x0, 0x1, 0xfd, 0x20, 0x0, 0xe, 0x10, 0x0, + 0xaf, 0x10, 0x0, 0x0, 0xc3, 0x0, 0x4d, 0xe0, + 0x0, 0x0, 0xc, 0x20, 0x1e, 0x3e, 0x0, 0x3b, + 0xb7, 0xe1, 0xb, 0x70, 0xe0, 0xe, 0x30, 0x4f, + 0x70, 0x50, 0xe, 0x0, 0xe1, 0x7, 0x9c, 0x60, + 0x0, 0xf0, 0x6, 0xcd, 0x90, 0x1, 0x0, 0x8, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+306E "の" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xad, 0xfd, 0x91, 0x0, 0x0, 0x9b, 0x46, 0xa1, + 0x5e, 0x40, 0x8, 0x90, 0x9, 0x70, 0x2, 0xe1, + 0x3d, 0x0, 0xc, 0x40, 0x0, 0x97, 0x77, 0x0, + 0xf, 0x10, 0x0, 0x5a, 0xa4, 0x0, 0x5c, 0x0, + 0x0, 0x5a, 0x95, 0x0, 0xb6, 0x0, 0x0, 0x97, + 0x5c, 0x5, 0xe0, 0x0, 0x2, 0xe2, 0xb, 0xff, + 0x30, 0x0, 0x5e, 0x60, 0x0, 0x31, 0x0, 0x9e, + 0xc3, 0x0, 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, + + /* U+306F "は" */ + 0x5, 0x40, 0x0, 0x0, 0x82, 0x0, 0x0, 0xa5, + 0x0, 0x0, 0xc, 0x30, 0x0, 0xc, 0x20, 0x0, + 0x0, 0xc4, 0x33, 0x0, 0xe0, 0x7, 0xee, 0xef, + 0xdb, 0x60, 0xd, 0x0, 0x0, 0x0, 0xb2, 0x0, + 0x1, 0xb0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x3b, + 0x0, 0x0, 0x0, 0xa4, 0x0, 0x3, 0xb9, 0x0, + 0x6a, 0xbd, 0x60, 0x0, 0x2d, 0xa0, 0x6a, 0x11, + 0xae, 0xb1, 0x0, 0xf5, 0x9, 0x70, 0xc, 0x47, + 0xd0, 0xd, 0x20, 0x2d, 0xdd, 0xc0, 0x1, 0x0, + 0x20, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+3070 "ば" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x80, + 0x0, 0x0, 0x9, 0x28, 0x92, 0xe, 0x0, 0x0, + 0x0, 0xf0, 0xb3, 0x43, 0xb0, 0x0, 0x0, 0xf, + 0x14, 0x20, 0x59, 0x0, 0xae, 0xee, 0xfd, 0xb4, + 0x7, 0x60, 0x0, 0x0, 0xf, 0x0, 0x0, 0x85, + 0x0, 0x0, 0x0, 0xe0, 0x0, 0x9, 0x40, 0x0, + 0x0, 0xd, 0x10, 0x0, 0xa5, 0x90, 0x6, 0x99, + 0xe2, 0x0, 0x9, 0xb5, 0xa, 0x82, 0x3d, 0xe6, + 0x0, 0x8f, 0x10, 0xe0, 0x0, 0xe5, 0xe8, 0x6, + 0xc0, 0xc, 0x83, 0x6e, 0x2, 0x60, 0x29, 0x0, + 0x18, 0xba, 0x20, 0x0, 0x0, + + /* U+3071 "ぱ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x99, 0x20, 0x80, + 0x0, 0x0, 0x9, 0x36, 0x8, 0xe, 0x0, 0x0, + 0x0, 0xf0, 0xa9, 0x43, 0xb0, 0x0, 0x0, 0xf, + 0x13, 0x30, 0x59, 0x0, 0xae, 0xee, 0xfd, 0xb4, + 0x7, 0x60, 0x0, 0x0, 0xf, 0x0, 0x0, 0x85, + 0x0, 0x0, 0x0, 0xe0, 0x0, 0x9, 0x40, 0x0, + 0x0, 0xd, 0x10, 0x0, 0xa5, 0x90, 0x6, 0x99, + 0xe2, 0x0, 0x9, 0xb5, 0xa, 0x82, 0x3d, 0xe6, + 0x0, 0x8f, 0x10, 0xe0, 0x0, 0xe5, 0xe8, 0x6, + 0xc0, 0xc, 0x83, 0x6e, 0x2, 0x60, 0x29, 0x0, + 0x18, 0xba, 0x20, 0x0, 0x0, + + /* U+3072 "ひ" */ + 0x13, 0x46, 0x9b, 0x0, 0x85, 0x0, 0x5, 0xb9, + 0xad, 0x20, 0x6, 0x90, 0x0, 0x0, 0x1d, 0x20, + 0x0, 0x5e, 0x0, 0x0, 0x9, 0x60, 0x0, 0x4, + 0xf5, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x3a, 0xd1, + 0x0, 0x78, 0x0, 0x0, 0x4, 0x85, 0xc0, 0xa, + 0x50, 0x0, 0x0, 0x78, 0x7, 0x0, 0xb4, 0x0, + 0x0, 0xa, 0x40, 0x0, 0x9, 0x70, 0x0, 0x2, + 0xe0, 0x0, 0x0, 0x2e, 0x61, 0x15, 0xe3, 0x0, + 0x0, 0x0, 0x3b, 0xef, 0xb4, 0x0, 0x0, 0x0, + + /* U+3073 "び" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x34, 0xa1, 0x23, 0x57, 0xa8, + 0x0, 0xb1, 0xb3, 0x68, 0xb9, 0xca, 0x10, 0xa, + 0x53, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x9a, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x8, 0xf2, 0x0, 0x5, + 0x90, 0x0, 0x0, 0x79, 0xa0, 0x0, 0xb3, 0x0, + 0x0, 0x8, 0x4a, 0x80, 0xe, 0x10, 0x0, 0x0, + 0xb4, 0x7, 0x0, 0xf0, 0x0, 0x0, 0xd, 0x0, + 0x0, 0xd, 0x30, 0x0, 0x6, 0xa0, 0x0, 0x0, + 0x6d, 0x30, 0x17, 0xd1, 0x0, 0x0, 0x0, 0x6d, + 0xfe, 0xa2, 0x0, 0x0, 0x0, + + /* U+3074 "ぴ" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x99, 0x32, 0x45, + 0x79, 0x60, 0xa, 0x63, 0x18, 0x79, 0x7d, 0x80, + 0x0, 0xd2, 0x78, 0x10, 0x5, 0xb0, 0x0, 0xc, + 0x70, 0x0, 0x0, 0xd1, 0x0, 0x0, 0xae, 0x0, + 0x0, 0x69, 0x0, 0x0, 0x9, 0x89, 0x0, 0xc, + 0x30, 0x0, 0x0, 0xa1, 0xb8, 0x0, 0xe0, 0x0, + 0x0, 0xd, 0x1, 0x60, 0xf, 0x0, 0x0, 0x1, + 0xc0, 0x0, 0x0, 0xd3, 0x0, 0x0, 0x87, 0x0, + 0x0, 0x6, 0xd3, 0x2, 0x8b, 0x0, 0x0, 0x0, + 0x6, 0xdf, 0xe9, 0x0, 0x0, 0x0, + + /* U+3075 "ふ" */ + 0x0, 0x0, 0x9, 0x91, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6e, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0x30, 0x0, 0x0, 0x0, 0x0, 0x6, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xd2, 0x0, + 0x41, 0x0, 0x0, 0x0, 0x0, 0x3d, 0x10, 0x6a, + 0x0, 0x0, 0x8, 0x80, 0x7, 0xa0, 0xc, 0x40, + 0x1, 0xbb, 0x0, 0x0, 0xf0, 0x4, 0xd0, 0x2e, + 0x70, 0x0, 0x2, 0xf1, 0x0, 0xd3, 0x2, 0x0, + 0x8f, 0xdf, 0x80, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x10, 0x0, 0x0, 0x0, + + /* U+3076 "ぶ" */ + 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xbc, 0x30, 0x43, 0x80, 0x0, 0x0, + 0x0, 0x8, 0xd0, 0x94, 0xb2, 0x0, 0x0, 0x0, + 0xa, 0x20, 0x17, 0x0, 0x0, 0x0, 0x7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xb0, 0x0, + 0x30, 0x0, 0x0, 0x0, 0x0, 0xa8, 0x0, 0xc4, + 0x0, 0x0, 0xb, 0x30, 0xd, 0x40, 0x2d, 0x0, + 0x2, 0xd8, 0x0, 0x5, 0xa0, 0xa, 0x70, 0x5e, + 0x60, 0x0, 0x6, 0xb0, 0x3, 0xe0, 0x22, 0x0, + 0xdc, 0xcf, 0x50, 0x0, 0x30, 0x0, 0x0, 0x2, + 0x31, 0x0, 0x0, 0x0, + + /* U+3077 "ぷ" */ + 0x0, 0x0, 0x7, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xd9, 0x10, 0x49, 0x90, 0x0, 0x0, + 0x0, 0x9, 0xd0, 0x90, 0x72, 0x0, 0x0, 0x0, + 0xb, 0x30, 0x49, 0x90, 0x0, 0x0, 0x6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xa0, 0x0, + 0x20, 0x0, 0x0, 0x0, 0x0, 0xa7, 0x0, 0xd3, + 0x0, 0x0, 0xb, 0x30, 0xd, 0x30, 0x3d, 0x0, + 0x2, 0xc9, 0x0, 0x6, 0xa0, 0xb, 0x50, 0x5e, + 0x60, 0x0, 0x6, 0xb0, 0x4, 0xc0, 0x22, 0x0, + 0xdc, 0xcf, 0x50, 0x0, 0x30, 0x0, 0x0, 0x2, + 0x31, 0x0, 0x0, 0x0, + + /* U+3078 "へ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1b, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd9, 0xc9, 0x0, 0x0, 0x0, 0x0, 0xa, 0x90, + 0xd, 0x70, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x1, + 0xe5, 0x0, 0x0, 0x6, 0xe1, 0x0, 0x0, 0x3e, + 0x40, 0x0, 0xc, 0x40, 0x0, 0x0, 0x4, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xf1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + + /* U+3079 "べ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3, 0x1c, 0x0, 0x0, 0x0, + 0x7, 0x30, 0xb, 0x37, 0x70, 0x0, 0x0, 0xbc, + 0xe3, 0x2, 0xb0, 0x30, 0x0, 0x9, 0xa0, 0x3e, + 0x20, 0x0, 0x0, 0x0, 0x6d, 0x0, 0x5, 0xd1, + 0x0, 0x0, 0x4, 0xe2, 0x0, 0x0, 0x8c, 0x0, + 0x0, 0x1f, 0x40, 0x0, 0x0, 0xa, 0xc0, 0x0, + 0x2, 0x0, 0x0, 0x0, 0x0, 0xbb, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x60, + + /* U+307A "ぺ" */ + 0x0, 0x0, 0x0, 0x0, 0x3, 0xba, 0x10, 0x0, + 0x0, 0x4, 0x10, 0xa, 0x2, 0x80, 0x0, 0x0, + 0x8e, 0xe2, 0xa, 0x25, 0x70, 0x0, 0x6, 0xd1, + 0x5e, 0x11, 0x87, 0x0, 0x0, 0x3e, 0x20, 0x7, + 0xd0, 0x0, 0x0, 0x2, 0xe4, 0x0, 0x0, 0x9b, + 0x0, 0x0, 0x1e, 0x70, 0x0, 0x0, 0xb, 0xb0, + 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0xca, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x90, + + /* U+307B "ほ" */ + 0x5, 0x50, 0x0, 0x0, 0x0, 0x10, 0x0, 0xa5, + 0x1, 0xed, 0xde, 0xdc, 0x30, 0xc, 0x20, 0x0, + 0x0, 0xe0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xe, + 0x0, 0x0, 0xd, 0x0, 0x4c, 0xcc, 0xfd, 0xe8, + 0x1, 0xc0, 0x0, 0x11, 0x2e, 0x0, 0x0, 0x3b, + 0x10, 0x0, 0x0, 0xd0, 0x0, 0x3, 0xb9, 0x0, + 0x6a, 0xae, 0x30, 0x0, 0x2d, 0x90, 0x7a, 0x22, + 0xdd, 0xa1, 0x0, 0xf5, 0x9, 0x70, 0xe, 0x16, + 0xd0, 0xd, 0x20, 0x1b, 0xde, 0x90, 0x1, 0x0, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+307C "ぼ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x90, + 0x0, 0x0, 0x0, 0xa, 0x65, 0x1d, 0x0, 0x5d, + 0xdd, 0xed, 0xe2, 0x54, 0xa0, 0x0, 0x0, 0x2b, + 0x0, 0x0, 0x68, 0x0, 0x0, 0x2, 0xb0, 0x0, + 0x8, 0x60, 0x6, 0xbb, 0xbe, 0xcd, 0x50, 0x94, + 0x0, 0x12, 0x24, 0xc1, 0x0, 0xa, 0x30, 0x0, + 0x0, 0x1c, 0x0, 0x0, 0xb3, 0x60, 0x0, 0x1, + 0xd0, 0x0, 0xa, 0x96, 0x5, 0xdc, 0xcf, 0x60, + 0x0, 0x9f, 0x10, 0xe1, 0x0, 0xe9, 0xd3, 0x7, + 0xc0, 0xd, 0x73, 0x7c, 0x4, 0x80, 0x49, 0x0, + 0x16, 0xa9, 0x20, 0x0, 0x0, + + /* U+307D "ぽ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x79, 0x50, 0x70, + 0x0, 0x0, 0x0, 0x9, 0x9, 0x1d, 0x0, 0x5d, + 0xdd, 0xed, 0xb9, 0x33, 0xa0, 0x0, 0x0, 0x2b, + 0x0, 0x0, 0x68, 0x0, 0x0, 0x2, 0xb0, 0x0, + 0x8, 0x60, 0x6, 0xbb, 0xbe, 0xcd, 0x50, 0x94, + 0x0, 0x12, 0x24, 0xc1, 0x0, 0xa, 0x30, 0x0, + 0x0, 0x1c, 0x0, 0x0, 0xb3, 0x60, 0x0, 0x1, + 0xd0, 0x0, 0xa, 0x96, 0x5, 0xdc, 0xcf, 0x60, + 0x0, 0x9f, 0x10, 0xe1, 0x0, 0xe9, 0xd3, 0x7, + 0xc0, 0xd, 0x73, 0x7c, 0x4, 0x80, 0x39, 0x0, + 0x16, 0xa9, 0x20, 0x0, 0x0, + + /* U+307E "ま" */ + 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x31, 0x0, + 0xe1, 0x24, 0x50, 0xb, 0xcd, 0xdf, 0xcb, 0xa7, + 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x4, 0x21, + 0x1f, 0x23, 0x56, 0x1, 0xab, 0xcc, 0xfb, 0xa9, + 0x70, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x17, + 0xaa, 0xf4, 0x0, 0x0, 0xc, 0x73, 0x3d, 0xdc, + 0x40, 0x2, 0xd0, 0x0, 0xd2, 0x5e, 0x80, 0xe, + 0x62, 0x6e, 0x0, 0x1b, 0x0, 0x28, 0xb9, 0x30, + 0x0, 0x0, + + /* U+307F "み" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0xc, + 0xee, 0xdf, 0x60, 0x0, 0x0, 0x0, 0x0, 0x2, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa5, 0x0, + 0x1, 0x0, 0x0, 0x0, 0x2d, 0x0, 0x3, 0xb0, + 0x0, 0x2a, 0xdf, 0xee, 0xb5, 0x4a, 0x0, 0x2d, + 0x41, 0xe0, 0x3, 0x9f, 0xb0, 0xb, 0x30, 0x87, + 0x0, 0x0, 0xbc, 0xd1, 0xd1, 0x2e, 0x0, 0x0, + 0x4d, 0x4, 0x7, 0xee, 0x50, 0x0, 0x2e, 0x30, + 0x0, 0x1, 0x10, 0x0, 0x7e, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, + + /* U+3080 "む" */ + 0x0, 0xd, 0x20, 0x0, 0x0, 0x0, 0x10, 0xc, + 0x35, 0x60, 0x42, 0x0, 0x9d, 0xdf, 0xc9, 0x50, + 0x4e, 0x40, 0x0, 0xc, 0x10, 0x0, 0x2, 0xe3, + 0x5, 0xbf, 0x10, 0x0, 0x0, 0x31, 0x3c, 0x1b, + 0x40, 0x0, 0x0, 0x0, 0x85, 0x8, 0x60, 0x0, + 0x0, 0x0, 0x87, 0xc, 0x30, 0x0, 0x9, 0x10, + 0x2e, 0xec, 0x0, 0x0, 0xc, 0x30, 0x0, 0x5b, + 0x0, 0x0, 0xe, 0x20, 0x0, 0x2e, 0x42, 0x34, + 0xac, 0x0, 0x0, 0x5, 0xac, 0xba, 0x70, 0x0, + + /* U+3081 "め" */ + 0x0, 0x0, 0x0, 0xa, 0x40, 0x0, 0x4, 0xb0, + 0x0, 0xd, 0x10, 0x0, 0x0, 0xe1, 0x59, 0xcf, + 0x82, 0x0, 0x0, 0xae, 0x94, 0x79, 0x6d, 0x50, + 0x2, 0xeb, 0x0, 0xc2, 0x1, 0xe2, 0xd, 0x3e, + 0x12, 0xd0, 0x0, 0x78, 0x69, 0x7, 0x9a, 0x60, + 0x0, 0x4b, 0xa4, 0x0, 0xed, 0x0, 0x0, 0x69, + 0xb3, 0x1, 0xdd, 0x10, 0x0, 0xa6, 0x7b, 0x5d, + 0x67, 0x20, 0x7, 0xd0, 0x8, 0xa4, 0x0, 0x26, + 0xcc, 0x20, 0x0, 0x0, 0x0, 0x79, 0x50, 0x0, + + /* U+3082 "も" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3d, + 0x0, 0x0, 0x0, 0x11, 0x4, 0xa0, 0x0, 0x0, + 0x5, 0xce, 0xde, 0xcd, 0x60, 0x0, 0x0, 0x9, + 0x72, 0x10, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, + 0x0, 0x75, 0x2c, 0x20, 0x20, 0x4b, 0x6, 0x9c, + 0xfe, 0xed, 0x40, 0xb6, 0x0, 0xe, 0x0, 0x0, + 0x4, 0xb0, 0x0, 0xf0, 0x0, 0x0, 0x2d, 0x0, + 0xd, 0x20, 0x0, 0x8, 0xa0, 0x0, 0x7c, 0x42, + 0x4a, 0xe1, 0x0, 0x0, 0x6b, 0xca, 0x70, 0x0, + + /* U+3083 "ゃ" */ + 0x0, 0x0, 0x9, 0x10, 0x0, 0x0, 0x9, 0x10, + 0x5a, 0x0, 0x0, 0x0, 0x88, 0x5, 0xad, 0xda, + 0x0, 0x2, 0xfd, 0x93, 0x0, 0x98, 0x1a, 0xec, + 0x70, 0x0, 0x5, 0xa0, 0x70, 0x2d, 0x5, 0x33, + 0xc6, 0x0, 0x0, 0xb3, 0x6a, 0xa5, 0x0, 0x0, + 0x5, 0x90, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x0, 0x0, 0x0, + + /* U+3084 "や" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, 0x69, 0x0, + 0x1c, 0x40, 0x0, 0x0, 0x0, 0xe2, 0x3, 0x9b, + 0xdd, 0x80, 0x0, 0x7, 0xcc, 0xb5, 0x20, 0xa, + 0x70, 0x4a, 0xde, 0x30, 0x0, 0x0, 0x4b, 0xa, + 0x60, 0x79, 0x1, 0x0, 0xa, 0x80, 0x0, 0x1, + 0xe0, 0x6e, 0xde, 0xa0, 0x0, 0x0, 0xa, 0x60, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x4c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x33, 0x0, 0x0, 0x0, + + /* U+3085 "ゅ" */ + 0x0, 0x0, 0x7, 0x30, 0x0, 0xd, 0x10, 0x7, + 0x60, 0x0, 0xd, 0x1, 0x9d, 0xec, 0x70, 0x1c, + 0x3c, 0x44, 0x90, 0x98, 0x2c, 0xb0, 0x3, 0xa0, + 0xd, 0x2f, 0x32, 0x5, 0x80, 0x1d, 0x1e, 0x9, + 0x78, 0x60, 0x98, 0xd, 0x0, 0x9f, 0xde, 0x90, + 0x0, 0x0, 0x7a, 0x10, 0x0, 0x0, 0x4, 0xb1, + 0x0, 0x0, + + /* U+3086 "ゆ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb5, 0x0, 0x0, 0x9, 0x30, 0x0, 0x77, + 0x0, 0x0, 0xc, 0x10, 0x19, 0xef, 0xd9, 0x10, + 0xd, 0x4, 0xc5, 0x5a, 0x6, 0xd0, 0xd, 0x3b, + 0x10, 0x3b, 0x0, 0x87, 0xd, 0xb1, 0x0, 0x3a, + 0x0, 0x4a, 0xf, 0x70, 0x10, 0x48, 0x0, 0x69, + 0xf, 0x23, 0xc0, 0x67, 0x0, 0xc5, 0xd, 0x10, + 0x8c, 0xc7, 0x5c, 0xa0, 0x7, 0x10, 0x5, 0xfb, + 0x95, 0x0, 0x0, 0x0, 0xb, 0x70, 0x0, 0x0, + 0x0, 0x0, 0xa8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+3087 "ょ" */ + 0x0, 0x0, 0x49, 0x0, 0x0, 0x0, 0x0, 0x4a, + 0x0, 0x0, 0x0, 0x0, 0x4e, 0xcc, 0xd2, 0x0, + 0x0, 0x4a, 0x10, 0x0, 0x0, 0x0, 0x4a, 0x0, + 0x0, 0x0, 0x0, 0x3a, 0x0, 0x0, 0x3, 0xac, + 0xdd, 0x40, 0x0, 0x1d, 0x30, 0x2d, 0xbc, 0x20, + 0x2d, 0x10, 0x6b, 0x5, 0xe2, 0x6, 0xde, 0xd3, + 0x0, 0x20, + + /* U+3088 "よ" */ + 0x0, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xa2, + 0x24, 0x40, 0x0, 0x0, 0x5, 0xec, 0xba, 0x80, + 0x0, 0x0, 0x5, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xb0, + 0x0, 0x0, 0x0, 0x7a, 0xcc, 0xd2, 0x0, 0x0, + 0xc, 0x83, 0x26, 0xee, 0xb3, 0x0, 0x2d, 0x0, + 0x4, 0xc0, 0x6e, 0x70, 0xd, 0x83, 0x4b, 0x90, + 0x3, 0xb0, 0x1, 0x8b, 0xc8, 0x0, 0x0, 0x0, + + /* U+3089 "ら" */ + 0x0, 0x49, 0x51, 0x0, 0x0, 0x0, 0x26, 0xad, + 0xec, 0x0, 0x4, 0x10, 0x0, 0x2, 0x0, 0xd, + 0x20, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x5, 0xac, 0xdc, 0x60, 0x2d, 0xb9, + 0x20, 0x2, 0xc6, 0x5f, 0x50, 0x0, 0x0, 0x3c, + 0x24, 0x0, 0x0, 0x0, 0x5b, 0x0, 0x0, 0x0, + 0x2, 0xd6, 0x0, 0x46, 0x67, 0xbe, 0x70, 0x0, + 0x5a, 0xa9, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+308A "り" */ + 0x0, 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0x96, 0x1b, 0xde, 0x70, 0xb, 0x4c, 0x40, + 0x1d, 0x40, 0xcb, 0x30, 0x0, 0x5b, 0xe, 0xa0, + 0x0, 0x1, 0xe0, 0xf4, 0x0, 0x0, 0xf, 0xf, + 0x10, 0x0, 0x2, 0xe0, 0xd1, 0x0, 0x0, 0x5b, + 0x0, 0x0, 0x0, 0xd, 0x50, 0x0, 0x0, 0x1a, + 0xa0, 0x0, 0x4, 0x8e, 0x80, 0x0, 0x1, 0xb6, + 0x20, 0x0, 0x0, + + /* U+308B "る" */ + 0x0, 0x0, 0x0, 0x12, 0x30, 0x0, 0x9, 0xed, + 0xdc, 0xdf, 0x30, 0x0, 0x0, 0x0, 0x3d, 0x30, + 0x0, 0x0, 0x0, 0x6c, 0x10, 0x0, 0x0, 0x0, + 0x9b, 0x10, 0x0, 0x0, 0x0, 0xbf, 0xba, 0xbd, + 0x50, 0x2, 0xd9, 0x10, 0x0, 0x1c, 0x62, 0xe5, + 0x0, 0x0, 0x0, 0x3c, 0x2, 0x3, 0xcc, 0xa1, + 0x2, 0xd0, 0x0, 0xc3, 0x6, 0xb0, 0x99, 0x0, + 0x9, 0x93, 0x2f, 0xbc, 0x0, 0x0, 0x7, 0xbb, + 0x95, 0x0, + + /* U+308C "れ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe3, 0x0, 0x0, 0x0, 0x0, 0x4, 0x79, 0xf7, + 0x6, 0xde, 0x80, 0x0, 0x5, 0x64, 0xf3, 0xb7, + 0x0, 0xe2, 0x0, 0x0, 0x1, 0xfd, 0x30, 0x0, + 0xc3, 0x0, 0x0, 0xa, 0xf2, 0x0, 0x0, 0xd1, + 0x0, 0x0, 0x4e, 0xd0, 0x0, 0x0, 0xf0, 0x0, + 0x1, 0xe4, 0xd0, 0x0, 0x0, 0xd0, 0x0, 0xb, + 0x71, 0xd0, 0x0, 0x2, 0xc0, 0x0, 0x7, 0x1, + 0xd0, 0x0, 0x2, 0xd1, 0x5b, 0x0, 0x1, 0xe0, + 0x0, 0x0, 0xbf, 0xc2, 0x0, 0x1, 0x80, 0x0, + 0x0, 0x0, 0x0, + + /* U+308D "ろ" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0xa, 0xee, + 0xed, 0xef, 0x20, 0x0, 0x0, 0x0, 0x3d, 0x40, + 0x0, 0x0, 0x0, 0x4c, 0x20, 0x0, 0x0, 0x0, + 0x6b, 0x20, 0x0, 0x0, 0x0, 0x9f, 0xcb, 0xcd, + 0x60, 0x1, 0xbc, 0x30, 0x0, 0x1c, 0x52, 0xd8, + 0x0, 0x0, 0x0, 0x4c, 0x5, 0x0, 0x0, 0x0, + 0x5, 0xb0, 0x0, 0x0, 0x0, 0x1, 0xc7, 0x0, + 0x2, 0x33, 0x48, 0xe9, 0x0, 0x0, 0x5b, 0xbb, + 0x72, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+308F "わ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x40, + 0x0, 0x0, 0x0, 0x2, 0x45, 0xd7, 0x0, 0x0, + 0x0, 0x0, 0x7a, 0x8e, 0x34, 0xbd, 0xde, 0x80, + 0x0, 0x0, 0xda, 0xb3, 0x0, 0x1b, 0x90, 0x0, + 0x5f, 0x70, 0x0, 0x0, 0xe, 0x0, 0x1d, 0xe0, + 0x0, 0x0, 0x0, 0xe2, 0xc, 0x5e, 0x0, 0x0, + 0x0, 0x1f, 0x8, 0xa0, 0xe0, 0x0, 0x0, 0xb, + 0x80, 0x80, 0xe, 0x0, 0x1, 0x5d, 0xa0, 0x0, + 0x0, 0xf0, 0x2, 0xea, 0x40, 0x0, 0x0, 0x8, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+3092 "を" */ + 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x23, 0x23, + 0xe3, 0x56, 0x80, 0x0, 0x5b, 0xbe, 0xca, 0x87, + 0x60, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xaa, 0xba, 0x30, 0x28, 0xe1, 0x6, 0xe5, + 0x14, 0xdb, 0xd7, 0x10, 0x5e, 0x10, 0x9, 0xf4, + 0x0, 0x0, 0x33, 0x3, 0xd6, 0xe0, 0x0, 0x0, + 0x0, 0xd, 0x30, 0xe0, 0x0, 0x0, 0x0, 0x2d, + 0x0, 0x60, 0x0, 0x0, 0x0, 0xe, 0x74, 0x22, + 0x35, 0x20, 0x0, 0x1, 0x8b, 0xcb, 0xb9, 0x30, + + /* U+3093 "ん" */ + 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xe2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0xba, 0xc5, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0xa2, 0x3e, 0x0, 0x0, + 0x0, 0x0, 0x8c, 0x0, 0xe, 0x10, 0x1, 0xb0, + 0x1, 0xf1, 0x0, 0xe, 0x10, 0x8, 0xa0, 0x7, + 0xa0, 0x0, 0xd, 0x30, 0x3e, 0x20, 0xe, 0x30, + 0x0, 0x7, 0xfd, 0xe4, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x22, 0x0, 0x0, + + /* U+30A1 "ァ" */ + 0x8c, 0xcc, 0xcc, 0xcc, 0xc9, 0x12, 0x22, 0x22, + 0x22, 0xd6, 0x0, 0x0, 0xb3, 0x9, 0xa0, 0x0, + 0x0, 0xc2, 0x9a, 0x0, 0x0, 0x0, 0xe1, 0x10, + 0x0, 0x0, 0x2, 0xd0, 0x0, 0x0, 0x0, 0xb, + 0x60, 0x0, 0x0, 0x1, 0xba, 0x0, 0x0, 0x0, + 0x6, 0x70, 0x0, 0x0, 0x0, + + /* U+30A2 "ア" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0xfe, + 0xee, 0xee, 0xee, 0xfa, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe3, 0x0, 0x0, 0x7, 0x20, 0xc, 0x70, + 0x0, 0x0, 0xc, 0x42, 0xd7, 0x0, 0x0, 0x0, + 0xc, 0x36, 0x60, 0x0, 0x0, 0x0, 0xe, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x3d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa7, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xd0, 0x0, 0x0, 0x0, 0x2, 0xcc, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + + /* U+30A3 "ィ" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x0, 0xb, 0xb0, 0x0, 0x0, 0x0, 0x2c, 0x90, + 0x0, 0x0, 0x0, 0x7e, 0x60, 0x0, 0x0, 0x27, + 0xea, 0xe0, 0x0, 0x0, 0xbe, 0x81, 0x1e, 0x0, + 0x0, 0x2, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x1, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x2f, 0x0, 0x0, + + /* U+30A4 "イ" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0x80, 0x0, 0x0, + 0x0, 0x4, 0xf5, 0x0, 0x0, 0x0, 0x7, 0xe4, + 0x0, 0x0, 0x0, 0x3c, 0xc1, 0x0, 0x0, 0x2, + 0xae, 0xf2, 0x0, 0x1, 0x7c, 0xe7, 0xe, 0x20, + 0x0, 0x8b, 0x50, 0x0, 0xe2, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0x0, 0x0, 0xe2, + 0x0, 0x0, 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x6, + 0x10, 0x0, + + /* U+30A6 "ウ" */ + 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x30, 0x0, 0x0, 0xf, 0xee, 0xef, 0xfe, + 0xee, 0xd0, 0xf, 0x0, 0x0, 0x0, 0x5, 0xc0, + 0xf, 0x0, 0x0, 0x0, 0x8, 0x90, 0xf, 0x0, + 0x0, 0x0, 0xd, 0x40, 0x5, 0x0, 0x0, 0x0, + 0x4e, 0x0, 0x0, 0x0, 0x0, 0x1, 0xd6, 0x0, + 0x0, 0x0, 0x0, 0xc, 0xb0, 0x0, 0x0, 0x0, + 0x6, 0xea, 0x0, 0x0, 0x0, 0x5, 0xed, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + + /* U+30A7 "ェ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5e, 0xee, + 0xfe, 0xee, 0xe0, 0x0, 0x0, 0xb, 0x30, 0x0, + 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, 0xb3, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0xfe, + 0xee, 0xff, 0xee, 0xf9, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+30A8 "エ" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x1, 0x0, 0x2f, + 0xee, 0xef, 0xfe, 0xee, 0xd0, 0x0, 0x0, 0x0, + 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x30, 0x0, 0x0, 0xe, 0xee, 0xee, 0xfe, + 0xee, 0xee, 0x80, 0x22, 0x11, 0x11, 0x11, 0x11, + 0x21, + + /* U+30AA "オ" */ + 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x12, 0x22, 0x22, 0x2f, + 0x22, 0x21, 0x5d, 0xcc, 0xcc, 0xef, 0xcc, 0xc6, + 0x0, 0x0, 0x1, 0xdf, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0x6e, 0x0, 0x0, 0x0, 0x2, 0xd6, 0xe, + 0x10, 0x0, 0x0, 0x6d, 0x40, 0xe, 0x10, 0x0, + 0x3c, 0xa1, 0x0, 0xe, 0x10, 0x0, 0x54, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0x5e, 0xde, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, + + /* U+30AB "カ" */ + 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf0, 0x0, 0x0, 0x3, 0x22, 0x3e, 0x22, 0x22, + 0x12, 0xcc, 0xcd, 0xfc, 0xcc, 0xdd, 0x0, 0x0, + 0x59, 0x0, 0x2, 0xd0, 0x0, 0x8, 0x60, 0x0, + 0x3c, 0x0, 0x0, 0xe2, 0x0, 0x4, 0xa0, 0x0, + 0x5b, 0x0, 0x0, 0x69, 0x0, 0x1e, 0x30, 0x0, + 0x8, 0x70, 0x2d, 0x70, 0x0, 0x0, 0xd3, 0x1e, + 0x70, 0x0, 0xbf, 0xfb, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+30AC "ガ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x0, 0x0, + 0x2, 0xf0, 0x0, 0xa2, 0xc0, 0x0, 0x0, 0x1e, + 0x0, 0x3, 0xa5, 0x30, 0x0, 0x2, 0xd0, 0x0, + 0x3, 0x0, 0x2f, 0xfe, 0xff, 0xee, 0xef, 0xd0, + 0x0, 0x0, 0x5, 0x90, 0x0, 0x2d, 0x0, 0x0, + 0x0, 0x96, 0x0, 0x3, 0xc0, 0x0, 0x0, 0xe, + 0x20, 0x0, 0x4b, 0x0, 0x0, 0x5, 0xb0, 0x0, + 0x6, 0x90, 0x0, 0x1, 0xe3, 0x0, 0x0, 0x87, + 0x0, 0x1, 0xd7, 0x0, 0x0, 0xd, 0x30, 0x1, + 0xe8, 0x0, 0xc, 0xee, 0xc0, 0x0, 0x2, 0x0, + 0x0, 0x1, 0x20, 0x0, 0x0, + + /* U+30AD "キ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, 0x0, + 0x2, 0x0, 0x0, 0x2, 0x7e, 0xac, 0xfd, 0x30, + 0x4e, 0xfd, 0xaf, 0x63, 0x0, 0x0, 0x12, 0x0, + 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x9, 0x70, + 0x2, 0x53, 0x0, 0x2, 0x5b, 0xdd, 0xfd, 0xa4, + 0x5e, 0xfc, 0xa8, 0xe2, 0x0, 0x0, 0x12, 0x0, + 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x97, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x44, 0x0, 0x0, + + /* U+30AE "ギ" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x63, 0x0, 0x0, + 0x9, 0x20, 0x0, 0xc2, 0xc0, 0x0, 0x0, 0xb5, + 0x0, 0x4, 0x52, 0x0, 0x0, 0x8, 0xa6, 0x9c, + 0xe0, 0x0, 0x6a, 0xcf, 0xee, 0x86, 0x31, 0x0, + 0x4, 0x52, 0x1, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x20, 0x0, 0x0, 0x2, + 0xca, 0xac, 0xfd, 0x20, 0x6a, 0xdf, 0xdd, 0xc5, + 0x20, 0x0, 0x4, 0x52, 0x0, 0x4b, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x93, 0x0, 0x0, 0x0, + + /* U+30AF "ク" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x20, 0x0, 0x0, 0x0, 0x0, 0x7b, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xee, 0xee, 0xee, 0xe0, + 0x0, 0x1d, 0x50, 0x0, 0x7, 0xa0, 0x1, 0xd8, + 0x0, 0x0, 0xd, 0x40, 0x3e, 0x60, 0x0, 0x0, + 0x5d, 0x0, 0x2, 0x0, 0x0, 0x1, 0xe4, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x90, 0x0, 0x0, 0x0, + 0x1, 0xbb, 0x0, 0x0, 0x0, 0x0, 0x3d, 0xa0, + 0x0, 0x0, 0x0, 0x5b, 0xe6, 0x0, 0x0, 0x0, + 0x0, 0x66, 0x0, 0x0, 0x0, 0x0, + + /* U+30B0 "グ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0x50, 0x0, + 0x0, 0x8, 0x80, 0x0, 0xb2, 0xc1, 0x0, 0x0, + 0xe, 0x30, 0x0, 0x28, 0x21, 0x0, 0x0, 0x9f, + 0xee, 0xee, 0xf5, 0x0, 0x0, 0x6, 0xd0, 0x0, + 0x1, 0xf1, 0x0, 0x0, 0x6e, 0x10, 0x0, 0x6, + 0xb0, 0x0, 0xa, 0xc1, 0x0, 0x0, 0xd, 0x50, + 0x0, 0x3, 0x0, 0x0, 0x0, 0x8b, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5e, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x17, 0xeb, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x3a, 0x30, 0x0, + 0x0, 0x0, 0x0, + + /* U+30B1 "ケ" */ + 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x3e, 0x22, 0x22, + 0x22, 0x22, 0x0, 0xbd, 0xdd, 0xdf, 0xdd, 0xda, + 0x6, 0xd0, 0x0, 0x1f, 0x0, 0x0, 0x4f, 0x30, + 0x0, 0x3c, 0x0, 0x0, 0x84, 0x0, 0x0, 0x7a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd4, 0x0, 0x0, + 0x0, 0x0, 0x6, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x3e, 0x30, 0x0, 0x0, 0x0, 0x6, 0xe5, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x30, 0x0, 0x0, 0x0, + + /* U+30B2 "ゲ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x20, 0x0, + 0x0, 0x83, 0x0, 0x0, 0xa2, 0xb0, 0x0, 0x0, + 0xf2, 0x0, 0x0, 0x58, 0x51, 0x0, 0x5, 0xc0, + 0x0, 0x0, 0x2, 0x0, 0x0, 0xc, 0xfe, 0xef, + 0xfe, 0xef, 0x90, 0x0, 0x7c, 0x0, 0x3, 0xc0, + 0x0, 0x0, 0x5, 0xe2, 0x0, 0x6, 0xa0, 0x0, + 0x0, 0xb, 0x30, 0x0, 0x9, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x1, 0xa3, 0x0, + 0x0, 0x0, 0x0, + + /* U+30B3 "コ" */ + 0x14, 0x33, 0x33, 0x33, 0x33, 0x5c, 0xcb, 0xbb, + 0xbb, 0xce, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x0, + 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x1e, + 0x9f, 0xee, 0xee, 0xee, 0xee, 0x11, 0x11, 0x11, + 0x11, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x4, + + /* U+30B4 "ゴ" */ + 0x0, 0x0, 0x0, 0x0, 0x31, 0x91, 0x0, 0x0, + 0x0, 0x0, 0x3a, 0x3a, 0x1, 0x0, 0x0, 0x0, + 0x7, 0x1, 0xf, 0xff, 0xff, 0xff, 0xff, 0x40, + 0x0, 0x0, 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x40, 0x0, 0x0, 0x0, 0x0, 0xb, 0x40, + 0x0, 0x0, 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x40, 0x1, 0x11, 0x11, 0x11, + 0x1c, 0x40, 0x3f, 0xfe, 0xee, 0xee, 0xef, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x6, 0x20, + + /* U+30B5 "サ" */ + 0x0, 0x1, 0xd0, 0x0, 0xf, 0x0, 0x0, 0x0, + 0x1e, 0x0, 0x0, 0xf0, 0x0, 0x0, 0x1, 0xe0, + 0x0, 0xf, 0x0, 0x0, 0xff, 0xff, 0xee, 0xee, + 0xff, 0xfd, 0x0, 0x1, 0xe0, 0x0, 0xf, 0x0, + 0x0, 0x0, 0x1e, 0x0, 0x1, 0xf0, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0x2d, 0x0, 0x0, 0x0, 0x18, + 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc5, 0x0, 0x0, 0x0, 0x0, 0x0, 0xab, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xdb, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, + + /* U+30B6 "ザ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x1, 0xa0, 0x0, 0xc, 0x26, 0xa1, 0x0, 0x2, + 0xd0, 0x0, 0xf, 0xb, 0x35, 0x0, 0x1, 0xd0, + 0x0, 0xf, 0x2, 0x0, 0x1e, 0xee, 0xfe, 0xee, + 0xef, 0xee, 0xc0, 0x1, 0x12, 0xd0, 0x0, 0x1f, + 0x1, 0x10, 0x0, 0x1, 0xd0, 0x0, 0x1e, 0x0, + 0x0, 0x0, 0x2, 0xd0, 0x0, 0x3d, 0x0, 0x0, + 0x0, 0x1, 0x80, 0x0, 0x6a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xcb, 0x10, 0x0, 0x0, 0x0, 0x0, 0x3, 0x50, + 0x0, 0x0, 0x0, + + /* U+30B7 "シ" */ + 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, + 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d, 0x0, + 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x2d, 0xb2, 0x0, 0x0, 0x0, 0x98, 0x0, 0x7d, + 0x0, 0x0, 0x5, 0xe1, 0x0, 0x0, 0x0, 0x0, + 0x4e, 0x20, 0x0, 0x0, 0x0, 0x8, 0xe4, 0x0, + 0x0, 0x0, 0x2, 0xcc, 0x10, 0x0, 0x0, 0x4, + 0xbf, 0x70, 0x0, 0x0, 0x8, 0xfd, 0x70, 0x0, + 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, + + /* U+30B8 "ジ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x40, 0x0, 0x2, 0xa, 0x30, 0x0, 0x3d, 0xa1, + 0x0, 0x58, 0x2c, 0x0, 0x0, 0x9, 0xc0, 0x0, + 0xc1, 0x30, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xe8, 0x0, 0x0, 0x0, 0x9, 0x60, 0x1, + 0xbb, 0x0, 0x0, 0x5, 0xd1, 0x0, 0x0, 0x10, + 0x0, 0x5, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xe3, 0x0, 0x0, 0x0, 0x0, 0x2c, 0xb1, 0x0, + 0x0, 0x0, 0x3, 0xaf, 0x70, 0x0, 0x0, 0x0, + 0x9f, 0xe7, 0x10, 0x0, 0x0, 0x0, 0x3, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30B9 "ス" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xff, + 0xff, 0xff, 0xfe, 0x0, 0x0, 0x10, 0x0, 0x0, + 0xa8, 0x0, 0x0, 0x0, 0x0, 0x1, 0xf1, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x6d, 0x0, 0x0, 0x0, 0x0, 0x5, 0xfb, + 0x0, 0x0, 0x0, 0x0, 0x6e, 0x3a, 0xc0, 0x0, + 0x0, 0x8, 0xe2, 0x0, 0xac, 0x0, 0x6, 0xea, + 0x10, 0x0, 0xb, 0xb0, 0x3d, 0x40, 0x0, 0x0, + 0x0, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30BA "ズ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x54, 0x70, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x3b, 0x10, 0x7b, 0xbb, 0xbb, 0xbb, + 0xa5, 0x0, 0x3, 0x44, 0x44, 0x44, 0xe6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4e, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xf6, + 0x0, 0x0, 0x0, 0x0, 0x6, 0xe6, 0xe5, 0x0, + 0x0, 0x0, 0x8, 0xd2, 0x3, 0xe5, 0x0, 0x0, + 0x5d, 0xb1, 0x0, 0x3, 0xf4, 0x0, 0x8e, 0x50, + 0x0, 0x0, 0x5, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x0, + + /* U+30BB "セ" */ + 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd1, + 0x0, 0x3, 0x68, 0x0, 0x0, 0xe, 0x79, 0xce, + 0xcd, 0xb0, 0x2a, 0xdf, 0xf9, 0x52, 0x1, 0xe2, + 0x1, 0x62, 0xd, 0x10, 0x0, 0xa7, 0x0, 0x0, + 0x0, 0xd1, 0x0, 0x8b, 0x0, 0x0, 0x0, 0xd, + 0x10, 0x3, 0x0, 0x0, 0x0, 0x0, 0xd2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd, 0x40, 0x0, 0x0, + 0x10, 0x0, 0x0, 0x5e, 0xdd, 0xde, 0xf7, 0x0, + 0x0, 0x0, 0x1, 0x21, 0x0, 0x0, + + /* U+30BC "ゼ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x40, 0x0, + 0x0, 0xb1, 0x0, 0x0, 0xb2, 0xc0, 0x0, 0x0, + 0xe1, 0x0, 0x0, 0x37, 0x20, 0x0, 0x0, 0xe1, + 0x0, 0x1, 0x56, 0x0, 0x0, 0x0, 0xe6, 0x8b, + 0xed, 0xdc, 0x0, 0x29, 0xce, 0xfa, 0x63, 0x1, + 0xe2, 0x0, 0x27, 0x30, 0xe1, 0x0, 0xa, 0x80, + 0x0, 0x0, 0x0, 0xe1, 0x0, 0x8b, 0x0, 0x0, + 0x0, 0x0, 0xe1, 0x0, 0x41, 0x0, 0x0, 0x0, + 0x0, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, + 0xcb, 0xcd, 0xf7, 0x0, 0x0, 0x0, 0x1, 0x33, + 0x32, 0x0, 0x0, + + /* U+30BD "ソ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc2, 0x0, + 0x0, 0x0, 0x7b, 0x8, 0xb0, 0x0, 0x0, 0xa, + 0x70, 0xe, 0x40, 0x0, 0x0, 0xe2, 0x0, 0x6d, + 0x0, 0x0, 0x4d, 0x0, 0x0, 0x40, 0x0, 0xc, + 0x60, 0x0, 0x0, 0x0, 0x5, 0xe0, 0x0, 0x0, + 0x0, 0x3, 0xf4, 0x0, 0x0, 0x0, 0x2, 0xe6, + 0x0, 0x0, 0x0, 0x6, 0xf7, 0x0, 0x0, 0x0, + 0xc, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, + + /* U+30BF "タ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x20, 0x0, 0x0, 0x0, 0x0, 0x7c, 0x22, + 0x22, 0x20, 0x0, 0x2, 0xec, 0xcc, 0xcd, 0xf0, + 0x0, 0x1d, 0x40, 0x0, 0x7, 0x90, 0x1, 0xd7, + 0x0, 0x0, 0xd, 0x30, 0x3e, 0x60, 0x9b, 0x10, + 0x6c, 0x0, 0x13, 0x0, 0x7, 0xe7, 0xe2, 0x0, + 0x0, 0x0, 0x0, 0x3f, 0xd1, 0x0, 0x0, 0x0, + 0x1, 0xd9, 0xae, 0x0, 0x0, 0x0, 0x4e, 0x70, + 0x3, 0x0, 0x0, 0x5d, 0xc4, 0x0, 0x0, 0x0, + 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, + + /* U+30C0 "ダ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0x50, 0x0, + 0x0, 0x5, 0x90, 0x0, 0xb2, 0xc1, 0x0, 0x0, + 0xd, 0x50, 0x0, 0x49, 0x21, 0x0, 0x0, 0x7f, + 0xee, 0xee, 0xf7, 0x0, 0x0, 0x4, 0xd1, 0x0, + 0x0, 0xe3, 0x0, 0x0, 0x4e, 0x20, 0x0, 0x4, + 0xd0, 0x0, 0x7, 0xd2, 0x1d, 0x40, 0xc, 0x60, + 0x0, 0x6, 0x10, 0x4, 0xd9, 0x7c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0xf6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4e, 0x8f, 0x60, 0x0, 0x0, 0x0, + 0x7, 0xe3, 0x3, 0x20, 0x0, 0x0, 0x7, 0xeb, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x5b, 0x30, 0x0, + 0x0, 0x0, 0x0, + + /* U+30C1 "チ" */ + 0x0, 0x0, 0x0, 0x3, 0x6a, 0x10, 0x5, 0xcc, + 0xde, 0xfb, 0x85, 0x10, 0x0, 0x21, 0x2, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0xd0, 0x0, 0x0, + 0x11, 0x0, 0x3, 0xd0, 0x0, 0x11, 0x8e, 0xdd, + 0xde, 0xfd, 0xdd, 0xec, 0x0, 0x0, 0x4, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x9b, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0x0, + + /* U+30C3 "ッ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0xd0, + 0x0, 0x34, 0x4c, 0x0, 0xb4, 0x0, 0x98, 0xd, + 0x30, 0x6a, 0x0, 0xd2, 0x7, 0x80, 0x1, 0x4, + 0xd0, 0x0, 0x0, 0x0, 0xd, 0x40, 0x0, 0x0, + 0x0, 0x9a, 0x0, 0x0, 0x0, 0xb, 0xb0, 0x0, + 0x0, 0x7, 0xe9, 0x0, 0x0, 0x0, 0x6c, 0x30, + 0x0, 0x0, + + /* U+30C4 "ツ" */ + 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x25, 0x0, + 0x5b, 0x0, 0x0, 0xa4, 0x3e, 0x0, 0xe, 0x10, + 0x0, 0xf3, 0xc, 0x50, 0x9, 0x70, 0x4, 0xd0, + 0x5, 0xb0, 0x2, 0x30, 0x9, 0x80, 0x0, 0x60, + 0x0, 0x0, 0x2f, 0x10, 0x0, 0x0, 0x0, 0x0, + 0xb7, 0x0, 0x0, 0x0, 0x0, 0x9, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0xac, 0x0, 0x0, 0x0, 0x0, + 0x3c, 0xb0, 0x0, 0x0, 0x0, 0x1c, 0xe7, 0x0, + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + + /* U+30C6 "テ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xee, + 0xee, 0xee, 0xef, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9e, 0xee, 0xee, 0xee, 0xee, 0xeb, 0x0, 0x0, + 0x4, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x1f, 0x20, 0x0, 0x0, 0x0, 0x0, + 0xc8, 0x0, 0x0, 0x0, 0x0, 0x4e, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + + /* U+30C7 "デ" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x17, 0x0, 0x0, + 0x0, 0x0, 0x1, 0x85, 0xa3, 0x3, 0xee, 0xee, + 0xee, 0xe3, 0xa1, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0x60, 0x22, + 0x11, 0x19, 0x91, 0x11, 0x21, 0x0, 0x0, 0x0, + 0x96, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xe5, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x23, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30C8 "ト" */ + 0x3e, 0x0, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, + 0x1e, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, + 0x1f, 0xfa, 0x40, 0x0, 0x1e, 0x17, 0xde, 0x81, + 0x1e, 0x0, 0x4, 0xbb, 0x1e, 0x0, 0x0, 0x0, + 0x1e, 0x0, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, + 0x2f, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + + /* U+30C9 "ド" */ + 0xc2, 0x0, 0x10, 0xa0, 0xe2, 0x0, 0x86, 0x77, + 0xe2, 0x0, 0xd, 0x4, 0xe2, 0x0, 0x0, 0x0, + 0xee, 0x94, 0x0, 0x0, 0xe4, 0x8d, 0xe7, 0x10, + 0xe2, 0x0, 0x4b, 0xe0, 0xe2, 0x0, 0x0, 0x10, + 0xe2, 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, + 0xe3, 0x0, 0x0, 0x0, 0x51, 0x0, 0x0, 0x0, + + /* U+30CA "ナ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x7b, 0xbb, 0xbc, 0xfb, 0xbb, 0xba, 0x24, 0x33, + 0x36, 0xe3, 0x33, 0x43, 0x0, 0x0, 0x4, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x6d, 0x0, 0x0, 0x0, 0x0, 0x6, 0xf2, 0x0, + 0x0, 0x0, 0x0, 0x9d, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30CB "ニ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xff, + 0xff, 0xff, 0xff, 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, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xf2, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x10, + + /* U+30CD "ネ" */ + 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4c, 0x0, 0x0, 0x0, 0xb, 0xee, 0xee, + 0xee, 0xef, 0x60, 0x0, 0x0, 0x0, 0x0, 0x9, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x2c, 0x90, 0x0, 0x0, 0x0, + 0x2, 0xaf, 0xc0, 0x85, 0x0, 0x1, 0x6b, 0xe7, + 0x5b, 0x3, 0xcc, 0x20, 0x5a, 0x50, 0x4, 0xb0, + 0x0, 0x6b, 0x0, 0x0, 0x0, 0x4b, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x36, 0x0, 0x0, 0x0, + + /* U+30CE "ノ" */ + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x4, 0xe0, 0x0, 0x0, 0x0, 0xa, 0x90, 0x0, + 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, 0x0, 0x7b, + 0x0, 0x0, 0x0, 0x1, 0xf3, 0x0, 0x0, 0x0, + 0xa, 0x90, 0x0, 0x0, 0x0, 0xac, 0x0, 0x0, + 0x0, 0x1b, 0xc0, 0x0, 0x0, 0x7, 0xfa, 0x0, + 0x0, 0x0, 0xad, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+30CF "ハ" */ + 0x0, 0x3, 0x50, 0x6, 0x30, 0x0, 0x0, 0x9, + 0x80, 0x6, 0xb0, 0x0, 0x0, 0xc, 0x40, 0x0, + 0xe3, 0x0, 0x0, 0xf, 0x0, 0x0, 0x7a, 0x0, + 0x0, 0x5b, 0x0, 0x0, 0x1f, 0x10, 0x0, 0xb6, + 0x0, 0x0, 0xa, 0x70, 0x2, 0xf0, 0x0, 0x0, + 0x4, 0xd0, 0xa, 0x80, 0x0, 0x0, 0x0, 0xe3, + 0x4e, 0x10, 0x0, 0x0, 0x0, 0x98, 0x75, 0x0, + 0x0, 0x0, 0x0, 0x47, + + /* U+30D0 "バ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x92, 0xb0, 0x0, 0x0, + 0x21, 0x0, 0x50, 0x67, 0x62, 0x0, 0x0, 0xa7, + 0x0, 0xb7, 0x2, 0x0, 0x0, 0x0, 0xe3, 0x0, + 0x3e, 0x0, 0x0, 0x0, 0x1, 0xf0, 0x0, 0xb, + 0x60, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x4, 0xd0, + 0x0, 0x0, 0xc, 0x50, 0x0, 0x0, 0xe3, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0x0, 0x89, 0x0, 0x0, + 0xb7, 0x0, 0x0, 0x0, 0x2f, 0x0, 0x5, 0xe0, + 0x0, 0x0, 0x0, 0xd, 0x50, 0xb, 0x50, 0x0, + 0x0, 0x0, 0x8, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+30D1 "パ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x39, 0x92, 0x0, + 0x0, 0x21, 0x0, 0x40, 0x90, 0x27, 0x0, 0x0, + 0xa7, 0x0, 0xb7, 0x29, 0x91, 0x0, 0x0, 0xd3, + 0x0, 0x3e, 0x0, 0x0, 0x0, 0x1, 0xf0, 0x0, + 0xb, 0x70, 0x0, 0x0, 0x6, 0xa0, 0x0, 0x4, + 0xe0, 0x0, 0x0, 0xc, 0x50, 0x0, 0x0, 0xd5, + 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, 0x7b, 0x0, + 0x0, 0xb7, 0x0, 0x0, 0x0, 0x1f, 0x10, 0x5, + 0xe0, 0x0, 0x0, 0x0, 0xc, 0x70, 0xb, 0x50, + 0x0, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+30D2 "ヒ" */ + 0xb1, 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, + 0x0, 0xe1, 0x0, 0x0, 0x19, 0xe, 0x10, 0x16, + 0xbe, 0x81, 0xe9, 0xce, 0xa4, 0x0, 0xe, 0x93, + 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x0, 0xe, + 0x10, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x0, + 0xc, 0x71, 0x0, 0x11, 0x34, 0x3b, 0xef, 0xfe, + 0xed, 0x90, + + /* U+30D3 "ビ" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x17, 0x0, + 0x0, 0x2, 0x86, 0x70, 0x1e, 0x0, 0x0, 0x0, + 0xa3, 0x70, 0x1e, 0x0, 0x0, 0x0, 0x50, 0x0, + 0x1e, 0x0, 0x3, 0x9e, 0xa0, 0x0, 0x1e, 0x59, + 0xec, 0x71, 0x0, 0x0, 0x1f, 0xb6, 0x20, 0x0, + 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, + 0x1, 0x0, 0x8, 0xfd, 0xcc, 0xde, 0xf8, 0x0, + 0x0, 0x2, 0x32, 0x21, 0x0, 0x0, + + /* U+30D4 "ピ" */ + 0x3, 0x0, 0x0, 0x0, 0x59, 0x70, 0x1f, 0x0, + 0x0, 0x0, 0x90, 0x90, 0x1e, 0x0, 0x0, 0x0, + 0x79, 0x50, 0x1e, 0x0, 0x3, 0x8e, 0xa0, 0x0, + 0x1e, 0x49, 0xdd, 0x72, 0x0, 0x0, 0x1f, 0xb7, + 0x20, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x20, + 0x0, 0x0, 0x1, 0x0, 0x8, 0xfd, 0xcc, 0xde, + 0xf8, 0x0, 0x0, 0x2, 0x32, 0x21, 0x0, 0x0, + + /* U+30D5 "フ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xff, 0xff, + 0xff, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x7a, 0x0, + 0x0, 0x0, 0x0, 0xb6, 0x0, 0x0, 0x0, 0x1, + 0xf1, 0x0, 0x0, 0x0, 0x8, 0xa0, 0x0, 0x0, + 0x0, 0x2f, 0x20, 0x0, 0x0, 0x2, 0xe7, 0x0, + 0x0, 0x0, 0x3e, 0x70, 0x0, 0x0, 0x4a, 0xe6, + 0x0, 0x0, 0x4, 0xe8, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+30D6 "ブ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x92, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x57, 0x31, 0xcb, 0xbb, 0xbb, 0xbb, + 0xc8, 0x0, 0x4, 0x33, 0x33, 0x33, 0x3b, 0x80, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, 0x0, 0x2, + 0xf1, 0x0, 0x0, 0x0, 0x0, 0x2, 0xd7, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xe7, 0x0, 0x0, 0x0, + 0x0, 0x29, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x7f, + 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x0, + + /* U+30D7 "プ" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0xab, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x62, 0x17, 0x39, 0x88, 0x88, + 0x88, 0x8c, 0x65, 0x52, 0x88, 0x88, 0x88, 0x88, + 0xeb, 0x70, 0x0, 0x0, 0x0, 0x0, 0xf, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3e, 0x10, 0x0, 0x0, 0x0, 0x0, 0x1d, + 0x70, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x6e, 0x80, 0x0, 0x0, 0x0, + 0x8, 0xed, 0x40, 0x0, 0x0, 0x0, 0x0, 0x34, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30D9 "ベ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0x1c, 0x0, 0x0, 0x0, + 0x7, 0x30, 0xb, 0x37, 0x70, 0x0, 0x0, 0xbc, + 0xe4, 0x2, 0xb0, 0x20, 0x0, 0x9, 0xb0, 0x3e, + 0x40, 0x0, 0x0, 0x0, 0x6d, 0x10, 0x3, 0xe4, + 0x0, 0x0, 0x5, 0xf2, 0x0, 0x0, 0x4e, 0x30, + 0x0, 0xe, 0x50, 0x0, 0x0, 0x6, 0xe2, 0x0, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x8e, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x30, + + /* U+30DA "ペ" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0x99, 0x20, 0x0, + 0x0, 0x1a, 0x60, 0xa, 0x1, 0x90, 0x0, 0x0, + 0xd9, 0xd8, 0x4, 0x9a, 0x30, 0x0, 0xb, 0x90, + 0x1c, 0x80, 0x0, 0x0, 0x0, 0x9c, 0x0, 0x1, + 0xd8, 0x0, 0x0, 0x8, 0xe1, 0x0, 0x0, 0x1e, + 0x70, 0x0, 0xc, 0x30, 0x0, 0x0, 0x2, 0xe6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+30DB "ホ" */ + 0x0, 0x0, 0x2, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x2b, 0xbb, 0xbb, + 0xfb, 0xbb, 0xb9, 0x0, 0x43, 0x33, 0x5f, 0x33, + 0x34, 0x30, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0x3, 0xa0, 0x1e, 0x0, 0xb2, 0x0, 0x0, + 0xd4, 0x1, 0xe0, 0x5, 0xc0, 0x0, 0x9a, 0x0, + 0x1e, 0x0, 0xb, 0x70, 0x5d, 0x0, 0x1, 0xe0, + 0x0, 0x2e, 0x0, 0x10, 0x0, 0x1e, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xdd, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, + + /* U+30DC "ボ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x72, 0x2, 0x68, 0x50, 0x0, 0x0, + 0x0, 0xc3, 0x0, 0xc2, 0xa0, 0x1, 0x10, 0x0, + 0xc4, 0x0, 0x32, 0x0, 0xd, 0xed, 0xdd, 0xfe, + 0xdd, 0xde, 0x10, 0x0, 0x0, 0x0, 0xc3, 0x0, + 0x0, 0x0, 0x0, 0x2, 0x0, 0xc3, 0x1, 0x10, + 0x0, 0x0, 0x3e, 0x0, 0xc3, 0x7, 0xa0, 0x0, + 0x0, 0xc5, 0x0, 0xc3, 0x0, 0xc5, 0x0, 0xa, + 0xa0, 0x0, 0xc3, 0x0, 0x3e, 0x10, 0x1a, 0x0, + 0x0, 0xc3, 0x0, 0x7, 0x30, 0x0, 0x0, 0x32, + 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, 0xa0, + 0x0, 0x0, 0x0, + + /* U+30DD "ポ" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x99, 0x30, 0x0, + 0x0, 0xb, 0x30, 0x62, 0x9, 0x0, 0x0, 0x0, + 0xc3, 0x3, 0xa8, 0x60, 0x11, 0x0, 0xc, 0x40, + 0x2, 0x40, 0xd, 0xed, 0xdd, 0xfe, 0xdd, 0xee, + 0x10, 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, + 0x2, 0x0, 0xc3, 0x2, 0x0, 0x0, 0x3, 0xe0, + 0xc, 0x30, 0xa9, 0x0, 0x0, 0xc5, 0x0, 0xc3, + 0x1, 0xe4, 0x0, 0xaa, 0x0, 0xc, 0x30, 0x4, + 0xe1, 0x1a, 0x0, 0x0, 0xc3, 0x0, 0x8, 0x20, + 0x0, 0x3, 0x2e, 0x30, 0x0, 0x0, 0x0, 0x0, + 0xac, 0xa0, 0x0, 0x0, 0x0, + + /* U+30DE "マ" */ + 0x23, 0x33, 0x33, 0x33, 0x33, 0x31, 0x6c, 0xbb, + 0xbb, 0xbb, 0xbb, 0xfb, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x50, + 0x0, 0x12, 0x0, 0x1, 0xc8, 0x0, 0x0, 0x5e, + 0x40, 0x1d, 0x80, 0x0, 0x0, 0x3, 0xe7, 0xd7, + 0x0, 0x0, 0x0, 0x0, 0x2e, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xe7, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0x60, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x60, 0x0, + + /* U+30DF "ミ" */ + 0x0, 0x74, 0x10, 0x0, 0x0, 0x1, 0x8b, 0xee, + 0xa6, 0x20, 0x0, 0x0, 0x1, 0x59, 0xe2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x9, 0xa7, 0x30, 0x0, + 0x0, 0x2, 0x58, 0xcf, 0xc7, 0x10, 0x0, 0x0, + 0x0, 0x49, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x69, 0x62, 0x0, 0x0, 0x0, 0x36, 0x9d, 0xfb, + 0x62, 0x0, 0x0, 0x0, 0x15, 0x9e, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x10, + + /* U+30E0 "ム" */ + 0x0, 0x0, 0x9, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x89, 0x0, 0x7, 0x10, 0x0, 0x0, + 0xd, 0x30, 0x0, 0x8a, 0x0, 0x0, 0x3, 0xe0, + 0x0, 0x0, 0xd4, 0x0, 0x0, 0x88, 0x0, 0x1, + 0x39, 0xc0, 0x6, 0x7e, 0xcb, 0xdf, 0xec, 0xae, + 0x50, 0x88, 0x75, 0x32, 0x0, 0x0, 0x6c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, + + /* U+30E1 "メ" */ + 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x0, 0x0, 0x22, 0x0, 0x0, + 0x98, 0x0, 0x0, 0x5e, 0x60, 0x1, 0xf1, 0x0, + 0x0, 0x2, 0xca, 0x1a, 0x80, 0x0, 0x0, 0x0, + 0x9, 0xee, 0x0, 0x0, 0x0, 0x0, 0x2, 0xfe, + 0x40, 0x0, 0x0, 0x0, 0x2e, 0x54, 0xf5, 0x0, + 0x0, 0x3, 0xe6, 0x0, 0x4f, 0x60, 0x0, 0x9e, + 0x50, 0x0, 0x4, 0xc0, 0x1e, 0xb1, 0x0, 0x0, + 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30E2 "モ" */ + 0x3, 0xfe, 0xee, 0xee, 0xee, 0xc0, 0x0, 0x0, + 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, + 0x5f, 0xee, 0xef, 0xee, 0xee, 0xea, 0x0, 0x0, + 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xfd, 0xde, 0xf3, 0x0, 0x0, 0x0, 0x2, + 0x11, 0x0, + + /* U+30E3 "ャ" */ + 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, 0x7, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x2d, 0x3, 0x69, 0xdd, + 0x4, 0x7a, 0xfd, 0xa7, 0x4b, 0x50, 0x67, 0x39, + 0x60, 0x6, 0xa0, 0x0, 0x0, 0x4a, 0x5, 0xd0, + 0x0, 0x0, 0x0, 0xe0, 0x21, 0x0, 0x0, 0x0, + 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x78, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x0, 0x0, 0x0, + + /* U+30E4 "ヤ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf1, + 0x0, 0x0, 0x2, 0x10, 0x0, 0xb, 0x52, 0x58, + 0xbe, 0xf8, 0x4, 0x69, 0xef, 0xc9, 0x63, 0x3e, + 0x10, 0xb9, 0x65, 0xd0, 0x0, 0x1d, 0x40, 0x0, + 0x0, 0xe, 0x20, 0x1c, 0x70, 0x0, 0x0, 0x0, + 0xa6, 0x6, 0x90, 0x0, 0x0, 0x0, 0x6, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x35, 0x0, 0x0, 0x0, + + /* U+30E5 "ュ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xff, 0xff, + 0xff, 0x20, 0x0, 0x0, 0x0, 0xf, 0x10, 0x0, + 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x3c, + 0x0, 0x0, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, + 0x0, 0x88, 0x0, 0xdf, 0xff, 0xff, 0xff, 0xfe, + + /* U+30E7 "ョ" */ + 0x9d, 0xcc, 0xcc, 0xcb, 0x11, 0x11, 0x11, 0x2e, + 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x1e, + 0x6d, 0xdd, 0xdd, 0xde, 0x0, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x0, 0xe, 0xde, 0xee, 0xee, 0xee, + 0x0, 0x0, 0x0, 0x1e, + + /* U+30E8 "ヨ" */ + 0x6f, 0xee, 0xee, 0xee, 0xeb, 0x0, 0x0, 0x0, + 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x0, + 0x0, 0x0, 0x0, 0x3c, 0xe, 0xdd, 0xdd, 0xdd, + 0xec, 0x1, 0x11, 0x11, 0x11, 0x5c, 0x0, 0x0, + 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x3c, + 0x12, 0x22, 0x22, 0x22, 0x5c, 0x8d, 0xdd, 0xdd, + 0xdd, 0xdc, 0x0, 0x0, 0x0, 0x0, 0x1, + + /* U+30E9 "ラ" */ + 0x0, 0x11, 0x11, 0x11, 0x11, 0x0, 0x0, 0xcd, + 0xdd, 0xdd, 0xde, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0xee, 0xee, 0xee, 0xee, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x30, 0x0, 0x0, 0x0, 0x0, 0x8a, 0x0, + 0x0, 0x0, 0x0, 0x7, 0xe1, 0x0, 0x0, 0x0, + 0x2, 0xbd, 0x20, 0x0, 0x0, 0x5, 0xce, 0x80, + 0x0, 0x0, 0x0, 0x3, 0x50, 0x0, 0x0, 0x0, + + /* U+30EA "リ" */ + 0x91, 0x0, 0x0, 0x3a, 0xe1, 0x0, 0x0, 0x3d, + 0xe1, 0x0, 0x0, 0x3d, 0xe1, 0x0, 0x0, 0x3d, + 0xe1, 0x0, 0x0, 0x3c, 0xe1, 0x0, 0x0, 0x4c, + 0xe2, 0x0, 0x0, 0x69, 0x0, 0x0, 0x0, 0xb6, + 0x0, 0x0, 0x6, 0xe0, 0x0, 0x0, 0x9e, 0x30, + 0x0, 0x7f, 0xa1, 0x0, 0x0, 0x11, 0x0, 0x0, + + /* U+30EB "ル" */ + 0x0, 0x16, 0x0, 0x52, 0x0, 0x0, 0x0, 0x2, + 0xd0, 0xc, 0x40, 0x0, 0x0, 0x0, 0x2d, 0x0, + 0xb4, 0x0, 0x0, 0x0, 0x2, 0xc0, 0xb, 0x40, + 0x0, 0x0, 0x0, 0x3c, 0x0, 0xb4, 0x0, 0x0, + 0x0, 0x4, 0xb0, 0xb, 0x40, 0x0, 0x0, 0x0, + 0x69, 0x0, 0xb4, 0x0, 0x7, 0x0, 0xb, 0x50, + 0xb, 0x40, 0xb, 0xa0, 0x3, 0xe0, 0x0, 0xb4, + 0x1b, 0xa0, 0x1, 0xc7, 0x0, 0xc, 0x9e, 0x80, + 0x0, 0xba, 0x0, 0x0, 0xcc, 0x30, 0x0, 0x1, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + + /* U+30EC "レ" */ + 0x5, 0x10, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, + 0x0, 0xe1, 0x0, 0x0, 0x0, 0x0, 0xe, 0x10, + 0x0, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x0, + 0x72, 0xe, 0x10, 0x0, 0x0, 0x8d, 0x10, 0xe1, + 0x0, 0x1, 0xbc, 0x10, 0xe, 0x10, 0x7, 0xe8, + 0x0, 0x0, 0xe5, 0x8e, 0xb2, 0x0, 0x0, 0xe, + 0xd8, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+30ED "ロ" */ + 0xab, 0xbb, 0xbb, 0xbb, 0xbb, 0xe5, 0x33, 0x33, + 0x33, 0x4f, 0xe1, 0x0, 0x0, 0x0, 0x1e, 0xe1, + 0x0, 0x0, 0x0, 0x1e, 0xe1, 0x0, 0x0, 0x0, + 0x1e, 0xe1, 0x0, 0x0, 0x0, 0x1e, 0xe1, 0x0, + 0x0, 0x0, 0x1e, 0xe1, 0x0, 0x0, 0x0, 0x1e, + 0xee, 0xee, 0xee, 0xee, 0xef, 0xc2, 0x0, 0x0, + 0x0, 0x1c, + + /* U+30EF "ワ" */ + 0x1e, 0xee, 0xee, 0xee, 0xee, 0xe1, 0xf, 0x0, + 0x0, 0x0, 0x3, 0xf0, 0xf, 0x0, 0x0, 0x0, + 0x5, 0xc0, 0xf, 0x0, 0x0, 0x0, 0x8, 0x90, + 0xc, 0x0, 0x0, 0x0, 0xe, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xe5, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x80, 0x0, + 0x0, 0x0, 0x18, 0xe7, 0x0, 0x0, 0x0, 0x4, + 0xf9, 0x10, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+30F3 "ン" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xd3, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xf6, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xe6, 0x0, 0x0, 0x17, 0x0, 0x2, + 0x10, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, 0x6, + 0xd0, 0x0, 0x0, 0x0, 0x7, 0xe2, 0x0, 0x0, + 0x0, 0x9, 0xd2, 0x0, 0x0, 0x0, 0x4c, 0xc1, + 0x0, 0x0, 0x27, 0xce, 0x60, 0x0, 0x0, 0xaf, + 0xa6, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+30F6 "ヶ" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x4d, + 0x0, 0x0, 0x0, 0x0, 0xa, 0x71, 0x11, 0x11, + 0x10, 0x2, 0xed, 0xdd, 0xfd, 0xdd, 0x1, 0xd4, + 0x0, 0x4b, 0x0, 0x0, 0xc8, 0x0, 0x6, 0x80, + 0x0, 0x1, 0x0, 0x0, 0xc4, 0x0, 0x0, 0x0, + 0x0, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x30, + 0x0, 0x0, 0x0, 0x4e, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x10, 0x0, 0x0, 0x0, + + /* U+30FC "ー" */ + 0xbf, 0xee, 0xee, 0xee, 0xef, 0xf4, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x20, + + /* U+4E00 "一" */ + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4E03 "七" */ + 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, + 0x0, 0x0, 0x1, 0x42, 0x0, 0x0, 0x1e, 0x46, + 0x9c, 0xfe, 0xb4, 0x5, 0x8b, 0xef, 0xc9, 0x64, + 0x10, 0x0, 0xa, 0x74, 0x3e, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, + 0x1e, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xf, + 0x42, 0x11, 0x27, 0xb0, 0x0, 0x0, 0x6, 0xcc, + 0xcc, 0xcb, 0x20, + + /* U+4E07 "万" */ + 0x1e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe1, 0x0, + 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xee, + 0xee, 0xeb, 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0x3c, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x4b, + 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, 0x59, 0x0, + 0x0, 0xb, 0x60, 0x0, 0x0, 0x78, 0x0, 0x0, + 0x4d, 0x0, 0x0, 0x0, 0x96, 0x0, 0x4, 0xe2, + 0x0, 0x0, 0x0, 0xd3, 0x0, 0x3d, 0x20, 0x0, + 0xd, 0xde, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+4E08 "丈" */ + 0x0, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x0, 0x1e, 0xee, 0xee, + 0xee, 0xfe, 0xee, 0xe1, 0x0, 0x3, 0x0, 0x1, + 0xe0, 0x0, 0x0, 0x0, 0xd, 0x20, 0x3, 0xc0, + 0x0, 0x0, 0x0, 0x7, 0x80, 0x5, 0xa0, 0x0, + 0x0, 0x0, 0x1, 0xe1, 0x8, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x7b, 0xe, 0x20, 0x0, 0x0, 0x0, + 0x0, 0xb, 0xd9, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1b, 0xfb, 0x30, 0x0, 0x0, 0x0, 0x48, 0xe7, + 0x5, 0xdb, 0x62, 0x0, 0xb, 0xc7, 0x10, 0x0, + 0x5, 0x9c, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4E09 "三" */ + 0x0, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x3, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x5e, 0xee, 0xee, 0xee, + 0xe3, 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, 0x1e, 0xee, + 0xee, 0xee, 0xee, 0xee, 0xe1, + + /* U+4E0A "上" */ + 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdf, 0xee, + 0xee, 0x40, 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd1, 0x0, 0x0, 0x0, 0xb, 0xbb, 0xbb, + 0xfb, 0xbb, 0xbb, 0xb5, 0x3, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x31, + + /* U+4E0B "下" */ + 0x3e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe3, 0x0, + 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb9, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xba, + 0xe7, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, 0x2a, + 0xd4, 0x0, 0x0, 0x0, 0x0, 0xb3, 0x0, 0x5e, + 0x30, 0x0, 0x0, 0x0, 0xb3, 0x0, 0x1, 0x0, + 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb3, 0x0, 0x0, 0x0, + + /* U+4E0D "不" */ + 0xe, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe0, 0x0, + 0x0, 0x0, 0x2e, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xf7, 0x50, 0x0, 0x0, 0x0, 0x0, 0x7d, 0x97, + 0x8d, 0x20, 0x0, 0x0, 0x9, 0xc1, 0x87, 0x4, + 0xe6, 0x0, 0x3, 0xca, 0x10, 0x87, 0x0, 0x1c, + 0x90, 0x1e, 0x50, 0x0, 0x87, 0x0, 0x0, 0xa2, + 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x0, 0x0, + + /* U+4E13 "专" */ + 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0xee, 0xef, + 0xee, 0xee, 0xee, 0x0, 0x0, 0x0, 0xe0, 0x0, + 0x0, 0x0, 0x2a, 0xaa, 0xce, 0xaa, 0xaa, 0xaa, + 0xa0, 0x33, 0x3c, 0x63, 0x33, 0x33, 0x33, 0x0, + 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, + 0xdd, 0xdd, 0xde, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xc0, 0x0, 0x0, 0x1, 0x0, 0x8, 0xc0, + 0x0, 0x0, 0x1, 0xcc, 0x68, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x28, 0xea, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6d, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+4E14 "且" */ + 0x0, 0xf, 0xee, 0xee, 0xee, 0xf2, 0x0, 0x0, + 0xe, 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0xf, 0xaa, + 0xaa, 0xaa, 0xe2, 0x0, 0x0, 0xf, 0x33, 0x33, + 0x33, 0xd2, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, + 0xc2, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xc2, + 0x0, 0x0, 0xf, 0xee, 0xee, 0xee, 0xf2, 0x0, + 0x0, 0xe, 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, + 0xe, 0x0, 0x0, 0x0, 0xc2, 0x0, 0x3, 0x3f, + 0x33, 0x33, 0x33, 0xd5, 0x30, 0x2a, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xa2, + + /* U+4E16 "世" */ + 0x0, 0x0, 0x0, 0x67, 0x0, 0x10, 0x0, 0x0, + 0xe, 0x0, 0x67, 0x0, 0xc2, 0x0, 0x0, 0xe, + 0x0, 0x67, 0x0, 0xc2, 0x0, 0x0, 0xe, 0x0, + 0x67, 0x0, 0xc2, 0x0, 0x1e, 0xef, 0xee, 0xff, + 0xee, 0xfe, 0xe6, 0x0, 0xe, 0x0, 0x67, 0x0, + 0xc2, 0x0, 0x0, 0xe, 0x0, 0x67, 0x0, 0xc2, + 0x0, 0x0, 0xe, 0x0, 0x67, 0x0, 0xc2, 0x0, + 0x0, 0xe, 0x0, 0x6e, 0xdd, 0xf2, 0x0, 0x0, + 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xee, + 0xee, 0xee, 0xee, 0xc0, + + /* U+4E21 "両" */ + 0x2e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe2, 0x0, + 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x85, 0x0, 0x0, 0x0, 0x6, 0xee, 0xee, + 0xff, 0xee, 0xee, 0x70, 0x7, 0x60, 0x0, 0x85, + 0x0, 0x6, 0x70, 0x7, 0x61, 0x50, 0x85, 0x4, + 0x6, 0x70, 0x7, 0x62, 0xa0, 0x85, 0xc, 0x6, + 0x70, 0x7, 0x62, 0xa0, 0x85, 0xc, 0x6, 0x70, + 0x7, 0x62, 0xa0, 0x96, 0xc, 0x6, 0x70, 0x7, + 0x61, 0xcc, 0xcc, 0xcc, 0x6, 0x70, 0x7, 0x60, + 0x0, 0x0, 0x0, 0x6, 0x70, 0x7, 0x60, 0x0, + 0x0, 0x6, 0xdd, 0x40, + + /* U+4E26 "並" */ + 0x0, 0x8, 0x10, 0x0, 0x1, 0xa0, 0x0, 0x0, + 0x5, 0xb0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, + 0xc1, 0x0, 0x1d, 0x0, 0x0, 0xc, 0xee, 0xee, + 0xee, 0xef, 0xee, 0xd0, 0x0, 0x0, 0xe, 0x0, + 0xe0, 0x0, 0x0, 0x0, 0x70, 0xe, 0x0, 0xe0, + 0x9, 0x10, 0x0, 0xd2, 0xe, 0x0, 0xe0, 0x2e, + 0x0, 0x0, 0x68, 0xe, 0x0, 0xe0, 0x78, 0x0, + 0x0, 0x2c, 0xe, 0x0, 0xe0, 0xd2, 0x0, 0x0, + 0xc, 0xe, 0x0, 0xe2, 0xa0, 0x0, 0x0, 0x0, + 0xe, 0x0, 0xe0, 0x0, 0x0, 0x2b, 0xbb, 0xbf, + 0xbb, 0xfb, 0xbb, 0xb2, 0x3, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x30, + + /* U+4E2D "中" */ + 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0x0, + 0xe1, 0x0, 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, + 0xd, 0xee, 0xee, 0xfe, 0xee, 0xef, 0xd1, 0x0, + 0xe, 0x10, 0x0, 0xfd, 0x10, 0x0, 0xe1, 0x0, + 0xf, 0xd1, 0x0, 0xe, 0x10, 0x0, 0xfd, 0x43, + 0x33, 0xe4, 0x33, 0x3f, 0xdb, 0xaa, 0xaf, 0xba, + 0xaa, 0xf7, 0x0, 0x0, 0xe1, 0x0, 0x7, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0x0, 0xe1, + 0x0, 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, + + /* U+4E3B "主" */ + 0x0, 0x0, 0x3, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xc7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x50, 0x0, 0x0, 0x8, 0xee, 0xee, + 0xef, 0xee, 0xee, 0x80, 0x0, 0x0, 0x0, 0x77, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, + 0x0, 0x0, 0xde, 0xee, 0xff, 0xee, 0xee, 0x0, + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x77, 0x0, 0x0, 0x0, 0x1, 0x11, 0x11, + 0x88, 0x11, 0x11, 0x10, 0x2c, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xc3, + + /* U+4E45 "久" */ + 0x0, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0xf4, 0x33, 0x30, 0x0, 0x0, 0x0, 0x9, 0xdb, + 0xbb, 0xe5, 0x0, 0x0, 0x0, 0x2e, 0x10, 0x1, + 0xe0, 0x0, 0x0, 0x0, 0xd5, 0x0, 0x7, 0x90, + 0x0, 0x0, 0xb, 0x90, 0x0, 0xd, 0x50, 0x0, + 0x0, 0x3a, 0x0, 0x0, 0x7e, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xe2, 0xc2, 0x0, 0x0, 0x0, + 0x0, 0x2d, 0x50, 0x2c, 0x0, 0x0, 0x0, 0x3, + 0xe6, 0x0, 0x8, 0xb0, 0x0, 0x0, 0x7e, 0x50, + 0x0, 0x0, 0xac, 0x20, 0x1e, 0xb2, 0x0, 0x0, + 0x0, 0x7, 0xf3, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, + + /* U+4E4B "之" */ + 0x0, 0x0, 0x0, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x89, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x0, 0x0, 0x0, 0x8, 0xee, 0xee, + 0xee, 0xee, 0xec, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xc7, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4d, 0x50, 0x0, 0x0, 0x0, 0x0, 0x6b, + 0xc2, 0x0, 0x0, 0x0, 0x0, 0x9, 0xb6, 0xd7, + 0x21, 0x1, 0x12, 0x31, 0x1b, 0x0, 0x17, 0xbd, + 0xdd, 0xdc, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4E4E "乎" */ + 0x0, 0x0, 0x0, 0x1, 0x35, 0x87, 0x0, 0x2, + 0xbc, 0xde, 0xfe, 0xb9, 0x63, 0x0, 0x0, 0x32, + 0x0, 0x59, 0x0, 0x5, 0x0, 0x0, 0x68, 0x0, + 0x59, 0x0, 0x6a, 0x0, 0x0, 0xe, 0x10, 0x59, + 0x0, 0xc3, 0x0, 0x0, 0x9, 0x60, 0x59, 0x4, + 0xa0, 0x0, 0x0, 0x1, 0x10, 0x59, 0x1, 0x10, + 0x0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x69, 0x0, 0x0, 0x0, 0x0, 0x3, 0xfe, 0xd4, + 0x0, 0x0, 0x0, + + /* U+4E4F "乏" */ + 0x0, 0x0, 0x0, 0x0, 0x24, 0x69, 0x10, 0x2, + 0xab, 0xcd, 0xed, 0xca, 0x74, 0x10, 0x0, 0x32, + 0x13, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55, + 0x0, 0x0, 0x0, 0x4, 0xee, 0xee, 0xee, 0xee, + 0xec, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xd4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4d, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xc1, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xe7, 0x0, 0x0, 0x0, 0x0, 0x9b, + 0xda, 0x10, 0x0, 0x0, 0x0, 0x9, 0x84, 0xe7, + 0x0, 0x0, 0x0, 0x11, 0x1c, 0x0, 0x29, 0xee, + 0xdd, 0xef, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4E57 "乗" */ + 0x0, 0x0, 0x0, 0x1, 0x35, 0x86, 0x0, 0x2, + 0xcd, 0xdd, 0xed, 0xa8, 0x52, 0x0, 0x0, 0x0, + 0x0, 0x76, 0x0, 0x0, 0x0, 0x6, 0xdd, 0xdd, + 0xee, 0xdd, 0xdd, 0x80, 0x0, 0x8, 0x50, 0x76, + 0x5, 0x80, 0x0, 0x0, 0x8, 0x50, 0x76, 0x5, + 0x80, 0x0, 0x2d, 0xde, 0xed, 0xee, 0xde, 0xed, + 0xd2, 0x0, 0x8, 0x50, 0x76, 0x5, 0x80, 0x0, + 0x8, 0xde, 0xed, 0xee, 0xde, 0xed, 0x90, 0x0, + 0x0, 0x2c, 0xcc, 0xc2, 0x0, 0x0, 0x0, 0x7, + 0xd3, 0x76, 0x4d, 0x60, 0x0, 0x19, 0xe8, 0x10, + 0x76, 0x1, 0x9e, 0x81, 0x6, 0x0, 0x0, 0x76, + 0x0, 0x1, 0x80, + + /* U+4E5D "九" */ + 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, + 0x0, 0x0, 0x0, 0x0, 0xe, 0xee, 0xff, 0xee, + 0xef, 0x10, 0x0, 0x0, 0x0, 0x2c, 0x0, 0xe, + 0x10, 0x0, 0x0, 0x0, 0x5a, 0x0, 0xe, 0x10, + 0x0, 0x0, 0x0, 0x87, 0x0, 0xe, 0x10, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0xe, 0x10, 0x0, 0x0, + 0x5, 0xc0, 0x0, 0xe, 0x10, 0x0, 0x0, 0x2e, + 0x30, 0x0, 0xe, 0x10, 0x37, 0x4, 0xd6, 0x0, + 0x0, 0xe, 0x10, 0x49, 0x4e, 0x40, 0x0, 0x0, + 0x9, 0xee, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4E5F "也" */ + 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0xe, + 0x0, 0xe, 0x0, 0x3, 0x0, 0x0, 0xe, 0x0, + 0xe, 0x5a, 0xde, 0x30, 0x0, 0xf, 0x37, 0xcf, + 0x73, 0xc, 0x20, 0x5, 0x9f, 0xa5, 0x1e, 0x0, + 0xc, 0x10, 0x58, 0x3f, 0x0, 0xe, 0x0, 0xe, + 0x0, 0x0, 0xe, 0x0, 0xe, 0x0, 0x1d, 0x0, + 0x0, 0xe, 0x0, 0xe, 0x2d, 0xd5, 0x0, 0x0, + 0xe, 0x0, 0xc, 0x0, 0x0, 0x72, 0x0, 0xe, + 0x0, 0x0, 0x0, 0x0, 0xb2, 0x0, 0xe, 0x10, + 0x0, 0x0, 0x1, 0xe0, 0x0, 0x5, 0xdd, 0xdd, + 0xdd, 0xed, 0x50, + + /* U+4E86 "了" */ + 0x5d, 0xdd, 0xdd, 0xdd, 0xdd, 0xd5, 0x1, 0x11, + 0x11, 0x11, 0x1b, 0xa0, 0x0, 0x0, 0x0, 0x2, + 0xc9, 0x0, 0x0, 0x0, 0x0, 0x7d, 0x40, 0x0, + 0x0, 0x0, 0x3, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xb0, + 0x0, 0x0, 0x0, 0xe, 0xee, 0x60, 0x0, 0x0, + + /* U+4E88 "予" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9d, 0xdd, 0xdd, 0xdd, 0xfa, 0x0, 0x0, 0x0, + 0x10, 0x0, 0x1b, 0xa0, 0x0, 0x0, 0x0, 0x6d, + 0x86, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d, + 0xb3, 0x0, 0x0, 0xb, 0xbb, 0xbb, 0xbc, 0xfe, + 0xbb, 0xc3, 0x2, 0x22, 0x22, 0x4d, 0x22, 0x26, + 0xd0, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x1d, 0x30, + 0x0, 0x0, 0x0, 0x2c, 0x0, 0x76, 0x0, 0x0, + 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7e, 0xd7, + 0x0, 0x0, 0x0, + + /* U+4E89 "争" */ + 0x0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xee, 0xcc, 0xcc, 0x20, 0x0, 0x0, 0xb, + 0x50, 0x0, 0x7b, 0x0, 0x0, 0x1, 0xd7, 0x0, + 0x3, 0xe1, 0x0, 0x0, 0x7, 0xbd, 0xdd, 0xee, + 0xdd, 0xeb, 0x0, 0x0, 0x0, 0x0, 0x77, 0x0, + 0x3b, 0x0, 0x2c, 0xcc, 0xcc, 0xee, 0xcc, 0xdf, + 0xc8, 0x0, 0x0, 0x0, 0x88, 0x0, 0x4b, 0x0, + 0x0, 0x0, 0x0, 0x77, 0x0, 0x3b, 0x0, 0x0, + 0xdd, 0xdd, 0xee, 0xdd, 0xda, 0x0, 0x0, 0x0, + 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd, 0xd3, + 0x0, 0x0, 0x0, + + /* U+4E8B "事" */ + 0x0, 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, 0xa, + 0xbb, 0xbb, 0xde, 0xbb, 0xbb, 0xb3, 0x1, 0x11, + 0x11, 0x89, 0x11, 0x11, 0x10, 0x0, 0x8c, 0xaa, + 0xdd, 0xaa, 0xbc, 0x0, 0x0, 0x85, 0x0, 0x68, + 0x0, 0x1d, 0x0, 0x0, 0x6a, 0xaa, 0xdd, 0xaa, + 0xa9, 0x0, 0x0, 0x55, 0x55, 0xab, 0x55, 0x55, + 0x0, 0x0, 0x44, 0x44, 0x9a, 0x44, 0x4e, 0x10, + 0xc, 0xcc, 0xcc, 0xde, 0xcc, 0xcf, 0xc6, 0x0, + 0x0, 0x0, 0x68, 0x0, 0xd, 0x10, 0x1, 0xcc, + 0xcc, 0xde, 0xcc, 0xcf, 0x10, 0x0, 0x0, 0x0, + 0x78, 0x0, 0x8, 0x0, 0x0, 0x0, 0x7c, 0xd5, + 0x0, 0x0, 0x0, + + /* U+4E8C "二" */ + 0x0, 0xee, 0xee, 0xee, 0xee, 0xee, 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, 0x0, 0x0, + 0x2, 0x22, 0x22, 0x22, 0x22, 0x22, 0x20, 0x2d, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xd3, + + /* U+4E94 "五" */ + 0x0, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x3, + 0xcc, 0xcd, 0xfc, 0xcc, 0xcc, 0x20, 0x0, 0x0, + 0x5, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, + 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x60, + 0x0, 0x0, 0x0, 0x0, 0x7d, 0xdf, 0xed, 0xde, + 0xd0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x3, 0xb0, + 0x0, 0x0, 0x0, 0x2d, 0x0, 0x5, 0xa0, 0x0, + 0x0, 0x0, 0x5a, 0x0, 0x6, 0x80, 0x0, 0x0, + 0x0, 0x96, 0x0, 0x8, 0x60, 0x0, 0x2d, 0xdd, + 0xfe, 0xdd, 0xde, 0xed, 0xd3, 0x1, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x10, + + /* U+4E9B "些" */ + 0x0, 0x3, 0xa0, 0x4, 0xa0, 0x0, 0x0, 0x0, + 0x3, 0xa0, 0x4, 0xa0, 0x0, 0x0, 0x6, 0x63, + 0xb0, 0x4, 0xa0, 0x6e, 0x40, 0x6, 0x63, 0xec, + 0xb4, 0xec, 0x71, 0x0, 0x6, 0x63, 0xa0, 0x4, + 0xa0, 0x0, 0x20, 0x6, 0x63, 0xa0, 0x14, 0xa0, + 0x0, 0x94, 0x2b, 0xdc, 0xfe, 0xc2, 0xed, 0xcd, + 0xe0, 0x28, 0x53, 0x10, 0x0, 0x1, 0x11, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8d, 0xdd, 0xdd, 0xdd, 0xda, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2e, 0xee, 0xee, 0xee, + 0xee, 0xee, 0xe2, + + /* U+4EA1 "亡" */ + 0x0, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x2e, 0xee, 0xee, + 0xee, 0xee, 0xee, 0xe3, 0x0, 0x2d, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xee, + 0xee, 0xee, 0xee, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+4EA4 "交" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x79, 0x0, 0x0, 0x0, 0xe, 0xee, 0xee, + 0xee, 0xee, 0xee, 0xe0, 0x0, 0x0, 0x51, 0x0, + 0x5, 0x0, 0x0, 0x0, 0x8, 0xb0, 0x0, 0xa, + 0xb1, 0x0, 0x0, 0xab, 0x0, 0x0, 0x0, 0x6d, + 0x10, 0xa, 0x80, 0xb2, 0x0, 0x2d, 0x5, 0xc0, + 0x0, 0x0, 0x4b, 0x0, 0xa6, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x86, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xee, 0x10, 0x0, 0x0, 0x0, 0x0, 0x3c, + 0xa9, 0xd4, 0x0, 0x0, 0x2, 0x6b, 0xd4, 0x0, + 0x3c, 0xc8, 0x40, 0x1d, 0x93, 0x0, 0x0, 0x0, + 0x27, 0xb1, + + /* U+4EA6 "亦" */ + 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x97, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2b, 0x0, 0x0, 0x0, 0x1d, 0xdd, 0xdf, + 0xdd, 0xee, 0xdd, 0xd1, 0x0, 0x0, 0xe, 0x0, + 0x86, 0x0, 0x0, 0x0, 0x35, 0xe, 0x0, 0x86, + 0x51, 0x0, 0x0, 0xa5, 0xe, 0x0, 0x86, 0x5a, + 0x0, 0x1, 0xe0, 0x1d, 0x0, 0x86, 0xc, 0x30, + 0xa, 0x70, 0x5a, 0x0, 0x86, 0x5, 0xa0, 0x8, + 0x0, 0xb5, 0x0, 0x86, 0x0, 0xd0, 0x0, 0x5, + 0xc0, 0x0, 0x86, 0x0, 0x0, 0x0, 0x4e, 0x30, + 0x0, 0x86, 0x0, 0x0, 0x1, 0xd4, 0x0, 0xbe, + 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4EAC "京" */ + 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0x1e, 0xee, + 0xee, 0xef, 0xee, 0xee, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4d, 0xdd, 0xdd, + 0xdd, 0xd6, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, + 0x77, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x77, + 0x0, 0x0, 0x5e, 0xdd, 0xdd, 0xdd, 0xe7, 0x0, + 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0x0, 0x78, 0x1, 0xc1, 0x0, 0x0, 0xc5, + 0x0, 0x78, 0x0, 0x6c, 0x0, 0xc, 0x70, 0x0, + 0x78, 0x0, 0x9, 0xa0, 0x4, 0x0, 0xad, 0xe4, + 0x0, 0x0, 0x50, + + /* U+4EBA "人" */ + 0x0, 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xfb, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x9e, 0x10, + 0x0, 0x0, 0x0, 0x0, 0xc, 0x49, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x3d, 0x3, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0xc5, 0x0, 0xb6, 0x0, 0x0, 0x0, + 0x8, 0xb0, 0x0, 0x2e, 0x30, 0x0, 0x0, 0x7d, + 0x10, 0x0, 0x4, 0xe3, 0x0, 0x1b, 0xc1, 0x0, + 0x0, 0x0, 0x4d, 0x80, 0x27, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x70, + + /* U+4EC0 "什" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd1, 0x0, 0x1d, 0x0, 0x0, 0x0, 0x5, + 0xb0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0xd, 0x30, + 0x0, 0x1d, 0x0, 0x0, 0x0, 0x6d, 0x0, 0x0, + 0x1d, 0x0, 0x0, 0x3, 0xfd, 0x0, 0x0, 0x1d, + 0x0, 0x0, 0xd, 0x8d, 0x2e, 0xee, 0xef, 0xee, + 0xea, 0x8, 0x1d, 0x0, 0x0, 0x1d, 0x0, 0x0, + 0x0, 0x1d, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, + 0x1d, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0x1d, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0x1d, 0x0, + 0x0, 0x1d, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, + 0x1d, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x1d, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+4ECA "今" */ + 0x0, 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xed, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x4d, 0x21, 0xc5, 0x0, 0x0, 0x0, 0x7, 0xd2, + 0x0, 0x1c, 0x80, 0x0, 0x3, 0xca, 0x13, 0xd3, + 0x0, 0xad, 0x40, 0x3e, 0x40, 0x0, 0x3d, 0x40, + 0x4, 0xd3, 0x0, 0x0, 0x0, 0x2, 0x50, 0x0, + 0x0, 0x0, 0xaf, 0xff, 0xff, 0xff, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0xe2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1d, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4ECB "介" */ + 0x0, 0x0, 0x0, 0x66, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xdd, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0x24, 0xd2, 0x0, 0x0, 0x0, 0x5, 0xd2, + 0x0, 0x4e, 0x50, 0x0, 0x2, 0xad, 0x20, 0x0, + 0x2, 0xcb, 0x40, 0x4e, 0x70, 0x50, 0x0, 0x5, + 0x6, 0xd4, 0x0, 0x0, 0xe0, 0x0, 0xe, 0x10, + 0x0, 0x0, 0x1, 0xe0, 0x0, 0xe, 0x10, 0x0, + 0x0, 0x2, 0xd0, 0x0, 0xe, 0x10, 0x0, 0x0, + 0x6, 0xa0, 0x0, 0xe, 0x10, 0x0, 0x0, 0xd, + 0x40, 0x0, 0xe, 0x10, 0x0, 0x1, 0xb9, 0x0, + 0x0, 0xe, 0x10, 0x0, 0xa, 0x70, 0x0, 0x0, + 0xe, 0x10, 0x0, + + /* U+4ECD "仍" */ + 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xb7, 0xdd, 0xdd, 0xdd, 0x0, 0x0, 0xb4, 0x0, + 0xd1, 0x0, 0xd0, 0x0, 0x3f, 0x0, 0xd, 0x10, + 0x3a, 0x0, 0xd, 0xf0, 0x0, 0xe0, 0x7, 0x60, + 0x7, 0xae, 0x0, 0xe, 0x0, 0xbe, 0xdb, 0x31, + 0xe0, 0x2, 0xc0, 0x0, 0x2, 0xc0, 0xe, 0x0, + 0x4a, 0x0, 0x0, 0x3b, 0x0, 0xe0, 0x8, 0x70, + 0x0, 0x4, 0xa0, 0xe, 0x0, 0xd2, 0x0, 0x0, + 0x68, 0x0, 0xe0, 0x3d, 0x0, 0x0, 0x7, 0x60, + 0xe, 0xd, 0x40, 0x0, 0x0, 0xb3, 0x0, 0xe5, + 0x90, 0x0, 0x5e, 0xeb, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+4ED5 "仕" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd3, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x5, + 0xc0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0xc, 0x40, + 0x0, 0x2c, 0x0, 0x0, 0x0, 0x5d, 0x0, 0x0, + 0x2c, 0x0, 0x0, 0x1, 0xec, 0x0, 0x0, 0x2d, + 0x0, 0x0, 0xc, 0xbc, 0x5d, 0xdd, 0xef, 0xdd, + 0xdc, 0x3b, 0x2c, 0x0, 0x0, 0x2c, 0x0, 0x0, + 0x0, 0x2c, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, + 0x2c, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x2c, + 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x2c, 0x0, + 0x0, 0x2c, 0x0, 0x0, 0x0, 0x2c, 0x2, 0x22, + 0x4d, 0x22, 0x22, 0x0, 0x2c, 0xb, 0xbb, 0xbb, + 0xbb, 0xb8, + + /* U+4ED6 "他" */ + 0x0, 0x9, 0x20, 0x0, 0xb2, 0x0, 0x0, 0x0, + 0x2d, 0x3, 0x0, 0xb2, 0x0, 0x0, 0x0, 0xa7, + 0xd, 0x10, 0xb2, 0x0, 0x10, 0x3, 0xf1, 0xd, + 0x10, 0xb6, 0x9e, 0xa0, 0x1e, 0xf0, 0xd, 0x48, + 0xfb, 0x54, 0xa0, 0xa9, 0xe0, 0x6f, 0xc6, 0xc2, + 0x3, 0xa0, 0x50, 0xe3, 0x8e, 0x10, 0xb2, 0x4, + 0x90, 0x0, 0xe0, 0xd, 0x10, 0xb2, 0x5, 0x80, + 0x0, 0xe0, 0xd, 0x10, 0xb4, 0xad, 0x40, 0x0, + 0xe0, 0xd, 0x10, 0x82, 0x21, 0x10, 0x0, 0xe0, + 0xd, 0x10, 0x0, 0x0, 0xa3, 0x0, 0xe0, 0xc, + 0x30, 0x0, 0x0, 0xd1, 0x0, 0xe0, 0x6, 0xdd, + 0xdd, 0xdd, 0x90, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4ED8 "付" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd2, 0x0, 0x0, 0x3b, 0x0, 0x0, 0x5, + 0xb0, 0x0, 0x0, 0x3b, 0x0, 0x0, 0xd, 0x40, + 0x0, 0x0, 0x3b, 0x0, 0x0, 0x5d, 0xc, 0xdd, + 0xdd, 0xdf, 0xd7, 0x1, 0xec, 0x1, 0x11, 0x11, + 0x5c, 0x11, 0xd, 0x9c, 0x0, 0x20, 0x0, 0x3b, + 0x0, 0x7, 0x2c, 0x0, 0xc4, 0x0, 0x3b, 0x0, + 0x0, 0x2c, 0x0, 0x3e, 0x0, 0x3b, 0x0, 0x0, + 0x2c, 0x0, 0x9, 0x80, 0x3b, 0x0, 0x0, 0x2c, + 0x0, 0x1, 0x50, 0x3b, 0x0, 0x0, 0x2c, 0x0, + 0x0, 0x0, 0x3b, 0x0, 0x0, 0x2c, 0x0, 0x0, + 0x0, 0x3b, 0x0, 0x0, 0x2b, 0x0, 0x2, 0xee, + 0xd5, 0x0, + + /* U+4EE3 "代" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb2, 0x2, 0xc0, 0x83, 0x0, 0x0, 0x4, + 0xc0, 0x1, 0xd0, 0x1d, 0x40, 0x0, 0xd, 0x30, + 0x0, 0xe0, 0x1, 0xb0, 0x0, 0x7e, 0x0, 0x0, + 0xe0, 0x1, 0x31, 0x4, 0xed, 0x15, 0x79, 0xfd, + 0xed, 0xb3, 0x3e, 0x4d, 0x39, 0x75, 0xc4, 0x0, + 0x0, 0x44, 0x1d, 0x0, 0x0, 0x95, 0x0, 0x0, + 0x0, 0x1d, 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, + 0x1d, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x1d, + 0x0, 0x0, 0xe, 0x10, 0x3, 0x0, 0x1d, 0x0, + 0x0, 0x9, 0x80, 0x39, 0x0, 0x1d, 0x0, 0x0, + 0x1, 0xe6, 0x76, 0x0, 0x1d, 0x0, 0x0, 0x0, + 0x3e, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+4EE4 "令" */ + 0x0, 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xbd, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0x76, 0xc1, 0x0, 0x0, 0x0, 0x3, 0xd5, + 0x0, 0x4d, 0x50, 0x0, 0x1, 0x9d, 0x31, 0xd3, + 0x2, 0xcb, 0x20, 0x3e, 0x70, 0x0, 0x3d, 0x20, + 0x5, 0xe4, 0x0, 0x0, 0x0, 0x4, 0x10, 0x0, + 0x0, 0x0, 0x8d, 0xdd, 0xdd, 0xdd, 0xf9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0xb0, 0x0, 0x0, + 0x0, 0x24, 0x0, 0x8c, 0x0, 0x0, 0x0, 0x0, + 0x2c, 0xa8, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8f, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+4EE5 "以" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, + 0x1, 0x0, 0x0, 0xa5, 0x0, 0xe, 0x10, 0xb6, + 0x0, 0xb, 0x40, 0x0, 0xe1, 0x1, 0xd2, 0x0, + 0xc2, 0x0, 0xe, 0x10, 0x6, 0xa0, 0xe, 0x0, + 0x0, 0xe1, 0x0, 0x4, 0x1, 0xe0, 0x0, 0xe, + 0x10, 0x0, 0x0, 0x69, 0x0, 0x0, 0xe1, 0x0, + 0x0, 0xa, 0x40, 0x0, 0xe, 0x10, 0x23, 0x1, + 0xe0, 0x0, 0x0, 0xe4, 0xad, 0x40, 0xaf, 0x60, + 0x0, 0x3f, 0xd5, 0x0, 0x6c, 0x1d, 0x60, 0x6, + 0x50, 0x0, 0x7e, 0x10, 0x1e, 0x40, 0x0, 0x2, + 0xd9, 0x10, 0x0, 0x3e, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, 0x0, + + /* U+4EEE "仮" */ + 0x0, 0x8, 0x40, 0x0, 0x0, 0x26, 0x30, 0x0, + 0x1e, 0x7, 0xab, 0xcc, 0xb7, 0x20, 0x0, 0x88, + 0xc, 0x30, 0x0, 0x0, 0x0, 0x1, 0xe1, 0xc, + 0x10, 0x0, 0x0, 0x0, 0xa, 0xf0, 0xc, 0x31, + 0x11, 0x12, 0x0, 0x7d, 0xe0, 0xd, 0xde, 0xcc, + 0xce, 0x60, 0x92, 0xe0, 0xe, 0x2c, 0x0, 0xd, + 0x10, 0x0, 0xe0, 0xe, 0xb, 0x30, 0x3b, 0x0, + 0x0, 0xe0, 0x1c, 0x3, 0xc0, 0xc3, 0x0, 0x0, + 0xe0, 0x5a, 0x0, 0x9c, 0x90, 0x0, 0x0, 0xe0, + 0x95, 0x0, 0x8f, 0x70, 0x0, 0x0, 0xe1, 0xe0, + 0x3c, 0x91, 0xca, 0x20, 0x0, 0xe6, 0x64, 0xc4, + 0x0, 0x6, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4EF6 "件" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x41, 0x30, 0xb3, 0x0, 0x0, 0x0, 0x2e, + 0x5, 0x90, 0xb3, 0x0, 0x0, 0x0, 0x98, 0x9, + 0x60, 0xb3, 0x0, 0x0, 0x2, 0xf2, 0xe, 0xfe, + 0xff, 0xee, 0x60, 0xd, 0xf1, 0x5b, 0x0, 0xb3, + 0x0, 0x0, 0x8b, 0xd1, 0xa3, 0x0, 0xb3, 0x0, + 0x0, 0x31, 0xd1, 0x0, 0x0, 0xb3, 0x0, 0x0, + 0x0, 0xd1, 0xbe, 0xee, 0xff, 0xee, 0xe1, 0x0, + 0xd1, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0xd1, + 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0xd1, 0x0, + 0x0, 0xb3, 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, + 0xb3, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0xb3, + 0x0, 0x0, + + /* U+4EFB "任" */ + 0x0, 0x0, 0xa2, 0x0, 0x0, 0x3, 0x60, 0x0, + 0x4, 0xc1, 0x46, 0x9c, 0xeb, 0x70, 0x0, 0xd, + 0x3a, 0x97, 0x6d, 0x0, 0x0, 0x0, 0x6d, 0x0, + 0x0, 0x1c, 0x0, 0x0, 0x3, 0xfc, 0x0, 0x0, + 0x1c, 0x0, 0x0, 0x2e, 0x6c, 0x0, 0x0, 0x1c, + 0x0, 0x0, 0x15, 0x2c, 0x7e, 0xee, 0xef, 0xee, + 0xec, 0x0, 0x2c, 0x0, 0x0, 0x1c, 0x0, 0x0, + 0x0, 0x2c, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, + 0x2c, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x2c, + 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x2c, 0x2, + 0x22, 0x3d, 0x22, 0x21, 0x0, 0x2c, 0xb, 0xcc, + 0xcc, 0xcc, 0xc7, + + /* U+4EFD "份" */ + 0x0, 0x3, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, + 0xd, 0x20, 0x4b, 0x4, 0xa0, 0x0, 0x0, 0x5b, + 0x0, 0xa5, 0x0, 0xe0, 0x0, 0x0, 0xc3, 0x1, + 0xe0, 0x0, 0x97, 0x0, 0x7, 0xf1, 0xc, 0x70, + 0x0, 0x1e, 0x30, 0x3e, 0xe1, 0xac, 0x0, 0x0, + 0x6, 0xe2, 0x75, 0xd1, 0x99, 0xdf, 0xed, 0xec, + 0x62, 0x0, 0xd1, 0x0, 0xc, 0x10, 0x2b, 0x0, + 0x0, 0xd1, 0x0, 0xe, 0x0, 0x3a, 0x0, 0x0, + 0xd1, 0x0, 0x59, 0x0, 0x59, 0x0, 0x0, 0xd1, + 0x0, 0xd3, 0x0, 0x77, 0x0, 0x0, 0xd1, 0xa, + 0x80, 0x0, 0xa5, 0x0, 0x0, 0xd1, 0x87, 0x0, + 0x9d, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4F01 "企" */ + 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xcc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x77, 0xa0, 0x0, 0x0, 0x0, 0x2, 0xc6, + 0x0, 0x7c, 0x10, 0x0, 0x0, 0x6e, 0x50, 0x36, + 0x4, 0xd8, 0x0, 0x3d, 0x91, 0x0, 0x59, 0x0, + 0x8, 0xe4, 0x2, 0x1, 0x0, 0x59, 0x0, 0x0, + 0x20, 0x0, 0xd, 0x0, 0x5f, 0xdd, 0xd9, 0x0, + 0x0, 0xd, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, + 0x59, 0x0, 0x0, 0x0, 0xc, 0xef, 0xdd, 0xef, + 0xdd, 0xdd, 0xd0, + + /* U+4F0A "伊" */ + 0x0, 0x6, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0x5d, 0xdd, 0xdd, 0xdd, 0x0, 0x0, 0x88, + 0x0, 0xa, 0x30, 0xe, 0x0, 0x2, 0xf2, 0x0, + 0xa, 0x30, 0xe, 0x0, 0xd, 0xf4, 0xaa, 0xae, + 0xca, 0xaf, 0xa0, 0xa9, 0xc3, 0x33, 0x3b, 0x63, + 0x3e, 0x30, 0x60, 0xc2, 0x0, 0xa, 0x30, 0xe, + 0x0, 0x0, 0xc2, 0x0, 0xb, 0x30, 0xe, 0x0, + 0x0, 0xc2, 0x7d, 0xdf, 0xed, 0xdf, 0x0, 0x0, + 0xc2, 0x0, 0x3c, 0x0, 0x5, 0x0, 0x0, 0xc2, + 0x0, 0xc4, 0x0, 0x0, 0x0, 0x0, 0xc2, 0x1b, + 0x80, 0x0, 0x0, 0x0, 0x0, 0xc3, 0xd5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4F11 "休" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd1, 0x0, 0xb2, 0x0, 0x0, 0x0, 0x6, + 0xb0, 0x0, 0xb2, 0x0, 0x0, 0x0, 0xd, 0x40, + 0x0, 0xb2, 0x0, 0x0, 0x0, 0x6e, 0x0, 0x0, + 0xb2, 0x0, 0x0, 0x2, 0xfc, 0x8e, 0xef, 0xff, + 0xee, 0xe4, 0x1d, 0xac, 0x0, 0x8, 0xfe, 0x10, + 0x0, 0x39, 0x2c, 0x0, 0x1d, 0xc8, 0xa0, 0x0, + 0x0, 0x2c, 0x0, 0x86, 0xb3, 0xc3, 0x0, 0x0, + 0x2c, 0x2, 0xd0, 0xb2, 0x3c, 0x0, 0x0, 0x2c, + 0x1d, 0x40, 0xb2, 0x9, 0xa0, 0x0, 0x2c, 0xc7, + 0x0, 0xb2, 0x0, 0xb6, 0x0, 0x2c, 0x10, 0x0, + 0xb2, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0xb2, + 0x0, 0x0, + + /* U+4F1A "会" */ + 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xad, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0xa7, 0xc1, 0x0, 0x0, 0x0, 0x3, 0xc9, + 0x0, 0x5d, 0x50, 0x0, 0x2, 0xaf, 0x82, 0x22, + 0x24, 0xbd, 0x50, 0x1d, 0x83, 0xbb, 0xbb, 0xbb, + 0x53, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xee, 0xee, 0xee, 0xee, 0xee, 0xd0, + 0x0, 0x0, 0x1d, 0x40, 0x2, 0x0, 0x0, 0x0, + 0x0, 0xb6, 0x0, 0x1c, 0x50, 0x0, 0x0, 0xa, + 0x80, 0x0, 0x2, 0xe4, 0x0, 0x0, 0xbf, 0xac, + 0xde, 0xec, 0xbe, 0x20, 0x0, 0x65, 0x32, 0x10, + 0x0, 0x5, 0x50, + + /* U+4F1D "伝" */ + 0x0, 0x8, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0xa, 0xdd, 0xdd, 0xdd, 0x30, 0x0, 0x87, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xf1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8b, 0xe0, 0x8b, 0xbb, 0xbb, + 0xbb, 0xb0, 0x31, 0xe0, 0x12, 0x2e, 0x52, 0x22, + 0x20, 0x0, 0xe0, 0x0, 0x5c, 0x0, 0x0, 0x0, + 0x0, 0xe0, 0x0, 0xc4, 0x0, 0xd2, 0x0, 0x0, + 0xe0, 0x5, 0xb0, 0x0, 0x5a, 0x0, 0x0, 0xe0, + 0x1e, 0x43, 0x46, 0x7f, 0x20, 0x0, 0xe0, 0x7f, + 0xdb, 0x97, 0x68, 0xa0, 0x0, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0xa0, + + /* U+4F38 "伸" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc1, 0x0, 0xe, 0x0, 0x0, 0x0, 0x4b, 0x0, + 0x0, 0xe0, 0x0, 0x0, 0xb, 0x59, 0xbb, 0xbf, + 0xbb, 0xbb, 0x4, 0xf0, 0xd2, 0x11, 0xe1, 0x11, + 0xe1, 0xef, 0xd, 0x0, 0xe, 0x0, 0xe, 0xb8, + 0xe0, 0xdd, 0xdd, 0xfd, 0xdd, 0xe4, 0xe, 0xd, + 0x10, 0xe, 0x0, 0xe, 0x0, 0xe0, 0xd0, 0x0, + 0xe0, 0x0, 0xe0, 0xe, 0xd, 0xed, 0xdf, 0xdd, + 0xde, 0x0, 0xe0, 0x90, 0x0, 0xe0, 0x0, 0x80, + 0xe, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe0, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0xe, 0x0, 0x0, + + /* U+4F3C "似" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0x6, 0x0, 0x0, 0xe, 0x0, 0x0, 0x87, + 0xe, 0x1d, 0x0, 0xe, 0x0, 0x0, 0xe1, 0xe, + 0x9, 0x60, 0x1d, 0x0, 0x9, 0xf0, 0xe, 0x1, + 0xd0, 0x2c, 0x0, 0x4d, 0xe0, 0xe, 0x0, 0xc3, + 0x4a, 0x0, 0x93, 0xe0, 0xe, 0x0, 0x20, 0x77, + 0x0, 0x0, 0xe0, 0xe, 0x0, 0x0, 0xa6, 0x0, + 0x0, 0xe0, 0xe, 0x2, 0x71, 0xec, 0x0, 0x0, + 0xe0, 0xe, 0x8d, 0x37, 0x9b, 0x40, 0x0, 0xe0, + 0x3f, 0x80, 0x1e, 0x13, 0xc0, 0x0, 0xe0, 0x14, + 0x1, 0xd6, 0x0, 0xd2, 0x0, 0xe0, 0x0, 0x6, + 0x70, 0x0, 0x41, + + /* U+4F46 "但" */ + 0x0, 0x6, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x2a, 0xee, 0xee, 0xee, 0x10, 0x0, 0x6a, + 0xb, 0x30, 0x0, 0xe, 0x10, 0x0, 0xe3, 0xb, + 0x30, 0x0, 0xe, 0x10, 0xb, 0xf2, 0xb, 0x30, + 0x0, 0xe, 0x10, 0x7d, 0xc2, 0xb, 0xed, 0xdd, + 0xdf, 0x10, 0x72, 0xb2, 0xb, 0x30, 0x0, 0xe, + 0x10, 0x0, 0xb2, 0xb, 0x30, 0x0, 0xe, 0x10, + 0x0, 0xb2, 0xb, 0x30, 0x0, 0xe, 0x10, 0x0, + 0xb2, 0xa, 0xee, 0xee, 0xee, 0x10, 0x0, 0xb2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb2, 0x22, + 0x22, 0x22, 0x22, 0x20, 0x0, 0xb2, 0xab, 0xbb, + 0xbb, 0xbb, 0xb3, + + /* U+4F4D "位" */ + 0x0, 0x0, 0x50, 0x0, 0x52, 0x0, 0x0, 0x0, + 0x3, 0xc0, 0x0, 0x78, 0x0, 0x0, 0x0, 0xb, + 0x50, 0x0, 0x28, 0x0, 0x0, 0x0, 0x3d, 0x8, + 0xee, 0xee, 0xee, 0xe0, 0x1, 0xeb, 0x0, 0x0, + 0x0, 0x3, 0x0, 0xb, 0xcb, 0x0, 0x85, 0x0, + 0xf, 0x0, 0x1a, 0x3b, 0x0, 0x58, 0x0, 0x3c, + 0x0, 0x0, 0x3b, 0x0, 0x2b, 0x0, 0x59, 0x0, + 0x0, 0x3b, 0x0, 0xe, 0x0, 0x86, 0x0, 0x0, + 0x3b, 0x0, 0xd, 0x10, 0xb2, 0x0, 0x0, 0x3b, + 0x0, 0xb, 0x20, 0xd0, 0x0, 0x0, 0x3b, 0x2, + 0x23, 0x25, 0xb2, 0x21, 0x0, 0x3b, 0x2b, 0xbb, + 0xbb, 0xbb, 0xb6, + + /* U+4F4E "低" */ + 0x0, 0x3, 0x10, 0x0, 0x0, 0x15, 0x0, 0x0, + 0xd, 0x21, 0x46, 0x9d, 0xc8, 0x10, 0x0, 0x5a, + 0xe, 0x96, 0x4d, 0x0, 0x0, 0x0, 0xd3, 0xd, + 0x0, 0xe, 0x0, 0x0, 0x8, 0xf0, 0xd, 0x0, + 0xe, 0x0, 0x0, 0x5e, 0xe0, 0xd, 0x11, 0x1d, + 0x21, 0x10, 0xb3, 0xd0, 0xe, 0xcc, 0xce, 0xcc, + 0xc0, 0x0, 0xd0, 0xd, 0x0, 0x9, 0x40, 0x0, + 0x0, 0xd0, 0xd, 0x0, 0x7, 0x70, 0x0, 0x0, + 0xd0, 0xd, 0x0, 0x4, 0xa0, 0x0, 0x0, 0xd0, + 0xd, 0x0, 0xb0, 0xe0, 0x83, 0x0, 0xd0, 0xe, + 0x59, 0x76, 0x99, 0xb1, 0x0, 0xd0, 0x5d, 0x83, + 0x8, 0xa, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4F4F "住" */ + 0x0, 0x0, 0x80, 0x0, 0x90, 0x0, 0x0, 0x0, + 0x4, 0xb0, 0x0, 0x88, 0x0, 0x0, 0x0, 0xc, + 0x40, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x5d, 0xe, + 0xee, 0xef, 0xee, 0xe6, 0x2, 0xfb, 0x0, 0x0, + 0x4a, 0x0, 0x0, 0xd, 0xab, 0x0, 0x0, 0x4a, + 0x0, 0x0, 0x7, 0x3b, 0x0, 0x0, 0x4a, 0x0, + 0x0, 0x0, 0x3b, 0x8, 0xee, 0xef, 0xee, 0xe0, + 0x0, 0x3b, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, + 0x3b, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x3b, + 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x3b, 0x1, + 0x11, 0x5a, 0x11, 0x10, 0x0, 0x3b, 0x5d, 0xdd, + 0xdd, 0xdd, 0xd8, + + /* U+4F53 "体" */ + 0x0, 0xb, 0x10, 0x0, 0xe0, 0x0, 0x0, 0x0, + 0x3c, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x96, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0x2, 0xf1, 0xee, + 0xee, 0xfe, 0xee, 0xe2, 0xb, 0xf0, 0x0, 0xc, + 0xfb, 0x0, 0x0, 0x6d, 0xe0, 0x0, 0x59, 0xea, + 0x30, 0x0, 0x63, 0xe0, 0x0, 0xc2, 0xe3, 0xb0, + 0x0, 0x0, 0xe0, 0x4, 0x90, 0xe0, 0xc2, 0x0, + 0x0, 0xe0, 0x1d, 0x20, 0xe0, 0x3c, 0x0, 0x0, + 0xe0, 0xb7, 0x33, 0xe3, 0x39, 0xa0, 0x0, 0xe4, + 0x84, 0xaa, 0xfa, 0xa2, 0xa2, 0x0, 0xe0, 0x0, + 0x0, 0xe0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, + 0xd0, 0x0, 0x0, + + /* U+4F55 "何" */ + 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x21, 0x11, 0x11, 0x11, 0x10, 0x0, 0x79, + 0x7c, 0xcc, 0xcc, 0xcf, 0xc0, 0x0, 0xe4, 0x0, + 0x0, 0x0, 0xe, 0x0, 0xa, 0xf2, 0x2, 0x22, + 0x20, 0xe, 0x0, 0x5e, 0xd2, 0x2e, 0xaa, 0xe2, + 0xe, 0x0, 0x43, 0xc2, 0x2a, 0x0, 0xb2, 0xe, + 0x0, 0x0, 0xc2, 0x2a, 0x0, 0xb2, 0xe, 0x0, + 0x0, 0xc2, 0x2e, 0xaa, 0xe2, 0xe, 0x0, 0x0, + 0xc2, 0x2b, 0x22, 0x20, 0xe, 0x0, 0x0, 0xc2, + 0x16, 0x0, 0x0, 0xe, 0x0, 0x0, 0xc2, 0x0, + 0x0, 0x0, 0xe, 0x0, 0x0, 0xc2, 0x0, 0x0, + 0x9f, 0xea, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4F59 "余" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xb9, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x8a, + 0x0, 0x7c, 0x10, 0x0, 0x0, 0x3c, 0x80, 0x0, + 0x5, 0xd7, 0x0, 0x2a, 0xc9, 0xaa, 0xaa, 0xaa, + 0x98, 0xe5, 0x16, 0x1, 0x33, 0x7b, 0x33, 0x20, + 0x22, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, + 0x8, 0xee, 0xee, 0xef, 0xee, 0xee, 0xd0, 0x0, + 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x80, 0x4a, 0x7, 0xa0, 0x0, 0x0, 0x6c, 0x0, + 0x4a, 0x0, 0x9b, 0x0, 0x9, 0xb1, 0x0, 0x5a, + 0x0, 0x9, 0xa0, 0x3, 0x0, 0x4e, 0xe6, 0x0, + 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+4F5C "作" */ + 0x0, 0x0, 0x40, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xd0, 0xd, 0x10, 0x0, 0x0, 0x0, 0xb, + 0x50, 0x5c, 0x22, 0x22, 0x21, 0x0, 0x3e, 0x0, + 0xcb, 0xfc, 0xbb, 0xb5, 0x1, 0xdb, 0x6, 0xa0, + 0xd1, 0x0, 0x0, 0xb, 0xcb, 0x2e, 0x10, 0xd3, + 0x22, 0x20, 0x1b, 0x3b, 0x24, 0x0, 0xdc, 0xbb, + 0xb2, 0x0, 0x3b, 0x0, 0x0, 0xd1, 0x0, 0x0, + 0x0, 0x3b, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, + 0x3b, 0x0, 0x0, 0xdd, 0xdd, 0xd4, 0x0, 0x3b, + 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x3b, 0x0, + 0x0, 0xd1, 0x0, 0x0, 0x0, 0x3b, 0x0, 0x0, + 0xd1, 0x0, 0x0, + + /* U+4F60 "你" */ + 0x0, 0x6, 0x20, 0x80, 0x0, 0x0, 0x0, 0x1, + 0xe0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0x88, 0x6, + 0x80, 0x0, 0x0, 0x0, 0x1f, 0x10, 0xce, 0xdf, + 0xed, 0xee, 0xc, 0xf0, 0x5b, 0x0, 0xc2, 0x2, + 0xb9, 0xbe, 0xc, 0x30, 0xc, 0x20, 0x57, 0x70, + 0xe0, 0x11, 0x90, 0xc2, 0x74, 0x0, 0xe, 0x0, + 0x68, 0xc, 0x23, 0xb0, 0x0, 0xe0, 0xb, 0x30, + 0xc2, 0xc, 0x20, 0xe, 0x4, 0xc0, 0xc, 0x20, + 0x77, 0x0, 0xe0, 0xa3, 0x0, 0xc2, 0x2, 0xb0, + 0xe, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0xd0, + 0x0, 0x4e, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+4F7F "使" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x40, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x2e, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x98, 0xcd, + 0xdd, 0xfd, 0xdd, 0xd1, 0x3, 0xf3, 0x0, 0x0, + 0xe0, 0x0, 0x0, 0xd, 0xf2, 0x6d, 0xcc, 0xfc, + 0xcc, 0x80, 0xaa, 0xc2, 0x76, 0x0, 0xe0, 0x4, + 0x90, 0x50, 0xc2, 0x76, 0x0, 0xe0, 0x4, 0x90, + 0x0, 0xc2, 0x7e, 0xcc, 0xfc, 0xcd, 0x90, 0x0, + 0xc2, 0x26, 0x2, 0xc0, 0x0, 0x0, 0x0, 0xc2, + 0xb, 0x57, 0x80, 0x0, 0x0, 0x0, 0xc2, 0x0, + 0xbf, 0x30, 0x0, 0x0, 0x0, 0xc2, 0x17, 0xd6, + 0xcb, 0x62, 0x0, 0x0, 0xc4, 0xc7, 0x0, 0x3, + 0x7b, 0xc0, + + /* U+4F86 "來" */ + 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0xe, 0xee, + 0xee, 0xff, 0xee, 0xee, 0xe1, 0x0, 0x5, 0x20, + 0x87, 0x0, 0x80, 0x0, 0x0, 0xe, 0x10, 0x87, + 0x3, 0xc0, 0x0, 0x0, 0x5f, 0x30, 0x87, 0x9, + 0xd1, 0x0, 0x1, 0xe6, 0xe3, 0x99, 0x4d, 0x5d, + 0x20, 0xc, 0x70, 0x35, 0xff, 0xa2, 0x3, 0xc0, + 0x2, 0x0, 0x3c, 0xa9, 0xd2, 0x0, 0x0, 0x0, + 0x4, 0xd2, 0x87, 0x2d, 0x30, 0x0, 0x0, 0x8d, + 0x20, 0x87, 0x3, 0xe8, 0x0, 0x2e, 0x80, 0x0, + 0x87, 0x0, 0x1a, 0xe2, 0x2, 0x0, 0x0, 0x87, + 0x0, 0x0, 0x20, + + /* U+4F8B "例" */ + 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x7, + 0x7b, 0xef, 0xee, 0x0, 0xd, 0x0, 0xc2, 0x6, + 0x80, 0x4, 0x80, 0xd0, 0x3f, 0x0, 0xb4, 0x0, + 0x48, 0xd, 0xc, 0xe0, 0xf, 0xed, 0x84, 0x80, + 0xd5, 0xce, 0x4, 0xa0, 0x57, 0x48, 0xd, 0x22, + 0xd0, 0xc4, 0x9, 0x54, 0x80, 0xd0, 0xd, 0x4c, + 0x71, 0xd1, 0x48, 0xd, 0x0, 0xd0, 0x15, 0xdc, + 0x4, 0x80, 0xd0, 0xd, 0x0, 0x9, 0x60, 0x36, + 0xd, 0x0, 0xd0, 0x3, 0xd0, 0x0, 0x0, 0xd0, + 0xd, 0x2, 0xd4, 0x0, 0x0, 0xd, 0x0, 0xd0, + 0xb5, 0x0, 0x0, 0xde, 0x90, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+4F9B "供" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x40, 0xb3, 0x0, 0xe0, 0x0, 0x0, 0x2d, + 0x0, 0xb3, 0x0, 0xe0, 0x0, 0x0, 0x97, 0x0, + 0xb3, 0x0, 0xe0, 0x0, 0x2, 0xf1, 0x8e, 0xfe, + 0xee, 0xfe, 0xe0, 0xb, 0xf0, 0x0, 0xb3, 0x0, + 0xe0, 0x0, 0x8b, 0xe0, 0x0, 0xb3, 0x0, 0xe0, + 0x0, 0x81, 0xe0, 0x0, 0xb3, 0x0, 0xe0, 0x0, + 0x0, 0xe0, 0x0, 0xb3, 0x0, 0xe0, 0x0, 0x0, + 0xe0, 0xde, 0xee, 0xee, 0xee, 0xe2, 0x0, 0xe0, + 0x0, 0x20, 0x0, 0x10, 0x0, 0x0, 0xe0, 0x1, + 0xd1, 0x0, 0xc4, 0x0, 0x0, 0xe0, 0x1c, 0x40, + 0x0, 0x1d, 0x30, 0x0, 0xe0, 0xa5, 0x0, 0x0, + 0x3, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+4F9D "依" */ + 0x0, 0x5, 0x20, 0x2, 0x30, 0x0, 0x0, 0x0, + 0xe, 0x10, 0x2, 0xc0, 0x0, 0x0, 0x0, 0x69, + 0x0, 0x0, 0x92, 0x0, 0x0, 0x0, 0xd3, 0xee, + 0xef, 0xfe, 0xee, 0xe0, 0xa, 0xf0, 0x0, 0x1e, + 0xb0, 0x0, 0x0, 0x6d, 0xe0, 0x0, 0xc6, 0xd1, + 0x0, 0x70, 0x52, 0xe0, 0x1b, 0xa0, 0x86, 0x1c, + 0x60, 0x0, 0xe3, 0xdc, 0x70, 0x3d, 0xc2, 0x0, + 0x0, 0xe7, 0x46, 0x70, 0xb, 0x50, 0x0, 0x0, + 0xe0, 0x6, 0x70, 0x3, 0xe1, 0x0, 0x0, 0xe0, + 0x6, 0x70, 0x10, 0x7b, 0x0, 0x0, 0xe0, 0x8, + 0xbc, 0xb1, 0x9, 0xd1, 0x0, 0xe0, 0xc, 0x82, + 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4FA1 "価" */ + 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0x11, 0x11, 0x11, 0x11, 0x10, 0x0, 0x88, + 0xac, 0xce, 0xce, 0xdc, 0xc0, 0x1, 0xe1, 0x0, + 0x2b, 0x8, 0x50, 0x0, 0xb, 0xf0, 0x0, 0x2b, + 0x8, 0x50, 0x0, 0x8b, 0xe0, 0xae, 0xdf, 0xde, + 0xed, 0xf0, 0x51, 0xe0, 0xa3, 0x1b, 0x8, 0x40, + 0xe0, 0x0, 0xe0, 0xa3, 0x1b, 0x8, 0x40, 0xe0, + 0x0, 0xe0, 0xa3, 0x1b, 0x8, 0x40, 0xe0, 0x0, + 0xe0, 0xa3, 0x1b, 0x8, 0x40, 0xe0, 0x0, 0xe0, + 0xa3, 0x1b, 0x8, 0x40, 0xe0, 0x0, 0xe0, 0xad, + 0xde, 0xde, 0xdd, 0xf0, 0x0, 0xe0, 0xa3, 0x0, + 0x0, 0x0, 0xd0, + + /* U+4FBF "便" */ + 0x0, 0x7, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0x8d, 0xdd, 0xfe, 0xdd, 0xd0, 0x0, 0x88, + 0x0, 0x0, 0xb3, 0x0, 0x0, 0x1, 0xe1, 0x2c, + 0xbb, 0xec, 0xbc, 0x70, 0xa, 0xf0, 0x3a, 0x0, + 0xb3, 0x5, 0x80, 0x5d, 0xe0, 0x3e, 0xbb, 0xec, + 0xbd, 0x80, 0x53, 0xe0, 0x3a, 0x0, 0xb3, 0x5, + 0x80, 0x0, 0xe0, 0x3b, 0x11, 0xb4, 0x16, 0x80, + 0x0, 0xe0, 0x2a, 0xaa, 0xfa, 0xaa, 0x50, 0x0, + 0xe0, 0x3a, 0x1, 0xd0, 0x0, 0x0, 0x0, 0xe0, + 0x7, 0xbb, 0x50, 0x0, 0x0, 0x0, 0xe0, 0x4, + 0xdc, 0xc7, 0x31, 0x0, 0x0, 0xe2, 0xd9, 0x20, + 0x16, 0x9c, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4FC2 "係" */ + 0x0, 0x7, 0x10, 0x0, 0x0, 0x14, 0x0, 0x0, + 0x2d, 0x47, 0x8a, 0xcd, 0xc9, 0x10, 0x0, 0x87, + 0x45, 0x6e, 0x20, 0x10, 0x0, 0x1, 0xf1, 0x0, + 0xc2, 0x4, 0xe1, 0x0, 0xb, 0xf0, 0x1d, 0xdb, + 0xbd, 0x20, 0x0, 0x6d, 0xe0, 0x5, 0x39, 0xb1, + 0x62, 0x0, 0x72, 0xd0, 0x1, 0xb7, 0x0, 0x5d, + 0x0, 0x0, 0xd0, 0x5e, 0xec, 0xfb, 0xaa, 0x90, + 0x0, 0xd0, 0x23, 0x10, 0xe0, 0x0, 0x80, 0x0, + 0xd0, 0xa, 0x40, 0xe0, 0x87, 0x0, 0x0, 0xd0, + 0x4c, 0x0, 0xe0, 0xb, 0x40, 0x0, 0xd3, 0xd1, + 0x0, 0xe0, 0x2, 0xc0, 0x0, 0xd0, 0x10, 0x5e, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4FDD "保" */ + 0x0, 0x4, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x2e, 0xdd, 0xdd, 0xdf, 0x50, 0x0, 0x69, + 0xe, 0x0, 0x0, 0x9, 0x50, 0x1, 0xe2, 0xe, + 0x0, 0x0, 0x9, 0x50, 0xc, 0xf2, 0xe, 0xbb, + 0xbb, 0xbe, 0x50, 0x99, 0xc2, 0x1, 0x11, 0xd3, + 0x11, 0x0, 0x50, 0xc2, 0x0, 0x0, 0xc1, 0x0, + 0x0, 0x0, 0xc2, 0xdd, 0xdd, 0xfe, 0xdd, 0xd1, + 0x0, 0xc2, 0x0, 0xc, 0xed, 0x20, 0x0, 0x0, + 0xc2, 0x0, 0xa6, 0xc4, 0xd1, 0x0, 0x0, 0xc2, + 0x1a, 0x90, 0xc1, 0x5c, 0x20, 0x0, 0xc4, 0xd6, + 0x0, 0xc1, 0x4, 0xe3, 0x0, 0xb2, 0x20, 0x0, + 0xc1, 0x0, 0x20, + + /* U+4FE1 "信" */ + 0x0, 0x4, 0x0, 0x3, 0x20, 0x0, 0x0, 0x0, + 0x1e, 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, 0x88, + 0x22, 0x22, 0xa3, 0x22, 0x20, 0x1, 0xe2, 0x89, + 0x99, 0x99, 0x99, 0x90, 0xc, 0xf0, 0x4, 0x55, + 0x55, 0x55, 0x0, 0x7b, 0xd0, 0x4, 0x55, 0x55, + 0x54, 0x0, 0x30, 0xd0, 0x9, 0xaa, 0xaa, 0xa9, + 0x0, 0x0, 0xd0, 0x1, 0x22, 0x22, 0x22, 0x0, + 0x0, 0xd0, 0x9, 0x99, 0x99, 0x99, 0x0, 0x0, + 0xd0, 0xd, 0x22, 0x22, 0x2d, 0x0, 0x0, 0xd0, + 0xc, 0x0, 0x0, 0xc, 0x0, 0x0, 0xd0, 0xc, + 0x0, 0x0, 0xd, 0x0, 0x0, 0xd0, 0xf, 0xbb, + 0xbb, 0xbe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+4FEE "修" */ + 0x0, 0x4, 0x0, 0x3, 0x40, 0x0, 0x0, 0x0, + 0x2d, 0x0, 0xc, 0x40, 0x0, 0x0, 0x0, 0x96, + 0x0, 0x5e, 0xcc, 0xce, 0x90, 0x1, 0xf0, 0x4, + 0xdb, 0x30, 0x1c, 0x10, 0xa, 0xf0, 0xa7, 0x20, + 0xb7, 0xc3, 0x0, 0x5c, 0xe0, 0xc0, 0x4, 0xbc, + 0xc4, 0x0, 0x92, 0xe0, 0xc8, 0xc8, 0x23, 0x39, + 0xd2, 0x0, 0xe0, 0xc0, 0x1, 0x89, 0x0, 0x0, + 0x0, 0xe0, 0xc0, 0x6a, 0x40, 0x85, 0x0, 0x0, + 0xe0, 0xc0, 0x1, 0x7c, 0x50, 0x40, 0x0, 0xe0, + 0xc0, 0x4a, 0x40, 0x2b, 0x70, 0x0, 0xe0, 0x0, + 0x3, 0x7b, 0xb3, 0x0, 0x0, 0xe0, 0x1, 0xc9, + 0x50, 0x0, 0x0, + + /* U+500B "個" */ + 0x0, 0x9, 0x10, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xc1, 0xfd, 0xdd, 0xdd, 0xde, 0x0, 0xa5, 0x1c, + 0x0, 0x52, 0x0, 0xe0, 0x2f, 0x1, 0xc0, 0x7, + 0x30, 0xe, 0xd, 0xf0, 0x1c, 0x7b, 0xdc, 0xb5, + 0xe9, 0xae, 0x1, 0xc0, 0x7, 0x30, 0xe, 0x60, + 0xe0, 0x1c, 0xb, 0xdc, 0x90, 0xe0, 0xe, 0x1, + 0xc0, 0xb0, 0xc, 0xe, 0x0, 0xe0, 0x1c, 0xb, + 0x0, 0xc0, 0xe0, 0xe, 0x1, 0xc0, 0xeb, 0xbc, + 0xe, 0x0, 0xe0, 0x1c, 0x0, 0x0, 0x0, 0xe0, + 0xe, 0x1, 0xfd, 0xdd, 0xdd, 0xde, 0x0, 0xe0, + 0x1c, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5011 "們" */ + 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, + 0x9d, 0xcc, 0xf0, 0xfc, 0xce, 0x0, 0xc4, 0xd0, + 0xb, 0xc, 0x0, 0xe0, 0x3f, 0xd, 0xcb, 0xe0, + 0xfb, 0xbe, 0xd, 0xf0, 0xd0, 0xb, 0xc, 0x0, + 0xe7, 0xbe, 0xd, 0xcc, 0xf0, 0xfc, 0xce, 0x71, + 0xe0, 0xd0, 0x0, 0x0, 0x0, 0xe0, 0xe, 0xd, + 0x0, 0x0, 0x0, 0xe, 0x0, 0xe0, 0xd0, 0x0, + 0x0, 0x0, 0xe0, 0xe, 0xd, 0x0, 0x0, 0x0, + 0xe, 0x0, 0xe0, 0xd0, 0x0, 0x0, 0x0, 0xe0, + 0xe, 0xd, 0x0, 0x0, 0x0, 0xe, 0x0, 0xe0, + 0xd0, 0x0, 0x6, 0xed, 0x80, + + /* U+5019 "候" */ + 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2c, 0x0, 0x7c, 0xcc, 0xcf, 0x0, 0x0, 0x86, + 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0xe0, 0xb4, + 0xaa, 0xaa, 0xbe, 0xa3, 0x9, 0xf0, 0xd0, 0x2b, + 0x32, 0x22, 0x20, 0x3d, 0xe0, 0xd0, 0x3e, 0x55, + 0x55, 0x40, 0x33, 0xe0, 0xd0, 0xb8, 0x6f, 0x66, + 0x50, 0x0, 0xe0, 0xd3, 0x90, 0xe, 0x0, 0x0, + 0x0, 0xe0, 0xd3, 0xaa, 0xaf, 0xaa, 0xa3, 0x0, + 0xe0, 0xd1, 0x22, 0x6f, 0x62, 0x20, 0x0, 0xe0, + 0x10, 0x0, 0xc6, 0xc0, 0x0, 0x0, 0xe0, 0x0, + 0x4d, 0x60, 0x6d, 0x40, 0x0, 0xe0, 0x7, 0xa2, + 0x0, 0x3, 0xb3, + + /* U+501F "借" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x50, 0xa3, 0x0, 0xe0, 0x0, 0x0, 0x1e, + 0x0, 0xa3, 0x0, 0xe0, 0x0, 0x0, 0x88, 0x7d, + 0xfd, 0xdd, 0xfd, 0xc0, 0x1, 0xf1, 0x0, 0xa3, + 0x0, 0xe0, 0x0, 0xb, 0xf0, 0x0, 0xa3, 0x0, + 0xe0, 0x0, 0x8c, 0xe2, 0xdd, 0xdd, 0xdd, 0xdd, + 0xd6, 0x81, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe0, 0xa, 0xdc, 0xcc, 0xcf, 0x20, 0x0, + 0xe0, 0xa, 0x30, 0x0, 0xc, 0x20, 0x0, 0xe0, + 0xa, 0xcb, 0xbb, 0xbf, 0x20, 0x0, 0xe0, 0xa, + 0x30, 0x0, 0xc, 0x20, 0x0, 0xe0, 0xa, 0x51, + 0x11, 0x1c, 0x20, 0x0, 0xd0, 0xa, 0xca, 0xaa, + 0xae, 0x20, + + /* U+5024 "値" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0x60, 0x0, 0x39, 0x0, 0x0, 0x0, 0xe, + 0x20, 0x0, 0x49, 0x0, 0x0, 0x0, 0x6a, 0xc, + 0xcc, 0xde, 0xcc, 0xb0, 0x0, 0xe2, 0x0, 0x0, + 0x65, 0x0, 0x0, 0x9, 0xf0, 0x16, 0xf, 0xbb, + 0xbf, 0x10, 0x6d, 0xe0, 0x3a, 0xe, 0x0, 0xc, + 0x10, 0xa2, 0xe0, 0x3a, 0xf, 0xaa, 0xae, 0x10, + 0x0, 0xe0, 0x3a, 0xe, 0x11, 0x1c, 0x10, 0x0, + 0xe0, 0x3a, 0xf, 0x99, 0x9e, 0x10, 0x0, 0xe0, + 0x3a, 0xe, 0x44, 0x4d, 0x10, 0x0, 0xe0, 0x3a, + 0x5, 0x55, 0x55, 0x0, 0x0, 0xe0, 0x3e, 0xaa, + 0xaa, 0xaa, 0xa0, 0x0, 0xe0, 0x3b, 0x22, 0x22, + 0x22, 0x20, + + /* U+503C "值" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x40, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x1e, + 0x10, 0x0, 0xe1, 0x0, 0x0, 0x0, 0x79, 0x7c, + 0xcc, 0xfc, 0xcc, 0x90, 0x1, 0xe2, 0x0, 0x4, + 0x90, 0x0, 0x0, 0xa, 0xf0, 0xc, 0xcb, 0xbb, + 0xbe, 0x0, 0x5d, 0xe0, 0xc, 0x0, 0x0, 0xe, + 0x0, 0x53, 0xd0, 0xc, 0xbb, 0xbb, 0xbe, 0x0, + 0x0, 0xd0, 0xc, 0x0, 0x0, 0xe, 0x0, 0x0, + 0xd0, 0xc, 0xbb, 0xbb, 0xbe, 0x0, 0x0, 0xd0, + 0xc, 0x0, 0x0, 0xe, 0x0, 0x0, 0xd0, 0xc, + 0xbb, 0xbb, 0xbe, 0x0, 0x0, 0xd0, 0xc, 0x0, + 0x0, 0xe, 0x0, 0x0, 0xd2, 0xcf, 0xdc, 0xcc, + 0xcf, 0xc3, + + /* U+505A "做" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x4, 0x70, 0x8, 0x60, 0x0, 0x0, 0x5a, + 0x4, 0x70, 0xc, 0x30, 0x0, 0x0, 0xb5, 0x4, + 0x70, 0xe, 0x0, 0x0, 0x2, 0xf3, 0xde, 0xed, + 0x7f, 0xcd, 0xf5, 0xa, 0xf0, 0x4, 0x70, 0x8a, + 0x4, 0xa0, 0x4d, 0xe0, 0x4, 0x70, 0xdc, 0x6, + 0x70, 0x93, 0xd0, 0x26, 0x95, 0x9c, 0x9, 0x40, + 0x0, 0xd0, 0xda, 0xaf, 0x9, 0x3d, 0x0, 0x0, + 0xd0, 0xd0, 0xc, 0x4, 0xba, 0x0, 0x0, 0xd0, + 0xd0, 0xc, 0x0, 0xf4, 0x0, 0x0, 0xd0, 0xd0, + 0xd, 0x5, 0xf8, 0x0, 0x0, 0xd0, 0xdc, 0xcc, + 0x4c, 0x1b, 0x50, 0x0, 0xd0, 0x90, 0x5, 0x90, + 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+505C "停" */ + 0x0, 0x6, 0x30, 0x1, 0x90, 0x0, 0x0, 0x0, + 0xe, 0x56, 0x67, 0xe8, 0x66, 0x61, 0x0, 0x69, + 0x35, 0x55, 0x55, 0x55, 0x50, 0x0, 0xd2, 0x7, + 0xba, 0xaa, 0xac, 0x0, 0x8, 0xf0, 0x9, 0x40, + 0x0, 0xe, 0x0, 0x4d, 0xe0, 0x7, 0xbb, 0xbb, + 0xbc, 0x0, 0x64, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd0, 0xdb, 0xbb, 0xbb, 0xbb, 0xe1, + 0x0, 0xd0, 0xd1, 0x22, 0x22, 0x22, 0xb1, 0x0, + 0xd0, 0x26, 0x99, 0xfa, 0x98, 0x20, 0x0, 0xd0, + 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0xd0, 0x0, + 0x0, 0xd1, 0x0, 0x0, 0x0, 0xd0, 0x0, 0xac, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5065 "健" */ + 0x0, 0x2b, 0x0, 0x0, 0xa, 0x10, 0x0, 0x0, + 0x78, 0xdd, 0xd6, 0xbe, 0xcb, 0x50, 0x0, 0xc2, + 0x5, 0x90, 0xa, 0x14, 0x70, 0x3, 0xf0, 0xc, + 0x3c, 0xce, 0xcd, 0xe6, 0xc, 0xe0, 0x59, 0x0, + 0xa, 0x14, 0x70, 0x5c, 0xd1, 0xeb, 0x86, 0xbe, + 0xcc, 0x70, 0x22, 0xd0, 0x43, 0xc0, 0xa, 0x10, + 0x0, 0x0, 0xd1, 0x32, 0xa8, 0xbe, 0xcb, 0x80, + 0x0, 0xd1, 0xc6, 0x70, 0xa, 0x10, 0x0, 0x0, + 0xd0, 0x9d, 0x2c, 0xce, 0xcc, 0xc2, 0x0, 0xd0, + 0x4f, 0x40, 0xa, 0x10, 0x0, 0x0, 0xd1, 0xc3, + 0xb9, 0x45, 0x10, 0x0, 0x0, 0xd8, 0x50, 0x4, + 0x8a, 0xcd, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5074 "側" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xc0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x78, 0xbd, + 0xcd, 0xc0, 0x30, 0xd0, 0xd, 0x3b, 0x10, 0x1c, + 0xc, 0xd, 0x4, 0xf0, 0xb7, 0x56, 0xc0, 0xc0, + 0xd0, 0xdf, 0xb, 0x76, 0x7c, 0xc, 0xd, 0x7b, + 0xe0, 0xb1, 0x1, 0xc0, 0xc0, 0xd8, 0x1e, 0xb, + 0xcb, 0xbc, 0xc, 0xd, 0x0, 0xe0, 0xb2, 0x1, + 0xc0, 0xc0, 0xd0, 0xe, 0xb, 0x20, 0x2c, 0xc, + 0xd, 0x0, 0xe0, 0x8b, 0xbb, 0x80, 0xb0, 0xd0, + 0xe, 0x1, 0xb0, 0x83, 0x0, 0xd, 0x0, 0xe0, + 0xb5, 0x2, 0xc0, 0x0, 0xd0, 0xe, 0x37, 0x0, + 0x5, 0x5, 0xda, + + /* U+5099 "備" */ + 0x0, 0xc, 0x0, 0x76, 0x1, 0xc0, 0x0, 0x0, + 0x5a, 0x0, 0x77, 0x2, 0xc0, 0x0, 0x0, 0xb5, + 0x8d, 0xee, 0xdd, 0xfd, 0x90, 0x2, 0xf0, 0x0, + 0x76, 0x1, 0xc0, 0x0, 0xb, 0xf0, 0xdd, 0xfe, + 0xde, 0xed, 0xd1, 0x4d, 0xe0, 0x7, 0xa0, 0x0, + 0x0, 0x0, 0x53, 0xe0, 0x8f, 0xdc, 0xdd, 0xcd, + 0x60, 0x0, 0xe8, 0x9e, 0x0, 0xa3, 0x7, 0x60, + 0x0, 0xe0, 0xd, 0xbb, 0xec, 0xbd, 0x60, 0x0, + 0xe0, 0xd, 0x0, 0xa3, 0x7, 0x60, 0x0, 0xe0, + 0xd, 0xcb, 0xec, 0xbd, 0x60, 0x0, 0xe0, 0xd, + 0x0, 0xa3, 0x7, 0x60, 0x0, 0xe0, 0xd, 0x0, + 0xa3, 0x5c, 0x40, + + /* U+50B3 "傳" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x40, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x2e, + 0xad, 0xdd, 0xfd, 0xdd, 0xd1, 0x0, 0x97, 0x0, + 0x0, 0xd1, 0x0, 0x0, 0x2, 0xf1, 0x2e, 0x99, + 0xfa, 0x9c, 0x70, 0xd, 0xf0, 0x2d, 0x77, 0xe8, + 0x7a, 0x70, 0xab, 0xe0, 0x2b, 0x11, 0xd2, 0x17, + 0x70, 0x70, 0xe0, 0x1a, 0xaa, 0xfa, 0xcd, 0x50, + 0x0, 0xe0, 0x56, 0x66, 0xe7, 0x8f, 0x60, 0x0, + 0xe0, 0x56, 0x55, 0x44, 0xc6, 0x91, 0x0, 0xe1, + 0xcc, 0xcc, 0xcc, 0xed, 0xc2, 0x0, 0xe0, 0x4, + 0x90, 0x0, 0xa3, 0x0, 0x0, 0xe0, 0x0, 0x79, + 0x0, 0xb3, 0x0, 0x0, 0xd0, 0x0, 0x1, 0x8c, + 0xd1, 0x0, + + /* U+50C5 "僅" */ + 0x0, 0xa, 0x20, 0xd0, 0x0, 0xd1, 0x0, 0x0, + 0x3d, 0x8a, 0xfa, 0xaa, 0xfa, 0xa0, 0x0, 0xa7, + 0x11, 0xe1, 0x11, 0xd2, 0x10, 0x2, 0xf1, 0x0, + 0xda, 0xaa, 0xf1, 0x0, 0xd, 0xf0, 0x0, 0x12, + 0xe2, 0x20, 0x0, 0xac, 0xe0, 0x2e, 0xaa, 0xfb, + 0xad, 0x60, 0x71, 0xe0, 0x2c, 0x11, 0xe2, 0x19, + 0x60, 0x0, 0xe0, 0x17, 0x77, 0xf8, 0x77, 0x30, + 0x0, 0xe0, 0x5b, 0xbb, 0xfc, 0xbb, 0x70, 0x0, + 0xe0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0xe0, + 0x1b, 0xbb, 0xfb, 0xbb, 0x30, 0x0, 0xe0, 0x0, + 0x0, 0xe0, 0x0, 0x0, 0x0, 0xe0, 0xbb, 0xbb, + 0xfc, 0xbb, 0xb0, + + /* U+50CD "働" */ + 0x0, 0xb, 0x0, 0x25, 0x60, 0xb1, 0x0, 0x0, + 0x6a, 0xbb, 0xe7, 0x40, 0xb1, 0x0, 0x0, 0xc4, + 0x66, 0xe6, 0x61, 0xb1, 0x0, 0x3, 0xf1, 0x55, + 0xe5, 0x5a, 0xeb, 0xb3, 0xc, 0xf0, 0xaa, 0xfa, + 0xa1, 0xc3, 0x94, 0x6b, 0xd0, 0xa0, 0xb0, 0xb0, + 0xc0, 0x93, 0x62, 0xd0, 0xe9, 0xe9, 0xe0, 0xd0, + 0x93, 0x0, 0xd0, 0xb1, 0xb1, 0xb0, 0xd0, 0xa2, + 0x0, 0xd0, 0x77, 0xe7, 0x71, 0xc0, 0xa2, 0x0, + 0xd0, 0x99, 0xe9, 0x96, 0x80, 0xb1, 0x0, 0xd0, + 0x11, 0xd1, 0x1b, 0x30, 0xd0, 0x0, 0xd1, 0x56, + 0xea, 0xcb, 0x0, 0xd0, 0x0, 0xd3, 0x86, 0x42, + 0xb2, 0x8d, 0x80, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+50CF "像" */ + 0x0, 0x5, 0x40, 0x64, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x22, 0xfc, 0xbb, 0x10, 0x0, 0x0, 0x6a, + 0x1c, 0x50, 0x3a, 0x0, 0x0, 0x1, 0xe4, 0xdf, + 0xbb, 0xed, 0xbc, 0x10, 0xb, 0xf2, 0x5d, 0x0, + 0xb0, 0xb, 0x20, 0x7c, 0xe0, 0xf, 0xbc, 0xeb, + 0xbe, 0x20, 0x41, 0xe0, 0x0, 0x8f, 0x10, 0x2, + 0x0, 0x0, 0xe0, 0x7d, 0x75, 0x90, 0x8b, 0x0, + 0x0, 0xe0, 0x20, 0x6a, 0xac, 0xd0, 0x0, 0x0, + 0xe0, 0x6c, 0x71, 0xc7, 0x75, 0x0, 0x0, 0xe0, + 0x41, 0x6b, 0x59, 0x1d, 0x20, 0x0, 0xe0, 0x7d, + 0x80, 0x58, 0x3, 0xd0, 0x0, 0xd0, 0x50, 0xb, + 0xd2, 0x0, 0x0, + + /* U+50D5 "僕" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x55, 0xc, 0xc, 0x4, 0x30, 0x0, 0x2e, + 0xd, 0xc, 0xc, 0xc, 0x20, 0x0, 0xa7, 0x5, + 0x2c, 0xc, 0x17, 0x0, 0x3, 0xf1, 0xcd, 0xfc, + 0xcc, 0xed, 0xc1, 0x1e, 0xf0, 0x0, 0xd1, 0x0, + 0xd1, 0x0, 0xb9, 0xe0, 0x7b, 0xec, 0xbc, 0xeb, + 0x90, 0x60, 0xe0, 0x0, 0x0, 0xe0, 0x0, 0x0, + 0x0, 0xe0, 0x2b, 0xbb, 0xfb, 0xbb, 0x30, 0x0, + 0xe0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0xe0, + 0xcc, 0xcc, 0xfc, 0xcc, 0xc3, 0x0, 0xe0, 0x0, + 0x9, 0xbc, 0x10, 0x0, 0x0, 0xe0, 0x3, 0xb9, + 0x4, 0xd6, 0x10, 0x0, 0xe0, 0xbb, 0x30, 0x0, + 0x29, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+50F9 "價" */ + 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0xab, 0xce, 0xbe, 0xcb, 0xb0, 0x0, 0xb3, + 0x59, 0xad, 0x9e, 0xa9, 0x60, 0x2, 0xf0, 0x84, + 0x2a, 0xa, 0x23, 0xa0, 0xc, 0xf0, 0x8a, 0x9d, + 0x8d, 0x9a, 0xa0, 0x7a, 0xe0, 0x13, 0x33, 0x33, + 0x33, 0x20, 0x71, 0xe0, 0x3d, 0x77, 0x77, 0x7b, + 0x70, 0x0, 0xe0, 0x3d, 0x99, 0x99, 0x9c, 0x70, + 0x0, 0xe0, 0x3a, 0x11, 0x11, 0x18, 0x70, 0x0, + 0xe0, 0x3d, 0x77, 0x77, 0x7b, 0x70, 0x0, 0xe0, + 0x3d, 0x99, 0x99, 0x9c, 0x70, 0x0, 0xe0, 0x2, + 0x94, 0x4, 0xa4, 0x0, 0x0, 0xe1, 0xb9, 0x30, + 0x0, 0x28, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5104 "億" */ + 0x0, 0x3, 0x10, 0x2, 0x40, 0x0, 0x0, 0x0, + 0xd, 0x31, 0x12, 0xd1, 0x11, 0x10, 0x0, 0x5a, + 0x4a, 0xd9, 0x99, 0xea, 0x70, 0x0, 0xd3, 0x11, + 0xc2, 0x13, 0xd1, 0x10, 0xa, 0xf1, 0xaa, 0xaa, + 0xaa, 0xaa, 0xa2, 0x6c, 0xe0, 0x9, 0xaa, 0xaa, + 0xaa, 0x10, 0x41, 0xe0, 0xe, 0x11, 0x11, 0x1d, + 0x10, 0x0, 0xe0, 0xe, 0x77, 0x77, 0x7e, 0x10, + 0x0, 0xe0, 0xe, 0x99, 0x99, 0x9e, 0x10, 0x0, + 0xe0, 0x0, 0x7, 0x90, 0x1, 0x0, 0x0, 0xe0, + 0x56, 0xd0, 0x79, 0xc, 0x20, 0x0, 0xe0, 0xd1, + 0xd0, 0x0, 0x56, 0xc0, 0x0, 0xe1, 0x60, 0x9c, + 0xcc, 0xc2, 0x61, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+512A "優" */ + 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3c, 0x7b, 0xbb, 0xfc, 0xbb, 0xb1, 0x0, 0xa5, + 0x5, 0x88, 0xe8, 0x88, 0x0, 0x1, 0xf0, 0x8, + 0xb8, 0x88, 0x8e, 0x0, 0xb, 0xf0, 0x8, 0x84, + 0x44, 0x4e, 0x0, 0x6b, 0xe0, 0x8, 0x84, 0x44, + 0x4e, 0x0, 0x81, 0xe0, 0xe9, 0xab, 0xfa, 0x9a, + 0xd5, 0x0, 0xe0, 0xb7, 0x78, 0x46, 0x4b, 0x94, + 0x0, 0xe0, 0x56, 0x1d, 0x98, 0x71, 0xa0, 0x0, + 0xe0, 0x1, 0xbf, 0xa9, 0x97, 0x0, 0x0, 0xe0, + 0xaa, 0xa9, 0x3, 0xc4, 0x0, 0x0, 0xe0, 0x10, + 0x2b, 0xef, 0x61, 0x0, 0x0, 0xe1, 0xbb, 0x95, + 0x14, 0x9c, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+513F "儿" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xd0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x1, + 0xd0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x1, 0xd0, + 0x0, 0xe, 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, + 0xe, 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, 0xe, + 0x0, 0x0, 0x0, 0x2, 0xc0, 0x0, 0xe, 0x0, + 0x0, 0x0, 0x3, 0xb0, 0x0, 0xe, 0x0, 0x0, + 0x0, 0x7, 0x80, 0x0, 0xe, 0x0, 0x0, 0x0, + 0xc, 0x40, 0x0, 0xe, 0x0, 0x26, 0x0, 0x5c, + 0x0, 0x0, 0xe, 0x0, 0x39, 0x4, 0xe3, 0x0, + 0x0, 0xd, 0x10, 0x68, 0x1d, 0x30, 0x0, 0x0, + 0x9, 0xee, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5143 "元" */ + 0x0, 0xcd, 0xdd, 0xdd, 0xdd, 0xdd, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2e, 0xee, 0xee, 0xee, + 0xee, 0xee, 0xe2, 0x0, 0x0, 0x96, 0x0, 0xc2, + 0x0, 0x0, 0x0, 0x0, 0xb4, 0x0, 0xc2, 0x0, + 0x0, 0x0, 0x0, 0xe1, 0x0, 0xc2, 0x0, 0x0, + 0x0, 0x4, 0xc0, 0x0, 0xc2, 0x0, 0x41, 0x0, + 0xd, 0x50, 0x0, 0xc2, 0x0, 0x85, 0x1, 0xaa, + 0x0, 0x0, 0xc3, 0x0, 0xa3, 0x1e, 0x70, 0x0, + 0x0, 0x7e, 0xee, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5144 "兄" */ + 0x0, 0xde, 0xee, 0xee, 0xee, 0xee, 0x0, 0x0, + 0xd1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0xd1, + 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0xd1, 0x0, + 0x0, 0x0, 0x1e, 0x0, 0x0, 0xd1, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0xce, 0xff, 0xee, 0xfe, + 0xed, 0x0, 0x0, 0x0, 0xb5, 0x0, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0xd2, 0x0, 0xe0, 0x0, 0x0, + 0x0, 0x2, 0xe0, 0x0, 0xe0, 0x0, 0x10, 0x0, + 0xb, 0x70, 0x0, 0xe0, 0x0, 0x76, 0x2, 0xbb, + 0x0, 0x0, 0xf0, 0x0, 0x95, 0x4d, 0x60, 0x0, + 0x0, 0xbe, 0xee, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5145 "充" */ + 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4d, 0x0, 0x0, 0x0, 0xb, 0xbb, + 0xbb, 0xbd, 0xbb, 0xbb, 0xb1, 0x3, 0x33, 0x8e, + 0x43, 0x34, 0x33, 0x30, 0x0, 0x2, 0xd2, 0x0, + 0x4c, 0x10, 0x0, 0x0, 0x1d, 0x40, 0x0, 0x4, + 0xd3, 0x0, 0x1, 0xee, 0xbc, 0xcd, 0xee, 0xde, + 0x20, 0x0, 0x54, 0x5d, 0x10, 0xf0, 0x4, 0x60, + 0x0, 0x0, 0x5a, 0x0, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0xa6, 0x0, 0xe0, 0x0, 0x10, 0x0, 0x2, + 0xe1, 0x0, 0xe0, 0x0, 0x95, 0x0, 0x3e, 0x50, + 0x0, 0xe1, 0x0, 0xb3, 0xb, 0xd5, 0x0, 0x0, + 0xae, 0xde, 0xc0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5148 "先" */ + 0x0, 0x5, 0x20, 0x77, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x20, 0x77, 0x0, 0x0, 0x0, 0x0, 0x3f, + 0xbb, 0xdd, 0xbb, 0xbb, 0x10, 0x0, 0xb6, 0x22, + 0x99, 0x22, 0x22, 0x0, 0x4, 0xc0, 0x0, 0x77, + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x77, 0x0, + 0x0, 0x0, 0x1e, 0xee, 0xee, 0xff, 0xee, 0xee, + 0xe2, 0x0, 0x0, 0x87, 0x0, 0xa4, 0x0, 0x0, + 0x0, 0x0, 0xa4, 0x0, 0xa4, 0x0, 0x0, 0x0, + 0x0, 0xe1, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x8, + 0x90, 0x0, 0xa4, 0x0, 0x84, 0x0, 0x7d, 0x10, + 0x0, 0xa4, 0x0, 0xa3, 0x1d, 0xa1, 0x0, 0x0, + 0x6e, 0xee, 0xc0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5149 "光" */ + 0x0, 0x10, 0x0, 0x86, 0x0, 0x3, 0x0, 0x0, + 0xc3, 0x0, 0x86, 0x0, 0x2e, 0x0, 0x0, 0x4b, + 0x0, 0x86, 0x0, 0x97, 0x0, 0x0, 0xd, 0x20, + 0x86, 0x1, 0xd0, 0x0, 0x0, 0x6, 0x50, 0x86, + 0x5, 0x60, 0x0, 0x1, 0x11, 0x11, 0x98, 0x11, + 0x11, 0x10, 0x2c, 0xcc, 0xde, 0xcc, 0xed, 0xcc, + 0xc3, 0x0, 0x0, 0x87, 0x0, 0xb3, 0x0, 0x0, + 0x0, 0x0, 0xb4, 0x0, 0xb3, 0x0, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0xa, + 0x80, 0x0, 0xb3, 0x0, 0x75, 0x3, 0xba, 0x0, + 0x0, 0xb3, 0x0, 0x94, 0x3d, 0x50, 0x0, 0x0, + 0x7e, 0xee, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+514B "克" */ + 0x0, 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0x1, + 0x11, 0x11, 0x87, 0x11, 0x11, 0x10, 0xc, 0xcc, + 0xcc, 0xee, 0xcc, 0xcc, 0xc0, 0x0, 0x0, 0x0, + 0x86, 0x0, 0x0, 0x0, 0x0, 0x6d, 0xdd, 0xee, + 0xdd, 0xd7, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, + 0x68, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x68, + 0x0, 0x0, 0x7e, 0xcc, 0xcc, 0xcc, 0xd8, 0x0, + 0x0, 0x1, 0x5b, 0x11, 0xf1, 0x10, 0x0, 0x0, + 0x0, 0x97, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x2, + 0xe1, 0x0, 0xe0, 0x0, 0x84, 0x0, 0x5e, 0x50, + 0x0, 0xf0, 0x0, 0xa4, 0x1e, 0xa3, 0x0, 0x0, + 0xbe, 0xee, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+514D "免" */ + 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xfc, 0xcc, 0xc4, 0x0, 0x0, 0x0, 0x2d, + 0x20, 0x1, 0xd1, 0x0, 0x0, 0x2, 0xe5, 0x0, + 0xb, 0x70, 0x0, 0x0, 0x2e, 0xfd, 0xdd, 0xff, + 0xdd, 0xdf, 0x10, 0x3, 0xe0, 0x0, 0xb8, 0x0, + 0xe, 0x10, 0x0, 0xe0, 0x0, 0xd5, 0x0, 0xe, + 0x10, 0x0, 0xed, 0xdd, 0xfe, 0xdd, 0xdf, 0x10, + 0x0, 0x0, 0x6, 0xb3, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x43, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0xb9, 0x3, 0xc0, 0x0, 0x91, 0x0, 0x5e, 0x80, + 0x3, 0xc0, 0x0, 0xd0, 0x2e, 0xa3, 0x0, 0x0, + 0xdd, 0xdd, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5152 "兒" */ + 0x0, 0x0, 0x49, 0x20, 0x0, 0x0, 0x0, 0x0, + 0xac, 0x84, 0x5, 0xdd, 0xdc, 0x0, 0x0, 0xe1, + 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0xe1, 0x0, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0xed, 0xdd, 0x11, + 0xdd, 0xdd, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x0, + 0x1d, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x0, 0x1d, + 0x0, 0x0, 0xcd, 0xdf, 0xdd, 0xfd, 0xdb, 0x0, + 0x0, 0x0, 0x3c, 0x2, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x79, 0x2, 0xc0, 0x0, 0x0, 0x0, 0x1, + 0xe2, 0x2, 0xc0, 0x0, 0x82, 0x0, 0x3d, 0x60, + 0x2, 0xc0, 0x0, 0xb2, 0x3d, 0xb3, 0x0, 0x0, + 0xcb, 0xbb, 0xb0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+515A "党" */ + 0x0, 0x44, 0x0, 0xb3, 0x0, 0x45, 0x0, 0x0, + 0x2e, 0x10, 0xb3, 0x0, 0xd4, 0x0, 0x0, 0x8, + 0x40, 0xb3, 0x5, 0xb0, 0x0, 0xe, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xf0, 0xe, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0xe, 0xd, 0xdd, 0xdd, 0xdd, + 0xe0, 0xe0, 0x0, 0xd, 0x10, 0x0, 0x1, 0xe0, + 0x0, 0x0, 0xd, 0x10, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0xb, 0xdf, 0xde, 0xfd, 0xc0, 0x0, 0x0, + 0x0, 0x4b, 0x4, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0xc5, 0x4, 0xb0, 0x0, 0x42, 0x0, 0x4c, 0x90, + 0x4, 0xc0, 0x0, 0xa4, 0x1e, 0xb4, 0x0, 0x1, + 0xee, 0xee, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5165 "入" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xce, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x1, 0xf9, 0x80, + 0x0, 0x0, 0x0, 0x0, 0x6, 0xa1, 0xe1, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x40, 0x7a, 0x0, 0x0, + 0x0, 0x0, 0x6b, 0x0, 0xe, 0x30, 0x0, 0x0, + 0x3, 0xe2, 0x0, 0x6, 0xd0, 0x0, 0x0, 0x2e, + 0x50, 0x0, 0x0, 0xbb, 0x0, 0x5, 0xe7, 0x0, + 0x0, 0x0, 0x1c, 0xc1, 0x1c, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x93, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5167 "內" */ + 0x0, 0x1, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa8, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x30, + 0x0, 0x0, 0x2c, 0xcc, 0xce, 0xec, 0xcc, 0xcb, + 0x3b, 0x11, 0x19, 0xf4, 0x11, 0x2d, 0x3b, 0x0, + 0xc, 0x6a, 0x0, 0x1d, 0x3b, 0x0, 0x58, 0xd, + 0x10, 0x1d, 0x3b, 0x2, 0xe1, 0x6, 0xc0, 0x1d, + 0x3b, 0x5e, 0x40, 0x0, 0xad, 0x4d, 0x3b, 0x72, + 0x0, 0x0, 0x5, 0x4d, 0x3b, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x1d, + 0x3b, 0x0, 0x0, 0x0, 0x5e, 0xe8, + + /* U+5168 "全" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x89, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xcc, 0x60, 0x0, 0x0, 0x0, 0x0, 0x5b, + 0x0, 0xb7, 0x0, 0x0, 0x0, 0x8, 0xc0, 0x0, + 0xb, 0x90, 0x0, 0x3, 0xc8, 0x0, 0x0, 0x0, + 0x8e, 0x50, 0x4d, 0x6c, 0xcc, 0xcc, 0xcc, 0xc7, + 0xd5, 0x0, 0x1, 0x11, 0x88, 0x11, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0xaa, 0xdd, 0xaa, 0xa3, 0x0, 0x0, 0x3, + 0x33, 0x99, 0x33, 0x31, 0x0, 0x0, 0x0, 0x0, + 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77, + 0x0, 0x0, 0x0, 0xc, 0xdd, 0xdd, 0xee, 0xdd, + 0xdd, 0xd0, + + /* U+5169 "兩" */ + 0x2e, 0xee, 0xee, 0xff, 0xee, 0xee, 0xe1, 0x0, + 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x86, 0x0, 0x0, 0x0, 0x6, 0xed, 0xdd, + 0xee, 0xdd, 0xde, 0x50, 0x6, 0x70, 0x0, 0x85, + 0x0, 0x8, 0x50, 0x6, 0x73, 0x90, 0x85, 0x48, + 0x8, 0x50, 0x6, 0x70, 0xe1, 0x85, 0xe, 0x18, + 0x50, 0x6, 0x74, 0xc9, 0x85, 0x4c, 0x88, 0x50, + 0x6, 0x7a, 0x2d, 0x85, 0xa2, 0xc8, 0x50, 0x6, + 0x99, 0x8, 0xa7, 0x90, 0xaa, 0x50, 0x6, 0x70, + 0x0, 0x85, 0x0, 0x8, 0x50, 0x6, 0x70, 0x0, + 0x43, 0x5, 0xdd, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+516B "八" */ + 0x0, 0x0, 0x41, 0x0, 0x80, 0x0, 0x0, 0x0, + 0x0, 0xd2, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, + 0xf0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x1, 0xe0, + 0x0, 0x87, 0x0, 0x0, 0x0, 0x4, 0xb0, 0x0, + 0x5a, 0x0, 0x0, 0x0, 0x8, 0x70, 0x0, 0x1e, + 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0xb, 0x40, + 0x0, 0x0, 0x2e, 0x0, 0x0, 0x5, 0xb0, 0x0, + 0x0, 0x97, 0x0, 0x0, 0x0, 0xe2, 0x0, 0x2, + 0xe1, 0x0, 0x0, 0x0, 0x7b, 0x0, 0x1d, 0x40, + 0x0, 0x0, 0x0, 0xc, 0x80, 0x67, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xc3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+516C "公" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb5, 0x0, 0x6a, 0x0, 0x0, 0x0, 0x4, + 0xd0, 0x0, 0xd, 0x50, 0x0, 0x0, 0xc, 0x50, + 0x0, 0x3, 0xe1, 0x0, 0x0, 0x9b, 0x0, 0x10, + 0x0, 0x8c, 0x0, 0x8, 0xd0, 0x0, 0xd5, 0x0, + 0xb, 0xb0, 0x1b, 0x10, 0x6, 0xc0, 0x0, 0x0, + 0xa2, 0x0, 0x0, 0x1e, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x99, 0x0, 0x2c, 0x0, 0x0, 0x0, + 0x5, 0xc0, 0x0, 0x8, 0xa0, 0x0, 0x0, 0x2e, + 0x20, 0x1, 0x23, 0xe6, 0x0, 0x0, 0xef, 0xef, + 0xed, 0xcb, 0xae, 0x10, 0x0, 0x32, 0x10, 0x0, + 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+516D "六" */ + 0x0, 0x0, 0x1, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x0, 0x0, 0x0, 0x2f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x13, 0x0, + 0x0, 0x0, 0x1, 0xf2, 0x0, 0x2e, 0x20, 0x0, + 0x0, 0xa, 0x80, 0x0, 0x6, 0xc0, 0x0, 0x0, + 0x3e, 0x10, 0x0, 0x0, 0xb7, 0x0, 0x0, 0xd6, + 0x0, 0x0, 0x0, 0x2e, 0x20, 0xb, 0xa0, 0x0, + 0x0, 0x0, 0x7, 0xc0, 0x2c, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5171 "共" */ + 0x0, 0x0, 0xc2, 0x0, 0xb, 0x40, 0x0, 0x0, + 0x0, 0xc2, 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, + 0xc2, 0x0, 0xb, 0x40, 0x0, 0x7, 0xee, 0xfe, + 0xee, 0xef, 0xee, 0xe1, 0x0, 0x0, 0xc2, 0x0, + 0xb, 0x40, 0x0, 0x0, 0x0, 0xc2, 0x0, 0xb, + 0x40, 0x0, 0x0, 0x0, 0xc2, 0x0, 0xb, 0x40, + 0x0, 0x2, 0x22, 0xd4, 0x22, 0x2b, 0x62, 0x21, + 0x1b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb7, 0x0, + 0x0, 0x12, 0x0, 0x3, 0x0, 0x0, 0x0, 0x2, + 0xd5, 0x0, 0x2d, 0x80, 0x0, 0x0, 0x4d, 0x50, + 0x0, 0x0, 0xab, 0x10, 0x7, 0xd3, 0x0, 0x0, + 0x0, 0x8, 0xd0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x20, + + /* U+5176 "其" */ + 0x0, 0x9, 0x40, 0x0, 0x5, 0x90, 0x0, 0x0, + 0x9, 0x40, 0x0, 0x5, 0x90, 0x0, 0xb, 0xdf, + 0xed, 0xdd, 0xde, 0xfd, 0xc0, 0x0, 0x9, 0x40, + 0x0, 0x5, 0x90, 0x0, 0x0, 0x9, 0xdc, 0xcc, + 0xcd, 0x90, 0x0, 0x0, 0x9, 0x40, 0x0, 0x5, + 0x90, 0x0, 0x0, 0x9, 0x50, 0x0, 0x5, 0x90, + 0x0, 0x0, 0x9, 0xdc, 0xcc, 0xcd, 0x90, 0x0, + 0x0, 0x9, 0x40, 0x0, 0x5, 0x90, 0x0, 0x3d, + 0xdf, 0xed, 0xdd, 0xde, 0xfd, 0xd3, 0x0, 0x0, + 0x56, 0x0, 0x65, 0x0, 0x0, 0x1, 0x6d, 0x91, + 0x0, 0x28, 0xd8, 0x10, 0x1c, 0x71, 0x0, 0x0, + 0x0, 0x7, 0xb0, + + /* U+5177 "具" */ + 0x0, 0xd, 0xdc, 0xcc, 0xcc, 0xe6, 0x0, 0x0, + 0xd, 0x10, 0x0, 0x0, 0x86, 0x0, 0x0, 0xd, + 0xbb, 0xbb, 0xbb, 0xd6, 0x0, 0x0, 0xd, 0x10, + 0x0, 0x0, 0x86, 0x0, 0x0, 0xd, 0xbb, 0xbb, + 0xbb, 0xd6, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, + 0x86, 0x0, 0x0, 0xd, 0xbb, 0xbb, 0xbb, 0xd6, + 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x86, 0x0, + 0x1d, 0xdf, 0xdd, 0xdd, 0xdd, 0xee, 0xd6, 0x0, + 0x0, 0x94, 0x0, 0xb, 0x40, 0x0, 0x0, 0x6d, + 0x80, 0x0, 0x2, 0xbc, 0x30, 0xc, 0x92, 0x0, + 0x0, 0x0, 0x4, 0xd4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5185 "内" */ + 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x30, 0x0, 0x0, 0x11, 0x11, 0x1b, 0x51, + 0x11, 0x10, 0xcd, 0xcc, 0xcf, 0xdc, 0xcc, 0xf2, + 0xc1, 0x0, 0xc, 0x20, 0x0, 0xb2, 0xc1, 0x0, + 0xf, 0x10, 0x0, 0xb2, 0xc1, 0x0, 0x5c, 0xc1, + 0x0, 0xb2, 0xc1, 0x1, 0xd1, 0x4d, 0x10, 0xb2, + 0xc1, 0x2d, 0x50, 0x4, 0xd1, 0xb2, 0xc4, 0xe5, + 0x0, 0x0, 0x58, 0xb2, 0xc1, 0x0, 0x0, 0x0, + 0x0, 0xb2, 0xc1, 0x0, 0x0, 0x0, 0x0, 0xc2, + 0xc1, 0x0, 0x0, 0x1, 0xee, 0xc0, + + /* U+5186 "円" */ + 0xce, 0xee, 0xee, 0xee, 0xee, 0xed, 0xd1, 0x0, + 0xd, 0x10, 0x0, 0x1d, 0xd1, 0x0, 0xd, 0x10, + 0x0, 0x1d, 0xd1, 0x0, 0xd, 0x10, 0x0, 0x1d, + 0xd1, 0x0, 0xd, 0x10, 0x0, 0x1d, 0xdd, 0xdd, + 0xdf, 0xdd, 0xdd, 0xdd, 0xd2, 0x11, 0x11, 0x11, + 0x11, 0x2d, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x1d, + 0xd1, 0x0, 0x0, 0x0, 0x0, 0x1d, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0x1d, 0xd1, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0xd1, 0x0, 0x0, 0x0, 0x9e, 0xd8, + + /* U+518A "冊" */ + 0x0, 0xce, 0xef, 0xee, 0xff, 0xef, 0x60, 0x0, + 0xc1, 0xb, 0x10, 0xa3, 0x8, 0x60, 0x0, 0xc1, + 0xb, 0x10, 0xa3, 0x8, 0x60, 0x0, 0xc1, 0xb, + 0x10, 0xa3, 0x8, 0x60, 0x0, 0xc1, 0xb, 0x10, + 0xa3, 0x8, 0x60, 0x2e, 0xfe, 0xef, 0xee, 0xfe, + 0xef, 0xf9, 0x0, 0xc1, 0xb, 0x10, 0xa3, 0x8, + 0x60, 0x0, 0xc1, 0xb, 0x10, 0xa3, 0x8, 0x60, + 0x0, 0xc1, 0xb, 0x10, 0xa3, 0x8, 0x60, 0x0, + 0xc1, 0xb, 0x10, 0xa3, 0x8, 0x60, 0x0, 0xc1, + 0xb, 0x10, 0xa3, 0x8, 0x60, 0x0, 0xc1, 0xb, + 0x10, 0xa3, 0xcd, 0x30, + + /* U+518D "再" */ + 0x9, 0xdd, 0xdd, 0xef, 0xdd, 0xdd, 0xd2, 0x0, + 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x6c, + 0xcc, 0xde, 0xcc, 0xcb, 0x0, 0x0, 0x87, 0x11, + 0x6a, 0x11, 0x1e, 0x0, 0x0, 0x86, 0x0, 0x4a, + 0x0, 0xe, 0x0, 0x0, 0x8e, 0xdd, 0xef, 0xdd, + 0xdf, 0x0, 0x0, 0x86, 0x0, 0x4a, 0x0, 0xe, + 0x0, 0x0, 0x86, 0x0, 0x4a, 0x0, 0xe, 0x0, + 0x2d, 0xfe, 0xdd, 0xdd, 0xdd, 0xdf, 0xd9, 0x0, + 0x86, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x86, + 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x86, 0x0, + 0x0, 0x3e, 0xea, 0x0, + + /* U+5199 "写" */ + 0xde, 0xdd, 0xdd, 0xdd, 0xdd, 0xee, 0xd0, 0xa, + 0x10, 0x0, 0x0, 0x1e, 0x90, 0xe, 0x0, 0x0, + 0x0, 0x9, 0x0, 0x3f, 0xdd, 0xdd, 0xdd, 0x20, + 0x0, 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa6, + 0x22, 0x22, 0x22, 0x10, 0x0, 0x9b, 0xbb, 0xbb, + 0xbd, 0x70, 0x0, 0x0, 0x0, 0x0, 0x9, 0x50, + 0x9d, 0xdd, 0xdd, 0xdd, 0x3b, 0x30, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3c, 0x0, 0x0, 0x0, 0x4, 0xdd, 0xe4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+519B "军" */ + 0xed, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xe, 0x0, + 0x7, 0x10, 0x0, 0x0, 0xe0, 0xc0, 0x2, 0xd0, + 0x0, 0x0, 0xd, 0x0, 0x6d, 0xfd, 0xdd, 0xdd, + 0xd6, 0x0, 0x0, 0x1c, 0x0, 0x90, 0x0, 0x0, + 0x0, 0xa, 0x40, 0xe, 0x0, 0x0, 0x0, 0x3, + 0xfd, 0xdd, 0xfd, 0xdd, 0xb0, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, + 0x0, 0x0, 0xc, 0xdd, 0xdd, 0xdf, 0xdd, 0xdd, + 0xd0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, + + /* U+51AC "冬" */ + 0x0, 0x0, 0x5, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3e, 0x11, 0x11, 0x10, 0x0, 0x0, 0x1, + 0xdb, 0xbb, 0xbd, 0xd0, 0x0, 0x0, 0x2d, 0xd1, + 0x0, 0x1d, 0x30, 0x0, 0x4, 0xe5, 0x3c, 0x22, + 0xd5, 0x0, 0x0, 0x6, 0x30, 0x3, 0xee, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x7d, 0x99, 0xd6, 0x0, + 0x0, 0x16, 0xbe, 0x91, 0x0, 0x29, 0xec, 0x81, + 0x8, 0x40, 0xb, 0x94, 0x0, 0x3, 0x70, 0x0, + 0x0, 0x0, 0x4a, 0xe8, 0x0, 0x0, 0x0, 0x4, + 0x40, 0x0, 0x3, 0x0, 0x0, 0x0, 0x4, 0x9d, + 0xb7, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, + 0xdc, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0x0, 0x0, + + /* U+51B7 "冷" */ + 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x1b, + 0x0, 0x0, 0x5, 0xf3, 0x0, 0x0, 0x8, 0x80, + 0x0, 0x2d, 0x5d, 0x10, 0x0, 0x0, 0xe2, 0x2, + 0xd4, 0x4, 0xc0, 0x0, 0x0, 0x31, 0x4e, 0x63, + 0x30, 0x6d, 0x20, 0x0, 0x3, 0xe3, 0x1, 0xd3, + 0x4, 0xe1, 0x0, 0x0, 0x10, 0x0, 0x22, 0x0, + 0x0, 0x0, 0x42, 0xe, 0xee, 0xee, 0xee, 0x0, + 0x0, 0xc3, 0x0, 0x0, 0x0, 0xb5, 0x0, 0x3, + 0xd0, 0x0, 0x0, 0x8, 0xa0, 0x0, 0xa, 0x60, + 0x0, 0xa9, 0x7b, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x7, 0xf3, 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, + 0x3d, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+51CD "凍" */ + 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x17, + 0x0, 0x11, 0x11, 0xd2, 0x11, 0x10, 0xa, 0xa0, + 0xbb, 0xbb, 0xfc, 0xbb, 0xb2, 0x0, 0xb5, 0x0, + 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0xbb, + 0xfb, 0xbd, 0x80, 0x0, 0x0, 0x49, 0x0, 0xd0, + 0x4, 0x80, 0x0, 0x1, 0x4d, 0xaa, 0xfb, 0xac, + 0x80, 0x0, 0x68, 0x49, 0x0, 0xd0, 0x4, 0x80, + 0x0, 0xe1, 0x3c, 0xcf, 0xff, 0xcc, 0x60, 0x8, + 0x80, 0x0, 0x6b, 0xea, 0x60, 0x0, 0x3e, 0x0, + 0x7, 0xb0, 0xd1, 0xb6, 0x0, 0x3, 0x4, 0xd9, + 0x0, 0xd0, 0xa, 0xb2, 0x0, 0x5, 0x30, 0x0, + 0xd0, 0x0, 0x51, + + /* U+51DD "凝" */ + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x0, 0xc1, 0x76, 0x9c, 0xcd, 0xd0, 0xb, 0x80, + 0xe9, 0x40, 0x4, 0x1c, 0x20, 0x0, 0xa4, 0xc0, + 0xa, 0x2a, 0xe5, 0x0, 0x0, 0x0, 0xac, 0xc9, + 0x0, 0x4b, 0x0, 0x0, 0x0, 0xb2, 0x0, 0xbc, + 0xcc, 0xc2, 0x0, 0x2, 0xee, 0xda, 0x0, 0xc0, + 0xb0, 0x0, 0x87, 0x38, 0x40, 0x73, 0xc0, 0x30, + 0x1, 0xd6, 0xce, 0xdc, 0xa2, 0xcc, 0xc1, 0x8, + 0x60, 0xc, 0x40, 0xb2, 0xc0, 0x0, 0xe, 0x0, + 0x1d, 0xd2, 0xc8, 0xc0, 0x0, 0x48, 0x0, 0xb5, + 0x3a, 0x99, 0xe0, 0x0, 0x0, 0x9, 0x70, 0x9, + 0x20, 0xad, 0xd3, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+51E6 "処" */ + 0x0, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa4, 0x0, 0x6, 0x88, 0x80, 0x0, 0x0, 0xd3, + 0x11, 0xc, 0x64, 0xe0, 0x0, 0x1, 0xfb, 0xbe, + 0xc, 0x10, 0xd0, 0x0, 0x4, 0xa0, 0x1b, 0xc, + 0x10, 0xd0, 0x0, 0xa, 0xb0, 0x49, 0xd, 0x0, + 0xd0, 0x0, 0x1e, 0xc0, 0x86, 0xd, 0x0, 0xd0, + 0x0, 0x96, 0x84, 0xd1, 0x1c, 0x0, 0xd0, 0x0, + 0x20, 0x2d, 0xb0, 0x58, 0x0, 0xd0, 0x10, 0x0, + 0xc, 0x80, 0xc3, 0x0, 0xd1, 0xb0, 0x0, 0x6c, + 0xd6, 0x70, 0x0, 0x59, 0x40, 0x4, 0xd1, 0x1c, + 0xb5, 0x10, 0x0, 0x0, 0x4d, 0x20, 0x0, 0x4a, + 0xde, 0xee, 0xe1, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+51FA "出" */ + 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x6, 0x30, + 0x1, 0xe0, 0x0, 0x90, 0xa, 0x50, 0x1, 0xe0, + 0x0, 0xe1, 0xa, 0x50, 0x1, 0xe0, 0x0, 0xe1, + 0xa, 0x50, 0x1, 0xe0, 0x0, 0xe1, 0xa, 0xdc, + 0xcd, 0xfc, 0xcc, 0xf1, 0x1, 0x11, 0x13, 0xe1, + 0x11, 0x10, 0x39, 0x0, 0x1, 0xe0, 0x0, 0x48, + 0x4b, 0x0, 0x1, 0xe0, 0x0, 0x5a, 0x4b, 0x0, + 0x1, 0xe0, 0x0, 0x5a, 0x4b, 0x0, 0x1, 0xe0, + 0x0, 0x5a, 0x4f, 0xee, 0xee, 0xfe, 0xee, 0xea, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6a, + + /* U+5206 "分" */ + 0x0, 0x0, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0xc5, 0x0, 0x3d, 0x0, 0x0, 0x0, 0x5, + 0xc0, 0x0, 0x9, 0x70, 0x0, 0x0, 0xe, 0x30, + 0x0, 0x1, 0xe2, 0x0, 0x0, 0xb9, 0x0, 0x0, + 0x0, 0x5d, 0x10, 0xb, 0xb3, 0x22, 0x22, 0x22, + 0x29, 0xd1, 0x18, 0x4b, 0xbe, 0xdb, 0xbb, 0xe5, + 0x60, 0x0, 0x0, 0xc, 0x30, 0x0, 0xb4, 0x0, + 0x0, 0x0, 0xe, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0x0, 0x79, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x3, + 0xe2, 0x0, 0x0, 0xf0, 0x0, 0x0, 0x5e, 0x30, + 0x0, 0x3, 0xd0, 0x0, 0xc, 0xa2, 0x0, 0xe, + 0xee, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5207 "切" */ + 0x0, 0xe0, 0x3, 0xaa, 0xaa, 0xaa, 0xa0, 0xe, + 0x0, 0x3, 0x3f, 0x33, 0x3e, 0x0, 0xe2, 0x67, + 0x0, 0xe0, 0x0, 0xe6, 0xbf, 0xb8, 0x40, 0xd, + 0x0, 0x1d, 0x32, 0xe0, 0x0, 0x2, 0xc0, 0x1, + 0xd0, 0xe, 0x0, 0x0, 0x4a, 0x0, 0x2c, 0x0, + 0xe0, 0x0, 0x7, 0x70, 0x3, 0xb0, 0xe, 0x4, + 0xa0, 0xc3, 0x0, 0x4b, 0x0, 0xfd, 0xa3, 0x3d, + 0x0, 0x5, 0x90, 0x4a, 0x20, 0xb, 0x50, 0x0, + 0x78, 0x0, 0x0, 0x9, 0xb0, 0x0, 0xb, 0x50, + 0x0, 0x8, 0xa0, 0x2, 0xee, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+520A "刊" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0xbe, + 0xef, 0xee, 0x70, 0x0, 0xe, 0x0, 0x2, 0xd0, + 0x0, 0x1d, 0x0, 0xe0, 0x0, 0x2d, 0x0, 0x1, + 0xd0, 0xe, 0x0, 0x2, 0xd0, 0x0, 0x1d, 0x0, + 0xe0, 0x44, 0x5d, 0x44, 0x31, 0xd0, 0xe, 0x2a, + 0xab, 0xfa, 0xaa, 0x1d, 0x0, 0xe0, 0x0, 0x2d, + 0x0, 0x1, 0xd0, 0xe, 0x0, 0x2, 0xd0, 0x0, + 0x1d, 0x0, 0xe0, 0x0, 0x2d, 0x0, 0x1, 0x90, + 0xe, 0x0, 0x2, 0xd0, 0x0, 0x0, 0x0, 0xe0, + 0x0, 0x2d, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x2, + 0xc0, 0x0, 0x6, 0xfe, 0x90, + + /* U+5217 "列" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xd1, 0xee, + 0xfe, 0xee, 0xe0, 0x0, 0x1d, 0x0, 0xe, 0x0, + 0x0, 0xe, 0x1, 0xd0, 0x4, 0xb0, 0x0, 0x0, + 0xe0, 0x1d, 0x0, 0x9e, 0xdd, 0xd6, 0xe, 0x1, + 0xd0, 0x1e, 0x10, 0x9, 0x40, 0xe0, 0x1d, 0x9, + 0x80, 0x0, 0xd0, 0xe, 0x1, 0xd0, 0xc3, 0xa0, + 0x3b, 0x0, 0xe0, 0x1d, 0x0, 0x7, 0xdc, 0x40, + 0xe, 0x1, 0xd0, 0x0, 0x7, 0xb0, 0x0, 0xa0, + 0x1d, 0x0, 0x3, 0xd2, 0x0, 0x0, 0x1, 0xd0, + 0x6, 0xe2, 0x0, 0x0, 0x0, 0x1d, 0x9, 0xa1, + 0x0, 0x0, 0x0, 0xde, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+521D "初" */ + 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xc0, 0x4, 0x44, 0x44, 0x44, 0x0, 0x8, 0x21, + 0x99, 0xea, 0x99, 0xf2, 0xdd, 0xdf, 0x60, 0xd, + 0x20, 0xe, 0x0, 0x1, 0xd0, 0x0, 0xe0, 0x0, + 0xe0, 0x0, 0xa6, 0x20, 0xe, 0x0, 0x1d, 0x0, + 0x5f, 0x5b, 0x2, 0xd0, 0x1, 0xd0, 0x5e, 0xfe, + 0x10, 0x59, 0x0, 0x2c, 0x3e, 0x3e, 0x4b, 0x8, + 0x60, 0x3, 0xb0, 0x11, 0xe0, 0x20, 0xe1, 0x0, + 0x4a, 0x0, 0x1e, 0x0, 0x79, 0x0, 0x6, 0x80, + 0x1, 0xe0, 0x4e, 0x20, 0x0, 0xa5, 0x0, 0x1e, + 0xc, 0x30, 0x3e, 0xec, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x0, + + /* U+5224 "判" */ + 0x1, 0x0, 0xe0, 0x1, 0x0, 0x0, 0xe0, 0xb3, + 0xe, 0x4, 0xb0, 0x0, 0xe, 0x3, 0xb0, 0xe0, + 0xc4, 0xe, 0x0, 0xe0, 0xc, 0x2e, 0x3c, 0x0, + 0xe0, 0xe, 0x6, 0x88, 0xf8, 0x95, 0xe, 0x0, + 0xe0, 0x45, 0x6f, 0x55, 0x30, 0xe0, 0xe, 0x0, + 0x0, 0xe0, 0x0, 0xe, 0x0, 0xe0, 0x11, 0x3e, + 0x11, 0x10, 0xe0, 0xe, 0x4b, 0xbd, 0xeb, 0xbb, + 0xe, 0x0, 0xe0, 0x0, 0x96, 0x0, 0x0, 0x90, + 0xe, 0x0, 0x1e, 0x10, 0x0, 0x0, 0x0, 0xe0, + 0x1c, 0x70, 0x0, 0x0, 0x0, 0xe, 0xa, 0x80, + 0x0, 0x0, 0x6, 0xee, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5225 "別" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xb0, 0xdd, + 0xdd, 0xea, 0x0, 0x0, 0x2b, 0xd, 0x0, 0x3, + 0xa0, 0xe0, 0x2, 0xb0, 0xd0, 0x0, 0x3a, 0xe, + 0x0, 0x2b, 0xd, 0x66, 0x68, 0xa0, 0xe0, 0x2, + 0xb0, 0x6a, 0xc7, 0x74, 0xe, 0x0, 0x2b, 0x0, + 0x68, 0x0, 0x0, 0xe0, 0x2, 0xb0, 0x8, 0xed, + 0xdb, 0xe, 0x0, 0x2b, 0x0, 0xb3, 0x3, 0xa0, + 0xe0, 0x2, 0xb0, 0xd, 0x0, 0x49, 0x9, 0x0, + 0x2b, 0x5, 0xa0, 0x5, 0x80, 0x0, 0x2, 0xb1, + 0xd3, 0x0, 0x86, 0x0, 0x0, 0x3b, 0x76, 0x9, + 0xcc, 0x10, 0xb, 0xee, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5229 "利" */ + 0x0, 0x0, 0x38, 0xc1, 0x0, 0x0, 0xe0, 0x8b, + 0xff, 0x82, 0x0, 0x0, 0xe, 0x6, 0x32, 0xd0, + 0x0, 0x67, 0x0, 0xe0, 0x0, 0x1d, 0x0, 0x6, + 0x70, 0xe, 0x7, 0x78, 0xe7, 0x74, 0x67, 0x0, + 0xe0, 0x66, 0xae, 0x66, 0x36, 0x70, 0xe, 0x0, + 0xd, 0xe1, 0x0, 0x67, 0x0, 0xe0, 0x6, 0xae, + 0xc2, 0x6, 0x70, 0xe, 0x1, 0xd2, 0xd2, 0xd3, + 0x67, 0x0, 0xe0, 0xb5, 0x1d, 0x2, 0x14, 0x50, + 0xe, 0x39, 0x1, 0xd0, 0x0, 0x0, 0x0, 0xe0, + 0x0, 0x1d, 0x0, 0x0, 0x0, 0xe, 0x0, 0x1, + 0xc0, 0x0, 0x4, 0xee, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5230 "到" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0xee, + 0xee, 0xee, 0xe2, 0x70, 0xe, 0x0, 0x1d, 0x22, + 0x20, 0xe, 0x0, 0xe0, 0x7, 0x70, 0x4b, 0x0, + 0xe0, 0xe, 0x3, 0xe4, 0x57, 0xd7, 0xe, 0x0, + 0xe0, 0x6a, 0x86, 0x53, 0xc0, 0xe0, 0xe, 0x0, + 0x0, 0xc1, 0x0, 0xe, 0x0, 0xe0, 0x36, 0x6e, + 0x76, 0x50, 0xe0, 0xe, 0x4, 0x66, 0xe7, 0x66, + 0xe, 0x0, 0xe0, 0x0, 0xd, 0x10, 0x0, 0xd0, + 0xe, 0x0, 0x0, 0xd5, 0x7a, 0x0, 0x0, 0xe0, + 0x7a, 0xde, 0xa7, 0x40, 0x0, 0xe, 0x7, 0x41, + 0x0, 0x0, 0x1, 0xee, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5236 "制" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xa, 0x30, 0x0, 0x0, 0xe, 0x1, 0xd0, 0xa3, + 0x0, 0x2, 0x50, 0xe0, 0x6f, 0xdf, 0xed, 0xd1, + 0x48, 0xe, 0xd, 0x20, 0xa3, 0x0, 0x4, 0x80, + 0xe1, 0xb7, 0x7d, 0x97, 0x75, 0x48, 0xe, 0x5, + 0x55, 0xc8, 0x55, 0x34, 0x80, 0xe0, 0x12, 0x2b, + 0x52, 0x20, 0x48, 0xe, 0x7, 0xdb, 0xec, 0xbe, + 0x24, 0x80, 0xe0, 0x76, 0xa, 0x30, 0xb2, 0x48, + 0xe, 0x7, 0x60, 0xa3, 0xb, 0x20, 0x0, 0xe0, + 0x76, 0xa, 0x30, 0xb2, 0x0, 0xe, 0x7, 0x50, + 0xa4, 0xcd, 0x10, 0x0, 0xe0, 0x0, 0xa, 0x30, + 0x0, 0xd, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5238 "券" */ + 0x0, 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x40, 0x78, 0x2, 0xc0, 0x0, 0x0, 0x2, + 0xa0, 0xc3, 0xc, 0x30, 0x0, 0x3, 0xdd, 0xde, + 0xfd, 0xdd, 0xdd, 0x20, 0x0, 0x0, 0xc, 0x40, + 0x0, 0x0, 0x0, 0x1d, 0xdd, 0xef, 0xdd, 0xdd, + 0xdd, 0xd2, 0x0, 0x8, 0xc0, 0x0, 0x2d, 0x30, + 0x0, 0x0, 0x9d, 0x10, 0x0, 0x3, 0xe5, 0x0, + 0x3e, 0x9d, 0xdf, 0xdd, 0xde, 0xcb, 0xd3, 0x2, + 0x0, 0xe, 0x0, 0x5, 0x90, 0x31, 0x0, 0x0, + 0x79, 0x0, 0x7, 0x70, 0x0, 0x0, 0x19, 0xc1, + 0x0, 0xa, 0x50, 0x0, 0x5, 0xd7, 0x0, 0xd, + 0xdc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+523B "刻" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x10, 0x0, 0x0, 0xe, 0x0, 0x0, 0x96, + 0x0, 0x0, 0x0, 0xe1, 0xdd, 0xef, 0xed, 0xd7, + 0x67, 0xe, 0x0, 0xa, 0x60, 0x0, 0x6, 0x70, + 0xe0, 0x6, 0x90, 0xa, 0x30, 0x67, 0xe, 0x5, + 0xf8, 0x8a, 0xb0, 0x6, 0x70, 0xe0, 0x35, 0x47, + 0xd1, 0x20, 0x67, 0xe, 0x0, 0x5, 0xd2, 0x1d, + 0x16, 0x70, 0xe0, 0x1a, 0xc1, 0xc, 0x40, 0x67, + 0xe, 0x9, 0x70, 0xb, 0x90, 0x4, 0x50, 0xe0, + 0x0, 0x2d, 0x8d, 0x50, 0x0, 0xe, 0x1, 0x8e, + 0x40, 0x1c, 0x50, 0x0, 0xe0, 0xa8, 0x0, 0x0, + 0x11, 0xd, 0xda, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5247 "則" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xc0, 0xdd, + 0xdd, 0xec, 0x0, 0x0, 0x2c, 0xd, 0x0, 0x2, + 0xc0, 0xe0, 0x2, 0xc0, 0xd8, 0x88, 0x9c, 0xe, + 0x0, 0x2c, 0xd, 0x44, 0x46, 0xc0, 0xe0, 0x2, + 0xc0, 0xd0, 0x0, 0x2c, 0xe, 0x0, 0x2c, 0xd, + 0xcc, 0xcd, 0xc0, 0xe0, 0x2, 0xc0, 0xd0, 0x0, + 0x2c, 0xe, 0x0, 0x2c, 0xd, 0x43, 0x35, 0xc0, + 0xe0, 0x2, 0xc0, 0x89, 0x99, 0x97, 0x9, 0x0, + 0x2c, 0x2, 0xc0, 0xb, 0x10, 0x0, 0x2, 0xc0, + 0xc6, 0x0, 0x5a, 0x0, 0x0, 0x3c, 0x68, 0x0, + 0x0, 0x80, 0xb, 0xee, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+524A "削" */ + 0x15, 0xb, 0x30, 0x63, 0x0, 0x1, 0xd0, 0xd0, + 0xb3, 0xe, 0x14, 0x10, 0x1d, 0x9, 0x4b, 0x34, + 0xb0, 0xa3, 0x1, 0xd0, 0x33, 0xb3, 0x53, 0xa, + 0x30, 0x1d, 0xc, 0xef, 0xee, 0xd0, 0xa3, 0x1, + 0xd0, 0xe0, 0x0, 0xe, 0xa, 0x30, 0x1d, 0xe, + 0xaa, 0xaa, 0xe0, 0xa3, 0x1, 0xd0, 0xe1, 0x11, + 0x1e, 0xa, 0x30, 0x1d, 0xe, 0x0, 0x0, 0xe0, + 0xa3, 0x1, 0xd0, 0xed, 0xdd, 0xde, 0x8, 0x20, + 0x1d, 0xe, 0x0, 0x0, 0xe0, 0x0, 0x1, 0xd0, + 0xe0, 0x0, 0xe, 0x0, 0x0, 0x1d, 0xd, 0x0, + 0xcd, 0x80, 0xc, 0xee, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+524D "前" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x30, 0x0, 0x2, 0xd0, 0x0, 0x0, 0x3, + 0xd0, 0x0, 0xb, 0x60, 0x0, 0x2b, 0xbb, 0xeb, + 0xbb, 0xbf, 0xbb, 0xb2, 0x2, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x20, 0x1, 0x33, 0x33, 0x20, 0x0, + 0x6, 0x20, 0x5, 0xda, 0xab, 0xb0, 0x76, 0xa, + 0x40, 0x5, 0x80, 0x3, 0xb0, 0x76, 0xa, 0x40, + 0x5, 0xec, 0xcd, 0xb0, 0x76, 0xa, 0x40, 0x5, + 0x80, 0x3, 0xb0, 0x76, 0xa, 0x40, 0x5, 0xd9, + 0x9b, 0xb0, 0x76, 0xa, 0x40, 0x5, 0x91, 0x14, + 0xb0, 0x54, 0xa, 0x40, 0x5, 0x80, 0x3, 0xb0, + 0x0, 0xa, 0x40, 0x5, 0x80, 0xbd, 0x70, 0x9, + 0xdd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+525B "剛" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xdd, 0xdd, + 0xdd, 0xe6, 0x1, 0xd, 0xd0, 0x70, 0x27, 0x76, + 0xd, 0xd, 0xd0, 0x90, 0x65, 0x76, 0xd, 0xd, + 0xd0, 0x53, 0xb1, 0x86, 0xd, 0xd, 0xd4, 0xad, + 0xba, 0x86, 0xd, 0xd, 0xd0, 0x37, 0x23, 0x76, + 0xd, 0xd, 0xd0, 0x97, 0x29, 0x76, 0xd, 0xd, + 0xd0, 0x97, 0x29, 0x76, 0xd, 0xd, 0xd0, 0x97, + 0x29, 0x76, 0xa, 0xd, 0xd0, 0xaa, 0xa6, 0x76, + 0x0, 0xd, 0xd0, 0x0, 0x0, 0x86, 0x0, 0xd, + 0xd0, 0x0, 0x6d, 0xd2, 0xc, 0xd9, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+5272 "割" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, + 0x0, 0x0, 0x0, 0xe, 0x99, 0x9f, 0xa9, 0x95, + 0x0, 0xe, 0xd1, 0x13, 0x21, 0x48, 0xa2, 0xe, + 0x89, 0x9e, 0x99, 0x93, 0xa2, 0xe, 0x3, 0x3d, + 0x33, 0x20, 0xa2, 0xe, 0xa, 0xbf, 0xbb, 0x50, + 0xa2, 0xe, 0x0, 0xc, 0x0, 0x0, 0xa2, 0xe, + 0xab, 0xbf, 0xbb, 0xb4, 0xa2, 0xe, 0x0, 0xc, + 0x0, 0x0, 0xa2, 0xe, 0x2e, 0xdd, 0xdd, 0xd0, + 0x82, 0xe, 0x29, 0x0, 0x0, 0xd0, 0x0, 0xe, + 0x2d, 0xaa, 0xaa, 0xd0, 0x0, 0xe, 0x2a, 0x11, + 0x11, 0xc0, 0x2d, 0xda, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5275 "創" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x30, 0x0, 0x0, 0xe, 0x0, 0xa, 0xac, + 0x40, 0x5, 0x0, 0xe0, 0xa, 0xa8, 0x1b, 0x80, + 0xd0, 0xe, 0x2e, 0x80, 0x86, 0x7, 0x1d, 0x0, + 0xe0, 0x49, 0x99, 0x99, 0x60, 0xd0, 0xe, 0x0, + 0xd2, 0x22, 0x4a, 0xd, 0x0, 0xe0, 0xe, 0xaa, + 0xab, 0xa0, 0xd0, 0xe, 0x2, 0xc3, 0x33, 0x5a, + 0xd, 0x0, 0xe0, 0x3c, 0x77, 0x77, 0x50, 0xd0, + 0xe, 0x7, 0x8b, 0xbb, 0xb8, 0x6, 0x0, 0xe0, + 0xc5, 0x90, 0x1, 0xb0, 0x0, 0xe, 0x59, 0x3e, + 0xaa, 0xbb, 0x0, 0x0, 0xe0, 0x13, 0xa1, 0x12, + 0xa0, 0x3e, 0xe9, + + /* U+5283 "劃" */ + 0x0, 0x0, 0x93, 0x0, 0x0, 0x0, 0xe0, 0x2a, + 0xad, 0xba, 0xe0, 0x11, 0xe, 0x19, 0x99, 0xda, + 0x9e, 0x88, 0x50, 0xe0, 0x22, 0x2a, 0x52, 0xd2, + 0x85, 0xe, 0x2, 0x99, 0xdb, 0x9a, 0x8, 0x50, + 0xe0, 0x38, 0x8d, 0xa8, 0x82, 0x85, 0xe, 0x9, + 0x99, 0xdb, 0x99, 0x88, 0x50, 0xe0, 0x14, 0x44, + 0x44, 0x41, 0x85, 0xe, 0x3, 0xb6, 0xb9, 0x6e, + 0x8, 0x50, 0xe0, 0x3c, 0x8c, 0xa8, 0xe0, 0x53, + 0xe, 0x3, 0xc7, 0xb9, 0x7e, 0x0, 0x0, 0xe0, + 0x2, 0x22, 0x34, 0x42, 0x0, 0xe, 0x1c, 0xcc, + 0xcb, 0xa9, 0x80, 0xbe, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+529B "力" */ + 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, + 0x0, 0x0, 0x8d, 0xdd, 0xdf, 0xdd, 0xdd, 0xdc, + 0x1, 0x11, 0x2e, 0x11, 0x11, 0x3d, 0x0, 0x0, + 0x4b, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x78, 0x0, + 0x0, 0x3b, 0x0, 0x0, 0xd3, 0x0, 0x0, 0x5a, + 0x0, 0x4, 0xd0, 0x0, 0x0, 0x68, 0x0, 0xe, + 0x40, 0x0, 0x0, 0x87, 0x0, 0xa9, 0x0, 0x0, + 0x0, 0xb4, 0xb, 0xb0, 0x0, 0x0, 0x1, 0xe1, + 0xb9, 0x0, 0x0, 0xd, 0xef, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+529F "功" */ + 0x0, 0x0, 0x0, 0x0, 0xc3, 0x0, 0x0, 0x16, + 0x66, 0x65, 0x0, 0xc2, 0x0, 0x0, 0x18, 0x9e, + 0x88, 0x0, 0xc2, 0x0, 0x0, 0x0, 0x1d, 0x0, + 0xbb, 0xfc, 0xbb, 0xb2, 0x0, 0x1d, 0x0, 0x22, + 0xe3, 0x22, 0xc2, 0x0, 0x1d, 0x0, 0x0, 0xe0, + 0x0, 0xc2, 0x0, 0x1d, 0x0, 0x1, 0xd0, 0x0, + 0xd1, 0x0, 0x1d, 0x0, 0x5, 0xa0, 0x0, 0xe0, + 0x0, 0x2e, 0x9d, 0x29, 0x60, 0x0, 0xe0, 0x2c, + 0xea, 0x61, 0x1e, 0x10, 0x0, 0xe0, 0x14, 0x0, + 0x0, 0x98, 0x0, 0x3, 0xc0, 0x0, 0x0, 0x8, + 0xd0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x6b, 0x0, + 0x3e, 0xee, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+52A0 "加" */ + 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xb0, 0x0, 0x1, 0x11, 0x11, 0x0, 0x3b, 0x0, + 0x0, 0xff, 0xff, 0xd3, 0xef, 0xfe, 0xed, 0xe, + 0x0, 0x1d, 0x0, 0x4a, 0x1, 0xc0, 0xe0, 0x1, + 0xd0, 0x5, 0x90, 0x2c, 0xe, 0x0, 0x1d, 0x0, + 0x67, 0x2, 0xc0, 0xe0, 0x1, 0xd0, 0x8, 0x50, + 0x2b, 0xe, 0x0, 0x1d, 0x0, 0xb3, 0x3, 0xb0, + 0xe0, 0x1, 0xd0, 0xe, 0x0, 0x4a, 0xe, 0x0, + 0x1d, 0x5, 0xa0, 0x5, 0x90, 0xe0, 0x1, 0xd0, + 0xd4, 0x0, 0x87, 0xf, 0xee, 0xed, 0x59, 0x7, + 0xed, 0x20, 0xe0, 0x1, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+52A8 "动" */ + 0x0, 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x9, + 0xcc, 0xcc, 0x80, 0xc, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x6, 0x7e, 0x87, 0x71, 0x0, 0x0, 0x0, 0x8, + 0x9f, 0x99, 0xe2, 0x3d, 0xef, 0xdd, 0xc0, 0xe, + 0x0, 0xc2, 0x0, 0x78, 0x0, 0x0, 0xe, 0x0, + 0xc1, 0x0, 0xb3, 0xa, 0x0, 0x3b, 0x0, 0xd1, + 0x0, 0xd0, 0x9, 0x40, 0x68, 0x0, 0xe0, 0x6, + 0x80, 0x39, 0xa0, 0xb4, 0x0, 0xe0, 0xe, 0xec, + 0x96, 0xd2, 0xe0, 0x1, 0xd0, 0x4, 0x0, 0x0, + 0x1b, 0x70, 0x5, 0xa0, 0x0, 0x0, 0x0, 0x4b, + 0xa, 0xee, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+52A9 "助" */ + 0x0, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0xbe, + 0xdd, 0xd0, 0x1, 0xd0, 0x0, 0xb, 0x20, 0xd, + 0x0, 0x1c, 0x0, 0x0, 0xb2, 0x0, 0xd5, 0x89, + 0xe8, 0x86, 0xb, 0xed, 0xdd, 0x35, 0x7d, 0x57, + 0xb0, 0xb2, 0x0, 0xd0, 0x4, 0xa0, 0x2b, 0xb, + 0x20, 0xd, 0x0, 0x68, 0x3, 0xb0, 0xbd, 0xdd, + 0xd0, 0x9, 0x50, 0x3a, 0xb, 0x20, 0xd, 0x0, + 0xe1, 0x4, 0x90, 0xb2, 0x1, 0xe5, 0x5b, 0x0, + 0x58, 0x3d, 0xbe, 0xc9, 0x4d, 0x20, 0x7, 0x76, + 0x74, 0x0, 0x1c, 0x80, 0x0, 0xa5, 0x0, 0x0, + 0xa, 0x70, 0xb, 0xed, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+52AA "努" */ + 0x0, 0x4, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x50, 0x5, 0xed, 0xdd, 0xf1, 0xd, 0xef, + 0xdd, 0xe0, 0xd1, 0x3, 0xb0, 0x0, 0xa5, 0x5, + 0x90, 0x68, 0xb, 0x40, 0x0, 0xba, 0x4d, 0x10, + 0xc, 0xb8, 0x0, 0x0, 0x6, 0xfd, 0x30, 0x4c, + 0xd9, 0x20, 0x8, 0xc9, 0x13, 0x78, 0x92, 0x5, + 0xd5, 0x4, 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, + 0x1, 0xcc, 0xcc, 0xee, 0xcc, 0xcc, 0x70, 0x0, + 0x0, 0x1, 0xe0, 0x0, 0x8, 0x70, 0x0, 0x0, + 0xb, 0x70, 0x0, 0xa, 0x40, 0x0, 0x5, 0xd8, + 0x0, 0x0, 0xe, 0x10, 0x8, 0xe9, 0x20, 0x0, + 0x6d, 0xd9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+52B3 "劳" */ + 0x0, 0x0, 0xf0, 0x0, 0xe, 0x0, 0x0, 0x2, + 0x22, 0xf2, 0x22, 0x3e, 0x22, 0x20, 0x1b, 0xbb, + 0xfb, 0xbb, 0xbf, 0xbb, 0xb2, 0x0, 0x0, 0xe0, + 0x0, 0xe, 0x0, 0x0, 0xb, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xa0, 0xd, 0x10, 0x0, 0x70, 0x0, + 0x2, 0xc0, 0x8, 0x0, 0x1, 0xd0, 0x0, 0x1, + 0x60, 0x1, 0xcc, 0xcc, 0xfc, 0xcc, 0xca, 0x0, + 0x0, 0x11, 0x19, 0x81, 0x11, 0x3c, 0x0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x3b, 0x0, 0x0, 0x0, + 0xa9, 0x0, 0x0, 0x59, 0x0, 0x0, 0x4d, 0xa0, + 0x0, 0x0, 0x87, 0x0, 0x1e, 0xa4, 0x0, 0x6, + 0xee, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+52C9 "勉" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xae, + 0xb8, 0x0, 0xe, 0x0, 0x0, 0x3, 0xc1, 0x39, + 0x0, 0xe, 0x0, 0x0, 0x1e, 0x30, 0x84, 0xd, + 0xdf, 0xdd, 0xb0, 0x8f, 0xcc, 0xfc, 0xf4, 0x4d, + 0x34, 0xc0, 0xd, 0x0, 0xc0, 0xc1, 0x2b, 0x2, + 0xb0, 0xd, 0x1, 0xc0, 0xc1, 0x59, 0x2, 0xb0, + 0xd, 0xcd, 0xfc, 0xf1, 0x95, 0x4, 0x90, 0x0, + 0x6, 0xb7, 0x1, 0xe0, 0x5, 0x80, 0x0, 0xc, + 0x67, 0xa, 0x70, 0x9, 0x60, 0x0, 0x5b, 0x37, + 0x79, 0x3, 0xdb, 0x51, 0x4, 0xd1, 0x28, 0x0, + 0x0, 0x0, 0xc2, 0x6c, 0x10, 0xb, 0xcc, 0xcc, + 0xcd, 0xa0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+52D5 "動" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x13, 0x59, 0xd4, 0xc, 0x20, 0x0, 0xa, 0xba, + 0xe6, 0x31, 0xc, 0x20, 0x0, 0x15, 0x56, 0xd5, + 0x54, 0xc, 0x20, 0x0, 0x15, 0x56, 0xd5, 0x57, + 0x7e, 0x87, 0x72, 0x7, 0xab, 0xea, 0xa7, 0x6e, + 0x66, 0xc5, 0xb, 0x1, 0xc0, 0x48, 0xe, 0x0, + 0xa4, 0xb, 0xab, 0xea, 0xc8, 0x1e, 0x0, 0xa3, + 0xb, 0x44, 0xd3, 0x78, 0x2c, 0x0, 0xb3, 0x4, + 0x67, 0xd6, 0x63, 0x68, 0x0, 0xc2, 0x9, 0xbc, + 0xfb, 0xb6, 0xb4, 0x0, 0xd1, 0x0, 0x1, 0xc0, + 0x3, 0xd0, 0x0, 0xe0, 0x6, 0x79, 0xfc, 0xdf, + 0x50, 0x2, 0xd0, 0x7, 0x53, 0x20, 0x77, 0x5, + 0xde, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+52D9 "務" */ + 0x0, 0x0, 0x0, 0x0, 0x72, 0x0, 0x0, 0x3d, + 0xdd, 0xdf, 0x13, 0xe1, 0x0, 0x0, 0x0, 0x0, + 0x99, 0x1d, 0xdc, 0xcd, 0xa0, 0x2, 0x97, 0xa0, + 0xc9, 0xb0, 0x1c, 0x20, 0x0, 0x5e, 0x0, 0x20, + 0x3b, 0xc4, 0x0, 0x5d, 0xde, 0xdd, 0x52, 0x9c, + 0xca, 0x40, 0x0, 0x7f, 0xa, 0xbc, 0x73, 0x5, + 0xb6, 0x0, 0xce, 0xc, 0x0, 0x4a, 0x0, 0x0, + 0x7, 0x7e, 0x24, 0xac, 0xee, 0xcd, 0xc0, 0x3d, + 0xe, 0x0, 0x0, 0xc2, 0x2, 0xc0, 0x33, 0xe, + 0x0, 0x6, 0xb0, 0x4, 0xa0, 0x0, 0xe, 0x0, + 0x7d, 0x10, 0x8, 0x60, 0x4, 0xdc, 0x9, 0x81, + 0x8, 0xdc, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+52DD "勝" */ + 0x0, 0x0, 0x0, 0x10, 0x35, 0x2, 0x0, 0xb, + 0xdd, 0xd1, 0xc2, 0x67, 0x2c, 0x0, 0xb, 0x0, + 0xd0, 0x26, 0x85, 0x92, 0x0, 0xb, 0x0, 0xd4, + 0xcc, 0xfd, 0xcc, 0x60, 0xb, 0xcc, 0xd0, 0x1, + 0xd0, 0x0, 0x0, 0xc, 0x0, 0xda, 0xce, 0xec, + 0xdc, 0xc1, 0xc, 0x21, 0xd0, 0x5b, 0x41, 0xa5, + 0x0, 0xc, 0xbb, 0xd7, 0xc1, 0xc1, 0xa, 0x91, + 0xc, 0x0, 0xe7, 0xdc, 0xfc, 0xcc, 0x40, 0xc, + 0x0, 0xd0, 0x3, 0xb0, 0xd, 0x0, 0x2c, 0x0, + 0xd0, 0xb, 0x50, 0x1c, 0x0, 0x58, 0x0, 0xd0, + 0x7b, 0x0, 0x3a, 0x0, 0x74, 0x5d, 0x99, 0x90, + 0x2c, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+52E4 "勤" */ + 0x0, 0xa2, 0x8, 0x50, 0x9, 0x30, 0x0, 0x2b, + 0xec, 0xbd, 0xda, 0xa, 0x30, 0x0, 0x0, 0xa2, + 0x8, 0x50, 0xa, 0x30, 0x0, 0x0, 0x6a, 0xe9, + 0x33, 0x9d, 0xb9, 0x93, 0x7, 0xab, 0xea, 0xa5, + 0x3c, 0x53, 0xa5, 0xa, 0x22, 0xb0, 0x85, 0xd, + 0x10, 0x85, 0xa, 0x88, 0xd6, 0xb5, 0xe, 0x0, + 0x94, 0x3, 0x46, 0xd4, 0x41, 0xd, 0x0, 0xa4, + 0x9, 0xbb, 0xeb, 0xb6, 0x2a, 0x0, 0xa3, 0x0, + 0x2, 0xb0, 0x0, 0x67, 0x0, 0xb2, 0x6, 0xab, + 0xea, 0xa3, 0xc1, 0x0, 0xd1, 0x3, 0x46, 0xd7, + 0x8a, 0xa0, 0x0, 0xe0, 0x19, 0x76, 0x43, 0x3c, + 0x2, 0xde, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+52F5 "勵" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0xb, + 0xcb, 0xbb, 0xbb, 0x40, 0xd0, 0x0, 0xb, 0x13, + 0xa1, 0xb1, 0x0, 0xd0, 0x0, 0xb, 0x69, 0xd8, + 0xe8, 0x33, 0xd2, 0x20, 0xb, 0x26, 0x96, 0xa5, + 0x8b, 0xea, 0xe2, 0xb, 0x4a, 0x3b, 0x3b, 0x2, + 0xb0, 0xb1, 0xc, 0x4c, 0x9d, 0x9c, 0x3, 0x90, + 0xb1, 0xc, 0x4c, 0x8d, 0x8c, 0x5, 0x70, 0xc1, + 0xc, 0x13, 0x3b, 0x33, 0x7, 0x50, 0xc0, 0xc, + 0xaa, 0x9d, 0x9d, 0x2b, 0x20, 0xd0, 0x3a, 0xa2, + 0xa, 0x98, 0x3d, 0x0, 0xd0, 0x66, 0xa7, 0xa7, + 0x9a, 0xa7, 0x1, 0xc0, 0x42, 0xa2, 0x0, 0x5c, + 0xc0, 0xad, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5305 "包" */ + 0x0, 0x0, 0x83, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0xfe, 0xee, 0xee, 0xee, 0x40, 0x0, 0x89, 0x0, + 0x0, 0x0, 0xa, 0x40, 0x7, 0xd3, 0x22, 0x22, + 0x20, 0xa, 0x40, 0x1b, 0x1f, 0xaa, 0xaa, 0xd0, + 0xb, 0x30, 0x0, 0xe, 0x0, 0x0, 0xd0, 0xc, + 0x20, 0x0, 0xe, 0x11, 0x11, 0xd0, 0xd, 0x10, + 0x0, 0xf, 0xbb, 0xbb, 0xa0, 0x1e, 0x0, 0x0, + 0xe, 0x0, 0x0, 0xa, 0xe7, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x0, 0x0, 0x55, 0x0, 0xf, 0x10, + 0x0, 0x0, 0x0, 0xa6, 0x0, 0x7, 0xee, 0xee, + 0xee, 0xee, 0xb0, + + /* U+5316 "化" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe1, 0xe, 0x10, 0x0, 0x0, 0x0, 0x7, + 0xa0, 0xe, 0x10, 0x0, 0x0, 0x0, 0xe, 0x20, + 0xe, 0x10, 0x6, 0xa0, 0x0, 0x9f, 0x0, 0xe, + 0x10, 0x3e, 0x30, 0x5, 0xef, 0x0, 0xe, 0x12, + 0xd5, 0x0, 0x2e, 0x4f, 0x0, 0xe, 0x3e, 0x60, + 0x0, 0x4, 0xf, 0x0, 0xe, 0xe5, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x8f, 0x40, 0x0, 0x0, 0x0, + 0xf, 0x2d, 0xbf, 0x10, 0x0, 0x0, 0x0, 0xf, + 0x5, 0xe, 0x10, 0x0, 0xa3, 0x0, 0xf, 0x0, + 0xe, 0x10, 0x0, 0xb3, 0x0, 0xf, 0x0, 0xe, + 0x20, 0x0, 0xe0, 0x0, 0xf, 0x0, 0x8, 0xfe, + 0xee, 0x80, + + /* U+5317 "北" */ + 0x0, 0x0, 0x3b, 0x0, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0x3b, 0x0, 0xe1, 0x0, 0x0, 0x0, 0x0, + 0x3b, 0x0, 0xe1, 0x0, 0x10, 0x0, 0x0, 0x3b, + 0x0, 0xe1, 0x4, 0xe2, 0xc, 0xee, 0xfb, 0x0, + 0xe1, 0x8d, 0x30, 0x0, 0x0, 0x3b, 0x0, 0xed, + 0x80, 0x0, 0x0, 0x0, 0x3b, 0x0, 0xe3, 0x0, + 0x0, 0x0, 0x0, 0x3b, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0x0, 0x3b, 0x0, 0xe1, 0x0, 0x0, 0x0, + 0x17, 0xdb, 0x0, 0xe1, 0x0, 0x18, 0x1b, 0xe8, + 0x5b, 0x0, 0xe1, 0x0, 0x2c, 0x5, 0x0, 0x3b, + 0x0, 0xd2, 0x0, 0x5a, 0x0, 0x0, 0x3b, 0x0, + 0x8f, 0xee, 0xe3, + + /* U+533B "医" */ + 0xde, 0xee, 0xee, 0xee, 0xee, 0xeb, 0xd, 0x10, + 0x8, 0x0, 0x0, 0x0, 0x0, 0xd1, 0x7, 0xa1, + 0x11, 0x11, 0x10, 0xd, 0x13, 0xeb, 0xbf, 0xbb, + 0xb9, 0x0, 0xd1, 0xb3, 0x0, 0xc1, 0x0, 0x0, + 0xd, 0x12, 0x22, 0x2d, 0x42, 0x22, 0x10, 0xd2, + 0xaa, 0xaa, 0xfb, 0xaa, 0xa5, 0xd, 0x10, 0x0, + 0x5d, 0xc2, 0x0, 0x0, 0xd1, 0x0, 0x4d, 0x23, + 0xd4, 0x0, 0xd, 0x14, 0xbc, 0x20, 0x1, 0xd5, + 0x0, 0xd3, 0x85, 0x21, 0x11, 0x13, 0x71, 0xa, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb1, + + /* U+5340 "區" */ + 0xed, 0xdd, 0xdd, 0xdd, 0xdd, 0xd4, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0xfa, 0xaa, + 0xf2, 0x0, 0xe0, 0x0, 0xe0, 0x0, 0xd2, 0x0, + 0xe0, 0x0, 0xdb, 0xbb, 0xc1, 0x0, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe0, 0xcb, 0xbe, 0xf, + 0xbb, 0xd0, 0xe0, 0xc0, 0xb, 0xc, 0x0, 0xd0, + 0xe0, 0xc5, 0x5d, 0xe, 0x55, 0xd0, 0xe0, 0x34, + 0x44, 0x4, 0x44, 0x30, 0xeb, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + + /* U+5341 "十" */ + 0x0, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, + 0x0, 0x0, 0x0, 0x3, 0x33, 0x33, 0x8b, 0x33, + 0x33, 0x31, 0xb, 0xbb, 0xbb, 0xce, 0xbb, 0xbb, + 0xb4, 0x0, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, + 0x0, 0x0, 0x0, + + /* U+5343 "千" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, + 0x0, 0x13, 0x57, 0xad, 0xd8, 0x0, 0x2, 0xde, + 0xca, 0xbc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x59, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x59, 0x0, + 0x0, 0x0, 0x1e, 0xee, 0xee, 0xff, 0xee, 0xee, + 0xe6, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x59, + 0x0, 0x0, 0x0, + + /* U+5348 "午" */ + 0x0, 0x7, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, + 0xee, 0xee, 0xee, 0xee, 0x20, 0x0, 0xd3, 0x0, + 0x77, 0x0, 0x0, 0x0, 0xa, 0xa0, 0x0, 0x77, + 0x0, 0x0, 0x0, 0xa, 0x10, 0x0, 0x77, 0x0, + 0x0, 0x0, 0x1, 0x11, 0x11, 0x88, 0x11, 0x11, + 0x10, 0x3d, 0xdd, 0xdd, 0xee, 0xdd, 0xdd, 0xd3, + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77, + 0x0, 0x0, 0x0, + + /* U+534A "半" */ + 0x0, 0x42, 0x0, 0x59, 0x0, 0x6, 0x0, 0x0, + 0x5b, 0x0, 0x59, 0x0, 0x5c, 0x0, 0x0, 0xd, + 0x30, 0x59, 0x0, 0xd3, 0x0, 0x0, 0x6, 0xa0, + 0x59, 0x5, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x59, + 0x0, 0x10, 0x0, 0x2, 0xee, 0xee, 0xff, 0xee, + 0xee, 0x80, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, + 0x1e, 0xee, 0xee, 0xff, 0xee, 0xee, 0xe6, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x59, + 0x0, 0x0, 0x0, + + /* U+5352 "卒" */ + 0x0, 0x0, 0x0, 0x72, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6a, 0x0, 0x0, 0x0, 0xc, 0xee, + 0xee, 0xee, 0xee, 0xee, 0xc0, 0x0, 0x1, 0xa0, + 0x0, 0x6, 0x40, 0x0, 0x0, 0x8, 0xa0, 0x0, + 0x1e, 0x10, 0x0, 0x0, 0x1e, 0xc7, 0x0, 0xad, + 0x80, 0x0, 0x2, 0xd5, 0x9, 0x5b, 0x80, 0x8c, + 0x10, 0xc, 0x70, 0x0, 0x48, 0x0, 0x5, 0xa0, + 0x1, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x3d, + 0xdd, 0xdd, 0xee, 0xdd, 0xdd, 0xd3, 0x0, 0x0, + 0x0, 0x86, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x86, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x86, + 0x0, 0x0, 0x0, + + /* U+5354 "協" */ + 0x0, 0x95, 0x0, 0x0, 0x74, 0x0, 0x0, 0x0, + 0x95, 0x0, 0x0, 0x83, 0x0, 0x0, 0x0, 0x95, + 0x5, 0xcc, 0xfc, 0xcd, 0xa0, 0x0, 0x95, 0x0, + 0x4, 0xa0, 0x7, 0x80, 0x5d, 0xee, 0xc0, 0x4d, + 0x10, 0xb, 0x40, 0x0, 0x95, 0xa, 0xc2, 0x6, + 0xc9, 0x0, 0x0, 0x95, 0x3, 0x60, 0x0, 0x80, + 0x0, 0x0, 0x95, 0x15, 0xb2, 0x12, 0xd2, 0x20, + 0x0, 0x95, 0x6c, 0xcb, 0xaa, 0xe9, 0xd3, 0x0, + 0x95, 0x8, 0x43, 0x81, 0xa0, 0x93, 0x0, 0x95, + 0xc, 0x14, 0x85, 0x60, 0xa2, 0x0, 0x95, 0x5a, + 0x6, 0x7c, 0x10, 0xc0, 0x0, 0x95, 0xa0, 0x9c, + 0x74, 0x4c, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5357 "南" */ + 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x1, + 0x11, 0x11, 0x98, 0x11, 0x11, 0x10, 0x1d, 0xdd, + 0xdd, 0xee, 0xdd, 0xdd, 0xd2, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x0, 0x0, 0x4, 0xdd, 0xdd, 0xfe, + 0xdd, 0xdd, 0x50, 0x5, 0x90, 0x44, 0x0, 0x54, + 0x8, 0x60, 0x5, 0x90, 0x1c, 0x0, 0xc1, 0x8, + 0x60, 0x5, 0x93, 0xcd, 0xcd, 0xec, 0x58, 0x60, + 0x5, 0x90, 0x0, 0x76, 0x0, 0x8, 0x60, 0x5, + 0x96, 0xaa, 0xdd, 0xaa, 0x78, 0x60, 0x5, 0x91, + 0x11, 0x87, 0x11, 0x18, 0x60, 0x5, 0x90, 0x0, + 0x76, 0x0, 0x9, 0x60, 0x5, 0x90, 0x0, 0x76, + 0x9, 0xcd, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5358 "単" */ + 0x0, 0x20, 0x0, 0x50, 0x0, 0x5, 0x0, 0x0, + 0x6b, 0x0, 0xc3, 0x0, 0x8a, 0x0, 0x0, 0xb, + 0x30, 0x58, 0x2, 0xd1, 0x0, 0x0, 0xbd, 0xcc, + 0xde, 0xcc, 0xcf, 0x20, 0x0, 0xb2, 0x0, 0x59, + 0x0, 0xc, 0x20, 0x0, 0xbc, 0xcc, 0xde, 0xcc, + 0xcf, 0x20, 0x0, 0xb2, 0x0, 0x59, 0x0, 0xc, + 0x20, 0x0, 0xbc, 0xbb, 0xce, 0xbb, 0xbe, 0x20, + 0x0, 0x11, 0x11, 0x6a, 0x11, 0x11, 0x0, 0x1, + 0x11, 0x11, 0x6a, 0x11, 0x11, 0x10, 0xc, 0xcc, + 0xcc, 0xde, 0xcc, 0xcc, 0xc5, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x59, + 0x0, 0x0, 0x0, + + /* U+5371 "危" */ + 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xfd, 0xdd, 0xd2, 0x0, 0x0, 0x0, 0x1e, + 0x20, 0x2, 0xe0, 0x0, 0x0, 0x2, 0xd8, 0x22, + 0x2a, 0x92, 0x22, 0x20, 0x2e, 0xfb, 0xaa, 0xaa, + 0xaa, 0xaa, 0xa0, 0x45, 0xd1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd1, 0x2f, 0xdd, 0xdd, 0xf0, + 0x0, 0x0, 0xf0, 0x2c, 0x0, 0x0, 0xe0, 0x0, + 0x0, 0xe0, 0x2c, 0x0, 0x2, 0xd0, 0x0, 0x2, + 0xc0, 0x2c, 0x2, 0xcd, 0x70, 0x0, 0x8, 0x70, + 0x2c, 0x0, 0x0, 0x0, 0xb1, 0x1e, 0x10, 0x2d, + 0x0, 0x0, 0x0, 0xe0, 0x87, 0x0, 0xb, 0xed, + 0xdd, 0xde, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5373 "即" */ + 0x3f, 0xdd, 0xdf, 0xb, 0xed, 0xde, 0x3b, 0x0, + 0xd, 0xc, 0x10, 0xe, 0x3b, 0x0, 0xd, 0xc, + 0x10, 0xe, 0x3f, 0xdd, 0xdf, 0xc, 0x10, 0xe, + 0x3b, 0x0, 0xd, 0xc, 0x10, 0xe, 0x3b, 0x11, + 0x1e, 0xc, 0x10, 0xe, 0x3e, 0xcc, 0xcc, 0xc, + 0x10, 0xe, 0x3b, 0x1, 0x50, 0xc, 0x10, 0xe, + 0x3b, 0x0, 0xc2, 0xc, 0x2a, 0xcd, 0x4b, 0x4a, + 0xdb, 0xc, 0x11, 0x10, 0x9f, 0xb5, 0xc, 0x2c, + 0x10, 0x0, 0x31, 0x0, 0x1, 0xc, 0x10, 0x0, + + /* U+537B "卻" */ + 0x0, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xb0, 0x6b, 0x3, 0xfd, 0xed, 0x2, 0xd2, 0x0, + 0xa8, 0x3b, 0x1, 0xd1, 0xd4, 0x1d, 0x1, 0xc4, + 0xb0, 0x1d, 0x3, 0x9, 0xe7, 0x0, 0x3b, 0x1, + 0xd0, 0x2, 0xd0, 0xa9, 0x3, 0xb0, 0x1d, 0x1, + 0xd3, 0x0, 0xa8, 0x3b, 0x1, 0xd2, 0xd6, 0x0, + 0x1, 0xa4, 0xb0, 0x1d, 0x24, 0xec, 0xcc, 0xf0, + 0x3b, 0x1, 0xd0, 0xd, 0x0, 0xd, 0x3, 0xb2, + 0x4d, 0x0, 0xd0, 0x0, 0xd0, 0x3b, 0x79, 0x40, + 0xe, 0xdd, 0xdf, 0x3, 0xb0, 0x0, 0x0, 0xd0, + 0x0, 0xd0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+539A "厚" */ + 0x0, 0xed, 0xdd, 0xdd, 0xdd, 0xdd, 0xd5, 0x0, + 0xe0, 0x45, 0x55, 0x55, 0x55, 0x0, 0x0, 0xe0, + 0xe5, 0x55, 0x55, 0x5f, 0x0, 0x0, 0xe0, 0xea, + 0x99, 0x99, 0x9f, 0x0, 0x0, 0xe0, 0xe2, 0x11, + 0x11, 0x1f, 0x0, 0x0, 0xf0, 0x78, 0x88, 0x88, + 0x87, 0x0, 0x1, 0xe0, 0xab, 0xbb, 0xbb, 0xba, + 0x0, 0x1, 0xc0, 0x0, 0x0, 0x2a, 0xc3, 0x0, + 0x4, 0xa0, 0x0, 0x0, 0xf4, 0x0, 0x0, 0x7, + 0x6b, 0xcc, 0xcc, 0xfc, 0xcc, 0xc6, 0xd, 0x20, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0x2a, 0x0, 0x5, + 0xcc, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+539F "原" */ + 0x0, 0xed, 0xdd, 0xdd, 0xdd, 0xdd, 0xd5, 0x0, + 0xe0, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, 0xe0, + 0xab, 0xbe, 0xdb, 0xbb, 0x0, 0x0, 0xe0, 0xe0, + 0x0, 0x0, 0xd, 0x10, 0x0, 0xf0, 0xe9, 0x99, + 0x99, 0x9f, 0x10, 0x0, 0xf0, 0xe1, 0x11, 0x11, + 0x1d, 0x10, 0x1, 0xe0, 0xe0, 0x0, 0x0, 0xd, + 0x10, 0x2, 0xc0, 0xab, 0xbb, 0xfb, 0xbb, 0x0, + 0x5, 0x90, 0x7, 0x0, 0xe0, 0x60, 0x0, 0x9, + 0x50, 0x98, 0x0, 0xe0, 0x6b, 0x0, 0xe, 0x19, + 0x90, 0x0, 0xe0, 0x7, 0xb0, 0x16, 0x2, 0x3, + 0xdd, 0xa0, 0x0, 0x40, + + /* U+53B3 "厳" */ + 0x0, 0x81, 0x3, 0x70, 0x0, 0x77, 0x0, 0x0, + 0x5a, 0x0, 0xd0, 0x2, 0xd1, 0x0, 0x7, 0xde, + 0xcc, 0xdc, 0xce, 0xec, 0xc0, 0x9, 0x42, 0x22, + 0x20, 0x6, 0x0, 0x0, 0x9, 0x59, 0x99, 0xe1, + 0x4b, 0x0, 0x0, 0x9, 0x53, 0x35, 0xc2, 0x8e, + 0xcc, 0xc2, 0x9, 0x6e, 0x77, 0xd6, 0xe4, 0x9, + 0x50, 0xa, 0x3c, 0xaa, 0xe9, 0xba, 0xc, 0x10, + 0xb, 0x2c, 0x0, 0xb4, 0xc, 0x3b, 0x0, 0xc, + 0xc, 0xaa, 0xe1, 0x6, 0xe4, 0x0, 0xd, 0xc, + 0x0, 0xb1, 0x6, 0xf2, 0x0, 0x59, 0x6e, 0xbb, + 0xe7, 0x7a, 0x4d, 0x30, 0x82, 0x11, 0x0, 0xb8, + 0x70, 0x2, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+53BB "去" */ + 0x0, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0xbb, + 0xbb, 0xce, 0xbb, 0xbb, 0x40, 0x0, 0x33, 0x33, + 0x7b, 0x33, 0x33, 0x10, 0x0, 0x0, 0x0, 0x5a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, 0x0, + 0x0, 0x0, 0x1e, 0xee, 0xee, 0xff, 0xee, 0xee, + 0xe7, 0x0, 0x0, 0xd, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x89, 0x0, 0x1d, 0x10, 0x0, 0x0, + 0x3, 0xd0, 0x0, 0x5, 0xc0, 0x0, 0x0, 0x1d, + 0x20, 0x0, 0x12, 0xb9, 0x0, 0x0, 0xde, 0xce, + 0xee, 0xcb, 0xad, 0x40, 0x0, 0x53, 0x20, 0x0, + 0x0, 0x3, 0x60, + + /* U+53C2 "参" */ + 0x0, 0x0, 0x6, 0xa0, 0x23, 0x0, 0x0, 0x0, + 0x0, 0x99, 0x0, 0x2c, 0x80, 0x0, 0x0, 0x4e, + 0xd9, 0xaa, 0xbc, 0xfb, 0x0, 0x0, 0x25, 0x46, + 0xd1, 0x0, 0x9, 0x50, 0x0, 0x0, 0x9, 0x70, + 0x0, 0x0, 0x0, 0x1d, 0xdd, 0xef, 0xdd, 0xef, + 0xdd, 0xd5, 0x0, 0x2, 0xd3, 0x3, 0x2a, 0x70, + 0x0, 0x0, 0x4e, 0x44, 0xba, 0x10, 0xba, 0x10, + 0xb, 0xc3, 0xb8, 0x20, 0x66, 0x6, 0xe5, 0x3, + 0x0, 0x3, 0x8c, 0x70, 0x10, 0x10, 0x0, 0x2, + 0xd9, 0x40, 0x5, 0xd4, 0x0, 0x0, 0x0, 0x0, + 0x27, 0xd9, 0x20, 0x0, 0x0, 0x19, 0xbd, 0xb6, + 0x10, 0x0, 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+53C3 "參" */ + 0x0, 0x0, 0x9, 0x20, 0x30, 0x0, 0x0, 0x0, + 0x4, 0xc5, 0x0, 0x6c, 0x20, 0x0, 0x0, 0x6e, + 0xcc, 0xbb, 0xa9, 0xc3, 0x0, 0x0, 0x39, 0x0, + 0x0, 0x8, 0x31, 0x0, 0x1, 0xc2, 0x90, 0xb8, + 0x4b, 0x1c, 0x20, 0x9, 0xdb, 0xcd, 0xab, 0xfc, + 0xba, 0xc0, 0x0, 0x1, 0xa7, 0x2, 0x9b, 0x20, + 0x20, 0x2, 0x8c, 0x53, 0xb7, 0x3, 0xba, 0x50, + 0x2c, 0x56, 0xb8, 0x10, 0x94, 0x2, 0x94, 0x0, + 0x2, 0x3, 0x8b, 0x40, 0x41, 0x0, 0x0, 0x7, + 0xc9, 0x30, 0x19, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x49, 0xc5, 0x0, 0x0, 0x0, 0x39, 0xcc, 0x83, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+53C8 "又" */ + 0x9, 0xee, 0xee, 0xee, 0xee, 0xec, 0x0, 0x0, + 0x5a, 0x0, 0x0, 0x0, 0x69, 0x0, 0x0, 0xd, + 0x10, 0x0, 0x0, 0xd3, 0x0, 0x0, 0x7, 0x80, + 0x0, 0x4, 0xc0, 0x0, 0x0, 0x1, 0xe1, 0x0, + 0xc, 0x40, 0x0, 0x0, 0x0, 0x6b, 0x0, 0x89, + 0x0, 0x0, 0x0, 0x0, 0xa, 0x75, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xee, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x9, 0xdd, 0x90, 0x0, 0x0, 0x0, + 0x4, 0xd9, 0x0, 0xad, 0x40, 0x0, 0x17, 0xdc, + 0x40, 0x0, 0x5, 0xcd, 0x71, 0x19, 0x20, 0x0, + 0x0, 0x0, 0x2, 0x92, + + /* U+53CA "及" */ + 0x8, 0xef, 0xfe, 0xee, 0xfe, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0x0, 0x3a, 0x0, 0x0, 0x0, 0x1, + 0xf4, 0x0, 0x76, 0x0, 0x0, 0x0, 0x1, 0xfa, + 0x0, 0xcd, 0xcc, 0x90, 0x0, 0x3, 0xcd, 0x10, + 0x11, 0x18, 0x70, 0x0, 0x6, 0xa6, 0x70, 0x0, + 0xe, 0x10, 0x0, 0x9, 0x60, 0xd2, 0x0, 0x6a, + 0x0, 0x0, 0x1f, 0x10, 0x4c, 0x3, 0xd1, 0x0, + 0x0, 0x7a, 0x0, 0x7, 0xce, 0x30, 0x0, 0x3, + 0xf2, 0x0, 0x7, 0xee, 0x50, 0x0, 0x1e, 0x50, + 0x27, 0xd9, 0x13, 0xcd, 0x71, 0x5, 0x0, 0x88, + 0x20, 0x0, 0x3, 0x93, + + /* U+53CB "友" */ + 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x2, 0x22, + 0x7a, 0x22, 0x22, 0x22, 0x20, 0xc, 0xcc, 0xed, + 0xcc, 0xcc, 0xcc, 0xc0, 0x0, 0x0, 0xa4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xdc, 0xbb, 0xbb, + 0xc4, 0x0, 0x0, 0x2, 0xfb, 0x22, 0x23, 0xe1, + 0x0, 0x0, 0x8, 0x6c, 0x20, 0x6, 0xa0, 0x0, + 0x0, 0xd, 0x4, 0xc0, 0x2d, 0x20, 0x0, 0x0, + 0x88, 0x0, 0x6c, 0xd4, 0x0, 0x0, 0x4, 0xc0, + 0x0, 0x5e, 0xe5, 0x0, 0x0, 0x3e, 0x21, 0x6c, + 0xb2, 0x2b, 0xd7, 0x30, 0x2, 0x8, 0x93, 0x0, + 0x0, 0x27, 0xc2, + + /* U+53CD "反" */ + 0x0, 0x0, 0x0, 0x12, 0x57, 0xb5, 0x0, 0x9, + 0xdd, 0xdc, 0xb9, 0x63, 0x0, 0x0, 0xc3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc5, 0x33, 0x33, 0x33, 0x31, + 0x0, 0xd, 0xbe, 0xba, 0xaa, 0xae, 0x60, 0x0, + 0xe1, 0x77, 0x0, 0x1, 0xe0, 0x0, 0xf, 0x1, + 0xd0, 0x0, 0x89, 0x0, 0x0, 0xe0, 0x7, 0xa0, + 0x3d, 0x10, 0x0, 0x2d, 0x0, 0xb, 0x9e, 0x30, + 0x0, 0x6, 0x90, 0x0, 0x6f, 0xc0, 0x0, 0x0, + 0xc4, 0x3, 0xbc, 0x37, 0xe6, 0x10, 0x3d, 0x1d, + 0xc5, 0x0, 0x2, 0x8e, 0x80, 0x10, 0x10, 0x0, + 0x0, 0x0, 0x0, + + /* U+53D6 "取" */ + 0x6e, 0xed, 0xdf, 0xc0, 0x0, 0x0, 0x0, 0x7, + 0x60, 0xd, 0xe, 0xfe, 0xee, 0xb0, 0x7, 0x60, + 0xd, 0x3, 0xa0, 0x4, 0x80, 0x7, 0xed, 0xdd, + 0x0, 0xd0, 0x8, 0x50, 0x7, 0x60, 0xd, 0x0, + 0xc1, 0xc, 0x10, 0x7, 0x60, 0xd, 0x0, 0x85, + 0x1d, 0x0, 0x7, 0xed, 0xdd, 0x0, 0x2b, 0x86, + 0x0, 0x7, 0x60, 0xd, 0x0, 0xc, 0xd0, 0x0, + 0x7, 0x62, 0x5e, 0x90, 0xa, 0xb0, 0x0, 0x5e, + 0xdb, 0x9e, 0x20, 0x5c, 0xc6, 0x0, 0x0, 0x0, + 0xd, 0x5, 0xd1, 0x1d, 0x70, 0x0, 0x0, 0xd, + 0x2b, 0x10, 0x1, 0xa2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+53D7 "受" */ + 0x0, 0x1, 0x23, 0x46, 0x79, 0xca, 0x0, 0x9, + 0xdc, 0xba, 0xb7, 0x53, 0x22, 0x0, 0x0, 0x77, + 0x0, 0xb3, 0x0, 0x88, 0x0, 0x0, 0x1e, 0x0, + 0x68, 0x2, 0xd0, 0x0, 0xc, 0xde, 0xdd, 0xdd, + 0xde, 0xed, 0xd0, 0xe, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe0, 0x0, 0x4f, 0xee, 0xee, 0xee, 0xe0, 0x0, + 0x0, 0x6, 0xb0, 0x0, 0xa, 0x50, 0x0, 0x0, + 0x0, 0x8a, 0x0, 0xa8, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xdd, 0x70, 0x0, 0x0, 0x0, 0x2, 0x7d, + 0xaa, 0xd8, 0x20, 0x0, 0xb, 0xec, 0x71, 0x0, + 0x17, 0xce, 0xb0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x20, + + /* U+53E3 "口" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xee, + 0xee, 0xee, 0xee, 0xf1, 0x1e, 0x0, 0x0, 0x0, + 0x0, 0xe1, 0x1e, 0x0, 0x0, 0x0, 0x0, 0xe1, + 0x1e, 0x0, 0x0, 0x0, 0x0, 0xe1, 0x1e, 0x0, + 0x0, 0x0, 0x0, 0xe1, 0x1e, 0x0, 0x0, 0x0, + 0x0, 0xe1, 0x1e, 0x0, 0x0, 0x0, 0x0, 0xe1, + 0x1e, 0x0, 0x0, 0x0, 0x0, 0xe1, 0x1e, 0x33, + 0x33, 0x33, 0x33, 0xe1, 0x1f, 0xbb, 0xbb, 0xbb, + 0xbb, 0xf1, 0x1e, 0x0, 0x0, 0x0, 0x0, 0xd1, + + /* U+53E4 "古" */ + 0x0, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0x0, 0x1e, 0xee, 0xee, + 0xff, 0xee, 0xee, 0xe6, 0x0, 0x0, 0x0, 0x5a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, 0x0, 0x0, + 0x0, 0x0, 0x8f, 0xee, 0xee, 0xee, 0xee, 0x0, + 0x0, 0x86, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x86, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x86, + 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x8d, 0xcc, + 0xcc, 0xcc, 0xce, 0x0, 0x0, 0x87, 0x11, 0x11, + 0x11, 0x3d, 0x0, + + /* U+53E5 "句" */ + 0x0, 0x3, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xed, + 0xdd, 0xdd, 0xdd, 0xb0, 0x9, 0x70, 0x0, 0x0, + 0x0, 0x3c, 0x3, 0xd0, 0x0, 0x0, 0x0, 0x3, + 0xc1, 0xd3, 0xcd, 0xdd, 0xda, 0x0, 0x3b, 0x36, + 0xe, 0x0, 0x2, 0xb0, 0x4, 0xa0, 0x0, 0xe0, + 0x0, 0x2b, 0x0, 0x59, 0x0, 0xe, 0x0, 0x2, + 0xb0, 0x6, 0x80, 0x0, 0xeb, 0xbb, 0xcb, 0x0, + 0x87, 0x0, 0xe, 0x11, 0x11, 0x10, 0xa, 0x50, + 0x0, 0x20, 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0x0, 0xee, 0xf9, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+53E6 "另" */ + 0x0, 0xbe, 0xee, 0xee, 0xee, 0xec, 0x0, 0xb, + 0x30, 0x0, 0x0, 0x2, 0xc0, 0x0, 0xb3, 0x0, + 0x0, 0x0, 0x2c, 0x0, 0xb, 0x30, 0x0, 0x0, + 0x2, 0xc0, 0x0, 0xae, 0xee, 0xfe, 0xee, 0xeb, + 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0xd, + 0xdd, 0xdd, 0xfd, 0xdd, 0xdd, 0x30, 0x0, 0x0, + 0x6b, 0x0, 0x0, 0xc3, 0x0, 0x0, 0xd, 0x40, + 0x0, 0xd, 0x20, 0x0, 0xb, 0x90, 0x0, 0x0, + 0xf0, 0x1, 0x6e, 0x80, 0x0, 0x0, 0x2d, 0x1, + 0xd9, 0x20, 0x0, 0xd, 0xee, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+53EA "只" */ + 0x0, 0xce, 0xee, 0xee, 0xee, 0xed, 0x0, 0x0, + 0xd1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0xd1, + 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0xd1, 0x0, + 0x0, 0x0, 0x1e, 0x0, 0x0, 0xd1, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0xd2, 0x11, 0x11, 0x11, + 0x2e, 0x0, 0x0, 0xbd, 0xdd, 0xdd, 0xdd, 0xdb, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x84, 0x0, 0x39, 0x0, 0x0, 0x0, + 0x8, 0xb0, 0x0, 0x8, 0xc1, 0x0, 0x1, 0xab, + 0x0, 0x0, 0x0, 0x6d, 0x20, 0x2e, 0x70, 0x0, + 0x0, 0x0, 0x5, 0xe1, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x20, + + /* U+53EB "叫" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe1, 0x8a, 0xaa, + 0x70, 0x90, 0x0, 0xe1, 0xd3, 0x35, 0xb0, 0xe1, + 0x0, 0xe1, 0xd0, 0x2, 0xb0, 0xe1, 0x0, 0xe1, + 0xd0, 0x2, 0xb0, 0xe1, 0x0, 0xe1, 0xd0, 0x2, + 0xb0, 0xe1, 0x0, 0xe1, 0xd0, 0x2, 0xb0, 0xe1, + 0x0, 0xe1, 0xd0, 0x2, 0xb0, 0xe1, 0x0, 0xe1, + 0xd2, 0x14, 0xb0, 0xe1, 0x26, 0xf1, 0xdc, 0xcc, + 0x83, 0xfe, 0xc8, 0xe1, 0x80, 0x0, 0x2, 0x61, + 0x0, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe1, + + /* U+53EF "可" */ + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0xad, 0xdd, + 0xdd, 0x0, 0x78, 0x0, 0x0, 0xb3, 0x0, 0xe, + 0x0, 0x78, 0x0, 0x0, 0xb2, 0x0, 0xe, 0x0, + 0x78, 0x0, 0x0, 0xb2, 0x0, 0xe, 0x0, 0x78, + 0x0, 0x0, 0xb4, 0x22, 0x2e, 0x0, 0x78, 0x0, + 0x0, 0xbc, 0xcc, 0xcb, 0x0, 0x78, 0x0, 0x0, + 0x51, 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xff, 0xd3, 0x0, + + /* U+53F0 "台" */ + 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x90, 0x0, 0x0, 0x0, 0x0, 0x5, 0xc0, + 0x0, 0xa1, 0x0, 0x0, 0x3, 0xc1, 0x0, 0x5, + 0xd2, 0x0, 0x3, 0xc1, 0x0, 0x12, 0x38, 0xe2, + 0x1, 0xff, 0xee, 0xdc, 0xba, 0x99, 0xd0, 0x2, + 0x0, 0x0, 0x0, 0x0, 0x5, 0x10, 0x3e, 0xee, + 0xee, 0xee, 0xec, 0x0, 0x3, 0xb0, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x1e, + 0x0, 0x3, 0xb0, 0x0, 0x0, 0x1, 0xe0, 0x0, + 0x3f, 0xdd, 0xdd, 0xdd, 0xde, 0x0, 0x3, 0xb1, + 0x11, 0x11, 0x13, 0xd0, 0x0, + + /* U+53F2 "史" */ + 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0xbb, + 0xbb, 0xbf, 0xbb, 0xbb, 0x90, 0x0, 0xe3, 0x33, + 0x4e, 0x33, 0x34, 0xd0, 0x0, 0xe0, 0x0, 0x1e, + 0x0, 0x1, 0xd0, 0x0, 0xe0, 0x0, 0x1e, 0x0, + 0x1, 0xd0, 0x0, 0xfe, 0xee, 0xef, 0xee, 0xee, + 0xd0, 0x0, 0x14, 0x0, 0x2c, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x69, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xd2, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7f, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x39, 0xe7, + 0xbd, 0x85, 0x20, 0x0, 0xd, 0xc7, 0x0, 0x2, + 0x6a, 0xce, 0xea, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+53F3 "右" */ + 0x0, 0x0, 0x2, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x40, 0x0, 0x0, 0x0, 0x1e, 0xee, 0xff, + 0xee, 0xee, 0xee, 0xe1, 0x0, 0x0, 0x88, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xb2, 0x22, 0x22, 0x22, + 0x0, 0x0, 0x7f, 0xec, 0xcc, 0xcc, 0xcf, 0x10, + 0x7, 0xe6, 0xb0, 0x0, 0x0, 0xd, 0x10, 0x4c, + 0x13, 0xb0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x3, + 0xb0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x3, 0xfd, + 0xdd, 0xdd, 0xdf, 0x10, 0x0, 0x3, 0xb1, 0x11, + 0x11, 0x1d, 0x10, + + /* U+53F7 "号" */ + 0x0, 0x6e, 0xdd, 0xdd, 0xdd, 0xe5, 0x0, 0x0, + 0x68, 0x0, 0x0, 0x0, 0x95, 0x0, 0x0, 0x69, + 0x11, 0x11, 0x11, 0xa5, 0x0, 0x0, 0x4b, 0xbb, + 0xbb, 0xbb, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1d, 0xde, 0xfd, 0xdd, 0xdd, + 0xdd, 0xd0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0xed, 0xdd, 0xdd, 0xd4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0x8d, 0xdd, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+53F8 "司" */ + 0x9e, 0xee, 0xee, 0xee, 0xee, 0xeb, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3b, 0x12, 0x22, 0x22, 0x22, + 0x20, 0x3b, 0x6b, 0xbb, 0xbb, 0xbb, 0xa0, 0x3b, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x9, 0xdd, + 0xdd, 0xdd, 0x0, 0x3b, 0x9, 0x40, 0x0, 0xe, + 0x0, 0x3b, 0x9, 0x40, 0x0, 0xe, 0x0, 0x3b, + 0x9, 0x51, 0x11, 0x1e, 0x0, 0x3b, 0x9, 0xcb, + 0xbb, 0xba, 0x0, 0x3b, 0x5, 0x20, 0x0, 0x0, + 0x0, 0x4b, 0x0, 0x0, 0x0, 0x0, 0xdf, 0xe6, + + /* U+5403 "吃" */ + 0x0, 0x0, 0x0, 0x85, 0x0, 0x0, 0x9, 0xaa, + 0x90, 0xe, 0x10, 0x0, 0x0, 0xe3, 0x3d, 0x5, + 0xfc, 0xcc, 0xcc, 0x4d, 0x0, 0xd0, 0xd4, 0x11, + 0x11, 0x10, 0xd0, 0xd, 0x88, 0x0, 0x0, 0x0, + 0xd, 0x0, 0xd1, 0x4d, 0xdd, 0xdd, 0x50, 0xd0, + 0xd, 0x0, 0x0, 0x1d, 0x80, 0xd, 0x0, 0xd0, + 0x0, 0x2e, 0x60, 0x0, 0xe0, 0xd, 0x0, 0x2e, + 0x50, 0x0, 0xe, 0xdd, 0xc0, 0x2e, 0x40, 0x0, + 0x0, 0xa0, 0x0, 0xc, 0x50, 0x0, 0x3, 0x80, + 0x0, 0x2, 0xe0, 0x0, 0x0, 0x68, 0x0, 0x0, + 0xa, 0xee, 0xee, 0xee, 0x20, + + /* U+5404 "各" */ + 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, + 0xec, 0xcc, 0xcd, 0xf1, 0x0, 0x0, 0x9c, 0xd3, + 0x0, 0xc, 0x60, 0x0, 0xc, 0x90, 0x2d, 0x63, + 0xc6, 0x0, 0x0, 0x1, 0x0, 0x2, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x3, 0xad, 0x65, 0xca, 0x40, + 0x0, 0x29, 0xdb, 0x50, 0x0, 0x4, 0xae, 0xa2, + 0x14, 0x1d, 0xdd, 0xdd, 0xdd, 0xd1, 0x40, 0x0, + 0x1d, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x1d, + 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x1e, 0x22, + 0x22, 0x22, 0xe1, 0x0, 0x0, 0x1f, 0xaa, 0xaa, + 0xaa, 0xe1, 0x0, + + /* U+5408 "合" */ + 0x0, 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xd5, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x9c, + 0x10, 0x2d, 0x70, 0x0, 0x0, 0x4d, 0x80, 0x0, + 0x0, 0x9d, 0x50, 0xc, 0xb8, 0xdd, 0xdd, 0xdd, + 0xc2, 0xb9, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xbb, 0xbb, 0xbb, 0xb8, 0x0, + 0x0, 0x1e, 0x11, 0x11, 0x11, 0x4c, 0x0, 0x0, + 0x1d, 0x0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x1d, + 0x0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x1f, 0xdd, + 0xdd, 0xdd, 0xec, 0x0, 0x0, 0x1d, 0x0, 0x0, + 0x0, 0x3b, 0x0, + + /* U+540C "同" */ + 0xee, 0xee, 0xee, 0xee, 0xee, 0xec, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x1c, 0xe0, 0xbc, 0xcc, 0xcc, + 0xc2, 0x1c, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x1c, + 0xe0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0xe0, 0x2e, + 0xcc, 0xce, 0x70, 0x1c, 0xe0, 0x2a, 0x0, 0x6, + 0x70, 0x1c, 0xe0, 0x2a, 0x0, 0x6, 0x70, 0x1c, + 0xe0, 0x2f, 0xcc, 0xce, 0x70, 0x1c, 0xe0, 0x2a, + 0x0, 0x0, 0x0, 0x1c, 0xe0, 0x14, 0x0, 0x0, + 0x0, 0x2c, 0xe0, 0x0, 0x0, 0x0, 0x9e, 0xd7, + + /* U+540D "名" */ + 0x0, 0x0, 0x2, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xd7, 0x11, 0x11, 0x10, 0x0, 0x1, 0xcc, + 0xbb, 0xbb, 0xeb, 0x0, 0x5, 0xe5, 0x0, 0x0, + 0x2d, 0x20, 0x6, 0xa2, 0x95, 0x0, 0x3d, 0x30, + 0x0, 0x0, 0x1, 0xba, 0x8b, 0x20, 0x0, 0x0, + 0x0, 0x17, 0xe6, 0x0, 0x0, 0x0, 0x15, 0xaf, + 0xfe, 0xdd, 0xdd, 0xd1, 0xb, 0x97, 0xb0, 0x0, + 0x0, 0xd, 0x10, 0x0, 0x3b, 0x0, 0x0, 0x0, + 0xd1, 0x0, 0x3, 0xb0, 0x0, 0x0, 0xd, 0x10, + 0x0, 0x3e, 0xbb, 0xbb, 0xbb, 0xf1, 0x0, 0x3, + 0xc1, 0x11, 0x11, 0x1e, 0x10, + + /* U+5411 "向" */ + 0x0, 0x0, 0x7, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x6d, 0x0, 0x0, 0x0, 0x11, 0x11, 0xc6, 0x11, + 0x11, 0x10, 0xcd, 0xdd, 0xdd, 0xdd, 0xdd, 0xf3, + 0xc1, 0x0, 0x0, 0x0, 0x0, 0xb3, 0xc1, 0xa, + 0xaa, 0xaa, 0x70, 0xb3, 0xc1, 0xe, 0x22, 0x24, + 0xb0, 0xb3, 0xc1, 0xd, 0x0, 0x1, 0xb0, 0xb3, + 0xc1, 0xd, 0x0, 0x1, 0xb0, 0xb3, 0xc1, 0xf, + 0xdd, 0xde, 0xb0, 0xb3, 0xc1, 0xd, 0x0, 0x0, + 0x0, 0xb3, 0xc1, 0x0, 0x0, 0x0, 0x0, 0xb3, + 0xc1, 0x0, 0x0, 0x0, 0xbe, 0xd1, + + /* U+5426 "否" */ + 0xe, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xe0, 0x0, + 0x0, 0x0, 0x6d, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xf7, 0x65, 0x0, 0x0, 0x0, 0x6, 0xd7, + 0x87, 0x2a, 0xd5, 0x0, 0x18, 0xeb, 0x20, 0x77, + 0x0, 0x2b, 0xb1, 0x19, 0x20, 0x0, 0x77, 0x0, + 0x0, 0x50, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, + 0x0, 0x0, 0x7e, 0xdd, 0xdd, 0xdd, 0xe9, 0x0, + 0x0, 0x77, 0x0, 0x0, 0x0, 0x69, 0x0, 0x0, + 0x77, 0x0, 0x0, 0x0, 0x69, 0x0, 0x0, 0x7d, + 0xaa, 0xaa, 0xaa, 0xc9, 0x0, 0x0, 0x78, 0x22, + 0x22, 0x22, 0x79, 0x0, + + /* U+5427 "吧" */ + 0x22, 0x22, 0xe, 0xee, 0xfe, 0xef, 0xd, 0xbb, + 0xe0, 0xe0, 0xd, 0x0, 0xe0, 0xd0, 0xe, 0xe, + 0x0, 0xd0, 0xe, 0xd, 0x0, 0xe0, 0xe0, 0xd, + 0x0, 0xe0, 0xd0, 0xe, 0xe, 0x0, 0xd0, 0xe, + 0xd, 0x0, 0xe0, 0xe5, 0x5e, 0x55, 0xe0, 0xd0, + 0xe, 0xe, 0x77, 0x77, 0x7e, 0xd, 0xbb, 0xe0, + 0xe0, 0x0, 0x0, 0x40, 0xd2, 0x22, 0xe, 0x0, + 0x0, 0x0, 0xc, 0x0, 0x0, 0xe0, 0x0, 0x0, + 0x66, 0x0, 0x0, 0xe, 0x10, 0x0, 0xa, 0x50, + 0x0, 0x0, 0x7e, 0xee, 0xee, 0xc0, + + /* U+5440 "呀" */ + 0x33, 0x33, 0x6e, 0xee, 0xee, 0xfe, 0x3e, 0xaa, + 0xd0, 0x21, 0x0, 0x2b, 0x0, 0xe0, 0xd, 0xa, + 0x30, 0x2, 0xb0, 0xe, 0x0, 0xd0, 0xd1, 0x0, + 0x2b, 0x0, 0xe0, 0xd, 0xe, 0x11, 0x14, 0xc1, + 0xe, 0x0, 0xd2, 0xcc, 0xcd, 0xff, 0xc6, 0xe0, + 0xd, 0x0, 0x0, 0x8c, 0xb0, 0xe, 0x0, 0xd0, + 0x0, 0x79, 0x3b, 0x0, 0xed, 0xdc, 0x0, 0x9a, + 0x2, 0xb0, 0xd, 0x0, 0x3, 0xc7, 0x0, 0x2b, + 0x0, 0x0, 0x2, 0xc3, 0x0, 0x3, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x7e, 0xe7, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+544A "告" */ + 0x0, 0x8, 0x30, 0x2c, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x8f, + 0xdd, 0xef, 0xdd, 0xdd, 0x10, 0x4, 0xd0, 0x0, + 0x2c, 0x0, 0x0, 0x0, 0x9, 0x30, 0x0, 0x2c, + 0x0, 0x0, 0x0, 0x1b, 0xbb, 0xbb, 0xcf, 0xbb, + 0xbb, 0xb2, 0x2, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5f, 0xdd, 0xdd, 0xdd, 0xe8, 0x0, 0x0, + 0x58, 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0x58, + 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0x5d, 0xaa, + 0xaa, 0xaa, 0xd8, 0x0, 0x0, 0x5a, 0x33, 0x33, + 0x33, 0x88, 0x0, + + /* U+5462 "呢" */ + 0x33, 0x32, 0xf, 0xdd, 0xdd, 0xde, 0xf, 0xab, + 0xb0, 0xc0, 0x0, 0x0, 0xe0, 0xd0, 0x1b, 0xc, + 0x0, 0x0, 0xe, 0xd, 0x1, 0xb0, 0xfd, 0xdd, + 0xdd, 0xc0, 0xd0, 0x1b, 0xc, 0x8, 0x0, 0x0, + 0xd, 0x1, 0xb1, 0xb0, 0xe0, 0x1, 0x60, 0xd0, + 0x1b, 0x3a, 0xe, 0x5, 0xd7, 0xd, 0x2, 0xb4, + 0x80, 0xfc, 0x91, 0x0, 0xfd, 0xda, 0x67, 0xe, + 0x10, 0x0, 0xd, 0x0, 0xb, 0x20, 0xe0, 0x0, + 0x42, 0x0, 0x3, 0xc0, 0xe, 0x0, 0x8, 0x50, + 0x0, 0x93, 0x0, 0xbe, 0xdd, 0xd1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5468 "周" */ + 0x0, 0xde, 0xee, 0xef, 0xee, 0xef, 0x10, 0xd, + 0x0, 0x6, 0x70, 0x0, 0xd1, 0x0, 0xd0, 0xbb, + 0xdd, 0xbb, 0x2d, 0x10, 0xd, 0x0, 0x6, 0x70, + 0x0, 0xd1, 0x0, 0xe4, 0x99, 0xcc, 0x99, 0x5d, + 0x10, 0xe, 0x2, 0x22, 0x22, 0x21, 0xd1, 0x0, + 0xe0, 0x12, 0x22, 0x22, 0xd, 0x10, 0x1c, 0xa, + 0xb9, 0x9a, 0xc0, 0xd1, 0x4, 0xa0, 0xa3, 0x0, + 0x1c, 0xd, 0x10, 0x86, 0xa, 0xcb, 0xbb, 0xc0, + 0xd1, 0x1e, 0x10, 0xa4, 0x0, 0x0, 0xe, 0x14, + 0x80, 0x2, 0x10, 0x0, 0xcd, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5473 "味" */ + 0x0, 0x0, 0x0, 0x2, 0xc0, 0x0, 0x7, 0x77, + 0x60, 0x0, 0x2c, 0x0, 0x0, 0xea, 0xad, 0x2, + 0x24, 0xd2, 0x22, 0xd, 0x0, 0xd0, 0xbb, 0xcf, + 0xbb, 0xa0, 0xd0, 0xd, 0x0, 0x2, 0xc0, 0x0, + 0xd, 0x0, 0xd0, 0x0, 0x2c, 0x0, 0x0, 0xd0, + 0xd, 0x8e, 0xef, 0xfe, 0xee, 0x7d, 0x0, 0xd0, + 0x0, 0xef, 0x90, 0x0, 0xe0, 0xd, 0x0, 0x9a, + 0xdd, 0x20, 0xf, 0xdd, 0xc0, 0x3c, 0x2c, 0x4b, + 0x0, 0xa0, 0x0, 0x3d, 0x22, 0xc0, 0x99, 0x0, + 0x0, 0x3d, 0x20, 0x2c, 0x0, 0xa6, 0x0, 0x0, + 0x0, 0x2, 0xc0, 0x0, 0x0, + + /* U+547C "呼" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x3, 0x56, 0x8a, 0xdd, 0x80, 0xed, 0xf2, 0x77, + 0x66, 0xd0, 0x0, 0xd, 0xb, 0x22, 0x70, 0x1c, + 0x1, 0xc0, 0xd0, 0xb2, 0xd, 0x11, 0xc0, 0x77, + 0xd, 0xb, 0x20, 0x86, 0x1c, 0xd, 0x0, 0xd0, + 0xb2, 0x2, 0x31, 0xc1, 0x40, 0xd, 0xb, 0x4d, + 0xdd, 0xdf, 0xdd, 0xd8, 0xee, 0xf2, 0x0, 0x1, + 0xc0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x1c, 0x0, + 0x0, 0xa0, 0x0, 0x0, 0x1, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xde, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+547D "命" */ + 0x0, 0x0, 0x0, 0x29, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xdd, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x4d, 0x40, 0xb7, 0x0, 0x0, 0x0, 0x2a, 0xd2, + 0x0, 0x9, 0xc4, 0x0, 0x1c, 0xd5, 0x8d, 0xdd, + 0xdc, 0x3b, 0xd2, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x30, 0x0, 0xfd, 0xde, 0x32, 0xed, 0xde, + 0x20, 0x0, 0xd0, 0xa, 0x32, 0xb0, 0xb, 0x20, + 0x0, 0xd0, 0xa, 0x32, 0xb0, 0xb, 0x20, 0x0, + 0xe2, 0x2b, 0x32, 0xb0, 0xb, 0x20, 0x0, 0xfa, + 0xaa, 0x22, 0xb3, 0xdd, 0x10, 0x0, 0xd0, 0x0, + 0x2, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0xb0, 0x0, 0x0, + + /* U+548C "和" */ + 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x57, + 0xad, 0xb5, 0x13, 0x33, 0x32, 0x7, 0x59, 0x60, + 0x8, 0xda, 0xab, 0xd0, 0x0, 0x76, 0x0, 0x86, + 0x0, 0x1d, 0x3d, 0xde, 0xed, 0xc8, 0x60, 0x1, + 0xd0, 0x1, 0xe9, 0x0, 0x86, 0x0, 0x1d, 0x0, + 0x6e, 0xe6, 0x8, 0x60, 0x1, 0xd0, 0xc, 0x87, + 0xc3, 0x86, 0x0, 0x1d, 0x7, 0x77, 0x62, 0x88, + 0x60, 0x1, 0xd4, 0xc0, 0x76, 0x0, 0x86, 0x0, + 0x1d, 0x42, 0x7, 0x60, 0x8, 0xec, 0xcd, 0xd0, + 0x0, 0x76, 0x0, 0x87, 0x11, 0x3d, 0x0, 0x7, + 0x60, 0x5, 0x40, 0x1, 0x70, + + /* U+54B2 "咲" */ + 0x0, 0x0, 0x8, 0x20, 0x0, 0x67, 0x7, 0x77, + 0x70, 0x5b, 0x0, 0xd, 0x20, 0xe6, 0x6e, 0x0, + 0xc1, 0x4, 0x80, 0xe, 0x0, 0xe5, 0xee, 0xee, + 0xee, 0xe3, 0xe0, 0xe, 0x0, 0x2, 0xc0, 0x0, + 0xe, 0x0, 0xe0, 0x0, 0x2c, 0x0, 0x0, 0xe0, + 0xe, 0x45, 0x57, 0xd5, 0x55, 0x3e, 0x0, 0xe5, + 0x88, 0xaf, 0x88, 0x85, 0xee, 0xef, 0x0, 0x8, + 0xf5, 0x0, 0xe, 0x0, 0x0, 0x1, 0xe3, 0xc0, + 0x0, 0x70, 0x0, 0x1, 0xc6, 0x9, 0x60, 0x0, + 0x0, 0x5, 0xd7, 0x0, 0x1d, 0x60, 0x0, 0x8, + 0xb3, 0x0, 0x0, 0x1b, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+54C1 "品" */ + 0x0, 0xee, 0xee, 0xee, 0xed, 0x0, 0x0, 0xe0, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0xe0, 0x0, 0x0, + 0x1d, 0x0, 0x0, 0xe3, 0x33, 0x33, 0x4d, 0x0, + 0x0, 0x9a, 0xaa, 0xaa, 0xa9, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xee, 0xee, 0xf0, 0x2f, + 0xee, 0xed, 0xe0, 0x0, 0xe0, 0x2b, 0x0, 0x1d, + 0xe0, 0x0, 0xe0, 0x2b, 0x0, 0x1d, 0xe0, 0x0, + 0xe0, 0x2b, 0x0, 0x1d, 0xec, 0xcc, 0xf0, 0x2f, + 0xcc, 0xdd, 0xe1, 0x11, 0xc0, 0x2c, 0x11, 0x2c, + + /* U+54E1 "員" */ + 0x0, 0x4e, 0xcc, 0xcc, 0xcc, 0xf3, 0x0, 0x0, + 0x49, 0x0, 0x0, 0x0, 0xc3, 0x0, 0x0, 0x4d, + 0xcc, 0xcc, 0xcc, 0xe2, 0x0, 0x0, 0x44, 0x44, + 0x44, 0x44, 0x43, 0x0, 0x0, 0xe6, 0x55, 0x55, + 0x55, 0x7c, 0x0, 0x0, 0xea, 0xaa, 0xaa, 0xaa, + 0xbc, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x2c, + 0x0, 0x0, 0xea, 0xaa, 0xaa, 0xaa, 0xbc, 0x0, + 0x0, 0xe0, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, + 0xbb, 0xcb, 0xbb, 0xcb, 0xb9, 0x0, 0x0, 0x39, + 0xd2, 0x0, 0x7d, 0x93, 0x0, 0x2d, 0xb5, 0x0, + 0x0, 0x0, 0x5b, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+54EA "哪" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x22, + 0x6d, 0xed, 0xd4, 0xec, 0xe2, 0xeb, 0xe0, 0x39, + 0xc, 0x47, 0xc, 0xc, 0xc, 0x3, 0x90, 0xc4, + 0x73, 0x90, 0xc0, 0xc6, 0xde, 0xcc, 0x47, 0x74, + 0xc, 0xc, 0x3, 0x90, 0xc4, 0x7b, 0x0, 0xc0, + 0xc0, 0x48, 0xc, 0x47, 0x57, 0xc, 0xc, 0x16, + 0x82, 0xc4, 0x70, 0xc0, 0xd4, 0xd5, 0xdc, 0xac, + 0x47, 0xb, 0xd, 0x66, 0xb, 0x10, 0xb4, 0x70, + 0xc1, 0xb0, 0x1, 0xc0, 0x1b, 0x47, 0xca, 0x0, + 0x0, 0xa5, 0x3, 0x94, 0x70, 0x0, 0x0, 0x1a, + 0xc, 0xe4, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5546 "商" */ + 0x0, 0x0, 0x0, 0x52, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x69, 0x0, 0x0, 0x0, 0x1d, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xd1, 0x0, 0x0, 0xd1, + 0x0, 0x1d, 0x10, 0x0, 0x0, 0x11, 0x76, 0x11, + 0x98, 0x11, 0x0, 0x4, 0xeb, 0xbb, 0xbb, 0xbb, + 0xbd, 0x50, 0x4, 0x90, 0x3b, 0x0, 0xb6, 0x8, + 0x50, 0x4, 0x97, 0xb1, 0x0, 0x9, 0xb9, 0x50, + 0x4, 0x93, 0x8c, 0xbb, 0xc7, 0x38, 0x50, 0x4, + 0x90, 0x93, 0x0, 0x48, 0x8, 0x50, 0x4, 0x90, + 0x9b, 0xaa, 0xb8, 0x8, 0x50, 0x4, 0x90, 0x84, + 0x0, 0x0, 0x8, 0x50, 0x4, 0x90, 0x0, 0x0, + 0x7, 0xbc, 0x20, + + /* U+554A "啊" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xdc, + 0x2f, 0xdc, 0xce, 0xee, 0xf6, 0xc1, 0xc2, 0x94, + 0x70, 0x0, 0x1b, 0xb, 0xc, 0x29, 0x83, 0x6b, + 0xb1, 0xb0, 0xb0, 0xc2, 0x9b, 0x9, 0x3b, 0x1b, + 0xb, 0xc, 0x29, 0xa2, 0x91, 0xa1, 0xb0, 0xb0, + 0xc2, 0x92, 0x99, 0x1a, 0x1b, 0xb, 0xc, 0x29, + 0xc, 0x91, 0xa1, 0xb0, 0xec, 0xe2, 0x90, 0xc9, + 0xce, 0x1b, 0xc, 0x11, 0x2a, 0xc8, 0x93, 0x21, + 0xb0, 0x50, 0x2, 0x90, 0x1, 0x0, 0x1b, 0x0, + 0x0, 0x29, 0x0, 0x0, 0x2, 0xb0, 0x0, 0x2, + 0x90, 0x0, 0xd, 0xd6, 0x0, + + /* U+554F "問" */ + 0xec, 0xcc, 0xf0, 0xcc, 0xcc, 0xcc, 0xe0, 0x0, + 0xc0, 0xc1, 0x0, 0x2c, 0xeb, 0xbb, 0xe0, 0xcb, + 0xbb, 0xcc, 0xe0, 0x0, 0xc0, 0xc1, 0x0, 0x2c, + 0xec, 0xcc, 0xc0, 0x9c, 0xbb, 0xcc, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x2c, 0xe0, 0xd, 0xcc, 0xce, + 0x30, 0x2c, 0xe0, 0xd, 0x0, 0xb, 0x30, 0x2c, + 0xe0, 0xd, 0x0, 0xb, 0x30, 0x2c, 0xe0, 0xe, + 0xcc, 0xcf, 0x30, 0x2c, 0xe0, 0xd, 0x0, 0x0, + 0x0, 0x3c, 0xe0, 0x0, 0x0, 0x0, 0xce, 0xe7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5566 "啦" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x3, 0x90, 0x0, 0x88, 0x80, 0xd, + 0x0, 0xd, 0x0, 0xd, 0x6d, 0x0, 0xd0, 0x22, + 0x93, 0x20, 0xc0, 0xc6, 0xdf, 0xa9, 0xaa, 0xaa, + 0xc, 0xc, 0x0, 0xd0, 0x31, 0x3, 0x50, 0xc0, + 0xc0, 0xd, 0x6, 0x50, 0x67, 0xc, 0xc, 0x0, + 0xe8, 0x48, 0x8, 0x50, 0xc0, 0xc5, 0xde, 0x32, + 0xa0, 0xa3, 0xe, 0xbf, 0x11, 0xd0, 0xc, 0xc, + 0x0, 0xc2, 0x20, 0xd, 0x0, 0xd0, 0xc0, 0x8, + 0x0, 0x0, 0xd0, 0xd, 0x1b, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x24, 0x80, 0x0, 0x0, 0x4d, 0x95, + 0xdd, 0xdd, 0xd4, + + /* U+5584 "善" */ + 0x0, 0x1, 0x50, 0x0, 0x4, 0x30, 0x0, 0x0, + 0x0, 0xd2, 0x0, 0xd, 0x20, 0x0, 0x3, 0xbb, + 0xbb, 0xde, 0xbb, 0xbb, 0x70, 0x0, 0x25, 0x55, + 0x9b, 0x55, 0x54, 0x0, 0x0, 0x24, 0x44, 0x8b, + 0x44, 0x43, 0x0, 0x8, 0xcc, 0xcc, 0xde, 0xcc, + 0xcc, 0xc1, 0x0, 0xb, 0x20, 0x59, 0x0, 0xc1, + 0x0, 0x7, 0x7a, 0xc7, 0xac, 0x7a, 0xd7, 0x73, + 0x5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x52, 0x0, + 0x2c, 0xcc, 0xcc, 0xcc, 0xc7, 0x0, 0x0, 0x3b, + 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x3b, 0x0, + 0x0, 0x0, 0x4a, 0x0, 0x0, 0x3e, 0xcc, 0xcc, + 0xcc, 0xd9, 0x0, + + /* U+5589 "喉" */ + 0x0, 0x0, 0x6, 0x20, 0x0, 0x0, 0xd, 0xdd, + 0x0, 0xe1, 0xbc, 0xcf, 0x20, 0xc0, 0xc0, 0x58, + 0x0, 0x0, 0xc0, 0xc, 0xc, 0xd, 0x3c, 0xcc, + 0xcf, 0xc2, 0xc0, 0xc7, 0xf0, 0xb, 0x0, 0x0, + 0xc, 0xc, 0xde, 0x2, 0xd0, 0x0, 0x0, 0xc0, + 0xc3, 0xd0, 0xad, 0xde, 0xba, 0xc, 0xc, 0xd, + 0x4c, 0x5, 0x80, 0x0, 0xc2, 0xc0, 0xd3, 0x64, + 0x8a, 0x44, 0xe, 0xbb, 0xd, 0x47, 0x7c, 0xf8, + 0x71, 0x80, 0x0, 0xd0, 0x1, 0xd9, 0x40, 0x0, + 0x0, 0xd, 0x3, 0xc4, 0xc, 0x40, 0x0, 0x0, + 0xd5, 0xb2, 0x0, 0x1b, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+559C "喜" */ + 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x7, + 0xbb, 0xbb, 0xce, 0xbb, 0xbb, 0xb1, 0x0, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x6a, 0xaa, + 0xaa, 0xaa, 0xaa, 0x10, 0x0, 0xa, 0xaa, 0xaa, + 0xaa, 0xa4, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, + 0x76, 0x0, 0x0, 0xf, 0xaa, 0xaa, 0xaa, 0xd6, + 0x0, 0x0, 0x0, 0xc3, 0x0, 0xd, 0x20, 0x0, + 0xc, 0xcc, 0xdd, 0xcc, 0xce, 0xcc, 0xc6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e, + 0xaa, 0xaa, 0xaa, 0xbb, 0x0, 0x0, 0x3a, 0x0, + 0x0, 0x0, 0x3b, 0x0, 0x0, 0x3e, 0xbb, 0xbb, + 0xbb, 0xcb, 0x0, + + /* U+559D "喝" */ + 0x33, 0x32, 0xf, 0xbb, 0xbb, 0xcb, 0xe, 0xbb, + 0xb0, 0xd0, 0x0, 0x2, 0xb0, 0xd0, 0x1b, 0xf, + 0xaa, 0xaa, 0xbb, 0xd, 0x1, 0xb0, 0xe3, 0x33, + 0x35, 0xb0, 0xd0, 0x1b, 0xa, 0xa6, 0x66, 0x64, + 0xd, 0x1, 0xb0, 0xcc, 0xaa, 0xaa, 0xa4, 0xd0, + 0x1b, 0x87, 0x11, 0x81, 0x18, 0x6e, 0xbc, 0xc8, + 0x70, 0x3d, 0x10, 0x85, 0xd2, 0x21, 0xb, 0x3a, + 0x3c, 0x29, 0x49, 0x0, 0x0, 0xb4, 0x10, 0x21, + 0xb3, 0x0, 0x0, 0xa, 0xaa, 0xaa, 0x7d, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x5b, 0xa0, + + /* U+55AE "單" */ + 0x1, 0xea, 0xac, 0x65, 0xda, 0xae, 0x30, 0x1, + 0xc0, 0x7, 0x65, 0x70, 0xa, 0x30, 0x0, 0x88, + 0x88, 0x33, 0x88, 0x88, 0x10, 0x0, 0x9c, 0xcc, + 0xcc, 0xcc, 0xcb, 0x0, 0x0, 0xc2, 0x0, 0x87, + 0x0, 0xe, 0x0, 0x0, 0xcc, 0xbb, 0xdd, 0xbb, + 0xbe, 0x0, 0x0, 0xc2, 0x0, 0x87, 0x0, 0xe, + 0x0, 0x0, 0xcc, 0xcc, 0xed, 0xcc, 0xce, 0x0, + 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x2d, + 0xdd, 0xdd, 0xee, 0xdd, 0xdd, 0xd3, 0x0, 0x0, + 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x0, 0x0, + + /* U+55B6 "営" */ + 0x8, 0x10, 0x1b, 0x0, 0x2, 0x90, 0x6, 0xa0, + 0xa, 0x60, 0xc, 0x40, 0xab, 0xfb, 0xbc, 0xdb, + 0xce, 0xba, 0xd1, 0x11, 0x11, 0x11, 0x11, 0x2e, + 0xd0, 0xab, 0xbb, 0xbb, 0xb9, 0xe, 0x0, 0xd0, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0xd0, 0x0, 0x0, + 0x1d, 0x0, 0x0, 0xab, 0xbb, 0xbb, 0xb9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xdd, + 0xdd, 0xdd, 0xdd, 0xe0, 0xc, 0x10, 0x0, 0x0, + 0x0, 0xe0, 0xc, 0x21, 0x11, 0x11, 0x11, 0xe0, + 0xc, 0xcb, 0xbb, 0xbb, 0xbc, 0xe0, + + /* U+55CE "嗎" */ + 0x44, 0x44, 0x2f, 0xdd, 0xfd, 0xd9, 0xe, 0x88, + 0xd2, 0xa0, 0x1b, 0x0, 0x0, 0xd0, 0xd, 0x2e, + 0xcc, 0xfc, 0xc5, 0xd, 0x0, 0xd2, 0xa0, 0x1b, + 0x0, 0x0, 0xd0, 0xd, 0x2e, 0xcc, 0xfc, 0xc5, + 0xd, 0x0, 0xd2, 0xa0, 0x1b, 0x0, 0x0, 0xd0, + 0xd, 0x2d, 0x89, 0xe8, 0x88, 0x1f, 0xdd, 0xd0, + 0x33, 0x44, 0x63, 0xd1, 0xd0, 0x0, 0x73, 0x95, + 0x59, 0x2d, 0x5, 0x0, 0xa, 0xb, 0xa, 0x26, + 0xd0, 0x0, 0x1, 0xa0, 0xa0, 0x40, 0x2c, 0x0, + 0x0, 0x12, 0x0, 0x1, 0xcd, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+55EF "嗯" */ + 0x33, 0x30, 0xdc, 0xcc, 0xcc, 0xd7, 0xd, 0x7d, + 0xd, 0x0, 0x64, 0x6, 0x70, 0xc0, 0xb0, 0xd4, + 0xbe, 0xbb, 0x67, 0xc, 0xb, 0xd, 0x1, 0xe7, + 0x6, 0x70, 0xc0, 0xb0, 0xd1, 0xb3, 0x6a, 0x67, + 0xc, 0xb, 0xd, 0x55, 0x33, 0x58, 0x70, 0xc0, + 0xb0, 0x78, 0x88, 0x88, 0x83, 0xe, 0xbe, 0x25, + 0x62, 0x76, 0x9, 0x10, 0xc2, 0x25, 0x79, 0x40, + 0xd1, 0x59, 0x8, 0x0, 0xa3, 0x94, 0x4, 0x46, + 0xd0, 0x0, 0x1c, 0x9, 0x40, 0x5, 0x78, 0x40, + 0x0, 0x30, 0x6e, 0xcc, 0xd2, 0x0, + + /* U+561B "嘛" */ + 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x7, 0x76, + 0x1, 0x11, 0xa7, 0x11, 0x10, 0xc5, 0xb6, 0xca, + 0xaa, 0xaa, 0xaa, 0x4b, 0xb, 0x65, 0x9, 0x0, + 0x17, 0x0, 0xb0, 0xb6, 0x50, 0xc0, 0x2, 0x90, + 0xb, 0xb, 0x79, 0xcf, 0xb6, 0xde, 0xb0, 0xb0, + 0xb7, 0x54, 0xf4, 0x9, 0xe0, 0xb, 0xb, 0x84, + 0x9c, 0xb1, 0xdf, 0x20, 0xc0, 0xb9, 0x39, 0xc4, + 0x68, 0xb7, 0xd, 0xb9, 0xa8, 0x5c, 0xb, 0x39, + 0x90, 0xb0, 0xc, 0x90, 0xc6, 0x62, 0x95, 0x40, + 0x2, 0xb0, 0xc, 0x10, 0x29, 0x0, 0x0, 0x55, + 0x0, 0xc0, 0x2, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+56B4 "嚴" */ + 0x0, 0xc9, 0x9a, 0xb0, 0xd9, 0x9a, 0xb0, 0x0, + 0xc6, 0x46, 0xb0, 0xd4, 0x47, 0xb0, 0x0, 0x56, + 0x66, 0x51, 0x56, 0x66, 0x40, 0x1, 0xeb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xb1, 0x1, 0xb1, 0x88, 0x98, + 0x5, 0x80, 0x0, 0x2, 0xb4, 0x55, 0xb9, 0x3b, + 0xdc, 0xd2, 0x2, 0xb5, 0xd5, 0x5d, 0x6f, 0x0, + 0xb0, 0x3, 0x91, 0xe9, 0x9d, 0xa9, 0x65, 0x80, + 0x4, 0x81, 0xc0, 0xd, 0x0, 0xca, 0x30, 0x8, + 0x51, 0xe8, 0x8d, 0x0, 0x8c, 0x0, 0xd, 0x27, + 0xd8, 0x9e, 0x64, 0xbb, 0x50, 0x29, 0x4, 0x31, + 0xd, 0x78, 0x0, 0x84, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+56DB "四" */ + 0xab, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0xd3, 0x25, + 0xc2, 0x2e, 0x22, 0x5c, 0xd1, 0x3, 0xa0, 0xd, + 0x0, 0x2c, 0xd1, 0x4, 0xa0, 0xd, 0x0, 0x2c, + 0xd1, 0x7, 0x70, 0xd, 0x0, 0x2c, 0xd1, 0xb, + 0x40, 0xd, 0x0, 0x2c, 0xd1, 0x5d, 0x0, 0xc, + 0xbb, 0x9c, 0xd7, 0xe3, 0x0, 0x0, 0x11, 0x3c, + 0xd3, 0x10, 0x0, 0x0, 0x0, 0x2c, 0xd3, 0x22, + 0x22, 0x22, 0x22, 0x4c, 0xdc, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0x50, 0x0, 0x0, 0x0, 0x0, 0x3, + + /* U+56DE "回" */ + 0xef, 0xee, 0xee, 0xee, 0xee, 0xfe, 0xe1, 0x0, + 0x0, 0x0, 0x0, 0x1e, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0xe1, 0xd, 0xdd, 0xdd, 0xc0, 0x1e, + 0xe1, 0xe, 0x0, 0x1, 0xd0, 0x1e, 0xe1, 0xe, + 0x0, 0x1, 0xd0, 0x1e, 0xe1, 0xe, 0x0, 0x1, + 0xd0, 0x1e, 0xe1, 0xe, 0xdd, 0xdd, 0xd0, 0x1e, + 0xe1, 0x0, 0x0, 0x0, 0x0, 0x1e, 0xe1, 0x0, + 0x0, 0x0, 0x0, 0x1e, 0xec, 0xcc, 0xcc, 0xcc, + 0xcc, 0xce, 0xe2, 0x11, 0x11, 0x11, 0x11, 0x2e, + + /* U+56E0 "因" */ + 0xed, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xe0, 0x0, + 0x1, 0x50, 0x0, 0x1d, 0xe0, 0x0, 0x4, 0xa0, + 0x0, 0x1d, 0xe0, 0x11, 0x16, 0xa1, 0x11, 0x1d, + 0xe1, 0xcc, 0xce, 0xec, 0xcc, 0x2d, 0xe0, 0x0, + 0xa, 0x70, 0x0, 0x1d, 0xe0, 0x0, 0x1d, 0xa7, + 0x0, 0x1d, 0xe0, 0x0, 0xa5, 0x9, 0x70, 0x1d, + 0xe0, 0x1a, 0xa0, 0x0, 0xa6, 0x1d, 0xe0, 0xa6, + 0x0, 0x0, 0x8, 0x1d, 0xea, 0xaa, 0xaa, 0xaa, + 0xaa, 0xad, 0xe2, 0x22, 0x22, 0x22, 0x22, 0x3d, + + /* U+56F0 "困" */ + 0xde, 0xdd, 0xdd, 0xdd, 0xdd, 0xee, 0xd1, 0x0, + 0x6, 0x10, 0x0, 0x1e, 0xd1, 0x0, 0xb, 0x20, + 0x0, 0x1e, 0xd2, 0xaa, 0xae, 0xba, 0xaa, 0x2e, + 0xd1, 0x33, 0x9f, 0xc3, 0x33, 0x1e, 0xd1, 0x2, + 0xbc, 0x9b, 0x0, 0x1e, 0xd1, 0x1c, 0x2b, 0x27, + 0xb0, 0x1e, 0xd2, 0xc5, 0xb, 0x20, 0x8a, 0x1e, + 0xd4, 0x50, 0xb, 0x20, 0x8, 0x2e, 0xd1, 0x0, + 0xb, 0x20, 0x0, 0x1e, 0xd4, 0x33, 0x33, 0x33, + 0x33, 0x4e, 0xdb, 0xaa, 0xaa, 0xaa, 0xaa, 0xbe, + + /* U+56F3 "図" */ + 0xde, 0xee, 0xee, 0xee, 0xee, 0xed, 0xd1, 0x0, + 0x9, 0x30, 0x0, 0x1d, 0xd1, 0x50, 0x1, 0xc4, + 0x16, 0x1d, 0xd1, 0x95, 0x59, 0x13, 0x87, 0x1d, + 0xd1, 0x1d, 0x8, 0x71, 0xe0, 0x1d, 0xd1, 0x8, + 0x90, 0x4b, 0x60, 0x1d, 0xd1, 0x0, 0xa9, 0xb8, + 0x0, 0x1d, 0xd1, 0x0, 0x5f, 0xe3, 0x0, 0x1d, + 0xd3, 0x7d, 0xb2, 0x4d, 0xc7, 0x4d, 0xd4, 0x71, + 0x0, 0x0, 0x37, 0x4d, 0xde, 0xee, 0xee, 0xee, + 0xee, 0xed, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x1d, + + /* U+56FD "国" */ + 0xde, 0xdd, 0xdd, 0xdd, 0xdd, 0xea, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0x4a, 0xd1, 0x9d, 0xde, 0xdd, + 0xd6, 0x4a, 0xd1, 0x0, 0x9, 0x40, 0x0, 0x4a, + 0xd1, 0x0, 0x9, 0x40, 0x0, 0x4a, 0xd1, 0x4d, + 0xde, 0xdd, 0xd2, 0x4a, 0xd1, 0x0, 0x9, 0x46, + 0x40, 0x4a, 0xd1, 0x0, 0x9, 0x40, 0xa1, 0x4a, + 0xd1, 0xcc, 0xce, 0xdc, 0xca, 0x4a, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0x4a, 0xdb, 0xaa, 0xaa, 0xaa, + 0xaa, 0xca, 0xd3, 0x22, 0x22, 0x22, 0x22, 0x6a, + + /* U+570B "國" */ + 0xed, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xe0, 0x0, + 0x0, 0xa0, 0xa3, 0xe, 0xe0, 0x44, 0x44, 0xd4, + 0x58, 0x1e, 0xe1, 0x66, 0x66, 0xd7, 0x66, 0x1e, + 0xe0, 0x69, 0x96, 0xa2, 0x55, 0xe, 0xe0, 0xa0, + 0xa, 0x85, 0xd1, 0xe, 0xe0, 0xa9, 0xaa, 0x4c, + 0xa0, 0xe, 0xe0, 0x0, 0x3, 0x2f, 0x11, 0xe, + 0xe2, 0xac, 0xb8, 0xcd, 0x68, 0x3e, 0xe1, 0x20, + 0xa, 0x61, 0xbd, 0xe, 0xe2, 0x22, 0x24, 0x22, + 0x22, 0x2e, 0xea, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, + + /* U+570D "圍" */ + 0xed, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xe0, 0x0, + 0x38, 0x0, 0x0, 0xe, 0xe0, 0x28, 0xca, 0x89, + 0xa0, 0xe, 0xe1, 0x88, 0xc9, 0x89, 0xc8, 0xe, + 0xe0, 0x19, 0x88, 0x88, 0x90, 0xe, 0xe0, 0x2b, + 0x0, 0x0, 0xd0, 0xe, 0xe0, 0x17, 0x77, 0xe7, + 0x70, 0xe, 0xe0, 0x9c, 0x99, 0xf9, 0x98, 0xe, + 0xe0, 0x57, 0x0, 0xd0, 0x0, 0xe, 0xe0, 0x59, + 0x99, 0xf9, 0x97, 0xe, 0xe2, 0x22, 0x22, 0x82, + 0x22, 0x2e, 0xeb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbe, + + /* U+5712 "園" */ + 0xed, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xe0, 0x0, + 0xb, 0x10, 0x0, 0xe, 0xe0, 0x69, 0x9e, 0xa9, + 0x90, 0xe, 0xe2, 0x66, 0x6d, 0x76, 0x66, 0xe, + 0xe1, 0x44, 0x44, 0x44, 0x43, 0xe, 0xe0, 0x9a, + 0x88, 0x88, 0xe0, 0xe, 0xe0, 0x9b, 0x99, 0x99, + 0xe1, 0xe, 0xe0, 0x0, 0x8f, 0x82, 0xa6, 0xe, + 0xe0, 0x6a, 0x3d, 0x3a, 0xb2, 0xe, 0xe4, 0x50, + 0xd, 0x0, 0x39, 0xe, 0xe2, 0x22, 0x23, 0x22, + 0x22, 0x2e, 0xeb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbe, + + /* U+5718 "團" */ + 0xdc, 0xcc, 0xcd, 0xcc, 0xcc, 0xe2, 0xd2, 0x55, + 0x5e, 0x55, 0x53, 0xb2, 0xd2, 0x55, 0x5e, 0x55, + 0x53, 0xb2, 0xd0, 0xc8, 0x8e, 0x88, 0xc2, 0xb2, + 0xd0, 0xc7, 0x7e, 0x77, 0xb2, 0xb2, 0xd0, 0x88, + 0x8e, 0x89, 0xa1, 0xb2, 0xd2, 0x99, 0x9e, 0x89, + 0xc2, 0xb2, 0xd5, 0xa9, 0x99, 0x9d, 0xa9, 0xb2, + 0xd0, 0x9, 0x20, 0xd, 0x0, 0xb2, 0xd0, 0x1, + 0x72, 0x7d, 0x0, 0xb2, 0xda, 0x99, 0x9a, 0xba, + 0x99, 0xe2, 0xd2, 0x22, 0x22, 0x22, 0x22, 0xa2, + + /* U+571F "土" */ + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x59, + 0x0, 0x0, 0x0, 0x2, 0xee, 0xee, 0xff, 0xee, + 0xee, 0x80, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x59, 0x0, 0x0, 0x0, 0xa, 0xaa, 0xaa, + 0xce, 0xaa, 0xaa, 0xa4, 0x3, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x31, + + /* U+5723 "圣" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xef, 0xdd, 0xdd, 0xdd, 0xf9, 0x0, 0x0, 0xc, + 0x60, 0x0, 0x5, 0xd1, 0x0, 0x0, 0x1, 0xd7, + 0x0, 0x7d, 0x20, 0x0, 0x0, 0x0, 0xa, 0xdc, + 0xa0, 0x0, 0x0, 0x0, 0x14, 0x9d, 0xab, 0xd8, + 0x30, 0x0, 0x3d, 0xc9, 0x50, 0x11, 0x16, 0xad, + 0xd2, 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, + 0x0, 0x8d, 0xdd, 0xee, 0xdd, 0xd8, 0x0, 0x0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x77, 0x0, 0x0, 0x0, 0x1, 0x11, 0x11, + 0x88, 0x11, 0x11, 0x10, 0x2c, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xc2, + + /* U+5728 "在" */ + 0x0, 0x0, 0x9, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0x1b, 0xbb, + 0xcf, 0xbb, 0xbb, 0xbb, 0xb1, 0x2, 0x22, 0xe4, + 0x22, 0x22, 0x22, 0x20, 0x0, 0x7, 0xa0, 0x0, + 0x63, 0x0, 0x0, 0x0, 0x1e, 0x20, 0x0, 0x95, + 0x0, 0x0, 0x0, 0xcb, 0x0, 0x0, 0x95, 0x0, + 0x0, 0xc, 0xda, 0xb, 0xdd, 0xfe, 0xdd, 0x80, + 0x3a, 0x4a, 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, + 0x3a, 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x3a, + 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x3a, 0x0, + 0x0, 0x95, 0x0, 0x0, 0x0, 0x3a, 0x5e, 0xee, + 0xfe, 0xee, 0xe1, + + /* U+5730 "地" */ + 0x0, 0x74, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, + 0x85, 0x0, 0x20, 0xd, 0x0, 0x0, 0x0, 0x85, + 0x0, 0xe0, 0xd, 0x0, 0x0, 0x1, 0x96, 0x10, + 0xe0, 0xe, 0x3a, 0xd0, 0x4c, 0xed, 0xc0, 0xe0, + 0x6f, 0xb5, 0xd0, 0x0, 0x85, 0x4, 0xfd, 0x7d, + 0x1, 0xd0, 0x0, 0x85, 0x49, 0xe0, 0xd, 0x1, + 0xc0, 0x0, 0x85, 0x0, 0xe0, 0xd, 0x2, 0xc0, + 0x0, 0x9b, 0xd1, 0xe0, 0xd, 0x5c, 0x80, 0x2b, + 0xe8, 0x10, 0xe0, 0xa, 0x1, 0x10, 0x37, 0x0, + 0x0, 0xe0, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, + 0xe0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x8d, + 0xdd, 0xdd, 0xb0, + + /* U+5747 "均" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, + 0x50, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x95, 0x0, + 0xb, 0x50, 0x0, 0x0, 0x9, 0x50, 0x2, 0xf8, + 0x77, 0x77, 0x1, 0xa6, 0x10, 0xbb, 0x99, 0x99, + 0xe4, 0xce, 0xdc, 0x8c, 0x0, 0x0, 0xd, 0x0, + 0x95, 0xa, 0x29, 0x10, 0x0, 0xe0, 0x9, 0x50, + 0x0, 0x4c, 0x20, 0xd, 0x0, 0x95, 0x0, 0x0, + 0x29, 0x1, 0xd0, 0x9, 0x56, 0x50, 0x0, 0x7c, + 0x3c, 0x1, 0xbe, 0x70, 0x17, 0xd6, 0x3, 0xa4, + 0xe7, 0x0, 0x2e, 0x70, 0x0, 0x59, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x60, 0x0, 0x0, 0x0, + 0x6, 0xde, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+574A "坊" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x3a, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x3a, + 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x3a, 0x2, + 0x44, 0x47, 0x54, 0x42, 0x0, 0x3a, 0x8, 0xcd, + 0xfc, 0xcc, 0xc7, 0x1e, 0xef, 0xe6, 0x1, 0xd0, + 0x0, 0x0, 0x0, 0x3a, 0x0, 0x1, 0xd0, 0x0, + 0x0, 0x0, 0x3a, 0x0, 0x2, 0xfd, 0xde, 0xc0, + 0x0, 0x3a, 0x0, 0x3, 0xb0, 0x3, 0xb0, 0x0, + 0x3a, 0x45, 0x8, 0x80, 0x3, 0xb0, 0x3, 0x9f, + 0xa3, 0xe, 0x20, 0x4, 0xa0, 0x3d, 0x71, 0x0, + 0x8a, 0x0, 0x6, 0x80, 0x0, 0x0, 0x8, 0xd0, + 0x0, 0x9, 0x60, 0x0, 0x0, 0x5b, 0x10, 0xc, + 0xed, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5750 "坐" */ + 0x0, 0x2, 0x30, 0x59, 0x0, 0x31, 0x0, 0x0, + 0xa, 0x50, 0x59, 0x0, 0xc3, 0x0, 0x0, 0xe, + 0x10, 0x59, 0x2, 0xe0, 0x0, 0x0, 0x4f, 0x40, + 0x59, 0x7, 0xd0, 0x0, 0x0, 0xb7, 0xe3, 0x59, + 0x1e, 0x8b, 0x0, 0x6, 0xc0, 0x3d, 0x6a, 0xb7, + 0x9, 0x90, 0x1e, 0x20, 0x3, 0x5c, 0x90, 0x0, + 0xc2, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, + 0x0, 0xee, 0xee, 0xff, 0xee, 0xee, 0x70, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x59, 0x0, 0x0, 0x0, 0x2, 0x22, 0x22, + 0x6a, 0x22, 0x22, 0x20, 0xb, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xb5, + + /* U+578B "型" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x30, 0xa, + 0xee, 0xdf, 0xd6, 0x49, 0xa, 0x30, 0x0, 0x66, + 0xb, 0x20, 0x49, 0xa, 0x30, 0x1, 0x77, 0x1b, + 0x31, 0x49, 0xa, 0x30, 0x2b, 0xed, 0xbe, 0xc9, + 0x49, 0xa, 0x30, 0x0, 0xc2, 0xb, 0x20, 0x26, + 0xa, 0x30, 0x4, 0xb0, 0xb, 0x20, 0x0, 0xa, + 0x30, 0x1c, 0x10, 0x7, 0x62, 0x6, 0xdb, 0x0, + 0x0, 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x1, + 0xdd, 0xdd, 0xfe, 0xdd, 0xd8, 0x0, 0x0, 0x0, + 0x0, 0x95, 0x0, 0x0, 0x0, 0x1, 0x11, 0x11, + 0xa6, 0x11, 0x11, 0x10, 0x7c, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xc1, + + /* U+57DF "域" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, + 0xc0, 0x0, 0x0, 0xe, 0x2c, 0x10, 0x1, 0xc0, + 0x0, 0x0, 0xe, 0x4, 0x90, 0x1, 0xc0, 0x8d, + 0xdd, 0xdf, 0xdd, 0xd0, 0x36, 0xe5, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x7c, 0xfc, 0x22, 0x22, 0xc, + 0x10, 0x0, 0x1, 0xc0, 0x4c, 0x9e, 0xb, 0x25, + 0x90, 0x1, 0xc0, 0x46, 0xb, 0xa, 0x3b, 0x30, + 0x1, 0xc0, 0x46, 0xb, 0x8, 0x7d, 0x0, 0x1, + 0xc1, 0x4c, 0xcc, 0x5, 0xe5, 0x0, 0x4, 0xfc, + 0x20, 0x3, 0x66, 0xd0, 0x0, 0x8c, 0x40, 0x8b, + 0xc9, 0x8e, 0xd0, 0x51, 0x0, 0x0, 0x51, 0x5, + 0xc2, 0xa5, 0xa0, 0x0, 0x0, 0x0, 0x1a, 0x0, + 0x2d, 0xb0, + + /* U+57F7 "執" */ + 0x0, 0x7, 0x60, 0x0, 0x3a, 0x0, 0x0, 0x0, + 0x7, 0x70, 0x0, 0x3a, 0x0, 0x0, 0x7, 0xcd, + 0xdc, 0x60, 0x3a, 0x0, 0x0, 0x0, 0x7, 0x60, + 0xb, 0xde, 0xcd, 0x10, 0x2d, 0xdd, 0xdd, 0xc0, + 0x3a, 0xc, 0x10, 0x1, 0xb0, 0xc, 0x0, 0x49, + 0xc, 0x10, 0x0, 0x91, 0x49, 0xb, 0x78, 0xc, + 0x10, 0x9, 0xce, 0xed, 0x83, 0xe8, 0xc, 0x10, + 0x0, 0x6, 0x60, 0x0, 0xbe, 0x5b, 0x10, 0x2c, + 0xce, 0xec, 0xc0, 0xe1, 0xaa, 0x20, 0x0, 0x6, + 0x60, 0x6, 0x80, 0x8, 0x48, 0x0, 0x6, 0x60, + 0x2d, 0x10, 0x4, 0xa9, 0x0, 0x6, 0x60, 0xa3, + 0x0, 0x0, 0x93, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+57FA "基" */ + 0x0, 0x4, 0x90, 0x0, 0x2, 0xc0, 0x0, 0x4, + 0x8b, 0xd8, 0x88, 0x89, 0xe8, 0x80, 0x1, 0x47, + 0xb4, 0x44, 0x45, 0xd4, 0x40, 0x0, 0x4, 0xeb, + 0xbb, 0xbc, 0xc0, 0x0, 0x0, 0x4, 0x90, 0x0, + 0x2, 0xc0, 0x0, 0x0, 0x4, 0xeb, 0xbb, 0xbc, + 0xc0, 0x0, 0x0, 0x4, 0x90, 0x0, 0x2, 0xc0, + 0x0, 0x1c, 0xcd, 0xfc, 0xcc, 0xcd, 0xec, 0xc7, + 0x0, 0xb, 0x60, 0x14, 0x0, 0xc5, 0x0, 0x5, + 0xda, 0xaa, 0xce, 0xaa, 0x8c, 0xb3, 0xc, 0x30, + 0x11, 0x5b, 0x11, 0x10, 0x64, 0x0, 0x0, 0x0, + 0x4a, 0x0, 0x0, 0x0, 0x0, 0xcc, 0xcc, 0xde, + 0xcc, 0xcc, 0x60, + + /* U+5831 "報" */ + 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x60, 0x8, 0xed, 0xdd, 0xe0, 0x8, 0xce, + 0xdc, 0x78, 0x50, 0x0, 0xe0, 0x0, 0x7, 0x60, + 0x8, 0x50, 0x22, 0xe0, 0x1d, 0xdd, 0xdd, 0xc8, + 0x50, 0x9a, 0x50, 0x0, 0xb0, 0xd, 0x8, 0x84, + 0x44, 0x40, 0x0, 0xa1, 0x67, 0x8, 0xdb, 0x88, + 0xe0, 0xb, 0xde, 0xed, 0x98, 0x7d, 0x2, 0xb0, + 0x0, 0x7, 0x60, 0x8, 0x5a, 0x69, 0x50, 0x2d, + 0xde, 0xed, 0xc8, 0x51, 0xdc, 0x0, 0x0, 0x7, + 0x60, 0x8, 0x51, 0xdb, 0x0, 0x0, 0x7, 0x60, + 0x8, 0x6c, 0x6a, 0xb1, 0x0, 0x7, 0x60, 0x8, + 0xe5, 0x0, 0x86, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5834 "場" */ + 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x0, 0xeb, 0xbb, 0xbc, 0xa0, 0x0, 0x85, + 0x0, 0xe6, 0x66, 0x68, 0xa0, 0x3e, 0xfe, 0xd0, + 0xd1, 0x11, 0x14, 0xa0, 0x0, 0x85, 0x0, 0xea, + 0xaa, 0xac, 0xa0, 0x0, 0x85, 0x0, 0x11, 0x11, + 0x11, 0x10, 0x0, 0x85, 0x4d, 0xee, 0xdd, 0xdd, + 0xd5, 0x0, 0x85, 0x10, 0xc4, 0x0, 0x0, 0x0, + 0x0, 0x9d, 0xc9, 0xdd, 0xfc, 0xfd, 0xe0, 0x3c, + 0xc5, 0xb8, 0xa, 0x41, 0xc0, 0xa0, 0x13, 0x0, + 0x20, 0x88, 0xa, 0x40, 0xa0, 0x0, 0x0, 0x1b, + 0x70, 0x7a, 0x0, 0xb0, 0x0, 0x0, 0x3, 0x4, + 0xb0, 0xac, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+584A "塊" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x75, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x75, + 0x0, 0x11, 0x88, 0x11, 0x10, 0x0, 0x75, 0x5, + 0xda, 0xbe, 0xaa, 0xe0, 0x3, 0x98, 0x35, 0x70, + 0x2b, 0x0, 0xd0, 0x19, 0xcb, 0x85, 0xdb, 0xce, + 0xbb, 0xe0, 0x0, 0x75, 0x5, 0x70, 0x58, 0x0, + 0xd0, 0x0, 0x75, 0x5, 0x92, 0x88, 0x22, 0xe0, + 0x0, 0x75, 0x3, 0xaa, 0xee, 0xaa, 0x90, 0x0, + 0x75, 0x0, 0x0, 0xdc, 0x9, 0x10, 0x0, 0x9d, + 0xd1, 0x7, 0x6c, 0x55, 0xa0, 0x3e, 0xa4, 0x0, + 0x2d, 0xc, 0xda, 0xc2, 0x1, 0x0, 0x3, 0xd3, + 0xd, 0x0, 0x26, 0x0, 0x0, 0x2d, 0x30, 0xb, + 0xcc, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5869 "塩" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x76, 0x0, 0x79, 0x0, 0x0, 0x0, 0x0, 0x76, + 0x0, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x76, 0x2, + 0xfd, 0xdd, 0xdd, 0xd3, 0x1, 0x87, 0x1b, 0x60, + 0x0, 0x0, 0x0, 0xb, 0xdd, 0xcc, 0xeb, 0xbb, + 0xbe, 0x30, 0x0, 0x76, 0x0, 0xd0, 0x0, 0x9, + 0x30, 0x0, 0x76, 0x0, 0xdb, 0xbb, 0xbe, 0x30, + 0x0, 0x76, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7a, 0xb7, 0xcc, 0xcc, 0xcc, 0xb0, 0x6, 0xec, + 0x48, 0x35, 0x70, 0xb0, 0xd0, 0x2b, 0x40, 0x8, + 0x35, 0x70, 0xb0, 0xd0, 0x0, 0x0, 0x8, 0x35, + 0x70, 0xb0, 0xd0, 0x0, 0x2, 0xdf, 0xee, 0xed, + 0xfd, 0xf6, + + /* U+5883 "境" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x86, 0x0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x86, + 0x2, 0xcc, 0xcf, 0xcc, 0xc0, 0x0, 0x86, 0x0, + 0xa, 0x0, 0x26, 0x0, 0x3, 0x98, 0x20, 0xc, + 0x20, 0x85, 0x0, 0xb, 0xdd, 0x88, 0xcc, 0xcc, + 0xcc, 0xc4, 0x0, 0x86, 0x0, 0x66, 0x66, 0x66, + 0x40, 0x0, 0x86, 0x0, 0xe2, 0x22, 0x27, 0x90, + 0x0, 0x86, 0x0, 0xea, 0xaa, 0xac, 0x90, 0x0, + 0x86, 0x0, 0xd0, 0x0, 0x5, 0x90, 0x0, 0x8c, + 0xd0, 0xad, 0xda, 0xfa, 0x60, 0x2d, 0xc6, 0x0, + 0xa, 0x50, 0xd0, 0x0, 0x2, 0x0, 0x0, 0x5d, + 0x0, 0xd0, 0x1a, 0x0, 0x0, 0x4c, 0xb2, 0x0, + 0xcc, 0xc6, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, + + /* U+5897 "増" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x0, 0xa5, 0x0, 0xd, 0x30, 0x0, 0x85, + 0x0, 0x4d, 0x0, 0x3b, 0x0, 0x0, 0x85, 0x7, + 0xcf, 0xcc, 0xdd, 0xc3, 0x4, 0xa8, 0x49, 0x30, + 0xc, 0x0, 0xa3, 0x19, 0xcb, 0x89, 0xcb, 0xbf, + 0xbb, 0xe3, 0x0, 0x85, 0x9, 0x30, 0xc, 0x0, + 0xa3, 0x0, 0x85, 0x9, 0xcb, 0xce, 0xbb, 0xe3, + 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x87, 0x71, 0xfc, 0xcc, 0xcc, 0xb0, 0x5, 0xce, + 0x80, 0xd0, 0x0, 0x2, 0xb0, 0x4b, 0x50, 0x0, + 0xfb, 0xbb, 0xbc, 0xb0, 0x0, 0x0, 0x0, 0xe0, + 0x0, 0x2, 0xb0, 0x0, 0x0, 0x0, 0xfb, 0xbb, + 0xbc, 0xb0, + + /* U+589E "增" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x50, 0x6, 0x90, 0x4, 0xa0, 0x0, 0x85, 0x0, + 0xe, 0x20, 0xb2, 0x0, 0x8, 0x50, 0x7b, 0xcb, + 0xbf, 0xb8, 0x1, 0x96, 0x9, 0x53, 0x1b, 0x14, + 0xa0, 0xce, 0xd9, 0x93, 0xb1, 0xb7, 0x4a, 0x0, + 0x85, 0x9, 0x25, 0x3b, 0x62, 0xa0, 0x8, 0x50, + 0x8b, 0xbb, 0xdb, 0xb9, 0x0, 0x85, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x50, 0xd, 0xbb, 0xbb, + 0xf0, 0x0, 0xac, 0xb0, 0xd2, 0x22, 0x2e, 0x1, + 0xd8, 0x20, 0xd, 0x66, 0x66, 0xf0, 0x0, 0x0, + 0x0, 0xd9, 0x99, 0x9f, 0x0, 0x0, 0x0, 0xd, + 0x22, 0x22, 0xe0, + + /* U+58CA "壊" */ + 0x0, 0x93, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, + 0x93, 0x4a, 0xaa, 0xfa, 0xaa, 0xa4, 0x0, 0x93, + 0x12, 0x22, 0xd3, 0x22, 0x21, 0x1, 0xa4, 0x8, + 0x88, 0xe9, 0x88, 0x70, 0xc, 0xed, 0x6c, 0x3c, + 0x3b, 0x63, 0xd0, 0x0, 0x93, 0xc, 0x2c, 0x2a, + 0x52, 0xd0, 0x0, 0x93, 0x6, 0x66, 0xc6, 0x66, + 0x50, 0x0, 0x93, 0x6b, 0xbb, 0xfc, 0xbb, 0xb5, + 0x0, 0xab, 0x90, 0x3d, 0xc6, 0x4, 0x70, 0x1b, + 0xd5, 0x7, 0xf2, 0x1d, 0x8b, 0x10, 0x4, 0x1, + 0xd7, 0xc0, 0x3, 0xe4, 0x0, 0x0, 0x0, 0x0, + 0xd6, 0xa6, 0x2d, 0x92, 0x0, 0x0, 0x0, 0xc7, + 0x10, 0x0, 0x64, + + /* U+58D3 "壓" */ + 0xa, 0xcb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb0, 0xa, + 0x2a, 0x77, 0xb0, 0x1, 0x87, 0x10, 0xa, 0x2d, + 0x77, 0xd0, 0x1, 0x92, 0x80, 0xa, 0x2a, 0x88, + 0xa5, 0xcc, 0xec, 0xc0, 0xa, 0x5a, 0x88, 0xa2, + 0x4, 0xf1, 0x0, 0xb, 0x5c, 0x77, 0xc3, 0xa, + 0x87, 0x0, 0xc, 0x4c, 0x88, 0xc3, 0x5b, 0xc, + 0x10, 0xc, 0x48, 0x4, 0xba, 0xd1, 0x4, 0xd1, + 0xd, 0x13, 0x4, 0x5a, 0x10, 0x0, 0x30, 0x1c, + 0xa, 0xbb, 0xbf, 0xbb, 0xbb, 0x30, 0x58, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x92, 0xab, 0xbb, + 0xbf, 0xbb, 0xbb, 0xb2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+58EB "士" */ + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, + 0x0, 0x0, 0x0, 0x1e, 0xee, 0xee, 0xff, 0xee, + 0xee, 0xe6, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x59, 0x0, 0x0, 0x0, 0x4, 0xdd, 0xdd, + 0xef, 0xdd, 0xdd, 0x90, 0x0, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x0, + + /* U+58F0 "声" */ + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0xcc, + 0xcc, 0xce, 0xdc, 0xcc, 0xcc, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x70, + 0x0, 0x0, 0x1, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xdc, 0xbb, 0xdd, 0xbb, 0xbf, 0x10, 0xd, 0x10, + 0x7, 0x60, 0x0, 0xd1, 0x0, 0xe0, 0x0, 0x76, + 0x0, 0xd, 0x10, 0xf, 0xdd, 0xdd, 0xdd, 0xdd, + 0xf1, 0x3, 0xb0, 0x0, 0x0, 0x0, 0x7, 0x0, + 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+58F2 "売" */ + 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x1, + 0x11, 0x11, 0x87, 0x11, 0x11, 0x10, 0xc, 0xcc, + 0xcc, 0xee, 0xcc, 0xcc, 0xc1, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x0, 0x0, 0x0, 0xad, 0xdd, 0xed, + 0xdd, 0xdb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0x90, 0xa, 0x30, 0x0, 0x0, 0x10, 0x3, 0xa0, + 0x7, 0x20, 0x78, 0x0, 0xe0, 0x2, 0x80, 0x0, + 0x0, 0xa5, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x1, + 0xe0, 0x0, 0xe0, 0x0, 0x71, 0x0, 0x2d, 0x60, + 0x0, 0xe0, 0x0, 0xc1, 0x1c, 0xc4, 0x0, 0x0, + 0xae, 0xde, 0xb0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5909 "変" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0xa, 0xaa, + 0xaa, 0xce, 0xaa, 0xaa, 0xa0, 0x2, 0x22, 0x3e, + 0x22, 0xe3, 0x22, 0x20, 0x0, 0x1b, 0x1d, 0x0, + 0xd2, 0xb1, 0x0, 0x0, 0xa5, 0xd, 0x0, 0xd0, + 0x4d, 0x10, 0x9, 0x90, 0xd, 0x0, 0xd0, 0x5, + 0xb0, 0x1, 0x0, 0xa, 0x20, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0x32, 0x22, 0x10, 0x0, 0x0, + 0x8, 0xfa, 0xaa, 0xad, 0xc0, 0x0, 0x4, 0xd9, + 0x97, 0x0, 0x3d, 0x20, 0x0, 0x6, 0x30, 0x8, + 0xa8, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x49, 0xed, + 0xa4, 0x0, 0x0, 0x19, 0xcd, 0xa4, 0x0, 0x4a, + 0xdd, 0xa2, 0x4, 0x10, 0x0, 0x0, 0x0, 0x1, + 0x40, + + /* U+590F "夏" */ + 0xb, 0xcc, 0xcc, 0xed, 0xcc, 0xcc, 0xb0, 0x0, + 0x59, 0x99, 0xeb, 0x99, 0x95, 0x0, 0x0, 0x87, + 0x22, 0x22, 0x22, 0x78, 0x0, 0x0, 0x8a, 0x77, + 0x77, 0x77, 0xa8, 0x0, 0x0, 0x8c, 0xaa, 0xaa, + 0xaa, 0xc8, 0x0, 0x0, 0x87, 0x11, 0x11, 0x11, + 0x78, 0x0, 0x0, 0x48, 0xbe, 0x88, 0x88, 0x84, + 0x0, 0x0, 0x5, 0xfd, 0xbb, 0xbb, 0xa0, 0x0, + 0x5, 0xc9, 0xb6, 0x0, 0x2c, 0x50, 0x0, 0x18, + 0x10, 0x8, 0xb8, 0xc3, 0x0, 0x0, 0x0, 0x25, + 0x8c, 0xaa, 0xd9, 0x53, 0x10, 0x3c, 0xa7, 0x40, + 0x0, 0x4, 0x8a, 0xd3, + + /* U+5915 "夕" */ + 0x0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x6b, 0x0, 0x0, 0x0, 0x0, 0x1, 0xed, 0xbb, + 0xbb, 0xb3, 0x0, 0xc, 0x73, 0x33, 0x33, 0xe1, + 0x0, 0xb9, 0x0, 0x0, 0x5, 0xa0, 0x1c, 0xa3, + 0x60, 0x0, 0xc, 0x40, 0x77, 0x1, 0xab, 0x10, + 0x6c, 0x0, 0x0, 0x0, 0x6, 0xe6, 0xe2, 0x0, + 0x0, 0x0, 0x0, 0x5f, 0x40, 0x0, 0x0, 0x0, + 0x5, 0xe6, 0x0, 0x0, 0x0, 0x1, 0x9d, 0x30, + 0x0, 0x0, 0x3, 0xae, 0x90, 0x0, 0x0, 0x0, + 0xc, 0x71, 0x0, 0x0, 0x0, 0x0, + + /* U+5916 "外" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x40, 0x0, 0x2c, 0x0, 0x0, 0x0, 0xe, + 0x10, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x3f, 0xcc, + 0xc5, 0x2c, 0x0, 0x0, 0x0, 0x87, 0x11, 0xb4, + 0x2c, 0x0, 0x0, 0x1, 0xe0, 0x0, 0xe0, 0x2e, + 0x50, 0x0, 0x9, 0x92, 0x2, 0xd0, 0x2d, 0xc8, + 0x0, 0xa, 0x3d, 0x68, 0x80, 0x2c, 0xa, 0xa0, + 0x0, 0x0, 0xbf, 0x10, 0x2c, 0x0, 0xb6, 0x0, + 0x0, 0x7a, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x3, + 0xe2, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x2e, 0x40, + 0x0, 0x2c, 0x0, 0x0, 0x6, 0xf6, 0x0, 0x0, + 0x2c, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x2c, + 0x0, 0x0, + + /* U+591A "多" */ + 0x0, 0x0, 0x1d, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0xeb, 0xbb, 0x90, 0x0, 0x0, 0x8d, 0x42, + 0x22, 0xc5, 0x0, 0x1, 0xd8, 0x65, 0x1, 0xb8, + 0x0, 0x0, 0x1, 0x0, 0xab, 0xd5, 0x0, 0x0, + 0x0, 0x1, 0x7d, 0x92, 0xc6, 0x0, 0x0, 0x6c, + 0xd8, 0x11, 0xcf, 0xcc, 0xcc, 0x2, 0x20, 0x6, + 0xd4, 0x0, 0xa, 0x70, 0x0, 0x6c, 0x96, 0x30, + 0x7, 0xb0, 0x0, 0x6, 0x10, 0x2d, 0x7b, 0xa1, + 0x0, 0x0, 0x0, 0x3, 0xae, 0x50, 0x0, 0x1, + 0x36, 0x9d, 0xb6, 0x0, 0x0, 0x0, 0x9b, 0x85, + 0x10, 0x0, 0x0, 0x0, 0x0, + + /* U+591C "夜" */ + 0x0, 0x0, 0x0, 0x71, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x79, 0x0, 0x0, 0x0, 0x2e, 0xee, + 0xfe, 0xee, 0xee, 0xee, 0xe2, 0x0, 0x4, 0xb0, + 0x7, 0x90, 0x0, 0x0, 0x0, 0xd, 0x20, 0x1e, + 0xdc, 0xcc, 0x80, 0x0, 0x7a, 0x0, 0x96, 0x40, + 0x9, 0x50, 0x6, 0xfa, 0x8, 0xf1, 0xa7, 0xd, + 0x0, 0x5d, 0x5a, 0x7c, 0x68, 0x8, 0x88, 0x0, + 0x12, 0x4a, 0x10, 0xa, 0x44, 0xc0, 0x0, 0x0, + 0x4a, 0x0, 0x1, 0xdd, 0x20, 0x0, 0x0, 0x4a, + 0x0, 0x6, 0xde, 0x50, 0x0, 0x0, 0x4a, 0x4, + 0xca, 0x11, 0xcb, 0x30, 0x0, 0x4a, 0x7b, 0x40, + 0x0, 0x5, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5920 "夠" */ + 0x0, 0x9, 0x30, 0x0, 0x73, 0x0, 0x0, 0x0, + 0x4f, 0x99, 0x30, 0xd1, 0x0, 0x0, 0x3, 0xc4, + 0x3c, 0x33, 0xfd, 0xdd, 0xd0, 0xd, 0x72, 0x4b, + 0xa, 0x40, 0x0, 0xd0, 0x0, 0x3d, 0xc2, 0x4c, + 0x0, 0x0, 0xd0, 0x0, 0x2c, 0x80, 0x65, 0xec, + 0xf0, 0xd0, 0x7, 0xc8, 0xc1, 0x11, 0xa0, 0xc0, + 0xd0, 0x2, 0x3d, 0xbb, 0xe1, 0xa0, 0xc0, 0xe0, + 0x7, 0xd3, 0x7, 0x81, 0xa0, 0xc0, 0xe0, 0x7, + 0x1c, 0x6e, 0x11, 0xec, 0xc0, 0xd0, 0x0, 0x2, + 0xf4, 0x1, 0xa0, 0x2, 0xc0, 0x0, 0x5d, 0x50, + 0x0, 0x0, 0x5, 0xa0, 0xc, 0xa2, 0x0, 0x0, + 0x4, 0xde, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5927 "大" */ + 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x86, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa5, 0x0, 0x0, 0x0, 0x1e, 0xee, 0xee, 0xfe, + 0xee, 0xee, 0xe2, 0x0, 0x0, 0x1, 0xfe, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x4, 0xba, 0x60, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x63, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x0, 0xb7, 0x0, 0x0, 0x0, + 0x1, 0xd5, 0x0, 0x2e, 0x30, 0x0, 0x0, 0x1d, + 0x80, 0x0, 0x5, 0xe3, 0x0, 0x7, 0xe7, 0x0, + 0x0, 0x0, 0x5f, 0x80, 0x1a, 0x20, 0x0, 0x0, + 0x0, 0x2, 0xa1, + + /* U+5929 "天" */ + 0x7, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0x60, 0x0, + 0x11, 0x11, 0x97, 0x11, 0x11, 0x0, 0x0, 0x0, + 0x0, 0x86, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x96, 0x0, 0x0, 0x0, 0x1, 0x11, 0x11, 0xa6, + 0x11, 0x11, 0x10, 0xd, 0xdd, 0xdd, 0xff, 0xdd, + 0xdd, 0xd1, 0x0, 0x0, 0x1, 0xfe, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x97, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0x20, 0xd3, 0x0, 0x0, 0x0, + 0x3, 0xe5, 0x0, 0x3e, 0x30, 0x0, 0x0, 0x7e, + 0x40, 0x0, 0x4, 0xe7, 0x0, 0x2e, 0x91, 0x0, + 0x0, 0x0, 0x2a, 0xe3, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, + + /* U+592A "太" */ + 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x96, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa5, 0x0, 0x0, 0x0, 0x1e, 0xee, 0xee, 0xff, + 0xee, 0xee, 0xe2, 0x0, 0x0, 0x0, 0xfe, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x3, 0xc8, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x82, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x1e, 0x10, 0xa7, 0x0, 0x0, 0x0, + 0x0, 0xbb, 0x0, 0x1e, 0x20, 0x0, 0x0, 0xa, + 0xb9, 0xb0, 0x5, 0xe2, 0x0, 0x3, 0xdb, 0x0, + 0x9b, 0x0, 0x7e, 0x50, 0x2e, 0x50, 0x0, 0x9, + 0x30, 0x4, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+592B "夫" */ + 0x0, 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0x1, 0xcc, + 0xcc, 0xee, 0xcc, 0xcc, 0x30, 0x0, 0x22, 0x22, + 0xa8, 0x22, 0x22, 0x0, 0x0, 0x0, 0x0, 0x96, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa6, 0x0, + 0x0, 0x0, 0xd, 0xdd, 0xdd, 0xfe, 0xdd, 0xdd, + 0xd1, 0x1, 0x11, 0x13, 0xfd, 0x21, 0x11, 0x10, + 0x0, 0x0, 0x7, 0xab, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x4e, 0x22, 0xe2, 0x0, 0x0, 0x0, 0x6, + 0xe4, 0x0, 0x4e, 0x40, 0x0, 0x5, 0xcc, 0x20, + 0x0, 0x3, 0xdb, 0x50, 0x2b, 0x40, 0x0, 0x0, + 0x0, 0x5, 0xa2, + + /* U+592E "央" */ + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x7e, + 0xee, 0xff, 0xee, 0xee, 0x0, 0x0, 0x86, 0x0, + 0x59, 0x0, 0xf, 0x0, 0x0, 0x86, 0x0, 0x59, + 0x0, 0xf, 0x0, 0x0, 0x86, 0x0, 0x68, 0x0, + 0xf, 0x0, 0x0, 0x86, 0x0, 0x77, 0x0, 0xf, + 0x0, 0x1e, 0xee, 0xee, 0xff, 0xee, 0xee, 0xe6, + 0x0, 0x0, 0x1, 0xea, 0x60, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x91, 0xd1, 0x0, 0x0, 0x0, 0x0, + 0x9c, 0x0, 0x5d, 0x10, 0x0, 0x0, 0x4c, 0xa0, + 0x0, 0x5, 0xe6, 0x0, 0xd, 0xc5, 0x0, 0x0, + 0x0, 0x29, 0xe6, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5931 "失" */ + 0x0, 0x8, 0x20, 0x86, 0x0, 0x0, 0x0, 0x0, + 0x1f, 0x10, 0x86, 0x0, 0x0, 0x0, 0x0, 0x6c, + 0x0, 0x96, 0x0, 0x0, 0x0, 0x0, 0xce, 0xee, + 0xff, 0xee, 0xee, 0x10, 0x6, 0xd0, 0x0, 0x96, + 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x96, 0x0, + 0x0, 0x0, 0x4, 0x33, 0x33, 0xb7, 0x33, 0x33, + 0x30, 0x2b, 0xbb, 0xbc, 0xff, 0xbb, 0xbb, 0xb2, + 0x0, 0x0, 0x4, 0xdc, 0x40, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x63, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0xba, 0x0, 0x8b, 0x0, 0x0, 0x0, 0x4d, 0x90, + 0x0, 0x9, 0xd4, 0x0, 0x2d, 0xc4, 0x0, 0x0, + 0x0, 0x4c, 0xe3, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x20, + + /* U+5947 "奇" */ + 0x0, 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x3, + 0xaa, 0xaa, 0xcd, 0xaa, 0xaa, 0x80, 0x1, 0x33, + 0x33, 0xe8, 0x33, 0x33, 0x20, 0x0, 0x0, 0x9, + 0xbc, 0xc6, 0x0, 0x0, 0x0, 0x37, 0xda, 0x0, + 0x3a, 0xe7, 0x0, 0x5, 0xb7, 0x20, 0x0, 0x0, + 0x29, 0x30, 0x1d, 0xdd, 0xdd, 0xdd, 0xdd, 0xee, + 0xd6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77, 0x0, + 0x0, 0x9d, 0xcc, 0xce, 0x0, 0x77, 0x0, 0x0, + 0x94, 0x0, 0xe, 0x0, 0x77, 0x0, 0x0, 0x95, + 0x11, 0x1e, 0x0, 0x77, 0x0, 0x0, 0x9c, 0xaa, + 0xa9, 0x0, 0x77, 0x0, 0x0, 0x52, 0x0, 0x0, + 0xdd, 0xd4, 0x0, + + /* U+5951 "契" */ + 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, 0x0, 0xb, + 0xbe, 0xcb, 0x7d, 0xdf, 0xdd, 0xe0, 0x0, 0xa, + 0x30, 0x0, 0x2b, 0x0, 0xe0, 0x8, 0xbe, 0xcb, + 0x30, 0x49, 0x0, 0xd0, 0x0, 0xa, 0x30, 0x0, + 0x95, 0x1, 0xc0, 0x1b, 0xbe, 0xcb, 0x73, 0xd0, + 0x3, 0xa0, 0x0, 0xa, 0x30, 0x6e, 0x31, 0xbd, + 0x60, 0x0, 0x3, 0x10, 0x94, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x1c, + 0xcc, 0xcd, 0xff, 0xdc, 0xcc, 0xc1, 0x0, 0x0, + 0x9, 0x87, 0x90, 0x0, 0x0, 0x0, 0x3, 0xba, + 0x0, 0xab, 0x30, 0x0, 0x2a, 0xdb, 0x40, 0x0, + 0x5, 0xcd, 0xb2, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x30, + + /* U+5957 "套" */ + 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, 0x0, 0x1, + 0x11, 0x15, 0xd1, 0x11, 0x11, 0x10, 0xb, 0xbb, + 0xdf, 0xbb, 0xed, 0xbb, 0xb0, 0x0, 0x3, 0xd3, + 0x0, 0x1b, 0x50, 0x0, 0x1, 0x8e, 0xec, 0xcc, + 0xcc, 0xba, 0x30, 0x2d, 0x56, 0xb4, 0x44, 0x44, + 0x13, 0xc3, 0x0, 0x5, 0xb6, 0x66, 0x66, 0x20, + 0x0, 0x0, 0x5, 0xdb, 0xbb, 0xbb, 0x40, 0x0, + 0x0, 0x5, 0x90, 0x0, 0x0, 0x0, 0x0, 0x1c, + 0xcd, 0xed, 0xcc, 0xcc, 0xcc, 0xc1, 0x0, 0x4, + 0xc2, 0x0, 0xa, 0x40, 0x0, 0x0, 0x9f, 0x88, + 0x9a, 0xbc, 0xf6, 0x0, 0x0, 0x55, 0x43, 0x21, + 0x0, 0xa, 0x10, + + /* U+5973 "女" */ + 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x40, 0x0, 0x0, 0x0, 0x1, 0x11, 0x4f, + 0x21, 0x11, 0x11, 0x10, 0x1d, 0xdd, 0xfe, 0xdd, + 0xdf, 0xed, 0xd2, 0x0, 0x0, 0xe1, 0x0, 0xc, + 0x40, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x1e, 0x0, + 0x0, 0x0, 0xe, 0x30, 0x0, 0x8a, 0x0, 0x0, + 0x0, 0x3d, 0xc5, 0x2, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0x4a, 0xed, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xeb, 0xe7, 0x0, 0x0, 0x0, 0x26, 0xdc, + 0x20, 0x2a, 0xe5, 0x0, 0x1e, 0xea, 0x40, 0x0, + 0x0, 0x4d, 0x80, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, + + /* U+5979 "她" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x58, 0x0, 0x0, 0xa, 0x20, 0x0, 0x0, 0x85, + 0x0, 0x4, 0xa, 0x20, 0x0, 0x0, 0xa3, 0x0, + 0xd, 0xa, 0x20, 0x0, 0x1d, 0xfe, 0xe6, 0xd, + 0xa, 0x7a, 0xf2, 0x0, 0xd0, 0x76, 0xe, 0x8f, + 0xa4, 0xc2, 0x3, 0xa0, 0x97, 0xbf, 0x7b, 0x20, + 0xc1, 0x7, 0x70, 0xb4, 0x4d, 0xa, 0x20, 0xc1, + 0xc, 0x30, 0xd0, 0xd, 0xa, 0x20, 0xc0, 0x5, + 0xb5, 0xa0, 0xd, 0xa, 0x43, 0xe0, 0x0, 0x2e, + 0x70, 0xd, 0x6, 0x3a, 0x71, 0x0, 0x5a, 0xb7, + 0xd, 0x0, 0x0, 0x49, 0x2, 0xd1, 0x16, 0xe, + 0x0, 0x0, 0x76, 0xd, 0x30, 0x0, 0x9, 0xed, + 0xde, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+597D "好" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x94, + 0x0, 0x5d, 0xdd, 0xdd, 0xa0, 0x0, 0xc2, 0x0, + 0x0, 0x0, 0x1d, 0x40, 0x5d, 0xfe, 0xdb, 0x0, + 0x0, 0xb7, 0x0, 0x2, 0xb0, 0x2b, 0x0, 0x9, + 0x80, 0x0, 0x6, 0x70, 0x58, 0x0, 0xb, 0x30, + 0x0, 0xa, 0x30, 0x86, 0xee, 0xef, 0xee, 0xe6, + 0xe, 0x30, 0xd1, 0x0, 0xb, 0x30, 0x0, 0x4, + 0xea, 0xb0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x1f, + 0xb0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x9a, 0xba, + 0x0, 0xb, 0x30, 0x0, 0x9, 0xc0, 0x6, 0x0, + 0xb, 0x30, 0x0, 0x59, 0x0, 0x0, 0x9, 0xdd, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5982 "如" */ + 0x0, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0x90, 0x0, 0x23, 0x33, 0x33, 0x0, 0x76, 0x0, + 0xb, 0xba, 0xaa, 0xd7, 0xdf, 0xed, 0xe5, 0xb2, + 0x0, 0x1d, 0x0, 0xe0, 0xa, 0x4b, 0x20, 0x1, + 0xd0, 0x2c, 0x0, 0xd1, 0xb2, 0x0, 0x1d, 0x6, + 0x80, 0xe, 0xb, 0x20, 0x1, 0xd0, 0xa5, 0x4, + 0xa0, 0xb2, 0x0, 0x1d, 0x5, 0xe5, 0xa4, 0xb, + 0x20, 0x1, 0xd0, 0x2, 0xdf, 0x0, 0xb2, 0x0, + 0x1d, 0x0, 0x1d, 0xd9, 0xb, 0x20, 0x1, 0xd0, + 0x3d, 0x80, 0xb3, 0xbe, 0xdd, 0xed, 0x4f, 0x70, + 0x0, 0xb, 0x20, 0x0, 0x70, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5987 "妇" */ + 0x0, 0x19, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xa0, 0x3, 0x77, 0x77, 0x75, 0x0, 0x68, 0x0, + 0x36, 0x66, 0x67, 0xc0, 0xdf, 0xed, 0xb0, 0x0, + 0x0, 0x1c, 0x0, 0xd1, 0x1b, 0x0, 0x0, 0x1, + 0xc0, 0xd, 0x4, 0x90, 0x0, 0x0, 0x1c, 0x4, + 0x90, 0x76, 0x2e, 0xee, 0xee, 0xc0, 0x98, 0xc, + 0x20, 0x0, 0x0, 0x1c, 0x1, 0xca, 0xd0, 0x0, + 0x0, 0x1, 0xc0, 0x0, 0xcd, 0x10, 0x0, 0x0, + 0x1c, 0x0, 0x5c, 0x7c, 0x0, 0x0, 0x1, 0xc0, + 0x5e, 0x20, 0x28, 0xdd, 0xdd, 0xec, 0x1b, 0x10, + 0x0, 0x0, 0x0, 0x1, 0xc0, + + /* U+59B3 "妳" */ + 0x0, 0x82, 0x0, 0x7, 0x30, 0x0, 0x0, 0x0, + 0xd1, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, 0xe0, + 0x0, 0x2f, 0x88, 0x88, 0x80, 0x8e, 0xfd, 0xe2, + 0x98, 0x5e, 0x55, 0xe0, 0x5, 0x80, 0xc3, 0xd0, + 0xe, 0x5, 0x90, 0x9, 0x40, 0xd2, 0x42, 0xe, + 0x6, 0x20, 0xc, 0x1, 0xc0, 0xd, 0xe, 0xd, + 0x0, 0x2d, 0x5, 0x80, 0x2b, 0xe, 0x8, 0x60, + 0x8, 0xcb, 0x40, 0x77, 0xe, 0x2, 0xb0, 0x0, + 0x7f, 0x10, 0xd1, 0xe, 0x0, 0xd0, 0x0, 0xbb, + 0xd0, 0x20, 0xe, 0x0, 0x40, 0x9, 0xb0, 0x40, + 0x0, 0xe, 0x0, 0x0, 0x6a, 0x0, 0x0, 0x8, + 0xdb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+59B9 "妹" */ + 0x0, 0x84, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, + 0x0, 0x66, 0x7e, 0x66, 0x60, 0x3d, 0xfd, 0xe4, + 0x77, 0x8e, 0x77, 0x70, 0x3, 0xa0, 0xb2, 0x0, + 0xd, 0x0, 0x0, 0x6, 0x70, 0xd0, 0x0, 0xd, + 0x0, 0x0, 0xa, 0x30, 0xe6, 0xdd, 0xef, 0xed, + 0xd5, 0xe, 0x14, 0xa0, 0x0, 0xbf, 0x90, 0x0, + 0x5, 0xdb, 0x50, 0x4, 0xbe, 0xb2, 0x0, 0x0, + 0x3f, 0x70, 0xc, 0x2d, 0x2c, 0x0, 0x0, 0xa8, + 0xd3, 0xb6, 0xd, 0x7, 0xa0, 0x8, 0xc0, 0x9, + 0x70, 0xd, 0x0, 0x84, 0x4a, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, + + /* U+59BB "妻" */ + 0x0, 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0xb, + 0xcc, 0xcc, 0xed, 0xcc, 0xcc, 0xa0, 0x0, 0x0, + 0x0, 0x86, 0x0, 0x0, 0x0, 0x0, 0x9b, 0xbb, + 0xed, 0xbb, 0xc9, 0x0, 0x0, 0x0, 0x0, 0x86, + 0x0, 0x4a, 0x0, 0x3c, 0xcc, 0xcc, 0xed, 0xcc, + 0xde, 0xc3, 0x0, 0x45, 0x55, 0xb9, 0x55, 0x8a, + 0x0, 0x0, 0x44, 0x4a, 0xb4, 0x44, 0x43, 0x0, + 0x2c, 0xcc, 0xcf, 0xdc, 0xcc, 0xcc, 0xc2, 0x0, + 0x1, 0xd2, 0x0, 0xc, 0x40, 0x0, 0x0, 0x8, + 0xd9, 0x53, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x29, + 0xfd, 0xe9, 0x40, 0x0, 0x1c, 0xcc, 0xb7, 0x20, + 0x4, 0x9d, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+59C9 "姉" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0xd0, + 0x0, 0x0, 0xd, 0x0, 0x0, 0x2, 0xb0, 0x4, + 0xbb, 0xbf, 0xbb, 0xb3, 0x8e, 0xfd, 0xe3, 0x33, + 0x4e, 0x33, 0x31, 0x7, 0x60, 0xd0, 0x0, 0xd, + 0x0, 0x0, 0xa, 0x30, 0xd1, 0xee, 0xef, 0xee, + 0xc0, 0xd, 0x2, 0xb1, 0xd0, 0xd, 0x0, 0xe0, + 0x1d, 0x6, 0x71, 0xd0, 0xd, 0x0, 0xe0, 0x7, + 0xbc, 0x21, 0xd0, 0xd, 0x0, 0xe0, 0x0, 0x7f, + 0x11, 0xd0, 0xd, 0x0, 0xe0, 0x0, 0xc8, 0xd3, + 0xd0, 0xd, 0x3d, 0xb0, 0xa, 0x90, 0x40, 0x10, + 0xd, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0xd, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+59CB "始" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb2, 0x0, 0x0, 0xd3, 0x0, 0x0, 0x0, 0xd0, + 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, 0xd0, 0x0, + 0xc, 0x40, 0x80, 0x0, 0x8e, 0xfd, 0xe2, 0x6a, + 0x0, 0x5a, 0x0, 0x6, 0x70, 0xc2, 0xe4, 0x34, + 0x5e, 0x40, 0x9, 0x30, 0xd8, 0xdc, 0xa9, 0x87, + 0xc0, 0xc, 0x1, 0xc0, 0x0, 0x0, 0x0, 0x30, + 0x2e, 0x16, 0x70, 0xac, 0xcc, 0xcc, 0x20, 0x7, + 0xed, 0x30, 0xd1, 0x11, 0x1b, 0x30, 0x0, 0x5f, + 0x30, 0xd0, 0x0, 0xa, 0x30, 0x0, 0xb9, 0xe1, + 0xd0, 0x0, 0xa, 0x30, 0x7, 0xa0, 0x63, 0xd2, + 0x22, 0x2b, 0x30, 0x58, 0x0, 0x0, 0xda, 0xaa, + 0xae, 0x30, + + /* U+59D0 "姐" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa3, + 0x0, 0xde, 0xee, 0xef, 0x10, 0x0, 0xc1, 0x0, + 0xd0, 0x0, 0xd, 0x10, 0x3d, 0xfd, 0xe3, 0xd0, + 0x0, 0xd, 0x10, 0x2, 0xb0, 0xb1, 0xdb, 0xbb, + 0xbf, 0x10, 0x5, 0x80, 0xd0, 0xd2, 0x22, 0x2e, + 0x10, 0x8, 0x50, 0xd0, 0xd0, 0x0, 0xd, 0x10, + 0xc, 0x23, 0xa0, 0xd0, 0x0, 0xd, 0x10, 0x9, + 0xb8, 0x60, 0xde, 0xdd, 0xdf, 0x10, 0x0, 0x7f, + 0x30, 0xd0, 0x0, 0xd, 0x10, 0x0, 0x6e, 0xc0, + 0xd0, 0x0, 0xd, 0x10, 0x2, 0xe1, 0x71, 0xd0, + 0x0, 0xd, 0x10, 0x1e, 0x40, 0x3d, 0xdd, 0xdd, + 0xdd, 0xd4, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+59D4 "委" */ + 0x0, 0x0, 0x12, 0x34, 0x68, 0xb7, 0x0, 0x1, + 0xcb, 0xa9, 0xbb, 0x54, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x68, 0x0, 0x0, 0x0, 0xd, 0xdd, 0xdd, + 0xee, 0xdd, 0xdd, 0xd5, 0x0, 0x0, 0x5c, 0x89, + 0xa8, 0x0, 0x0, 0x0, 0x2a, 0xa0, 0x68, 0x7, + 0xd6, 0x0, 0x1c, 0xb4, 0x2, 0xa7, 0x0, 0x18, + 0xe5, 0x2, 0x0, 0xc, 0x40, 0x0, 0x0, 0x0, + 0x1d, 0xdd, 0xfe, 0xdd, 0xde, 0xed, 0xd7, 0x0, + 0x5, 0xc0, 0x0, 0x1e, 0x20, 0x0, 0x0, 0xb, + 0xda, 0x64, 0xd6, 0x0, 0x0, 0x0, 0x0, 0x18, + 0xfd, 0xdb, 0x62, 0x0, 0x9, 0xcd, 0xc8, 0x20, + 0x2, 0x7c, 0xc1, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5A18 "娘" */ + 0x0, 0x43, 0x0, 0x0, 0x52, 0x0, 0x0, 0x0, + 0xa3, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0xc1, + 0x0, 0xed, 0xdd, 0xdf, 0x30, 0x2b, 0xfb, 0xb0, + 0xe0, 0x0, 0xb, 0x30, 0x2, 0xa0, 0xd0, 0xec, + 0xcc, 0xcf, 0x30, 0x6, 0x70, 0xd0, 0xe0, 0x0, + 0xb, 0x30, 0xa, 0x42, 0xb0, 0xe0, 0x0, 0xb, + 0x30, 0xe, 0x6, 0x80, 0xec, 0xee, 0xcc, 0x20, + 0xb, 0x7a, 0x30, 0xe0, 0x3a, 0x3, 0x70, 0x0, + 0xaf, 0x0, 0xe0, 0xd, 0x8c, 0x20, 0x0, 0x8e, + 0x70, 0xe0, 0x3, 0xe1, 0x0, 0x4, 0xd1, 0xb1, + 0xf3, 0x83, 0x7c, 0x20, 0x3d, 0x20, 0x3, 0xfa, + 0x40, 0x5, 0xd0, 0x1, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+5A5A "婚" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x76, 0x0, 0x1, 0x36, 0x9e, 0x30, 0x0, 0xa4, + 0x0, 0xcb, 0x9d, 0x62, 0x0, 0x0, 0xc1, 0x0, + 0xc1, 0x9, 0x30, 0x0, 0x2d, 0xfe, 0xe3, 0xcc, + 0xcd, 0xdc, 0xc3, 0x2, 0xb0, 0xa2, 0xc1, 0x1, + 0xc0, 0x0, 0x6, 0x70, 0xd1, 0xd6, 0x83, 0x96, + 0x45, 0x9, 0x30, 0xe3, 0xb7, 0x40, 0xa, 0xd2, + 0xe, 0x44, 0xa0, 0x6a, 0xaa, 0xaa, 0x20, 0x7, + 0xfc, 0x60, 0x95, 0x11, 0x1b, 0x30, 0x0, 0x4f, + 0x60, 0x95, 0x22, 0x2b, 0x30, 0x0, 0x7b, 0xe4, + 0x9b, 0x99, 0x9e, 0x30, 0x4, 0xd0, 0x34, 0x94, + 0x0, 0xb, 0x30, 0x2b, 0x10, 0x0, 0x9c, 0xbb, + 0xbe, 0x30, + + /* U+5A66 "婦" */ + 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc1, 0x0, 0xab, 0xbb, 0xbe, 0x30, 0x0, 0xd0, + 0x0, 0x8b, 0xbb, 0xbe, 0x30, 0x4f, 0xff, 0xe0, + 0x0, 0x0, 0xb, 0x30, 0x3, 0x90, 0xc0, 0xbb, + 0xbb, 0xbd, 0x30, 0x6, 0x61, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x9, 0x33, 0xa8, 0xba, 0xaf, 0xaa, + 0xe1, 0xd, 0x7, 0x68, 0x30, 0xe, 0x0, 0xb1, + 0xa, 0x8b, 0x20, 0xec, 0xcf, 0xce, 0x60, 0x0, + 0x8f, 0x0, 0xd0, 0xe, 0x7, 0x60, 0x0, 0xba, + 0xb0, 0xd0, 0xe, 0x7, 0x60, 0x8, 0xa0, 0x72, + 0xd0, 0xe, 0x5d, 0x30, 0x39, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x0, + + /* U+5A92 "媒" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa2, 0x0, 0x1c, 0x0, 0xe, 0x0, 0x0, 0xc1, + 0x0, 0x1c, 0x0, 0xe, 0x0, 0x0, 0xd0, 0x7, + 0xdf, 0xdd, 0xdf, 0xd3, 0x2b, 0xfb, 0xb0, 0x1c, + 0x0, 0xe, 0x0, 0x4, 0xa1, 0xd0, 0x1f, 0xbb, + 0xbe, 0x0, 0x7, 0x60, 0xd0, 0x1c, 0x0, 0xe, + 0x0, 0xa, 0x32, 0xb0, 0x1d, 0xce, 0xcd, 0x0, + 0xd, 0x6, 0x70, 0x0, 0xe, 0x0, 0x0, 0xa, + 0xab, 0x36, 0xdd, 0xdf, 0xdd, 0xd2, 0x0, 0x8f, + 0x10, 0x1, 0xcf, 0xb0, 0x0, 0x0, 0xbb, 0xc0, + 0x1c, 0x3e, 0x5b, 0x0, 0x8, 0xb0, 0x57, 0xd4, + 0xe, 0x6, 0xd3, 0x39, 0x0, 0x6, 0x10, 0xe, + 0x0, 0x41, + + /* U+5ABD "媽" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, + 0x2, 0xed, 0xdf, 0xdd, 0xc0, 0x0, 0xd0, 0x2, + 0x90, 0xe, 0x0, 0x0, 0x3e, 0xfd, 0xd4, 0xec, + 0xcf, 0xcc, 0x70, 0x5, 0x80, 0xc3, 0x90, 0xe, + 0x0, 0x0, 0x8, 0x40, 0xd2, 0xec, 0xcf, 0xcc, + 0x70, 0xc, 0x11, 0xc2, 0x90, 0xe, 0x0, 0x0, + 0xe, 0x16, 0x82, 0xec, 0xcf, 0xcc, 0xc1, 0x6, + 0xdc, 0x30, 0x10, 0x1, 0x40, 0xd0, 0x0, 0x6f, + 0x14, 0x69, 0x19, 0x64, 0xd0, 0x0, 0xba, 0xc8, + 0x3b, 0xb, 0x4, 0xd0, 0x8, 0xb0, 0x3c, 0x9, + 0x2, 0x2, 0xc0, 0x4a, 0x0, 0x1, 0x0, 0x0, + 0xcd, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5ACC "嫌" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb1, 0x0, 0x92, 0x0, 0x78, 0x0, 0x0, 0xd0, + 0x0, 0x3b, 0x3, 0xd1, 0x0, 0x0, 0xd0, 0x7, + 0xac, 0xae, 0xca, 0xa3, 0x3e, 0xfe, 0xb1, 0x1d, + 0x1c, 0x31, 0x10, 0x4, 0x81, 0xa4, 0xcf, 0xcf, + 0xcc, 0x80, 0x8, 0x43, 0x80, 0xd, 0xb, 0x10, + 0xb0, 0xb, 0x16, 0x6b, 0xcf, 0xcf, 0xcc, 0xf6, + 0xd, 0x9, 0x20, 0xd, 0xb, 0x10, 0xb0, 0xa, + 0x9c, 0x5, 0xbf, 0xbe, 0xcc, 0xb0, 0x0, 0x9d, + 0x0, 0x7f, 0xb, 0xd1, 0x0, 0x0, 0xc9, 0xb3, + 0xbd, 0xb, 0x6c, 0x0, 0x9, 0x80, 0x8d, 0x2d, + 0xb, 0x16, 0xd2, 0x48, 0x0, 0x33, 0xd, 0xb, + 0x10, 0x32, + + /* U+5B09 "嬉" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa3, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0xc1, + 0xa, 0xbb, 0xbf, 0xbb, 0xb6, 0x0, 0xd0, 0x0, + 0x0, 0x2d, 0x0, 0x0, 0x3d, 0xfd, 0xe4, 0xaa, + 0xaa, 0xaa, 0xa1, 0x3, 0x90, 0xc0, 0xaa, 0xaa, + 0xaa, 0x70, 0x6, 0x61, 0xb0, 0xe0, 0x0, 0x3, + 0xb0, 0x9, 0x33, 0xa0, 0xea, 0xaa, 0xab, 0xa0, + 0xd, 0x6, 0x70, 0x1b, 0x0, 0x2b, 0x0, 0xb, + 0x8a, 0x58, 0x8e, 0x98, 0xbb, 0x87, 0x0, 0xaf, + 0x13, 0x33, 0x33, 0x33, 0x33, 0x0, 0x8e, 0x80, + 0xfb, 0xbb, 0xbb, 0xe0, 0x3, 0xc1, 0xb1, 0xe0, + 0x0, 0x0, 0xe0, 0x1b, 0x10, 0x0, 0xfb, 0xbb, + 0xbb, 0xd0, + + /* U+5B50 "子" */ + 0x0, 0x9e, 0xee, 0xee, 0xee, 0xee, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x5, 0xd4, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xab, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x3e, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, + 0x0, 0x0, 0x0, 0xb, 0xbb, 0xbb, 0xce, 0xbb, + 0xbb, 0xb5, 0x3, 0x33, 0x33, 0x6c, 0x33, 0x33, + 0x31, 0x0, 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4b, 0x0, 0x0, 0x0, 0x0, 0x0, 0xde, + 0xe6, 0x0, 0x0, 0x0, + + /* U+5B57 "字" */ + 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x80, 0x0, 0x0, 0xd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xde, 0xd0, 0xd1, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0xa, 0x1a, 0xee, 0xee, 0xee, 0x81, + 0xa0, 0x0, 0x0, 0x0, 0x7, 0xe3, 0x0, 0x0, + 0x0, 0x0, 0x1a, 0xb1, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x90, 0x0, 0x0, 0xe, 0xee, 0xee, 0xff, + 0xee, 0xee, 0xe0, 0x0, 0x0, 0x7, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x9e, 0xe4, 0x0, 0x0, 0x0, + + /* U+5B58 "存" */ + 0x0, 0x0, 0x7, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0x1e, 0xee, + 0xef, 0xee, 0xee, 0xee, 0xe1, 0x0, 0x0, 0xd3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xa0, 0x11, + 0x11, 0x12, 0x0, 0x0, 0x2e, 0x11, 0xbb, 0xbb, + 0xdf, 0x30, 0x2, 0xea, 0x0, 0x0, 0x7, 0xb2, + 0x0, 0x2e, 0xb9, 0x0, 0x0, 0x6a, 0x0, 0x0, + 0x24, 0x49, 0x4e, 0xee, 0xef, 0xee, 0xe5, 0x0, + 0x49, 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, 0x49, + 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, 0x49, 0x0, + 0x0, 0x68, 0x0, 0x0, 0x0, 0x49, 0x0, 0x8d, + 0xe5, 0x0, 0x0, + + /* U+5B63 "季" */ + 0x0, 0x0, 0x12, 0x35, 0x79, 0xc4, 0x0, 0x1, + 0xcb, 0xba, 0xcb, 0x53, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x76, 0x0, 0x0, 0x0, 0x2d, 0xdd, 0xdd, + 0xee, 0xdd, 0xdd, 0xd2, 0x0, 0x0, 0x4c, 0xa9, + 0xd4, 0x0, 0x0, 0x0, 0x7, 0xc1, 0x76, 0x2c, + 0x70, 0x0, 0x6, 0xd8, 0x0, 0x44, 0x0, 0x7d, + 0x70, 0x28, 0x1a, 0xcc, 0xcc, 0xef, 0x51, 0x81, + 0x0, 0x0, 0x0, 0x3a, 0x71, 0x0, 0x0, 0x2d, + 0xdd, 0xdd, 0xee, 0xdd, 0xdd, 0xd2, 0x0, 0x0, + 0x0, 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9c, 0xd4, + 0x0, 0x0, 0x0, + + /* U+5B66 "学" */ + 0x0, 0x20, 0x0, 0x70, 0x0, 0x4, 0x0, 0x0, + 0x6b, 0x0, 0x87, 0x0, 0x89, 0x0, 0x2, 0x2c, + 0x52, 0x4c, 0x24, 0xe3, 0x20, 0xd, 0xba, 0xaa, + 0xaa, 0xaa, 0xaa, 0xf0, 0xd, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe0, 0x7, 0xa, 0xdd, 0xdd, 0xdf, + 0xa0, 0x80, 0x0, 0x0, 0x0, 0x6, 0xd8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7a, 0x10, 0x0, 0x0, + 0x2e, 0xee, 0xee, 0xff, 0xee, 0xee, 0xe3, 0x0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdd, 0xd3, + 0x0, 0x0, 0x0, + + /* U+5B69 "孩" */ + 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0xc, + 0xdd, 0xd9, 0x0, 0xa, 0x60, 0x0, 0x0, 0x0, + 0xb4, 0xdd, 0xde, 0xed, 0xd8, 0x0, 0x4, 0x90, + 0x0, 0xa4, 0x0, 0x0, 0x0, 0xd, 0x10, 0x4, + 0xb0, 0x9, 0x0, 0x0, 0xe, 0x0, 0x3d, 0x65, + 0xa7, 0x0, 0x0, 0xe, 0x46, 0x79, 0x8d, 0xa0, + 0x10, 0x5, 0xaf, 0xa4, 0x0, 0x9b, 0x4, 0xc0, + 0x1a, 0x5e, 0x0, 0x3c, 0x80, 0x1d, 0x20, 0x0, + 0xe, 0x0, 0xb3, 0x2, 0xd4, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x5d, 0xba, 0x0, 0x0, 0xe, 0x0, + 0x4b, 0xb1, 0x8, 0xb0, 0xa, 0xd9, 0x8, 0xb4, + 0x0, 0x0, 0x84, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5B6B "孫" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x47, 0x90, 0x8, + 0xcc, 0xd6, 0x9c, 0xdd, 0x85, 0x10, 0x0, 0x0, + 0xd1, 0x0, 0xa5, 0x1, 0x0, 0x0, 0x7, 0x70, + 0x8, 0x60, 0x5c, 0x0, 0x0, 0x1c, 0x0, 0xae, + 0xab, 0xc0, 0x0, 0x0, 0x2b, 0x0, 0x43, 0x8b, + 0x7, 0x10, 0x0, 0x2c, 0x66, 0x9, 0x90, 0x5, + 0xa0, 0x5, 0xbe, 0x72, 0xdf, 0xce, 0xba, 0xc4, + 0x9, 0x5b, 0x0, 0x32, 0xd, 0x3, 0x23, 0x0, + 0x2b, 0x0, 0x68, 0xd, 0x8, 0x70, 0x0, 0x2b, + 0x1, 0xd1, 0xd, 0x0, 0xc2, 0x0, 0x2b, 0xc, + 0x50, 0xd, 0x0, 0x4a, 0x5, 0xc8, 0x2, 0x3, + 0xcb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5B78 "學" */ + 0x0, 0x1, 0x40, 0x3, 0x10, 0x0, 0x0, 0x0, + 0xc8, 0x52, 0xcc, 0xa, 0xae, 0x40, 0x0, 0xea, + 0xa6, 0x55, 0x4a, 0xae, 0x30, 0x0, 0xd3, 0x33, + 0xab, 0x13, 0x3d, 0x10, 0x0, 0xc7, 0x67, 0xaa, + 0x46, 0x6f, 0x0, 0x9, 0xec, 0xbc, 0xbb, 0xcb, + 0xbf, 0xb1, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd1, 0x9, 0x7, 0xbb, 0xbb, 0xcf, 0x70, 0xa1, + 0x0, 0x0, 0x0, 0x19, 0x93, 0x0, 0x0, 0xb, + 0xbb, 0xbb, 0xce, 0xbb, 0xbb, 0xb4, 0x1, 0x11, + 0x11, 0x69, 0x11, 0x11, 0x10, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4c, 0xd5, + 0x0, 0x0, 0x0, + + /* U+5B83 "它" */ + 0x0, 0x0, 0xb, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x90, 0x0, 0x0, 0xce, 0xee, 0xee, 0xfe, + 0xee, 0xec, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x1d, + 0xd1, 0x30, 0x0, 0x0, 0x0, 0x1d, 0x0, 0xe1, + 0x0, 0x0, 0x13, 0x0, 0x0, 0xe1, 0x0, 0x4a, + 0xe8, 0x0, 0x0, 0xe5, 0x9e, 0xb5, 0x0, 0x0, + 0x0, 0xe9, 0x40, 0x0, 0x0, 0x0, 0x0, 0xe1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0x59, 0x0, 0xd3, 0x0, 0x0, 0x0, 0xa6, + 0x0, 0x6e, 0xee, 0xee, 0xee, 0xb1, + + /* U+5B85 "宅" */ + 0x0, 0x0, 0x0, 0x71, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x89, 0x0, 0x0, 0x0, 0xd, 0xed, + 0xdd, 0xdd, 0xdd, 0xde, 0xe0, 0xd, 0x10, 0x0, + 0x0, 0x3, 0x1, 0xe0, 0xc, 0x10, 0x3, 0x6a, + 0xec, 0x41, 0xc0, 0x0, 0xad, 0xdb, 0xf4, 0x0, + 0x0, 0x0, 0x0, 0x10, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xe4, 0x57, 0x9b, 0xd1, + 0x29, 0xbc, 0xed, 0xfa, 0x86, 0x42, 0x0, 0x15, + 0x31, 0x1, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, + 0xf0, 0x0, 0x2, 0xd0, 0x0, 0x0, 0x0, 0xaf, + 0xee, 0xee, 0x60, + + /* U+5B87 "宇" */ + 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa6, 0x0, 0x0, 0x0, 0xfd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdf, 0xe, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0xe1, 0xdd, 0xdd, 0xdd, 0xdd, 0xf, + 0x0, 0x0, 0x0, 0x79, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0x80, 0x0, 0x0, 0x3, 0x33, 0x33, + 0x8a, 0x33, 0x33, 0x30, 0xaa, 0xaa, 0xad, 0xda, + 0xaa, 0xaa, 0x0, 0x0, 0x0, 0x68, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, 0xc, + 0xee, 0x40, 0x0, 0x0, 0x0, + + /* U+5B88 "守" */ + 0x0, 0x0, 0x0, 0x81, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x69, 0x0, 0x0, 0x0, 0xd, 0xee, + 0xee, 0xee, 0xee, 0xee, 0xc0, 0xd, 0x10, 0x0, + 0x0, 0x12, 0x3, 0xc0, 0xa, 0x10, 0x0, 0x0, + 0x68, 0x2, 0x90, 0x0, 0x0, 0x0, 0x0, 0x69, + 0x0, 0x0, 0x2d, 0xdd, 0xdd, 0xdd, 0xef, 0xdd, + 0xd2, 0x0, 0x2, 0x0, 0x0, 0x68, 0x0, 0x0, + 0x0, 0x1d, 0x30, 0x0, 0x68, 0x0, 0x0, 0x0, + 0x2, 0xd1, 0x0, 0x68, 0x0, 0x0, 0x0, 0x0, + 0x65, 0x0, 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, 0x0, 0xde, + 0xd4, 0x0, 0x0, + + /* U+5B89 "安" */ + 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb6, 0x0, 0x0, 0x0, 0xae, 0xee, 0xee, + 0xee, 0xee, 0xea, 0xa, 0x40, 0x1, 0x50, 0x0, + 0x4, 0xa0, 0x83, 0x0, 0x89, 0x0, 0x0, 0x38, + 0x0, 0x0, 0x1e, 0x20, 0x0, 0x0, 0x0, 0xdd, + 0xdf, 0xed, 0xdd, 0xfe, 0xdd, 0x0, 0x3, 0xe0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0xd8, 0x0, 0xa, + 0x80, 0x0, 0x0, 0x5, 0xbd, 0x88, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x2e, 0xfc, 0x40, 0x0, 0x0, + 0x2, 0x8e, 0x60, 0x5d, 0xd4, 0x0, 0x6e, 0xc7, + 0x10, 0x0, 0x5, 0xe6, 0x1, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5B8C "完" */ + 0x0, 0x0, 0x0, 0x91, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x98, 0x0, 0x0, 0x0, 0xd, 0xee, + 0xee, 0xee, 0xee, 0xee, 0xc0, 0xd, 0x10, 0x0, + 0x0, 0x0, 0x2, 0xc0, 0xd, 0x1b, 0xdd, 0xdd, + 0xdd, 0xa2, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0xee, 0xef, 0xee, 0xfe, 0xee, 0xe2, + 0x0, 0x0, 0x77, 0x0, 0xd1, 0x0, 0x0, 0x0, + 0x0, 0xa5, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x1, + 0xe0, 0x0, 0xd1, 0x0, 0x53, 0x0, 0x2d, 0x60, + 0x0, 0xd1, 0x0, 0x94, 0x2c, 0xc4, 0x0, 0x0, + 0x9e, 0xde, 0xd0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5B98 "官" */ + 0x0, 0x0, 0x4, 0x30, 0x0, 0x0, 0x22, 0x22, + 0x27, 0xb2, 0x22, 0x22, 0xec, 0xbb, 0xbb, 0xbb, + 0xbb, 0xce, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x1e, + 0x42, 0xfd, 0xdd, 0xdd, 0xdf, 0x14, 0x2, 0xc0, + 0x0, 0x0, 0xd, 0x10, 0x2, 0xfb, 0xbb, 0xbb, + 0xbf, 0x10, 0x2, 0xd1, 0x11, 0x11, 0x11, 0x0, + 0x2, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xfd, + 0xdd, 0xdd, 0xde, 0x90, 0x2, 0xc0, 0x0, 0x0, + 0x5, 0x90, 0x2, 0xd3, 0x33, 0x33, 0x38, 0x90, + 0x2, 0xea, 0xaa, 0xaa, 0xac, 0x80, + + /* U+5B99 "宙" */ + 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x40, 0x0, 0x0, 0xee, 0xee, 0xee, 0xee, + 0xee, 0xed, 0xe0, 0x0, 0xb, 0x10, 0x0, 0x1d, + 0xc0, 0x0, 0xd, 0x10, 0x0, 0x1b, 0x9, 0xbb, + 0xbf, 0xbb, 0xbb, 0x90, 0xc, 0x32, 0x2d, 0x42, + 0x24, 0xd0, 0xc, 0x0, 0xd, 0x10, 0x1, 0xd0, + 0xc, 0xcb, 0xbf, 0xcb, 0xbc, 0xd0, 0xc, 0x10, + 0xd, 0x20, 0x2, 0xd0, 0xc, 0x0, 0xd, 0x10, + 0x1, 0xd0, 0xc, 0xbb, 0xbf, 0xbb, 0xbb, 0xd0, + 0xc, 0x32, 0x22, 0x22, 0x24, 0xd0, + + /* U+5B9A "定" */ + 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc4, 0x0, 0x0, 0x0, 0xd, 0xee, + 0xee, 0xee, 0xee, 0xee, 0xd0, 0xd, 0x10, 0x0, + 0x0, 0x0, 0x1, 0xd0, 0xd, 0x13, 0x33, 0x33, + 0x33, 0x21, 0xd0, 0x0, 0x1b, 0xbb, 0xec, 0xbb, + 0xa0, 0x0, 0x0, 0x1, 0x0, 0xb3, 0x0, 0x0, + 0x0, 0x0, 0x1e, 0x0, 0xb3, 0x0, 0x0, 0x0, + 0x0, 0x5b, 0x0, 0xbe, 0xee, 0xe6, 0x0, 0x0, + 0x9f, 0x10, 0xb3, 0x0, 0x0, 0x0, 0x0, 0xd6, + 0xb0, 0xb3, 0x0, 0x0, 0x0, 0x7, 0x90, 0x7d, + 0xd4, 0x0, 0x0, 0x0, 0x3d, 0x0, 0x2, 0x9d, + 0xef, 0xee, 0xf4, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5B9E "实" */ + 0x0, 0x0, 0x7, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7a, 0x0, 0x0, 0x0, 0xae, 0xdd, 0xdd, + 0xdd, 0xdd, 0xeb, 0xa, 0x33, 0x30, 0xa, 0x0, + 0x3, 0xb0, 0x82, 0x2c, 0x50, 0xf0, 0x0, 0x28, + 0x0, 0x10, 0x18, 0xe, 0x0, 0x0, 0x0, 0x9, + 0xb1, 0x2, 0xd0, 0x0, 0x0, 0x0, 0x4, 0x60, + 0x5a, 0x0, 0x0, 0x0, 0xbb, 0xbb, 0xbd, 0xeb, + 0xbb, 0xbb, 0x0, 0x0, 0x4, 0xe2, 0x51, 0x0, + 0x0, 0x0, 0x4, 0xd4, 0x1a, 0xd6, 0x0, 0x1, + 0x5b, 0xc3, 0x0, 0x1, 0x9d, 0x40, 0x79, 0x40, + 0x0, 0x0, 0x0, 0x38, 0x0, + + /* U+5B9F "実" */ + 0x0, 0x0, 0x0, 0x51, 0x0, 0x0, 0x0, 0x1, + 0x11, 0x11, 0x89, 0x11, 0x11, 0x10, 0xe, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbc, 0xd0, 0xe, 0x0, 0x0, + 0x75, 0x0, 0x1, 0xd0, 0x7, 0x9c, 0xcc, 0xee, + 0xcc, 0xcb, 0x70, 0x0, 0x0, 0x0, 0x86, 0x0, + 0x0, 0x0, 0x0, 0x6c, 0xcc, 0xee, 0xcc, 0xc7, + 0x0, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, + 0x1a, 0xaa, 0xaa, 0xeb, 0xaa, 0xaa, 0xa2, 0x2, + 0x22, 0x2a, 0x9b, 0x72, 0x22, 0x20, 0x0, 0x0, + 0x9b, 0x1, 0xd5, 0x0, 0x0, 0x2, 0x7d, 0x70, + 0x0, 0x1b, 0xc5, 0x10, 0xb, 0x61, 0x0, 0x0, + 0x0, 0x39, 0xc1, + + /* U+5BA2 "客" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x9, 0xaa, + 0xaa, 0xce, 0xaa, 0xaa, 0x90, 0xe, 0x33, 0x37, + 0x33, 0x33, 0x34, 0xd0, 0xd, 0x0, 0x8c, 0x0, + 0x0, 0x1, 0xc0, 0x0, 0x6, 0xfb, 0xbb, 0xbf, + 0x60, 0x0, 0x1, 0xbb, 0xc8, 0x0, 0x99, 0x0, + 0x0, 0x5, 0x60, 0xa, 0xcc, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x4b, 0xcc, 0xb5, 0x0, 0x0, 0x15, + 0x9d, 0x92, 0x0, 0x39, 0xec, 0x82, 0x29, 0x5e, + 0xcc, 0xcc, 0xcd, 0xe3, 0x60, 0x0, 0xe, 0x0, + 0x0, 0x1, 0xd0, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x1, 0xd0, 0x0, 0x0, 0xe, 0xcc, 0xcc, 0xcd, + 0xd0, 0x0, + + /* U+5BA4 "室" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0xa, 0xaa, + 0xaa, 0xce, 0xaa, 0xaa, 0xa0, 0xe, 0x22, 0x22, + 0x22, 0x22, 0x22, 0xf0, 0xa, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0x0, 0x6b, 0xbf, 0xdb, 0xbb, + 0xb7, 0x0, 0x0, 0x0, 0x7a, 0x0, 0x2b, 0x0, + 0x0, 0x0, 0x9, 0xa2, 0x34, 0x5c, 0xc1, 0x0, + 0x0, 0x7d, 0xba, 0xa9, 0x65, 0x6a, 0x0, 0x0, + 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0xcd, + 0xdd, 0xee, 0xdd, 0xdc, 0x0, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x87, + 0x0, 0x0, 0x0, 0x2d, 0xdd, 0xdd, 0xee, 0xdd, + 0xdd, 0xd2, + + /* U+5BB3 "害" */ + 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, 0x0, 0x1, + 0x22, 0x22, 0x99, 0x22, 0x22, 0x10, 0xc, 0xcb, + 0xbb, 0xdd, 0xbb, 0xbb, 0xd0, 0xc, 0x20, 0x0, + 0x88, 0x0, 0x2, 0xd0, 0x3, 0x39, 0x99, 0xcc, + 0x99, 0x93, 0x30, 0x0, 0x8a, 0xaa, 0xdd, 0xaa, + 0xa9, 0x0, 0x0, 0x1, 0x11, 0x88, 0x11, 0x11, + 0x0, 0xc, 0xcc, 0xcc, 0xee, 0xcc, 0xcc, 0xc0, + 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0x0, + 0x4d, 0xcc, 0xdd, 0xcc, 0xd6, 0x0, 0x0, 0x49, + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x49, 0x0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x4e, 0xcc, 0xcc, + 0xcc, 0xd7, 0x0, + + /* U+5BB5 "宵" */ + 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x23, 0x33, + 0x3c, 0x73, 0x33, 0x31, 0xea, 0xaa, 0xad, 0xba, + 0xaa, 0xc8, 0xe0, 0x90, 0xc, 0x10, 0x74, 0x68, + 0x50, 0x58, 0xc, 0x13, 0xc0, 0x23, 0x3, 0x7b, + 0x7e, 0x8b, 0x97, 0x0, 0x6, 0x93, 0x33, 0x33, + 0x3e, 0x10, 0x6, 0xdb, 0xbb, 0xbb, 0xbf, 0x10, + 0x6, 0x80, 0x0, 0x0, 0xd, 0x10, 0x6, 0xda, + 0xaa, 0xaa, 0xaf, 0x10, 0x6, 0x81, 0x11, 0x11, + 0x1d, 0x10, 0x6, 0x70, 0x0, 0x0, 0xd, 0x10, + 0x6, 0x70, 0x0, 0xb, 0xcc, 0x0, + + /* U+5BB6 "家" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x9, 0xaa, + 0xaa, 0xed, 0xaa, 0xaa, 0x90, 0xe, 0x22, 0x22, + 0x22, 0x22, 0x24, 0xe0, 0xe, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xe0, 0x2, 0x2c, 0xcd, 0xfd, 0xcc, + 0xc1, 0x20, 0x0, 0x0, 0x5d, 0xa0, 0x0, 0x24, + 0x0, 0x4, 0x9b, 0x71, 0xc3, 0x5, 0xd4, 0x0, + 0x6, 0x30, 0x19, 0xac, 0xad, 0x10, 0x0, 0x0, + 0x5a, 0xa2, 0x1e, 0x5c, 0x10, 0x0, 0x9, 0x82, + 0x5, 0xcc, 0x44, 0xa0, 0x0, 0x0, 0x16, 0xc8, + 0xa, 0x50, 0xa9, 0x0, 0xb, 0xd7, 0x10, 0x1e, + 0x20, 0x9, 0xd2, 0x3, 0x0, 0x3d, 0xe7, 0x0, + 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5BB9 "容" */ + 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, 0x0, 0x2, + 0x33, 0x33, 0xa9, 0x33, 0x33, 0x20, 0xe, 0xaa, + 0xaa, 0xaa, 0xaa, 0xab, 0xd0, 0xe, 0x0, 0x62, + 0x0, 0x43, 0x1, 0xd0, 0x3, 0xa, 0x90, 0x22, + 0x1b, 0x91, 0x30, 0x4, 0xd7, 0x1, 0xdc, 0x10, + 0x6d, 0x30, 0x4, 0x20, 0x2c, 0x35, 0xd3, 0x3, + 0x20, 0x0, 0x18, 0xb1, 0x0, 0x2c, 0x81, 0x0, + 0x18, 0xef, 0xcc, 0xcc, 0xcc, 0xfe, 0xa2, 0x39, + 0x1e, 0x0, 0x0, 0x1, 0xd0, 0x71, 0x0, 0xe, + 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, 0xe, 0x0, + 0x0, 0x1, 0xd0, 0x0, 0x0, 0xf, 0xcc, 0xcc, + 0xcd, 0xd0, 0x0, + + /* U+5BBF "宿" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x0, 0xa, 0xaa, 0xaa, + 0xed, 0xaa, 0xaa, 0x80, 0xe2, 0x22, 0x22, 0x22, + 0x22, 0x5b, 0x8, 0xa, 0x40, 0x0, 0x0, 0x1, + 0x40, 0x3, 0xd4, 0xdd, 0xdf, 0xed, 0xdc, 0x0, + 0xb7, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x8f, 0x50, + 0x9d, 0xdf, 0xdd, 0xd2, 0x5d, 0x95, 0xb, 0x20, + 0x0, 0xc, 0x22, 0x28, 0x50, 0xb3, 0x0, 0x0, + 0xc2, 0x0, 0x85, 0xb, 0xcc, 0xcc, 0xcf, 0x20, + 0x8, 0x50, 0xb2, 0x0, 0x0, 0xc2, 0x0, 0x85, + 0xb, 0xdc, 0xcc, 0xcf, 0x20, 0x8, 0x50, 0xb3, + 0x0, 0x0, 0xb2, + + /* U+5BC4 "寄" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0xc, 0xcc, + 0xcc, 0xde, 0xcc, 0xcc, 0xc0, 0xe, 0x0, 0x0, + 0x45, 0x0, 0x0, 0xe0, 0xb, 0x5c, 0xcc, 0xee, + 0xcc, 0xc5, 0xc0, 0x0, 0x0, 0x4, 0xf9, 0x30, + 0x0, 0x0, 0x0, 0x25, 0xab, 0x13, 0x8d, 0x81, + 0x0, 0x16, 0xdd, 0x96, 0x66, 0x67, 0xc9, 0x61, + 0x16, 0x66, 0x66, 0x66, 0x66, 0xd8, 0x61, 0x0, + 0x4a, 0xaa, 0xaa, 0x10, 0xb2, 0x0, 0x0, 0x77, + 0x11, 0x1b, 0x20, 0xb2, 0x0, 0x0, 0x76, 0x0, + 0xb, 0x20, 0xb2, 0x0, 0x0, 0x7d, 0xcc, 0xcc, + 0x10, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, 0xad, + 0xd0, 0x0, + + /* U+5BC6 "密" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0xa, 0xbb, + 0xbb, 0xec, 0xbb, 0xbb, 0xb0, 0xe, 0x11, 0x28, + 0x21, 0x12, 0x11, 0xe0, 0xe, 0x0, 0x25, 0xd3, + 0x2d, 0x30, 0xe0, 0x0, 0x91, 0xd0, 0x16, 0xd4, + 0x56, 0x0, 0x4, 0xb0, 0xd0, 0x8d, 0x30, 0x4c, + 0x60, 0x1d, 0x10, 0xee, 0x80, 0x3, 0xb1, 0xd2, + 0x6, 0xad, 0xbe, 0xcc, 0xce, 0x50, 0x20, 0x18, + 0x30, 0x0, 0x82, 0x0, 0x0, 0x0, 0x0, 0x91, + 0x0, 0xb3, 0x0, 0xd, 0x0, 0x0, 0xb2, 0x0, + 0xb3, 0x0, 0xe, 0x0, 0x0, 0xbb, 0xaa, 0xeb, + 0xaa, 0xae, 0x0, 0x0, 0x23, 0x33, 0x33, 0x33, + 0x3e, 0x0, + + /* U+5BCC "富" */ + 0x0, 0x0, 0x1b, 0x0, 0x0, 0x0, 0x89, 0x99, + 0x9e, 0xb9, 0x99, 0x97, 0xe3, 0x33, 0x33, 0x33, + 0x33, 0x4d, 0xe1, 0xaa, 0xaa, 0xaa, 0xaa, 0x1d, + 0x0, 0x11, 0x11, 0x11, 0x11, 0x0, 0x0, 0xf9, + 0x99, 0x99, 0x9e, 0x0, 0x0, 0xe5, 0x55, 0x55, + 0x5e, 0x0, 0x0, 0x44, 0x44, 0x44, 0x44, 0x0, + 0xd, 0xbb, 0xbe, 0xcb, 0xbb, 0xe0, 0xe, 0x0, + 0xc, 0x10, 0x0, 0xe0, 0xe, 0xaa, 0xaf, 0xba, + 0xaa, 0xf0, 0xe, 0x0, 0xc, 0x10, 0x0, 0xe0, + 0xe, 0xbb, 0xbb, 0xbb, 0xbb, 0xe0, + + /* U+5BD2 "寒" */ + 0x0, 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0xb, + 0xcc, 0xcc, 0xef, 0xcc, 0xcc, 0xb0, 0xe, 0x0, + 0x33, 0x0, 0x33, 0x0, 0xe0, 0xa, 0x8a, 0xdd, + 0xaa, 0xdd, 0xa8, 0xa0, 0x0, 0x0, 0x87, 0x0, + 0x78, 0x0, 0x0, 0x0, 0x5b, 0xdd, 0xbb, 0xdd, + 0xb5, 0x0, 0x0, 0x0, 0x77, 0x0, 0x68, 0x0, + 0x0, 0x1c, 0xcc, 0xed, 0xcc, 0xee, 0xcc, 0xc2, + 0x0, 0x5, 0xc3, 0x30, 0x1c, 0x50, 0x0, 0x0, + 0x7d, 0x13, 0x9c, 0x70, 0xb9, 0x20, 0x2e, 0x70, + 0x30, 0x0, 0x30, 0x5, 0xd2, 0x1, 0x1, 0x9c, + 0xc8, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x9d, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5BDD "寝" */ + 0x0, 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, 0xb, + 0xcc, 0xcc, 0xef, 0xcc, 0xcc, 0xc0, 0xd, 0x4, + 0x1, 0x11, 0x11, 0x11, 0xd0, 0x6, 0xe, 0x5, + 0x88, 0x88, 0x8e, 0x60, 0x9, 0xe, 0x2, 0x99, + 0x99, 0x9e, 0x0, 0x9, 0x4e, 0x1, 0x22, 0x22, + 0x2e, 0x0, 0x3, 0xae, 0x5, 0x77, 0x77, 0x77, + 0x0, 0x0, 0x1e, 0x3b, 0xbb, 0xbb, 0xbb, 0xb0, + 0x0, 0x1e, 0x47, 0x0, 0x0, 0x0, 0xd0, 0x18, + 0xdf, 0x13, 0xec, 0xaa, 0xda, 0x30, 0x47, 0xe, + 0x0, 0x2c, 0x45, 0xb1, 0x0, 0x0, 0xe, 0x0, + 0x27, 0xff, 0x62, 0x0, 0x0, 0xe, 0x3c, 0xa5, + 0x1, 0x6a, 0xc1, + + /* U+5BDF "察" */ + 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0xc, + 0xcc, 0xcc, 0xcf, 0xcc, 0xcc, 0xc0, 0xe, 0x2, + 0x70, 0x6, 0x0, 0x0, 0xe0, 0x4, 0xc, 0xda, + 0xa8, 0xba, 0xaa, 0x70, 0x1, 0xa7, 0x3, 0xa1, + 0xd2, 0x3d, 0x0, 0x1d, 0x63, 0xcc, 0x30, 0x89, + 0xa4, 0x0, 0x2, 0x94, 0xb7, 0x0, 0xb, 0xb0, + 0x0, 0x0, 0x4f, 0x8c, 0xcc, 0xc9, 0xab, 0x40, + 0x2c, 0xb3, 0x11, 0x11, 0x11, 0x15, 0xa3, 0x1, + 0x8b, 0xbb, 0xcf, 0xbb, 0xb9, 0x0, 0x0, 0x5, + 0xa0, 0x1d, 0x7, 0x80, 0x0, 0x2, 0xab, 0x10, + 0x1d, 0x0, 0x6d, 0x50, 0xa, 0x40, 0xb, 0xd9, + 0x0, 0x1, 0x70, + + /* U+5BE6 "實" */ + 0x0, 0x0, 0x0, 0x91, 0x0, 0x0, 0x0, 0x6, + 0x77, 0x77, 0xbb, 0x77, 0x77, 0x70, 0xd, 0x44, + 0x44, 0x44, 0x44, 0x44, 0xe0, 0xa, 0xd, 0x99, + 0xbc, 0x99, 0xe5, 0x90, 0x3a, 0xbe, 0x88, 0xbb, + 0x88, 0xec, 0xa6, 0x0, 0x2e, 0x99, 0xcb, 0x99, + 0xf2, 0x0, 0x0, 0x25, 0x55, 0x55, 0x55, 0x53, + 0x0, 0x0, 0x6a, 0x44, 0x44, 0x44, 0x7b, 0x0, + 0x0, 0x6c, 0x88, 0x88, 0x88, 0xab, 0x0, 0x0, + 0x6c, 0x88, 0x88, 0x88, 0xab, 0x0, 0x0, 0x6c, + 0x99, 0x99, 0x99, 0xab, 0x0, 0x0, 0x4, 0x98, + 0x0, 0x9a, 0x61, 0x0, 0x9, 0xb7, 0x20, 0x0, + 0x0, 0x5a, 0x90, + + /* U+5BEB "寫" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x20, 0x0, 0x0, 0xb, 0xcc, 0xcc, + 0xdd, 0xcc, 0xcc, 0xb0, 0xe0, 0x0, 0x33, 0x0, + 0x0, 0xe, 0x8, 0x1a, 0xb8, 0x39, 0xbb, 0xb0, + 0x80, 0x3, 0xb0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x3e, 0xaa, 0x66, 0xaa, 0xf0, 0x0, 0x3, 0xc2, + 0x22, 0x22, 0x2d, 0x0, 0x0, 0x17, 0xdb, 0x77, + 0x77, 0x70, 0x0, 0x0, 0x9f, 0xaa, 0xaa, 0xaa, + 0xa5, 0x5, 0xc8, 0x44, 0x35, 0x45, 0x2a, 0x71, + 0xa2, 0x77, 0x66, 0xc1, 0xc1, 0xb5, 0x0, 0x1d, + 0x13, 0x98, 0x43, 0x1d, 0x30, 0x3, 0x40, 0x3, + 0x1, 0xcd, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5BFA "寺" */ + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0xce, + 0xee, 0xef, 0xee, 0xee, 0x60, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, + 0x0, 0x0, 0x0, 0x1d, 0xdd, 0xdd, 0xdd, 0xdf, + 0xed, 0xd6, 0x0, 0x0, 0x0, 0x0, 0xc, 0x20, + 0x0, 0x8, 0xbb, 0xbb, 0xbb, 0xbf, 0xcb, 0xb2, + 0x1, 0x25, 0x22, 0x22, 0x2d, 0x52, 0x20, 0x0, + 0x8, 0xb0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, + 0xa9, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, 0x7, + 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, 0x0, 0x2e, + 0xec, 0x0, 0x0, + + /* U+5BFE "対" */ + 0x0, 0x9, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x8, 0x80, 0x0, 0x0, 0xe, 0x0, 0x4, 0x45, + 0xb4, 0x40, 0x0, 0xe, 0x0, 0x2b, 0xbb, 0xbc, + 0xa1, 0x11, 0x1e, 0x10, 0x0, 0x0, 0xe, 0x1c, + 0xcc, 0xcf, 0xc7, 0x4, 0x60, 0x2d, 0x0, 0x0, + 0xe, 0x0, 0x1, 0xd4, 0x6a, 0x6, 0x30, 0xe, + 0x0, 0x0, 0x2d, 0xc4, 0x2, 0xd0, 0xe, 0x0, + 0x0, 0x5, 0xf1, 0x0, 0xa5, 0xe, 0x0, 0x0, + 0xb, 0xbb, 0x0, 0x23, 0xe, 0x0, 0x0, 0x7b, + 0xc, 0x50, 0x0, 0xe, 0x0, 0x9, 0xc1, 0x2, + 0x20, 0x0, 0xe, 0x0, 0x19, 0x0, 0x0, 0x0, + 0x1f, 0xe9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5C04 "射" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x6, + 0x90, 0x0, 0x0, 0xd, 0x0, 0x0, 0xfc, 0xcc, + 0xd0, 0x0, 0xd, 0x0, 0x0, 0xd0, 0x0, 0xd2, + 0x44, 0x4e, 0x42, 0x0, 0xfb, 0xbb, 0xd6, 0x99, + 0x9f, 0x95, 0x0, 0xd0, 0x0, 0xd0, 0x0, 0xd, + 0x0, 0x0, 0xfb, 0xbb, 0xd0, 0xb0, 0xd, 0x0, + 0x0, 0xd0, 0x0, 0xd0, 0x77, 0xd, 0x0, 0xa, + 0xdd, 0xdf, 0xd0, 0xd, 0xd, 0x0, 0x0, 0x1, + 0xc4, 0xd0, 0x4, 0xd, 0x0, 0x0, 0x3c, 0x40, + 0xd0, 0x0, 0xd, 0x0, 0xa, 0xa1, 0x0, 0xd0, + 0x0, 0xe, 0x0, 0x2, 0x0, 0xbd, 0x90, 0xb, + 0xda, 0x0, + + /* U+5C07 "將" */ + 0x0, 0x0, 0xe0, 0x0, 0x2b, 0x0, 0x0, 0xd, + 0x0, 0xe0, 0x2, 0xed, 0xbb, 0xa0, 0xd, 0x0, + 0xe0, 0x6b, 0x52, 0x7, 0x70, 0xd, 0x0, 0xe7, + 0x73, 0x1b, 0x8c, 0x0, 0xd, 0xdd, 0xe0, 0x9, + 0x77, 0xb0, 0x0, 0x0, 0x0, 0xe0, 0x16, 0xe7, + 0x28, 0x0, 0x0, 0x0, 0xe4, 0xc7, 0x10, 0x3a, + 0x0, 0x3e, 0xdd, 0xe7, 0xcc, 0xcc, 0xde, 0xc6, + 0xa, 0x20, 0xe0, 0x24, 0x11, 0x4b, 0x10, 0xb, + 0x10, 0xe0, 0x2d, 0x20, 0x3a, 0x0, 0xc, 0x0, + 0xe0, 0x5, 0xc0, 0x3a, 0x0, 0x1a, 0x0, 0xe0, + 0x0, 0x30, 0x3a, 0x0, 0x35, 0x0, 0xe0, 0x0, + 0x2e, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5C08 "專" */ + 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x8, + 0xcc, 0xcc, 0xde, 0xcc, 0xcc, 0xc0, 0x0, 0x0, + 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0xab, 0xaa, + 0xbe, 0xaa, 0xae, 0x20, 0x0, 0xa9, 0x66, 0x9c, + 0x66, 0x6e, 0x20, 0x0, 0xa6, 0x33, 0x6b, 0x33, + 0x3d, 0x20, 0x0, 0x8a, 0xaa, 0xbe, 0xac, 0xcc, + 0x10, 0x3, 0x55, 0x55, 0x8c, 0x69, 0xfb, 0x20, + 0x3, 0x65, 0x55, 0x44, 0x4c, 0x53, 0x70, 0x1c, + 0xcc, 0xcc, 0xcc, 0xcf, 0xdc, 0xc7, 0x0, 0x8, + 0x80, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, 0x7c, + 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, 0x1, 0x9, + 0xcd, 0x10, 0x0, + + /* U+5C0D "對" */ + 0x4, 0xc, 0xb, 0x4, 0x0, 0xd, 0x0, 0x7, + 0x6c, 0xb, 0x87, 0x0, 0xe, 0x0, 0x0, 0x9c, + 0xd, 0x90, 0x0, 0xe, 0x0, 0x2c, 0xcf, 0xcf, + 0xcb, 0x0, 0xe, 0x0, 0x1, 0x93, 0x14, 0x83, + 0xdd, 0xdf, 0xd5, 0x0, 0x3a, 0xa, 0x30, 0x0, + 0xe, 0x0, 0x8, 0xcd, 0xdf, 0xc6, 0x83, 0xe, + 0x0, 0x0, 0x0, 0xd0, 0x0, 0x4a, 0xe, 0x0, + 0x0, 0x23, 0xd2, 0x20, 0xd, 0xe, 0x0, 0x2, + 0x9a, 0xe9, 0x91, 0x7, 0x1e, 0x0, 0x0, 0x0, + 0xd0, 0x12, 0x0, 0xe, 0x0, 0x8, 0xac, 0xec, + 0xa7, 0x0, 0xe, 0x0, 0x4, 0x20, 0x0, 0x0, + 0xb, 0xdb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5C0E "導" */ + 0x5, 0x20, 0x0, 0xa2, 0x0, 0xb2, 0x0, 0x3, + 0xd3, 0x6a, 0xcd, 0xab, 0xea, 0xa0, 0x0, 0x34, + 0x2, 0x24, 0xc2, 0x22, 0x0, 0x15, 0x52, 0xb, + 0x97, 0x77, 0x7e, 0x0, 0x27, 0xa7, 0xb, 0x98, + 0x88, 0x8e, 0x0, 0x0, 0x57, 0xb, 0x87, 0x77, + 0x7e, 0x0, 0x0, 0x9b, 0xb, 0x98, 0x88, 0x8e, + 0x0, 0xb, 0x63, 0xb9, 0x65, 0x55, 0x66, 0x72, + 0x4, 0x0, 0x2, 0x56, 0x6c, 0x95, 0x40, 0x2b, + 0xbb, 0xbb, 0xbb, 0xbe, 0xcb, 0xb1, 0x0, 0x9, + 0x60, 0x0, 0x9, 0x50, 0x0, 0x0, 0x1, 0xc6, + 0x0, 0x9, 0x40, 0x0, 0x0, 0x0, 0x3, 0x8, + 0xcd, 0x20, 0x0, + + /* U+5C0F "小" */ + 0x0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, + 0x3c, 0x0, 0x62, 0x0, 0x0, 0x3e, 0x0, 0x3c, + 0x0, 0x6a, 0x0, 0x0, 0x79, 0x0, 0x3c, 0x0, + 0xe, 0x30, 0x0, 0xc4, 0x0, 0x3c, 0x0, 0x6, + 0xb0, 0x3, 0xe0, 0x0, 0x3c, 0x0, 0x0, 0xf2, + 0xb, 0x70, 0x0, 0x3c, 0x0, 0x0, 0x97, 0x1a, + 0x0, 0x0, 0x3c, 0x0, 0x0, 0x5b, 0x0, 0x0, + 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf, 0xe6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5C11 "少" */ + 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x28, + 0x0, 0xd0, 0x1, 0x80, 0x0, 0x0, 0x96, 0x0, + 0xd0, 0x0, 0xb4, 0x0, 0x1, 0xd0, 0x0, 0xd0, + 0x0, 0x2d, 0x0, 0xb, 0x50, 0x0, 0xd0, 0x0, + 0x8, 0x80, 0x3b, 0x0, 0x0, 0xd0, 0x0, 0x0, + 0xb0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x91, 0x0, + 0x0, 0x0, 0x0, 0x80, 0xa, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xca, 0x0, 0x0, 0x0, 0x0, + 0x4, 0x9d, 0x40, 0x0, 0x0, 0x14, 0x7a, 0xeb, + 0x50, 0x0, 0x0, 0x0, 0x6a, 0x74, 0x10, 0x0, + 0x0, 0x0, 0x0, + + /* U+5C1A "尚" */ + 0x5, 0x0, 0x2, 0xc0, 0x0, 0x44, 0x8, 0xa0, + 0x2, 0xc0, 0x0, 0xe3, 0x0, 0xc6, 0x2, 0xc0, + 0xa, 0x70, 0x0, 0x26, 0x2, 0xc0, 0x18, 0x0, + 0x1d, 0xdd, 0xdd, 0xfd, 0xdd, 0xd9, 0x1d, 0x0, + 0x0, 0x0, 0x0, 0x3b, 0x1d, 0x0, 0x0, 0x0, + 0x0, 0x2b, 0x1d, 0x2, 0xec, 0xcc, 0xe0, 0x2b, + 0x1d, 0x2, 0xb0, 0x0, 0xe0, 0x2b, 0x1d, 0x2, + 0xb0, 0x0, 0xe0, 0x2b, 0x1d, 0x2, 0xfc, 0xcc, + 0xb0, 0x2b, 0x1d, 0x2, 0x90, 0x0, 0x0, 0x3b, + 0x1d, 0x0, 0x0, 0x0, 0x5e, 0xd7, + + /* U+5C24 "尤" */ + 0x0, 0x0, 0x0, 0xe0, 0x38, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe0, 0xa, 0xd2, 0x0, 0x0, 0x0, + 0x0, 0xe0, 0x0, 0x6e, 0x0, 0x3, 0x33, 0x34, + 0xe3, 0x33, 0x35, 0x30, 0x2a, 0xaa, 0xab, 0xea, + 0xaa, 0xaa, 0xa2, 0x0, 0x0, 0x4, 0xa7, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x7, 0x7c, 0x20, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x4c, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0xc, 0x20, 0x0, 0x0, 0x0, + 0x0, 0xa7, 0xc, 0x20, 0x0, 0x41, 0x0, 0x8, + 0xb0, 0xc, 0x20, 0x0, 0x94, 0x1, 0xad, 0x10, + 0xc, 0x30, 0x0, 0xc2, 0x2f, 0x90, 0x0, 0x7, + 0xfe, 0xee, 0xa0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5C31 "就" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x30, 0x0, 0xd, 0x1, 0x0, 0x0, 0x5, + 0x90, 0x0, 0xe, 0xc, 0x20, 0x3d, 0xdd, 0xdd, + 0xd2, 0xe, 0x3, 0xc0, 0x0, 0x0, 0x0, 0x1, + 0x1e, 0x11, 0x40, 0x6, 0xdc, 0xcd, 0x88, 0xcf, + 0xcc, 0xc6, 0x7, 0x50, 0x4, 0x80, 0x1c, 0x20, + 0x0, 0x7, 0xc9, 0x9b, 0x80, 0x3a, 0xe0, 0x0, + 0x1, 0x26, 0x92, 0x10, 0x58, 0xe0, 0x0, 0x1, + 0xa4, 0x8a, 0x20, 0x94, 0xe0, 0x0, 0x5, 0x74, + 0x84, 0x80, 0xd0, 0xe0, 0x0, 0xc, 0x24, 0x80, + 0x95, 0x80, 0xe0, 0x8, 0x19, 0x4, 0x80, 0x1c, + 0x10, 0xf0, 0xb, 0x0, 0x6d, 0x50, 0x94, 0x0, + 0xbb, 0xc6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5C3A "尺" */ + 0x0, 0xaf, 0xee, 0xee, 0xee, 0xed, 0x0, 0x0, + 0xa4, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0xa4, + 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0xa4, 0x0, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0xbd, 0xbb, 0xbb, + 0xbb, 0xcd, 0x0, 0x0, 0xb5, 0x22, 0x2c, 0x52, + 0x22, 0x0, 0x0, 0xd0, 0x0, 0x7, 0x80, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x1, 0xe1, 0x0, 0x0, + 0x4, 0xb0, 0x0, 0x0, 0x7a, 0x0, 0x0, 0xa, + 0x60, 0x0, 0x0, 0xb, 0xa0, 0x0, 0x4e, 0x0, + 0x0, 0x0, 0x0, 0xad, 0x50, 0x65, 0x0, 0x0, + 0x0, 0x0, 0x4, 0xa0, + + /* U+5C40 "局" */ + 0x0, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0x0, 0xd, + 0x10, 0x0, 0x0, 0x0, 0xd0, 0x0, 0xd2, 0x0, + 0x0, 0x0, 0x1d, 0x0, 0xd, 0xcb, 0xbb, 0xbb, + 0xbb, 0xa0, 0x0, 0xe1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0x0, + 0xe0, 0x0, 0x0, 0x0, 0x2, 0xb0, 0x2b, 0xd, + 0xcc, 0xcc, 0xd0, 0x3b, 0x6, 0x80, 0xd0, 0x0, + 0xd, 0x4, 0xa0, 0xb2, 0xd, 0x99, 0x9a, 0xd0, + 0x68, 0x3a, 0x0, 0xd2, 0x22, 0x22, 0x9, 0x63, + 0x30, 0x5, 0x0, 0x0, 0x9d, 0xc1, + + /* U+5C45 "居" */ + 0x0, 0xfd, 0xdd, 0xdd, 0xdd, 0xdf, 0x40, 0x0, + 0xe0, 0x0, 0x0, 0x0, 0x9, 0x40, 0x0, 0xfa, + 0xaa, 0xaa, 0xaa, 0xae, 0x40, 0x0, 0xf2, 0x22, + 0x25, 0xc2, 0x22, 0x0, 0x0, 0xf0, 0x0, 0x3, + 0xb0, 0x0, 0x0, 0x0, 0xfd, 0xdd, 0xde, 0xfd, + 0xdd, 0xd1, 0x1, 0xd0, 0x0, 0x3, 0xb0, 0x0, + 0x0, 0x2, 0xb0, 0x23, 0x35, 0xc3, 0x33, 0x0, + 0x4, 0x90, 0xea, 0xaa, 0xaa, 0xaf, 0x0, 0x8, + 0x50, 0xe0, 0x0, 0x0, 0xd, 0x0, 0xd, 0x10, + 0xe0, 0x0, 0x0, 0xe, 0x0, 0x48, 0x0, 0xec, + 0xcc, 0xcc, 0xcf, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5C4A "届" */ + 0x0, 0xfd, 0xdd, 0xdd, 0xdd, 0xdf, 0x10, 0xe, + 0x0, 0x0, 0x0, 0x0, 0xd1, 0x0, 0xf0, 0x0, + 0x0, 0x0, 0xd, 0x10, 0xf, 0xdd, 0xdd, 0xdd, + 0xdd, 0xd1, 0x0, 0xe0, 0x0, 0x1, 0xc0, 0x0, + 0x0, 0x1d, 0xc, 0xcc, 0xdf, 0xcc, 0xc3, 0x2, + 0xc0, 0xe0, 0x2, 0xc0, 0xa, 0x30, 0x3b, 0xd, + 0x0, 0x1c, 0x0, 0xa3, 0x5, 0x90, 0xfc, 0xcc, + 0xfc, 0xce, 0x30, 0x95, 0xd, 0x0, 0x1c, 0x0, + 0xa3, 0xd, 0x10, 0xe0, 0x2, 0xc0, 0xb, 0x34, + 0x80, 0xf, 0xcc, 0xcc, 0xcc, 0xe3, + + /* U+5C4B "屋" */ + 0x0, 0xfc, 0xcc, 0xcc, 0xcc, 0xcf, 0x10, 0x0, + 0xe0, 0x0, 0x0, 0x0, 0xc, 0x10, 0x0, 0xfc, + 0xcc, 0xcc, 0xcc, 0xcf, 0x10, 0x0, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xeb, 0xcc, 0xdc, + 0xcc, 0xcc, 0xa0, 0x1, 0xe0, 0x1c, 0x40, 0xb, + 0x60, 0x0, 0x2, 0xd3, 0xeb, 0x9a, 0xbc, 0xfa, + 0x0, 0x3, 0xb1, 0x54, 0x3d, 0x20, 0x8, 0x30, + 0x5, 0x93, 0xbb, 0xbf, 0xbb, 0xba, 0x0, 0x9, + 0x50, 0x0, 0xd, 0x20, 0x0, 0x0, 0xd, 0x10, + 0x0, 0xc, 0x10, 0x0, 0x0, 0x4b, 0x4c, 0xcc, + 0xcf, 0xcc, 0xcc, 0xc3, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5C55 "展" */ + 0x0, 0xfd, 0xdd, 0xdd, 0xdd, 0xdf, 0x30, 0x0, + 0xe0, 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0xfd, + 0xdd, 0xdd, 0xdd, 0xdf, 0x30, 0x0, 0xe0, 0x2, + 0x60, 0x8, 0x0, 0x0, 0x0, 0xe1, 0x25, 0xa2, + 0x2d, 0x32, 0x10, 0x1, 0xe5, 0xab, 0xda, 0xae, + 0xaa, 0x50, 0x2, 0xd0, 0x2, 0x90, 0xc, 0x10, + 0x0, 0x3, 0xbd, 0xdf, 0xde, 0xed, 0xdd, 0xd0, + 0x6, 0x80, 0x2b, 0x2, 0xb0, 0x4b, 0x0, 0xa, + 0x50, 0x2b, 0x0, 0x6c, 0x90, 0x0, 0x1e, 0x0, + 0x4c, 0x5a, 0x67, 0xb3, 0x0, 0x58, 0x0, 0xbb, + 0x72, 0x0, 0x3a, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5C65 "履" */ + 0x0, 0xfc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, 0x0, + 0xe1, 0x11, 0x11, 0x11, 0x13, 0xc0, 0x0, 0xf8, + 0x8b, 0x8a, 0xa8, 0x88, 0x60, 0x0, 0xe0, 0x97, + 0xc, 0xca, 0xaa, 0xa0, 0x0, 0xe9, 0x82, 0x9b, + 0x44, 0x44, 0x20, 0x1, 0xe0, 0x3c, 0x7d, 0x55, + 0x56, 0xa0, 0x2, 0xc3, 0xe2, 0xe, 0x88, 0x89, + 0xa0, 0x3, 0xcc, 0xe0, 0xb, 0xa8, 0x78, 0x80, + 0x6, 0x80, 0xd0, 0x5, 0xfa, 0xaa, 0x60, 0xa, + 0x50, 0xd1, 0xab, 0xa1, 0x3c, 0x20, 0x1e, 0x0, + 0xd0, 0x30, 0x8f, 0xf6, 0x0, 0x38, 0x0, 0xd0, + 0x9a, 0x62, 0x27, 0xb3, + + /* U+5C6C "屬" */ + 0x0, 0xfa, 0xaa, 0xaa, 0xaa, 0xab, 0xd0, 0x0, + 0xf8, 0x88, 0x88, 0x88, 0x88, 0xd0, 0x0, 0xe0, + 0x89, 0x35, 0x63, 0x88, 0x10, 0x0, 0xe1, 0x58, + 0x96, 0x76, 0x86, 0x10, 0x0, 0xe4, 0xc8, 0x79, + 0x97, 0x7b, 0x60, 0x1, 0xd6, 0x71, 0xc1, 0x1c, + 0x13, 0xb0, 0x2, 0xc3, 0x8e, 0x98, 0x89, 0x88, + 0x60, 0x3, 0xb0, 0xac, 0x9c, 0x99, 0x99, 0xc0, + 0x5, 0x9c, 0xd8, 0x8e, 0x88, 0x60, 0xd0, 0x8, + 0x50, 0xc6, 0x7e, 0x68, 0x90, 0xd0, 0xc, 0x10, + 0x12, 0x4d, 0x5d, 0x51, 0xc0, 0x2b, 0x6, 0xaa, + 0x87, 0x53, 0xbc, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5C71 "山" */ + 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xe0, 0x0, 0x0, 0x3, 0x90, 0x0, 0x1e, 0x0, + 0x0, 0xc0, 0x3b, 0x0, 0x1, 0xe0, 0x0, 0xe, + 0x3, 0xb0, 0x0, 0x1e, 0x0, 0x0, 0xe0, 0x3b, + 0x0, 0x1, 0xe0, 0x0, 0xe, 0x3, 0xb0, 0x0, + 0x1e, 0x0, 0x0, 0xe0, 0x3b, 0x0, 0x1, 0xe0, + 0x0, 0xe, 0x3, 0xb0, 0x0, 0x1e, 0x0, 0x0, + 0xe0, 0x3b, 0x0, 0x1, 0xe0, 0x0, 0xe, 0x3, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x0, + + /* U+5CF6 "島" */ + 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x7b, + 0xbd, 0xdb, 0xbb, 0xa0, 0x0, 0xb, 0x20, 0x0, + 0x0, 0xe, 0x0, 0x0, 0xbb, 0xaa, 0xaa, 0xaa, + 0xe0, 0x0, 0xb, 0x20, 0x0, 0x0, 0xe, 0x0, + 0x0, 0xbc, 0xbb, 0xbb, 0xbb, 0xa0, 0x0, 0xb, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xb2, 0xb, 0x75, 0x55, 0x55, + 0x55, 0x54, 0x0, 0x35, 0xa6, 0x55, 0x55, 0x59, + 0x90, 0xd0, 0xa, 0x20, 0xd, 0x0, 0x87, 0xd, + 0xaa, 0xeb, 0xaa, 0xd0, 0xb, 0x40, 0x0, 0x0, + 0x0, 0x9, 0xac, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5D4C "嵌" */ + 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x9, + 0x50, 0x0, 0xb3, 0x0, 0xe, 0x10, 0x9, 0xed, + 0xdd, 0xfd, 0xdd, 0xdf, 0x10, 0x1, 0x10, 0x0, + 0x0, 0x60, 0x0, 0x0, 0x6, 0x70, 0xd, 0x3, + 0xb1, 0x11, 0x10, 0x8e, 0xed, 0xdf, 0xd8, 0xca, + 0xaa, 0xd0, 0x7, 0x80, 0xe, 0xb, 0x25, 0x23, + 0x90, 0x6, 0x70, 0xd, 0x2d, 0xb, 0x37, 0x50, + 0x6, 0xec, 0xcf, 0x3, 0xd, 0x40, 0x0, 0x6, + 0x70, 0xd, 0x0, 0x1f, 0xb0, 0x0, 0x6, 0x70, + 0xd, 0x0, 0x96, 0xc3, 0x0, 0x6, 0xed, 0xdf, + 0x7, 0xb0, 0x3d, 0x10, 0x6, 0x70, 0xd, 0x49, + 0x0, 0x3, 0xb0, + + /* U+5DDD "川" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x10, 0x0, 0x40, 0x0, 0xd1, 0x0, 0xd1, 0x0, + 0x2c, 0x0, 0xd, 0x10, 0xd, 0x10, 0x2, 0xc0, + 0x0, 0xd1, 0x0, 0xd1, 0x0, 0x2c, 0x0, 0xd, + 0x10, 0xe, 0x10, 0x2, 0xc0, 0x0, 0xd1, 0x0, + 0xf0, 0x0, 0x2c, 0x0, 0xd, 0x10, 0xf, 0x0, + 0x2, 0xc0, 0x0, 0xd1, 0x1, 0xe0, 0x0, 0x2c, + 0x0, 0xd, 0x10, 0x3c, 0x0, 0x2, 0xc0, 0x0, + 0xd1, 0x8, 0x70, 0x0, 0x2c, 0x0, 0xd, 0x11, + 0xe1, 0x0, 0x2, 0xb0, 0x0, 0xd1, 0x77, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5DDE "州" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd1, 0x0, 0x0, 0x0, 0xd0, 0x0, 0xd, 0x10, + 0xd, 0x10, 0xd, 0x0, 0x0, 0xd1, 0x0, 0xd1, + 0x0, 0xd0, 0x0, 0xd, 0x10, 0xd, 0x10, 0xd, + 0x0, 0x84, 0xd5, 0x60, 0xd6, 0x60, 0xd0, 0xc, + 0xe, 0x2c, 0xd, 0x2d, 0xd, 0x3, 0xb0, 0xe0, + 0xc1, 0xd1, 0x85, 0xd0, 0x74, 0x1e, 0x7, 0x3d, + 0x13, 0x5d, 0x0, 0x3, 0xb0, 0x0, 0xd1, 0x0, + 0xd0, 0x0, 0x87, 0x0, 0xd, 0x10, 0xd, 0x0, + 0xe, 0x10, 0x0, 0xd1, 0x0, 0xd0, 0x9, 0x80, + 0x0, 0xd, 0x10, 0xd, 0x2, 0xc0, 0x0, 0x0, + 0x40, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5DE5 "工" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xee, 0xee, 0xff, 0xee, 0xee, 0xb0, 0x0, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x1e, 0xee, + 0xee, 0xff, 0xee, 0xee, 0xe7, + + /* U+5DE6 "左" */ + 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2c, 0x0, 0x0, 0x0, 0x0, 0xe, 0xee, 0xff, + 0xee, 0xee, 0xee, 0xe0, 0x0, 0x0, 0xb4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xdb, 0xbb, 0xbb, 0xbb, + 0x60, 0x0, 0xc, 0x42, 0x24, 0xd2, 0x22, 0x10, + 0x0, 0x2d, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, + 0xc5, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x7, 0xb0, + 0x0, 0x2, 0xc0, 0x0, 0x0, 0x4d, 0x10, 0x0, + 0x2, 0xc0, 0x0, 0x0, 0x12, 0xb, 0xee, 0xee, + 0xfe, 0xee, 0xe3, + + /* U+5DEE "差" */ + 0x0, 0x4, 0x40, 0x0, 0x5, 0x60, 0x0, 0x0, + 0x1, 0xd0, 0x0, 0xe, 0x20, 0x0, 0x7, 0xdd, + 0xfe, 0xdd, 0xef, 0xdd, 0x80, 0x0, 0x0, 0x0, + 0xe1, 0x0, 0x0, 0x0, 0x0, 0xbd, 0xdd, 0xfd, + 0xdd, 0xdc, 0x0, 0x0, 0x0, 0x8, 0x70, 0x0, + 0x0, 0x0, 0x1a, 0xaa, 0xaf, 0xca, 0xaa, 0xaa, + 0xa1, 0x2, 0x22, 0xa9, 0x22, 0x22, 0x22, 0x20, + 0x0, 0x3, 0xeb, 0xaa, 0xaa, 0xaa, 0x0, 0x0, + 0x1d, 0x43, 0x35, 0xd3, 0x33, 0x0, 0x3, 0xd7, + 0x0, 0x2, 0xc0, 0x0, 0x0, 0x2f, 0x63, 0x33, + 0x35, 0xd3, 0x33, 0x30, 0x2, 0x9, 0xaa, 0xaa, + 0xaa, 0xaa, 0xa1, + + /* U+5DF1 "己" */ + 0xf, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3c, 0x0, 0x1, 0x11, 0x11, 0x11, 0x14, 0xc0, + 0x0, 0xdd, 0xcc, 0xcc, 0xcc, 0xdc, 0x0, 0xd, + 0x10, 0x0, 0x0, 0x1, 0x40, 0x0, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, + 0x0, 0x4, 0x30, 0xd1, 0x0, 0x0, 0x0, 0x0, + 0x87, 0xd, 0x40, 0x0, 0x0, 0x0, 0x1d, 0x30, + 0x5d, 0xee, 0xee, 0xee, 0xee, 0x80, + + /* U+5DF2 "已" */ + 0x7e, 0xee, 0xee, 0xee, 0xef, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3b, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x3, 0xb0, 0x0, 0xe0, 0x0, 0x0, 0x0, + 0x3b, 0x0, 0xe, 0x0, 0x0, 0x0, 0x3, 0xb0, + 0x0, 0xee, 0xee, 0xee, 0xee, 0xfb, 0x0, 0xe, + 0x0, 0x0, 0x0, 0x1, 0x40, 0x0, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x50, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0xa5, 0xd, 0x40, 0x0, 0x0, 0x0, 0x2e, 0x10, + 0x5d, 0xee, 0xee, 0xee, 0xed, 0x60, + + /* U+5E02 "市" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5c, 0x0, 0x0, 0x0, 0x1d, 0xdd, 0xdd, + 0xef, 0xed, 0xdd, 0xd6, 0x0, 0x0, 0x0, 0x5a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x59, 0x0, + 0x0, 0x0, 0x0, 0x9e, 0xee, 0xff, 0xee, 0xee, + 0x20, 0x0, 0xa4, 0x0, 0x59, 0x0, 0xb, 0x30, + 0x0, 0xa4, 0x0, 0x59, 0x0, 0xb, 0x30, 0x0, + 0xa4, 0x0, 0x59, 0x0, 0xb, 0x30, 0x0, 0xa4, + 0x0, 0x59, 0x0, 0xc, 0x30, 0x0, 0xa4, 0x0, + 0x59, 0xb, 0xbe, 0x10, 0x0, 0x20, 0x0, 0x59, + 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x59, 0x0, + 0x0, 0x0, + + /* U+5E03 "布" */ + 0x0, 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x0, 0x0, 0x1c, 0xcc, + 0xcf, 0xcc, 0xcc, 0xcc, 0xc1, 0x1, 0x12, 0xd5, + 0x12, 0x21, 0x11, 0x10, 0x0, 0x5, 0xc0, 0xc, + 0x10, 0x0, 0x0, 0x0, 0xe, 0x30, 0xc, 0x10, + 0x0, 0x0, 0x0, 0xbf, 0xee, 0xef, 0xee, 0xef, + 0x50, 0xc, 0xae, 0x0, 0xc, 0x10, 0x9, 0x50, + 0x49, 0xd, 0x0, 0xc, 0x10, 0x9, 0x50, 0x0, + 0xd, 0x0, 0xc, 0x10, 0x9, 0x50, 0x0, 0xd, + 0x0, 0xc, 0x10, 0xa, 0x50, 0x0, 0xc, 0x0, + 0xc, 0x18, 0xca, 0x10, 0x0, 0x0, 0x0, 0xc, + 0x10, 0x0, 0x0, + + /* U+5E08 "师" */ + 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0xb, 0xdd, 0xee, 0xdd, 0xd0, 0xd0, 0xd0, 0x0, + 0x7, 0x60, 0x0, 0xd, 0xd, 0x1, 0x44, 0xa9, + 0x44, 0x20, 0xd0, 0xd0, 0x5c, 0x8c, 0xc8, 0xb7, + 0xd, 0xd, 0x5, 0x80, 0x76, 0x6, 0x70, 0xd0, + 0xe0, 0x58, 0x7, 0x60, 0x67, 0xd, 0xf, 0x5, + 0x80, 0x76, 0x6, 0x70, 0x91, 0xd0, 0x58, 0x7, + 0x60, 0x67, 0x0, 0x3b, 0x5, 0x80, 0x76, 0x6, + 0x70, 0x8, 0x60, 0x58, 0x7, 0x68, 0xd4, 0x2, + 0xd0, 0x0, 0x0, 0x76, 0x0, 0x0, 0x84, 0x0, + 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5E0C "希" */ + 0x0, 0x13, 0x0, 0x0, 0x0, 0x73, 0x0, 0x0, + 0x39, 0xc9, 0x40, 0x6c, 0x70, 0x0, 0x0, 0x0, + 0x18, 0xff, 0xf4, 0x0, 0x0, 0x3, 0x9d, 0xdc, + 0x90, 0x4b, 0xd6, 0x0, 0x1, 0x51, 0xc, 0x40, + 0x0, 0x24, 0x0, 0x2d, 0xdd, 0xee, 0xdd, 0xdd, + 0xdd, 0xd2, 0x0, 0x3, 0xd1, 0xe, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0xca, 0xaf, 0xaa, 0xaa, 0x0, + 0x7, 0xde, 0x42, 0x2e, 0x22, 0x2e, 0x10, 0x39, + 0xc, 0x20, 0xe, 0x0, 0xd, 0x10, 0x0, 0xc, + 0x20, 0xe, 0x0, 0xd, 0x10, 0x0, 0xc, 0x20, + 0xe, 0x9, 0xcb, 0x0, 0x0, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x0, + + /* U+5E2B "師" */ + 0x2, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x85, + 0x4, 0xdd, 0xdf, 0xdd, 0xd4, 0xbf, 0xdc, 0x10, + 0x0, 0xd0, 0x0, 0xd, 0x0, 0xb1, 0x68, 0x8f, + 0x88, 0x70, 0xd0, 0xb, 0x1c, 0x65, 0xe5, 0x5e, + 0xd, 0xdd, 0xf1, 0xc1, 0xd, 0x0, 0xe0, 0xd0, + 0x0, 0xc, 0x10, 0xd0, 0xe, 0xd, 0xaa, 0xa2, + 0xc1, 0xd, 0x0, 0xe0, 0xd2, 0x2b, 0x3c, 0x10, + 0xd0, 0xe, 0xd, 0x0, 0x93, 0xc1, 0xd, 0x0, + 0xe0, 0xd0, 0x9, 0x3c, 0x10, 0xd2, 0xdc, 0xd, + 0xcc, 0xc3, 0x10, 0xd, 0x0, 0x0, 0xd0, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x0, + + /* U+5E2D "席" */ + 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, + 0x11, 0x11, 0x1b, 0x71, 0x11, 0x10, 0x0, 0xfc, + 0xcc, 0xcc, 0xcc, 0xcc, 0xc5, 0x0, 0xd0, 0x7, + 0x60, 0x0, 0xe0, 0x0, 0x0, 0xd8, 0xce, 0xec, + 0xcc, 0xfc, 0xc4, 0x1, 0xd0, 0x7, 0x60, 0x0, + 0xe0, 0x0, 0x1, 0xc0, 0x7, 0xc9, 0x99, 0xf0, + 0x0, 0x2, 0xb0, 0x1, 0x22, 0xe2, 0x20, 0x0, + 0x3, 0xa0, 0xab, 0xbb, 0xfb, 0xbb, 0x60, 0x4, + 0x90, 0xe1, 0x11, 0xe1, 0x17, 0x80, 0x8, 0x50, + 0xe0, 0x0, 0xe0, 0x5, 0x80, 0xc, 0x10, 0xe0, + 0x0, 0xe0, 0x27, 0x80, 0x2a, 0x0, 0xa0, 0x0, + 0xe0, 0xa9, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5E2F "帯" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x20, 0x49, 0x0, 0xb2, 0x0, 0x0, 0xb, + 0x20, 0x49, 0x0, 0xc2, 0x0, 0xc, 0xcf, 0xdc, + 0xde, 0xcc, 0xfd, 0xc6, 0x0, 0xb, 0x20, 0x49, + 0x0, 0xb2, 0x0, 0x0, 0x9, 0xcc, 0xcc, 0xcc, + 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xcb, 0xbb, 0xde, 0xbb, 0xbb, 0xf1, + 0xa, 0x20, 0x0, 0x49, 0x0, 0x0, 0xd1, 0x7, + 0x3e, 0xcc, 0xde, 0xcc, 0xda, 0x80, 0x0, 0x1c, + 0x0, 0x49, 0x0, 0x3a, 0x0, 0x0, 0x1c, 0x0, + 0x49, 0x0, 0x4a, 0x0, 0x0, 0x1c, 0x0, 0x49, + 0xc, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x49, 0x0, + 0x0, 0x0, + + /* U+5E30 "帰" */ + 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x2, 0xbb, 0xbb, 0xbe, 0x0, 0x1, 0xd, + 0x1, 0xbb, 0xbb, 0xbe, 0x0, 0xb, 0xd, 0x0, + 0x0, 0x0, 0xe, 0x0, 0xc, 0xd, 0x7, 0xbb, + 0xbb, 0xbc, 0x0, 0xc, 0xd, 0x1, 0x11, 0x11, + 0x11, 0x10, 0x1b, 0xd, 0x6d, 0x99, 0xf9, 0x99, + 0xf0, 0x26, 0xd, 0x69, 0x0, 0xe0, 0x0, 0xd0, + 0x0, 0x1c, 0x3, 0xec, 0xfc, 0xcf, 0x10, 0x0, + 0x49, 0x2, 0xb0, 0xe0, 0xd, 0x0, 0x0, 0xb4, + 0x2, 0xb0, 0xe0, 0xd, 0x0, 0x5, 0xc0, 0x2, + 0xb0, 0xe1, 0xcb, 0x0, 0xb, 0x10, 0x0, 0x0, + 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5E33 "帳" */ + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x5e, 0xcc, 0xcc, 0xa0, 0x0, 0xc0, 0x5, + 0x90, 0x0, 0x0, 0xf, 0xdf, 0xe4, 0x5d, 0xaa, + 0xaa, 0x30, 0xb0, 0xc6, 0x45, 0x90, 0x0, 0x0, + 0xb, 0xc, 0x64, 0x5e, 0xbb, 0xbb, 0x40, 0xb0, + 0xc6, 0x46, 0x90, 0x0, 0x0, 0xb, 0xc, 0x69, + 0xfd, 0xed, 0xcc, 0xc0, 0xb0, 0xc6, 0x4b, 0x24, + 0xa0, 0x67, 0xb, 0xc, 0xd1, 0xb2, 0xa, 0xb9, + 0x0, 0x10, 0xc0, 0xb, 0x20, 0x1e, 0x40, 0x0, + 0xc, 0x0, 0xc7, 0xa9, 0x2d, 0x70, 0x0, 0xc0, + 0xd, 0x82, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5E36 "帶" */ + 0x0, 0xd, 0xc, 0x0, 0xd0, 0xd0, 0x0, 0x0, + 0xd, 0xc, 0x0, 0xd0, 0xd0, 0x0, 0x2c, 0xcf, + 0xcf, 0xcc, 0xfc, 0xfc, 0xc2, 0x0, 0x3c, 0xc, + 0x0, 0xd0, 0xd0, 0x51, 0x2, 0xc3, 0xc, 0xaa, + 0xd0, 0xc7, 0xc2, 0x9, 0x30, 0x2, 0x33, 0x20, + 0x26, 0x40, 0xd, 0xcc, 0xcc, 0xed, 0xcc, 0xcc, + 0xf0, 0xd, 0x0, 0x0, 0x76, 0x0, 0x0, 0xe0, + 0x8, 0x7d, 0xcc, 0xed, 0xcc, 0xd9, 0x90, 0x0, + 0x76, 0x0, 0x76, 0x0, 0x4a, 0x0, 0x0, 0x76, + 0x0, 0x76, 0x0, 0x4a, 0x0, 0x0, 0x76, 0x0, + 0x76, 0x2c, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x76, + 0x0, 0x0, 0x0, + + /* U+5E38 "常" */ + 0x8, 0x30, 0x4, 0xa0, 0x6, 0x50, 0x4, 0xd0, + 0x4, 0xa0, 0x2d, 0x10, 0x9a, 0xda, 0xac, 0xea, + 0xbc, 0xa9, 0xe2, 0x22, 0x22, 0x22, 0x22, 0x4d, + 0xe0, 0xab, 0xbb, 0xbb, 0xb9, 0x1d, 0x60, 0xe0, + 0x0, 0x0, 0x1d, 0x5, 0x0, 0xea, 0xaa, 0xaa, + 0xbd, 0x0, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0xb, 0xbb, 0xbc, 0xeb, 0xbb, 0xb0, 0xd, 0x22, + 0x25, 0xc2, 0x22, 0xe0, 0xc, 0x0, 0x3, 0xb0, + 0x0, 0xd0, 0xc, 0x0, 0x3, 0xb0, 0x11, 0xe0, + 0x8, 0x0, 0x3, 0xb0, 0x9b, 0x70, + + /* U+5E45 "幅" */ + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x0, 0xcc, 0xcc, 0xcc, 0xc4, 0x0, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0xdf, 0xd8, 0x3e, 0xbb, + 0xbd, 0x80, 0xb0, 0xc3, 0x83, 0x90, 0x0, 0x48, + 0xb, 0xc, 0x38, 0x3e, 0xbb, 0xbd, 0x80, 0xb0, + 0xc3, 0x80, 0x0, 0x0, 0x0, 0xb, 0xc, 0x38, + 0xac, 0xcc, 0xcc, 0xc1, 0xb0, 0xc3, 0x8d, 0x0, + 0xd0, 0xb, 0x2b, 0xc, 0xb4, 0xda, 0xaf, 0xaa, + 0xe2, 0x0, 0xc0, 0xd, 0x11, 0xd1, 0x1c, 0x20, + 0xc, 0x0, 0xd0, 0xd, 0x0, 0xb2, 0x0, 0xc0, + 0xd, 0xcc, 0xcc, 0xce, 0x20, + + /* U+5E73 "平" */ + 0x5, 0xee, 0xee, 0xee, 0xee, 0xee, 0x90, 0x0, + 0x1, 0x0, 0x59, 0x0, 0x12, 0x0, 0x0, 0x2d, + 0x0, 0x59, 0x0, 0x88, 0x0, 0x0, 0xa, 0x50, + 0x59, 0x0, 0xe1, 0x0, 0x0, 0x4, 0xb0, 0x59, + 0x7, 0x70, 0x0, 0x0, 0x0, 0x10, 0x59, 0x2, + 0x0, 0x0, 0x1e, 0xee, 0xee, 0xff, 0xee, 0xee, + 0xe6, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x0, 0x0, + + /* U+5E74 "年" */ + 0x0, 0x1, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0xee, 0xef, 0xfe, 0xee, 0xb0, 0x0, 0xa8, 0x0, + 0xa, 0x30, 0x0, 0x0, 0x8, 0xc0, 0x0, 0xa, + 0x30, 0x0, 0x0, 0x7, 0x1b, 0xee, 0xef, 0xee, + 0xee, 0x50, 0x0, 0xc, 0x10, 0xa, 0x30, 0x0, + 0x0, 0x0, 0xc, 0x10, 0xa, 0x30, 0x0, 0x0, + 0x0, 0xc, 0x10, 0xa, 0x30, 0x0, 0x0, 0x1e, + 0xee, 0xee, 0xef, 0xee, 0xee, 0xe7, 0x0, 0x0, + 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, + 0x30, 0x0, 0x0, + + /* U+5E78 "幸" */ + 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x8d, + 0xdd, 0xef, 0xdd, 0xdd, 0x10, 0x0, 0x0, 0x0, + 0x4a, 0x0, 0x0, 0x0, 0x1d, 0xdd, 0xdd, 0xef, + 0xdd, 0xdd, 0xd7, 0x0, 0x3, 0xa0, 0x0, 0x4, + 0x90, 0x0, 0x0, 0x0, 0xd3, 0x0, 0xc, 0x40, + 0x0, 0x0, 0xcd, 0xed, 0xdd, 0xdf, 0xdd, 0x60, + 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x9, 0xdd, + 0xdd, 0xef, 0xdd, 0xdd, 0xd1, 0x0, 0x0, 0x0, + 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4a, + 0x0, 0x0, 0x0, + + /* U+5E7E "幾" */ + 0x0, 0x9, 0x0, 0x85, 0x1, 0x90, 0x0, 0x0, + 0x57, 0x0, 0x76, 0x8, 0x33, 0x20, 0x1, 0xb0, + 0xb3, 0x67, 0x3a, 0x3c, 0x10, 0xb, 0xcd, 0x60, + 0x58, 0x79, 0xe5, 0x10, 0x0, 0x58, 0x28, 0x3b, + 0x9, 0x45, 0x90, 0x6, 0xe9, 0xae, 0x2e, 0x8d, + 0xc9, 0xc1, 0x3, 0x39, 0x43, 0x2c, 0x22, 0xc4, + 0x10, 0x1c, 0xce, 0xdc, 0xcf, 0xdc, 0xdd, 0xc5, + 0x0, 0xd, 0x10, 0x3, 0xc0, 0x55, 0x0, 0x0, + 0x2f, 0xa1, 0x0, 0xc5, 0xd1, 0x0, 0x0, 0x78, + 0x5d, 0x10, 0x8f, 0x20, 0x25, 0x2, 0xe1, 0x2, + 0x4c, 0xaa, 0xa1, 0x67, 0xc, 0x30, 0x7, 0xb3, + 0x0, 0x8d, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5E83 "広" */ + 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x60, 0x0, 0x0, 0x0, 0xde, + 0xee, 0xee, 0xfe, 0xee, 0xe5, 0x0, 0xe0, 0x0, + 0x2, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0xe, + 0x20, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x4c, 0x0, + 0x0, 0x0, 0x0, 0xe0, 0x0, 0xb5, 0x0, 0x0, + 0x0, 0x0, 0xe0, 0x1, 0xe0, 0x5, 0x30, 0x0, + 0x1, 0xc0, 0x9, 0x60, 0x3, 0xd1, 0x0, 0x3, + 0xb0, 0x1d, 0x0, 0x0, 0x8a, 0x0, 0x7, 0x70, + 0xa5, 0x0, 0x12, 0x4f, 0x40, 0xd, 0x34, 0xfc, + 0xdd, 0xca, 0x98, 0xc0, 0x1a, 0x1, 0x42, 0x0, + 0x0, 0x0, 0xa1, + + /* U+5E86 "庆" */ + 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, 0x1, 0xfe, + 0xee, 0xee, 0xee, 0xee, 0xe7, 0x1, 0xc0, 0x0, + 0x0, 0x50, 0x0, 0x0, 0x1, 0xc0, 0x0, 0x3, + 0xc0, 0x0, 0x0, 0x1, 0xc0, 0x0, 0x5, 0xb0, + 0x0, 0x0, 0x2, 0xc4, 0xdd, 0xde, 0xfd, 0xdd, + 0xd3, 0x3, 0xb0, 0x0, 0xb, 0xe0, 0x0, 0x0, + 0x4, 0xa0, 0x0, 0xe, 0x87, 0x0, 0x0, 0x5, + 0x90, 0x0, 0x89, 0xc, 0x30, 0x0, 0x8, 0x60, + 0x3, 0xe1, 0x2, 0xd2, 0x0, 0xd, 0x20, 0x4e, + 0x30, 0x0, 0x5e, 0x40, 0x3c, 0x9, 0xc2, 0x0, + 0x0, 0x4, 0xd6, 0x1, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5E95 "底" */ + 0x0, 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, 0x0, + 0x11, 0x11, 0x1d, 0x31, 0x11, 0x10, 0x0, 0xfc, + 0xcc, 0xcc, 0xcc, 0xcc, 0xc6, 0x0, 0xd0, 0x0, + 0x12, 0x35, 0x67, 0x0, 0x0, 0xd0, 0xcc, 0xba, + 0xd9, 0x42, 0x0, 0x1, 0xd0, 0xc1, 0x0, 0x95, + 0x0, 0x0, 0x1, 0xc0, 0xc1, 0x0, 0x76, 0x0, + 0x0, 0x2, 0xb0, 0xcd, 0xdd, 0xee, 0xdd, 0xb0, + 0x3, 0xa0, 0xc1, 0x0, 0x1c, 0x0, 0x0, 0x4, + 0x90, 0xc1, 0x3, 0xc, 0x10, 0x0, 0x8, 0x60, + 0xc1, 0x7, 0x66, 0x80, 0x56, 0xc, 0x20, 0xd9, + 0xc4, 0xd0, 0xd3, 0x87, 0x2c, 0x1, 0xb5, 0x0, + 0x72, 0x2c, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5E97 "店" */ + 0x0, 0x0, 0x0, 0x26, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x20, 0x0, 0x0, 0x0, 0xfe, + 0xee, 0xee, 0xee, 0xee, 0xe5, 0x0, 0xf0, 0x0, + 0x7, 0x10, 0x0, 0x0, 0x0, 0xf0, 0x0, 0xc, + 0x20, 0x0, 0x0, 0x0, 0xf0, 0x0, 0xc, 0xed, + 0xdd, 0xa0, 0x0, 0xe0, 0x0, 0xc, 0x20, 0x0, + 0x0, 0x1, 0xd0, 0x0, 0xc, 0x20, 0x0, 0x0, + 0x2, 0xc0, 0xed, 0xdd, 0xdd, 0xdf, 0x10, 0x4, + 0xa0, 0xe0, 0x0, 0x0, 0xd, 0x10, 0x8, 0x70, + 0xe0, 0x0, 0x0, 0xd, 0x10, 0xe, 0x30, 0xeb, + 0xbb, 0xbb, 0xbf, 0x10, 0x2c, 0x0, 0xe1, 0x11, + 0x11, 0x1d, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5E9C "府" */ + 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x2, 0xfe, + 0xee, 0xee, 0xee, 0xee, 0xe7, 0x2, 0xc0, 0x3, + 0x80, 0x0, 0xa, 0x0, 0x2, 0xc0, 0xb, 0x50, + 0x0, 0xd, 0x0, 0x2, 0xc0, 0x3e, 0x3d, 0xdd, + 0xef, 0xd7, 0x2, 0xc1, 0xee, 0x0, 0x0, 0xd, + 0x0, 0x3, 0xb9, 0x6e, 0x6, 0x50, 0xd, 0x0, + 0x3, 0xa0, 0xe, 0x1, 0xd0, 0xd, 0x0, 0x4, + 0x90, 0xe, 0x0, 0x77, 0xd, 0x0, 0x7, 0x70, + 0xe, 0x0, 0x0, 0xd, 0x0, 0xb, 0x40, 0xe, + 0x0, 0x0, 0x1d, 0x0, 0x1c, 0x0, 0xe, 0x0, + 0xd, 0xe9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5EA6 "度" */ + 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, + 0x11, 0x11, 0x1a, 0x71, 0x11, 0x10, 0x0, 0xfc, + 0xcc, 0xdc, 0xcc, 0xdc, 0xc6, 0x0, 0xe0, 0x2, + 0xb0, 0x0, 0xe0, 0x0, 0x0, 0xe8, 0xcd, 0xfc, + 0xcc, 0xfc, 0xc3, 0x0, 0xe0, 0x2, 0xb0, 0x0, + 0xe0, 0x0, 0x0, 0xe0, 0x2, 0xd7, 0x77, 0xf0, + 0x0, 0x1, 0xd0, 0x0, 0x44, 0x44, 0x40, 0x0, + 0x2, 0xc5, 0xcc, 0xcc, 0xcc, 0xcc, 0x10, 0x4, + 0xa0, 0x8, 0x80, 0x0, 0x98, 0x0, 0x7, 0x70, + 0x0, 0x9b, 0x4b, 0x70, 0x0, 0xc, 0x30, 0x36, + 0x9e, 0xdd, 0x74, 0x0, 0x1b, 0xc, 0xb8, 0x50, + 0x2, 0x7b, 0xe5, + + /* U+5EA7 "座" */ + 0x0, 0x0, 0x0, 0x34, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xd0, 0x0, 0x0, 0x9, 0xed, 0xdd, + 0xdd, 0xdd, 0xdd, 0xc0, 0x94, 0x1, 0x10, 0x60, + 0x2, 0x0, 0x9, 0x40, 0xa4, 0xd, 0x0, 0xe0, + 0x0, 0xa4, 0xe, 0x20, 0xd0, 0x5b, 0x0, 0xa, + 0x47, 0xac, 0x1d, 0x1c, 0x99, 0x0, 0xb6, 0xb0, + 0x38, 0xdb, 0x50, 0x6a, 0xc, 0x21, 0x0, 0xd, + 0x10, 0x0, 0x10, 0xd1, 0xad, 0xdd, 0xfd, 0xdd, + 0xd1, 0xd, 0x0, 0x0, 0xd, 0x0, 0x0, 0x4, + 0xa0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xa4, 0x8d, + 0xdd, 0xdf, 0xdd, 0xdd, 0xc1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5EAB "庫" */ + 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, 0x1, + 0xaa, 0xaa, 0xad, 0xea, 0xaa, 0xa2, 0x1, 0xd1, + 0x11, 0x12, 0x61, 0x11, 0x10, 0x1, 0xc2, 0x66, + 0x67, 0xe6, 0x66, 0x60, 0x1, 0xc2, 0x55, 0x55, + 0xe5, 0x55, 0x40, 0x1, 0xc0, 0x8a, 0xaa, 0xfa, + 0xaa, 0x10, 0x2, 0xb0, 0xd0, 0x0, 0xd0, 0xb, + 0x20, 0x3, 0xa0, 0xda, 0xaa, 0xfa, 0xae, 0x20, + 0x4, 0x90, 0xd3, 0x33, 0xe3, 0x3c, 0x20, 0x5, + 0x80, 0x56, 0x67, 0xe6, 0x66, 0x10, 0x9, 0x59, + 0x99, 0x9a, 0xf9, 0x99, 0x93, 0xd, 0x12, 0x22, + 0x23, 0xe2, 0x22, 0x20, 0x2a, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5EAD "庭" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x10, 0x0, 0x0, 0x1, 0xaa, + 0xaa, 0xad, 0xca, 0xaa, 0xa5, 0x2, 0xc3, 0x33, + 0x33, 0x33, 0x33, 0x31, 0x2, 0xb6, 0xaa, 0x71, + 0x36, 0x9c, 0x50, 0x2, 0xb1, 0x2c, 0x36, 0x8a, + 0x90, 0x0, 0x2, 0xb0, 0x58, 0x0, 0x5, 0x80, + 0x0, 0x3, 0xb3, 0xea, 0x74, 0xac, 0xda, 0x90, + 0x3, 0xa2, 0x24, 0xa0, 0x26, 0x92, 0x10, 0x4, + 0x94, 0x46, 0x60, 0x5, 0x80, 0x0, 0x6, 0x82, + 0xbb, 0x11, 0x16, 0x91, 0x10, 0x8, 0x50, 0xba, + 0xa, 0xbb, 0xbb, 0xb1, 0xc, 0x23, 0xdd, 0x81, + 0x0, 0x0, 0x0, 0x1c, 0x2d, 0x21, 0x7c, 0xdd, + 0xdd, 0xd6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5EB7 "康" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, 0x1, 0xaa, + 0xaa, 0xaf, 0xca, 0xaa, 0xa2, 0x1, 0xd2, 0x22, + 0x2b, 0x52, 0x22, 0x20, 0x1, 0xc3, 0xaa, 0xae, + 0xba, 0xaa, 0x0, 0x1, 0xc0, 0x0, 0xb, 0x40, + 0xe, 0x0, 0x1, 0xdb, 0xbb, 0xbe, 0xcb, 0xbf, + 0xc5, 0x2, 0xb0, 0x0, 0xb, 0x30, 0xe, 0x10, + 0x3, 0xa5, 0xbb, 0xbe, 0xcb, 0xbf, 0x0, 0x4, + 0x94, 0x70, 0xb, 0x80, 0x7, 0x30, 0x6, 0x80, + 0x6a, 0x1c, 0xd7, 0xb6, 0x0, 0x9, 0x40, 0x4b, + 0xad, 0x48, 0xa1, 0x0, 0xd, 0x2c, 0x81, 0xb, + 0x30, 0x4b, 0xb2, 0x29, 0x0, 0xa, 0xcd, 0x10, + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5EE0 "廠" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x69, 0x0, 0x0, 0x0, 0x7, 0xaa, + 0xaa, 0xbf, 0xba, 0xaa, 0xa3, 0xb, 0x31, 0x24, + 0x11, 0x13, 0x21, 0x10, 0xb, 0x36, 0xc, 0x9, + 0x9, 0x50, 0x0, 0xb, 0x2b, 0x2c, 0x76, 0xd, + 0x10, 0x0, 0xb, 0x23, 0x3c, 0x51, 0x3f, 0xcd, + 0xe4, 0xc, 0x4c, 0x88, 0x8d, 0xce, 0x5, 0x80, + 0xc, 0x37, 0x79, 0x5a, 0x98, 0x48, 0x40, 0xd, + 0x37, 0x81, 0x8a, 0x12, 0x9d, 0x0, 0xd, 0x27, + 0x80, 0x8a, 0x10, 0xd9, 0x0, 0x1b, 0x27, 0xaa, + 0x7a, 0x10, 0xd8, 0x0, 0x68, 0x27, 0x10, 0xa, + 0x2b, 0x5b, 0x50, 0x82, 0x27, 0x1, 0xbb, 0xc5, + 0x1, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5EFA "建" */ + 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x1d, + 0xdf, 0x75, 0xbb, 0xfc, 0xbb, 0x20, 0x0, 0xd, + 0x10, 0x0, 0xd1, 0xa, 0x20, 0x0, 0x77, 0x5c, + 0xcc, 0xfc, 0xce, 0xc2, 0x1, 0xd0, 0x0, 0x0, + 0xd0, 0xa, 0x20, 0xc, 0xed, 0x76, 0xcc, 0xfc, + 0xce, 0x20, 0x1, 0x7, 0x60, 0x0, 0xd0, 0x0, + 0x0, 0x8, 0xa, 0x38, 0xbb, 0xfb, 0xbb, 0x60, + 0x7, 0x6d, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x1, + 0xd9, 0x4c, 0xcc, 0xfc, 0xcc, 0xc0, 0x0, 0xcb, + 0x10, 0x0, 0xd0, 0x0, 0x0, 0x6, 0x93, 0xc6, + 0x10, 0x10, 0x0, 0x0, 0x3d, 0x10, 0x7, 0xbd, + 0xdd, 0xdd, 0xd2, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5EFF "廿" */ + 0x0, 0x5, 0x90, 0x0, 0x3, 0xc0, 0x0, 0x0, + 0x5, 0x90, 0x0, 0x3, 0xc0, 0x0, 0x0, 0x5, + 0x90, 0x0, 0x3, 0xc0, 0x0, 0x0, 0x5, 0x90, + 0x0, 0x3, 0xc0, 0x0, 0x1f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf6, 0x0, 0x5, 0x90, 0x0, 0x3, + 0xc0, 0x0, 0x0, 0x5, 0x90, 0x0, 0x3, 0xc0, + 0x0, 0x0, 0x5, 0x90, 0x0, 0x3, 0xc0, 0x0, + 0x0, 0x5, 0x90, 0x0, 0x3, 0xc0, 0x0, 0x0, + 0x5, 0x90, 0x0, 0x3, 0xc0, 0x0, 0x0, 0x5, + 0x90, 0x0, 0x3, 0xc0, 0x0, 0x0, 0x5, 0xff, + 0xff, 0xff, 0xc0, 0x0, 0x0, 0x5, 0x90, 0x0, + 0x3, 0xb0, 0x0, + + /* U+5F0F "式" */ + 0x0, 0x0, 0x0, 0x0, 0xf0, 0xa2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf0, 0x3e, 0x30, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x4, 0x30, 0x3e, 0xee, 0xee, + 0xee, 0xfe, 0xee, 0xe3, 0x0, 0x0, 0x0, 0x0, + 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb4, + 0x0, 0x0, 0xa, 0xee, 0xfe, 0xe7, 0x96, 0x0, + 0x0, 0x0, 0x2, 0xc0, 0x0, 0x68, 0x0, 0x0, + 0x0, 0x2, 0xc0, 0x0, 0x2c, 0x0, 0x0, 0x0, + 0x2, 0xc0, 0x0, 0xe, 0x10, 0x22, 0x0, 0x2, + 0xd5, 0x8a, 0x9, 0x70, 0x67, 0x7, 0xbe, 0xc9, + 0x51, 0x2, 0xe3, 0x94, 0x6, 0x30, 0x0, 0x0, + 0x0, 0x5e, 0xc0, + + /* U+5F15 "引" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe4, 0xdd, 0xdd, + 0xec, 0x0, 0xe, 0x0, 0x0, 0x1, 0xc0, 0x0, + 0xe0, 0x0, 0x0, 0x1c, 0x0, 0xe, 0xc, 0xed, + 0xde, 0xc0, 0x0, 0xe0, 0xe0, 0x0, 0x0, 0x0, + 0xe, 0x2c, 0x0, 0x0, 0x0, 0x0, 0xe6, 0xfd, + 0xdd, 0xdb, 0x0, 0xe, 0x0, 0x0, 0x3, 0xb0, + 0x0, 0xe0, 0x0, 0x0, 0x4a, 0x0, 0xe, 0x0, + 0x0, 0x7, 0x80, 0x0, 0xe0, 0x0, 0x0, 0xb5, + 0x0, 0xe, 0x0, 0x8e, 0xfb, 0x0, 0x0, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5F1F "弟" */ + 0x0, 0x6, 0x70, 0x0, 0x3, 0xa0, 0x0, 0x0, + 0x1e, 0x10, 0x0, 0xb4, 0x0, 0x5, 0xcc, 0xed, + 0xcc, 0xcf, 0xcc, 0x20, 0x1, 0x11, 0x14, 0xb1, + 0x11, 0xb3, 0x0, 0x0, 0x0, 0x3b, 0x0, 0xb, + 0x30, 0x8, 0xdd, 0xde, 0xfd, 0xdd, 0xf3, 0x0, + 0xc2, 0x0, 0x3b, 0x0, 0x0, 0x0, 0xe, 0x0, + 0x3, 0xb0, 0x0, 0x0, 0x3, 0xdd, 0xdd, 0xff, + 0xdd, 0xde, 0xd0, 0x0, 0x0, 0xad, 0xb0, 0x0, + 0x2c, 0x0, 0x4, 0xd7, 0x3b, 0x0, 0x6, 0x90, + 0x8e, 0xb3, 0x3, 0xb0, 0x8b, 0xe4, 0x6, 0x20, + 0x0, 0x3b, 0x0, 0x10, 0x0, + + /* U+5F31 "弱" */ + 0xd, 0xdd, 0xdf, 0x27, 0xdd, 0xdd, 0xb0, 0x0, + 0x0, 0xc2, 0x0, 0x0, 0x3b, 0x7, 0xbb, 0xbf, + 0x27, 0xbb, 0xbc, 0xb0, 0xa4, 0x11, 0x10, 0xa5, + 0x11, 0x11, 0xb, 0x20, 0x0, 0xa, 0x20, 0x0, + 0x0, 0xcd, 0xcc, 0xc2, 0xad, 0xcc, 0xcb, 0x4, + 0x30, 0xc, 0x23, 0x30, 0x1, 0xd0, 0x4a, 0xc3, + 0xd1, 0x39, 0xd6, 0x2c, 0x0, 0x4, 0x8f, 0x0, + 0x1, 0x8a, 0xb1, 0x7c, 0xb6, 0xe0, 0x49, 0xc8, + 0x79, 0x27, 0x10, 0x4b, 0x6, 0x30, 0x8, 0x70, + 0x4, 0xdd, 0x40, 0x5, 0xbb, 0xd2, 0x0, 0x0, + 0x0, 0x0, 0x1, 0x10, 0x0, + + /* U+5F35 "張" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, + 0xdd, 0xc0, 0x9d, 0xcc, 0xcc, 0xc0, 0x0, 0x0, + 0xc0, 0x94, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, + 0x9c, 0xbb, 0xbb, 0x50, 0xa, 0xdd, 0xc0, 0x94, + 0x0, 0x0, 0x0, 0xd, 0x11, 0x10, 0x9d, 0xbb, + 0xbb, 0x50, 0xd, 0x0, 0x2, 0xa7, 0x33, 0x33, + 0x30, 0xe, 0xdd, 0xa6, 0xf8, 0xda, 0x88, 0x82, + 0x0, 0x1, 0xc0, 0xd0, 0x4a, 0x7, 0x80, 0x0, + 0x2, 0xb0, 0xd0, 0xa, 0xb9, 0x0, 0x0, 0x4, + 0x90, 0xd0, 0x1, 0xd4, 0x0, 0x0, 0x7, 0x70, + 0xe6, 0xb4, 0x1d, 0x80, 0x9, 0xdd, 0x21, 0xd7, + 0x10, 0x0, 0x93, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5F37 "強" */ + 0x0, 0x0, 0x0, 0x0, 0x72, 0x0, 0x0, 0x2d, + 0xdd, 0xf1, 0x4, 0xc0, 0x22, 0x0, 0x0, 0x0, + 0xc1, 0xc, 0x20, 0x2c, 0x10, 0x0, 0x0, 0xc1, + 0xba, 0x78, 0xad, 0xb0, 0x7, 0x99, 0xe1, 0x87, + 0x5b, 0x21, 0xa3, 0xd, 0x44, 0x40, 0x0, 0xe, + 0x0, 0x0, 0xd, 0x0, 0x0, 0xfc, 0xcf, 0xcc, + 0xd0, 0x2d, 0x77, 0x71, 0xd0, 0xe, 0x0, 0xd0, + 0x16, 0x66, 0xd2, 0xe2, 0x2e, 0x22, 0xd0, 0x0, + 0x0, 0xd1, 0xaa, 0xaf, 0xaa, 0x90, 0x0, 0x0, + 0xe0, 0x0, 0xe, 0xa, 0x30, 0x0, 0x2, 0xd0, + 0x0, 0xe, 0x37, 0xd0, 0x2, 0xdd, 0x68, 0xed, + 0xca, 0x86, 0x97, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5F53 "当" */ + 0x2, 0x0, 0xb, 0x40, 0x0, 0x50, 0x2d, 0x0, + 0xb, 0x40, 0x5, 0xb0, 0x8, 0x90, 0xb, 0x40, + 0xd, 0x30, 0x1, 0xe1, 0xb, 0x40, 0x79, 0x0, + 0x0, 0x10, 0xb, 0x40, 0x21, 0x0, 0x4e, 0xee, + 0xef, 0xfe, 0xee, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xe0, + 0xc, 0xee, 0xee, 0xee, 0xee, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe0, 0x23, 0x33, 0x33, 0x33, 0x34, 0xe0, + 0x6b, 0xbb, 0xbb, 0xbb, 0xbb, 0xe0, + + /* U+5F62 "形" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x30, 0x4d, + 0xfe, 0xde, 0xfc, 0x0, 0x6d, 0x10, 0x0, 0xa3, + 0x6, 0x80, 0x8, 0xd1, 0x0, 0x0, 0xa3, 0x6, + 0x80, 0xc9, 0x0, 0x0, 0x0, 0xa3, 0x6, 0x80, + 0x0, 0x0, 0x60, 0x0, 0xa4, 0x6, 0x80, 0x0, + 0x1c, 0x60, 0x6d, 0xfe, 0xde, 0xed, 0x12, 0xc6, + 0x0, 0x0, 0xb2, 0x6, 0x80, 0x7d, 0x30, 0x0, + 0x0, 0xd0, 0x6, 0x80, 0x20, 0x0, 0x72, 0x0, + 0xd0, 0x6, 0x80, 0x0, 0x7, 0xb0, 0x5, 0xa0, + 0x6, 0x80, 0x0, 0x9b, 0x0, 0xd, 0x30, 0x6, + 0x80, 0x5d, 0x70, 0x0, 0x58, 0x0, 0x6, 0x85, + 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5F71 "影" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, + 0xda, 0xaa, 0xbc, 0x0, 0x1c, 0x50, 0x6, 0xc9, + 0x99, 0xac, 0x2, 0xc6, 0x0, 0x6, 0x70, 0x0, + 0x1c, 0x5d, 0x40, 0x0, 0x4, 0xaa, 0xda, 0xa8, + 0x1, 0x0, 0x60, 0x17, 0x77, 0xf7, 0x77, 0x20, + 0xb, 0x70, 0x4, 0x44, 0x44, 0x44, 0x13, 0xc6, + 0x0, 0x5, 0xdb, 0xbb, 0xca, 0x5d, 0x30, 0x0, + 0x5, 0x80, 0x0, 0x4a, 0x0, 0x0, 0x41, 0x3, + 0xaa, 0xfb, 0xa7, 0x0, 0x3, 0xc0, 0x2, 0xb0, + 0xd1, 0xb0, 0x0, 0x4d, 0x10, 0xc, 0x40, 0xd1, + 0x49, 0x1a, 0xb1, 0x0, 0x4, 0x1c, 0xd0, 0x2, + 0xb6, 0x0, 0x0, + + /* U+5F79 "役" */ + 0x0, 0x3, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0x10, 0xbe, 0xdd, 0xf1, 0x0, 0x3, 0xd3, + 0x0, 0xc2, 0x0, 0xd1, 0x0, 0xb, 0x22, 0x40, + 0xf0, 0x0, 0xd1, 0x0, 0x0, 0xd, 0x48, 0x90, + 0x0, 0xb8, 0x73, 0x0, 0xab, 0x7a, 0x0, 0x0, + 0x4, 0x41, 0xb, 0xca, 0x2b, 0xbb, 0xbb, 0xbc, + 0x30, 0x19, 0x3a, 0x7, 0xa2, 0x22, 0x3e, 0x0, + 0x0, 0x3a, 0x0, 0xd3, 0x0, 0xb7, 0x0, 0x0, + 0x3a, 0x0, 0x3d, 0x3a, 0x90, 0x0, 0x0, 0x3a, + 0x0, 0x7, 0xfd, 0x0, 0x0, 0x0, 0x3a, 0x4, + 0xbd, 0x6b, 0xd6, 0x10, 0x0, 0x3a, 0xca, 0x50, + 0x0, 0x49, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5F7C "彼" */ + 0x0, 0x2b, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x1d, + 0x40, 0x0, 0xe, 0x0, 0x0, 0x2d, 0x60, 0xc, + 0xdd, 0xfd, 0xdd, 0x74, 0x50, 0x91, 0xe0, 0xe, + 0x0, 0xa4, 0x0, 0x5c, 0xe, 0x0, 0xe0, 0xd, + 0x0, 0x1e, 0x40, 0xe0, 0xe, 0x0, 0x40, 0x1d, + 0xf2, 0xf, 0xfd, 0xdd, 0xec, 0x8, 0x8c, 0x20, + 0xe8, 0x40, 0x7, 0x60, 0x0, 0xc2, 0x1c, 0x1c, + 0x1, 0xd1, 0x0, 0xc, 0x24, 0xa0, 0x78, 0xb5, + 0x0, 0x0, 0xc2, 0x86, 0x1, 0xec, 0x0, 0x0, + 0xc, 0x3e, 0x14, 0xd6, 0x9c, 0x40, 0x0, 0xc5, + 0x77, 0xa2, 0x0, 0x3a, 0x80, + + /* U+5F80 "往" */ + 0x0, 0x4, 0x30, 0x0, 0x80, 0x0, 0x0, 0x0, + 0x3d, 0x10, 0x0, 0x97, 0x0, 0x0, 0x4, 0xd3, + 0x0, 0x0, 0x1a, 0x0, 0x0, 0xb, 0x21, 0x4d, + 0xee, 0xef, 0xee, 0xe3, 0x0, 0xa, 0x60, 0x0, + 0x4a, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x4a, + 0x0, 0x0, 0x7, 0xfb, 0x0, 0x0, 0x4a, 0x0, + 0x0, 0x2c, 0x5b, 0x5, 0xee, 0xef, 0xee, 0xb0, + 0x0, 0x3b, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, + 0x3b, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x3b, + 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x3b, 0x0, + 0x0, 0x4a, 0x0, 0x0, 0x0, 0x3b, 0x4e, 0xee, + 0xef, 0xee, 0xe8, + + /* U+5F85 "待" */ + 0x0, 0x8, 0x60, 0x0, 0x3a, 0x0, 0x0, 0x0, + 0x4d, 0x0, 0x0, 0x3a, 0x0, 0x0, 0x5, 0xd2, + 0x5, 0xdd, 0xef, 0xdd, 0xd0, 0xb, 0x11, 0x50, + 0x0, 0x3a, 0x0, 0x0, 0x0, 0xb, 0x60, 0x0, + 0x3a, 0x0, 0x0, 0x0, 0x9d, 0x2d, 0xdd, 0xdd, + 0xef, 0xd9, 0xa, 0xdc, 0x0, 0x0, 0x0, 0x4a, + 0x0, 0x19, 0x2c, 0xd, 0xdd, 0xdd, 0xef, 0xd7, + 0x0, 0x2c, 0x0, 0x40, 0x0, 0x4a, 0x0, 0x0, + 0x2c, 0x0, 0x7a, 0x0, 0x4a, 0x0, 0x0, 0x2c, + 0x0, 0xc, 0x40, 0x4a, 0x0, 0x0, 0x2c, 0x0, + 0x2, 0x10, 0x4a, 0x0, 0x0, 0x2c, 0x0, 0x0, + 0x3d, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5F88 "很" */ + 0x0, 0x3, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3d, 0x20, 0xfd, 0xdd, 0xdf, 0x20, 0x6, 0xd2, + 0x0, 0xe0, 0x0, 0xc, 0x20, 0x8, 0x2, 0x80, + 0xfa, 0xaa, 0xae, 0x20, 0x0, 0xc, 0x50, 0xe1, + 0x11, 0x1c, 0x20, 0x0, 0x8c, 0x0, 0xe0, 0x0, + 0xc, 0x20, 0x9, 0xeb, 0x0, 0xfd, 0xdd, 0xdf, + 0x20, 0x2c, 0x4b, 0x0, 0xe0, 0x66, 0x0, 0x30, + 0x0, 0x2b, 0x0, 0xe0, 0x1c, 0x2c, 0x60, 0x0, + 0x2b, 0x0, 0xe0, 0x9, 0xc2, 0x0, 0x0, 0x2b, + 0x0, 0xe0, 0x1, 0xd2, 0x0, 0x0, 0x2b, 0x1, + 0xf7, 0xb7, 0x3e, 0x60, 0x0, 0x2b, 0x5, 0xc7, + 0x20, 0x2, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5F8B "律" */ + 0x0, 0x5, 0x60, 0x0, 0x86, 0x0, 0x0, 0x0, + 0x2d, 0x10, 0x0, 0x86, 0x0, 0x0, 0x3, 0xd3, + 0x8, 0xcc, 0xee, 0xcd, 0xb0, 0xc, 0x20, 0x40, + 0x0, 0x86, 0x3, 0xb0, 0x0, 0xa, 0x7c, 0xcc, + 0xee, 0xcd, 0xf9, 0x0, 0x6c, 0x0, 0x0, 0x86, + 0x3, 0xb0, 0x7, 0xeb, 0x9, 0xcc, 0xee, 0xcc, + 0x90, 0x2c, 0x3b, 0x0, 0x0, 0x86, 0x0, 0x0, + 0x0, 0x2b, 0x7, 0xcc, 0xee, 0xcc, 0xb0, 0x0, + 0x2b, 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0x2b, + 0x3c, 0xcc, 0xee, 0xcc, 0xc7, 0x0, 0x2b, 0x0, + 0x0, 0x86, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, + 0x86, 0x0, 0x0, + + /* U+5F8C "後" */ + 0x0, 0x18, 0x0, 0x4, 0x50, 0x0, 0x0, 0x0, + 0xb6, 0x0, 0x2c, 0x10, 0x20, 0x0, 0xb, 0x80, + 0x3, 0xc1, 0x5, 0xc2, 0x0, 0x56, 0xa, 0x5f, + 0xdb, 0xc9, 0x10, 0x0, 0x0, 0x6a, 0x1, 0x5a, + 0x30, 0x96, 0x0, 0x4, 0xf3, 0x4d, 0xe9, 0xab, + 0xbf, 0x50, 0x5d, 0xd2, 0x35, 0x5e, 0x30, 0x1, + 0xb0, 0x31, 0xb2, 0x0, 0xce, 0xaa, 0xa8, 0x0, + 0x0, 0xb2, 0x3d, 0xd4, 0x11, 0xc5, 0x0, 0x0, + 0xb3, 0xb3, 0x1c, 0x2b, 0x90, 0x0, 0x0, 0xb2, + 0x0, 0x5, 0xfc, 0x0, 0x0, 0x0, 0xb2, 0x5, + 0xbc, 0x59, 0xd6, 0x10, 0x0, 0xb3, 0xd9, 0x40, + 0x0, 0x28, 0xd2, + + /* U+5F92 "徒" */ + 0x0, 0x3a, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x1, + 0xd3, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x1d, 0x50, + 0xd, 0xdd, 0xfd, 0xdd, 0x40, 0x74, 0xa, 0x10, + 0x0, 0xd1, 0x0, 0x0, 0x0, 0x7a, 0x0, 0x0, + 0xd1, 0x0, 0x0, 0x5, 0xf3, 0xad, 0xdd, 0xfd, + 0xdd, 0xd1, 0x5e, 0xd3, 0x0, 0x0, 0xb2, 0x0, + 0x0, 0x72, 0xa3, 0xa, 0x20, 0xb2, 0x0, 0x0, + 0x0, 0xa3, 0xe, 0x0, 0xbd, 0xdd, 0x60, 0x0, + 0xa3, 0xf, 0x20, 0xb2, 0x0, 0x0, 0x0, 0xa3, + 0x4c, 0xb0, 0xb2, 0x0, 0x0, 0x0, 0xa3, 0xb2, + 0x8b, 0xc2, 0x0, 0x0, 0x0, 0xa7, 0x80, 0x5, + 0xbe, 0xdd, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5F93 "従" */ + 0x0, 0x2b, 0x0, 0xa0, 0x0, 0x9, 0x30, 0x1, + 0xd3, 0x0, 0x78, 0x0, 0x1d, 0x0, 0x3d, 0x40, + 0x0, 0xd, 0x10, 0x96, 0x0, 0x42, 0xc, 0x3b, + 0xbd, 0xbb, 0xdb, 0xb0, 0x0, 0x88, 0x2, 0x22, + 0x6b, 0x22, 0x20, 0x6, 0xf3, 0x0, 0x0, 0x49, + 0x0, 0x0, 0x7c, 0xc3, 0x3, 0xa0, 0x49, 0x0, + 0x0, 0x51, 0xa3, 0x4, 0x90, 0x4f, 0xee, 0xb0, + 0x0, 0xa3, 0x7, 0x70, 0x49, 0x0, 0x0, 0x0, + 0xa3, 0xa, 0xb0, 0x49, 0x0, 0x0, 0x0, 0xa3, + 0x1e, 0xb3, 0x49, 0x0, 0x0, 0x0, 0xa3, 0x87, + 0x2e, 0xa9, 0x0, 0x0, 0x0, 0xa5, 0xb0, 0x2, + 0xae, 0xee, 0xe2, + + /* U+5F97 "得" */ + 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3d, 0x20, 0xfb, 0xbb, 0xbd, 0x90, 0x7, 0xd2, + 0x0, 0xf9, 0x99, 0x9b, 0x90, 0x8, 0x3, 0x70, + 0xe1, 0x11, 0x16, 0x90, 0x0, 0x1d, 0x30, 0xf9, + 0x99, 0x9b, 0x90, 0x0, 0xbb, 0x0, 0x22, 0x22, + 0x22, 0x10, 0xc, 0xca, 0xb, 0xcc, 0xcc, 0xcc, + 0xc4, 0x38, 0x3a, 0x0, 0x0, 0x0, 0x76, 0x0, + 0x0, 0x3a, 0x3d, 0xdd, 0xdd, 0xee, 0xd7, 0x0, + 0x3a, 0x0, 0x71, 0x0, 0x76, 0x0, 0x0, 0x3a, + 0x0, 0x5c, 0x0, 0x76, 0x0, 0x0, 0x3a, 0x0, + 0x7, 0x30, 0x86, 0x0, 0x0, 0x3a, 0x0, 0x0, + 0x4d, 0xd3, 0x0, + + /* U+5F9E "從" */ + 0x0, 0x8, 0x0, 0x54, 0x0, 0x90, 0x0, 0x0, + 0xb6, 0x0, 0xb4, 0x2, 0xd0, 0x0, 0x1b, 0x70, + 0x1, 0xf1, 0x6, 0xa0, 0x0, 0x75, 0x8, 0x37, + 0xcb, 0x1c, 0xc6, 0x0, 0x0, 0x5b, 0x3f, 0x25, + 0xc7, 0xc, 0x60, 0x3, 0xf3, 0x95, 0x0, 0xb0, + 0x0, 0x90, 0x5e, 0xd3, 0x0, 0x20, 0xc1, 0x0, + 0x0, 0x72, 0xa3, 0x3, 0xa0, 0xc1, 0x0, 0x0, + 0x0, 0xa3, 0x5, 0x90, 0xcd, 0xcc, 0x30, 0x0, + 0xa3, 0x9, 0xb0, 0xc1, 0x0, 0x0, 0x0, 0xa3, + 0xd, 0xc2, 0xc1, 0x0, 0x0, 0x0, 0xa3, 0x79, + 0x2c, 0xd1, 0x0, 0x0, 0x0, 0xa5, 0xb0, 0x2, + 0xbd, 0xdd, 0xb0, + + /* U+5FA1 "御" */ + 0x0, 0x33, 0x6, 0x0, 0x0, 0x0, 0x0, 0x1d, + 0x22, 0xc0, 0x0, 0x27, 0x77, 0xc, 0x50, 0x7e, + 0xee, 0xd6, 0xa6, 0xe5, 0x52, 0x9d, 0x8, 0x40, + 0x57, 0xd, 0x0, 0xb6, 0x30, 0x84, 0x5, 0x70, + 0xd0, 0x7f, 0xd, 0xdf, 0xed, 0x77, 0xd, 0x5d, + 0xe0, 0x10, 0x84, 0x5, 0x70, 0xd4, 0x1d, 0x9, + 0x28, 0xba, 0x67, 0xd, 0x0, 0xd0, 0x92, 0x86, + 0x25, 0x70, 0xd0, 0xd, 0x9, 0x28, 0x40, 0x57, + 0xd, 0x0, 0xd0, 0x92, 0x85, 0x47, 0x7c, 0xb0, + 0xd, 0x3d, 0xdd, 0xb8, 0x87, 0x0, 0x0, 0xd1, + 0x20, 0x0, 0x5, 0x70, 0x0, + + /* U+5FA9 "復" */ + 0x0, 0x1a, 0x0, 0x94, 0x0, 0x0, 0x0, 0x1, + 0xc4, 0x2, 0xf8, 0x66, 0x66, 0x60, 0x2d, 0x50, + 0xa, 0xa5, 0x55, 0x55, 0x50, 0x53, 0xb, 0xbd, + 0xba, 0xaa, 0xaa, 0x0, 0x0, 0x7b, 0x22, 0xd0, + 0x0, 0xd, 0x0, 0x5, 0xf3, 0x0, 0xfa, 0xaa, + 0xaf, 0x0, 0x6d, 0xc3, 0x0, 0xe4, 0x44, 0x4e, + 0x0, 0x51, 0xa3, 0x0, 0x6e, 0x75, 0x55, 0x0, + 0x0, 0xa3, 0x0, 0x8f, 0xbb, 0xb9, 0x0, 0x0, + 0xa3, 0x1a, 0xbb, 0x10, 0xb6, 0x0, 0x0, 0xa3, + 0x56, 0x4, 0xcc, 0x70, 0x0, 0x0, 0xa3, 0x1, + 0x5a, 0xcc, 0xa4, 0x0, 0x0, 0xa3, 0x8c, 0x83, + 0x0, 0x49, 0xc0, + + /* U+5FC3 "心" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x90, 0x0, 0x0, 0x0, 0x0, 0x90, 0x0, + 0x80, 0x0, 0x0, 0x1, 0x60, 0xe1, 0x0, 0x0, + 0x1a, 0x0, 0x4, 0xa0, 0xe1, 0x0, 0x0, 0xd, + 0x30, 0x7, 0x70, 0xe1, 0x0, 0x0, 0x6, 0x90, + 0xb, 0x40, 0xe1, 0x0, 0x0, 0x1, 0xe0, 0xe, + 0x0, 0xe1, 0x0, 0x0, 0x90, 0xc3, 0x3a, 0x0, + 0xe1, 0x0, 0x1, 0xd0, 0x53, 0x0, 0x0, 0xd2, + 0x0, 0x4, 0xa0, 0x0, 0x0, 0x0, 0x8e, 0xee, + 0xee, 0x30, 0x0, + + /* U+5FC5 "必" */ + 0x0, 0x0, 0x52, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3d, 0x70, 0x0, 0x47, 0x0, 0x0, 0x0, + 0x1, 0xba, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x30, + 0x7, 0x7, 0x80, 0x0, 0x1, 0x30, 0xd1, 0x0, + 0x3d, 0x0, 0x0, 0x5, 0x90, 0xd1, 0x2, 0xd3, + 0x84, 0x0, 0x9, 0x50, 0xd1, 0x1d, 0x50, 0x2d, + 0x0, 0xe, 0x10, 0xd3, 0xd4, 0x0, 0x9, 0x70, + 0x69, 0x0, 0xdd, 0x40, 0x0, 0x2, 0xe0, 0x42, + 0x6, 0xf4, 0x0, 0x0, 0x60, 0xa2, 0x3, 0xcb, + 0xe1, 0x0, 0x2, 0xc0, 0x0, 0x6d, 0x50, 0xd2, + 0x0, 0x5, 0xa0, 0x0, 0x0, 0x0, 0x7f, 0xee, + 0xee, 0x30, 0x0, + + /* U+5FD8 "忘" */ + 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x79, 0x0, 0x0, 0x0, 0xe, 0xef, + 0xee, 0xee, 0xee, 0xee, 0xd0, 0x0, 0x3b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3b, 0x11, 0x11, 0x11, + 0x11, 0x0, 0x0, 0x2c, 0xcc, 0xcc, 0xcc, 0xcc, + 0x30, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x20, 0x7a, 0x0, 0x3, 0x0, 0x1, + 0xd2, 0xc0, 0xa, 0x60, 0xd, 0x30, 0x8, 0x71, + 0xc0, 0x1, 0x10, 0x54, 0xb0, 0x1e, 0x1, 0xd0, + 0x0, 0x1, 0xd0, 0xd2, 0x2, 0x0, 0xce, 0xdd, + 0xde, 0x70, 0x20, + + /* U+5FD9 "忙" */ + 0x0, 0xb1, 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, + 0xb1, 0x0, 0x0, 0x5c, 0x0, 0x0, 0x0, 0xb6, + 0x10, 0x0, 0x7, 0x10, 0x0, 0x29, 0xb7, 0x8e, + 0xee, 0xee, 0xee, 0xe2, 0x47, 0xb2, 0xc0, 0x95, + 0x0, 0x0, 0x0, 0x84, 0xb1, 0x20, 0x95, 0x0, + 0x0, 0x0, 0x60, 0xb1, 0x0, 0x95, 0x0, 0x0, + 0x0, 0x0, 0xb1, 0x0, 0x95, 0x0, 0x0, 0x0, + 0x0, 0xb1, 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, + 0xb1, 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, 0xb1, + 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, 0xb1, 0x0, + 0x9e, 0xdd, 0xdd, 0xd0, 0x0, 0xb1, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+5FEB "快" */ + 0x0, 0xc2, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, + 0xc2, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x2, 0xc9, + 0x7, 0xbb, 0xfb, 0xba, 0x0, 0x29, 0xca, 0x71, + 0x22, 0xe2, 0x2e, 0x0, 0x47, 0xc5, 0xe0, 0x0, + 0xd0, 0xd, 0x0, 0x74, 0xc2, 0x40, 0x0, 0xd0, + 0xd, 0x0, 0xa1, 0xc2, 0x0, 0x1, 0xd0, 0xe, + 0x0, 0x0, 0xc2, 0xbd, 0xdd, 0xfe, 0xdd, 0xd1, + 0x0, 0xc2, 0x0, 0x6, 0xda, 0x0, 0x0, 0x0, + 0xc2, 0x0, 0xd, 0x2c, 0x30, 0x0, 0x0, 0xc2, + 0x0, 0x99, 0x4, 0xc0, 0x0, 0x0, 0xc2, 0x1a, + 0xa0, 0x0, 0x9c, 0x20, 0x0, 0xc2, 0xc7, 0x0, + 0x0, 0x7, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5FF5 "念" */ + 0x0, 0x0, 0x0, 0x98, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xaa, 0x80, 0x0, 0x0, 0x0, 0x2, + 0xb7, 0x10, 0x6c, 0x40, 0x0, 0x3, 0xad, 0x40, + 0xb8, 0x3, 0xbc, 0x50, 0x2d, 0x60, 0x0, 0x7, + 0x10, 0x3, 0xb4, 0x0, 0x5d, 0xdd, 0xdd, 0xdd, + 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xa0, + 0x0, 0x0, 0x0, 0x5, 0x30, 0x4d, 0x10, 0x0, + 0x0, 0x0, 0x32, 0xd3, 0xa1, 0x2, 0x0, 0x1, + 0xd1, 0xd0, 0x3d, 0x10, 0x1d, 0x10, 0x6, 0x81, + 0xd0, 0x4, 0x10, 0x45, 0xa0, 0xd, 0x21, 0xe0, + 0x0, 0x1, 0xd0, 0xd2, 0x16, 0x0, 0xbe, 0xdd, + 0xde, 0x70, 0x31, + + /* U+600E "怎" */ + 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdd, 0xdf, + 0xdd, 0xdd, 0xdc, 0x0, 0x7b, 0x0, 0xe0, 0x0, + 0x0, 0x0, 0x5e, 0x10, 0xf, 0xcc, 0xcc, 0xc3, + 0x8, 0x30, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xcc, 0xcc, 0xc7, 0x0, 0x0, 0x0, + 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x10, + 0x0, 0x0, 0x0, 0xb0, 0xd0, 0x5d, 0x30, 0x3c, + 0x0, 0x2c, 0xe, 0x0, 0x28, 0x3, 0xa5, 0x9, + 0x60, 0xe0, 0x0, 0x0, 0xd2, 0xd0, 0x70, 0xa, + 0xed, 0xdd, 0xe7, 0x7, 0x10, + + /* U+6012 "怒" */ + 0x0, 0x9, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0x0, 0x1e, 0xed, 0xde, 0x70, 0x3d, 0xfe, + 0xde, 0x86, 0x80, 0xb, 0x30, 0x0, 0xe1, 0xb, + 0x31, 0xd0, 0x2d, 0x0, 0x8, 0xb0, 0x2c, 0x0, + 0x88, 0xc4, 0x0, 0x1, 0x8c, 0xd3, 0x0, 0xf, + 0xa0, 0x0, 0x0, 0x3d, 0xcb, 0x13, 0xc9, 0xd8, + 0x0, 0x1b, 0xc3, 0x5, 0x2b, 0x20, 0x19, 0xe1, + 0x2, 0x0, 0x5, 0xc3, 0x0, 0x0, 0x10, 0x0, + 0xb1, 0xd1, 0x3d, 0x50, 0x69, 0x0, 0x4, 0xb0, + 0xd1, 0x0, 0x5, 0x1c, 0x50, 0xd, 0x30, 0xd1, + 0x0, 0xc, 0x22, 0xe0, 0x26, 0x0, 0x8e, 0xdd, + 0xeb, 0x0, 0x62, + + /* U+6015 "怕" */ + 0x0, 0x2c, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, + 0x2c, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x2c, + 0x20, 0x0, 0x78, 0x0, 0x0, 0x7, 0x4c, 0xc0, + 0xee, 0xee, 0xee, 0xf1, 0xa, 0x3c, 0x65, 0xe0, + 0x0, 0x0, 0xd1, 0xc, 0x2c, 0x13, 0xe0, 0x0, + 0x0, 0xd1, 0x17, 0x2c, 0x0, 0xe0, 0x0, 0x0, + 0xd1, 0x0, 0x2c, 0x0, 0xed, 0xdd, 0xdd, 0xf1, + 0x0, 0x2c, 0x0, 0xe0, 0x0, 0x0, 0xd1, 0x0, + 0x2c, 0x0, 0xe0, 0x0, 0x0, 0xd1, 0x0, 0x2c, + 0x0, 0xe0, 0x0, 0x0, 0xd1, 0x0, 0x2c, 0x0, + 0xec, 0xcc, 0xcc, 0xf1, 0x0, 0x2c, 0x0, 0xe1, + 0x11, 0x11, 0xc1, + + /* U+601D "思" */ + 0x0, 0xed, 0xdd, 0xfd, 0xdd, 0xdf, 0x0, 0x0, + 0xd0, 0x0, 0xb3, 0x0, 0xe, 0x0, 0x0, 0xe9, + 0x99, 0xeb, 0x99, 0x9f, 0x0, 0x0, 0xe2, 0x22, + 0xc5, 0x22, 0x2e, 0x0, 0x0, 0xd0, 0x0, 0xb3, + 0x0, 0xe, 0x0, 0x0, 0xed, 0xdd, 0xfe, 0xdd, + 0xdf, 0x0, 0x0, 0x0, 0x4, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x34, 0xd8, 0x0, 0x13, 0x0, + 0x0, 0xd0, 0xe0, 0xb, 0xa0, 0x1d, 0x10, 0x5, + 0x90, 0xe0, 0x0, 0x12, 0x56, 0xa0, 0xd, 0x20, + 0xe0, 0x0, 0x5, 0x80, 0xe2, 0x5, 0x0, 0xae, + 0xdd, 0xde, 0x30, 0x31, + + /* U+6025 "急" */ + 0x0, 0x7, 0x70, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xfd, 0xcc, 0xcb, 0x0, 0x0, 0x3, 0xd3, 0x0, + 0x9, 0x80, 0x0, 0x5, 0xfd, 0xaa, 0xaa, 0xfa, + 0xa9, 0x0, 0x42, 0x11, 0x11, 0x11, 0x12, 0xd0, + 0x0, 0x8, 0x99, 0x99, 0x99, 0xad, 0x0, 0x0, + 0x11, 0x11, 0x11, 0x12, 0xd0, 0x0, 0x2, 0x22, + 0x22, 0x22, 0x2d, 0x0, 0x4, 0xaa, 0xab, 0xaa, + 0xaa, 0x90, 0x0, 0x20, 0x50, 0x98, 0x0, 0x5, + 0x20, 0xd, 0x2d, 0x0, 0xa8, 0x3, 0x4c, 0x8, + 0x81, 0xe0, 0x0, 0x40, 0xd1, 0xa5, 0x71, 0xb, + 0xdd, 0xdd, 0xea, 0x2, 0x30, + + /* U+6027 "性" */ + 0x0, 0xb2, 0x0, 0x30, 0x76, 0x0, 0x0, 0x0, + 0xb2, 0x0, 0xe0, 0x77, 0x0, 0x0, 0x2, 0xb7, + 0x13, 0xc0, 0x77, 0x0, 0x0, 0x29, 0xb6, 0x97, + 0xfe, 0xff, 0xee, 0xa0, 0x47, 0xb3, 0xbd, 0x20, + 0x77, 0x0, 0x0, 0x83, 0xb2, 0x5b, 0x0, 0x77, + 0x0, 0x0, 0x60, 0xb2, 0x1, 0x0, 0x77, 0x0, + 0x0, 0x0, 0xb2, 0x7, 0xdd, 0xee, 0xdd, 0x50, + 0x0, 0xb2, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, + 0xb2, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0xb2, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0xb2, 0x1, + 0x11, 0x88, 0x11, 0x10, 0x0, 0xb2, 0x7c, 0xcc, + 0xcc, 0xcc, 0xc0, + + /* U+606F "息" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0x0, 0xa, + 0xaa, 0xeb, 0xaa, 0xa2, 0x0, 0x0, 0xe, 0x11, + 0x11, 0x11, 0xb3, 0x0, 0x0, 0xf, 0xaa, 0xaa, + 0xaa, 0xe3, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, + 0xb3, 0x0, 0x0, 0xf, 0xbb, 0xbb, 0xbb, 0xe3, + 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0xa3, 0x0, + 0x0, 0xf, 0xcc, 0xcc, 0xcc, 0xe3, 0x0, 0x0, + 0x0, 0x0, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x61, + 0x80, 0x3d, 0x0, 0x1b, 0x0, 0x2, 0xc1, 0xc0, + 0x7, 0x50, 0x39, 0x70, 0xb, 0x51, 0xd0, 0x0, + 0x3, 0xa1, 0xe0, 0x6, 0x0, 0xce, 0xdd, 0xee, + 0x40, 0x10, + + /* U+60A8 "您" */ + 0x0, 0x0, 0x60, 0x24, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x70, 0xa8, 0x22, 0x22, 0x20, 0x0, 0x6d, + 0x5, 0xda, 0xad, 0xaa, 0xf3, 0x7, 0xea, 0x3d, + 0x10, 0xe, 0x2, 0x80, 0x1a, 0x4a, 0x0, 0x68, + 0xe, 0xc, 0x0, 0x0, 0x3a, 0x1, 0xd1, 0xe, + 0x6, 0x90, 0x0, 0x3a, 0xa, 0x50, 0xe, 0x0, + 0xd1, 0x0, 0x3a, 0x0, 0x7, 0xcb, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa6, 0x0, 0x0, 0x0, 0x0, + 0x71, 0xb0, 0xd, 0x30, 0xa, 0x40, 0x2, 0xd1, + 0xd0, 0x3, 0xa0, 0x34, 0xc0, 0xa, 0x61, 0xe0, + 0x0, 0x0, 0xb3, 0xc3, 0x8, 0x0, 0xbe, 0xdd, + 0xde, 0xc0, 0x32, + + /* U+60AA "悪" */ + 0xc, 0xcc, 0xdf, 0xcc, 0xfc, 0xcc, 0xc0, 0x0, + 0x0, 0xd, 0x0, 0xe0, 0x0, 0x0, 0x0, 0xfc, + 0xcf, 0xcc, 0xfc, 0xcf, 0x0, 0x0, 0xd0, 0xd, + 0x0, 0xe0, 0xd, 0x0, 0x0, 0xfa, 0xaf, 0xaa, + 0xfa, 0xaf, 0x0, 0x0, 0x11, 0x2e, 0x11, 0xe1, + 0x11, 0x0, 0x2, 0x22, 0x3e, 0x22, 0xe2, 0x22, + 0x20, 0x2a, 0xaa, 0xad, 0xca, 0xaa, 0xaa, 0xa2, + 0x0, 0x30, 0x44, 0xb8, 0x0, 0x51, 0x0, 0x0, + 0xd1, 0xb2, 0x7, 0x11, 0x5d, 0x20, 0x9, 0x90, + 0xb3, 0x0, 0xb, 0x25, 0xd0, 0x18, 0x0, 0x6e, + 0xdd, 0xec, 0x0, 0x61, + + /* U+60B2 "悲" */ + 0x0, 0x0, 0xe, 0x1, 0xe0, 0x0, 0x0, 0x9, + 0xaa, 0xaf, 0x1, 0xfa, 0xaa, 0xa0, 0x2, 0x22, + 0x2f, 0x1, 0xe2, 0x22, 0x20, 0x0, 0x11, 0x1f, + 0x1, 0xe1, 0x11, 0x0, 0x5, 0xbb, 0xbf, 0x1, + 0xfb, 0xbb, 0x50, 0x0, 0x0, 0xf, 0x1, 0xe0, + 0x0, 0x0, 0xc, 0xcc, 0xdf, 0x1, 0xfd, 0xdd, + 0xd2, 0x0, 0x0, 0xa, 0x0, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x40, 0xa5, 0x0, 0x20, 0x0, 0x0, + 0xb0, 0xe0, 0x1d, 0x20, 0x79, 0x0, 0x4, 0xa0, + 0xe0, 0x4, 0x82, 0x2c, 0x40, 0xd, 0x20, 0xe0, + 0x0, 0x7, 0x62, 0xe0, 0x5, 0x0, 0xae, 0xdd, + 0xde, 0x20, 0x40, + + /* U+60C5 "情" */ + 0x0, 0xd0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, + 0xd0, 0x6c, 0xcc, 0xfc, 0xcc, 0xa0, 0x0, 0xd7, + 0x0, 0x0, 0xd1, 0x0, 0x0, 0xa, 0xd9, 0x4b, + 0xbb, 0xfb, 0xbb, 0x50, 0x29, 0xd2, 0x63, 0x33, + 0xe4, 0x33, 0x30, 0x66, 0xd0, 0x66, 0x66, 0x66, + 0x66, 0x61, 0x41, 0xd0, 0xa, 0xbb, 0xbb, 0xbb, + 0x10, 0x0, 0xd0, 0xd, 0x0, 0x0, 0xc, 0x10, + 0x0, 0xd0, 0xe, 0xbb, 0xbb, 0xbf, 0x10, 0x0, + 0xd0, 0xd, 0x0, 0x0, 0xc, 0x10, 0x0, 0xd0, + 0xe, 0xbb, 0xbb, 0xbf, 0x10, 0x0, 0xd0, 0xd, + 0x0, 0x0, 0xc, 0x10, 0x0, 0xd0, 0xd, 0x0, + 0x6, 0xcc, 0x0, + + /* U+60F3 "想" */ + 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x60, 0xa, 0xdc, 0xcc, 0xe0, 0x9, 0x9c, + 0xc9, 0x7a, 0x30, 0x0, 0xe0, 0x3, 0x3e, 0x83, + 0x2a, 0xcb, 0xbb, 0xe0, 0x0, 0x6e, 0xd3, 0xa, + 0x30, 0x0, 0xe0, 0x3, 0xc7, 0x7b, 0x6a, 0xcb, + 0xbb, 0xe0, 0x2d, 0x27, 0x60, 0x2a, 0x30, 0x0, + 0xe0, 0x1, 0x7, 0x60, 0xa, 0xcb, 0xbb, 0xe0, + 0x0, 0x0, 0x0, 0xb2, 0x0, 0x2, 0x0, 0x0, + 0x70, 0x70, 0x4d, 0x0, 0xb, 0x50, 0x4, 0xa0, + 0xd0, 0x7, 0x51, 0x32, 0xd0, 0xc, 0x30, 0xd1, + 0x0, 0x4, 0xa0, 0xa5, 0x5, 0x0, 0x7e, 0xdd, + 0xde, 0x40, 0x10, + + /* U+6108 "愈" */ + 0x0, 0x0, 0x0, 0x34, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xbb, 0x50, 0x0, 0x0, 0x0, 0x17, + 0xc5, 0x0, 0x7c, 0x61, 0x0, 0x2b, 0xa5, 0x8a, + 0xaa, 0xa3, 0x4a, 0xb2, 0x1, 0x97, 0x78, 0x60, + 0x60, 0xa, 0x0, 0x0, 0xe8, 0x8a, 0x90, 0xd0, + 0xd, 0x0, 0x0, 0xd3, 0x37, 0x90, 0xd0, 0xd, + 0x0, 0x0, 0xe6, 0x69, 0x90, 0x90, 0xd, 0x0, + 0x0, 0xd0, 0x3b, 0x50, 0x4, 0xbb, 0x0, 0x0, + 0x10, 0x12, 0xc4, 0x0, 0x1, 0x0, 0x0, 0xc1, + 0xc1, 0x1c, 0x41, 0x3c, 0x10, 0x7, 0x90, 0xc1, + 0x0, 0xc, 0x36, 0xa0, 0x8, 0x0, 0x7d, 0xdd, + 0xdd, 0x0, 0x80, + + /* U+610F "意" */ + 0x0, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x4, + 0xcc, 0xcc, 0xdf, 0xcc, 0xcc, 0x40, 0x0, 0x0, + 0xc0, 0x0, 0xd, 0x10, 0x0, 0x7, 0x77, 0xd9, + 0x77, 0x9d, 0x77, 0x70, 0x5, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x50, 0x0, 0x4c, 0xaa, 0xaa, 0xaa, + 0xc5, 0x0, 0x0, 0x5b, 0x44, 0x44, 0x44, 0xa6, + 0x0, 0x0, 0x5b, 0x55, 0x55, 0x55, 0xb6, 0x0, + 0x0, 0x5d, 0xaa, 0xaa, 0xaa, 0xd6, 0x0, 0x0, + 0x0, 0x1, 0xc4, 0x0, 0x11, 0x0, 0x0, 0xc2, + 0xc1, 0x1c, 0x31, 0x3c, 0x0, 0x7, 0x90, 0xc1, + 0x0, 0xc, 0x16, 0x90, 0x8, 0x0, 0x7d, 0xcc, + 0xdb, 0x0, 0x50, + + /* U+611A "愚" */ + 0x0, 0x2e, 0xaa, 0xaf, 0xaa, 0xbc, 0x0, 0x0, + 0x2e, 0xaa, 0xaf, 0xaa, 0xbc, 0x0, 0x0, 0x2c, + 0x11, 0x1e, 0x11, 0x3c, 0x0, 0x0, 0x18, 0x88, + 0x8f, 0x88, 0x87, 0x0, 0x1, 0xbb, 0xbb, 0xbf, + 0xbb, 0xbb, 0x90, 0x2, 0xb0, 0x0, 0xe, 0x8, + 0x21, 0xc0, 0x2, 0xb6, 0xbb, 0xac, 0xaa, 0xc3, + 0xc0, 0x2, 0xb0, 0x0, 0x92, 0x0, 0x3b, 0xa0, + 0x0, 0x20, 0x50, 0x4d, 0x60, 0x2, 0x0, 0x0, + 0xd2, 0xe0, 0x1, 0xb3, 0x18, 0x90, 0x7, 0xa0, + 0xe0, 0x0, 0x0, 0xd0, 0xc4, 0x8, 0x10, 0xae, + 0xdd, 0xde, 0x70, 0x35, + + /* U+611B "愛" */ + 0x0, 0x0, 0x0, 0x2, 0x35, 0x78, 0x0, 0x3, + 0xcd, 0xcc, 0xfa, 0x86, 0x84, 0x0, 0x0, 0xb, + 0x60, 0x75, 0x1, 0xd2, 0x0, 0x9, 0xac, 0xea, + 0xbc, 0xad, 0xda, 0xa0, 0xe, 0x11, 0x12, 0xb7, + 0x11, 0x21, 0xe0, 0xa, 0x1b, 0x3a, 0x8, 0x22, + 0xc4, 0xb0, 0x1, 0xb5, 0x2c, 0x55, 0x7a, 0x1d, + 0x30, 0x2, 0x50, 0xd, 0x85, 0x51, 0x2, 0x10, + 0x0, 0x1, 0xce, 0xaa, 0xaa, 0x60, 0x0, 0x1, + 0x8c, 0xc7, 0x11, 0x4d, 0x20, 0x0, 0x9, 0x60, + 0x8, 0xb9, 0xc2, 0x0, 0x0, 0x0, 0x14, 0x8b, + 0xba, 0xc9, 0x52, 0x0, 0xc, 0xb8, 0x50, 0x0, + 0x4, 0x8b, 0xd1, + + /* U+611F "感" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x94, 0xa5, 0x0, 0x0, 0x11, + 0x11, 0x11, 0x95, 0x2c, 0x20, 0x0, 0xfb, 0xbb, + 0xbb, 0xdd, 0xbb, 0xb5, 0x0, 0xd3, 0x66, 0x66, + 0x58, 0x4, 0x40, 0x1, 0xd1, 0x33, 0x33, 0x1c, + 0xd, 0x20, 0x2, 0xb4, 0xda, 0xab, 0xc, 0x89, + 0x0, 0x4, 0x94, 0x80, 0xc, 0x7, 0xe0, 0x23, + 0x9, 0x54, 0xda, 0xac, 0x6d, 0xd4, 0x56, 0xd, + 0x0, 0x0, 0x11, 0xa1, 0x1b, 0xe2, 0x0, 0x0, + 0x80, 0x79, 0x0, 0x5, 0x0, 0x1, 0xd1, 0xe0, + 0xa, 0x60, 0x49, 0x60, 0xa, 0x51, 0xe0, 0x0, + 0x10, 0xd1, 0xd0, 0x7, 0x0, 0xbc, 0xcc, 0xcd, + 0x80, 0x30, + + /* U+614B "態" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x41, 0x0, 0xe0, 0x3, 0x10, 0x0, 0xb6, + 0xb, 0x50, 0xe6, 0xca, 0x20, 0xb, 0xeb, 0xbc, + 0xe2, 0xe6, 0x10, 0x50, 0x3, 0x54, 0x33, 0x52, + 0xc6, 0x56, 0xd0, 0x3, 0xc6, 0x67, 0xc0, 0x65, + 0x55, 0x10, 0x3, 0xd9, 0x9a, 0xc0, 0xe0, 0x6, + 0x50, 0x3, 0xb3, 0x34, 0xc0, 0xea, 0xb6, 0x10, + 0x3, 0xc5, 0x56, 0xc0, 0xe0, 0x0, 0x80, 0x3, + 0xa0, 0x4b, 0xa0, 0xbb, 0xaa, 0xc0, 0x0, 0x20, + 0x10, 0x58, 0x2, 0x26, 0x10, 0x3, 0xb0, 0xe0, + 0xb, 0x31, 0x7, 0x80, 0xc, 0x40, 0xe0, 0x1, + 0x7, 0x51, 0xe0, 0x5, 0x0, 0xad, 0xcc, 0xcd, + 0x10, 0x50, + + /* U+6163 "慣" */ + 0x0, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb1, 0x6, 0xda, 0xdc, 0xae, 0x20, 0x0, 0xb4, + 0x4c, 0xb7, 0xba, 0x7d, 0xa3, 0x9, 0xb9, 0x5a, + 0x52, 0xa4, 0x2d, 0x31, 0x9, 0xb4, 0x77, 0xaa, + 0xaa, 0xaa, 0x0, 0x47, 0xb2, 0x47, 0x99, 0x99, + 0x99, 0x20, 0x52, 0xb1, 0xc, 0x21, 0x11, 0x1a, + 0x40, 0x0, 0xb1, 0xc, 0xba, 0xaa, 0xad, 0x40, + 0x0, 0xb1, 0xc, 0x76, 0x66, 0x6c, 0x40, 0x0, + 0xb1, 0xc, 0x53, 0x33, 0x3b, 0x40, 0x0, 0xb1, + 0xb, 0xbb, 0xaa, 0xbd, 0x40, 0x0, 0xb1, 0x2, + 0xa7, 0x0, 0xb8, 0x10, 0x0, 0xb1, 0x9a, 0x30, + 0x0, 0x5, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6167 "慧" */ + 0x0, 0x9, 0x40, 0x0, 0xb, 0x20, 0x0, 0x8a, + 0xdb, 0xa2, 0x9a, 0xeb, 0xa5, 0x6, 0xad, 0xba, + 0x7, 0xae, 0xba, 0x20, 0x55, 0xc8, 0x53, 0x55, + 0xd6, 0x54, 0x3, 0x3a, 0x63, 0x23, 0x3c, 0x53, + 0x30, 0xa, 0xaa, 0xaa, 0xaa, 0xaa, 0x50, 0x0, + 0x12, 0x22, 0x22, 0x22, 0x87, 0x0, 0x3, 0x66, + 0x66, 0x66, 0x6a, 0x70, 0x0, 0xaa, 0xaa, 0xaa, + 0xaa, 0xc7, 0x0, 0x0, 0x1, 0x9, 0x10, 0x0, + 0x0, 0x0, 0xa0, 0xe0, 0x3c, 0x10, 0x2c, 0x0, + 0x77, 0xe, 0x0, 0x20, 0x84, 0x88, 0x8, 0x0, + 0xbd, 0xcc, 0xcd, 0x11, 0x90, + + /* U+616E "慮" */ + 0x0, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9c, 0xaa, 0xaa, 0x10, 0x0, 0x77, + 0x77, 0xca, 0x77, 0x77, 0x60, 0x0, 0xe5, 0x55, + 0xb7, 0x55, 0x66, 0xa0, 0x0, 0xe2, 0x99, 0xda, + 0x98, 0x73, 0x70, 0x0, 0xe0, 0x0, 0x3a, 0x99, + 0x99, 0x80, 0x0, 0xd0, 0x88, 0x88, 0x88, 0x88, + 0x0, 0x1, 0xc1, 0xc3, 0x3c, 0x53, 0x3e, 0x0, + 0x2, 0xb1, 0xc5, 0x5d, 0x65, 0x5e, 0x0, 0x3, + 0xa1, 0x98, 0xab, 0x88, 0x89, 0x0, 0x6, 0x72, + 0x27, 0x3c, 0x50, 0x17, 0x0, 0xb, 0x4b, 0x2d, + 0x0, 0x32, 0x57, 0x90, 0xd, 0x66, 0x9, 0xcc, + 0xcc, 0x50, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+61C9 "應" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x8, 0xcc, + 0xcc, 0xdf, 0xcc, 0xcc, 0xc1, 0xa, 0x30, 0x45, + 0x36, 0x28, 0x0, 0x0, 0xa, 0x30, 0xd1, 0xba, + 0x7e, 0x87, 0x40, 0xa, 0x3a, 0xd5, 0xf2, 0x2d, + 0x22, 0x10, 0xa, 0xcb, 0xdc, 0xd8, 0x8e, 0x88, + 0x10, 0xb, 0x50, 0xd0, 0xc8, 0x8e, 0x88, 0x10, + 0xc, 0x10, 0xd0, 0xc1, 0x1d, 0x11, 0x0, 0xd, + 0x0, 0xa0, 0xab, 0xaa, 0xaa, 0x80, 0xe, 0x0, + 0x11, 0x2b, 0x80, 0x30, 0x0, 0x1c, 0x6, 0x96, + 0x50, 0x73, 0x5b, 0x0, 0x68, 0x2d, 0x16, 0x50, + 0x4, 0x78, 0x80, 0x92, 0x54, 0x3, 0xdc, 0xcd, + 0x40, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+61F8 "懸" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x1, + 0xea, 0xac, 0x65, 0x9b, 0xb9, 0x40, 0x1, 0xd7, + 0x7b, 0x60, 0x3a, 0x5, 0x0, 0x1, 0xd8, 0x8b, + 0x63, 0xea, 0xb8, 0x0, 0x1, 0xc4, 0x49, 0x60, + 0x3b, 0x55, 0x20, 0x1, 0xb3, 0x38, 0x66, 0xfa, + 0x9a, 0xc0, 0x9, 0xaa, 0xda, 0x93, 0x63, 0xa4, + 0x41, 0x4, 0xa2, 0xa8, 0x54, 0x91, 0xa3, 0xa0, + 0xa, 0x4a, 0x90, 0x56, 0x3b, 0x90, 0x31, 0x0, + 0x2, 0x10, 0xb7, 0x1, 0x1, 0x0, 0x0, 0xc0, + 0xd0, 0xb, 0x50, 0x4c, 0x10, 0x8, 0x70, 0xd0, + 0x0, 0x8, 0x25, 0xc0, 0x9, 0x0, 0x8c, 0xcc, + 0xcd, 0x0, 0x61, + + /* U+6210 "成" */ + 0x0, 0x0, 0x0, 0x1, 0xd1, 0xb1, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xe0, 0x5e, 0x40, 0x0, 0x11, + 0x11, 0x12, 0xe1, 0x14, 0x80, 0x0, 0xfc, 0xcc, + 0xcc, 0xfd, 0xcc, 0xc7, 0x0, 0xe0, 0x0, 0x0, + 0xe1, 0x1, 0x20, 0x0, 0xfb, 0xbb, 0x80, 0xc3, + 0x8, 0x70, 0x0, 0xe2, 0x25, 0xb0, 0xa5, 0xe, + 0x10, 0x1, 0xd0, 0x3, 0xa0, 0x69, 0x89, 0x0, + 0x2, 0xc0, 0x4, 0x90, 0x2e, 0xe1, 0x0, 0x4, + 0xa0, 0x6, 0x80, 0x1f, 0x50, 0x14, 0x7, 0x77, + 0xdd, 0x31, 0xcd, 0x80, 0x2a, 0xd, 0x30, 0x0, + 0x3d, 0x51, 0xe4, 0x57, 0x2b, 0x0, 0x0, 0xc3, + 0x0, 0x3d, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6211 "我" */ + 0x0, 0x1, 0x59, 0xb1, 0xe0, 0x80, 0x0, 0xa, + 0xed, 0xe5, 0x10, 0xe0, 0x6c, 0x0, 0x2, 0x2, + 0xc0, 0x0, 0xf0, 0x8, 0x90, 0x0, 0x2, 0xc0, + 0x0, 0xf0, 0x0, 0x10, 0x2c, 0xcc, 0xfc, 0xcc, + 0xfc, 0xcc, 0xc2, 0x1, 0x13, 0xc1, 0x11, 0xc4, + 0x12, 0x10, 0x0, 0x2, 0xc0, 0x0, 0x96, 0xc, + 0x40, 0x0, 0x4, 0xea, 0xd5, 0x79, 0x8a, 0x0, + 0x3c, 0xec, 0xd4, 0x0, 0x3e, 0xd1, 0x0, 0x3, + 0x2, 0xc0, 0x0, 0x5f, 0x30, 0x21, 0x0, 0x2, + 0xc0, 0x7, 0xcb, 0x60, 0x66, 0x0, 0x2, 0xc1, + 0xc8, 0x2, 0xe2, 0x94, 0x4, 0xee, 0x70, 0x30, + 0x0, 0x5e, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6216 "或" */ + 0x0, 0x0, 0x0, 0x3, 0xc1, 0xb4, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xc0, 0x1b, 0x60, 0xa, 0xaa, + 0xaa, 0xab, 0xfa, 0xab, 0xb0, 0x3, 0x33, 0x33, + 0x34, 0xe3, 0x33, 0x30, 0x0, 0x0, 0x0, 0x0, + 0xf0, 0x2, 0x0, 0x2, 0xfc, 0xcd, 0x90, 0xd1, + 0xc, 0x40, 0x2, 0xa0, 0x4, 0x90, 0xb4, 0x2d, + 0x0, 0x2, 0xa0, 0x4, 0x90, 0x87, 0xb6, 0x0, + 0x2, 0xec, 0xcd, 0x90, 0x5e, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3f, 0x20, 0x21, 0x0, 0x36, + 0xad, 0xd4, 0xdd, 0x50, 0x75, 0xe, 0xb7, 0x41, + 0x6c, 0x23, 0xe2, 0xa3, 0x0, 0x0, 0x4, 0xa0, + 0x0, 0x5e, 0xc0, + + /* U+6226 "戦" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, + 0x8, 0x40, 0x3a, 0xe, 0x9, 0x0, 0xd, 0x15, + 0x90, 0xa5, 0xe, 0x7, 0x90, 0x7, 0x41, 0x61, + 0xc0, 0xd, 0x0, 0xb1, 0x9, 0xaa, 0xaa, 0xb5, + 0xc, 0x23, 0x53, 0xd, 0x2, 0xb0, 0x6b, 0xdf, + 0xda, 0x83, 0xd, 0x9a, 0xe9, 0xb8, 0xa, 0x30, + 0x80, 0xd, 0x23, 0xc2, 0x77, 0x8, 0x54, 0xb0, + 0xd, 0x2, 0xb0, 0x67, 0x6, 0x7a, 0x40, 0x9, + 0xab, 0xea, 0xa5, 0x4, 0xcc, 0x0, 0x0, 0x2, + 0xc0, 0x0, 0x1, 0xf4, 0x0, 0x4c, 0xcd, 0xfc, + 0xcb, 0xa, 0xf3, 0x8, 0x0, 0x2, 0xc0, 0x3, + 0xc8, 0x5c, 0x68, 0x0, 0x2, 0xc0, 0x1b, 0x40, + 0x9, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+6230 "戰" */ + 0x0, 0x0, 0x0, 0x0, 0xd, 0x5, 0x0, 0xd, + 0xae, 0x5c, 0xb9, 0xd, 0xa, 0x50, 0xb, 0xc, + 0x57, 0x39, 0xd, 0x1, 0xd1, 0x7, 0x88, 0x28, + 0x85, 0xc, 0x10, 0x31, 0x9, 0xbb, 0xbb, 0xb8, + 0xae, 0xed, 0xc5, 0xc, 0x1, 0xb0, 0x58, 0x4b, + 0x40, 0x40, 0xc, 0xbb, 0xeb, 0xd7, 0x8, 0x53, + 0xc0, 0xc, 0x1, 0xb0, 0x57, 0x6, 0x8b, 0x50, + 0xb, 0xbc, 0xeb, 0xd7, 0x3, 0xdc, 0x0, 0x0, + 0x2, 0xb0, 0x0, 0x1, 0xf3, 0x0, 0x4d, 0xdd, + 0xfd, 0xdc, 0x1c, 0xe4, 0xa, 0x0, 0x2, 0xb0, + 0x4, 0xd6, 0x4c, 0x58, 0x0, 0x2, 0xb0, 0xa, + 0x30, 0x9, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+623B "戻" */ + 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, 0x0, 0xcc, + 0xcc, 0xdf, 0xcc, 0xcc, 0x0, 0x0, 0xe0, 0x0, + 0x0, 0x0, 0xd, 0x10, 0x0, 0xe0, 0x0, 0x0, + 0x0, 0xd, 0x10, 0x0, 0xfb, 0xbb, 0xbb, 0xbb, + 0xbb, 0x0, 0x1, 0xd0, 0x0, 0x8, 0x30, 0x0, + 0x0, 0x2, 0xc0, 0x0, 0xc, 0x20, 0x0, 0x0, + 0x3, 0xaa, 0xdd, 0xdf, 0xed, 0xdd, 0x50, 0x6, + 0x80, 0x0, 0x6d, 0xb0, 0x0, 0x0, 0xa, 0x40, + 0x2, 0xd1, 0xa9, 0x0, 0x0, 0x1e, 0x0, 0x7d, + 0x30, 0x9, 0xc4, 0x0, 0x36, 0x5d, 0x81, 0x0, + 0x0, 0x29, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+623F "房" */ + 0x0, 0x0, 0x0, 0x42, 0x0, 0x0, 0x0, 0x1, + 0x11, 0x18, 0x91, 0x11, 0x10, 0x0, 0xeb, 0xbb, + 0xbb, 0xbb, 0xbe, 0x30, 0xe, 0x0, 0x0, 0x0, + 0x0, 0xb3, 0x0, 0xec, 0xcc, 0xcd, 0xcc, 0xcd, + 0x20, 0xf, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, + 0xf0, 0x0, 0x5, 0x80, 0x0, 0x0, 0x1e, 0x6c, + 0xcf, 0xcc, 0xcc, 0xc9, 0x2, 0xc0, 0x0, 0xe0, + 0x0, 0x0, 0x0, 0x4a, 0x0, 0x3e, 0xcc, 0xcc, + 0xf0, 0x8, 0x60, 0xa, 0x30, 0x0, 0x3d, 0x0, + 0xe1, 0x8, 0xa0, 0x0, 0x7, 0xa0, 0x3a, 0xc, + 0x80, 0x0, 0xab, 0xd4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+6240 "所" */ + 0x0, 0x0, 0x4, 0x0, 0x0, 0x5, 0x20, 0x5, + 0x8b, 0xea, 0x25, 0x8c, 0xe9, 0x30, 0xc, 0x62, + 0x0, 0xd, 0x51, 0x0, 0x0, 0xc, 0x43, 0x33, + 0xd, 0x10, 0x0, 0x0, 0xc, 0xaa, 0xae, 0xd, + 0x10, 0x0, 0x0, 0xc, 0x10, 0xe, 0xd, 0xee, + 0xfe, 0xe0, 0xd, 0x10, 0xe, 0xd, 0x10, 0xa3, + 0x0, 0xd, 0xdd, 0xdc, 0xe, 0x0, 0xa3, 0x0, + 0xe, 0x0, 0x0, 0xe, 0x0, 0xa3, 0x0, 0xe, + 0x0, 0x0, 0x2c, 0x0, 0xa3, 0x0, 0x2c, 0x0, + 0x0, 0x68, 0x0, 0xa3, 0x0, 0x67, 0x0, 0x0, + 0xd3, 0x0, 0xa3, 0x0, 0x92, 0x0, 0x4, 0x90, + 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+624B "手" */ + 0x0, 0x0, 0x0, 0x13, 0x57, 0xba, 0x0, 0x0, + 0xcd, 0xdd, 0xde, 0x86, 0x30, 0x0, 0x0, 0x10, + 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3b, 0x0, 0x0, 0x0, 0x2, 0xee, 0xee, 0xef, + 0xee, 0xee, 0xa0, 0x0, 0x0, 0x0, 0x3b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x0, 0x0, + 0x0, 0xb, 0xbb, 0xbb, 0xce, 0xbb, 0xbb, 0xb5, + 0x3, 0x33, 0x33, 0x6c, 0x33, 0x33, 0x31, 0x0, + 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4b, 0x0, 0x0, 0x0, 0x0, 0x1, 0xee, 0xd5, + 0x0, 0x0, 0x0, + + /* U+624D "才" */ + 0x0, 0x0, 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb4, 0x0, 0x0, 0xe, 0xee, 0xee, + 0xee, 0xff, 0xee, 0xe1, 0x0, 0x0, 0x0, 0x2e, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb7, 0xb4, + 0x0, 0x0, 0x0, 0x0, 0x8, 0xb0, 0xb4, 0x0, + 0x0, 0x0, 0x0, 0x6d, 0x0, 0xb4, 0x0, 0x0, + 0x0, 0x8, 0xd1, 0x0, 0xb4, 0x0, 0x0, 0x1, + 0xac, 0x10, 0x0, 0xb4, 0x0, 0x0, 0x3e, 0x90, + 0x0, 0x0, 0xb4, 0x0, 0x0, 0x3, 0x0, 0x0, + 0x0, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x3, 0xfe, + 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6253 "打" */ + 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x0, 0xbb, 0xbb, 0xbb, 0xb6, 0x0, 0xe, + 0x0, 0x44, 0x44, 0xf5, 0x42, 0x2e, 0xef, 0xed, + 0x0, 0x0, 0xf0, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x0, 0xf0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, + 0xf0, 0x0, 0x0, 0xe, 0x59, 0x0, 0x0, 0xf0, + 0x0, 0x17, 0xbf, 0x94, 0x0, 0x0, 0xf0, 0x0, + 0x18, 0x3e, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0xe, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, 0xe, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x8, 0xea, 0x0, 0x7, + 0xee, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+6255 "払" */ + 0x0, 0xe, 0x0, 0x0, 0x33, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, 0xe, + 0x0, 0x0, 0xc2, 0x0, 0x0, 0xd, 0xdf, 0xda, + 0x0, 0xe0, 0x0, 0x0, 0x0, 0xe, 0x0, 0x3, + 0xb0, 0x0, 0x0, 0x0, 0xe, 0x0, 0x7, 0x80, + 0x0, 0x0, 0x0, 0xe, 0x46, 0xc, 0x40, 0x90, + 0x0, 0x7, 0xbf, 0x94, 0xe, 0x0, 0xa5, 0x0, + 0x8, 0x3e, 0x0, 0x5b, 0x0, 0x4c, 0x0, 0x0, + 0xe, 0x0, 0xa5, 0x0, 0xd, 0x40, 0x0, 0xe, + 0x1, 0xf1, 0x2, 0x4b, 0xa0, 0x0, 0xe, 0x8, + 0xfd, 0xdb, 0x86, 0xf0, 0x7, 0xdb, 0x2, 0x30, + 0x0, 0x0, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+627E "找" */ + 0x0, 0xd, 0x0, 0x4, 0xa0, 0x50, 0x0, 0x0, + 0xd, 0x0, 0x3, 0xb0, 0xb7, 0x0, 0x0, 0xd, + 0x0, 0x1, 0xc0, 0xd, 0x10, 0x1d, 0xef, 0xd8, + 0x0, 0xe1, 0x35, 0x72, 0x0, 0xd, 0x2, 0xce, + 0xfc, 0xa8, 0x61, 0x0, 0xd, 0x0, 0x10, 0xc2, + 0x2, 0x10, 0x0, 0xd, 0x56, 0x0, 0xa4, 0xa, + 0x50, 0x17, 0xcf, 0x93, 0x0, 0x78, 0x5c, 0x0, + 0x17, 0x4d, 0x0, 0x0, 0x3d, 0xd2, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x2f, 0x50, 0x1, 0x0, 0xd, + 0x0, 0x4, 0xeb, 0xa0, 0x1b, 0x0, 0x1d, 0x2, + 0xbd, 0x21, 0xe6, 0x68, 0x9, 0xd9, 0x2, 0x60, + 0x0, 0x3d, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6280 "技" */ + 0x0, 0x77, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, + 0x77, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x77, + 0x6, 0x88, 0xae, 0x88, 0x81, 0x3d, 0xee, 0xd5, + 0x55, 0x7d, 0x55, 0x51, 0x0, 0x77, 0x0, 0x0, + 0x2c, 0x0, 0x0, 0x0, 0x77, 0x4, 0xaa, 0xbe, + 0xaa, 0x70, 0x0, 0x7a, 0x92, 0xc6, 0x33, 0x39, + 0x70, 0x3b, 0xfc, 0x50, 0x5b, 0x0, 0x1e, 0x0, + 0x14, 0x77, 0x0, 0xc, 0x50, 0xa7, 0x0, 0x0, + 0x77, 0x0, 0x1, 0xea, 0xa0, 0x0, 0x0, 0x77, + 0x0, 0x1, 0xcf, 0x50, 0x0, 0x0, 0x77, 0x2, + 0x8e, 0x62, 0xca, 0x30, 0xd, 0xe4, 0x4d, 0x71, + 0x0, 0x6, 0xd6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+628A "把" */ + 0x0, 0x76, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x76, 0x3, 0xfe, 0xef, 0xee, 0xe0, 0x0, 0x76, + 0x3, 0xc0, 0xd, 0x1, 0xe0, 0x3d, 0xee, 0xc3, + 0xc0, 0xd, 0x1, 0xe0, 0x0, 0x76, 0x3, 0xc0, + 0xd, 0x1, 0xe0, 0x0, 0x76, 0x3, 0xc0, 0xd, + 0x1, 0xe0, 0x0, 0x8a, 0x94, 0xeb, 0xbf, 0xbb, + 0xe0, 0x2b, 0xfc, 0x53, 0xc2, 0x22, 0x24, 0xe0, + 0x26, 0x96, 0x3, 0xc0, 0x0, 0x0, 0x40, 0x0, + 0x76, 0x3, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x76, + 0x3, 0xc0, 0x0, 0x0, 0x49, 0x0, 0x86, 0x2, + 0xe0, 0x0, 0x0, 0x87, 0xa, 0xe3, 0x0, 0xbe, + 0xee, 0xee, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6295 "投" */ + 0x0, 0x94, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x94, 0x0, 0xce, 0xdd, 0xe0, 0x0, 0x0, 0x94, + 0x0, 0xd1, 0x0, 0xe0, 0x0, 0x7d, 0xfe, 0xd1, + 0xe0, 0x0, 0xe0, 0x0, 0x0, 0x94, 0x8, 0x90, + 0x0, 0xd7, 0x70, 0x0, 0x94, 0x2a, 0x0, 0x0, + 0x14, 0x40, 0x0, 0x99, 0x7b, 0xbb, 0xbb, 0xbb, + 0x10, 0x6d, 0xfa, 0x37, 0x82, 0x22, 0x6c, 0x0, + 0x32, 0x94, 0x0, 0xd1, 0x0, 0xd4, 0x0, 0x0, + 0x94, 0x0, 0x4d, 0x2c, 0x70, 0x0, 0x0, 0x94, + 0x0, 0x9, 0xfb, 0x0, 0x0, 0x0, 0x94, 0x3, + 0xbd, 0x7d, 0xb4, 0x0, 0x2d, 0xd2, 0xcc, 0x60, + 0x0, 0x6b, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+62BC "押" */ + 0x0, 0x86, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x60, 0x4f, 0xdd, 0xfd, 0xdf, 0x0, 0x86, 0x4, + 0xa0, 0xe, 0x0, 0xe3, 0xef, 0xfe, 0x4a, 0x0, + 0xe0, 0xe, 0x0, 0x86, 0x4, 0xfd, 0xdf, 0xdd, + 0xf0, 0x8, 0x60, 0x4a, 0x0, 0xe0, 0xe, 0x0, + 0x89, 0x84, 0xa0, 0xe, 0x0, 0xe3, 0xbf, 0xb5, + 0x4f, 0xdd, 0xfd, 0xdf, 0x14, 0x86, 0x4, 0x90, + 0xe, 0x0, 0xc0, 0x8, 0x60, 0x0, 0x0, 0xe0, + 0x0, 0x0, 0x86, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x8, 0x60, 0x0, 0x0, 0xe0, 0x0, 0xc, 0xd3, + 0x0, 0x0, 0xe, 0x0, 0x0, + + /* U+62C5 "担" */ + 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0x0, 0xbe, 0xee, 0xee, 0xa0, 0x0, 0x1d, + 0x0, 0xd2, 0x11, 0x14, 0xb0, 0x1d, 0xef, 0xd7, + 0xd1, 0x0, 0x3, 0xb0, 0x0, 0x1d, 0x0, 0xd1, + 0x0, 0x3, 0xb0, 0x0, 0x1d, 0x0, 0xdd, 0xdd, + 0xde, 0xb0, 0x0, 0x1d, 0x44, 0xd1, 0x0, 0x3, + 0xb0, 0x16, 0xbf, 0xa3, 0xd1, 0x0, 0x3, 0xb0, + 0x19, 0x5d, 0x0, 0xd1, 0x0, 0x3, 0xb0, 0x0, + 0x1d, 0x0, 0xbe, 0xee, 0xee, 0xa0, 0x0, 0x1d, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x2, + 0x22, 0x22, 0x22, 0x21, 0x9, 0xd9, 0xa, 0xbb, + 0xbb, 0xbb, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+62C9 "拉" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x67, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, 0x67, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x67, 0x1, + 0x22, 0x48, 0x22, 0x20, 0x2d, 0xee, 0xd4, 0xbb, + 0xbb, 0xbb, 0xb1, 0x0, 0x67, 0x0, 0x11, 0x0, + 0x5, 0x0, 0x0, 0x67, 0x0, 0x49, 0x0, 0xe, + 0x0, 0x0, 0x68, 0x40, 0x1c, 0x0, 0x3b, 0x0, + 0x16, 0xcf, 0xa0, 0xe, 0x0, 0x68, 0x0, 0x29, + 0xa7, 0x0, 0xc, 0x20, 0x85, 0x0, 0x0, 0x67, + 0x0, 0x9, 0x40, 0xc2, 0x0, 0x0, 0x67, 0x0, + 0x8, 0x60, 0xd0, 0x0, 0x0, 0x77, 0x2, 0x23, + 0x25, 0xb2, 0x21, 0xa, 0xd4, 0xb, 0xbb, 0xbb, + 0xbb, 0xb5, + + /* U+62DB "招" */ + 0x0, 0x94, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x94, 0x4, 0xdd, 0xfe, 0xdd, 0xf0, 0x0, 0x94, + 0x0, 0x0, 0xe0, 0x0, 0xe0, 0x5d, 0xfe, 0xd0, + 0x5, 0xa0, 0x0, 0xe0, 0x0, 0x94, 0x0, 0x1d, + 0x30, 0x2, 0xc0, 0x0, 0x94, 0x4, 0xd6, 0x2, + 0x8b, 0x80, 0x0, 0x99, 0x94, 0x30, 0x0, 0x43, + 0x0, 0x4c, 0xfa, 0x20, 0xcd, 0xdd, 0xdd, 0xb0, + 0x23, 0x94, 0x0, 0xe0, 0x0, 0x1, 0xd0, 0x0, + 0x94, 0x0, 0xe0, 0x0, 0x1, 0xd0, 0x0, 0x94, + 0x0, 0xe0, 0x0, 0x1, 0xd0, 0x0, 0x94, 0x0, + 0xeb, 0xaa, 0xab, 0xd0, 0xd, 0xd2, 0x0, 0xd2, + 0x22, 0x23, 0xc0, + + /* U+62E1 "拡" */ + 0x0, 0x85, 0x0, 0x0, 0x72, 0x0, 0x0, 0x0, + 0x85, 0x0, 0x0, 0x69, 0x0, 0x0, 0x0, 0x85, + 0x4, 0xaa, 0xaf, 0xaa, 0xa2, 0x4d, 0xfe, 0xc7, + 0x94, 0x44, 0x44, 0x41, 0x0, 0x85, 0x7, 0x60, + 0xa, 0x0, 0x0, 0x0, 0x85, 0x7, 0x60, 0x3c, + 0x0, 0x0, 0x0, 0x88, 0x68, 0x50, 0x77, 0x0, + 0x0, 0x28, 0xec, 0x69, 0x40, 0xb3, 0x44, 0x0, + 0x36, 0x95, 0xb, 0x30, 0xe0, 0x1c, 0x0, 0x0, + 0x85, 0xd, 0x15, 0x90, 0xa, 0x30, 0x0, 0x85, + 0x2c, 0xc, 0x30, 0x4, 0xa0, 0x0, 0x85, 0x97, + 0x4f, 0xbd, 0xdc, 0xe1, 0xc, 0xd2, 0xa0, 0x15, + 0x30, 0x0, 0x63, + + /* U+62EC "括" */ + 0x0, 0x85, 0x0, 0x0, 0x13, 0x6a, 0x90, 0x0, + 0x85, 0x3, 0xcd, 0xdf, 0x74, 0x0, 0x1, 0x96, + 0x10, 0x0, 0xe, 0x0, 0x0, 0x4c, 0xed, 0xc0, + 0x0, 0xe, 0x0, 0x0, 0x0, 0x85, 0x6, 0xbb, + 0xbf, 0xbb, 0xb7, 0x0, 0x85, 0x1, 0x22, 0x3e, + 0x22, 0x21, 0x0, 0x87, 0x71, 0x0, 0xe, 0x0, + 0x0, 0x28, 0xee, 0x81, 0x0, 0xe, 0x0, 0x0, + 0x48, 0xa5, 0x1, 0xfd, 0xdd, 0xde, 0xd0, 0x0, + 0x85, 0x1, 0xd0, 0x0, 0x1, 0xd0, 0x0, 0x85, + 0x1, 0xd0, 0x0, 0x1, 0xd0, 0x0, 0x85, 0x1, + 0xe2, 0x22, 0x23, 0xd0, 0x1d, 0xd2, 0x1, 0xfb, + 0xbb, 0xbb, 0xc0, + + /* U+62ED "拭" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x0, 0x0, 0x1, 0xd5, 0x40, 0x0, 0x85, + 0x0, 0x0, 0x1, 0xe0, 0xc2, 0x0, 0x85, 0x0, + 0x0, 0x0, 0xe0, 0x33, 0x4d, 0xfe, 0xca, 0xee, + 0xee, 0xfe, 0xe6, 0x0, 0x85, 0x0, 0x0, 0x0, + 0xe0, 0x0, 0x0, 0x85, 0x0, 0x0, 0x0, 0xe0, + 0x0, 0x0, 0x88, 0x77, 0xdd, 0xd8, 0xd1, 0x0, + 0x3a, 0xec, 0x60, 0xd, 0x0, 0xb2, 0x0, 0x25, + 0x95, 0x0, 0xd, 0x0, 0x94, 0x0, 0x0, 0x85, + 0x0, 0xd, 0x0, 0x77, 0x1, 0x0, 0x85, 0x0, + 0x2e, 0x8b, 0x5b, 0x39, 0x0, 0x95, 0xe, 0xc9, + 0x63, 0xe, 0x86, 0x1d, 0xc2, 0x0, 0x0, 0x0, + 0x6, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+62FF "拿" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4c, 0x67, 0xb4, 0x0, 0x0, 0x3, 0x8e, 0xd6, + 0x44, 0x6d, 0xd9, 0x40, 0x3b, 0x51, 0x55, 0x55, + 0x55, 0x15, 0xa2, 0x0, 0x4c, 0xaa, 0xaa, 0xaa, + 0xd3, 0x0, 0x0, 0x4b, 0x33, 0x33, 0x33, 0xc3, + 0x0, 0x0, 0x16, 0x66, 0x66, 0x66, 0x92, 0x0, + 0x0, 0xaa, 0xaa, 0xbb, 0xaa, 0x83, 0x0, 0x1, + 0x54, 0x44, 0xa9, 0x44, 0x44, 0x20, 0x2, 0x66, + 0x66, 0xba, 0x66, 0x66, 0x20, 0x1b, 0xbb, 0xbb, + 0xdd, 0xbb, 0xbb, 0xb1, 0x0, 0x0, 0x0, 0x77, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6b, 0xd4, 0x0, + 0x0, 0x0, + + /* U+6301 "持" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x76, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x76, + 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x76, 0x1, + 0xff, 0xff, 0xff, 0xe0, 0x4d, 0xee, 0xc0, 0x0, + 0xe, 0x0, 0x0, 0x0, 0x76, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x0, 0x76, 0xb, 0xdd, 0xdd, 0xef, + 0xd8, 0x0, 0x79, 0x70, 0x0, 0x0, 0x2b, 0x0, + 0x4b, 0xfa, 0x39, 0xdd, 0xdd, 0xef, 0xd7, 0x23, + 0x76, 0x0, 0x23, 0x0, 0x2c, 0x0, 0x0, 0x76, + 0x0, 0x2d, 0x0, 0x2b, 0x0, 0x0, 0x76, 0x0, + 0x8, 0x80, 0x2b, 0x0, 0x0, 0x76, 0x0, 0x0, + 0x30, 0x2b, 0x0, 0xc, 0xd2, 0x0, 0x0, 0xd, + 0xe7, 0x0, + + /* U+6307 "指" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x85, + 0x0, 0xe0, 0x4, 0x9d, 0x20, 0x0, 0x85, 0x0, + 0xfc, 0xda, 0x50, 0x0, 0x7d, 0xfe, 0xd1, 0xe1, + 0x0, 0x0, 0x63, 0x0, 0x85, 0x0, 0xe1, 0x0, + 0x0, 0xb3, 0x0, 0x85, 0x0, 0x7c, 0xdd, 0xdd, + 0x90, 0x0, 0x88, 0x71, 0x0, 0x0, 0x0, 0x0, + 0x39, 0xed, 0x71, 0xfc, 0xcc, 0xcd, 0xc0, 0x45, + 0x95, 0x0, 0xe0, 0x0, 0x1, 0xc0, 0x0, 0x85, + 0x0, 0xfc, 0xcc, 0xcc, 0xc0, 0x0, 0x85, 0x0, + 0xe0, 0x0, 0x1, 0xc0, 0x0, 0x85, 0x0, 0xe2, + 0x22, 0x24, 0xc0, 0x1d, 0xe3, 0x0, 0xfa, 0xaa, + 0xaa, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+6319 "挙" */ + 0x0, 0x21, 0x2, 0x40, 0x0, 0x32, 0x0, 0x0, + 0x5b, 0x0, 0xd2, 0x0, 0xd3, 0x0, 0x0, 0xa, + 0x50, 0x66, 0x9, 0x70, 0x0, 0x2d, 0xdd, 0xfd, + 0xdd, 0xdf, 0xdd, 0xd3, 0x0, 0x5, 0xc0, 0x0, + 0x1a, 0x60, 0x0, 0x0, 0x4e, 0xaa, 0xbc, 0xa4, + 0xc6, 0x0, 0x1a, 0xd1, 0x21, 0x86, 0x0, 0x9, + 0xc2, 0x26, 0x3c, 0xcc, 0xed, 0xcc, 0xc1, 0x41, + 0x0, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0xb, + 0xdd, 0xdd, 0xee, 0xdd, 0xdd, 0xb0, 0x0, 0x0, + 0x0, 0x76, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x86, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbc, 0xd3, + 0x0, 0x0, 0x0, + + /* U+6355 "捕" */ + 0x0, 0x67, 0x0, 0x0, 0x1c, 0x66, 0x0, 0x0, + 0x67, 0x0, 0x0, 0x1c, 0x7, 0xa0, 0x1, 0x78, + 0x1b, 0xdd, 0xdf, 0xdd, 0xd3, 0x6f, 0xff, 0xf1, + 0x0, 0x1d, 0x0, 0x0, 0x0, 0x67, 0x0, 0x11, + 0x2d, 0x11, 0x10, 0x0, 0x67, 0x6, 0xeb, 0xcf, + 0xbb, 0xe0, 0x0, 0x68, 0x57, 0x80, 0x1c, 0x0, + 0xe0, 0x38, 0xed, 0x77, 0xec, 0xdf, 0xcc, 0xe0, + 0x45, 0x87, 0x6, 0x80, 0x1c, 0x0, 0xe0, 0x0, + 0x67, 0x6, 0xec, 0xdf, 0xcc, 0xe0, 0x0, 0x67, + 0x6, 0x80, 0x1c, 0x0, 0xe0, 0x0, 0x77, 0x6, + 0x80, 0x1c, 0x0, 0xe0, 0xc, 0xd4, 0x6, 0x80, + 0x1b, 0x4c, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6368 "捨" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x66, 0x0, 0x1, 0xd1, 0x0, 0x0, 0x0, 0x66, + 0x0, 0xa, 0x9c, 0x10, 0x0, 0x0, 0x66, 0x0, + 0x69, 0x4, 0xc3, 0x0, 0x1e, 0xff, 0xc9, 0xa0, + 0x0, 0x3d, 0x80, 0x0, 0x66, 0x47, 0x8d, 0xfd, + 0xd2, 0x83, 0x0, 0x66, 0x0, 0x0, 0xb1, 0x0, + 0x0, 0x0, 0x69, 0x5d, 0xdd, 0xfd, 0xdd, 0xa0, + 0x1a, 0xeb, 0x30, 0x0, 0xb1, 0x0, 0x0, 0x4, + 0x76, 0x4, 0xcc, 0xfc, 0xca, 0x0, 0x0, 0x66, + 0x5, 0x60, 0x0, 0xd, 0x0, 0x0, 0x66, 0x5, + 0x60, 0x0, 0xd, 0x0, 0x0, 0x66, 0x5, 0x72, + 0x22, 0x2d, 0x0, 0xb, 0xd3, 0x5, 0xca, 0xaa, + 0xad, 0x0, + + /* U+6388 "授" */ + 0x0, 0x85, 0x0, 0x1, 0x35, 0x7a, 0x50, 0x0, + 0x85, 0x7, 0xba, 0x97, 0x42, 0x10, 0x1, 0x86, + 0x11, 0x80, 0x84, 0x7, 0x70, 0x4c, 0xed, 0xb0, + 0xc1, 0x38, 0x1c, 0x0, 0x0, 0x85, 0x8, 0xba, + 0xaa, 0xcc, 0xa1, 0x0, 0x85, 0xd, 0x22, 0x22, + 0x22, 0xc1, 0x0, 0x8b, 0xb8, 0x0, 0x0, 0x0, + 0x71, 0x2a, 0xfb, 0x52, 0xdd, 0xcc, 0xcd, 0x10, + 0x25, 0x85, 0x0, 0x68, 0x0, 0x4a, 0x0, 0x0, + 0x85, 0x0, 0xc, 0x42, 0xc1, 0x0, 0x0, 0x85, + 0x0, 0x1, 0xee, 0x20, 0x0, 0x0, 0x85, 0x1, + 0x5c, 0xaa, 0xc5, 0x0, 0xd, 0xe2, 0x2d, 0x82, + 0x0, 0x39, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6392 "排" */ + 0x0, 0x68, 0x0, 0x0, 0xd0, 0xd0, 0x0, 0x0, + 0x68, 0x0, 0x0, 0xe0, 0xe0, 0x0, 0x0, 0x68, + 0x0, 0x55, 0xe0, 0xf5, 0x51, 0x2d, 0xef, 0xd2, + 0x88, 0xe0, 0xf8, 0x82, 0x0, 0x68, 0x0, 0x0, + 0xe0, 0xe0, 0x0, 0x0, 0x68, 0x0, 0x23, 0xe0, + 0xe2, 0x20, 0x0, 0x68, 0x21, 0xaa, 0xe0, 0xfa, + 0xa1, 0x28, 0xdd, 0x81, 0x0, 0xe0, 0xe0, 0x0, + 0x14, 0x68, 0x5, 0xbb, 0xe0, 0xfa, 0xa4, 0x0, + 0x68, 0x0, 0x22, 0xe0, 0xe2, 0x21, 0x0, 0x68, + 0x0, 0x0, 0xe0, 0xe0, 0x0, 0x0, 0x68, 0x0, + 0x0, 0xe0, 0xe0, 0x0, 0xa, 0xe4, 0x0, 0x0, + 0xe0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+639B "掛" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x66, 0x0, 0xd, 0x0, 0xd0, 0x0, 0x0, 0x66, + 0x0, 0xd, 0x0, 0xd0, 0x0, 0x0, 0x66, 0xc, + 0xdf, 0xd5, 0xd0, 0x0, 0x2d, 0xee, 0xa0, 0xd, + 0x0, 0xd0, 0x0, 0x0, 0x66, 0x0, 0xd, 0x0, + 0xd0, 0x0, 0x0, 0x66, 0x3c, 0xcc, 0xc9, 0xdb, + 0x10, 0x0, 0x6a, 0x90, 0xa, 0x0, 0xd4, 0xd2, + 0x2b, 0xfb, 0x30, 0xd, 0x0, 0xd0, 0x35, 0x13, + 0x66, 0x1c, 0xcf, 0xc7, 0xd0, 0x0, 0x0, 0x66, + 0x0, 0xd, 0x0, 0xd0, 0x0, 0x0, 0x66, 0x0, + 0xd, 0x24, 0xd0, 0x0, 0x0, 0x66, 0x6b, 0xcb, + 0x95, 0xd0, 0x0, 0xb, 0xd3, 0x11, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+63A1 "採" */ + 0x0, 0x85, 0x0, 0x0, 0x1, 0x47, 0x70, 0x0, + 0x85, 0x8, 0xcd, 0xdc, 0x96, 0x20, 0x0, 0x85, + 0x1, 0x10, 0x42, 0x0, 0x63, 0x4d, 0xfe, 0xc6, + 0x70, 0x58, 0x0, 0xd1, 0x0, 0x85, 0x0, 0xd0, + 0x1c, 0x7, 0x70, 0x0, 0x85, 0x0, 0x61, 0x8, + 0xc, 0x0, 0x0, 0x8a, 0x90, 0x0, 0xd, 0x0, + 0x0, 0x3c, 0xfa, 0x3b, 0xdd, 0xdf, 0xdd, 0xd6, + 0x23, 0x85, 0x0, 0x3, 0xdf, 0xc0, 0x0, 0x0, + 0x85, 0x0, 0x2d, 0x3d, 0x6a, 0x0, 0x0, 0x85, + 0x5, 0xd4, 0xd, 0x8, 0xa0, 0x0, 0x85, 0x5c, + 0x10, 0xd, 0x0, 0x69, 0xd, 0xd2, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+63A2 "探" */ + 0x0, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x67, 0xa, 0xdd, 0xdd, 0xdd, 0xf0, 0x0, 0x67, + 0xa, 0x30, 0x0, 0x10, 0xd0, 0x1d, 0xee, 0xc4, + 0x18, 0x80, 0xc3, 0x50, 0x0, 0x67, 0x0, 0x7c, + 0x0, 0x1d, 0x20, 0x0, 0x67, 0x8, 0xb0, 0x6, + 0x4, 0xa0, 0x0, 0x6a, 0x80, 0x0, 0xd, 0x0, + 0x0, 0x8, 0xec, 0x5b, 0xdd, 0xef, 0xdd, 0xd2, + 0x7, 0x77, 0x0, 0x2, 0xdf, 0xb0, 0x0, 0x0, + 0x67, 0x0, 0xc, 0x3d, 0x77, 0x0, 0x0, 0x67, + 0x3, 0xc5, 0xd, 0xc, 0x60, 0x0, 0x67, 0x4d, + 0x30, 0xd, 0x0, 0xc5, 0x9, 0xd4, 0x0, 0x0, + 0xd, 0x0, 0x0, + + /* U+63A5 "接" */ + 0x0, 0x76, 0x0, 0x0, 0x83, 0x0, 0x0, 0x0, + 0x76, 0x2, 0x55, 0x8c, 0x55, 0x50, 0x0, 0x76, + 0x3, 0x9a, 0x88, 0x9a, 0x81, 0x2d, 0xee, 0xb0, + 0x2c, 0x0, 0x5a, 0x0, 0x0, 0x76, 0x0, 0x9, + 0x30, 0xd1, 0x0, 0x0, 0x76, 0xb, 0xcc, 0xdd, + 0xdc, 0xc6, 0x0, 0x79, 0x50, 0x1, 0xd0, 0x0, + 0x0, 0x2b, 0xfb, 0x5b, 0xbd, 0xeb, 0xbb, 0xb8, + 0x14, 0x86, 0x1, 0x4c, 0x11, 0x4c, 0x10, 0x0, + 0x76, 0x0, 0xd8, 0x0, 0xa6, 0x0, 0x0, 0x76, + 0x0, 0x28, 0xdb, 0xc0, 0x0, 0x0, 0x76, 0x0, + 0x16, 0xd9, 0xda, 0x20, 0xa, 0xd3, 0x1d, 0xb7, + 0x10, 0x6, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+63A7 "控" */ + 0x0, 0x76, 0x0, 0x0, 0x49, 0x0, 0x0, 0x0, + 0x76, 0x1, 0x11, 0x2e, 0x21, 0x11, 0x0, 0x76, + 0xa, 0xdc, 0xcc, 0xcc, 0xdb, 0x2d, 0xee, 0xca, + 0x30, 0x20, 0x10, 0x2b, 0x0, 0x76, 0x4, 0x19, + 0x80, 0x89, 0x2, 0x0, 0x76, 0x0, 0xa9, 0x0, + 0x6, 0xb0, 0x0, 0x78, 0x64, 0x60, 0x0, 0x0, + 0x52, 0x17, 0xdd, 0x60, 0xdd, 0xdd, 0xdd, 0xc0, + 0x28, 0x96, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, + 0x76, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0x76, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0x76, 0x0, + 0x0, 0x1d, 0x0, 0x0, 0xc, 0xe3, 0x1d, 0xdd, + 0xdd, 0xdd, 0xdb, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+63A8 "推" */ + 0x0, 0x95, 0x0, 0x29, 0x19, 0x0, 0x0, 0x0, + 0x95, 0x0, 0x87, 0xc, 0x30, 0x0, 0x0, 0x95, + 0x0, 0xe6, 0x38, 0x93, 0x30, 0x5e, 0xfe, 0xd4, + 0xfa, 0xae, 0xaa, 0xa0, 0x0, 0x95, 0xd, 0xe0, + 0xc, 0x10, 0x0, 0x0, 0x95, 0x89, 0xe2, 0x2d, + 0x42, 0x20, 0x0, 0x95, 0x80, 0xfa, 0xae, 0xaa, + 0x80, 0x28, 0xdc, 0x60, 0xe0, 0xc, 0x10, 0x0, + 0x24, 0x95, 0x0, 0xfd, 0xdf, 0xdd, 0xa0, 0x0, + 0x95, 0x0, 0xe0, 0xd, 0x10, 0x0, 0x0, 0x95, + 0x0, 0xe0, 0xc, 0x10, 0x0, 0x0, 0x95, 0x0, + 0xfd, 0xdf, 0xdd, 0xd4, 0xd, 0xe2, 0x0, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+63CF "描" */ + 0x0, 0x75, 0x0, 0xe, 0x0, 0x1c, 0x0, 0x0, + 0x75, 0x0, 0xe, 0x0, 0x1c, 0x0, 0x0, 0x75, + 0xa, 0xcf, 0xcc, 0xcf, 0xc8, 0x3d, 0xee, 0xc2, + 0x2e, 0x22, 0x4d, 0x21, 0x0, 0x75, 0x0, 0xb, + 0x0, 0x1a, 0x0, 0x0, 0x75, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x76, 0x33, 0xec, 0xcf, 0xcc, + 0xf2, 0x28, 0xdc, 0x73, 0x90, 0x1e, 0x0, 0xb2, + 0x14, 0x85, 0x3, 0xda, 0xaf, 0xaa, 0xe2, 0x0, + 0x75, 0x3, 0xb3, 0x4e, 0x33, 0xc2, 0x0, 0x75, + 0x3, 0x90, 0x1e, 0x0, 0xb2, 0x0, 0x85, 0x3, + 0xeb, 0xbf, 0xbb, 0xe2, 0xc, 0xd2, 0x3, 0xa1, + 0x11, 0x11, 0xb2, + + /* U+63D0 "提" */ + 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x1, 0xfb, 0xbb, 0xbe, 0x30, 0x0, 0x85, + 0x1, 0xd4, 0x44, 0x4c, 0x30, 0x4d, 0xfe, 0xc1, + 0xd5, 0x55, 0x5c, 0x30, 0x0, 0x85, 0x1, 0xe8, + 0x88, 0x8d, 0x30, 0x0, 0x85, 0x0, 0x22, 0x22, + 0x22, 0x0, 0x0, 0x88, 0x79, 0xcc, 0xcc, 0xcc, + 0xc0, 0x29, 0xec, 0x50, 0x10, 0x1c, 0x0, 0x0, + 0x38, 0xa5, 0x0, 0xe0, 0x1c, 0x0, 0x0, 0x0, + 0x85, 0x3, 0xe0, 0x1f, 0xcc, 0x40, 0x0, 0x85, + 0x7, 0xe6, 0x1c, 0x0, 0x0, 0x0, 0x85, 0x2e, + 0x2d, 0x8c, 0x0, 0x0, 0xb, 0xe3, 0xb5, 0x1, + 0x9d, 0xdd, 0xd4, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+63DB "換" */ + 0x0, 0xc0, 0x0, 0xc, 0x10, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x5f, 0xcc, 0x40, 0x0, 0x1, 0xc0, + 0x2, 0xd2, 0xb, 0x10, 0x0, 0x8c, 0xfc, 0x3d, + 0xe9, 0xbd, 0x99, 0x0, 0x0, 0xc0, 0x28, 0xa2, + 0x33, 0x2c, 0x0, 0x0, 0xc0, 0x2, 0x94, 0x69, + 0x2b, 0x0, 0x0, 0xd7, 0x12, 0x9a, 0x1, 0x9b, + 0x0, 0x4b, 0xf8, 0x2, 0xb6, 0x42, 0x7b, 0x0, + 0x75, 0xc0, 0x2, 0x90, 0x92, 0xb, 0x0, 0x0, + 0xc0, 0x8c, 0xcc, 0xfe, 0xcc, 0xc0, 0x0, 0xc0, + 0x0, 0x5, 0xab, 0x10, 0x0, 0x0, 0xc0, 0x0, + 0x7b, 0x2, 0xc5, 0x0, 0x4e, 0x90, 0xab, 0x60, + 0x0, 0x17, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+63EE "揮" */ + 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0xb, 0xdc, 0xcc, 0xcc, 0xe5, 0x0, 0x85, + 0xb, 0x20, 0x9, 0x0, 0x75, 0x4d, 0xfe, 0xc5, + 0xcc, 0xcf, 0xcc, 0xc1, 0x0, 0x85, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x0, 0x85, 0x1, 0xeb, 0xbf, + 0xbb, 0xc0, 0x0, 0x88, 0x71, 0xb0, 0xc, 0x0, + 0xd0, 0x29, 0xec, 0x51, 0xea, 0xbf, 0xaa, 0xd0, + 0x24, 0x85, 0x1, 0xd4, 0x5d, 0x45, 0xd0, 0x0, + 0x85, 0x0, 0x44, 0x5d, 0x44, 0x30, 0x0, 0x85, + 0x2c, 0xcc, 0xcf, 0xcc, 0xc8, 0x0, 0x85, 0x0, + 0x0, 0xc, 0x0, 0x0, 0xd, 0xd2, 0x0, 0x0, + 0xc, 0x0, 0x0, + + /* U+63FA "揺" */ + 0x0, 0x67, 0x0, 0x0, 0x2, 0x47, 0x60, 0x0, + 0x67, 0xa, 0xcc, 0xca, 0x86, 0x30, 0x0, 0x67, + 0x1, 0x50, 0x63, 0x2, 0xc0, 0x5d, 0xee, 0xd1, + 0xd1, 0x48, 0xa, 0x50, 0x0, 0x67, 0x0, 0x63, + 0x14, 0x1c, 0x0, 0x0, 0x67, 0x9, 0xcc, 0xdd, + 0xdd, 0xc2, 0x0, 0x7a, 0x81, 0x0, 0x1c, 0x0, + 0x0, 0x4b, 0xfb, 0x5c, 0xcc, 0xcf, 0xcc, 0xc6, + 0x33, 0x77, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, + 0x67, 0x6, 0x70, 0x1c, 0x0, 0xc0, 0x0, 0x67, + 0x6, 0x80, 0x1c, 0x0, 0xd0, 0x0, 0x77, 0x6, + 0xdb, 0xce, 0xbb, 0xd0, 0xc, 0xd4, 0x6, 0x81, + 0x11, 0x11, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+643A "携" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x0, 0x75, 0x3a, 0x0, 0x0, 0x0, 0x85, + 0x0, 0xe6, 0x4e, 0x64, 0x40, 0x0, 0x85, 0x6, + 0xe8, 0x8e, 0x88, 0x70, 0x1d, 0xfe, 0xbe, 0xe8, + 0x8e, 0x88, 0x50, 0x0, 0x85, 0x23, 0xd1, 0x1d, + 0x11, 0x10, 0x0, 0x85, 0x0, 0xe9, 0x9f, 0x99, + 0x70, 0x0, 0x86, 0x30, 0xd1, 0x1e, 0x11, 0x10, + 0x5, 0xcd, 0x60, 0xd9, 0x99, 0x99, 0x92, 0x7, + 0xa5, 0x8, 0xab, 0xaa, 0xa0, 0x0, 0x0, 0x85, + 0x0, 0xd, 0x4, 0xeb, 0xb4, 0x0, 0x85, 0x0, + 0x59, 0x0, 0x0, 0xa3, 0x0, 0x85, 0x2, 0xd2, + 0x0, 0x0, 0xd1, 0xb, 0xe3, 0x4d, 0x30, 0x1, + 0xcc, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+64C1 "擁" */ + 0x0, 0xc0, 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc0, + 0x8d, 0xdd, 0xdd, 0xdd, 0xd3, 0x3b, 0xfb, 0x17, + 0x20, 0x26, 0x70, 0x0, 0x2, 0xd3, 0xc, 0x0, + 0x86, 0x87, 0x20, 0x0, 0xc0, 0x68, 0x86, 0xe9, + 0xda, 0x91, 0x0, 0xc3, 0xab, 0xda, 0xf0, 0x92, + 0x0, 0x17, 0xfb, 0x17, 0x45, 0xcb, 0xeb, 0xa0, + 0x27, 0xd0, 0x3d, 0x88, 0xc0, 0x92, 0x0, 0x0, + 0xc0, 0x87, 0xb2, 0xcb, 0xeb, 0x90, 0x0, 0xc0, + 0x2, 0xc0, 0xc0, 0x92, 0x0, 0x0, 0xd0, 0x3d, + 0x30, 0xcc, 0xec, 0xc4, 0x1c, 0xc0, 0xc3, 0x0, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+64C7 "擇" */ + 0x0, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x67, 0x5, 0xdb, 0xeb, 0xeb, 0xf0, 0x0, 0x67, + 0x5, 0x70, 0xc0, 0xb0, 0xc0, 0x1d, 0xee, 0xc4, + 0xba, 0xbe, 0xba, 0xb0, 0x0, 0x67, 0x1, 0x66, + 0x7d, 0x66, 0x40, 0x0, 0x67, 0x0, 0x33, 0x4d, + 0x33, 0x20, 0x0, 0x7c, 0xba, 0xcc, 0xcf, 0xcc, + 0xc1, 0x2e, 0xea, 0x10, 0xc, 0x0, 0x48, 0x0, + 0x1, 0x67, 0x5, 0x9d, 0xb9, 0xdb, 0x80, 0x0, + 0x67, 0x1, 0x22, 0x3c, 0x22, 0x20, 0x0, 0x67, + 0xb, 0xbb, 0xbf, 0xbb, 0xb4, 0x0, 0x67, 0x0, + 0x0, 0xc, 0x0, 0x0, 0xb, 0xd3, 0x0, 0x0, + 0xc, 0x0, 0x0, + + /* U+64D4 "擔" */ + 0x0, 0x75, 0x0, 0xc, 0x40, 0x0, 0x0, 0x0, + 0x75, 0x0, 0x5e, 0xaa, 0xe4, 0x0, 0x0, 0x75, + 0x4, 0xf8, 0x56, 0xe5, 0x53, 0x1d, 0xee, 0x8c, + 0xd6, 0x7a, 0x69, 0x64, 0x0, 0x75, 0x2, 0xc2, + 0xb2, 0x18, 0x90, 0x0, 0x75, 0x2, 0xc5, 0x13, + 0x90, 0x32, 0x0, 0x78, 0x62, 0xc9, 0x99, 0xa9, + 0x97, 0x8, 0xeb, 0x33, 0xa4, 0x99, 0x99, 0x90, + 0x7, 0x95, 0x4, 0xa1, 0x44, 0x44, 0x30, 0x0, + 0x75, 0x5, 0x82, 0x55, 0x55, 0x50, 0x0, 0x75, + 0x8, 0x57, 0xca, 0xaa, 0xe1, 0x0, 0x85, 0xc, + 0x27, 0x60, 0x0, 0xc1, 0xa, 0xd2, 0x2b, 0x7, + 0xc9, 0x99, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+64DA "據" */ + 0x0, 0xd0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0xdb, 0xbb, 0x50, 0x0, 0xd0, + 0x5, 0x55, 0xe6, 0x55, 0x50, 0x7d, 0xfd, 0x2d, + 0x66, 0xe6, 0x66, 0xc0, 0x0, 0xd0, 0x1b, 0x57, + 0xea, 0xa4, 0x60, 0x0, 0xd0, 0x1b, 0x42, 0xd3, + 0x34, 0x70, 0x0, 0xd3, 0x2b, 0x0, 0x47, 0x77, + 0x10, 0x17, 0xfb, 0x4a, 0x9a, 0xdd, 0xaa, 0x70, + 0x67, 0xd0, 0x38, 0x48, 0xa6, 0x6, 0x70, 0x0, + 0xd0, 0x57, 0x44, 0x9b, 0xab, 0x0, 0x0, 0xd0, + 0x95, 0xa6, 0x5b, 0x7a, 0x10, 0x0, 0xd0, 0xd0, + 0x49, 0x53, 0x82, 0xb1, 0x3d, 0xa4, 0x64, 0x60, + 0x8c, 0x20, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+652F "支" */ + 0x0, 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0xb, 0xcc, + 0xcc, 0xed, 0xcc, 0xcc, 0xa0, 0x2, 0x22, 0x22, + 0x98, 0x22, 0x22, 0x20, 0x0, 0x0, 0x0, 0x86, + 0x0, 0x0, 0x0, 0x0, 0x22, 0x22, 0x98, 0x22, + 0x20, 0x0, 0x3, 0xcf, 0xcc, 0xcc, 0xcc, 0xf7, + 0x0, 0x0, 0xa, 0x60, 0x0, 0x3, 0xd0, 0x0, + 0x0, 0x1, 0xe2, 0x0, 0x1d, 0x30, 0x0, 0x0, + 0x0, 0x3d, 0x43, 0xd4, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xff, 0x40, 0x0, 0x0, 0x0, 0x4, 0xad, + 0x77, 0xea, 0x40, 0x0, 0x3c, 0xea, 0x50, 0x0, + 0x6, 0xae, 0xd3, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x20, + + /* U+6539 "改" */ + 0x0, 0x0, 0x0, 0x0, 0x71, 0x0, 0x0, 0x9, + 0x99, 0x99, 0x0, 0xe0, 0x0, 0x0, 0x4, 0x44, + 0x4e, 0x5, 0xb0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0xa, 0xed, 0xdf, 0xe3, 0x0, 0x0, 0xe, 0x1f, + 0x50, 0xe, 0x10, 0xc, 0xee, 0xef, 0xa9, 0xa0, + 0x2d, 0x0, 0xd, 0x10, 0x0, 0x80, 0xd0, 0x69, + 0x0, 0xd, 0x10, 0x0, 0x0, 0x96, 0xd3, 0x0, + 0xd, 0x10, 0x0, 0x0, 0x2e, 0xb0, 0x0, 0xd, + 0x10, 0x49, 0x0, 0x1e, 0x80, 0x0, 0xe, 0x9e, + 0xb5, 0x1, 0xd7, 0xd5, 0x0, 0x1e, 0x81, 0x0, + 0x5e, 0x70, 0x2e, 0x80, 0x0, 0x0, 0x1, 0xb3, + 0x0, 0x1, 0x92, + + /* U+653E "放" */ + 0x0, 0x7, 0x0, 0x0, 0x44, 0x0, 0x0, 0x0, + 0xa, 0x40, 0x0, 0xa5, 0x0, 0x0, 0x15, 0x58, + 0x85, 0x50, 0xe2, 0x0, 0x0, 0x28, 0xdb, 0x88, + 0x83, 0xfd, 0xdf, 0xe6, 0x0, 0x94, 0x0, 0x9, + 0xc0, 0xa, 0x40, 0x0, 0x9e, 0xdd, 0x6d, 0xc0, + 0xd, 0x0, 0x0, 0x95, 0xa, 0x95, 0x85, 0x2c, + 0x0, 0x0, 0xb3, 0xb, 0x20, 0x3b, 0x86, 0x0, + 0x0, 0xd2, 0xb, 0x20, 0xc, 0xe0, 0x0, 0x0, + 0xe0, 0xc, 0x10, 0xa, 0xc0, 0x0, 0x4, 0xa0, + 0xd, 0x0, 0x7c, 0xc6, 0x0, 0xc, 0x30, 0xe, + 0x9, 0xd1, 0x1e, 0x70, 0x59, 0xa, 0xe8, 0xa9, + 0x0, 0x1, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+653F "政" */ + 0x0, 0x0, 0x0, 0x0, 0x43, 0x0, 0x0, 0x29, + 0x99, 0x99, 0x91, 0xb4, 0x0, 0x0, 0x14, 0x47, + 0xc4, 0x41, 0xf1, 0x0, 0x0, 0x0, 0x4, 0xa0, + 0x4, 0xfd, 0xdf, 0xe5, 0x6, 0x24, 0xa0, 0xc, + 0xa0, 0xa, 0x40, 0xa, 0x34, 0xfd, 0xcc, 0xd0, + 0xe, 0x0, 0xa, 0x34, 0xa0, 0x63, 0xa3, 0x2c, + 0x0, 0xa, 0x34, 0xa0, 0x0, 0x59, 0x96, 0x0, + 0xa, 0x34, 0xa0, 0x0, 0xd, 0xd0, 0x0, 0xa, + 0x34, 0xc7, 0xb2, 0xb, 0xb0, 0x0, 0x3d, 0xde, + 0xa7, 0x30, 0x9b, 0xb7, 0x0, 0x36, 0x20, 0x0, + 0x2b, 0xb0, 0x1d, 0x90, 0x0, 0x0, 0x0, 0x76, + 0x0, 0x0, 0x93, + + /* U+6545 "故" */ + 0x0, 0x9, 0x50, 0x0, 0xa3, 0x0, 0x0, 0x0, + 0x9, 0x50, 0x0, 0xe1, 0x0, 0x0, 0x0, 0x9, + 0x50, 0x3, 0xd0, 0x0, 0x0, 0x2d, 0xdf, 0xed, + 0xc8, 0xed, 0xdf, 0xe5, 0x0, 0x9, 0x50, 0xe, + 0x90, 0xb, 0x30, 0x0, 0x9, 0x50, 0x8b, 0xc0, + 0xe, 0x0, 0x6, 0xad, 0xca, 0xa1, 0xc1, 0x2c, + 0x0, 0x9, 0x73, 0x3a, 0x50, 0x78, 0x96, 0x0, + 0x9, 0x40, 0x8, 0x50, 0x1e, 0xd0, 0x0, 0x9, + 0x40, 0x8, 0x50, 0xc, 0x90, 0x0, 0x9, 0x62, + 0x2a, 0x50, 0x9c, 0xe4, 0x0, 0x9, 0xcb, 0xbb, + 0x8c, 0xa0, 0x3e, 0x70, 0x2, 0x10, 0x1, 0xb3, + 0x0, 0x1, 0xa3, + + /* U+6548 "效" */ + 0x0, 0x6, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, + 0xb, 0x40, 0x0, 0x3b, 0x0, 0x0, 0x17, 0x79, + 0xb7, 0x71, 0x78, 0x0, 0x0, 0x5, 0x75, 0x57, + 0x50, 0xae, 0xee, 0xf4, 0x0, 0xd0, 0x1d, 0x10, + 0xe0, 0x8, 0x60, 0x8, 0x70, 0x5, 0xa6, 0xf0, + 0xb, 0x20, 0x3c, 0x30, 0x38, 0x5d, 0xb5, 0xd, + 0x0, 0x1, 0xa8, 0x94, 0x3, 0x3b, 0x5a, 0x0, + 0x0, 0xb, 0xe0, 0x0, 0xd, 0xc3, 0x0, 0x0, + 0xb, 0xe4, 0x0, 0x8, 0xc0, 0x0, 0x0, 0x7a, + 0x2e, 0x10, 0x2d, 0xd4, 0x0, 0x8, 0xc0, 0x6, + 0x33, 0xd4, 0x2e, 0x30, 0x2a, 0x0, 0x0, 0x7d, + 0x30, 0x3, 0xe3, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x10, + + /* U+6557 "敗" */ + 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0xe, + 0xcc, 0xcf, 0x1, 0xe0, 0x0, 0x0, 0xe, 0x0, + 0xe, 0x6, 0xb2, 0x22, 0x20, 0xe, 0xbb, 0xbf, + 0xb, 0xa8, 0x8f, 0x92, 0xe, 0x0, 0xe, 0x3f, + 0x60, 0xe, 0x0, 0xe, 0x0, 0xe, 0xca, 0xa0, + 0x3c, 0x0, 0xe, 0xcc, 0xcf, 0xa0, 0xd0, 0x78, + 0x0, 0xe, 0x0, 0xe, 0x0, 0xb4, 0xc3, 0x0, + 0xe, 0x11, 0x1e, 0x0, 0x4c, 0xc0, 0x0, 0x9, + 0xaa, 0xba, 0x0, 0xf, 0x70, 0x0, 0x2, 0xb0, + 0x93, 0x0, 0x8d, 0xe1, 0x0, 0xa, 0x50, 0x2d, + 0x18, 0xd0, 0x7d, 0x20, 0x6b, 0x0, 0x4, 0xda, + 0x10, 0x7, 0xe3, 0x1, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x10, + + /* U+6559 "教" */ + 0x0, 0x2b, 0x0, 0x42, 0x58, 0x0, 0x0, 0x0, + 0x2c, 0x1, 0xe1, 0xa6, 0x0, 0x0, 0xc, 0xdf, + 0xcf, 0x80, 0xe3, 0x0, 0x0, 0x0, 0x2b, 0x1e, + 0x12, 0xfc, 0xbd, 0xd5, 0x8d, 0xde, 0xfe, 0xdc, + 0xe0, 0xa, 0x50, 0x0, 0x9, 0xa0, 0x2f, 0xd2, + 0xe, 0x10, 0x6, 0xfd, 0xcf, 0x97, 0x76, 0x2d, + 0x0, 0x3d, 0x72, 0xb4, 0x0, 0x3c, 0x87, 0x0, + 0x23, 0xa, 0x51, 0x31, 0xc, 0xe1, 0x0, 0x6b, + 0xcf, 0xdb, 0x92, 0xa, 0xd0, 0x0, 0x12, 0xa, + 0x30, 0x0, 0x8c, 0xc8, 0x0, 0x0, 0xa, 0x30, + 0x1a, 0xc1, 0x1e, 0x80, 0x3, 0xcd, 0x10, 0xa8, + 0x0, 0x1, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6562 "敢" */ + 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x4, + 0xcc, 0xce, 0x50, 0x3c, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x10, 0x79, 0x11, 0x10, 0x1d, 0xdd, 0xdf, + 0xd9, 0xac, 0xce, 0xd7, 0x0, 0xd0, 0x6, 0x71, + 0xf2, 0x9, 0x40, 0x0, 0xd1, 0x17, 0x77, 0xf4, + 0xc, 0x10, 0x0, 0xea, 0xac, 0x7d, 0x78, 0xd, + 0x0, 0x0, 0xd0, 0x6, 0x72, 0x1d, 0x3a, 0x0, + 0x0, 0xfc, 0xcd, 0x70, 0xc, 0xb4, 0x0, 0x0, + 0xd0, 0x6, 0x81, 0x5, 0xf0, 0x0, 0x16, 0xfa, + 0xce, 0xd5, 0xc, 0xd6, 0x0, 0x27, 0x52, 0x6, + 0x71, 0xb8, 0x1d, 0x80, 0x0, 0x0, 0x6, 0x7b, + 0x60, 0x1, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6570 "数" */ + 0x2, 0x32, 0xb0, 0x60, 0xa, 0x0, 0x0, 0x2, + 0xb2, 0xb2, 0xb0, 0x3b, 0x0, 0x0, 0x1, 0x93, + 0xc6, 0x41, 0x78, 0x0, 0x0, 0xa, 0xad, 0xfb, + 0xa7, 0xbe, 0xde, 0xe6, 0x0, 0x5d, 0xdb, 0x61, + 0xf6, 0x8, 0x50, 0xa, 0xa2, 0xb0, 0x78, 0xab, + 0xb, 0x20, 0x4, 0x6, 0x30, 0xa, 0xc, 0x1d, + 0x0, 0x8, 0xbf, 0xbb, 0xa0, 0x8, 0xa8, 0x0, + 0x1, 0x97, 0x15, 0xa0, 0x2, 0xf2, 0x0, 0x0, + 0xe7, 0x2d, 0x20, 0x6, 0xf4, 0x0, 0x0, 0x8, + 0xfb, 0x0, 0x3c, 0x3d, 0x10, 0x3, 0x8c, 0x37, + 0x57, 0xd1, 0x5, 0xd3, 0x9, 0x40, 0x0, 0x39, + 0x0, 0x0, 0x45, + + /* U+6574 "整" */ + 0x0, 0x3, 0x90, 0x0, 0x2a, 0x0, 0x0, 0xb, + 0xbc, 0xeb, 0xb3, 0x8a, 0x55, 0x52, 0x4, 0x8a, + 0xd8, 0x71, 0xf7, 0x6c, 0xa3, 0x8, 0x44, 0xa1, + 0xcb, 0x97, 0x1e, 0x10, 0x8, 0xbb, 0xda, 0xd2, + 0xb, 0xa8, 0x0, 0x0, 0x2c, 0xc9, 0x20, 0x8, + 0xf3, 0x0, 0x8, 0xa4, 0x91, 0x65, 0xb6, 0x2c, + 0xa3, 0x3, 0x1, 0x20, 0x4, 0x10, 0x0, 0x52, + 0x2, 0xcc, 0xcc, 0xde, 0xcc, 0xcc, 0x60, 0x0, + 0x2, 0x0, 0x58, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x10, 0x5e, 0xcc, 0xc6, 0x0, 0x0, 0xc, 0x10, + 0x58, 0x0, 0x0, 0x0, 0x1c, 0xcf, 0xdc, 0xee, + 0xcc, 0xcc, 0xc7, + + /* U+6587 "文" */ + 0x0, 0x0, 0x0, 0x52, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x10, 0x0, 0x0, 0x1e, 0xef, 0xee, + 0xee, 0xee, 0xfe, 0xe7, 0x0, 0x9, 0x60, 0x0, + 0x1, 0xe1, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x8, + 0x80, 0x0, 0x0, 0x0, 0x97, 0x0, 0x1e, 0x10, + 0x0, 0x0, 0x0, 0x1d, 0x30, 0xb7, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xe9, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xcf, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x3d, 0x95, 0xe8, 0x0, 0x0, 0x0, 0x4a, 0xe4, + 0x0, 0x1a, 0xd7, 0x10, 0x1d, 0xc5, 0x0, 0x0, + 0x0, 0x39, 0xf6, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6599 "料" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0xd, 0x0, 0x1a, 0xd, + 0xc, 0x6, 0x70, 0xd, 0x0, 0xc, 0xd, 0x1b, + 0x0, 0xaa, 0xd, 0x0, 0x9, 0x3d, 0x65, 0x0, + 0x6, 0xd, 0x0, 0x2, 0x1d, 0x30, 0x0, 0x0, + 0xd, 0x0, 0x4e, 0xef, 0xee, 0x5d, 0x40, 0xd, + 0x0, 0x0, 0x8f, 0x20, 0x1, 0xc4, 0xd, 0x0, + 0x0, 0xce, 0xc0, 0x0, 0x0, 0xd, 0x0, 0x6, + 0x7d, 0x5a, 0x0, 0x35, 0x8f, 0xd8, 0x1c, 0x1d, + 0x4, 0xad, 0xa8, 0x5e, 0x0, 0x56, 0xd, 0x0, + 0x0, 0x0, 0xd, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x0, 0xd, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+65AD "断" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x18, 0xd0, 0xd3, 0x1c, 0x6, + 0x15, 0xaf, 0xc7, 0x1d, 0x46, 0xc2, 0xc0, 0xe4, + 0x0, 0x0, 0xd0, 0x8c, 0x74, 0xe, 0x0, 0x0, + 0xd, 0x47, 0xd7, 0x72, 0xe0, 0x0, 0x0, 0xd3, + 0x6f, 0x75, 0x2f, 0xee, 0xfe, 0x6d, 0x7, 0xfc, + 0x20, 0xd0, 0xe, 0x0, 0xd1, 0xac, 0x2d, 0x2c, + 0x0, 0xe0, 0xd, 0xa2, 0xc0, 0x12, 0xb0, 0xe, + 0x0, 0xd0, 0xc, 0x0, 0x3a, 0x0, 0xe0, 0xd, + 0x0, 0x0, 0x6, 0x70, 0xe, 0x0, 0xbd, 0xdd, + 0xdd, 0xc3, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x1b, + 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+65B0 "新" */ + 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x8, 0x70, 0x0, 0x48, 0xbd, 0x70, 0x1c, 0xcc, + 0xcd, 0xc4, 0xc4, 0x10, 0x0, 0x1, 0xc0, 0xd, + 0x3, 0xa0, 0x0, 0x0, 0x0, 0xb1, 0x4a, 0x3, + 0xa0, 0x0, 0x0, 0x4c, 0xcd, 0xdc, 0xc7, 0xfd, + 0xdf, 0xd5, 0x0, 0x6, 0x60, 0x3, 0xa0, 0xe, + 0x0, 0x3d, 0xde, 0xed, 0xd6, 0x90, 0xe, 0x0, + 0x0, 0x26, 0x63, 0x5, 0x70, 0xe, 0x0, 0x6, + 0x76, 0x6a, 0x27, 0x60, 0xe, 0x0, 0xd, 0x16, + 0x63, 0xaa, 0x30, 0xe, 0x0, 0x25, 0x6, 0x60, + 0x3d, 0x0, 0xe, 0x0, 0x0, 0x6d, 0x40, 0x56, + 0x0, 0xe, 0x0, + + /* U+65B7 "斷" */ + 0x0, 0x20, 0x3, 0x0, 0x0, 0x24, 0xd, 0xa, + 0x10, 0x91, 0x5, 0xbc, 0x50, 0xd7, 0xb8, 0xaa, + 0x70, 0xd1, 0x0, 0xd, 0x2a, 0x43, 0x94, 0xc, + 0x0, 0x0, 0xd8, 0x9a, 0x98, 0xa0, 0xd3, 0x33, + 0x2d, 0xbb, 0xcb, 0xbb, 0x1e, 0x8e, 0x84, 0xd0, + 0x50, 0x6, 0x0, 0xc0, 0xc0, 0xd, 0x18, 0x53, + 0x76, 0xb, 0xc, 0x0, 0xda, 0xb6, 0xbc, 0x41, + 0xa0, 0xc0, 0xd, 0x18, 0x42, 0x75, 0x39, 0xc, + 0x0, 0xd9, 0x9a, 0xa8, 0x97, 0x60, 0xc0, 0xd, + 0xcc, 0xcc, 0xc7, 0xc1, 0xc, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x0, 0xc0, 0x0, + + /* U+65B9 "方" */ + 0x0, 0x0, 0x0, 0x42, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1c, 0x10, 0x0, 0x0, 0xd, 0xdd, 0xdf, + 0xdd, 0xdd, 0xdd, 0xd0, 0x0, 0x0, 0x2d, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4b, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6f, 0xee, 0xee, 0xfa, + 0x0, 0x0, 0x0, 0xa6, 0x0, 0x0, 0x68, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0x77, 0x0, 0x0, + 0x6, 0xb0, 0x0, 0x0, 0x95, 0x0, 0x0, 0x1e, + 0x30, 0x0, 0x0, 0xc3, 0x0, 0x2, 0xd7, 0x0, + 0x0, 0x1, 0xe0, 0x0, 0x1e, 0x50, 0x0, 0x1e, + 0xee, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+65BC "於" */ + 0x0, 0x15, 0x0, 0x0, 0x7, 0x50, 0x0, 0x0, + 0xd, 0x30, 0x0, 0xf, 0x90, 0x0, 0x2, 0x27, + 0x82, 0x10, 0x7c, 0xe4, 0x0, 0xa, 0xec, 0xaa, + 0x62, 0xe2, 0x3e, 0x20, 0x0, 0xa4, 0x0, 0x3d, + 0x50, 0x5, 0xd4, 0x0, 0xac, 0xbb, 0x63, 0x13, + 0x0, 0x34, 0x0, 0xb4, 0x2e, 0x0, 0x2d, 0x70, + 0x0, 0x0, 0xc0, 0xe, 0x0, 0x1, 0xc4, 0x0, + 0x0, 0xd0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xc0, 0x1d, 0x0, 0x30, 0x0, 0x0, 0x5, 0x90, + 0x2b, 0x2, 0xda, 0x10, 0x0, 0xc, 0x40, 0x59, + 0x0, 0x7, 0xe5, 0x0, 0x2c, 0xb, 0xe3, 0x0, + 0x0, 0x39, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+65BD "施" */ + 0x0, 0x13, 0x0, 0x3, 0x30, 0x0, 0x0, 0x0, + 0x1d, 0x0, 0xa, 0x50, 0x0, 0x0, 0x13, 0x3b, + 0x53, 0x1f, 0x98, 0x88, 0x82, 0x4a, 0xfa, 0xaa, + 0x9b, 0x56, 0x55, 0x51, 0x0, 0xe0, 0x2, 0xe4, + 0xc, 0x1, 0x30, 0x0, 0xf8, 0x84, 0x2d, 0xc, + 0xae, 0xa0, 0x1, 0xe5, 0x98, 0xd, 0x9f, 0x52, + 0xa0, 0x2, 0xb0, 0x58, 0x9f, 0x5c, 0x2, 0xa0, + 0x4, 0x90, 0x67, 0x4d, 0xc, 0x2, 0xa0, 0x7, + 0x70, 0x67, 0xd, 0xc, 0x4b, 0x70, 0xb, 0x30, + 0x76, 0xd, 0xb, 0x12, 0x10, 0x2e, 0x0, 0xa4, + 0xd, 0x0, 0x0, 0x84, 0x66, 0x5d, 0xc0, 0x8, + 0xdd, 0xdd, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+65C1 "旁" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, 0x6, 0xaa, + 0xaa, 0xbf, 0xaa, 0xaa, 0xa0, 0x1, 0x23, 0xd3, + 0x22, 0x29, 0x72, 0x20, 0x0, 0x0, 0xa7, 0x0, + 0xe, 0x10, 0x0, 0x8, 0xdd, 0xee, 0xdd, 0xef, + 0xdd, 0xd0, 0xa, 0x30, 0x0, 0x44, 0x0, 0x0, + 0xe0, 0x4, 0x10, 0x0, 0x4d, 0x0, 0x0, 0x60, + 0x1d, 0xdd, 0xdf, 0xdd, 0xdd, 0xdd, 0xd5, 0x0, + 0x0, 0x4b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9e, 0xcc, 0xcc, 0xd8, 0x0, 0x0, 0x3, 0xe0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x6e, 0x30, 0x0, + 0x0, 0xb4, 0x0, 0x2e, 0x91, 0x0, 0x5, 0xcc, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+65C5 "旅" */ + 0x0, 0x14, 0x0, 0x1, 0x40, 0x0, 0x0, 0x0, + 0x1d, 0x0, 0x7, 0x70, 0x0, 0x0, 0x2, 0x29, + 0x42, 0xd, 0xb9, 0x99, 0x92, 0x3b, 0xec, 0xbb, + 0x9a, 0x33, 0x47, 0x70, 0x0, 0xb2, 0x0, 0xb3, + 0x69, 0xb9, 0x40, 0x0, 0xbd, 0xd9, 0xe, 0x4a, + 0x30, 0x10, 0x0, 0xc2, 0x3b, 0xe, 0x6, 0x76, + 0xc0, 0x0, 0xd0, 0x3a, 0xe, 0x3, 0xeb, 0x0, + 0x0, 0xd0, 0x39, 0xe, 0x0, 0xe1, 0x0, 0x2, + 0xb0, 0x49, 0xe, 0x0, 0x97, 0x0, 0x7, 0x60, + 0x58, 0xe, 0x2, 0x3d, 0x0, 0xd, 0x10, 0x76, + 0xf, 0xac, 0x28, 0xb0, 0x58, 0xc, 0xd2, 0x2c, + 0x40, 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+65CF "族" */ + 0x0, 0x41, 0x0, 0x3, 0x20, 0x0, 0x0, 0x0, + 0x4c, 0x0, 0xa, 0x30, 0x0, 0x0, 0x13, 0x3a, + 0x53, 0x1f, 0xaa, 0xaa, 0xa3, 0x4a, 0xeb, 0xaa, + 0xb7, 0x73, 0x33, 0x30, 0x0, 0xc1, 0x1, 0x84, + 0xa2, 0x22, 0x10, 0x0, 0xdb, 0xb7, 0xb, 0x8f, + 0x88, 0x60, 0x0, 0xd2, 0x59, 0x76, 0xd, 0x0, + 0x0, 0x0, 0xc0, 0x49, 0x0, 0xe, 0x0, 0x0, + 0x0, 0xb0, 0x49, 0xad, 0xdf, 0xed, 0xd3, 0x3, + 0xa0, 0x58, 0x0, 0x3e, 0xa0, 0x0, 0x7, 0x70, + 0x67, 0x0, 0xb4, 0xc3, 0x0, 0xd, 0x20, 0x85, + 0x8, 0x90, 0x3d, 0x40, 0x4a, 0x2d, 0xd1, 0xc8, + 0x0, 0x2, 0xd3, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+65E2 "既" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0xdc, 0xcd, 0x1d, 0xdd, 0xdd, 0xb0, 0xc, 0x10, + 0xd, 0x0, 0x4, 0x80, 0x0, 0xc, 0x31, 0x1d, + 0x8, 0x45, 0x80, 0x0, 0xc, 0xa9, 0x9d, 0xb, + 0x16, 0x60, 0x0, 0xc, 0x10, 0xd, 0xd, 0x8, + 0x50, 0x0, 0xc, 0xdd, 0xdd, 0x4c, 0xcf, 0xcc, + 0xc1, 0xc, 0x10, 0x0, 0x0, 0x1f, 0x40, 0x0, + 0xc, 0x10, 0x92, 0x0, 0x6c, 0x90, 0x0, 0xc, + 0x10, 0x59, 0x0, 0xc5, 0x90, 0x0, 0xc, 0x49, + 0xdd, 0x5, 0xb2, 0x90, 0x52, 0xf, 0xe6, 0x5, + 0x3d, 0x12, 0x90, 0x73, 0x6, 0x0, 0x0, 0xc4, + 0x1, 0xdd, 0xc0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+65E5 "日" */ + 0x3e, 0xee, 0xee, 0xee, 0xed, 0x4b, 0x0, 0x0, + 0x0, 0x1e, 0x4b, 0x0, 0x0, 0x0, 0x1e, 0x4b, + 0x0, 0x0, 0x0, 0x1e, 0x4b, 0x0, 0x0, 0x0, + 0x1e, 0x4f, 0xee, 0xee, 0xee, 0xee, 0x4b, 0x0, + 0x0, 0x0, 0x1e, 0x4b, 0x0, 0x0, 0x0, 0x1e, + 0x4b, 0x0, 0x0, 0x0, 0x1e, 0x4b, 0x0, 0x0, + 0x0, 0x1e, 0x4f, 0xee, 0xee, 0xee, 0xfe, 0x4b, + 0x0, 0x0, 0x0, 0x1d, + + /* U+65E6 "旦" */ + 0x0, 0xf, 0xee, 0xee, 0xee, 0xf2, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0xd, + 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0xd, 0x0, + 0x0, 0x0, 0xc2, 0x0, 0x0, 0xf, 0xee, 0xee, + 0xee, 0xf2, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, + 0xc2, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0xc2, + 0x0, 0x0, 0xe, 0x33, 0x33, 0x33, 0xd2, 0x0, + 0x0, 0xb, 0xbb, 0xbb, 0xbb, 0xb1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x3, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x30, + + /* U+65E9 "早" */ + 0x0, 0x9e, 0xdd, 0xdd, 0xdd, 0xdf, 0x0, 0x0, + 0x94, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x9d, + 0xcc, 0xcc, 0xcc, 0xcf, 0x0, 0x0, 0x94, 0x0, + 0x0, 0x0, 0xe, 0x0, 0x0, 0x94, 0x0, 0x0, + 0x0, 0xe, 0x0, 0x0, 0x8d, 0xdd, 0xef, 0xdd, + 0xdd, 0x0, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, + 0x1e, 0xee, 0xee, 0xef, 0xee, 0xee, 0xe8, 0x0, + 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4a, 0x0, 0x0, 0x0, + + /* U+65F6 "时" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0xd0, 0xa, 0xbb, + 0xb2, 0x0, 0x0, 0x1d, 0x0, 0xe2, 0x2b, 0x20, + 0x0, 0x1, 0xd0, 0xe, 0x0, 0xa4, 0xee, 0xee, + 0xef, 0xe8, 0xe0, 0xa, 0x20, 0x0, 0x1, 0xd0, + 0xe, 0xbb, 0xe2, 0x39, 0x0, 0x1d, 0x0, 0xe1, + 0x1b, 0x20, 0xc5, 0x1, 0xd0, 0xe, 0x0, 0xa2, + 0x3, 0xe1, 0x1d, 0x0, 0xe0, 0xa, 0x20, 0x9, + 0x71, 0xd0, 0xe, 0x22, 0xb2, 0x0, 0x0, 0x1d, + 0x0, 0xeb, 0xbb, 0x10, 0x0, 0x1, 0xd0, 0x9, + 0x0, 0x0, 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, + 0x0, 0xe, 0xee, 0x70, 0x0, + + /* U+6607 "昇" */ + 0x0, 0x9d, 0xcc, 0xcc, 0xcc, 0xcf, 0x0, 0x0, + 0x95, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x9d, + 0xbb, 0xbb, 0xbb, 0xbf, 0x0, 0x0, 0x95, 0x0, + 0x0, 0x0, 0xe, 0x0, 0x0, 0x7c, 0xcc, 0xcd, + 0xcc, 0xcc, 0x0, 0x0, 0x14, 0x69, 0xd8, 0x7, + 0x70, 0x0, 0x4, 0xb9, 0xb8, 0x0, 0x7, 0x70, + 0x0, 0x1, 0x11, 0x88, 0x11, 0x18, 0x81, 0x10, + 0x1b, 0xbb, 0xed, 0xbb, 0xbd, 0xdb, 0xb6, 0x0, + 0x0, 0xd2, 0x0, 0x7, 0x70, 0x0, 0x0, 0x1b, + 0x80, 0x0, 0x7, 0x70, 0x0, 0x5, 0xc5, 0x0, + 0x0, 0x7, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+660E "明" */ + 0xed, 0xdd, 0xd0, 0xfd, 0xdd, 0xee, 0xe0, 0x0, + 0xd0, 0xe0, 0x0, 0xe, 0xe0, 0x0, 0xd0, 0xe0, + 0x0, 0xe, 0xe0, 0x0, 0xd0, 0xf8, 0x88, 0x9e, + 0xed, 0xdd, 0xd0, 0xf5, 0x55, 0x5e, 0xe0, 0x0, + 0xd0, 0xe0, 0x0, 0xe, 0xe0, 0x0, 0xd1, 0xd0, + 0x0, 0xe, 0xe3, 0x33, 0xd3, 0xfc, 0xcc, 0xde, + 0xea, 0xaa, 0x97, 0x70, 0x0, 0xe, 0x90, 0x0, + 0xe, 0x20, 0x0, 0xe, 0x0, 0x0, 0x9a, 0x0, + 0x0, 0xe, 0x0, 0x3, 0xd1, 0x0, 0x3e, 0xe9, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6613 "易" */ + 0x0, 0x2f, 0xcc, 0xcc, 0xcc, 0xdd, 0x0, 0x2, + 0xc0, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x2f, 0xcc, + 0xcc, 0xcc, 0xcd, 0x0, 0x2, 0xc0, 0x0, 0x0, + 0x1, 0xd0, 0x0, 0x2f, 0xcc, 0xcc, 0xcc, 0xcd, + 0x0, 0x0, 0x1d, 0x30, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xeb, 0xbb, 0xbb, 0xbb, 0x80, 0x2d, 0x61, + 0x7b, 0x15, 0xc1, 0x5a, 0xc, 0x40, 0x3d, 0x10, + 0xb4, 0x5, 0x90, 0x0, 0x2d, 0x30, 0x4c, 0x0, + 0x76, 0x0, 0x5d, 0x30, 0x3d, 0x20, 0xb, 0x40, + 0x6, 0x20, 0xb, 0x30, 0xcc, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6614 "昔" */ + 0x0, 0x0, 0xd1, 0x0, 0xe, 0x0, 0x0, 0x0, + 0x0, 0xd1, 0x0, 0xe, 0x0, 0x0, 0x5, 0xdd, + 0xfe, 0xdd, 0xef, 0xdd, 0x70, 0x0, 0x0, 0xd1, + 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0xd1, 0x0, + 0xe, 0x0, 0x0, 0x2e, 0xee, 0xee, 0xee, 0xee, + 0xee, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1f, 0xcc, 0xcc, 0xcc, 0xf2, 0x0, + 0x0, 0x1c, 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, + 0x1f, 0xcc, 0xcc, 0xcc, 0xf2, 0x0, 0x0, 0x1c, + 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x1d, 0x0, + 0x0, 0x0, 0xc2, 0x0, 0x0, 0x1f, 0xcc, 0xcc, + 0xcc, 0xf2, 0x0, + + /* U+661F "星" */ + 0x0, 0x9d, 0xbb, 0xbb, 0xbb, 0xda, 0x0, 0x0, + 0x94, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x9d, + 0xbb, 0xbb, 0xbb, 0xca, 0x0, 0x0, 0x94, 0x0, + 0x0, 0x0, 0x4a, 0x0, 0x0, 0x7c, 0xcc, 0xcc, + 0xcc, 0xc8, 0x0, 0x0, 0x1b, 0x0, 0x44, 0x0, + 0x0, 0x0, 0x0, 0xbf, 0xdd, 0xee, 0xdd, 0xdd, + 0x30, 0xb, 0x70, 0x0, 0x77, 0x0, 0x0, 0x0, + 0x4, 0x5b, 0xbb, 0xdd, 0xbb, 0xb7, 0x0, 0x0, + 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x77, 0x0, 0x0, 0x0, 0x1d, 0xdd, 0xdd, + 0xee, 0xdd, 0xdd, 0xd1, + + /* U+6620 "映" */ + 0x0, 0x0, 0x0, 0x0, 0xd0, 0x0, 0xd, 0xee, + 0xd0, 0x0, 0xd, 0x0, 0x0, 0xd0, 0xd, 0x9, + 0xaa, 0xfa, 0xa9, 0xd, 0x0, 0xd0, 0xd2, 0x2e, + 0x22, 0xd0, 0xd0, 0xd, 0xd, 0x0, 0xd0, 0xd, + 0xe, 0xbb, 0xd0, 0xd0, 0xd, 0x0, 0xd0, 0xd2, + 0x2d, 0xd, 0x0, 0xd0, 0xd, 0xd, 0x0, 0xda, + 0xfd, 0xdf, 0xdd, 0xfa, 0xd0, 0xd, 0x0, 0x6, + 0xf6, 0x0, 0xd, 0x22, 0xd0, 0x0, 0xc6, 0xd0, + 0x0, 0xea, 0xa9, 0x0, 0x8b, 0x9, 0x70, 0x7, + 0x0, 0x1, 0xab, 0x10, 0x1d, 0x60, 0x0, 0x1, + 0xd7, 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+6625 "春" */ + 0x0, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, 0x5, + 0xbb, 0xbb, 0xec, 0xbb, 0xbb, 0x50, 0x0, 0x11, + 0x13, 0xe1, 0x11, 0x11, 0x0, 0x0, 0xcc, 0xcd, + 0xfc, 0xcc, 0xcc, 0x0, 0x0, 0x0, 0xe, 0x20, + 0x0, 0x0, 0x0, 0x3d, 0xdd, 0xdf, 0xdd, 0xdd, + 0xdd, 0xd3, 0x0, 0x6, 0xd0, 0x0, 0xb, 0x60, + 0x0, 0x0, 0x6f, 0xec, 0xcc, 0xcd, 0xf7, 0x0, + 0x2b, 0xbb, 0x50, 0x0, 0x4, 0xca, 0xd2, 0x5, + 0x9, 0xdb, 0xbb, 0xbc, 0xb0, 0x30, 0x0, 0x9, + 0x50, 0x0, 0x5, 0xb0, 0x0, 0x0, 0x9, 0x61, + 0x11, 0x15, 0xb0, 0x0, 0x0, 0x9, 0xdb, 0xbb, + 0xbc, 0xa0, 0x0, + + /* U+6628 "昨" */ + 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0xc, 0xdd, + 0xd0, 0x3c, 0x0, 0x0, 0x0, 0xe0, 0xe, 0x8, + 0xdb, 0xbb, 0xbb, 0x3e, 0x0, 0xe1, 0xe3, 0xe3, + 0x22, 0x20, 0xe0, 0xe, 0x97, 0xe, 0x0, 0x0, + 0xe, 0xdd, 0xf6, 0x0, 0xec, 0xcc, 0xb0, 0xe0, + 0xe, 0x0, 0xe, 0x11, 0x11, 0xe, 0x0, 0xe0, + 0x0, 0xe0, 0x0, 0x0, 0xe0, 0xe, 0x0, 0xe, + 0x55, 0x55, 0xe, 0x33, 0xe0, 0x0, 0xea, 0xaa, + 0xa0, 0xea, 0xaa, 0x0, 0xe, 0x0, 0x0, 0x7, + 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x0, 0x0, 0x0, + + /* U+662F "是" */ + 0x0, 0xac, 0xbb, 0xbb, 0xbb, 0xc9, 0x0, 0x0, + 0xa3, 0x0, 0x0, 0x0, 0x49, 0x0, 0x0, 0xac, + 0xaa, 0xaa, 0xaa, 0xc9, 0x0, 0x0, 0xa6, 0x33, + 0x33, 0x33, 0x79, 0x0, 0x0, 0x45, 0x55, 0x55, + 0x55, 0x53, 0x0, 0x2b, 0xbb, 0xbb, 0xbb, 0xbb, + 0xbb, 0xb2, 0x1, 0x14, 0x21, 0x6a, 0x11, 0x11, + 0x10, 0x0, 0xf, 0x10, 0x59, 0x0, 0x0, 0x0, + 0x0, 0x4f, 0x0, 0x5e, 0xdd, 0xdd, 0x30, 0x0, + 0xac, 0x80, 0x59, 0x0, 0x0, 0x0, 0x7, 0xd0, + 0xbb, 0x89, 0x0, 0x0, 0x0, 0x3e, 0x20, 0x5, + 0xbe, 0xee, 0xee, 0xe4, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+663C "昼" */ + 0x0, 0xad, 0xcc, 0xcc, 0xcc, 0xde, 0x0, 0x0, + 0xa4, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0xbd, + 0xcc, 0xcc, 0xcc, 0xce, 0x0, 0x0, 0xd2, 0x0, + 0x0, 0x3e, 0x20, 0x0, 0x1, 0xd0, 0x0, 0x0, + 0x9, 0xc0, 0x0, 0x7, 0x8e, 0xbb, 0xbb, 0xbc, + 0xfd, 0x40, 0x3e, 0x1d, 0x0, 0x0, 0x1, 0xd5, + 0xd2, 0x2, 0xe, 0xaa, 0xaa, 0xab, 0xc0, 0x0, + 0x0, 0xd, 0x0, 0x0, 0x1, 0xc0, 0x0, 0x0, + 0xa, 0xbb, 0xbb, 0xbb, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xee, 0xee, + 0xee, 0xee, 0xee, 0xb0, + + /* U+6642 "時" */ + 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0xe, 0xdd, + 0xf0, 0x0, 0xe, 0x0, 0x0, 0xd0, 0xe, 0x1d, + 0xdd, 0xfd, 0xdd, 0xd, 0x0, 0xe0, 0x0, 0xe, + 0x0, 0x0, 0xd0, 0xe, 0x46, 0x66, 0xf6, 0x66, + 0x4e, 0xdd, 0xf4, 0x66, 0x66, 0x7d, 0x63, 0xd0, + 0xe, 0x0, 0x0, 0x2, 0xc0, 0xd, 0x0, 0xe8, + 0xdd, 0xdd, 0xdf, 0xd6, 0xd0, 0xe, 0x3, 0x20, + 0x2, 0xc0, 0xe, 0xbb, 0xf0, 0x3d, 0x20, 0x2c, + 0x0, 0xe1, 0x11, 0x0, 0x6b, 0x2, 0xc0, 0x3, + 0x0, 0x0, 0x0, 0x10, 0x2c, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xdd, 0x80, 0x0, + + /* U+6669 "晩" */ + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0xd, 0xdd, + 0xc0, 0x1f, 0xdb, 0xb2, 0x0, 0xd0, 0xd, 0xa, + 0x60, 0x2c, 0x0, 0xd, 0x0, 0xd9, 0xe6, 0x6b, + 0xa6, 0x50, 0xd0, 0xe, 0xbd, 0x66, 0xe6, 0x6e, + 0xe, 0xdd, 0xd2, 0xb0, 0xd, 0x0, 0xd0, 0xd0, + 0xd, 0x2b, 0x0, 0xd0, 0xd, 0xd, 0x0, 0xd2, + 0xfd, 0xdf, 0xdd, 0xe0, 0xd0, 0xd, 0x0, 0x95, + 0x1c, 0x0, 0xe, 0xbb, 0xd0, 0xc, 0x21, 0xc0, + 0x0, 0xd1, 0x11, 0x4, 0xc0, 0x1c, 0x4, 0x53, + 0x0, 0x4, 0xd3, 0x1, 0xc0, 0x66, 0x0, 0xa, + 0xb2, 0x0, 0xc, 0xde, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+666E "普" */ + 0x0, 0x3, 0x60, 0x0, 0x3, 0x60, 0x0, 0x0, + 0x0, 0xd1, 0x0, 0xc, 0x30, 0x0, 0x3, 0xcc, + 0xce, 0xdc, 0xfc, 0xcc, 0x90, 0x0, 0x57, 0xa, + 0x30, 0xe0, 0x3b, 0x0, 0x0, 0xd, 0x1a, 0x30, + 0xe0, 0xb3, 0x0, 0x6, 0x69, 0x7d, 0x86, 0xe6, + 0xa6, 0x63, 0x5, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x52, 0x0, 0x1b, 0xbb, 0xbb, 0xbb, 0xb6, 0x0, + 0x0, 0x1c, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, + 0x1e, 0xaa, 0xaa, 0xaa, 0xc9, 0x0, 0x0, 0x1d, + 0x11, 0x11, 0x11, 0x69, 0x0, 0x0, 0x1c, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x1f, 0xcc, 0xcc, + 0xcc, 0xd8, 0x0, + + /* U+666F "景" */ + 0x0, 0x9c, 0xaa, 0xaa, 0xaa, 0xc9, 0x0, 0x0, + 0x9a, 0x77, 0x77, 0x77, 0xa9, 0x0, 0x0, 0x96, + 0x11, 0x11, 0x11, 0x69, 0x0, 0x0, 0x6a, 0xaa, + 0xdb, 0xaa, 0xa6, 0x0, 0x16, 0x66, 0x66, 0xc9, + 0x66, 0x66, 0x61, 0x16, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x61, 0x0, 0x3c, 0xbb, 0xbb, 0xbb, 0xc4, + 0x0, 0x0, 0x49, 0x0, 0x0, 0x0, 0x95, 0x0, + 0x0, 0x4e, 0xbb, 0xbb, 0xbb, 0xe5, 0x0, 0x0, + 0x4, 0x60, 0x77, 0x6, 0x10, 0x0, 0x4, 0xaa, + 0x10, 0x77, 0x4, 0xba, 0x20, 0x19, 0x30, 0x2b, + 0xd4, 0x0, 0x3, 0x90, + + /* U+6674 "晴" */ + 0x0, 0x0, 0x0, 0x1, 0xc0, 0x0, 0xc, 0xdd, + 0x93, 0xaa, 0xae, 0xaa, 0xa1, 0xc0, 0xb, 0x1, + 0x13, 0xd1, 0x11, 0xc, 0x0, 0xb0, 0xbb, 0xbf, + 0xbb, 0x90, 0xc0, 0xb, 0x24, 0x45, 0xd4, 0x44, + 0x1e, 0xcc, 0xb4, 0x66, 0x66, 0x66, 0x62, 0xc0, + 0xb, 0x8, 0xbb, 0xbb, 0xb5, 0xc, 0x0, 0xb0, + 0xb1, 0x0, 0x6, 0x70, 0xc0, 0xb, 0xb, 0xba, + 0xaa, 0xc7, 0xd, 0x89, 0xb0, 0xb1, 0x0, 0x6, + 0x70, 0xd4, 0x43, 0xb, 0xbb, 0xbb, 0xd7, 0x4, + 0x0, 0x0, 0xb1, 0x0, 0x6, 0x70, 0x0, 0x0, + 0xb, 0x10, 0xa, 0xd4, 0x0, + + /* U+667A "智" */ + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, + 0xcc, 0xc8, 0x4c, 0xcc, 0xc3, 0xd, 0x15, 0x90, + 0x6, 0x70, 0xa, 0x42, 0xb9, 0xbd, 0x99, 0x66, + 0x0, 0xa4, 0x2, 0x2c, 0xa2, 0x26, 0x60, 0xa, + 0x40, 0x6, 0xb7, 0xc3, 0x6e, 0xdd, 0xf4, 0x1a, + 0xa0, 0x3, 0x70, 0x0, 0x0, 0x0, 0x42, 0xcc, + 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x3b, 0x0, 0x0, + 0x0, 0xd1, 0x0, 0x3, 0xea, 0xaa, 0xaa, 0xaf, + 0x10, 0x0, 0x3b, 0x11, 0x11, 0x11, 0xd1, 0x0, + 0x3, 0xb0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x3e, + 0xcc, 0xcc, 0xcc, 0xf1, 0x0, + + /* U+6687 "暇" */ + 0xcd, 0xd2, 0xdc, 0xcd, 0x7d, 0xdf, 0xc, 0x9, + 0x2d, 0x0, 0xd0, 0x0, 0xd0, 0xc0, 0x92, 0xd0, + 0xd, 0x0, 0xd, 0xc, 0x9, 0x2d, 0xcc, 0xd7, + 0xcc, 0xf0, 0xec, 0xe2, 0xd0, 0x0, 0x0, 0x0, + 0xd, 0x4b, 0x2d, 0x0, 0x8, 0x88, 0x80, 0xc0, + 0x92, 0xdc, 0xc5, 0xa7, 0x5d, 0xc, 0x9, 0x2d, + 0x0, 0x3, 0x96, 0x90, 0xea, 0xd2, 0xdc, 0xca, + 0xc, 0xd1, 0xd, 0x33, 0xd, 0x0, 0x0, 0xab, + 0x0, 0x50, 0x0, 0xd0, 0x0, 0x9a, 0xb7, 0x0, + 0x0, 0xd, 0x0, 0xa6, 0x0, 0xb3, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6691 "暑" */ + 0x0, 0xcb, 0xaa, 0xaa, 0xaa, 0xc8, 0x0, 0x0, + 0xc8, 0x77, 0x77, 0x77, 0xb8, 0x0, 0x0, 0xc4, + 0x22, 0x22, 0x22, 0x78, 0x0, 0x0, 0x8a, 0xac, + 0xca, 0xaa, 0xa8, 0x20, 0x1, 0x88, 0x8b, 0xc8, + 0x88, 0x6b, 0x20, 0x0, 0x33, 0x37, 0xa3, 0x7e, + 0x70, 0x0, 0x1b, 0xbb, 0xbd, 0xed, 0xed, 0xbb, + 0xb0, 0x0, 0x16, 0xaf, 0xb5, 0x33, 0x32, 0x0, + 0x2d, 0xde, 0x86, 0x66, 0x66, 0x8b, 0x0, 0x1, + 0xb, 0xba, 0xaa, 0xaa, 0xbb, 0x0, 0x0, 0xb, + 0x30, 0x0, 0x0, 0x2b, 0x0, 0x0, 0xb, 0xba, + 0xaa, 0xaa, 0xbb, 0x0, + + /* U+6696 "暖" */ + 0x0, 0x0, 0x0, 0x12, 0x45, 0x86, 0xc, 0xdd, + 0xb6, 0xba, 0xa9, 0x66, 0x40, 0xd0, 0xd, 0xc, + 0x6, 0x60, 0xa6, 0xd, 0x0, 0xd0, 0x83, 0x26, + 0x2c, 0x0, 0xd0, 0xd, 0x5c, 0xed, 0xcc, 0xcc, + 0x2e, 0xaa, 0xd0, 0xc, 0x20, 0x0, 0x0, 0xd2, + 0x2d, 0xbc, 0xfc, 0xcc, 0xcc, 0x6d, 0x0, 0xd0, + 0x1e, 0x33, 0x34, 0x10, 0xd0, 0xd, 0x5, 0xf7, + 0x67, 0xe4, 0xe, 0xbb, 0xd0, 0xb7, 0xa0, 0x6c, + 0x0, 0xd2, 0x21, 0x5a, 0x6, 0xcd, 0x10, 0x4, + 0x0, 0x4c, 0x24, 0xac, 0xea, 0x40, 0x0, 0xa, + 0x18, 0xb4, 0x0, 0x7c, 0x70, + + /* U+6697 "暗" */ + 0x0, 0x0, 0x0, 0x3, 0x60, 0x0, 0x9, 0xaa, + 0x80, 0x0, 0x1e, 0x0, 0x0, 0xd3, 0x3d, 0x4d, + 0xdd, 0xdd, 0xdd, 0x2d, 0x0, 0xd0, 0x4a, 0x0, + 0xe, 0x10, 0xd0, 0xd, 0x0, 0xe0, 0x5, 0xa0, + 0xd, 0xaa, 0xd9, 0xde, 0xdd, 0xee, 0xd8, 0xd3, + 0x3d, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0xd0, + 0xcc, 0xcc, 0xcc, 0xa0, 0xd0, 0xd, 0xd, 0x0, + 0x0, 0x2b, 0xd, 0x22, 0xd0, 0xd6, 0x66, 0x68, + 0xb0, 0xea, 0xa9, 0xd, 0x55, 0x55, 0x7b, 0x7, + 0x0, 0x0, 0xd1, 0x11, 0x13, 0xb0, 0x0, 0x0, + 0xd, 0xaa, 0xaa, 0xbb, 0x0, + + /* U+66C7 "曇" */ + 0x0, 0xb9, 0x88, 0x88, 0x88, 0xaa, 0x0, 0x0, + 0xb8, 0x77, 0x77, 0x77, 0x9a, 0x0, 0x0, 0x89, + 0x88, 0x88, 0x88, 0x97, 0x0, 0x3, 0x99, 0x99, + 0xba, 0x99, 0x99, 0x30, 0x9, 0xaa, 0xaa, 0xdc, + 0xaa, 0xaa, 0x90, 0xd, 0x16, 0x65, 0x75, 0x56, + 0x61, 0xd0, 0x3, 0x1, 0x11, 0x75, 0x11, 0x10, + 0x30, 0x0, 0x47, 0x75, 0x54, 0x68, 0x85, 0x0, + 0x0, 0x69, 0x99, 0x99, 0x99, 0x97, 0x0, 0x2a, + 0xaa, 0xcc, 0xaa, 0xac, 0xaa, 0xa2, 0x0, 0x5, + 0xd2, 0x0, 0x1d, 0x80, 0x0, 0x0, 0x8f, 0xba, + 0xaa, 0xab, 0xdc, 0x10, 0x0, 0x22, 0x10, 0x0, + 0x0, 0x4, 0x10, + + /* U+66DC "曜" */ + 0xcd, 0xd8, 0x9b, 0xbc, 0x7b, 0xbe, 0xc, 0x2, + 0xa3, 0xa0, 0xc1, 0xb1, 0xd0, 0xc0, 0x2a, 0x5, + 0x8c, 0x2, 0x8e, 0xc, 0x2, 0xa7, 0xc5, 0xc5, + 0xc7, 0xd0, 0xd8, 0x9a, 0x32, 0x45, 0x90, 0x5, + 0xc, 0x3, 0xa0, 0xbc, 0xae, 0xba, 0xa0, 0xc0, + 0x2a, 0x5e, 0x11, 0xa4, 0x11, 0xc, 0x2, 0xcc, + 0xfa, 0xad, 0xba, 0x60, 0xd8, 0x9a, 0x1d, 0x0, + 0x93, 0x0, 0xd, 0x44, 0x30, 0xfa, 0xae, 0xca, + 0x60, 0x40, 0x0, 0xe, 0x0, 0x93, 0x0, 0x0, + 0x0, 0x0, 0xfb, 0xbb, 0xbb, 0xb3, + + /* U+66F2 "曲" */ + 0x0, 0x3, 0xb0, 0xe, 0x0, 0x0, 0x0, 0x3, + 0xb0, 0xe, 0x0, 0x0, 0x0, 0x3, 0xb0, 0xe, + 0x0, 0x0, 0xce, 0xef, 0xfe, 0xef, 0xee, 0xe3, + 0xc1, 0x3, 0xb0, 0xe, 0x0, 0xb3, 0xc1, 0x3, + 0xb0, 0xe, 0x0, 0xb3, 0xc1, 0x3, 0xb0, 0xe, + 0x0, 0xb3, 0xce, 0xde, 0xfd, 0xdf, 0xdd, 0xf3, + 0xc1, 0x3, 0xb0, 0xe, 0x0, 0xb3, 0xc1, 0x3, + 0xb0, 0xe, 0x0, 0xb3, 0xc1, 0x3, 0xb0, 0xe, + 0x0, 0xb3, 0xcf, 0xef, 0xfe, 0xef, 0xee, 0xf3, + 0xc1, 0x0, 0x0, 0x0, 0x0, 0xa3, + + /* U+66F4 "更" */ + 0x1d, 0xdd, 0xdd, 0xef, 0xdd, 0xdd, 0xd1, 0x0, + 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, 0x0, 0xbc, + 0xcc, 0xee, 0xcc, 0xcd, 0x20, 0x0, 0xc1, 0x0, + 0x68, 0x0, 0xb, 0x30, 0x0, 0xcc, 0xcc, 0xde, + 0xcc, 0xcf, 0x30, 0x0, 0xc1, 0x0, 0x68, 0x0, + 0xb, 0x30, 0x0, 0xc2, 0x11, 0x79, 0x11, 0x1c, + 0x30, 0x0, 0x9c, 0xbb, 0xed, 0xbb, 0xbb, 0x20, + 0x0, 0x1d, 0x30, 0xd2, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xdb, 0x80, 0x0, 0x0, 0x0, 0x0, 0x28, + 0xda, 0xc8, 0x42, 0x0, 0x0, 0x1e, 0xc7, 0x0, + 0x4, 0x9b, 0xde, 0xe4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+66F8 "書" */ + 0x0, 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0x0, + 0x7a, 0xaa, 0xdc, 0xaa, 0xb5, 0x0, 0x3, 0x33, + 0x33, 0xa9, 0x33, 0x99, 0x30, 0x17, 0x77, 0x77, + 0xbb, 0x77, 0xbb, 0x71, 0x0, 0x8a, 0xaa, 0xdc, + 0xaa, 0xc7, 0x0, 0x0, 0x33, 0x33, 0x98, 0x33, + 0x33, 0x0, 0x1, 0x66, 0x66, 0xba, 0x66, 0x66, + 0x20, 0x2b, 0xbb, 0xbb, 0xdd, 0xbb, 0xbb, 0xb2, + 0x0, 0x14, 0x44, 0x44, 0x44, 0x42, 0x0, 0x0, + 0x6b, 0x66, 0x66, 0x66, 0xa8, 0x0, 0x0, 0x6d, + 0x99, 0x99, 0x99, 0xc8, 0x0, 0x0, 0x68, 0x0, + 0x0, 0x0, 0x68, 0x0, 0x0, 0x6d, 0xaa, 0xaa, + 0xaa, 0xc8, 0x0, + + /* U+66FE "曾" */ + 0x0, 0x9, 0x0, 0x0, 0x90, 0x0, 0x0, 0x8, + 0x70, 0x5, 0x90, 0x0, 0x1e, 0xbc, 0xcc, 0xdc, + 0xcb, 0xe1, 0x1d, 0x19, 0x3, 0xa0, 0x81, 0xe1, + 0x1d, 0x6, 0x73, 0xa4, 0x80, 0xe1, 0x1e, 0x66, + 0x88, 0xc8, 0x66, 0xf1, 0x5, 0x55, 0x55, 0x55, + 0x55, 0x50, 0x2, 0xbb, 0xbb, 0xbb, 0xbb, 0x20, + 0x2, 0xd0, 0x0, 0x0, 0xc, 0x30, 0x2, 0xfb, + 0xbb, 0xbb, 0xbe, 0x30, 0x2, 0xd0, 0x0, 0x0, + 0xc, 0x30, 0x2, 0xe9, 0x99, 0x99, 0x9e, 0x30, + 0x2, 0xd2, 0x22, 0x22, 0x2c, 0x30, + + /* U+66FF "替" */ + 0x0, 0x7, 0x60, 0x0, 0x3, 0xa0, 0x0, 0x7, + 0xad, 0xda, 0x35, 0xac, 0xea, 0xa0, 0x0, 0x8, + 0x60, 0x0, 0x5, 0xa0, 0x0, 0x9, 0x9d, 0xc9, + 0x58, 0x9c, 0xd9, 0x93, 0x2, 0x3f, 0xa2, 0x12, + 0x3e, 0xc6, 0x21, 0x0, 0x98, 0xaa, 0x1, 0xb8, + 0x1d, 0x10, 0x9, 0xa0, 0x7, 0x2d, 0x70, 0x4, + 0xd5, 0x6, 0x3d, 0xdd, 0xdd, 0xdd, 0xd7, 0x12, + 0x0, 0x49, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, + 0x4e, 0xbb, 0xbb, 0xbb, 0xd9, 0x0, 0x0, 0x49, + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x4a, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x4e, 0xcc, 0xcc, + 0xcc, 0xd8, 0x0, + + /* U+6700 "最" */ + 0x0, 0xac, 0xbb, 0xbb, 0xbb, 0xd7, 0x0, 0x0, + 0xac, 0xaa, 0xaa, 0xaa, 0xc7, 0x0, 0x0, 0xa4, + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x8b, 0xaa, + 0xaa, 0xaa, 0xc6, 0x0, 0x25, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x50, 0x26, 0xd5, 0x5a, 0xa5, 0x55, + 0x55, 0x50, 0x1, 0xfb, 0xbd, 0x7b, 0xcc, 0xcc, + 0x60, 0x1, 0xc0, 0x7, 0x71, 0xb0, 0xb, 0x30, + 0x1, 0xfb, 0xbd, 0x70, 0x76, 0x6b, 0x0, 0x1, + 0xc0, 0x8, 0x91, 0xc, 0xd1, 0x0, 0x4b, 0xfc, + 0xcd, 0xb2, 0x7b, 0xc7, 0x0, 0x11, 0x0, 0x7, + 0x7b, 0x50, 0x7, 0xc1, + + /* U+6703 "會" */ + 0x0, 0x0, 0x0, 0x66, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x8d, 0x70, 0x0, 0x0, 0x0, 0x5, + 0xc6, 0x23, 0xdd, 0x50, 0x0, 0x28, 0xc7, 0x78, + 0x88, 0x84, 0x9d, 0x93, 0x25, 0x9a, 0xaa, 0xba, + 0xaa, 0xa9, 0x52, 0x0, 0xd1, 0x80, 0xc0, 0x57, + 0x1c, 0x0, 0x0, 0xd0, 0x91, 0xc0, 0xa1, 0x1c, + 0x0, 0x0, 0x89, 0x99, 0x99, 0x99, 0x97, 0x0, + 0x0, 0xa, 0xaa, 0xaa, 0xaa, 0xa1, 0x0, 0x0, + 0xc, 0x0, 0x0, 0x1, 0xf1, 0x0, 0x0, 0xe, + 0xaa, 0xaa, 0xab, 0xf1, 0x0, 0x0, 0xc, 0x0, + 0x0, 0x1, 0xf1, 0x0, 0x0, 0xe, 0xaa, 0xaa, + 0xab, 0xf1, 0x0, + + /* U+6708 "月" */ + 0x0, 0xf, 0xee, 0xee, 0xee, 0xf3, 0x0, 0xe, + 0x0, 0x0, 0x0, 0xc3, 0x0, 0xe, 0x0, 0x0, + 0x0, 0xc3, 0x0, 0xf, 0xdd, 0xdd, 0xdd, 0xf3, + 0x0, 0xe, 0x11, 0x11, 0x11, 0xc3, 0x0, 0x1c, + 0x0, 0x0, 0x0, 0xc3, 0x0, 0x3c, 0x0, 0x0, + 0x0, 0xc3, 0x0, 0x6f, 0xee, 0xee, 0xee, 0xf3, + 0x0, 0xb5, 0x0, 0x0, 0x0, 0xc3, 0x2, 0xe0, + 0x0, 0x0, 0x0, 0xc3, 0xc, 0x60, 0x0, 0x0, + 0x0, 0xc3, 0x59, 0x0, 0x0, 0x8, 0xfe, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6709 "有" */ + 0x0, 0x0, 0x6, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x10, 0x0, 0x0, 0x0, 0x1d, 0xdd, + 0xef, 0xdd, 0xdd, 0xdd, 0xd1, 0x0, 0x0, 0xc4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xd1, 0x11, + 0x11, 0x10, 0x0, 0x0, 0x2f, 0xec, 0xcc, 0xcc, + 0xe7, 0x0, 0x2, 0xdb, 0x80, 0x0, 0x0, 0x77, + 0x0, 0x2d, 0x46, 0xec, 0xcc, 0xcc, 0xe7, 0x0, + 0x2, 0x6, 0x80, 0x0, 0x0, 0x77, 0x0, 0x0, + 0x6, 0xeb, 0xbb, 0xbb, 0xd7, 0x0, 0x0, 0x6, + 0x91, 0x11, 0x11, 0x77, 0x0, 0x0, 0x6, 0x80, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x6, 0x80, 0x0, + 0x9d, 0xd3, 0x0, + + /* U+670B "朋" */ + 0x0, 0xfe, 0xee, 0xa0, 0xfe, 0xee, 0xe0, 0xd, + 0x0, 0x3a, 0xe, 0x0, 0xe, 0x0, 0xd0, 0x3, + 0xa0, 0xe0, 0x0, 0xe0, 0xf, 0xdd, 0xea, 0xf, + 0xdd, 0xde, 0x0, 0xd0, 0x3, 0xa0, 0xe0, 0x0, + 0xe0, 0xd, 0x0, 0x3a, 0xe, 0x0, 0xe, 0x1, + 0xfd, 0xdd, 0xa1, 0xfd, 0xdd, 0xe0, 0x2b, 0x0, + 0x4a, 0x2b, 0x0, 0xe, 0x4, 0x80, 0x3, 0xa3, + 0x90, 0x0, 0xe0, 0x76, 0x0, 0x3a, 0x76, 0x0, + 0xe, 0xc, 0x10, 0x4, 0xac, 0x10, 0x0, 0xe2, + 0xa0, 0xc, 0xc7, 0x90, 0xe, 0xe9, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+670D "服" */ + 0xa, 0xed, 0xf1, 0x1e, 0xdd, 0xde, 0xa0, 0xa, + 0x20, 0xc1, 0x1b, 0x0, 0x2, 0xb0, 0xa, 0x20, + 0xc1, 0x1b, 0x0, 0x36, 0xb0, 0xa, 0xed, 0xf1, + 0x1b, 0x0, 0x88, 0x30, 0xa, 0x20, 0xc1, 0x1d, + 0x77, 0x77, 0x70, 0xb, 0x20, 0xc1, 0x1d, 0xc6, + 0x45, 0xd0, 0xb, 0xcc, 0xf1, 0x1b, 0x69, 0x5, + 0x80, 0xc, 0x21, 0xc1, 0x1b, 0xe, 0x1c, 0x20, + 0xd, 0x0, 0xc1, 0x1b, 0x6, 0xd9, 0x0, 0xc, + 0x0, 0xc1, 0x1b, 0x3, 0xf6, 0x0, 0x58, 0x0, + 0xc1, 0x1b, 0x3c, 0x4d, 0x60, 0x73, 0x2e, 0xd0, + 0x1c, 0xa1, 0x1, 0xb4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+671B "望" */ + 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x1a, 0x71, 0x14, 0xeb, 0xbb, 0xe0, 0x15, 0xe6, + 0x55, 0x54, 0xda, 0xaa, 0xe0, 0x0, 0xd0, 0x0, + 0x4, 0x90, 0x0, 0xe0, 0x0, 0xd0, 0x3, 0x36, + 0xdb, 0xbb, 0xe0, 0x1, 0xfb, 0xea, 0x3b, 0x20, + 0x0, 0xe0, 0x2, 0x83, 0x0, 0x7b, 0x0, 0x67, + 0xe0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x57, 0x30, + 0x2, 0xcc, 0xcc, 0xee, 0xcc, 0xcc, 0x60, 0x0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x8c, + 0xcc, 0xee, 0xcc, 0xca, 0x0, 0x0, 0x0, 0x0, + 0x77, 0x0, 0x0, 0x0, 0x2c, 0xcc, 0xcc, 0xee, + 0xcc, 0xcc, 0xc5, + + /* U+671D "朝" */ + 0x0, 0x9, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x94, 0x0, 0x2f, 0xdd, 0xde, 0x3d, 0xdf, 0xed, + 0xd2, 0xc0, 0x0, 0xe0, 0x0, 0x94, 0x0, 0x2c, + 0x0, 0xe, 0xd, 0xbb, 0xbc, 0x92, 0xe9, 0x99, + 0xe0, 0xd0, 0x0, 0x39, 0x2d, 0x44, 0x4e, 0xd, + 0xbb, 0xbc, 0x92, 0xc0, 0x0, 0xe0, 0xd0, 0x0, + 0x39, 0x3c, 0x33, 0x3e, 0xa, 0xbe, 0xcb, 0x75, + 0xda, 0xaa, 0xe0, 0x0, 0x94, 0x0, 0x86, 0x0, + 0xe, 0x5d, 0xde, 0xed, 0xde, 0x20, 0x0, 0xe0, + 0x0, 0x94, 0x6, 0xb0, 0x0, 0xe, 0x0, 0x9, + 0x40, 0xc2, 0x0, 0xbe, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+671F "期" */ + 0x0, 0xc0, 0x4, 0x90, 0x0, 0x0, 0x0, 0xc, + 0x0, 0x49, 0xa, 0xed, 0xdf, 0xd, 0xfd, 0xde, + 0xe8, 0xa2, 0x0, 0xe0, 0xc, 0x0, 0x49, 0xa, + 0x20, 0xe, 0x0, 0xcb, 0xbc, 0x90, 0xae, 0xdd, + 0xf0, 0xc, 0x10, 0x59, 0xa, 0x20, 0xe, 0x0, + 0xca, 0xac, 0x90, 0xa2, 0x0, 0xe0, 0xc, 0x21, + 0x59, 0xb, 0xcb, 0xbf, 0x0, 0xc0, 0x4, 0x90, + 0xc6, 0x55, 0xf2, 0xdd, 0xdd, 0xdd, 0x8d, 0x0, + 0xe, 0x0, 0x75, 0x9, 0x1, 0xc0, 0x0, 0xe0, + 0x3d, 0x0, 0x79, 0x77, 0x0, 0xe, 0xc, 0x20, + 0x0, 0x4b, 0x10, 0x9e, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+6728 "木" */ + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0x0, 0x0, 0x0, 0xe, 0xee, 0xee, 0xff, + 0xee, 0xee, 0xe1, 0x0, 0x0, 0x5, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x1d, 0x99, 0xc1, 0x0, + 0x0, 0x0, 0x0, 0xb4, 0x77, 0x4b, 0x0, 0x0, + 0x0, 0xa, 0x80, 0x77, 0x8, 0xa0, 0x0, 0x0, + 0xba, 0x0, 0x77, 0x0, 0x9b, 0x10, 0x3d, 0x80, + 0x0, 0x77, 0x0, 0x8, 0xe3, 0x14, 0x0, 0x0, + 0x77, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x77, + 0x0, 0x0, 0x0, + + /* U+672A "未" */ + 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x22, + 0x22, 0x98, 0x22, 0x22, 0x0, 0x1, 0xbb, 0xbb, + 0xed, 0xbb, 0xbb, 0x20, 0x0, 0x0, 0x0, 0x87, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x87, 0x0, + 0x0, 0x0, 0x1e, 0xee, 0xef, 0xff, 0xfe, 0xee, + 0xe2, 0x0, 0x0, 0x8, 0xfe, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x6a, 0x87, 0xa6, 0x0, 0x0, 0x0, + 0x7, 0xb0, 0x87, 0xb, 0x70, 0x0, 0x2, 0xba, + 0x0, 0x87, 0x0, 0xbb, 0x20, 0x3e, 0x50, 0x0, + 0x87, 0x0, 0x6, 0xe3, 0x0, 0x0, 0x0, 0x87, + 0x0, 0x0, 0x0, + + /* U+672B "末" */ + 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x1, 0x11, + 0x11, 0x98, 0x11, 0x11, 0x10, 0x1c, 0xcc, 0xcc, + 0xee, 0xcc, 0xcc, 0xc2, 0x0, 0x0, 0x0, 0x87, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x87, 0x0, + 0x0, 0x0, 0x5, 0xee, 0xee, 0xff, 0xee, 0xee, + 0x60, 0x0, 0x0, 0x8, 0xee, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x6a, 0x87, 0x96, 0x0, 0x0, 0x0, + 0x7, 0xb0, 0x87, 0xb, 0x80, 0x0, 0x2, 0xba, + 0x0, 0x87, 0x0, 0xac, 0x30, 0x2e, 0x60, 0x0, + 0x87, 0x0, 0x6, 0xe3, 0x0, 0x0, 0x0, 0x87, + 0x0, 0x0, 0x0, + + /* U+672C "本" */ + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x77, 0x0, 0x0, 0x0, 0x1e, 0xee, 0xee, + 0xff, 0xee, 0xee, 0xe1, 0x0, 0x0, 0x1d, 0x99, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x96, 0x77, 0x96, + 0x0, 0x0, 0x0, 0x3, 0xd0, 0x77, 0x1d, 0x10, + 0x0, 0x0, 0xd, 0x40, 0x77, 0x5, 0xc0, 0x0, + 0x0, 0xb8, 0x0, 0x77, 0x0, 0x9b, 0x0, 0x1c, + 0x99, 0xbb, 0xdd, 0xbb, 0x99, 0xd2, 0x6, 0x2, + 0x33, 0x99, 0x33, 0x20, 0x50, 0x0, 0x0, 0x0, + 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77, + 0x0, 0x0, 0x0, + + /* U+672D "札" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x60, 0x5, 0x80, 0x0, 0x0, 0x0, 0x8, + 0x60, 0x5, 0x80, 0x0, 0x0, 0x0, 0x8, 0x60, + 0x5, 0x80, 0x0, 0x0, 0x2e, 0xef, 0xee, 0xd5, + 0x80, 0x0, 0x0, 0x0, 0xe, 0x80, 0x5, 0x80, + 0x0, 0x0, 0x0, 0x4f, 0xf4, 0x5, 0x80, 0x0, + 0x0, 0x0, 0xab, 0x8d, 0x25, 0x80, 0x0, 0x0, + 0x2, 0xb8, 0x65, 0x85, 0x80, 0x0, 0x0, 0xb, + 0x48, 0x60, 0x5, 0x80, 0x0, 0x0, 0x5b, 0x8, + 0x60, 0x5, 0x80, 0x0, 0x41, 0x32, 0x8, 0x60, + 0x5, 0x80, 0x0, 0x93, 0x0, 0x8, 0x60, 0x5, + 0x90, 0x0, 0xc1, 0x0, 0x8, 0x60, 0x1, 0xdd, + 0xdd, 0xa0, + + /* U+673A "机" */ + 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x0, 0xf, 0xee, 0xed, 0x0, 0x0, 0xe, + 0x0, 0xf, 0x0, 0x1d, 0x0, 0x3e, 0xef, 0xee, + 0x2f, 0x0, 0x1d, 0x0, 0x0, 0x3f, 0x0, 0xf, + 0x0, 0x1d, 0x0, 0x0, 0x8f, 0x30, 0xf, 0x0, + 0x1d, 0x0, 0x0, 0xce, 0xc2, 0xf, 0x0, 0x1d, + 0x0, 0x5, 0x7e, 0x3d, 0x1e, 0x0, 0x1d, 0x0, + 0xc, 0x1e, 0x4, 0x3b, 0x0, 0x1d, 0x0, 0x67, + 0xe, 0x0, 0x78, 0x0, 0x1d, 0x4, 0x10, 0xe, + 0x0, 0xc2, 0x0, 0x1d, 0xb, 0x0, 0xe, 0x6, + 0xb0, 0x0, 0x1d, 0x1a, 0x0, 0xe, 0xb, 0x10, + 0x0, 0xc, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6750 "材" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x20, 0x0, 0x0, 0xe, 0x0, 0x0, 0xc, + 0x20, 0x0, 0x0, 0xe, 0x0, 0x0, 0xc, 0x20, + 0x0, 0x0, 0xe, 0x0, 0x1e, 0xef, 0xee, 0x6e, + 0xee, 0xef, 0xe5, 0x0, 0x1f, 0x50, 0x0, 0x0, + 0xae, 0x0, 0x0, 0x7f, 0xd2, 0x0, 0x3, 0xde, + 0x0, 0x0, 0xcc, 0x5d, 0x10, 0xc, 0x3e, 0x0, + 0x5, 0x8c, 0x26, 0x30, 0x98, 0xe, 0x0, 0xd, + 0x2c, 0x20, 0x7, 0xc0, 0xe, 0x0, 0x77, 0xc, + 0x20, 0x8d, 0x10, 0xe, 0x0, 0x10, 0xc, 0x20, + 0x71, 0x0, 0xe, 0x0, 0x0, 0xc, 0x20, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0xc, 0x20, 0x0, 0x5f, + 0xe9, 0x0, + + /* U+6751 "村" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x50, 0x0, 0x0, 0xd, 0x10, 0x0, 0x8, + 0x50, 0x0, 0x0, 0xd, 0x10, 0x0, 0x8, 0x50, + 0x0, 0x0, 0xd, 0x10, 0x1d, 0xdf, 0xed, 0x8e, + 0xee, 0xef, 0xe8, 0x0, 0xe, 0x60, 0x0, 0x0, + 0xd, 0x10, 0x0, 0x4f, 0x80, 0x3, 0x10, 0xd, + 0x10, 0x0, 0xab, 0xe7, 0x6, 0xa0, 0xd, 0x10, + 0x2, 0xb8, 0x6c, 0x40, 0xc3, 0xd, 0x10, 0xa, + 0x48, 0x52, 0x10, 0x5a, 0xd, 0x10, 0x3a, 0x8, + 0x50, 0x0, 0x2, 0xd, 0x10, 0x1, 0x8, 0x50, + 0x0, 0x0, 0xd, 0x10, 0x0, 0x8, 0x50, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x8, 0x50, 0x0, 0x2f, + 0xeb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+675F "束" */ + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0xd, 0xdd, + 0xdd, 0xee, 0xdd, 0xdd, 0xd0, 0x0, 0x0, 0x0, + 0x77, 0x0, 0x0, 0x0, 0x0, 0xdd, 0xdd, 0xee, + 0xdd, 0xdd, 0x0, 0x0, 0xe0, 0x0, 0x77, 0x0, + 0xf, 0x0, 0x0, 0xe0, 0x0, 0x77, 0x0, 0xf, + 0x0, 0x0, 0xfd, 0xdd, 0xee, 0xdd, 0xdf, 0x0, + 0x0, 0x0, 0x9, 0xff, 0x80, 0x0, 0x0, 0x0, + 0x0, 0xaa, 0x87, 0x99, 0x0, 0x0, 0x0, 0x4c, + 0x80, 0x77, 0x8, 0xd4, 0x0, 0x2c, 0xc3, 0x0, + 0x77, 0x0, 0x3c, 0xc2, 0x4, 0x0, 0x0, 0x77, + 0x0, 0x0, 0x40, + + /* U+6761 "条" */ + 0x0, 0x0, 0x1d, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xce, 0xaa, 0xaa, 0x60, 0x0, 0x0, 0x1c, + 0xe4, 0x22, 0x3e, 0x40, 0x0, 0x6, 0xd5, 0x3c, + 0x22, 0xc6, 0x0, 0x0, 0x4, 0x10, 0x3, 0xff, + 0x50, 0x0, 0x0, 0x0, 0x3, 0x9d, 0x88, 0xea, + 0x40, 0x0, 0x3c, 0xeb, 0x50, 0x44, 0x5, 0xae, + 0xd3, 0x2, 0x0, 0x0, 0x77, 0x0, 0x0, 0x10, + 0x0, 0xcd, 0xdd, 0xee, 0xdd, 0xdb, 0x0, 0x0, + 0x0, 0x60, 0x77, 0x6, 0x0, 0x0, 0x0, 0xb, + 0x50, 0x77, 0x8, 0xb0, 0x0, 0x3, 0xd5, 0x0, + 0x77, 0x0, 0x7b, 0x0, 0x1, 0x30, 0x9, 0xd4, + 0x0, 0x5, 0x0, + + /* U+6765 "来" */ + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x7, 0xee, + 0xee, 0xff, 0xee, 0xee, 0x90, 0x0, 0x17, 0x0, + 0x77, 0x0, 0x64, 0x0, 0x0, 0xc, 0x30, 0x77, + 0x1, 0xe1, 0x0, 0x0, 0x4, 0x90, 0x77, 0x8, + 0x60, 0x0, 0x2b, 0xbb, 0xbb, 0xdd, 0xbb, 0xbb, + 0xb2, 0x2, 0x22, 0x2a, 0xfe, 0xa2, 0x22, 0x20, + 0x0, 0x0, 0x6b, 0x88, 0xb6, 0x0, 0x0, 0x0, + 0x6, 0xc0, 0x77, 0xc, 0x60, 0x0, 0x0, 0x9c, + 0x10, 0x77, 0x1, 0xc9, 0x0, 0x3e, 0x80, 0x0, + 0x77, 0x0, 0x9, 0xe3, 0x2, 0x0, 0x0, 0x77, + 0x0, 0x0, 0x20, + + /* U+676F "杯" */ + 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x4, 0xcc, 0xcc, 0xcc, 0xc6, 0x0, 0xe, + 0x0, 0x22, 0x28, 0xb2, 0x21, 0x2e, 0xef, 0xed, + 0x0, 0x1e, 0x30, 0x0, 0x0, 0x3f, 0x10, 0x0, + 0xae, 0x60, 0x0, 0x0, 0x8f, 0xc1, 0x5, 0xde, + 0x6c, 0x10, 0x0, 0xce, 0x59, 0x5d, 0x1e, 0x5, + 0xc0, 0x4, 0x7e, 0xa, 0xd2, 0xe, 0x0, 0x88, + 0xc, 0x1e, 0x3, 0x0, 0xe, 0x0, 0x0, 0x48, + 0xe, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe, + 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe, 0x0, + 0x0, 0xe, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, + 0xe, 0x0, 0x0, + + /* U+6771 "東" */ + 0x0, 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0x2, + 0x22, 0x22, 0x98, 0x22, 0x22, 0x20, 0xb, 0xbb, + 0xbb, 0xdd, 0xbb, 0xbb, 0xb1, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x0, 0x0, 0x0, 0xdc, 0xbb, 0xed, + 0xbb, 0xbf, 0x0, 0x0, 0xd1, 0x0, 0x86, 0x0, + 0xe, 0x0, 0x0, 0xdc, 0xbb, 0xdd, 0xbb, 0xbf, + 0x0, 0x0, 0xd1, 0x0, 0x86, 0x0, 0xe, 0x0, + 0x0, 0xbc, 0xbc, 0xff, 0xcb, 0xbd, 0x0, 0x0, + 0x0, 0x3d, 0xba, 0xc3, 0x0, 0x0, 0x0, 0x7, + 0xd2, 0x86, 0x2d, 0x60, 0x0, 0x6, 0xd9, 0x0, + 0x86, 0x1, 0x9d, 0x60, 0x19, 0x20, 0x0, 0x86, + 0x0, 0x2, 0x91, + + /* U+6790 "析" */ + 0x0, 0xe, 0x0, 0x0, 0x1, 0x7b, 0x10, 0x0, + 0xe, 0x0, 0x19, 0xdd, 0x94, 0x0, 0x0, 0xe, + 0x0, 0x4a, 0x10, 0x0, 0x0, 0x1c, 0xcf, 0xcc, + 0x48, 0x0, 0x0, 0x0, 0x2, 0x5e, 0x22, 0x48, + 0x0, 0x0, 0x0, 0x0, 0x9f, 0x50, 0x4f, 0xee, + 0xee, 0xe5, 0x0, 0xce, 0xc2, 0x48, 0x0, 0xd0, + 0x0, 0x5, 0x7e, 0x3a, 0x57, 0x0, 0xd0, 0x0, + 0xc, 0x1e, 0x0, 0x76, 0x0, 0xd0, 0x0, 0x58, + 0xe, 0x0, 0x84, 0x0, 0xd0, 0x0, 0x0, 0xe, + 0x0, 0xc1, 0x0, 0xd0, 0x0, 0x0, 0xe, 0x2, + 0xc0, 0x0, 0xd0, 0x0, 0x0, 0xe, 0x6, 0x50, + 0x0, 0xd0, 0x0, + + /* U+6797 "林" */ + 0x0, 0x8, 0x60, 0x0, 0x2, 0xc0, 0x0, 0x0, + 0x8, 0x60, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x8, + 0x60, 0x0, 0x2, 0xc0, 0x0, 0x1e, 0xef, 0xee, + 0x6c, 0xee, 0xfe, 0xe6, 0x0, 0xd, 0x90, 0x0, + 0x9, 0xf3, 0x0, 0x0, 0x4f, 0xe7, 0x0, 0x1f, + 0xf9, 0x0, 0x0, 0xab, 0x6c, 0x50, 0x7a, 0xcd, + 0x0, 0x2, 0xb8, 0x62, 0x50, 0xd3, 0xc8, 0x60, + 0xb, 0x48, 0x60, 0x9, 0x72, 0xc1, 0xd0, 0x4a, + 0x8, 0x60, 0x6d, 0x2, 0xc0, 0x89, 0x1, 0x8, + 0x60, 0x82, 0x2, 0xc0, 0x4, 0x0, 0x8, 0x60, + 0x0, 0x2, 0xc0, 0x0, 0x0, 0x8, 0x60, 0x0, + 0x2, 0xc0, 0x0, + + /* U+679C "果" */ + 0x0, 0xcd, 0xdd, 0xee, 0xdd, 0xdd, 0x0, 0x0, + 0xc3, 0x0, 0x77, 0x0, 0x2d, 0x0, 0x0, 0xcd, + 0xcc, 0xee, 0xcc, 0xdd, 0x0, 0x0, 0xc3, 0x0, + 0x77, 0x0, 0x2d, 0x0, 0x0, 0xc5, 0x22, 0x99, + 0x22, 0x4d, 0x0, 0x0, 0x8a, 0xaa, 0xdd, 0xaa, + 0xa9, 0x0, 0x1, 0x11, 0x11, 0x88, 0x11, 0x11, + 0x10, 0x1c, 0xcc, 0xce, 0xff, 0xec, 0xcc, 0xc1, + 0x0, 0x0, 0x4c, 0xa9, 0xc5, 0x0, 0x0, 0x0, + 0x18, 0xc1, 0x77, 0xa, 0x92, 0x0, 0x19, 0xd6, + 0x0, 0x77, 0x0, 0x5c, 0xa2, 0x6, 0x0, 0x0, + 0x77, 0x0, 0x0, 0x40, + + /* U+67D0 "某" */ + 0x0, 0x9, 0x50, 0x0, 0x6, 0x80, 0x0, 0x0, + 0x9, 0x60, 0x0, 0x7, 0x90, 0x0, 0x2c, 0xce, + 0xdc, 0xcc, 0xcd, 0xec, 0xc2, 0x0, 0x9, 0x50, + 0x0, 0x6, 0x80, 0x0, 0x0, 0x9, 0xdc, 0xcc, + 0xcd, 0x80, 0x0, 0x0, 0x9, 0x50, 0x0, 0x6, + 0x80, 0x0, 0x0, 0x7, 0xcc, 0xee, 0xcc, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, + 0x2d, 0xdd, 0xde, 0xff, 0xed, 0xdd, 0xd3, 0x0, + 0x0, 0x4c, 0xaa, 0xc3, 0x0, 0x0, 0x0, 0x7, + 0xc1, 0x77, 0x1c, 0x70, 0x0, 0x17, 0xd7, 0x0, + 0x77, 0x0, 0x7d, 0x81, 0x18, 0x10, 0x0, 0x77, + 0x0, 0x0, 0x71, + + /* U+67E5 "查" */ + 0x0, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x2c, 0xcc, + 0xcd, 0xff, 0xdc, 0xcc, 0xc2, 0x0, 0x0, 0x5c, + 0x98, 0xd5, 0x0, 0x0, 0x0, 0x8, 0xc0, 0x76, + 0x1c, 0x91, 0x0, 0x17, 0xe8, 0x0, 0x54, 0x0, + 0x7e, 0xa2, 0x29, 0x19, 0xbb, 0xbb, 0xbb, 0x91, + 0x81, 0x0, 0xd, 0x0, 0x0, 0x1, 0xd0, 0x0, + 0x0, 0xd, 0xba, 0xaa, 0xab, 0xd0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, 0xc, + 0xbb, 0xbb, 0xbb, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xd0, + + /* U+67F1 "柱" */ + 0x0, 0xe, 0x0, 0x0, 0x39, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x8, 0x40, 0x0, 0x1d, 0xef, 0xda, + 0xcc, 0xcf, 0xdc, 0xc2, 0x0, 0x3e, 0x0, 0x0, + 0xe, 0x10, 0x0, 0x0, 0x8f, 0x80, 0x0, 0xe, + 0x10, 0x0, 0x0, 0xbe, 0xa4, 0x0, 0xe, 0x10, + 0x0, 0x4, 0x8e, 0x18, 0x9d, 0xdf, 0xdd, 0xb0, + 0xb, 0x2e, 0x0, 0x0, 0xe, 0x10, 0x0, 0x2a, + 0xe, 0x0, 0x0, 0xe, 0x10, 0x0, 0x1, 0xe, + 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0xe, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0xe, 0x6, 0xdd, + 0xdf, 0xdd, 0xd6, + + /* U+67FB "査" */ + 0x0, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x2c, 0xcc, + 0xcd, 0xff, 0xdc, 0xcc, 0xc2, 0x0, 0x0, 0x5c, + 0x98, 0xc4, 0x0, 0x0, 0x0, 0x9, 0xb1, 0x76, + 0x1c, 0x91, 0x0, 0x18, 0xd6, 0x0, 0x54, 0x0, + 0x6d, 0xa2, 0x17, 0xb, 0xcc, 0xcc, 0xcc, 0xb0, + 0x61, 0x0, 0xd, 0x0, 0x0, 0x0, 0xe0, 0x0, + 0x0, 0xd, 0xbb, 0xbb, 0xbb, 0xe0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xd, + 0xbb, 0xbb, 0xbb, 0xe0, 0x0, 0x0, 0xd, 0x0, + 0x0, 0x0, 0xe0, 0x0, 0x3d, 0xdf, 0xdd, 0xdd, + 0xdd, 0xfd, 0xd3, + + /* U+67FF "柿" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, 0x85, + 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, 0x85, 0x9, + 0xdd, 0xdf, 0xdd, 0xd5, 0x6d, 0xfe, 0xd2, 0x11, + 0x1e, 0x11, 0x10, 0x0, 0xd7, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x1, 0xfe, 0x10, 0xfd, 0xdf, 0xdd, + 0xd0, 0x5, 0xe9, 0xa0, 0xe0, 0xe, 0x0, 0xe0, + 0xb, 0x95, 0x90, 0xe0, 0xe, 0x0, 0xe0, 0x2b, + 0x85, 0x0, 0xe0, 0xe, 0x0, 0xe0, 0x74, 0x85, + 0x0, 0xe0, 0xe, 0x0, 0xe0, 0x10, 0x85, 0x0, + 0xe0, 0xe, 0x4d, 0xa0, 0x0, 0x85, 0x0, 0x0, + 0xe, 0x0, 0x0, 0x0, 0x85, 0x0, 0x0, 0xe, + 0x0, 0x0, + + /* U+6811 "树" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x75, 0x0, 0x0, 0x0, 0x4, 0x90, 0x0, 0x75, + 0x4, 0x44, 0x20, 0x4, 0x90, 0x0, 0x75, 0x8, + 0x8b, 0x90, 0x4, 0x90, 0x1d, 0xee, 0x90, 0x7, + 0x8d, 0xde, 0xe9, 0x0, 0xb6, 0xb, 0xa, 0x40, + 0x4, 0x90, 0x0, 0xed, 0x7, 0x7d, 0x14, 0x4, + 0x90, 0x2, 0xfa, 0x60, 0xdd, 0x5, 0x84, 0x90, + 0x7, 0xc5, 0x90, 0x6c, 0x0, 0xc5, 0x90, 0xc, + 0x85, 0x0, 0xbe, 0x40, 0x57, 0x90, 0x38, 0x75, + 0x1, 0xd3, 0xd0, 0x4, 0x90, 0x1, 0x75, 0x9, + 0x60, 0x20, 0x4, 0x90, 0x0, 0x75, 0x3b, 0x0, + 0x0, 0x4, 0x90, 0x0, 0x75, 0x1, 0x0, 0x2, + 0xed, 0x50, + + /* U+6821 "校" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x39, 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x39, + 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x39, 0x5, + 0xcc, 0xcd, 0xcc, 0xc3, 0x1d, 0xef, 0xd3, 0x15, + 0x21, 0x61, 0x10, 0x0, 0x9a, 0x0, 0x2d, 0x0, + 0x6b, 0x0, 0x0, 0xdf, 0x31, 0xc4, 0x0, 0x8, + 0x90, 0x2, 0xdb, 0xb8, 0x7b, 0x0, 0x76, 0xa0, + 0x8, 0x79, 0x81, 0xb, 0x30, 0xd1, 0x0, 0xc, + 0x49, 0x0, 0x3, 0xc6, 0xa0, 0x0, 0x66, 0x39, + 0x0, 0x0, 0x9f, 0x10, 0x0, 0x0, 0x39, 0x0, + 0x3, 0xec, 0xa0, 0x0, 0x0, 0x39, 0x0, 0x7d, + 0x30, 0x9d, 0x50, 0x0, 0x39, 0x9, 0x91, 0x0, + 0x3, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+682A "株" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x2, 0xe, 0x0, 0x0, 0x0, 0xe, + 0x0, 0x1d, 0xe, 0x0, 0x0, 0x0, 0xe, 0x0, + 0x4a, 0xe, 0x0, 0x0, 0x1d, 0xef, 0xda, 0x8e, + 0xdf, 0xdd, 0xa0, 0x0, 0x4f, 0x10, 0xe1, 0xe, + 0x0, 0x0, 0x0, 0x9f, 0xa1, 0x60, 0xe, 0x0, + 0x0, 0x0, 0xae, 0x79, 0xdd, 0xdf, 0xdd, 0xd4, + 0x6, 0x5e, 0x2, 0x0, 0xbf, 0xc0, 0x0, 0x1c, + 0xe, 0x0, 0x5, 0x9e, 0x76, 0x0, 0x36, 0xe, + 0x0, 0xd, 0x1e, 0xd, 0x10, 0x0, 0xe, 0x0, + 0xb5, 0xe, 0x5, 0xb0, 0x0, 0xe, 0xa, 0x60, + 0xe, 0x0, 0x86, 0x0, 0xe, 0x1, 0x0, 0xe, + 0x0, 0x0, + + /* U+6839 "根" */ + 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0xdd, 0xdd, 0xdf, 0x30, 0x2, 0x2e, + 0x21, 0xd0, 0x0, 0xb, 0x30, 0xa, 0xaf, 0xa6, + 0xdb, 0xaa, 0xae, 0x30, 0x0, 0x4f, 0x10, 0xd2, + 0x11, 0x1b, 0x30, 0x0, 0x9f, 0xa0, 0xd0, 0x0, + 0xb, 0x30, 0x0, 0xcd, 0x94, 0xdd, 0xdd, 0xdf, + 0x30, 0x5, 0x8d, 0x13, 0xd0, 0x57, 0x0, 0x40, + 0xd, 0x2d, 0x0, 0xd0, 0xd, 0x2b, 0x70, 0x18, + 0xd, 0x0, 0xd0, 0x8, 0xd3, 0x0, 0x0, 0xd, + 0x0, 0xd0, 0x1, 0xd3, 0x0, 0x0, 0xd, 0x0, + 0xd6, 0x98, 0x2e, 0x70, 0x0, 0xd, 0x0, 0xd8, + 0x30, 0x2, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+683C "格" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe0, 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x5, 0xf7, 0x66, 0x40, 0x0, 0x0, + 0xe0, 0x1, 0xe8, 0x66, 0xc7, 0x0, 0x1d, 0xdf, + 0xdc, 0xcb, 0xa0, 0x3e, 0x0, 0x0, 0x3, 0xf0, + 0x68, 0xa, 0x7d, 0x50, 0x0, 0x0, 0x8f, 0x90, + 0x0, 0x2f, 0xb0, 0x0, 0x0, 0xb, 0xe9, 0x50, + 0x3d, 0x7b, 0xa1, 0x0, 0x3, 0x9e, 0x19, 0xbc, + 0x20, 0x6, 0xe9, 0x0, 0xa3, 0xe0, 0x89, 0xec, + 0xcc, 0xdc, 0x30, 0x3a, 0xe, 0x0, 0x49, 0x0, + 0x2, 0xb0, 0x0, 0x20, 0xe0, 0x4, 0x90, 0x0, + 0x2b, 0x0, 0x0, 0xe, 0x0, 0x4a, 0x22, 0x24, + 0xb0, 0x0, 0x0, 0xe0, 0x4, 0xda, 0xaa, 0xbb, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+6843 "桃" */ + 0x0, 0x58, 0x0, 0x2, 0xb0, 0xe0, 0x0, 0x0, + 0x58, 0x0, 0x2, 0xb0, 0xe0, 0x0, 0x0, 0x58, + 0x3, 0x32, 0xb0, 0xe0, 0x62, 0x3d, 0xef, 0xc2, + 0xc2, 0xb0, 0xe0, 0xd0, 0x0, 0x9a, 0x0, 0xa6, + 0xb0, 0xe7, 0x60, 0x0, 0xef, 0x50, 0x35, 0xb0, + 0xe5, 0x0, 0x2, 0xf9, 0xc1, 0x2, 0xa0, 0xe1, + 0x0, 0x8, 0xa8, 0x30, 0x1c, 0xa0, 0xec, 0x30, + 0xd, 0x68, 0x6, 0xd8, 0x70, 0xe1, 0xc2, 0x47, + 0x58, 0x8, 0x19, 0x30, 0xe0, 0x24, 0x0, 0x58, + 0x0, 0x1b, 0x0, 0xe0, 0x14, 0x0, 0x58, 0x1, + 0xb3, 0x0, 0xe0, 0x3a, 0x0, 0x58, 0x1b, 0x20, + 0x0, 0xbd, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6848 "案" */ + 0x0, 0x0, 0x0, 0x75, 0x0, 0x0, 0x0, 0x8, + 0xcc, 0xcc, 0xdf, 0xcc, 0xcc, 0xc1, 0xa, 0x30, + 0x2, 0x80, 0x0, 0x0, 0xc1, 0x3, 0x21, 0x1a, + 0x61, 0x11, 0x11, 0x40, 0xa, 0xaa, 0xec, 0xaa, + 0xae, 0xda, 0xa3, 0x0, 0x7, 0xc2, 0x0, 0x6c, + 0x0, 0x0, 0x0, 0x3, 0x6c, 0xfe, 0xf7, 0x30, + 0x0, 0x9, 0xcb, 0xb7, 0x64, 0x15, 0xae, 0x80, + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x1d, + 0xdd, 0xdd, 0xff, 0xed, 0xdd, 0xd5, 0x0, 0x0, + 0x5b, 0x8a, 0xb9, 0x10, 0x0, 0x2, 0x7c, 0x80, + 0x59, 0x5, 0xc9, 0x40, 0x1a, 0x50, 0x0, 0x59, + 0x0, 0x3, 0x96, + + /* U+689D "條" */ + 0x0, 0x9, 0x0, 0x0, 0x92, 0x0, 0x0, 0x0, + 0x5a, 0x0, 0x6, 0xf8, 0x88, 0x30, 0x0, 0xa4, + 0xc0, 0x5f, 0x63, 0x4e, 0x10, 0x2, 0xf0, 0xd3, + 0xc4, 0xc1, 0xc6, 0x0, 0xb, 0xf0, 0xd0, 0x0, + 0x6f, 0x80, 0x0, 0x5d, 0xe0, 0xd0, 0x28, 0xc6, + 0xd8, 0x20, 0x43, 0xe0, 0xd6, 0xb5, 0xb, 0x6, + 0xb3, 0x0, 0xe0, 0xd0, 0x33, 0x3e, 0x33, 0x30, + 0x0, 0xe0, 0xd2, 0x99, 0x9f, 0x99, 0x90, 0x0, + 0xe0, 0xd0, 0x37, 0xe, 0x9, 0x0, 0x0, 0xe0, + 0x80, 0xd2, 0xe, 0x7, 0x80, 0x0, 0xe0, 0xb, + 0x50, 0xe, 0x0, 0xb1, 0x0, 0xe0, 0x1, 0x6, + 0xd8, 0x0, 0x0, + + /* U+68B0 "械" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x66, 0x0, 0x0, 0x5, 0x86, 0x0, 0x0, 0x66, + 0x0, 0x0, 0x5, 0x94, 0xb0, 0x0, 0x66, 0x0, + 0x0, 0x5, 0x90, 0x40, 0xa, 0xdd, 0x7b, 0xee, + 0xef, 0xfe, 0xe7, 0x4, 0xa9, 0x30, 0x20, 0x32, + 0xb0, 0x0, 0x0, 0xcd, 0x0, 0xc0, 0xc1, 0xc0, + 0x63, 0x1, 0xfb, 0x80, 0xc0, 0xc0, 0xd0, 0xd1, + 0x5, 0xc7, 0x4a, 0xfc, 0xf7, 0xd3, 0xc0, 0xc, + 0x76, 0x1, 0xb0, 0xc0, 0xbb, 0x50, 0x49, 0x66, + 0x3, 0x80, 0xc0, 0x8d, 0x0, 0x22, 0x66, 0x7, + 0x50, 0xc0, 0xba, 0x5, 0x0, 0x66, 0x1c, 0x0, + 0xba, 0x7d, 0x39, 0x0, 0x66, 0x12, 0x0, 0x84, + 0x5, 0xe4, + + /* U+68EE "森" */ + 0x0, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5, 0xa0, 0x0, 0x0, 0x0, 0x4, + 0xdd, 0xde, 0xff, 0xfd, 0xdd, 0xc0, 0x0, 0x0, + 0x3, 0xc9, 0xba, 0x80, 0x0, 0x0, 0x0, 0x29, + 0xb1, 0x5a, 0x6, 0xc6, 0x10, 0x0, 0x7b, 0x51, + 0x5, 0xa0, 0x2, 0x6c, 0x30, 0x0, 0x7, 0x60, + 0x1, 0x3, 0xb0, 0x0, 0x0, 0x22, 0x97, 0x21, + 0x12, 0x5b, 0x22, 0x10, 0xa, 0xbf, 0xca, 0x58, + 0xbf, 0xfc, 0xa7, 0x0, 0x7, 0xed, 0x30, 0x6, + 0xcc, 0xb0, 0x0, 0x5, 0xb8, 0x7b, 0x34, 0xc3, + 0xb5, 0xa0, 0x3, 0xc1, 0x76, 0x8, 0xb1, 0x3b, + 0x7, 0xb0, 0x0, 0x7, 0x60, 0x20, 0x3, 0xb0, + 0x2, 0x0, + + /* U+690D "植" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x76, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x76, + 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x76, 0x9, + 0xcd, 0xfc, 0xcc, 0xa0, 0x3d, 0xee, 0xc0, 0x2, + 0xb0, 0x0, 0x0, 0x0, 0xa7, 0x2, 0xeb, 0xbb, + 0xbf, 0x0, 0x0, 0xfe, 0x12, 0xb0, 0x0, 0xe, + 0x0, 0x4, 0xea, 0xa2, 0xeb, 0xbb, 0xbf, 0x0, + 0xa, 0x96, 0x62, 0xb0, 0x0, 0xe, 0x0, 0x1c, + 0x76, 0x2, 0xea, 0xaa, 0xaf, 0x0, 0x75, 0x76, + 0x2, 0xb0, 0x0, 0xe, 0x0, 0x0, 0x76, 0x2, + 0xeb, 0xbb, 0xbf, 0x0, 0x0, 0x76, 0x2, 0xb0, + 0x0, 0xe, 0x0, 0x0, 0x76, 0x5d, 0xfc, 0xcc, + 0xcf, 0xc3, + + /* U+691C "検" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3a, 0x0, 0x0, 0xae, 0x20, 0x0, 0x0, 0x3a, + 0x0, 0x7, 0xb4, 0xd1, 0x0, 0x0, 0x3a, 0x0, + 0x9b, 0x0, 0x4d, 0x50, 0x3d, 0xef, 0xde, 0xda, + 0x99, 0x9b, 0xc6, 0x0, 0x8a, 0x1, 0x12, 0x6a, + 0x22, 0x0, 0x0, 0xdc, 0x0, 0x0, 0x49, 0x0, + 0x0, 0x2, 0xff, 0x85, 0xdb, 0xce, 0xbc, 0xc0, + 0x8, 0x9a, 0xb7, 0x70, 0x49, 0x1, 0xc0, 0x1d, + 0x4a, 0x5, 0xda, 0xcd, 0xaa, 0xc0, 0x66, 0x3a, + 0x0, 0x11, 0xae, 0x41, 0x10, 0x0, 0x3a, 0x0, + 0x4, 0xd3, 0xc0, 0x0, 0x0, 0x3a, 0x0, 0x7d, + 0x20, 0x6c, 0x40, 0x0, 0x3a, 0x1d, 0x80, 0x0, + 0x3, 0xc5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+695A "楚" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x60, 0x0, 0xb, 0x20, 0x0, 0x9, 0xad, + 0xca, 0x4a, 0xae, 0xba, 0x90, 0x2, 0x5f, 0xd4, + 0x12, 0x8f, 0xc3, 0x20, 0x2, 0xc9, 0x8c, 0x23, + 0xac, 0x6b, 0x20, 0x2d, 0x28, 0x61, 0x4c, 0x1b, + 0x22, 0xc0, 0x0, 0x5, 0x40, 0x0, 0x7, 0x10, + 0x0, 0xb, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xb0, + 0x0, 0x3, 0x10, 0x95, 0x0, 0x8, 0x80, 0x0, + 0xe, 0x10, 0x85, 0x0, 0x8, 0x10, 0x0, 0x3f, + 0x10, 0x8e, 0xdd, 0xd6, 0x0, 0x0, 0x8d, 0x90, + 0x85, 0x0, 0x0, 0x0, 0x4, 0xe1, 0xbb, 0xa5, + 0x0, 0x0, 0x0, 0x2d, 0x30, 0x6, 0xbe, 0xee, + 0xee, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+696D "業" */ + 0x0, 0x81, 0xc, 0x11, 0xc0, 0x9, 0x0, 0x0, + 0x5a, 0xc, 0x11, 0xc0, 0x79, 0x0, 0x0, 0xc, + 0xc, 0x11, 0xc0, 0xc1, 0x0, 0xc, 0xcc, 0xfc, + 0xcc, 0xcf, 0xdc, 0xc0, 0x0, 0x0, 0xb4, 0x0, + 0x3b, 0x0, 0x0, 0x6, 0xcc, 0xde, 0xcc, 0xed, + 0xcc, 0x70, 0x0, 0x0, 0x0, 0x76, 0x0, 0x0, + 0x0, 0x0, 0x8b, 0xbb, 0xdd, 0xbb, 0xba, 0x0, + 0x0, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x1c, + 0xcc, 0xce, 0xff, 0xec, 0xcc, 0xc1, 0x0, 0x1, + 0x9b, 0x98, 0xb8, 0x0, 0x0, 0x4, 0xad, 0x50, + 0x76, 0x6, 0xd9, 0x40, 0x29, 0x40, 0x0, 0x76, + 0x0, 0x4, 0xa2, + + /* U+6975 "極" */ + 0x0, 0x75, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x75, 0xc, 0xdd, 0xdd, 0xdf, 0x90, 0x0, 0x75, + 0x0, 0x0, 0x2, 0xb8, 0x0, 0x1e, 0xfe, 0x80, + 0x0, 0x6b, 0x20, 0x0, 0x0, 0xb5, 0xd, 0xb9, + 0x85, 0xbb, 0xe2, 0x0, 0xfd, 0xb, 0xa, 0x85, + 0x30, 0xc0, 0x3, 0xf9, 0x8b, 0xa, 0x85, 0xa7, + 0xa0, 0x8, 0xa5, 0x2b, 0xa, 0x84, 0xd, 0x50, + 0x1c, 0x75, 0xe, 0xba, 0x84, 0x2d, 0xa0, 0x46, + 0x75, 0xb, 0x0, 0x86, 0xc2, 0xa2, 0x0, 0x75, + 0x0, 0xa, 0xb4, 0x30, 0x10, 0x0, 0x75, 0x7a, + 0xaa, 0xaa, 0xaa, 0xa7, 0x0, 0x75, 0x22, 0x22, + 0x22, 0x22, 0x22, + + /* U+697D "楽" */ + 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, 0x0, 0x6, + 0x10, 0x1, 0xa6, 0x10, 0x3, 0x80, 0x3, 0xd3, + 0x8c, 0xaa, 0xc9, 0x3c, 0x20, 0x0, 0x29, 0x84, + 0x0, 0x4a, 0x91, 0x0, 0x0, 0x2, 0x9d, 0xbb, + 0xda, 0x50, 0x0, 0x1, 0xab, 0x94, 0x0, 0x4a, + 0x9c, 0x30, 0x3d, 0x50, 0x8d, 0xcc, 0xd9, 0x3, + 0xd2, 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, + 0x2d, 0xdd, 0xdd, 0xee, 0xdd, 0xdd, 0xd3, 0x0, + 0x0, 0x3c, 0xbb, 0xc2, 0x0, 0x0, 0x0, 0x6, + 0xd2, 0x77, 0x2d, 0x60, 0x0, 0x7, 0xd9, 0x10, + 0x77, 0x1, 0x9d, 0x81, 0x29, 0x20, 0x0, 0x77, + 0x0, 0x1, 0x71, + + /* U+6982 "概" */ + 0x0, 0x84, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x84, 0x1e, 0xce, 0x3d, 0xdf, 0xd4, 0x0, 0x84, + 0x19, 0xb, 0x1, 0xc, 0x0, 0xc, 0xed, 0x8d, + 0x9e, 0xb, 0x1c, 0x0, 0x0, 0xb5, 0x1a, 0x1b, + 0xc, 0xc, 0x0, 0x0, 0xfc, 0x19, 0xb, 0x2b, + 0x1b, 0x0, 0x3, 0xfc, 0x7e, 0xce, 0x6d, 0xee, + 0xc6, 0x7, 0xd6, 0x79, 0x0, 0x0, 0x98, 0x0, + 0xc, 0x94, 0x19, 0x29, 0x0, 0xec, 0x0, 0x49, + 0x84, 0x19, 0x3e, 0x16, 0x8c, 0x0, 0x1, 0x84, + 0x3e, 0xa6, 0x5d, 0x1c, 0x5, 0x0, 0x84, 0x65, + 0x0, 0xa4, 0xc, 0x8, 0x0, 0x84, 0x0, 0x6, + 0x60, 0xc, 0xc5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+69CB "構" */ + 0x0, 0xc, 0x0, 0xd, 0x0, 0x2c, 0x0, 0x0, + 0xc, 0x3, 0xbf, 0xbb, 0xce, 0xb6, 0x0, 0xc, + 0x0, 0x1d, 0x21, 0x3c, 0x10, 0x1e, 0xef, 0xe7, + 0x9e, 0xa9, 0xae, 0x93, 0x0, 0x5c, 0x3, 0x5e, + 0x65, 0x7d, 0x54, 0x0, 0x9f, 0x23, 0x55, 0x6f, + 0x55, 0x54, 0x0, 0xce, 0xb0, 0xab, 0xbf, 0xbb, + 0xb0, 0x4, 0x8c, 0x75, 0xc0, 0x1e, 0x0, 0xc0, + 0xb, 0x2c, 0x0, 0xeb, 0xbf, 0xbb, 0xf0, 0x39, + 0xc, 0x0, 0xc0, 0x1e, 0x0, 0xc0, 0x1, 0xc, + 0xa, 0xfb, 0xcc, 0xbb, 0xfc, 0x0, 0xc, 0x0, + 0xc0, 0x0, 0x0, 0xc0, 0x0, 0xc, 0x0, 0xc0, + 0x0, 0x6b, 0xc0, + + /* U+69D8 "様" */ + 0x0, 0xc, 0x0, 0xa, 0x0, 0xc, 0x10, 0x0, + 0xc, 0x0, 0xb, 0x30, 0x3b, 0x0, 0x0, 0xc, + 0x3, 0xcd, 0xce, 0xcd, 0xc4, 0xa, 0xae, 0xa4, + 0x0, 0xe, 0x0, 0x0, 0x4, 0x8d, 0x42, 0xac, + 0xcf, 0xcc, 0xc0, 0x0, 0x8e, 0x10, 0x0, 0xe, + 0x0, 0x0, 0x0, 0xce, 0xa7, 0xcc, 0xcf, 0xcc, + 0xc6, 0x3, 0x9c, 0x85, 0x60, 0xf, 0x10, 0x61, + 0xb, 0x3c, 0x11, 0x79, 0xf, 0x87, 0x90, 0x39, + 0xc, 0x0, 0x6, 0x2e, 0xb9, 0x0, 0x1, 0xc, + 0x0, 0x5c, 0x5e, 0x1d, 0x20, 0x0, 0xc, 0xc, + 0x91, 0xe, 0x2, 0xd6, 0x0, 0xc, 0x0, 0x7, + 0xda, 0x0, 0x2, + + /* U+6A02 "樂" */ + 0x0, 0x82, 0x0, 0xa2, 0x0, 0x64, 0x0, 0x0, + 0xb0, 0x19, 0xe9, 0x60, 0xc0, 0x0, 0x6, 0x57, + 0x5d, 0x25, 0xa4, 0x82, 0xa0, 0x1e, 0xab, 0xd, + 0x3, 0xad, 0x9c, 0x20, 0x4, 0xa3, 0xf, 0xbc, + 0xa7, 0x88, 0x0, 0x5, 0x65, 0x5d, 0x3, 0xa1, + 0xa2, 0x70, 0x1e, 0xa9, 0x9d, 0xbc, 0x9c, 0xca, + 0xc0, 0x0, 0x0, 0x10, 0x83, 0x1, 0x0, 0x20, + 0x5c, 0xcc, 0xcd, 0xfe, 0xcc, 0xcc, 0xc1, 0x0, + 0x0, 0x3c, 0xdb, 0xa1, 0x0, 0x0, 0x0, 0x19, + 0xb1, 0xa4, 0x3c, 0x71, 0x0, 0x3b, 0xc5, 0x0, + 0xa4, 0x0, 0x6d, 0xa1, 0x14, 0x0, 0x0, 0xa4, + 0x0, 0x0, 0x50, + + /* U+6A19 "標" */ + 0x0, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x67, 0xa, 0xcd, 0xed, 0xec, 0xc3, 0x0, 0x67, + 0x2, 0x69, 0xb7, 0xc6, 0x50, 0x6e, 0xff, 0xe7, + 0x86, 0x95, 0xb3, 0xd0, 0x0, 0xa7, 0x5, 0x63, + 0x71, 0x90, 0xd0, 0x0, 0xfb, 0x5, 0xed, 0xed, + 0xec, 0xe0, 0x4, 0xee, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x98, 0xc0, 0xbb, 0xbb, 0xbb, 0x60, + 0x1c, 0x67, 0x20, 0x0, 0x0, 0x0, 0x0, 0x85, + 0x67, 0xb, 0xcc, 0xde, 0xcc, 0xc3, 0x20, 0x67, + 0x0, 0xa3, 0x49, 0x1a, 0x10, 0x0, 0x67, 0x1b, + 0x70, 0x49, 0x4, 0xc1, 0x0, 0x67, 0x13, 0x9, + 0xd6, 0x0, 0x30, + + /* U+6A21 "模" */ + 0x0, 0x76, 0x0, 0xe, 0x0, 0xe0, 0x0, 0x0, + 0x76, 0xa, 0xaf, 0xaa, 0xfa, 0xa0, 0x0, 0x76, + 0x3, 0x3e, 0x33, 0xe3, 0x30, 0x3d, 0xee, 0xc2, + 0x79, 0x77, 0x97, 0x20, 0x0, 0xa8, 0x5, 0xa5, + 0x55, 0x5b, 0x40, 0x0, 0xee, 0x25, 0xdb, 0xbb, + 0xbe, 0x40, 0x3, 0xf9, 0xa5, 0x70, 0x0, 0x9, + 0x40, 0x9, 0xa6, 0x75, 0xcb, 0xbb, 0xbd, 0x40, + 0x1c, 0x76, 0x0, 0x0, 0xa3, 0x0, 0x0, 0x55, + 0x76, 0x3c, 0xcd, 0xfd, 0xcc, 0xc0, 0x0, 0x76, + 0x0, 0x7, 0x9a, 0x40, 0x0, 0x0, 0x76, 0x0, + 0x8c, 0x10, 0xc7, 0x10, 0x0, 0x76, 0x5c, 0x70, + 0x0, 0x6, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6A23 "樣" */ + 0x0, 0xc, 0x0, 0xb, 0x0, 0xb, 0x0, 0x0, + 0xc, 0x1, 0x5b, 0x85, 0x9a, 0x51, 0x0, 0xc, + 0x1, 0x55, 0x5f, 0x55, 0x52, 0x1e, 0xef, 0xe6, + 0x7a, 0xaf, 0xaa, 0x90, 0x0, 0x5c, 0x0, 0x0, + 0xe, 0x0, 0x0, 0x0, 0xaf, 0x27, 0xcc, 0xcf, + 0xcc, 0xc6, 0x0, 0xde, 0xb0, 0x0, 0xaa, 0x40, + 0x0, 0x4, 0x8c, 0x75, 0x47, 0x78, 0x83, 0x0, + 0xb, 0x3c, 0x0, 0x23, 0x3f, 0x12, 0xc0, 0x39, + 0xc, 0x7, 0xad, 0x3f, 0xbb, 0x20, 0x1, 0xc, + 0x0, 0x2b, 0xe, 0x78, 0x0, 0x0, 0xc, 0x5, + 0xc2, 0xe, 0x7, 0xb3, 0x0, 0xc, 0x6, 0x5, + 0xcb, 0x0, 0x23, + + /* U+6A2A "横" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0x0, 0xc, 0x10, 0x1c, 0x0, 0x0, 0x1c, + 0x3, 0xae, 0xaa, 0xae, 0xa5, 0x0, 0x1c, 0x0, + 0x2d, 0x32, 0x3d, 0x21, 0xb, 0xbf, 0xb5, 0xc, + 0x10, 0x1c, 0x0, 0x4, 0x8d, 0x4a, 0xcc, 0xdf, + 0xcc, 0xca, 0x0, 0x8e, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0x0, 0xdf, 0x81, 0xea, 0xbf, 0xaa, 0xd4, + 0x3, 0x9c, 0xa5, 0xa0, 0x1f, 0x0, 0x94, 0xa, + 0x4c, 0x23, 0xea, 0xbf, 0xaa, 0xd4, 0x3a, 0x1c, + 0x1, 0xa0, 0x2f, 0x0, 0x94, 0x12, 0x1c, 0x1, + 0xaa, 0xaa, 0xaa, 0xa3, 0x0, 0x1c, 0x0, 0x4d, + 0x20, 0x1b, 0x50, 0x0, 0x1c, 0x9, 0x91, 0x0, + 0x0, 0x89, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+6A39 "樹" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x57, 0x0, 0xd, 0x0, 0x0, 0xd0, 0x0, 0x57, + 0x1, 0x1d, 0x11, 0x0, 0xd0, 0x0, 0x57, 0x3b, + 0xbf, 0xba, 0x0, 0xd0, 0x9, 0xbc, 0x71, 0x1d, + 0x11, 0x66, 0xe5, 0x3, 0xa9, 0x28, 0x88, 0x85, + 0x55, 0xe4, 0x0, 0xcb, 0x9, 0xbb, 0xb5, 0x40, + 0xd0, 0x1, 0xfd, 0x4c, 0x10, 0x57, 0xc0, 0xd0, + 0x5, 0xa8, 0xac, 0x10, 0x57, 0x84, 0xd0, 0xb, + 0x67, 0x28, 0xbb, 0xb5, 0x57, 0xd0, 0x38, 0x57, + 0x5, 0x60, 0xa2, 0x12, 0xd0, 0x1, 0x57, 0x2, + 0xd1, 0xd0, 0x0, 0xd0, 0x0, 0x57, 0x13, 0x99, + 0xdb, 0x10, 0xe0, 0x0, 0x57, 0x49, 0x64, 0x10, + 0x6d, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+6A4B "橋" */ + 0x0, 0x58, 0x0, 0x1, 0x23, 0x58, 0x10, 0x0, + 0x58, 0x4, 0xa9, 0xf8, 0x53, 0x0, 0x0, 0x58, + 0x5, 0x67, 0xe6, 0x66, 0x61, 0x3b, 0xdd, 0xb5, + 0x5e, 0x75, 0xd7, 0x51, 0x3, 0xaa, 0x30, 0x9f, + 0xaa, 0xcd, 0x20, 0x0, 0xda, 0xc, 0x8c, 0x0, + 0x69, 0xd4, 0x2, 0xfe, 0x51, 0xd, 0xaa, 0xb5, + 0x0, 0x7, 0x98, 0xc4, 0x66, 0x66, 0x66, 0x60, + 0xc, 0x58, 0x28, 0x84, 0x44, 0x44, 0xe0, 0x66, + 0x58, 0x8, 0x48, 0xaa, 0xd0, 0xd0, 0x10, 0x58, + 0x8, 0x49, 0x20, 0xb0, 0xd0, 0x0, 0x58, 0x8, + 0x49, 0xba, 0xa0, 0xd0, 0x0, 0x58, 0x8, 0x43, + 0x0, 0x5c, 0xc0, + + /* U+6A5F "機" */ + 0x0, 0xc0, 0x2, 0x31, 0xa0, 0x33, 0x0, 0x0, + 0xc0, 0x9, 0x20, 0xc0, 0x91, 0x0, 0x0, 0xc0, + 0x18, 0x44, 0xd3, 0x87, 0x50, 0x6e, 0xfd, 0xbb, + 0xb0, 0xd8, 0xbc, 0x0, 0x2, 0xe0, 0x17, 0x63, + 0xc0, 0x94, 0x60, 0x6, 0xf5, 0x5b, 0xaa, 0xb8, + 0xd9, 0xb0, 0xa, 0xcb, 0x39, 0x15, 0x94, 0x77, + 0x20, 0x19, 0xc2, 0x8e, 0xbb, 0xdc, 0xbe, 0xa0, + 0x74, 0xc0, 0xe, 0x20, 0x4a, 0x19, 0x10, 0x50, + 0xc0, 0x1e, 0xc3, 0xd, 0x69, 0x0, 0x0, 0xc0, + 0x58, 0x1b, 0xa, 0xc0, 0x20, 0x0, 0xc1, 0xc1, + 0x2, 0xaa, 0xd3, 0x93, 0x0, 0xc6, 0x40, 0x1b, + 0x30, 0x3c, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B21 "次" */ + 0x0, 0x0, 0x0, 0x52, 0x0, 0x0, 0x0, 0x5, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x8, 0xd3, + 0x2, 0xe1, 0x11, 0x11, 0x0, 0x0, 0x3c, 0x7, + 0xed, 0xdd, 0xdd, 0xd0, 0x0, 0x0, 0xe, 0x30, + 0x70, 0x6, 0x80, 0x0, 0x0, 0x7c, 0x0, 0xf0, + 0xc, 0x30, 0x0, 0x0, 0x73, 0x0, 0xf0, 0x1a, + 0x0, 0x0, 0xb, 0x10, 0x3, 0xf4, 0x0, 0x0, + 0x0, 0x7b, 0x0, 0x8, 0xda, 0x0, 0x0, 0x2, + 0xe1, 0x0, 0x1e, 0x2d, 0x20, 0x0, 0xd, 0x60, + 0x0, 0xb8, 0x5, 0xc0, 0x0, 0x19, 0x0, 0x1b, + 0xa0, 0x0, 0x9c, 0x20, 0x0, 0x4, 0xe7, 0x0, + 0x0, 0x7, 0xe2, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x10, + + /* U+6B32 "欲" */ + 0x0, 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, 0x0, + 0x78, 0xc, 0x30, 0x95, 0x0, 0x0, 0x2, 0xd0, + 0x1, 0xd2, 0xc4, 0x11, 0x10, 0x1d, 0x32, 0x80, + 0x35, 0xec, 0xcc, 0xe8, 0x1, 0xb, 0xd5, 0x8, + 0x71, 0xb0, 0x94, 0x0, 0x59, 0xc, 0x5c, 0x3, + 0xa0, 0xc0, 0x6, 0xb0, 0x0, 0xc4, 0x4, 0xa0, + 0x10, 0x2c, 0xed, 0xdd, 0xb2, 0x7, 0xe0, 0x0, + 0x0, 0xe0, 0x2, 0xb0, 0xa, 0xc2, 0x0, 0x0, + 0xd0, 0x1, 0xb0, 0xb, 0x48, 0x0, 0x0, 0xd0, + 0x1, 0xb0, 0x77, 0xd, 0x10, 0x0, 0xfd, 0xdd, + 0xb3, 0xd1, 0x5, 0xc0, 0x0, 0xd0, 0x0, 0xb, + 0x20, 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B4C "歌" */ + 0x0, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x3d, + 0xdd, 0xde, 0xe8, 0x69, 0x0, 0x0, 0x0, 0x11, + 0x14, 0x90, 0x99, 0x33, 0x30, 0x7, 0xb9, 0xb4, + 0x90, 0xda, 0x99, 0xd4, 0x7, 0x30, 0xb4, 0x95, + 0xc1, 0x60, 0xc1, 0x5, 0xaa, 0x84, 0x9c, 0x42, + 0xb0, 0xc0, 0x25, 0x55, 0x58, 0xb6, 0x3, 0xb0, + 0x30, 0x26, 0x66, 0x68, 0xc6, 0x5, 0xe0, 0x0, + 0x7, 0xbb, 0x82, 0xa0, 0x8, 0xe3, 0x0, 0xa, + 0x20, 0xc2, 0xa0, 0xd, 0x49, 0x0, 0xa, 0xba, + 0xc2, 0xa0, 0x69, 0xc, 0x20, 0x9, 0x30, 0x2, + 0xa3, 0xe1, 0x3, 0xc0, 0x0, 0x0, 0x7b, 0x8c, + 0x30, 0x0, 0x58, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B50 "歐" */ + 0x0, 0x0, 0x0, 0x3, 0x80, 0x0, 0xe, 0xcc, + 0xcc, 0xc5, 0x89, 0x0, 0x0, 0xd0, 0x0, 0x0, + 0xb, 0x82, 0x22, 0xd, 0xe, 0xab, 0x61, 0xfb, + 0xbb, 0xf2, 0xd0, 0xb0, 0x36, 0x7c, 0x1, 0xd, + 0xd, 0xe, 0xab, 0x6d, 0x43, 0xa3, 0x70, 0xd0, + 0x0, 0x0, 0x10, 0x5a, 0x0, 0xd, 0x8a, 0x7c, + 0xd0, 0x7, 0xe0, 0x0, 0xd8, 0x17, 0x88, 0x0, + 0x9f, 0x30, 0xd, 0x85, 0x7a, 0xa0, 0xd, 0x59, + 0x0, 0xd3, 0x52, 0x55, 0x5, 0x90, 0xd2, 0xe, + 0xaa, 0xaa, 0xa9, 0xe2, 0x4, 0xc1, 0x11, 0x11, + 0x12, 0xa3, 0x0, 0x5, 0x30, + + /* U+6B61 "歡" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x93, 0xa, 0x30, 0xd, 0x0, 0x0, 0x3b, 0xec, + 0xbe, 0xca, 0x1c, 0x0, 0x0, 0x0, 0x41, 0x4, + 0x10, 0x5e, 0xbb, 0xb5, 0xb, 0x9c, 0x5b, 0xb5, + 0x99, 0x66, 0xb5, 0xa, 0xa, 0x55, 0x46, 0xc0, + 0x80, 0xa1, 0x7, 0xb8, 0x48, 0x89, 0x70, 0xc0, + 0xb0, 0x0, 0xd4, 0xb6, 0x42, 0x0, 0xd0, 0x20, + 0x9, 0xc6, 0xb9, 0x63, 0x1, 0xf1, 0x0, 0x4c, + 0xda, 0xdc, 0xa2, 0x4, 0xf4, 0x0, 0x3, 0xa2, + 0x97, 0x21, 0xa, 0x6a, 0x0, 0x3, 0xc6, 0xb9, + 0x62, 0x2d, 0xb, 0x20, 0x3, 0xd9, 0xcb, 0x95, + 0xd5, 0x3, 0xc0, 0x3, 0x91, 0x11, 0x15, 0x90, + 0x0, 0x64, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+6B62 "止" */ + 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x66, 0x0, + 0xe, 0x0, 0x0, 0x0, 0x0, 0x77, 0x0, 0xe, + 0x0, 0x0, 0x0, 0x0, 0x77, 0x0, 0xf, 0xee, + 0xee, 0xa0, 0x0, 0x77, 0x0, 0xe, 0x0, 0x0, + 0x0, 0x0, 0x77, 0x0, 0xe, 0x0, 0x0, 0x0, + 0x0, 0x77, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, + 0x77, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x77, + 0x0, 0xe, 0x0, 0x0, 0x0, 0x5b, 0xdd, 0xbb, + 0xcf, 0xbb, 0xbb, 0xb0, 0x12, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x20, + + /* U+6B63 "正" */ + 0x8, 0xee, 0xee, 0xee, 0xee, 0xee, 0xd0, 0x0, + 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, + 0xe, 0x0, 0x0, 0x0, 0x0, 0x2c, 0x0, 0xe, + 0x0, 0x0, 0x0, 0x0, 0x2c, 0x0, 0xf, 0xee, + 0xee, 0x40, 0x0, 0x2c, 0x0, 0xe, 0x0, 0x0, + 0x0, 0x0, 0x2c, 0x0, 0xe, 0x0, 0x0, 0x0, + 0x0, 0x2c, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, + 0x2c, 0x0, 0xe, 0x0, 0x0, 0x0, 0xa, 0xbe, + 0xaa, 0xbf, 0xaa, 0xaa, 0xa5, 0x3, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x31, + + /* U+6B64 "此" */ + 0x0, 0x0, 0x3b, 0x0, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0x3b, 0x0, 0xe1, 0x0, 0x0, 0x0, 0x0, + 0x3b, 0x0, 0xe1, 0x0, 0x0, 0x0, 0xc0, 0x3b, + 0x0, 0xe1, 0x0, 0x50, 0x0, 0xe0, 0x3c, 0x22, + 0xe1, 0x3d, 0xb0, 0x0, 0xe0, 0x3e, 0xb9, 0xea, + 0xd5, 0x0, 0x0, 0xe0, 0x3b, 0x0, 0xe7, 0x0, + 0x0, 0x0, 0xe0, 0x3b, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0xe0, 0x3b, 0x0, 0xe1, 0x0, 0x0, 0x0, + 0xe0, 0x3b, 0x0, 0xe1, 0x0, 0x14, 0x0, 0xe0, + 0x3b, 0x0, 0xe1, 0x0, 0x3a, 0x0, 0xe5, 0x9e, + 0xdc, 0xd4, 0x11, 0x78, 0x1f, 0xda, 0x74, 0x10, + 0x5c, 0xdd, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B65 "步" */ + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, + 0x5, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0xf, + 0x0, 0x5f, 0xdd, 0xda, 0x0, 0x0, 0xf, 0x0, + 0x59, 0x0, 0x0, 0x0, 0x3, 0x3f, 0x33, 0x7b, + 0x33, 0x33, 0x30, 0x1a, 0xaa, 0xaa, 0xdd, 0xaa, + 0xaa, 0xa1, 0x0, 0x1, 0x70, 0x68, 0x0, 0x15, + 0x0, 0x0, 0xb, 0x60, 0x68, 0x0, 0xa7, 0x0, + 0x0, 0xaa, 0x0, 0x68, 0x6, 0xc0, 0x0, 0x6, + 0xa0, 0x0, 0x69, 0x8d, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x6e, 0xa0, 0x0, 0x0, 0x0, 0x3, 0x8e, + 0xb4, 0x0, 0x0, 0x0, 0x1d, 0xeb, 0x72, 0x0, + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B69 "歩" */ + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, + 0x5, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x1d, + 0x0, 0x7e, 0xdd, 0xdc, 0x0, 0x0, 0x1d, 0x0, + 0x77, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x0, 0x78, + 0x0, 0x0, 0x0, 0x2d, 0xdd, 0xdd, 0xee, 0xdd, + 0xdd, 0xd3, 0x0, 0x6, 0x40, 0x77, 0x1, 0x70, + 0x0, 0x0, 0x4d, 0x10, 0x77, 0x0, 0x8b, 0x0, + 0x7, 0xd2, 0x0, 0x77, 0x4, 0x98, 0xb0, 0x5, + 0x10, 0x5d, 0xd4, 0xd, 0x40, 0x50, 0x0, 0x0, + 0x0, 0x3, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x26, + 0xbd, 0x40, 0x0, 0x0, 0x0, 0xbe, 0xc9, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B6F "歯" */ + 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x5e, 0xcc, 0xcc, 0x0, 0x0, 0xd, + 0x0, 0x58, 0x0, 0x0, 0x0, 0xb, 0xbf, 0xbb, + 0xcd, 0xbb, 0xbb, 0xb5, 0x2, 0x42, 0x22, 0x34, + 0x22, 0x23, 0x31, 0x2, 0xa0, 0xa0, 0x57, 0xa, + 0x7, 0x70, 0x2, 0xa0, 0x66, 0x57, 0x57, 0x7, + 0x70, 0x2, 0xa8, 0xbb, 0xdd, 0xcc, 0xb7, 0x70, + 0x2, 0xa0, 0x4, 0xe8, 0x80, 0x7, 0x70, 0x2, + 0xa0, 0x5b, 0x67, 0x6a, 0x7, 0x70, 0x2, 0xa7, + 0xa0, 0x57, 0x5, 0x47, 0x70, 0x2, 0xb3, 0x22, + 0x55, 0x22, 0x28, 0x70, 0x1, 0xaa, 0xaa, 0xaa, + 0xaa, 0xad, 0x70, + + /* U+6B72 "歲" */ + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x5c, 0x77, 0x76, 0x0, 0x0, 0xd, + 0x0, 0x5a, 0x22, 0x22, 0x0, 0x1c, 0xcf, 0xcc, + 0xde, 0xcc, 0xcc, 0xc1, 0x0, 0x0, 0x0, 0x0, + 0xc2, 0xb6, 0x0, 0x2, 0x88, 0x88, 0x88, 0xe9, + 0x9d, 0x80, 0x4, 0xa4, 0x44, 0x44, 0xb7, 0x44, + 0x40, 0x5, 0x88, 0xbc, 0xb8, 0x66, 0x1c, 0x0, + 0x5, 0x72, 0x2c, 0x3, 0x39, 0x86, 0x0, 0x7, + 0x6b, 0x2c, 0x39, 0xd, 0xc0, 0x0, 0x9, 0x6a, + 0xb, 0xc1, 0x1d, 0x60, 0x41, 0xd, 0x10, 0x4c, + 0x32, 0xc7, 0xd1, 0x92, 0x3a, 0xa, 0x80, 0x2c, + 0x20, 0x4c, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6B73 "歳" */ + 0x0, 0x0, 0x0, 0x49, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x4e, 0xbb, 0xb8, 0x0, 0x0, 0xd, + 0x0, 0x49, 0x0, 0x0, 0x0, 0x1c, 0xcf, 0xdc, + 0xde, 0xcc, 0xcc, 0xc2, 0x0, 0x0, 0x0, 0x0, + 0xd0, 0xa6, 0x0, 0x4, 0xcc, 0xcc, 0xcc, 0xfd, + 0xcf, 0xd1, 0x5, 0x80, 0x0, 0x0, 0x85, 0x2, + 0x0, 0x5, 0x89, 0xbb, 0xba, 0x58, 0xd, 0x20, + 0x6, 0x71, 0x1c, 0x0, 0x1c, 0x5b, 0x0, 0x7, + 0x59, 0x3c, 0x39, 0xc, 0xd3, 0x0, 0xa, 0x5c, + 0xc, 0xb, 0x1a, 0xb0, 0x23, 0xd, 0x23, 0xc, + 0x2, 0xc9, 0xc4, 0x55, 0x47, 0x0, 0xba, 0xb, + 0x50, 0x1b, 0xd1, + + /* U+6B77 "歷" */ + 0x0, 0xfd, 0xdd, 0xdd, 0xdd, 0xdd, 0xd8, 0x0, + 0xd1, 0x36, 0xa3, 0x14, 0x6a, 0x40, 0x0, 0xd2, + 0x5b, 0x30, 0x25, 0xd0, 0x0, 0x0, 0xd6, 0xbd, + 0xca, 0x7b, 0xfb, 0xb5, 0x0, 0xd0, 0x4f, 0xa0, + 0xa, 0xec, 0x0, 0x1, 0xd2, 0xc9, 0x89, 0x76, + 0xc5, 0xb1, 0x2, 0xcc, 0x28, 0x33, 0xa0, 0xb0, + 0x69, 0x3, 0xb0, 0x0, 0x1, 0xb0, 0x0, 0x0, + 0x4, 0x90, 0x29, 0x1, 0xfc, 0xcc, 0x30, 0x7, + 0x60, 0x2b, 0x1, 0xd0, 0x0, 0x0, 0xc, 0x20, + 0x2b, 0x1, 0xd0, 0x0, 0x0, 0x2d, 0x3c, 0xdf, + 0xcd, 0xfc, 0xcc, 0xc8, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+6B7B "死" */ + 0x3e, 0xef, 0xfe, 0xee, 0xfe, 0xee, 0xe3, 0x0, + 0xa, 0x50, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x1e, + 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x7e, 0xbb, + 0xb1, 0xd1, 0x8, 0x90, 0x2, 0xd2, 0x22, 0xe0, + 0xd2, 0xbb, 0x0, 0xd, 0x51, 0x3, 0xb0, 0xde, + 0x70, 0x0, 0x37, 0x5c, 0x19, 0x60, 0xd3, 0x0, + 0x0, 0x0, 0x7, 0xdd, 0x0, 0xd1, 0x0, 0x0, + 0x0, 0x0, 0xd5, 0x0, 0xd1, 0x0, 0x10, 0x0, + 0xa, 0x90, 0x0, 0xd1, 0x0, 0x75, 0x3, 0xc9, + 0x0, 0x0, 0xc3, 0x0, 0xa4, 0x2d, 0x50, 0x0, + 0x0, 0x6c, 0xdd, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+6B8A "殊" */ + 0x0, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x3d, + 0xee, 0xdd, 0x2c, 0xe, 0x0, 0x0, 0x0, 0xa4, + 0x0, 0x3b, 0xe, 0x0, 0x0, 0x0, 0xe0, 0x0, + 0x8f, 0xef, 0xee, 0xb0, 0x3, 0xfd, 0xeb, 0xd1, + 0xe, 0x0, 0x0, 0xa, 0x60, 0x6b, 0x50, 0xe, + 0x0, 0x0, 0x2e, 0x70, 0xa7, 0xdd, 0xdf, 0xdd, + 0xd5, 0x55, 0x7d, 0xe0, 0x0, 0xbf, 0xc0, 0x0, + 0x0, 0x7, 0xa0, 0x7, 0x8e, 0x77, 0x0, 0x0, + 0xd, 0x30, 0x5c, 0xe, 0xc, 0x30, 0x0, 0x7a, + 0x7, 0xd1, 0xe, 0x2, 0xe4, 0x7, 0xd1, 0x19, + 0x0, 0xe, 0x0, 0x33, 0xa, 0x10, 0x0, 0x0, + 0xe, 0x0, 0x0, + + /* U+6B8B "残" */ + 0x0, 0x0, 0x0, 0x0, 0xe0, 0x50, 0x0, 0x3d, + 0xee, 0xdd, 0x10, 0xe0, 0x8b, 0x10, 0x0, 0x95, + 0x0, 0x0, 0xe0, 0x4, 0x10, 0x0, 0xd1, 0x0, + 0x36, 0xfb, 0xdd, 0x70, 0x1, 0xfd, 0xe8, 0x97, + 0xe4, 0x0, 0x0, 0x7, 0x80, 0x75, 0x0, 0xb3, + 0x14, 0x70, 0xe, 0x20, 0xb3, 0x58, 0xee, 0xc9, + 0x60, 0x59, 0xa7, 0xd1, 0x85, 0x87, 0x0, 0x80, + 0x0, 0xb, 0x80, 0x0, 0x3b, 0xb, 0x50, 0x0, + 0xd, 0x20, 0x0, 0xe, 0xc6, 0x0, 0x0, 0x79, + 0x0, 0x0, 0x7f, 0x70, 0x20, 0x6, 0xd0, 0x2, + 0x8c, 0x63, 0xd2, 0x93, 0x2c, 0x10, 0x7, 0x60, + 0x0, 0x6e, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6BB5 "段" */ + 0x0, 0x0, 0x17, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x7b, 0xc7, 0x10, 0xfc, 0xdc, 0x0, 0x1, 0xd1, + 0x0, 0x0, 0xd0, 0xc, 0x0, 0x1, 0xd1, 0x11, + 0x2, 0xb0, 0xc, 0x0, 0x1, 0xfb, 0xbb, 0x17, + 0x80, 0xd, 0x0, 0x1, 0xd0, 0x0, 0x4d, 0x10, + 0x8, 0xb8, 0x1, 0xd3, 0x33, 0x24, 0x22, 0x22, + 0x10, 0x1, 0xe9, 0x99, 0x2d, 0xca, 0xad, 0x90, + 0x1, 0xd0, 0x0, 0x3, 0xa0, 0xc, 0x30, 0x2, + 0xe5, 0x7a, 0x40, 0xa5, 0x5b, 0x0, 0x2d, 0xe7, + 0x52, 0x0, 0x1d, 0xd1, 0x0, 0x1, 0xd0, 0x0, + 0x1, 0x9c, 0xc9, 0x10, 0x1, 0xd0, 0x0, 0xbc, + 0x60, 0x6, 0xd8, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+6BCD "母" */ + 0x0, 0xd, 0xed, 0xdd, 0xdd, 0xed, 0x0, 0x0, + 0xf, 0x1, 0x50, 0x0, 0x2c, 0x0, 0x0, 0x2d, + 0x0, 0x7c, 0x30, 0x3b, 0x0, 0x0, 0x4a, 0x0, + 0x2, 0x60, 0x4a, 0x0, 0x2d, 0xef, 0xdd, 0xdd, + 0xdd, 0xef, 0xd2, 0x0, 0x96, 0x2, 0x0, 0x0, + 0x69, 0x0, 0x0, 0xb3, 0x9, 0xb2, 0x0, 0x78, + 0x0, 0x0, 0xe1, 0x0, 0x4d, 0x30, 0x86, 0x0, + 0x0, 0xe0, 0x0, 0x3, 0x20, 0xa5, 0x0, 0x3, + 0xdd, 0xdd, 0xdd, 0xdd, 0xfe, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0xde, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+6BCE "毎" */ + 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xc1, 0x11, 0x11, 0x11, 0x10, 0x0, 0x1e, + 0xcc, 0xcc, 0xcc, 0xcc, 0xb0, 0x0, 0xc6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0x78, 0xed, 0xdf, + 0xdd, 0xdc, 0x0, 0x0, 0xa, 0x40, 0xe, 0x0, + 0x2b, 0x0, 0x0, 0xc, 0x10, 0x1c, 0x0, 0x3a, + 0x0, 0x2d, 0xdf, 0xdd, 0xef, 0xdd, 0xef, 0xd8, + 0x0, 0x2c, 0x0, 0x58, 0x0, 0x68, 0x0, 0x0, + 0x49, 0x0, 0x76, 0x0, 0x86, 0x0, 0x0, 0x8e, + 0xdd, 0xee, 0xdd, 0xee, 0xd3, 0x0, 0x93, 0x0, + 0x0, 0x0, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xbc, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6BCF "每" */ + 0x0, 0x1, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x91, 0x11, 0x11, 0x11, 0x10, 0x0, 0x2e, + 0xcc, 0xcc, 0xcc, 0xcc, 0xc1, 0x1, 0xd5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc, 0x8b, 0xed, 0xdd, + 0xdd, 0xeb, 0x0, 0x4, 0xd, 0x11, 0xb5, 0x0, + 0x3b, 0x0, 0x0, 0xe, 0x0, 0x8, 0x80, 0x4a, + 0x0, 0x2d, 0xdf, 0xcc, 0xcc, 0xdc, 0xdf, 0xd8, + 0x0, 0x3a, 0x5, 0x91, 0x0, 0x58, 0x0, 0x0, + 0x68, 0x0, 0x3c, 0x30, 0x67, 0x0, 0x0, 0x9e, + 0xcc, 0xcd, 0xdc, 0xee, 0xc1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xbc, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6BD4 "比" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, 0xe0, + 0x0, 0x3, 0xc0, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x3c, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x3, 0xc0, + 0x0, 0x0, 0x1e, 0x0, 0x0, 0x3c, 0x0, 0x6a, + 0x1, 0xe2, 0x22, 0x13, 0xc0, 0x7e, 0x30, 0x1f, + 0xcc, 0xc5, 0x3d, 0xab, 0x10, 0x1, 0xe0, 0x0, + 0x3, 0xf6, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x3c, + 0x0, 0x0, 0x1, 0xe0, 0x0, 0x3, 0xc0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x3c, 0x0, 0xb, 0x21, + 0xe0, 0x1, 0x23, 0xc0, 0x0, 0xc1, 0x2e, 0x7c, + 0xe4, 0x2d, 0x0, 0xe, 0x7, 0xe8, 0x30, 0x0, + 0xce, 0xee, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6BDB "毛" */ + 0x0, 0x0, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, + 0x1, 0x47, 0xbe, 0xa3, 0x0, 0x49, 0xbe, 0xde, + 0x73, 0x0, 0x0, 0x3, 0x42, 0x1, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1d, 0x35, 0x7a, 0xc4, + 0x3, 0x8a, 0xce, 0xfa, 0x86, 0x41, 0x0, 0x36, + 0x31, 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xd0, 0x24, 0x68, 0xa3, 0x35, 0x79, 0xcf, 0xec, + 0xa7, 0x53, 0x8, 0x86, 0x44, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x4, 0x60, + 0x0, 0x1, 0xe0, 0x0, 0x0, 0x87, 0x0, 0x0, + 0xa, 0xee, 0xee, 0xed, 0x10, + + /* U+6C0F "氏" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x1, + 0x35, 0x68, 0xbe, 0xd6, 0x0, 0xd, 0xca, 0x97, + 0xe4, 0x0, 0x0, 0x0, 0xd1, 0x0, 0xc, 0x30, + 0x0, 0x0, 0xd, 0x10, 0x0, 0xb4, 0x0, 0x0, + 0x0, 0xd2, 0x0, 0xa, 0x50, 0x0, 0x0, 0xd, + 0xed, 0xdd, 0xef, 0xdd, 0xdd, 0x0, 0xd1, 0x0, + 0x4, 0xa0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x1e, + 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0xc3, 0x0, + 0x0, 0xd, 0x10, 0x27, 0x15, 0xa0, 0x9, 0x10, + 0xeb, 0xeb, 0x60, 0xc, 0x70, 0xd0, 0x1a, 0x40, + 0x0, 0x0, 0x1a, 0xe9, 0x0, + + /* U+6C11 "民" */ + 0x2f, 0xdd, 0xdd, 0xdd, 0xdd, 0xd0, 0x2, 0xd0, + 0x0, 0x0, 0x0, 0x1d, 0x0, 0x2d, 0x0, 0x0, + 0x0, 0x1, 0xd0, 0x2, 0xfd, 0xdd, 0xee, 0xdd, + 0xed, 0x0, 0x2d, 0x0, 0x3, 0xc0, 0x0, 0x0, + 0x2, 0xd0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x2f, + 0xee, 0xee, 0xfe, 0xee, 0xec, 0x2, 0xd0, 0x0, + 0x9, 0x70, 0x0, 0x0, 0x2d, 0x0, 0x0, 0x3d, + 0x0, 0x0, 0x2, 0xd0, 0x0, 0x30, 0xb7, 0x0, + 0xa0, 0x3d, 0x6b, 0xe8, 0x1, 0xe6, 0xd, 0x9, + 0xd8, 0x30, 0x0, 0x2, 0xbe, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6C14 "气" */ + 0x0, 0x4, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5e, + 0xdd, 0xdd, 0xdd, 0xdd, 0xd0, 0x0, 0xc3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x9, 0xa5, 0xcc, 0xcc, + 0xcc, 0xcc, 0x0, 0x4d, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xac, 0xcc, 0xcc, 0xcd, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa4, 0x22, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5b, 0x56, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xe2, + + /* U+6C17 "気" */ + 0x0, 0x3, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, + 0xcc, 0xcc, 0xcc, 0xcc, 0xc2, 0x0, 0xb7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa, 0xc3, 0xcc, 0xcc, + 0xcc, 0xca, 0x0, 0x2b, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xcc, 0xcc, 0xcc, 0xcc, 0xf3, + 0x0, 0x0, 0x2, 0x0, 0xa, 0x30, 0xa4, 0x0, + 0x0, 0x2c, 0x91, 0x89, 0x0, 0xa4, 0x0, 0x0, + 0x0, 0x6e, 0xe0, 0x0, 0x96, 0x0, 0x0, 0x0, + 0xab, 0xba, 0x0, 0x68, 0x15, 0x0, 0x6d, 0x60, + 0x8, 0xd0, 0x2d, 0x38, 0xb, 0x91, 0x0, 0x0, + 0x30, 0x7, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6C34 "水" */ + 0x0, 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3b, 0x0, 0xa, 0x30, 0xb, 0xee, 0xfc, 0x3f, + 0x20, 0x8b, 0x0, 0x0, 0x0, 0x68, 0x3f, 0xa7, + 0xb0, 0x0, 0x0, 0x0, 0xc3, 0x3b, 0xab, 0x0, + 0x0, 0x0, 0x3, 0xc0, 0x3b, 0x1d, 0x20, 0x0, + 0x0, 0xc, 0x50, 0x3b, 0x5, 0xd1, 0x0, 0x0, + 0x9a, 0x0, 0x3b, 0x0, 0x7d, 0x30, 0xa, 0xc0, + 0x0, 0x3b, 0x0, 0x6, 0xf7, 0x6, 0x0, 0x0, + 0x4b, 0x0, 0x0, 0x22, 0x0, 0x0, 0x2f, 0xe6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6C37 "氷" */ + 0x0, 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, + 0x97, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x9, + 0xc1, 0x3c, 0x0, 0x1, 0x80, 0x0, 0x0, 0x78, + 0x3f, 0x10, 0xc, 0x80, 0x0, 0x0, 0x0, 0x3f, + 0x70, 0xb8, 0x0, 0xd, 0xee, 0xea, 0x3c, 0xdb, + 0x70, 0x0, 0x0, 0x0, 0x87, 0x3b, 0x99, 0x0, + 0x0, 0x0, 0x0, 0xe2, 0x3b, 0x1e, 0x10, 0x0, + 0x0, 0x7, 0x90, 0x3b, 0x7, 0xc0, 0x0, 0x0, + 0x4d, 0x10, 0x3b, 0x0, 0xa9, 0x0, 0x5, 0xe3, + 0x0, 0x3b, 0x0, 0xb, 0xc2, 0xb, 0x20, 0x0, + 0x4b, 0x0, 0x0, 0x76, 0x0, 0x0, 0x9f, 0xe6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6C38 "永" */ + 0x0, 0x0, 0x78, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x16, 0xbe, 0x81, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x87, 0x0, 0x0, 0x0, 0x2e, 0xee, + 0xea, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e, + 0x0, 0x1, 0xa0, 0x0, 0x0, 0x0, 0x3f, 0x40, + 0x1d, 0x60, 0xe, 0xee, 0xf7, 0x3f, 0xb3, 0xd5, + 0x0, 0x0, 0x0, 0xd2, 0x3c, 0xcc, 0x20, 0x0, + 0x0, 0x7, 0xb0, 0x3b, 0x3d, 0x10, 0x0, 0x0, + 0x1e, 0x20, 0x3b, 0x7, 0xc0, 0x0, 0x2, 0xd5, + 0x0, 0x3b, 0x0, 0x7d, 0x50, 0x1d, 0x50, 0x0, + 0x4b, 0x0, 0x4, 0xc6, 0x0, 0x0, 0x4e, 0xe7, + 0x0, 0x0, 0x0, + + /* U+6C42 "求" */ + 0x0, 0x0, 0x0, 0x87, 0xb, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x87, 0x4, 0xe5, 0x0, 0x1, 0x11, + 0x11, 0x98, 0x11, 0x4a, 0x10, 0xc, 0xcc, 0xcc, + 0xee, 0xcc, 0xcc, 0xc1, 0x0, 0x20, 0x0, 0x8b, + 0x0, 0x4, 0x10, 0x1, 0xc5, 0x0, 0x8f, 0x30, + 0x4d, 0x10, 0x0, 0x1d, 0x40, 0x8a, 0xb4, 0xd2, + 0x0, 0x0, 0x2, 0x50, 0xa7, 0x9c, 0x10, 0x0, + 0x0, 0x0, 0x4c, 0xd7, 0xd, 0x30, 0x0, 0x0, + 0x3b, 0xb2, 0x87, 0x4, 0xe3, 0x0, 0x1a, 0xd4, + 0x0, 0x87, 0x0, 0x4e, 0x91, 0x5, 0x0, 0x0, + 0x97, 0x0, 0x1, 0x92, 0x0, 0x0, 0xdf, 0xd3, + 0x0, 0x0, 0x0, + + /* U+6C5A "汚" */ + 0x6, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xc9, 0x1e, 0xef, 0xee, 0xee, 0x90, 0x0, 0x5, + 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x0, 0x0, 0x6b, 0x30, 0x9d, 0xdf, + 0xdd, 0xdd, 0xd2, 0x3, 0xd3, 0x0, 0x78, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, + 0x0, 0x0, 0x3, 0x0, 0xec, 0xbb, 0xbb, 0x20, + 0x0, 0x3c, 0x0, 0x22, 0x22, 0x2d, 0x20, 0x0, + 0xb5, 0x0, 0x0, 0x0, 0xe, 0x0, 0x3, 0xd0, + 0x0, 0x0, 0x0, 0xe, 0x0, 0xc, 0x50, 0x0, + 0x0, 0x0, 0x5b, 0x0, 0x9, 0x0, 0x0, 0x3, + 0xdd, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6C60 "池" */ + 0x2, 0x80, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, + 0x8d, 0x31, 0x30, 0xe, 0x0, 0x0, 0x0, 0x3, + 0x43, 0xb0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xb0, 0xe, 0x4b, 0xf0, 0x7, 0x10, 0x3, 0xb1, + 0x7f, 0xb4, 0xe0, 0x7, 0xe6, 0x6, 0xfe, 0x8e, + 0x0, 0xe0, 0x0, 0x14, 0xbc, 0xc0, 0xe, 0x0, + 0xe0, 0x0, 0x0, 0x3, 0xb0, 0xe, 0x0, 0xe0, + 0x0, 0x7, 0x43, 0xb0, 0xe, 0x13, 0xd0, 0x0, + 0x1e, 0x13, 0xb0, 0xa, 0x4a, 0x50, 0x0, 0x97, + 0x3, 0xb0, 0x0, 0x0, 0x49, 0x3, 0xd0, 0x2, + 0xd0, 0x0, 0x0, 0x77, 0x6, 0x50, 0x0, 0xbe, + 0xee, 0xee, 0xd1, + + /* U+6C7A "決" */ + 0x8, 0x60, 0x0, 0x2, 0xb0, 0x0, 0x0, 0x1, + 0xac, 0x0, 0x2, 0xb0, 0x0, 0x0, 0x0, 0x3, + 0xa, 0xbb, 0xeb, 0xbb, 0x0, 0x0, 0x0, 0x3, + 0x35, 0xc3, 0x3d, 0x10, 0x59, 0x10, 0x0, 0x2, + 0xb0, 0xc, 0x10, 0x7, 0xe3, 0x0, 0x2, 0xb0, + 0xc, 0x10, 0x0, 0x30, 0x11, 0x14, 0xb1, 0x1d, + 0x20, 0x0, 0x0, 0xbc, 0xce, 0xfe, 0xcc, 0xc3, + 0x0, 0x2a, 0x0, 0x9, 0xbb, 0x0, 0x0, 0x0, + 0x96, 0x0, 0x1e, 0x1e, 0x30, 0x0, 0x2, 0xe0, + 0x0, 0xa8, 0x6, 0xb0, 0x0, 0xa, 0x60, 0xa, + 0xb0, 0x0, 0xba, 0x0, 0x1c, 0x3, 0xe8, 0x0, + 0x0, 0x9, 0xe1, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x0, 0x20, + + /* U+6C88 "沈" */ + 0x3, 0x80, 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, + 0x8e, 0x30, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x3, + 0x10, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x0, 0xf, + 0xee, 0xfe, 0xee, 0xf1, 0x7, 0x10, 0xd, 0x0, + 0xd1, 0x0, 0xd1, 0x6, 0xd6, 0xc, 0x0, 0xe4, + 0x0, 0xc1, 0x0, 0x13, 0x0, 0x1, 0xed, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x5, 0xbd, 0x0, 0x0, + 0x0, 0x8, 0x50, 0x9, 0x6d, 0x0, 0x0, 0x0, + 0x1d, 0x0, 0x2e, 0x1d, 0x0, 0x0, 0x0, 0x96, + 0x0, 0xb7, 0xd, 0x0, 0x65, 0x3, 0xd0, 0xa, + 0xb0, 0xd, 0x0, 0x85, 0x7, 0x40, 0xa9, 0x0, + 0xc, 0xed, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6C92 "沒" */ + 0x6, 0x70, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, + 0x8d, 0x20, 0x7e, 0xaa, 0xaa, 0x50, 0x0, 0x3, + 0x0, 0xb6, 0x33, 0x39, 0x60, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x9, 0x50, 0x3a, 0x20, 0x8, 0x90, + 0x0, 0xb, 0x30, 0x6, 0xe5, 0x4d, 0x0, 0xa, + 0xae, 0x0, 0x0, 0x12, 0x23, 0x0, 0x3, 0x40, + 0x0, 0x0, 0x0, 0xd, 0xfd, 0xdd, 0xdf, 0x50, + 0x0, 0xb, 0x10, 0xb4, 0x0, 0x2d, 0x0, 0x0, + 0x4b, 0x0, 0x1d, 0x21, 0xd4, 0x0, 0x0, 0xd3, + 0x0, 0x3, 0xed, 0x40, 0x0, 0x6, 0xb0, 0x0, + 0x4b, 0xcc, 0xa2, 0x0, 0xb, 0x20, 0x8e, 0xb4, + 0x0, 0x6d, 0xd2, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x20, + + /* U+6CB9 "油" */ + 0x6, 0x70, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x19, + 0xd2, 0x0, 0xc, 0x10, 0x0, 0x0, 0x4, 0x10, + 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0xde, 0xef, + 0xee, 0xe3, 0x29, 0x20, 0xe, 0x0, 0xc1, 0xa, + 0x30, 0x5d, 0x50, 0xe0, 0xc, 0x10, 0xa3, 0x0, + 0x1, 0xe, 0x0, 0xc1, 0xa, 0x30, 0x0, 0x0, + 0xee, 0xef, 0xee, 0xf3, 0x0, 0x8, 0xe, 0x0, + 0xc1, 0xa, 0x30, 0x6, 0xa0, 0xe0, 0xc, 0x10, + 0xa3, 0x0, 0xe2, 0xe, 0x0, 0xc1, 0xa, 0x30, + 0x98, 0x0, 0xee, 0xef, 0xee, 0xf3, 0x7, 0x0, + 0xe, 0x0, 0x0, 0x9, 0x30, + + /* U+6CBB "治" */ + 0x2, 0x40, 0x0, 0x5, 0x50, 0x0, 0x0, 0x2, + 0xbb, 0x20, 0xe, 0x20, 0x0, 0x0, 0x0, 0x5, + 0x20, 0x88, 0x6, 0x60, 0x0, 0x0, 0x0, 0x2, + 0xd0, 0x1, 0xd4, 0x0, 0x27, 0x0, 0xc, 0x30, + 0x0, 0x4e, 0x10, 0x7, 0xd4, 0x9f, 0xde, 0xed, + 0xcc, 0xa0, 0x0, 0x11, 0x22, 0x0, 0x0, 0x0, + 0x40, 0x0, 0x3, 0xa, 0xbb, 0xbb, 0xbb, 0x0, + 0x0, 0xe, 0x1e, 0x22, 0x22, 0x2e, 0x10, 0x0, + 0x88, 0xe, 0x0, 0x0, 0xd, 0x10, 0x1, 0xe1, + 0xe, 0x0, 0x0, 0xd, 0x10, 0xb, 0x70, 0xe, + 0x22, 0x22, 0x2e, 0x10, 0x9, 0x0, 0xe, 0xbb, + 0xbb, 0xbe, 0x10, + + /* U+6CC1 "況" */ + 0x3, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xcb, 0x1d, 0xed, 0xdd, 0xdf, 0x20, 0x0, 0x5, + 0xd, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0xd, + 0x0, 0x0, 0xb, 0x20, 0x24, 0x0, 0xd, 0x0, + 0x0, 0xb, 0x20, 0x3a, 0xd4, 0xd, 0x21, 0x11, + 0x1c, 0x20, 0x0, 0x23, 0xa, 0xde, 0xcf, 0xdc, + 0x20, 0x0, 0x0, 0x0, 0x67, 0xd, 0x10, 0x0, + 0x0, 0xa, 0x30, 0x85, 0xd, 0x10, 0x0, 0x0, + 0x3c, 0x0, 0xc2, 0xd, 0x10, 0x0, 0x0, 0xc3, + 0x2, 0xd0, 0xd, 0x10, 0x90, 0x8, 0x90, 0x3d, + 0x30, 0xd, 0x10, 0xd0, 0xb, 0x13, 0xd4, 0x0, + 0x9, 0xed, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6CCA "泊" */ + 0x1, 0x10, 0x0, 0x0, 0x50, 0x0, 0x0, 0x4d, + 0x80, 0x0, 0x2e, 0x0, 0x0, 0x0, 0x8, 0x20, + 0x6, 0x90, 0x0, 0x0, 0x0, 0x0, 0xee, 0xee, + 0xee, 0xed, 0x16, 0x0, 0xe, 0x0, 0x0, 0x1, + 0xd1, 0x8d, 0x30, 0xe0, 0x0, 0x0, 0x1d, 0x0, + 0x21, 0xe, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x10, + 0xed, 0xdd, 0xdd, 0xed, 0x0, 0xd, 0xe, 0x0, + 0x0, 0x1, 0xd0, 0x6, 0x90, 0xe0, 0x0, 0x0, + 0x1d, 0x0, 0xe1, 0xe, 0x0, 0x0, 0x1, 0xd0, + 0x88, 0x0, 0xec, 0xcc, 0xcc, 0xcd, 0x6, 0x10, + 0xe, 0x11, 0x11, 0x13, 0xc0, + + /* U+6CD5 "法" */ + 0x5, 0x70, 0x0, 0x0, 0x95, 0x0, 0x0, 0x2, + 0xbc, 0x20, 0x0, 0x95, 0x0, 0x0, 0x0, 0x7, + 0x30, 0x0, 0x96, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xdd, 0xee, 0xdd, 0x70, 0x17, 0x10, 0x0, 0x0, + 0x95, 0x0, 0x0, 0x6, 0xd5, 0x0, 0x0, 0x95, + 0x0, 0x0, 0x0, 0x1, 0x3e, 0xee, 0xfe, 0xee, + 0xe1, 0x0, 0x1, 0x0, 0x4, 0xd0, 0x0, 0x0, + 0x0, 0xc, 0x30, 0xc, 0x40, 0x40, 0x0, 0x0, + 0x4b, 0x0, 0x5b, 0x0, 0xa5, 0x0, 0x0, 0xd3, + 0x1, 0xd1, 0x0, 0x3e, 0x10, 0x8, 0x90, 0xb, + 0xed, 0xdc, 0xaa, 0x90, 0x6, 0x10, 0x4, 0x30, + 0x0, 0x0, 0xb0, + + /* U+6CE2 "波" */ + 0x5, 0x70, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, + 0x9d, 0x10, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x3, + 0xd, 0xdd, 0xfe, 0xdd, 0xd0, 0x0, 0x0, 0xe, + 0x0, 0xc1, 0x3, 0xc0, 0x2a, 0x10, 0xe, 0x0, + 0xc1, 0x9, 0x50, 0x7, 0xe3, 0xe, 0x0, 0xc2, + 0x3, 0x0, 0x0, 0x32, 0xf, 0xfd, 0xdd, 0xdf, + 0x0, 0x0, 0x0, 0x2c, 0x66, 0x0, 0x4a, 0x0, + 0x0, 0xa, 0x3a, 0xd, 0x0, 0xc3, 0x0, 0x0, + 0x78, 0x59, 0x6, 0xa8, 0x90, 0x0, 0x0, 0xe1, + 0x95, 0x0, 0xde, 0x0, 0x0, 0x7, 0x90, 0xe1, + 0x1a, 0xb9, 0xc3, 0x0, 0xc, 0x18, 0x87, 0xe7, + 0x0, 0x4c, 0xc1, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x20, + + /* U+6CE3 "泣" */ + 0x1, 0x20, 0x0, 0x0, 0x70, 0x0, 0x0, 0x3, + 0xca, 0x10, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x6, + 0x40, 0x0, 0x74, 0x0, 0x0, 0x0, 0x0, 0x6e, + 0xee, 0xee, 0xee, 0xe1, 0x17, 0x10, 0x0, 0x10, + 0x0, 0x14, 0x0, 0x6, 0xd5, 0x3, 0xb0, 0x0, + 0x4b, 0x0, 0x0, 0x12, 0x0, 0xe0, 0x0, 0x77, + 0x0, 0x0, 0x1, 0x0, 0xd2, 0x0, 0xb4, 0x0, + 0x0, 0xa, 0x40, 0xa4, 0x0, 0xe0, 0x0, 0x0, + 0x3c, 0x0, 0x87, 0x2, 0xb0, 0x0, 0x0, 0xd4, + 0x0, 0x56, 0x7, 0x70, 0x0, 0x7, 0xa0, 0xaa, + 0xaa, 0xae, 0xca, 0xa5, 0x5, 0x10, 0x33, 0x33, + 0x33, 0x33, 0x31, + + /* U+6CE8 "注" */ + 0x3, 0x20, 0x0, 0x2, 0x60, 0x0, 0x0, 0x4, + 0xd9, 0x10, 0x0, 0xd2, 0x0, 0x0, 0x0, 0x7, + 0x10, 0x0, 0x66, 0x0, 0x0, 0x0, 0x0, 0x6e, + 0xee, 0xfe, 0xee, 0xe0, 0x26, 0x0, 0x0, 0x0, + 0xb3, 0x0, 0x0, 0x18, 0xd3, 0x0, 0x0, 0xb3, + 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0xb3, 0x0, + 0x0, 0x0, 0x0, 0xd, 0xee, 0xfe, 0xee, 0x70, + 0x0, 0xc, 0x10, 0x0, 0xb3, 0x0, 0x0, 0x0, + 0x5b, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0xd3, + 0x0, 0x0, 0xb3, 0x0, 0x0, 0x7, 0xa0, 0x0, + 0x0, 0xb3, 0x0, 0x0, 0xd, 0x20, 0xde, 0xee, + 0xfe, 0xee, 0xe4, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6CF3 "泳" */ + 0x6, 0x20, 0x0, 0x86, 0x20, 0x0, 0x0, 0x4, + 0xd9, 0x0, 0x27, 0xcc, 0x40, 0x0, 0x0, 0x6, + 0x0, 0x0, 0x3, 0x40, 0x0, 0x0, 0x0, 0xc, + 0xee, 0xe0, 0x0, 0x0, 0x67, 0x0, 0x0, 0x0, + 0xe0, 0x0, 0x30, 0x19, 0xd2, 0x0, 0x0, 0xe5, + 0x9, 0x90, 0x0, 0x43, 0xcc, 0xf3, 0xea, 0x99, + 0x0, 0x0, 0x0, 0x0, 0xe0, 0xec, 0x80, 0x0, + 0x0, 0x2a, 0x6, 0x90, 0xe4, 0x90, 0x0, 0x0, + 0xa5, 0xd, 0x20, 0xe0, 0xc4, 0x0, 0x3, 0xd0, + 0xa7, 0x0, 0xe0, 0x2e, 0x50, 0xc, 0x47, 0x90, + 0x0, 0xe0, 0x3, 0xd1, 0x18, 0x0, 0x0, 0xae, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6D0B "洋" */ + 0x2, 0x0, 0x1, 0x60, 0x0, 0x26, 0x0, 0x8, + 0xc2, 0x0, 0xc3, 0x0, 0xa6, 0x0, 0x0, 0x4d, + 0x0, 0x49, 0x2, 0xd0, 0x0, 0x0, 0x0, 0x4d, + 0xdd, 0xfe, 0xdd, 0xb0, 0x24, 0x0, 0x0, 0x0, + 0xc2, 0x0, 0x0, 0x2b, 0xc2, 0x0, 0x0, 0xc2, + 0x0, 0x0, 0x0, 0x53, 0xc, 0xee, 0xfe, 0xee, + 0x60, 0x0, 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, + 0x0, 0x59, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, + 0xd3, 0xae, 0xee, 0xfe, 0xee, 0xe2, 0x5, 0xb0, + 0x0, 0x0, 0xc2, 0x0, 0x0, 0xe, 0x30, 0x0, + 0x0, 0xc2, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, + 0xc2, 0x0, 0x0, + + /* U+6D17 "洗" */ + 0x7, 0x30, 0x1, 0x80, 0xb2, 0x0, 0x0, 0x4, + 0xe5, 0x5, 0xa0, 0xb2, 0x0, 0x0, 0x0, 0x2a, + 0x9, 0x92, 0xc5, 0x22, 0x20, 0x0, 0x0, 0xe, + 0xbb, 0xec, 0xbb, 0x70, 0x36, 0x0, 0x7a, 0x0, + 0xb2, 0x0, 0x0, 0x18, 0xc1, 0x51, 0x0, 0xb2, + 0x0, 0x0, 0x0, 0x30, 0xde, 0xee, 0xfe, 0xee, + 0xe3, 0x0, 0x0, 0x0, 0x77, 0x8, 0x50, 0x0, + 0x0, 0x49, 0x0, 0x95, 0x8, 0x50, 0x0, 0x0, + 0xb3, 0x0, 0xc2, 0x8, 0x50, 0x0, 0x3, 0xc0, + 0x3, 0xd0, 0x8, 0x50, 0x64, 0xb, 0x50, 0x2d, + 0x40, 0x8, 0x60, 0x85, 0xb, 0x4, 0xd5, 0x0, + 0x4, 0xdd, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6D32 "洲" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d, + 0x40, 0xe, 0x0, 0xe0, 0xe, 0x0, 0x2a, 0x0, + 0xe0, 0xe, 0x0, 0xe0, 0x0, 0x0, 0xe, 0x0, + 0xe0, 0xe, 0x6, 0x0, 0x13, 0xe3, 0xe, 0x50, + 0xe0, 0x8d, 0x45, 0x6e, 0xb1, 0xeb, 0x2e, 0x0, + 0x22, 0xa3, 0xd6, 0x6e, 0x39, 0xe0, 0x0, 0x1b, + 0x2d, 0x28, 0xe0, 0xae, 0x0, 0x26, 0x3, 0xb0, + 0xe, 0x0, 0xe0, 0x9, 0x60, 0x58, 0x0, 0xe0, + 0xe, 0x0, 0xe0, 0xa, 0x30, 0xe, 0x0, 0xe0, + 0x79, 0x2, 0xc0, 0x0, 0xe0, 0xe, 0xa, 0x10, + 0xa2, 0x0, 0xe, 0x0, 0xe0, + + /* U+6D3B "活" */ + 0x8, 0x40, 0x0, 0x0, 0x25, 0x8c, 0x20, 0x2, + 0xbc, 0x1b, 0xdd, 0xea, 0x51, 0x0, 0x0, 0x3, + 0x1, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa3, 0x0, 0x0, 0x59, 0x10, 0xad, 0xdd, + 0xfe, 0xdd, 0xd2, 0x7, 0xe3, 0x0, 0x0, 0xa4, + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0xa3, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x11, 0xb4, 0x11, 0x0, + 0x0, 0xb, 0xb, 0xdc, 0xcc, 0xce, 0x30, 0x0, + 0x78, 0xb, 0x20, 0x0, 0xb, 0x30, 0x1, 0xe1, + 0xb, 0x20, 0x0, 0xb, 0x30, 0xb, 0x60, 0xb, + 0x42, 0x22, 0x2b, 0x30, 0x19, 0x0, 0xb, 0xba, + 0xaa, 0xad, 0x20, + + /* U+6D3E "派" */ + 0x3, 0x20, 0x0, 0x0, 0x1, 0x59, 0x10, 0x3, + 0xd8, 0x4, 0x8b, 0xdd, 0x95, 0x0, 0x0, 0x7, + 0xd, 0x52, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x1, 0x48, 0xda, 0x0, 0x28, 0x10, 0xd, 0xb, + 0x9e, 0x10, 0x0, 0x7, 0xd2, 0xd, 0xb, 0x1a, + 0x30, 0x0, 0x0, 0x20, 0xe, 0xb, 0x17, 0x64, + 0xc0, 0x0, 0x1, 0xe, 0xb, 0x14, 0xdb, 0x10, + 0x0, 0x3a, 0x1c, 0xb, 0x10, 0xe0, 0x0, 0x0, + 0xa4, 0x3a, 0xb, 0x10, 0xa6, 0x0, 0x3, 0xc0, + 0x76, 0xb, 0x11, 0x4d, 0x0, 0xb, 0x50, 0xd1, + 0xd, 0xbc, 0x39, 0xb0, 0x8, 0x4, 0x90, 0xb, + 0x40, 0x0, 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6D41 "流" */ + 0x4, 0x10, 0x0, 0x1, 0x70, 0x0, 0x0, 0x6, + 0xd3, 0x0, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x29, + 0xad, 0xde, 0xfe, 0xdd, 0xd1, 0x0, 0x0, 0x0, + 0x5b, 0x0, 0x80, 0x0, 0x37, 0x0, 0x3, 0xd1, + 0x0, 0x7a, 0x0, 0x8, 0xd3, 0x5f, 0xdc, 0xdd, + 0xdd, 0x70, 0x0, 0x31, 0x14, 0x20, 0x0, 0x1, + 0x80, 0x0, 0x0, 0x8, 0x40, 0xc0, 0x85, 0x0, + 0x0, 0xd, 0x9, 0x40, 0xc0, 0x85, 0x0, 0x0, + 0x79, 0xb, 0x30, 0xc0, 0x85, 0x0, 0x1, 0xe1, + 0xe, 0x0, 0xc0, 0x85, 0x31, 0xa, 0x70, 0x7a, + 0x0, 0xc0, 0x85, 0x64, 0xc, 0x3, 0xd1, 0x0, + 0x60, 0x5d, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6D45 "浅" */ + 0x6, 0x70, 0x0, 0xe, 0x8, 0x20, 0x0, 0x0, + 0x8c, 0x0, 0xd, 0x13, 0xd3, 0x0, 0x0, 0x3, + 0x0, 0xd, 0x21, 0x46, 0x40, 0x0, 0x0, 0x49, + 0xbf, 0xec, 0xa8, 0x50, 0x2c, 0x40, 0x24, 0x2a, + 0x50, 0x0, 0x0, 0x2, 0xc4, 0x0, 0x8, 0x72, + 0x46, 0x81, 0x0, 0x0, 0x6a, 0xce, 0xfc, 0xa7, + 0x61, 0x0, 0x2, 0x44, 0x22, 0xd0, 0x4, 0xc0, + 0x0, 0x3b, 0x0, 0x0, 0xc2, 0x4d, 0x20, 0x0, + 0xb4, 0x0, 0x0, 0x8c, 0xc2, 0x20, 0x2, 0xd0, + 0x0, 0x6, 0xdf, 0x10, 0x84, 0xb, 0x50, 0x39, + 0xd8, 0x17, 0xb1, 0xb2, 0x8, 0x0, 0x45, 0x0, + 0x0, 0x8e, 0xa0, + + /* U+6D74 "浴" */ + 0x2, 0x0, 0x0, 0x13, 0x1, 0x20, 0x0, 0x6, + 0xd4, 0x0, 0xb5, 0x3, 0xd2, 0x0, 0x0, 0x2c, + 0x18, 0xa0, 0x0, 0x4d, 0x10, 0x0, 0x0, 0x8b, + 0x2, 0xe0, 0x5, 0xc0, 0x24, 0x0, 0x40, 0xb, + 0xc6, 0x0, 0x10, 0x2b, 0xb1, 0x0, 0x89, 0xc, + 0x40, 0x0, 0x0, 0x50, 0x8, 0xb0, 0x1, 0xd6, + 0x0, 0x0, 0x2, 0xca, 0x0, 0x0, 0x1b, 0xc2, + 0x0, 0x15, 0x6e, 0xdd, 0xdd, 0xdd, 0x62, 0x0, + 0x96, 0xe, 0x0, 0x0, 0x1d, 0x0, 0x2, 0xd0, + 0xe, 0x0, 0x0, 0x1d, 0x0, 0xa, 0x60, 0xe, + 0x22, 0x22, 0x3d, 0x0, 0x9, 0x0, 0xe, 0xbb, + 0xbb, 0xbc, 0x0, + + /* U+6D77 "海" */ + 0x2, 0x10, 0x0, 0x70, 0x0, 0x0, 0x0, 0x3, + 0xc8, 0x4, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x7, + 0xb, 0xed, 0xdd, 0xdd, 0xd1, 0x0, 0x0, 0x5b, + 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0xd6, 0xdd, + 0xdd, 0xdd, 0x60, 0x1a, 0xb1, 0x6, 0x70, 0xa1, + 0x7, 0x60, 0x0, 0x51, 0x8, 0x50, 0x29, 0x8, + 0x50, 0x0, 0x0, 0xdf, 0xed, 0xdd, 0xdf, 0xe6, + 0x0, 0x58, 0xc, 0x14, 0x80, 0xa, 0x30, 0x0, + 0xb3, 0xe, 0x0, 0x66, 0xb, 0x20, 0x2, 0xd0, + 0x2f, 0xdd, 0xdd, 0xdf, 0xd0, 0x9, 0x60, 0x0, + 0x0, 0x0, 0x1d, 0x0, 0x9, 0x0, 0x0, 0x0, + 0x4c, 0xd6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6D88 "消" */ + 0x8, 0x40, 0x4, 0x0, 0xe0, 0x4, 0x20, 0x2c, + 0x90, 0xc2, 0xe, 0x0, 0xd2, 0x0, 0x4, 0x4, + 0xa0, 0xe0, 0x78, 0x0, 0x0, 0x0, 0x5, 0xe, + 0x4, 0x0, 0x5a, 0x10, 0xc, 0xee, 0xfe, 0xee, + 0x0, 0x8e, 0x20, 0xd1, 0x0, 0x0, 0xe0, 0x0, + 0x40, 0xd, 0x10, 0x0, 0xe, 0x0, 0x0, 0x0, + 0xdc, 0xcc, 0xcc, 0xf0, 0x0, 0x1a, 0xd, 0x10, + 0x0, 0xe, 0x0, 0x9, 0x60, 0xdd, 0xcc, 0xcc, + 0xf0, 0x2, 0xd0, 0xd, 0x10, 0x0, 0xe, 0x0, + 0xb5, 0x0, 0xd1, 0x0, 0x0, 0xe0, 0x9, 0x0, + 0xd, 0x10, 0xa, 0xda, 0x0, + + /* U+6DBC "涼" */ + 0x4, 0x10, 0x0, 0x2, 0x70, 0x0, 0x0, 0x6, + 0xd6, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x18, + 0x7d, 0xdd, 0xdd, 0xdd, 0xd1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x56, 0x0, 0xd, 0xdd, + 0xdd, 0xdf, 0x10, 0x19, 0xc1, 0xd, 0x10, 0x0, + 0xd, 0x10, 0x0, 0x30, 0xd, 0x10, 0x0, 0xd, + 0x10, 0x0, 0x0, 0xb, 0xdd, 0xfd, 0xdd, 0x10, + 0x0, 0x1c, 0x1, 0x20, 0xd1, 0x1, 0x0, 0x0, + 0x96, 0x9, 0x60, 0xd1, 0x5b, 0x0, 0x2, 0xd0, + 0x4c, 0x0, 0xd1, 0xa, 0x50, 0xc, 0x51, 0xd1, + 0x0, 0xd1, 0x2, 0xd0, 0x19, 0x0, 0x0, 0x9c, + 0xd0, 0x0, 0x0, + + /* U+6DF1 "深" */ + 0x4, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xc9, 0x5e, 0xdd, 0xdd, 0xdd, 0xd0, 0x0, 0x4, + 0x58, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x23, + 0x5b, 0x4, 0xc1, 0x50, 0x29, 0x20, 0x4, 0xd1, + 0x0, 0x5c, 0x0, 0x6, 0xd5, 0x2d, 0x20, 0x61, + 0x7, 0x70, 0x0, 0x11, 0x0, 0x0, 0xc2, 0x0, + 0x0, 0x0, 0x1, 0x5d, 0xde, 0xff, 0xdd, 0xc0, + 0x0, 0x2b, 0x0, 0xc, 0xed, 0x30, 0x0, 0x0, + 0x95, 0x0, 0x96, 0xc4, 0xd1, 0x0, 0x2, 0xd0, + 0x9, 0xa0, 0xc2, 0x4d, 0x20, 0xa, 0x50, 0xd7, + 0x0, 0xc2, 0x4, 0xe1, 0x7, 0x0, 0x10, 0x0, + 0xc2, 0x0, 0x10, + + /* U+6DF7 "混" */ + 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xc8, 0xf, 0xcc, 0xcc, 0xcf, 0x0, 0x0, 0x7, + 0x2e, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xf, + 0xbb, 0xbb, 0xbf, 0x0, 0x18, 0x10, 0xe, 0x0, + 0x0, 0xe, 0x0, 0x8, 0xe4, 0xf, 0xcc, 0xcc, + 0xcf, 0x0, 0x0, 0x23, 0x4, 0x0, 0x3, 0x0, + 0x0, 0x0, 0x1, 0xe, 0x0, 0xe, 0x0, 0x50, + 0x0, 0xb, 0x3e, 0xdd, 0x7e, 0x6d, 0x60, 0x0, + 0x4b, 0xe, 0x0, 0xe, 0x71, 0x0, 0x0, 0xc3, + 0xe, 0x0, 0xe, 0x0, 0x52, 0x6, 0xa0, 0xe, + 0x26, 0x5e, 0x0, 0x93, 0xa, 0x20, 0x3f, 0xc7, + 0x2a, 0xed, 0xd0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+6E05 "清" */ + 0x6, 0x40, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x3, + 0xd8, 0x6c, 0xcc, 0xfc, 0xcc, 0x90, 0x0, 0x5, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x2b, + 0xbb, 0xfb, 0xbb, 0x40, 0x39, 0x10, 0x33, 0x33, + 0xe4, 0x33, 0x31, 0x5, 0xd2, 0x66, 0x66, 0x66, + 0x66, 0x61, 0x0, 0x10, 0xb, 0xbb, 0xbb, 0xbb, + 0x0, 0x0, 0x1, 0xd, 0x0, 0x0, 0xd, 0x0, + 0x0, 0x3b, 0xe, 0xbb, 0xbb, 0xbf, 0x0, 0x0, + 0xa6, 0xd, 0x0, 0x0, 0xd, 0x0, 0x2, 0xe0, + 0xe, 0xbb, 0xbb, 0xbf, 0x0, 0xa, 0x70, 0xd, + 0x0, 0x0, 0xd, 0x0, 0x9, 0x0, 0xd, 0x0, + 0x7, 0xcb, 0x0, + + /* U+6E07 "渇" */ + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8d, + 0x30, 0xbd, 0xcc, 0xcc, 0xf0, 0x0, 0x39, 0xb, + 0x20, 0x0, 0xe, 0x0, 0x0, 0x0, 0xbc, 0xbb, + 0xbb, 0xf0, 0x35, 0x0, 0xb, 0x20, 0x0, 0xe, + 0x2, 0xbc, 0x10, 0x8e, 0xdb, 0xbb, 0xb0, 0x0, + 0x40, 0x2, 0xe3, 0x11, 0x11, 0x10, 0x0, 0x1, + 0xdb, 0xbb, 0xbb, 0xcb, 0x0, 0x59, 0xdd, 0x22, + 0x78, 0x4, 0x90, 0xc, 0x32, 0xac, 0x95, 0x0, + 0x58, 0x4, 0xb0, 0xa, 0x20, 0x5, 0x37, 0x60, + 0xd3, 0x0, 0x5d, 0xcc, 0xc1, 0xa4, 0x18, 0x0, + 0x0, 0x0, 0x8, 0xdc, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+6E08 "済" */ + 0x1, 0x0, 0x0, 0x4, 0x20, 0x0, 0x0, 0x9, + 0x90, 0x11, 0x14, 0xb1, 0x11, 0x10, 0x0, 0x76, + 0xad, 0xdb, 0xbb, 0xdd, 0xb0, 0x0, 0x0, 0x3, + 0xc1, 0x2, 0xd1, 0x0, 0x43, 0x0, 0x0, 0x2c, + 0x9c, 0x20, 0x0, 0x2c, 0x70, 0x48, 0xba, 0x7b, + 0xdb, 0x70, 0x0, 0x40, 0x56, 0x10, 0x0, 0x35, + 0x40, 0x0, 0x0, 0x9, 0x61, 0x11, 0x86, 0x0, + 0x0, 0x44, 0xa, 0xca, 0xaa, 0xd6, 0x0, 0x0, + 0xc1, 0xc, 0x30, 0x0, 0x76, 0x0, 0x5, 0x90, + 0xe, 0xbb, 0xbb, 0xd6, 0x0, 0xd, 0x10, 0x89, + 0x0, 0x0, 0x76, 0x0, 0x17, 0x2, 0xc0, 0x0, + 0x0, 0x76, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6E09 "渉" */ + 0x6, 0x60, 0x0, 0x0, 0x76, 0x0, 0x0, 0x1, + 0xbb, 0x3, 0x70, 0x76, 0x0, 0x0, 0x0, 0x7, + 0x4, 0x90, 0x7e, 0xdd, 0xa0, 0x0, 0x0, 0x4, + 0x90, 0x76, 0x0, 0x0, 0x3c, 0x40, 0xac, 0xeb, + 0xdd, 0xbb, 0xb4, 0x3, 0xc5, 0x22, 0x22, 0x97, + 0x23, 0x20, 0x0, 0x0, 0x1, 0xd0, 0x76, 0x1d, + 0x10, 0x0, 0x1, 0xb, 0x50, 0x76, 0x5, 0xb0, + 0x0, 0x1d, 0x79, 0x0, 0x86, 0x8, 0xa3, 0x0, + 0x96, 0x0, 0x2d, 0xc2, 0x88, 0x0, 0x2, 0xe0, + 0x0, 0x0, 0x9, 0xb0, 0x0, 0xb, 0x60, 0x0, + 0x27, 0xd8, 0x0, 0x0, 0xa, 0x0, 0x3e, 0xc7, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6E1B "減" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, + 0x70, 0x0, 0x0, 0xc, 0x4b, 0x10, 0x1, 0xaa, + 0x0, 0x0, 0xb, 0x14, 0xb0, 0x0, 0x1, 0x9a, + 0xaa, 0xae, 0xba, 0xb0, 0x0, 0x0, 0xd2, 0x22, + 0x2b, 0x52, 0x20, 0x5b, 0x30, 0xd4, 0xaa, 0xa9, + 0x40, 0x50, 0x3, 0xc0, 0xd0, 0x11, 0x17, 0x56, + 0x80, 0x0, 0x0, 0xd3, 0xbb, 0xa6, 0x7b, 0x40, + 0x0, 0x31, 0xd4, 0x60, 0xb3, 0xbd, 0x0, 0x0, + 0xc2, 0xc4, 0x60, 0xb1, 0xf6, 0x0, 0x2, 0xc2, + 0xb4, 0xdb, 0xd2, 0xf0, 0x10, 0x9, 0x66, 0x74, + 0x60, 0x1c, 0xc3, 0x55, 0x1e, 0xc, 0x20, 0x2, + 0xc3, 0x5b, 0x92, 0x26, 0x1a, 0x0, 0x9, 0x30, + 0xa, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+6E21 "渡" */ + 0x0, 0x10, 0x0, 0x0, 0x33, 0x0, 0x0, 0x2, + 0xd8, 0x0, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x8, + 0x3f, 0xbc, 0xcb, 0xbc, 0xb5, 0x0, 0x0, 0x1c, + 0xc, 0x10, 0xd, 0x0, 0xa, 0x30, 0x1d, 0xcf, + 0xcc, 0xcf, 0xc4, 0x3, 0xd7, 0x1c, 0xc, 0x10, + 0xd, 0x0, 0x0, 0x1, 0x2b, 0xc, 0xaa, 0xae, + 0x0, 0x0, 0x0, 0x3a, 0x1, 0x11, 0x11, 0x0, + 0x0, 0x1b, 0x49, 0xbf, 0xcc, 0xce, 0x90, 0x0, + 0x87, 0x67, 0x9, 0x40, 0x1d, 0x10, 0x1, 0xe1, + 0xa3, 0x0, 0xb7, 0xd3, 0x0, 0x8, 0x81, 0xd0, + 0x3, 0xbd, 0xd6, 0x10, 0xa, 0x17, 0x73, 0xda, + 0x30, 0x39, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6E29 "温" */ + 0x3, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xd8, 0xf, 0xcc, 0xcc, 0xdc, 0x0, 0x0, 0x6, + 0xe, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0xf, + 0xcc, 0xcc, 0xcc, 0x0, 0x58, 0x10, 0xe, 0x0, + 0x0, 0x1c, 0x0, 0x6, 0xd3, 0xf, 0xcc, 0xcc, + 0xdc, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0x5b, 0xbb, 0xbb, 0xbb, 0x20, + 0x0, 0x3c, 0x77, 0x3a, 0x1c, 0x1a, 0x30, 0x0, + 0xa5, 0x76, 0x19, 0xb, 0xa, 0x30, 0x2, 0xd0, + 0x76, 0x19, 0xb, 0xa, 0x30, 0xb, 0x50, 0x76, + 0x19, 0xb, 0xa, 0x30, 0x1c, 0x9, 0xee, 0xdf, + 0xdf, 0xdf, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6E2F "港" */ + 0x4, 0x80, 0x0, 0x85, 0x0, 0xc2, 0x0, 0x1, + 0x9c, 0x10, 0x85, 0x0, 0xc2, 0x0, 0x0, 0x6, + 0x7d, 0xfe, 0xdd, 0xfe, 0xd4, 0x0, 0x0, 0x0, + 0x85, 0x0, 0xc2, 0x0, 0x1d, 0x50, 0xaa, 0xdc, + 0xaa, 0xeb, 0xa7, 0x3, 0xc7, 0x33, 0xc6, 0x33, + 0xb8, 0x32, 0x0, 0x0, 0x5, 0xd0, 0x0, 0x3e, + 0x0, 0x0, 0x0, 0x3e, 0xfb, 0xbb, 0xec, 0xc1, + 0x0, 0xc, 0xd3, 0xd0, 0x0, 0x84, 0x79, 0x0, + 0x69, 0x0, 0xec, 0xcc, 0xe4, 0x0, 0x0, 0xd2, + 0x0, 0xd0, 0x0, 0x0, 0x40, 0x7, 0xa0, 0x0, + 0xd0, 0x0, 0x1, 0xc0, 0x9, 0x20, 0x0, 0x9e, + 0xdd, 0xde, 0x60, + + /* U+6E56 "湖" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4c, + 0x60, 0xc, 0x0, 0xad, 0xdf, 0x0, 0x7, 0x0, + 0xc0, 0xa, 0x10, 0xd0, 0x0, 0x2b, 0xbf, 0xb8, + 0xa1, 0xd, 0xa, 0x30, 0x12, 0xd1, 0x1a, 0xdd, + 0xf0, 0x3b, 0x50, 0xc, 0x0, 0xa1, 0xd, 0x0, + 0x0, 0x57, 0xe7, 0x2b, 0x10, 0xd0, 0x0, 0xb, + 0x64, 0xa5, 0xcb, 0xaf, 0x0, 0x4a, 0xb2, 0x8, + 0x5c, 0x22, 0xe0, 0xa, 0x5b, 0x20, 0x85, 0xb0, + 0xd, 0x1, 0xe0, 0xbd, 0xde, 0x89, 0x0, 0xd0, + 0x88, 0xb, 0x20, 0xa, 0x30, 0xd, 0x9, 0x10, + 0x30, 0x2, 0xa0, 0x4c, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+6E90 "源" */ + 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0xb9, 0x1f, 0xdd, 0xdd, 0xdd, 0xd6, 0x0, 0x5, + 0x1e, 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0xe, + 0x3b, 0xce, 0xbb, 0xb0, 0xc, 0x50, 0xe, 0x48, + 0x0, 0x0, 0xd0, 0x1, 0xb7, 0x1d, 0x4d, 0xbb, + 0xbb, 0xe0, 0x0, 0x0, 0x2c, 0x48, 0x0, 0x0, + 0xd0, 0x0, 0x2, 0x3a, 0x4d, 0xaa, 0xaa, 0xe0, + 0x0, 0x2d, 0x49, 0x1, 0x1e, 0x11, 0x10, 0x0, + 0x96, 0x86, 0x1c, 0xe, 0x7, 0x70, 0x1, 0xe0, + 0xc2, 0xa5, 0xe, 0x0, 0xd2, 0x8, 0x84, 0xc2, + 0xb0, 0xe, 0x0, 0x67, 0x7, 0x17, 0x30, 0x5, + 0xcc, 0x0, 0x0, + + /* U+6E96 "準" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa5, 0x1, 0xc0, 0x74, 0x0, 0x0, 0x0, 0x1a, + 0x4a, 0xb6, 0xad, 0x66, 0x40, 0x5, 0x0, 0x6f, + 0x54, 0x8a, 0x44, 0x30, 0x7, 0xd6, 0xde, 0x99, + 0xbc, 0x99, 0x20, 0x0, 0x10, 0xd, 0x11, 0x69, + 0x11, 0x0, 0x0, 0xa, 0x2d, 0xaa, 0xcd, 0xaa, + 0x20, 0x0, 0x98, 0xd, 0x0, 0x58, 0x0, 0x0, + 0x8, 0xa0, 0xd, 0xcc, 0xde, 0xcc, 0xb0, 0x3, + 0x0, 0x6, 0x55, 0x0, 0x0, 0x0, 0xc, 0xcc, + 0xcc, 0xee, 0xcc, 0xcc, 0xc5, 0x1, 0x11, 0x11, + 0x78, 0x11, 0x11, 0x10, 0x0, 0x0, 0x0, 0x68, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0x0, + 0x0, 0x0, + + /* U+6E9D "溝" */ + 0x5, 0x70, 0x0, 0x68, 0x0, 0xe0, 0x0, 0x1, + 0xac, 0x5b, 0xde, 0xbc, 0xfb, 0xb0, 0x0, 0x6, + 0x0, 0x68, 0x0, 0xe0, 0x0, 0x0, 0x0, 0xb, + 0xdd, 0xbb, 0xfb, 0x80, 0x1b, 0x40, 0x33, 0x8a, + 0x33, 0xe3, 0x31, 0x3, 0xc5, 0x77, 0x77, 0xd9, + 0x77, 0x73, 0x0, 0x0, 0x8, 0xbb, 0xec, 0xbb, + 0x40, 0x0, 0x1, 0xb, 0x20, 0xb2, 0x8, 0x50, + 0x0, 0x1d, 0xb, 0xcb, 0xec, 0xbd, 0x50, 0x0, + 0x88, 0xb, 0x20, 0xb2, 0x8, 0x50, 0x1, 0xe2, + 0xcf, 0xdc, 0xdc, 0xce, 0xd6, 0x8, 0x80, 0xb, + 0x20, 0x0, 0x8, 0x50, 0x8, 0x10, 0xb, 0x20, + 0x4, 0xbd, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6EFF "滿" */ + 0x6, 0x10, 0x0, 0xe0, 0x0, 0xd1, 0x0, 0x6, + 0xe3, 0x22, 0xe2, 0x22, 0xd3, 0x20, 0x0, 0x36, + 0xbb, 0xfb, 0xbb, 0xfb, 0xb4, 0x0, 0x0, 0x0, + 0xe0, 0x0, 0xd1, 0x0, 0x23, 0x0, 0x0, 0xbc, + 0xfc, 0xc0, 0x0, 0x2c, 0xa0, 0x12, 0x22, 0xe2, + 0x22, 0x20, 0x0, 0x50, 0xab, 0xaa, 0xfa, 0xaa, + 0xe0, 0x0, 0x0, 0xa2, 0x70, 0xd1, 0x70, 0xd0, + 0x0, 0x38, 0xa1, 0xa1, 0xd0, 0xc1, 0xd0, 0x0, + 0xb2, 0xa3, 0xb8, 0xd4, 0xa7, 0xd0, 0x4, 0xa0, + 0xaa, 0x1a, 0xd9, 0xa, 0xd0, 0xd, 0x20, 0xa2, + 0x0, 0xd0, 0x0, 0xd0, 0x6, 0x0, 0xa1, 0x0, + 0xb0, 0x4b, 0xb0, + + /* U+6F22 "漢" */ + 0x7, 0x50, 0x0, 0xd0, 0x2, 0xb0, 0x0, 0x2, + 0xc9, 0xbc, 0xfc, 0xcc, 0xfc, 0xc1, 0x0, 0x5, + 0x0, 0xd0, 0x2, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0x8a, 0xfa, 0x70, 0x0, 0x5b, 0x20, 0x2a, 0xaa, + 0xfa, 0xaa, 0x30, 0x5, 0xe2, 0x3a, 0x0, 0xe0, + 0x9, 0x40, 0x0, 0x10, 0x3d, 0x99, 0xf9, 0x9d, + 0x40, 0x0, 0x0, 0x1, 0x11, 0xe1, 0x11, 0x0, + 0x0, 0x3a, 0x4b, 0xbc, 0xfb, 0xbb, 0x50, 0x0, + 0xb5, 0x0, 0x3, 0xb0, 0x0, 0x0, 0x2, 0xd0, + 0xbb, 0xbf, 0xde, 0xbb, 0xb1, 0xa, 0x60, 0x0, + 0xaa, 0xa, 0x80, 0x0, 0x1d, 0x0, 0x9d, 0x60, + 0x0, 0x7c, 0xa1, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x0, 0x30, + + /* U+6F38 "漸" */ + 0x5, 0x20, 0x1, 0xb0, 0x0, 0x0, 0x31, 0x3, + 0xd2, 0x2, 0xb0, 0x1, 0x6c, 0xc2, 0x0, 0x36, + 0xbb, 0xeb, 0x97, 0xa2, 0x0, 0x0, 0x0, 0x1, + 0xb0, 0x7, 0x60, 0x0, 0x3, 0x0, 0xda, 0xdb, + 0x87, 0x60, 0x0, 0xa, 0x80, 0xa0, 0x82, 0x87, + 0xdb, 0xe4, 0x0, 0x40, 0xda, 0xdb, 0x87, 0x60, + 0xb0, 0x0, 0x0, 0xa0, 0x82, 0x88, 0x50, 0xb0, + 0x0, 0x55, 0x9b, 0xea, 0x59, 0x40, 0xb0, 0x0, + 0xb1, 0x1, 0xb0, 0xa, 0x20, 0xb0, 0x2, 0xa3, + 0xcc, 0xec, 0xad, 0x0, 0xb0, 0x9, 0x40, 0x1, + 0xb0, 0x4a, 0x0, 0xb0, 0x7, 0x0, 0x1, 0xb0, + 0x53, 0x0, 0xb0, + + /* U+6FC3 "濃" */ + 0x3, 0x70, 0x0, 0xc, 0x0, 0xc0, 0x0, 0x1, + 0xbc, 0x1d, 0xae, 0xaa, 0xea, 0xf0, 0x0, 0x7, + 0xc, 0xc, 0x0, 0xc0, 0xd0, 0x0, 0x0, 0xd, + 0x9e, 0x99, 0xe9, 0xf0, 0x7, 0x10, 0xd, 0x5d, + 0x55, 0xd5, 0xe0, 0x7, 0xd3, 0x4, 0x44, 0x44, + 0x44, 0x40, 0x0, 0x20, 0x2e, 0xbb, 0xbb, 0xbb, + 0xb5, 0x0, 0x0, 0x2a, 0x57, 0x77, 0x77, 0x40, + 0x0, 0xc, 0x3a, 0x22, 0x22, 0x22, 0x10, 0x0, + 0x58, 0x5e, 0xdd, 0xcf, 0xcb, 0xc7, 0x0, 0xd1, + 0x76, 0x56, 0x7, 0x95, 0xb1, 0x6, 0x90, 0xc1, + 0x66, 0x14, 0xac, 0x10, 0x9, 0x15, 0x90, 0xae, + 0xb7, 0x5, 0xd6, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+6FDF "濟" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x10, 0x0, 0x3, 0xb0, 0x0, 0x0, 0x3, 0xc2, + 0x99, 0x99, 0xf9, 0x99, 0x92, 0x0, 0x31, 0x22, + 0x29, 0x3b, 0x32, 0x30, 0x0, 0x0, 0x99, 0x97, + 0x94, 0x8c, 0x40, 0x39, 0x0, 0x47, 0x92, 0xb3, + 0x77, 0x10, 0x6, 0xc0, 0x92, 0x91, 0xb3, 0x63, + 0x80, 0x0, 0x23, 0x75, 0xb0, 0xb5, 0xb5, 0x71, + 0x0, 0x0, 0xe, 0x0, 0x0, 0xd, 0x0, 0x0, + 0xa0, 0xe, 0xcc, 0xcc, 0xcd, 0x0, 0x1, 0xb0, + 0xf, 0x0, 0x0, 0xd, 0x0, 0x8, 0x50, 0x2f, + 0xcc, 0xcc, 0xcd, 0x0, 0xd, 0x0, 0xa7, 0x0, + 0x0, 0xd, 0x0, 0x16, 0x4, 0xa0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+7063 "灣" */ + 0x7, 0x10, 0x52, 0x3, 0x50, 0x7, 0x0, 0x8, + 0xe2, 0x84, 0x48, 0xc7, 0x53, 0x60, 0x0, 0x67, + 0xfc, 0x12, 0x22, 0xdf, 0x30, 0x0, 0x0, 0x63, + 0x28, 0x85, 0x26, 0x40, 0x26, 0x5, 0xb8, 0x77, + 0x85, 0xb8, 0x91, 0x8, 0xb3, 0x44, 0x5d, 0x9a, + 0x55, 0x70, 0x0, 0x19, 0x17, 0x5b, 0x7a, 0x79, + 0x52, 0x0, 0x0, 0x7a, 0xaa, 0xaa, 0xba, 0x10, + 0x0, 0xb2, 0x2, 0x22, 0x22, 0x2d, 0x10, 0x1, + 0xd0, 0x5c, 0x77, 0x77, 0x77, 0x0, 0x7, 0x80, + 0x9c, 0xaa, 0xaa, 0xaa, 0x70, 0xd, 0x20, 0x0, + 0x0, 0x0, 0x8, 0x60, 0x19, 0x0, 0x0, 0x0, + 0x6b, 0xbc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+706B "火" */ + 0x0, 0x0, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x59, 0x0, 0x0, 0x10, 0x0, 0x1e, 0x0, + 0x68, 0x0, 0x6, 0xb0, 0x0, 0x5a, 0x0, 0x87, + 0x0, 0xd, 0x30, 0x0, 0xd3, 0x0, 0xb9, 0x0, + 0x5b, 0x0, 0x5, 0xa0, 0x0, 0xee, 0x0, 0xb2, + 0x0, 0x0, 0x0, 0x3, 0xda, 0x40, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x72, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x6d, 0x0, 0x8a, 0x0, 0x0, 0x0, 0x7, + 0xd2, 0x0, 0xa, 0xc1, 0x0, 0x5, 0xcb, 0x10, + 0x0, 0x0, 0x6e, 0xa3, 0x6, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x62, + + /* U+707D "災" */ + 0x0, 0x9, 0x0, 0x9, 0x10, 0x8, 0x20, 0x0, + 0xa7, 0x0, 0xa7, 0x0, 0x98, 0x0, 0x7, 0xa0, + 0x8, 0xa0, 0x8, 0xa0, 0x0, 0x2, 0xd2, 0x2, + 0xd3, 0x3, 0xd2, 0x0, 0x0, 0x3d, 0x10, 0x2d, + 0x20, 0x2d, 0x20, 0x0, 0x4, 0x10, 0x45, 0x0, + 0x4, 0x30, 0x0, 0x7, 0x0, 0xb7, 0x0, 0x6, + 0x20, 0x0, 0x4b, 0x0, 0xda, 0x0, 0x2d, 0x0, + 0x2, 0xd2, 0x2, 0xed, 0x0, 0xc3, 0x0, 0x5, + 0x30, 0x9, 0x88, 0x81, 0x50, 0x0, 0x0, 0x0, + 0x6d, 0x11, 0xd4, 0x0, 0x0, 0x0, 0x4b, 0xc2, + 0x0, 0x2e, 0x93, 0x0, 0x2e, 0xb5, 0x0, 0x0, + 0x0, 0x7c, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+70B9 "点" */ + 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xde, 0xee, 0xee, 0xa0, 0x0, 0x0, 0x0, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x9a, 0xaa, 0xfb, + 0xaa, 0xa2, 0x0, 0x0, 0xd3, 0x33, 0x33, 0x33, + 0xc3, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xb3, + 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xb3, 0x0, + 0x0, 0xde, 0xdd, 0xdd, 0xdd, 0xe3, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x1, 0xe0, + 0x47, 0x6, 0x60, 0x89, 0x0, 0xa, 0x70, 0x3b, + 0x1, 0xd0, 0xc, 0x70, 0x4b, 0x0, 0x2b, 0x0, + 0xb1, 0x2, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+70BA "為" */ + 0x0, 0x5, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x90, 0x3d, 0x0, 0x0, 0x0, 0x1, 0x12, + 0xb2, 0x98, 0x11, 0x10, 0x0, 0x9, 0xcc, 0xcd, + 0xfc, 0xcc, 0xd0, 0x0, 0x0, 0x0, 0xa, 0x60, + 0x4, 0x90, 0x0, 0x0, 0x0, 0x5f, 0xdd, 0xde, + 0xec, 0x0, 0x0, 0x1, 0xe2, 0x0, 0x0, 0xc, + 0x0, 0x0, 0x2d, 0x70, 0x0, 0x0, 0x4a, 0x0, + 0x4, 0xec, 0xcc, 0xcc, 0xcc, 0xcc, 0xf0, 0x4e, + 0x54, 0x2, 0x4, 0x7, 0x0, 0xe0, 0x1, 0x59, + 0xb, 0xb, 0x16, 0x73, 0xb0, 0x0, 0xc2, 0xc, + 0x6, 0x40, 0x17, 0x80, 0x4, 0x70, 0x4, 0x0, + 0xa, 0xdd, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7121 "無" */ + 0x0, 0x5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, + 0xdf, 0xde, 0xfd, 0xfe, 0xa0, 0x1c, 0xc9, 0xc, + 0x3, 0x90, 0x93, 0x0, 0x5, 0x49, 0xc, 0x3, + 0x90, 0x93, 0x0, 0xb, 0xef, 0xdf, 0xee, 0xfd, + 0xfe, 0xb0, 0x0, 0x49, 0xc, 0x3, 0x90, 0x93, + 0x0, 0x0, 0x49, 0xc, 0x3, 0x90, 0x93, 0x0, + 0x2a, 0xbd, 0xae, 0xab, 0xda, 0xdb, 0xa1, 0x3, + 0x43, 0x33, 0x33, 0x33, 0x34, 0x30, 0x0, 0xd1, + 0xb, 0x1, 0xb0, 0x2d, 0x10, 0x7, 0x90, 0xe, + 0x0, 0xc2, 0x6, 0xb0, 0x1a, 0x0, 0x9, 0x0, + 0x64, 0x0, 0xa2, + + /* U+7136 "然" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x50, 0x0, 0xd, 0x36, 0x0, 0x0, 0x2f, + 0xdc, 0xc0, 0xd, 0xc, 0x30, 0x0, 0x97, 0x1, + 0xb0, 0xd, 0x2, 0x50, 0x5, 0xd6, 0x86, 0x8e, + 0xef, 0xee, 0xd0, 0x2e, 0x30, 0x5f, 0x10, 0xf, + 0x30, 0x0, 0x13, 0x98, 0x68, 0x0, 0x5e, 0xa0, + 0x0, 0x0, 0x9, 0xd0, 0x0, 0xc3, 0xd1, 0x0, + 0x0, 0x5d, 0x10, 0x9, 0x90, 0x5b, 0x0, 0xb, + 0xa1, 0x1, 0xba, 0x0, 0x8, 0xc0, 0x2, 0x0, + 0x0, 0x50, 0x0, 0x0, 0x30, 0x0, 0xd1, 0xa, + 0x3, 0x90, 0x4c, 0x0, 0x8, 0x70, 0xe, 0x0, + 0xd0, 0x9, 0x80, 0x2a, 0x0, 0xa, 0x0, 0x72, + 0x0, 0xb0, + + /* U+7159 "煙" */ + 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x6d, 0xdf, 0xde, 0xed, 0xd0, 0x0, 0xc0, + 0x0, 0xd, 0x6, 0x70, 0x0, 0x8, 0xc4, 0x9c, + 0xcf, 0xce, 0xec, 0x90, 0x28, 0xc8, 0x4a, 0xc, + 0x6, 0x61, 0xb0, 0x65, 0xc7, 0x2a, 0xc, 0x6, + 0x61, 0xb0, 0x50, 0xd0, 0x2e, 0xcf, 0xce, 0xed, + 0xb0, 0x0, 0xd0, 0x0, 0x0, 0x31, 0x0, 0x0, + 0x0, 0xe0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x2, + 0xe6, 0xc, 0xcc, 0xed, 0xcc, 0x70, 0x7, 0x6c, + 0x10, 0x0, 0xa4, 0x0, 0x0, 0xd, 0x15, 0x30, + 0x0, 0xa4, 0x0, 0x0, 0x77, 0x0, 0xcd, 0xdd, + 0xfd, 0xdd, 0xd2, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+71B1 "熱" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x7, 0x50, 0x0, 0xd, 0x0, 0x0, 0x6, 0xbd, + 0xcb, 0x50, 0xd, 0x0, 0x0, 0x0, 0x7, 0x50, + 0x8, 0xbf, 0xbb, 0x0, 0x1b, 0xbc, 0xcb, 0xa1, + 0x3c, 0x2d, 0x0, 0x1, 0xa1, 0x18, 0x16, 0x5a, + 0xd, 0x0, 0x19, 0x15, 0x32, 0x92, 0xcb, 0xd, + 0x0, 0x8, 0xbd, 0xcb, 0x60, 0xaa, 0xac, 0x0, + 0x0, 0x8, 0x60, 0x1, 0xd0, 0x2b, 0x46, 0x1, + 0x3a, 0xa8, 0xab, 0x60, 0x7, 0x85, 0x2b, 0x98, + 0x64, 0x68, 0x0, 0x1, 0xb1, 0x0, 0x61, 0x4, + 0x0, 0x50, 0x18, 0x0, 0x3, 0xc0, 0x1d, 0x0, + 0xe2, 0xb, 0x70, 0xd, 0x20, 0xe, 0x0, 0x95, + 0x1, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+71DF "營" */ + 0x0, 0x17, 0x51, 0x1, 0xa, 0x20, 0x20, 0x9, + 0x49, 0x2a, 0x4b, 0x1d, 0x8, 0x80, 0x6, 0x1f, + 0x63, 0x24, 0x5f, 0x66, 0x0, 0x16, 0xd4, 0x9a, + 0x39, 0xc2, 0x9c, 0x40, 0x1b, 0x64, 0x48, 0x79, + 0x54, 0x47, 0xc0, 0xe, 0x77, 0x77, 0x77, 0x77, + 0x78, 0xd0, 0xe, 0x9, 0xaa, 0xaa, 0xaa, 0x61, + 0xd0, 0x4, 0xd, 0x0, 0x0, 0x5, 0xa0, 0x40, + 0x0, 0xd, 0xaa, 0xaa, 0xac, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcc, + 0xbb, 0xbb, 0xbb, 0xcf, 0x0, 0x0, 0xc1, 0x0, + 0x0, 0x0, 0x1f, 0x0, 0x0, 0xcc, 0xbb, 0xbb, + 0xbb, 0xcf, 0x0, + + /* U+722D "爭" */ + 0x0, 0x0, 0x12, 0x34, 0x67, 0xab, 0x10, 0x4, + 0xcb, 0xa9, 0xa7, 0x64, 0x36, 0x0, 0x0, 0x1c, + 0x0, 0xb4, 0x0, 0x99, 0x0, 0x0, 0x8, 0x40, + 0x47, 0x4, 0xc0, 0x0, 0x0, 0xac, 0xcc, 0xcc, + 0xcc, 0xda, 0x0, 0x0, 0x0, 0x0, 0x78, 0x0, + 0x1d, 0x0, 0x1, 0x11, 0x11, 0x89, 0x11, 0x2d, + 0x11, 0x2b, 0xbb, 0xbb, 0xdd, 0xbb, 0xbf, 0xb7, + 0x0, 0x0, 0x0, 0x78, 0x0, 0x1d, 0x0, 0x0, + 0xcc, 0xcc, 0xde, 0xcc, 0xcc, 0x0, 0x0, 0x0, + 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x78, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdd, 0xd4, + 0x0, 0x0, 0x0, + + /* U+7236 "父" */ + 0x0, 0x0, 0x52, 0x0, 0x25, 0x0, 0x0, 0x0, + 0x4, 0xe1, 0x0, 0x1d, 0x50, 0x0, 0x0, 0x1e, + 0x40, 0x0, 0x1, 0xd6, 0x0, 0x2, 0xd7, 0x0, + 0x0, 0x0, 0x2e, 0x40, 0xd, 0x62, 0x60, 0x0, + 0x7, 0x43, 0xe0, 0x1, 0x0, 0xe1, 0x0, 0x1e, + 0x10, 0x10, 0x0, 0x0, 0x79, 0x0, 0x89, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x43, 0xe1, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xed, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xef, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x7e, 0x54, 0xe9, 0x0, 0x0, 0x2, 0x8e, 0xb1, + 0x0, 0x1a, 0xe9, 0x40, 0x3f, 0x92, 0x0, 0x0, + 0x0, 0x28, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7238 "爸" */ + 0x0, 0x0, 0x97, 0x0, 0x1b, 0x40, 0x0, 0x0, + 0x1b, 0xd0, 0x0, 0x3, 0xfa, 0x10, 0x7, 0xd5, + 0x8c, 0x20, 0x5e, 0x56, 0xe2, 0x2, 0x10, 0x3, + 0xdc, 0xc1, 0x0, 0x20, 0x0, 0x0, 0x6c, 0xb7, + 0xca, 0x40, 0x0, 0x18, 0xcd, 0x82, 0x0, 0x3, + 0x9d, 0xb6, 0x6, 0x4c, 0xcc, 0xcc, 0xcc, 0xcc, + 0x32, 0x0, 0x2c, 0x0, 0xe, 0x0, 0xd, 0x0, + 0x0, 0x2c, 0x0, 0xe, 0x0, 0xd, 0x0, 0x0, + 0x2f, 0xcc, 0xcd, 0xcc, 0xcd, 0x0, 0x0, 0x2c, + 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x1d, 0x0, + 0x0, 0x0, 0x0, 0x69, 0x0, 0x9, 0xdd, 0xdd, + 0xdd, 0xdd, 0xd2, + + /* U+7247 "片" */ + 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x3, + 0xb0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x3b, 0x0, + 0x1, 0xe0, 0x0, 0x0, 0x3, 0xc0, 0x0, 0x1e, + 0x0, 0x0, 0x0, 0x3f, 0xee, 0xee, 0xee, 0xee, + 0xc0, 0x3, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xfe, + 0xee, 0xee, 0xe9, 0x0, 0x0, 0x78, 0x0, 0x0, + 0x5, 0xa0, 0x0, 0xb, 0x40, 0x0, 0x0, 0x4a, + 0x0, 0x1, 0xe0, 0x0, 0x0, 0x4, 0xa0, 0x0, + 0xa8, 0x0, 0x0, 0x0, 0x4a, 0x0, 0xb, 0x0, + 0x0, 0x0, 0x4, 0xa0, 0x0, + + /* U+725B "牛" */ + 0x0, 0x4, 0x20, 0x2d, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x30, 0x2d, 0x0, 0x0, 0x0, 0x0, 0x3e, + 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0xae, 0xee, + 0xef, 0xee, 0xee, 0x90, 0x4, 0xd0, 0x0, 0x2d, + 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x2d, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x0, 0x0, + 0x0, 0x1e, 0xee, 0xee, 0xef, 0xee, 0xee, 0xe6, + 0x0, 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, + 0x0, 0x0, 0x0, + + /* U+7260 "牠" */ + 0x0, 0xd, 0x0, 0x0, 0xd, 0x0, 0x0, 0xa, + 0x1d, 0x0, 0x30, 0xd, 0x0, 0x0, 0xc, 0xd, + 0x0, 0xa2, 0xd, 0x0, 0x20, 0xf, 0xef, 0xe3, + 0xa2, 0xd, 0x8d, 0xf0, 0x39, 0xd, 0x0, 0xb9, + 0xcf, 0x60, 0xd0, 0x54, 0xd, 0xb, 0xf7, 0x1d, + 0x0, 0xd0, 0x0, 0xe, 0x66, 0xa2, 0xd, 0x0, + 0xd0, 0x28, 0xcf, 0x71, 0xa2, 0xd, 0x0, 0xd0, + 0x25, 0x1d, 0x0, 0xa2, 0xd, 0x3b, 0x90, 0x0, + 0xd, 0x0, 0xa2, 0x9, 0x1, 0x0, 0x0, 0xd, + 0x0, 0xa2, 0x0, 0x0, 0x55, 0x0, 0xd, 0x0, + 0xa3, 0x0, 0x0, 0x85, 0x0, 0xd, 0x0, 0x5d, + 0xcc, 0xcd, 0xc0, + + /* U+7269 "物" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0xa, 0x30, 0x0, 0x0, 0xb, 0x2d, + 0x0, 0xe, 0x0, 0x0, 0x0, 0xd, 0xd, 0x0, + 0x4e, 0x77, 0x77, 0x71, 0xf, 0xef, 0xe7, 0xb8, + 0xba, 0xab, 0xd3, 0x3a, 0xd, 0x5, 0xb0, 0xc1, + 0x94, 0xb2, 0x75, 0xd, 0xc, 0x23, 0xa0, 0xc0, + 0xc1, 0x0, 0xd, 0x14, 0x9, 0x42, 0xb0, 0xe0, + 0x3, 0x8f, 0xc6, 0x3c, 0x8, 0x50, 0xe0, 0x5b, + 0x6e, 0x1, 0xd3, 0xd, 0x0, 0xd0, 0x0, 0xd, + 0x7, 0x60, 0x87, 0x2, 0xc0, 0x0, 0xd, 0x0, + 0x2, 0xd0, 0x5, 0x90, 0x0, 0xd, 0x0, 0x2d, + 0x30, 0xa, 0x60, 0x0, 0xd, 0x0, 0x85, 0x9, + 0xec, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+7279 "特" */ + 0x0, 0xd, 0x0, 0x0, 0x3b, 0x0, 0x0, 0x5, + 0x1e, 0x0, 0x0, 0x3b, 0x0, 0x0, 0xb, 0x1e, + 0x0, 0xdd, 0xef, 0xdd, 0x70, 0xd, 0xaf, 0xa0, + 0x0, 0x3b, 0x0, 0x0, 0xd, 0x4e, 0x42, 0x33, + 0x5c, 0x33, 0x30, 0x49, 0xe, 0x8, 0xaa, 0xaa, + 0xdd, 0xa1, 0x12, 0xe, 0x0, 0x0, 0x0, 0x76, + 0x0, 0x1, 0x5f, 0xd9, 0xdd, 0xdd, 0xee, 0xd1, + 0x3e, 0x9e, 0x0, 0x41, 0x0, 0x76, 0x0, 0x0, + 0xe, 0x0, 0x4c, 0x0, 0x76, 0x0, 0x0, 0xe, + 0x0, 0x8, 0x70, 0x76, 0x0, 0x0, 0xe, 0x0, + 0x0, 0x0, 0x76, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x7e, 0xe3, 0x0, + + /* U+72AC "犬" */ + 0x0, 0x0, 0x0, 0x87, 0x6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x86, 0x8, 0xc1, 0x0, 0x0, 0x0, + 0x0, 0x96, 0x0, 0x5d, 0x10, 0x0, 0x0, 0x0, + 0xa5, 0x0, 0x2, 0x0, 0x3c, 0xcc, 0xcc, 0xfd, + 0xcc, 0xcc, 0xc3, 0x1, 0x11, 0x12, 0xfe, 0x21, + 0x11, 0x10, 0x0, 0x0, 0x3, 0xdb, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x84, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0x10, 0xc5, 0x0, 0x0, 0x0, + 0x0, 0xc7, 0x0, 0x3e, 0x20, 0x0, 0x0, 0x1c, + 0x90, 0x0, 0x6, 0xe2, 0x0, 0x6, 0xe8, 0x0, + 0x0, 0x0, 0x6f, 0x81, 0x1a, 0x20, 0x0, 0x0, + 0x0, 0x2, 0xa2, + + /* U+72AF "犯" */ + 0x9, 0x10, 0x66, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xd5, 0xe1, 0x3d, 0xdd, 0xdd, 0xa0, 0x0, 0x7f, + 0x30, 0x3b, 0x0, 0x2, 0xc0, 0x4, 0xed, 0x20, + 0x3a, 0x0, 0x2, 0xc0, 0x3d, 0x27, 0x80, 0x3a, + 0x0, 0x2, 0xc0, 0x1, 0x3, 0xc0, 0x3a, 0x0, + 0x2, 0xc0, 0x0, 0xc, 0xd0, 0x3a, 0x1, 0x14, + 0xc0, 0x0, 0x9a, 0xe0, 0x3a, 0x7, 0xdc, 0x50, + 0xa, 0xb0, 0xe0, 0x3a, 0x0, 0x0, 0x0, 0x48, + 0x0, 0xd0, 0x3a, 0x0, 0x0, 0x0, 0x0, 0x2, + 0xc0, 0x3a, 0x0, 0x0, 0x3a, 0x0, 0x7, 0x90, + 0x3d, 0x10, 0x0, 0x78, 0xb, 0xdc, 0x10, 0xa, + 0xee, 0xee, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+72B6 "状" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x30, 0x0, 0xe0, 0x40, 0x0, 0x0, 0xa, + 0x30, 0x0, 0xe0, 0x6a, 0x0, 0x3b, 0xa, 0x30, + 0x0, 0xe0, 0xb, 0x50, 0x9, 0x7a, 0x30, 0x0, + 0xe0, 0x1, 0x10, 0x0, 0xab, 0x7c, 0xcc, 0xfc, + 0xcc, 0xc0, 0x0, 0xa, 0x42, 0x23, 0xf5, 0x22, + 0x20, 0x0, 0xd, 0x30, 0x3, 0xf8, 0x0, 0x0, + 0x0, 0xce, 0x30, 0x7, 0x9c, 0x0, 0x0, 0x1d, + 0x6a, 0x30, 0xc, 0x3b, 0x40, 0x0, 0x85, 0xa, + 0x30, 0x4c, 0x4, 0xb0, 0x0, 0x0, 0xa, 0x30, + 0xd4, 0x0, 0xb7, 0x0, 0x0, 0xa, 0x4c, 0x80, + 0x0, 0x1e, 0x70, 0x0, 0xa, 0x99, 0x0, 0x0, + 0x2, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+72C0 "狀" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe0, 0x0, 0x3a, 0x0, 0x0, 0xd, 0x0, + 0xe0, 0x0, 0x3a, 0x3c, 0x10, 0xd, 0x0, 0xe0, + 0x0, 0x3a, 0x5, 0xb0, 0xd, 0x0, 0xe0, 0x0, + 0x3a, 0x0, 0x40, 0xd, 0xdd, 0xf6, 0xcc, 0xde, + 0xcc, 0xc6, 0x0, 0x0, 0xe1, 0x22, 0x6f, 0x22, + 0x21, 0x0, 0x0, 0xe0, 0x0, 0x6f, 0x20, 0x0, + 0x5d, 0xdd, 0xf0, 0x0, 0xad, 0x60, 0x0, 0x5, + 0x80, 0xe0, 0x0, 0xe5, 0xb0, 0x0, 0x7, 0x60, + 0xe0, 0x7, 0xa0, 0xd3, 0x0, 0x9, 0x40, 0xe0, + 0x2e, 0x20, 0x5c, 0x0, 0x1d, 0x0, 0xe3, 0xe5, + 0x0, 0xa, 0xc1, 0x34, 0x0, 0xeb, 0x50, 0x0, + 0x0, 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+72EC "独" */ + 0x17, 0x2, 0x50, 0x0, 0xc2, 0x0, 0x0, 0xa, + 0x5b, 0x40, 0x0, 0xc2, 0x0, 0x0, 0x0, 0xea, + 0x0, 0x0, 0xc2, 0x0, 0x0, 0x6, 0xf7, 0xd, + 0xdd, 0xfd, 0xdd, 0xa0, 0x4b, 0x2c, 0xe, 0x0, + 0xc2, 0x3, 0xb0, 0x0, 0xd, 0x1e, 0x0, 0xc2, + 0x3, 0xb0, 0x0, 0x5f, 0x2e, 0x0, 0xc2, 0x3, + 0xb0, 0x2, 0xdc, 0x3e, 0xdd, 0xfd, 0xdd, 0xb0, + 0x3e, 0x3b, 0x30, 0x0, 0xc2, 0x4, 0x0, 0x23, + 0xb, 0x20, 0x0, 0xc2, 0xe, 0x30, 0x0, 0xd, + 0x10, 0x0, 0xc2, 0x7, 0xa0, 0x0, 0x1e, 0x37, + 0x9b, 0xfe, 0xfd, 0xe1, 0xd, 0xe6, 0x37, 0x64, + 0x21, 0x0, 0x85, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+72ED "狭" */ + 0x9, 0x10, 0xb1, 0x0, 0x1e, 0x0, 0x0, 0x5, + 0xc9, 0x80, 0x0, 0x1e, 0x0, 0x0, 0x0, 0xad, + 0x4, 0xee, 0xef, 0xee, 0xe4, 0x6, 0xdd, 0x0, + 0x40, 0x1e, 0x0, 0x50, 0x1b, 0x1a, 0x40, 0xa4, + 0x1e, 0x6, 0x90, 0x0, 0x7, 0x80, 0x4a, 0x1d, + 0xc, 0x20, 0x0, 0x1e, 0x90, 0x7, 0x2c, 0x7, + 0x0, 0x0, 0xc8, 0xab, 0xee, 0xff, 0xee, 0xe8, + 0x1c, 0x74, 0xa0, 0x0, 0x9f, 0x30, 0x0, 0x15, + 0x4, 0x90, 0x1, 0xe3, 0xb0, 0x0, 0x0, 0x6, + 0x80, 0x1c, 0x50, 0x88, 0x0, 0x0, 0xa, 0x54, + 0xd7, 0x0, 0xc, 0x91, 0xa, 0xdb, 0x4c, 0x30, + 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+732B "猫" */ + 0x5, 0x10, 0x60, 0xe, 0x0, 0x3a, 0x0, 0x4, + 0xc7, 0x90, 0xe, 0x0, 0x3a, 0x0, 0x0, 0x9e, + 0xd, 0xdf, 0xdd, 0xef, 0xd8, 0x6, 0xdd, 0x0, + 0xe, 0x0, 0x3a, 0x0, 0x1a, 0x1a, 0x40, 0xb, + 0x0, 0x28, 0x0, 0x0, 0x7, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1e, 0x94, 0xec, 0xcf, 0xcc, + 0xf1, 0x1, 0xc9, 0xa4, 0x80, 0x1d, 0x0, 0xc1, + 0xd, 0x74, 0xa4, 0xda, 0xaf, 0xaa, 0xe1, 0x2, + 0x4, 0x94, 0xa3, 0x4d, 0x33, 0xd1, 0x0, 0x6, + 0x84, 0x80, 0x1d, 0x0, 0xc1, 0x0, 0x1a, 0x44, + 0xdb, 0xbf, 0xbb, 0xe1, 0x6, 0xc9, 0x4, 0x91, + 0x11, 0x11, 0xc1, + + /* U+733F "猿" */ + 0x28, 0x4, 0x70, 0x0, 0xc2, 0x0, 0x0, 0xa, + 0x8d, 0x28, 0xcc, 0xfd, 0xcc, 0x30, 0x0, 0xf7, + 0x0, 0x0, 0xc2, 0x0, 0x0, 0xa, 0xd8, 0x4b, + 0xbb, 0xfc, 0xbb, 0xa0, 0x58, 0x1d, 0x1, 0x11, + 0x11, 0x11, 0x10, 0x0, 0xe, 0x18, 0xcb, 0xbb, + 0xbd, 0x20, 0x0, 0x6f, 0x29, 0x40, 0x0, 0xb, + 0x20, 0x4, 0xcb, 0x39, 0xcb, 0xbb, 0xbe, 0x20, + 0x4d, 0x2b, 0x30, 0x1b, 0xb8, 0x2, 0x60, 0x22, + 0xb, 0x49, 0xf5, 0xb, 0x7c, 0x30, 0x0, 0xc, + 0x55, 0xa2, 0x3, 0xe0, 0x0, 0x0, 0x1d, 0x0, + 0xb7, 0x82, 0x8c, 0x20, 0xd, 0xd6, 0x1, 0xe9, + 0x40, 0x5, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7372 "獲" */ + 0x6, 0x3, 0x40, 0xb, 0x0, 0xf0, 0x0, 0xa, + 0x8d, 0x3b, 0xbe, 0xbb, 0xfc, 0xb3, 0x0, 0xe7, + 0x0, 0x4a, 0x53, 0xb0, 0x0, 0x8, 0xf8, 0x1, + 0xe1, 0x2d, 0x0, 0x0, 0x6c, 0x2d, 0xb, 0xe9, + 0x9f, 0x99, 0x90, 0x10, 0xe, 0x59, 0xe7, 0x7e, + 0x77, 0x40, 0x0, 0x6f, 0x20, 0xe9, 0x9e, 0x99, + 0x50, 0x3, 0xca, 0x30, 0xd2, 0x2d, 0x22, 0x20, + 0x3d, 0x2a, 0x30, 0xc7, 0x77, 0x77, 0x70, 0x23, + 0xb, 0x28, 0xcb, 0xbb, 0xbc, 0x80, 0x0, 0xc, + 0x10, 0xa9, 0x0, 0x7c, 0x10, 0x0, 0xd, 0x0, + 0x9, 0xee, 0xa0, 0x0, 0xd, 0xe6, 0x3b, 0xc9, + 0x55, 0x9c, 0xc4, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x10, + + /* U+73A9 "玩" */ + 0x1c, 0xcc, 0xc7, 0xbe, 0xee, 0xee, 0xc0, 0x1, + 0x4b, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa, 0xde, 0xc9, 0xee, + 0xee, 0xee, 0xe8, 0x1, 0x4b, 0x10, 0xa, 0x40, + 0xe0, 0x0, 0x0, 0x3a, 0x0, 0xb, 0x20, 0xe0, + 0x0, 0x0, 0x3a, 0x0, 0xd, 0x10, 0xe0, 0x0, + 0x0, 0x4d, 0x9a, 0x1d, 0x0, 0xe0, 0x0, 0x2c, + 0xe9, 0x40, 0x97, 0x0, 0xe0, 0x8, 0x3, 0x0, + 0x6, 0xd0, 0x0, 0xe0, 0x2b, 0x0, 0x0, 0x8a, + 0x10, 0x0, 0xae, 0xe6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+73FE "現" */ + 0x0, 0x0, 0x0, 0x1, 0x11, 0x11, 0x10, 0x1d, + 0xef, 0xd9, 0x9c, 0xbb, 0xbb, 0xe0, 0x0, 0x1c, + 0x0, 0x94, 0x0, 0x0, 0xe0, 0x0, 0x1c, 0x0, + 0x9d, 0xcc, 0xcc, 0xe0, 0x2, 0x4d, 0x31, 0x94, + 0x0, 0x0, 0xe0, 0x8, 0xae, 0x95, 0x9d, 0xbb, + 0xbb, 0xe0, 0x0, 0x1c, 0x0, 0x94, 0x0, 0x0, + 0xe0, 0x0, 0x1c, 0x0, 0x94, 0x0, 0x0, 0xe0, + 0x0, 0x1c, 0x2, 0x7d, 0xec, 0xfc, 0xb0, 0x2, + 0x6f, 0xd9, 0x7, 0x60, 0xe0, 0x0, 0x2c, 0x73, + 0x0, 0xd, 0x20, 0xe0, 0x2, 0x0, 0x0, 0x1, + 0xb8, 0x0, 0xe0, 0xc, 0x0, 0x0, 0x6d, 0x60, + 0x0, 0xad, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7403 "球" */ + 0x0, 0x0, 0x0, 0x0, 0xe, 0x27, 0x0, 0x4d, + 0xdd, 0xc0, 0x0, 0xe, 0xa, 0x70, 0x13, 0xb6, + 0x30, 0x0, 0xe, 0x1, 0x50, 0x0, 0x94, 0x9, + 0xcc, 0xdf, 0xcc, 0xc7, 0x0, 0x94, 0x1, 0x30, + 0xf, 0x0, 0x51, 0x3d, 0xfe, 0xa1, 0xd1, 0xf, + 0x33, 0xc0, 0x0, 0x94, 0x0, 0x5b, 0xf, 0x8c, + 0x20, 0x0, 0x94, 0x0, 0x3, 0x6f, 0xf3, 0x0, + 0x0, 0x94, 0x0, 0x8, 0xae, 0x95, 0x0, 0x0, + 0x98, 0xa2, 0xa9, 0xe, 0x1d, 0x10, 0x3b, 0xe9, + 0x5c, 0x80, 0xe, 0x5, 0xd2, 0x23, 0x0, 0x4, + 0x0, 0xe, 0x0, 0x49, 0x0, 0x0, 0x0, 0x1d, + 0xe9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7406 "理" */ + 0x4d, 0xdd, 0xd4, 0xfd, 0xdf, 0xdd, 0xe0, 0x0, + 0x85, 0x4, 0xa0, 0xd, 0x0, 0xe0, 0x0, 0x85, + 0x4, 0xb2, 0x2d, 0x22, 0xe0, 0x0, 0x85, 0x4, + 0xd9, 0x9e, 0x99, 0xe0, 0x1a, 0xdc, 0x84, 0xa0, + 0xd, 0x0, 0xe0, 0x0, 0x96, 0x4, 0xec, 0xcf, + 0xcc, 0xe0, 0x0, 0x85, 0x0, 0x0, 0xe, 0x0, + 0x0, 0x0, 0x85, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x0, 0x87, 0x76, 0xdd, 0xdf, 0xdd, 0xd1, 0x17, + 0xed, 0x80, 0x0, 0xe, 0x0, 0x0, 0x49, 0x30, + 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x7d, + 0xdd, 0xdd, 0xdd, 0xd7, + + /* U+74B0 "環" */ + 0x58, 0x88, 0x1d, 0xae, 0xae, 0xac, 0x60, 0x25, + 0xc3, 0xc, 0xa, 0xa, 0x6, 0x60, 0x1, 0xb0, + 0x9, 0xbb, 0xbb, 0xbb, 0x40, 0x1, 0xb0, 0x38, + 0x88, 0x88, 0x88, 0x80, 0x5b, 0xea, 0x13, 0x33, + 0x33, 0x33, 0x30, 0x14, 0xc2, 0x7, 0xdb, 0xbb, + 0xbf, 0x0, 0x1, 0xb0, 0x7, 0x50, 0x0, 0xd, + 0x0, 0x1, 0xb0, 0x6, 0xcc, 0xdc, 0xbe, 0x0, + 0x1, 0xb4, 0x0, 0x6b, 0x38, 0x7, 0x50, 0x5b, + 0xe9, 0x8c, 0xd0, 0x4, 0xd6, 0x0, 0x43, 0x0, + 0x20, 0xc3, 0x65, 0x99, 0x10, 0x0, 0x0, 0x2, + 0xd9, 0x51, 0x6, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+7518 "甘" */ + 0x0, 0x7, 0x80, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x7, 0x80, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x7, + 0x80, 0x0, 0x1, 0xe0, 0x0, 0x1e, 0xef, 0xfe, + 0xee, 0xee, 0xfe, 0xe7, 0x0, 0x7, 0x80, 0x0, + 0x1, 0xe0, 0x0, 0x0, 0x7, 0x80, 0x0, 0x1, + 0xe0, 0x0, 0x0, 0x7, 0x80, 0x0, 0x1, 0xe0, + 0x0, 0x0, 0x7, 0xfe, 0xee, 0xee, 0xe0, 0x0, + 0x0, 0x7, 0x80, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x7, 0x80, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x7, + 0x80, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x7, 0xfe, + 0xee, 0xee, 0xe0, 0x0, 0x0, 0x7, 0x80, 0x0, + 0x1, 0xd0, 0x0, + + /* U+751A "甚" */ + 0x0, 0x5, 0x80, 0x0, 0x3, 0xa0, 0x0, 0x0, + 0x6, 0x80, 0x0, 0x4, 0xb0, 0x0, 0x9, 0xcd, + 0xec, 0xcc, 0xcd, 0xec, 0xc0, 0x0, 0x5, 0xa4, + 0x44, 0x47, 0xa0, 0x0, 0x0, 0x5, 0xb5, 0x55, + 0x58, 0xa0, 0x0, 0x0, 0x5, 0xd9, 0x99, 0x9b, + 0xa0, 0x0, 0x0, 0x5, 0x91, 0x11, 0x15, 0xa0, + 0x0, 0x2, 0x27, 0xa2, 0x22, 0x26, 0xb2, 0x21, + 0xa, 0xcd, 0xaa, 0xaa, 0xaa, 0xaa, 0xa5, 0x0, + 0x68, 0x2, 0xc0, 0x4c, 0x10, 0x0, 0x0, 0x68, + 0x1c, 0x20, 0x4, 0xc1, 0x0, 0x0, 0x68, 0x55, + 0x0, 0x0, 0x52, 0x0, 0x0, 0x4b, 0xbb, 0xbb, + 0xbb, 0xbb, 0x30, + + /* U+751F "生" */ + 0x0, 0x7, 0x20, 0x78, 0x0, 0x0, 0x0, 0x0, + 0xf, 0x10, 0x78, 0x0, 0x0, 0x0, 0x0, 0x6b, + 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xee, + 0xff, 0xee, 0xee, 0x80, 0x6, 0xc0, 0x0, 0x78, + 0x0, 0x0, 0x0, 0xe, 0x20, 0x0, 0x78, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x78, 0x0, 0x0, + 0x0, 0x0, 0xae, 0xee, 0xff, 0xee, 0xee, 0x10, + 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x78, 0x0, 0x0, 0x0, 0x1, 0x11, 0x11, + 0x88, 0x11, 0x11, 0x10, 0x2d, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xd3, + + /* U+7522 "產" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x0, 0x9a, + 0xaa, 0xaf, 0xaa, 0xaa, 0xa0, 0x0, 0x24, 0xd9, + 0x52, 0x3a, 0xb2, 0x20, 0x0, 0x0, 0x5, 0xde, + 0xf8, 0x0, 0x0, 0x0, 0x5, 0xba, 0x51, 0x39, + 0xc4, 0x0, 0x0, 0xed, 0xcc, 0xcc, 0xcc, 0xdd, + 0xc5, 0x0, 0xe0, 0x52, 0x4, 0x50, 0x0, 0x0, + 0x0, 0xe0, 0xec, 0xcd, 0xec, 0xcc, 0x70, 0x0, + 0xda, 0x30, 0x5, 0x80, 0x0, 0x0, 0x2, 0xc4, + 0x8b, 0xbd, 0xdb, 0xbb, 0x10, 0x4, 0xa0, 0x0, + 0x6, 0x80, 0x0, 0x0, 0x9, 0x60, 0x0, 0x5, + 0x80, 0x0, 0x0, 0x1e, 0x1a, 0xcc, 0xcc, 0xcc, + 0xcc, 0xc8, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+7523 "産" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x11, 0x11, 0x7a, 0x11, 0x11, 0x10, 0x2, 0xbb, + 0xdb, 0xbb, 0xbc, 0xbb, 0x80, 0x0, 0x0, 0x87, + 0x0, 0xc, 0x40, 0x0, 0x0, 0xaa, 0xae, 0xaa, + 0xbe, 0xaa, 0xa2, 0x0, 0xe2, 0x33, 0x23, 0x32, + 0x22, 0x20, 0x0, 0xd0, 0x68, 0x7, 0x60, 0x0, + 0x0, 0x0, 0xc1, 0xdc, 0xce, 0xdc, 0xcc, 0x20, + 0x2, 0xb9, 0x50, 0x7, 0x60, 0x0, 0x0, 0x3, + 0xa0, 0x8c, 0xce, 0xdc, 0xc9, 0x0, 0x6, 0x70, + 0x0, 0x7, 0x60, 0x0, 0x0, 0xb, 0x30, 0x0, + 0x7, 0x60, 0x0, 0x0, 0x2d, 0xb, 0xdd, 0xde, + 0xed, 0xdd, 0xd3, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7528 "用" */ + 0x0, 0xce, 0xee, 0xee, 0xee, 0xee, 0x20, 0xd, + 0x10, 0x3, 0xb0, 0x0, 0xc2, 0x0, 0xd1, 0x0, + 0x3b, 0x0, 0xc, 0x20, 0xd, 0xba, 0xac, 0xea, + 0xaa, 0xe2, 0x0, 0xd4, 0x33, 0x5c, 0x33, 0x3d, + 0x20, 0xd, 0x10, 0x3, 0xb0, 0x0, 0xc2, 0x0, + 0xf0, 0x0, 0x3b, 0x0, 0xc, 0x20, 0xf, 0xdd, + 0xde, 0xfd, 0xdd, 0xf2, 0x2, 0xc0, 0x0, 0x3b, + 0x0, 0xc, 0x20, 0x68, 0x0, 0x3, 0xb0, 0x0, + 0xc2, 0xd, 0x30, 0x0, 0x3b, 0x0, 0xc, 0x25, + 0x90, 0x0, 0x3, 0xb0, 0xcd, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7530 "田" */ + 0xce, 0xee, 0xee, 0xee, 0xee, 0xe3, 0xd1, 0x0, + 0xd, 0x10, 0x0, 0xb3, 0xd1, 0x0, 0xd, 0x10, + 0x0, 0xb3, 0xd1, 0x0, 0xd, 0x10, 0x0, 0xb3, + 0xd1, 0x0, 0xd, 0x10, 0x0, 0xb3, 0xdf, 0xee, + 0xef, 0xfe, 0xee, 0xf3, 0xd1, 0x0, 0xd, 0x10, + 0x0, 0xb3, 0xd1, 0x0, 0xd, 0x10, 0x0, 0xb3, + 0xd1, 0x0, 0xd, 0x10, 0x0, 0xb3, 0xd1, 0x0, + 0xd, 0x10, 0x0, 0xb3, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xf3, 0xd1, 0x0, 0x0, 0x0, 0x0, 0xb3, + + /* U+7531 "由" */ + 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xe0, + 0x0, 0x0, 0x2f, 0xee, 0xef, 0xfe, 0xee, 0xff, + 0x2c, 0x0, 0x1, 0xe0, 0x0, 0xf, 0x2c, 0x0, + 0x1, 0xe0, 0x0, 0xf, 0x2c, 0x0, 0x1, 0xe0, + 0x0, 0xf, 0x2f, 0xee, 0xee, 0xfe, 0xee, 0xef, + 0x2c, 0x0, 0x1, 0xe0, 0x0, 0xf, 0x2c, 0x0, + 0x1, 0xe0, 0x0, 0xf, 0x2c, 0x0, 0x1, 0xe0, + 0x0, 0xf, 0x2f, 0xee, 0xef, 0xfe, 0xee, 0xff, + 0x2c, 0x0, 0x0, 0x0, 0x0, 0xe, + + /* U+7533 "申" */ + 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0x0, 0x2e, 0xee, 0xee, 0xfe, + 0xee, 0xec, 0x2b, 0x0, 0x1, 0xe0, 0x0, 0x1d, + 0x2b, 0x0, 0x1, 0xe0, 0x0, 0x1d, 0x2f, 0xdd, + 0xdd, 0xfd, 0xdd, 0xdd, 0x2b, 0x0, 0x1, 0xe0, + 0x0, 0x1d, 0x2b, 0x0, 0x1, 0xe0, 0x0, 0x1d, + 0x2f, 0xee, 0xee, 0xfe, 0xee, 0xed, 0x2b, 0x0, + 0x1, 0xe0, 0x0, 0x1c, 0x0, 0x0, 0x1, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, + + /* U+7535 "电" */ + 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb3, 0x0, 0x0, 0x0, 0x1e, 0xee, 0xef, + 0xfe, 0xee, 0xe1, 0x1, 0xd0, 0x0, 0xb3, 0x0, + 0xd, 0x10, 0x1d, 0x0, 0xb, 0x30, 0x0, 0xd1, + 0x1, 0xfd, 0xdd, 0xfe, 0xdd, 0xdf, 0x10, 0x1d, + 0x0, 0xb, 0x30, 0x0, 0xd1, 0x1, 0xd0, 0x0, + 0xb3, 0x0, 0xd, 0x10, 0x1f, 0xdd, 0xdf, 0xed, + 0xdd, 0xf1, 0x1, 0xd0, 0x0, 0xb4, 0x0, 0x0, + 0x42, 0x0, 0x0, 0xb, 0x40, 0x0, 0x9, 0x50, + 0x0, 0x0, 0xa6, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0x4, 0xef, 0xff, 0xfa, 0x0, + + /* U+7537 "男" */ + 0x0, 0xdd, 0xcc, 0xee, 0xcc, 0xdd, 0x0, 0xd, + 0x10, 0x8, 0x60, 0x1, 0xd0, 0x0, 0xdc, 0xbb, + 0xed, 0xbb, 0xcd, 0x0, 0xd, 0x10, 0x8, 0x60, + 0x1, 0xd0, 0x0, 0xd1, 0x0, 0x86, 0x0, 0x1d, + 0x0, 0xa, 0xdd, 0xdf, 0xdd, 0xdd, 0xa0, 0x0, + 0x0, 0x0, 0xe1, 0x0, 0x0, 0x0, 0xdd, 0xdd, + 0xef, 0xdd, 0xdd, 0xf4, 0x0, 0x0, 0xa, 0x60, + 0x0, 0xc, 0x20, 0x0, 0x7, 0xc0, 0x0, 0x0, + 0xe0, 0x0, 0x4c, 0xb1, 0x0, 0x0, 0x3c, 0x1, + 0xea, 0x40, 0x0, 0x1d, 0xdd, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+753A "町" */ + 0x44, 0x44, 0x40, 0x11, 0x11, 0x11, 0xe, 0x8e, + 0x8d, 0x4c, 0xcc, 0xfd, 0xc2, 0xc0, 0xb0, 0xa2, + 0x0, 0xb, 0x20, 0xc, 0xb, 0xa, 0x20, 0x0, + 0xb2, 0x0, 0xd0, 0xc0, 0xb2, 0x0, 0xb, 0x20, + 0xf, 0xcf, 0xce, 0x20, 0x0, 0xb2, 0x0, 0xc0, + 0xb0, 0xa2, 0x0, 0xb, 0x20, 0xc, 0xb, 0xa, + 0x20, 0x0, 0xb2, 0x0, 0xc0, 0xb0, 0xa2, 0x0, + 0xb, 0x20, 0xf, 0xde, 0xde, 0x20, 0x0, 0xb2, + 0x0, 0xc0, 0x0, 0x0, 0x0, 0xc, 0x20, 0x0, + 0x0, 0x0, 0x4, 0xee, 0xc0, 0x0, + + /* U+753B "画" */ + 0xbe, 0xee, 0xee, 0xee, 0xee, 0xea, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x50, 0xcb, 0xbf, 0xbb, 0xf0, 0x15, + 0xd1, 0xc0, 0xd, 0x0, 0xd0, 0x2c, 0xd1, 0xcb, + 0xbf, 0xbb, 0xf0, 0x2c, 0xd1, 0xc0, 0xd, 0x0, + 0xd0, 0x2c, 0xd1, 0xc0, 0xd, 0x0, 0xd0, 0x2c, + 0xd1, 0xcc, 0xcf, 0xcc, 0xf0, 0x2c, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0x2c, 0xdb, 0xbb, 0xbb, 0xbb, + 0xbb, 0xcc, 0x22, 0x22, 0x22, 0x22, 0x22, 0x4c, + + /* U+754C "界" */ + 0x0, 0xdd, 0xcc, 0xfd, 0xcc, 0xdc, 0x0, 0x0, + 0xd1, 0x0, 0xc2, 0x0, 0x2c, 0x0, 0x0, 0xdc, + 0xbb, 0xfc, 0xbb, 0xcc, 0x0, 0x0, 0xd1, 0x0, + 0xc2, 0x0, 0x2c, 0x0, 0x0, 0xdc, 0xbb, 0xfc, + 0xbb, 0xcc, 0x0, 0x0, 0x1, 0x98, 0x12, 0xd9, + 0x10, 0x0, 0x0, 0x1b, 0x80, 0x0, 0x1c, 0xb2, + 0x0, 0x19, 0xd5, 0x93, 0x0, 0x1c, 0x6d, 0xa2, + 0x6, 0x0, 0xc2, 0x0, 0x1d, 0x0, 0x50, 0x0, + 0x1, 0xe0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0x2c, + 0x60, 0x0, 0x1d, 0x0, 0x0, 0x2, 0xd5, 0x0, + 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+7559 "留" */ + 0x0, 0x3, 0x94, 0x0, 0x0, 0x0, 0x1, 0xbc, + 0x95, 0xd, 0xdf, 0xdd, 0xf0, 0x2c, 0x0, 0x10, + 0x0, 0xc0, 0xe, 0x2, 0xb0, 0x1d, 0x0, 0x49, + 0x0, 0xe0, 0x2b, 0x14, 0xc7, 0xb, 0x30, 0x1c, + 0x7, 0xfd, 0x95, 0xb9, 0x90, 0x69, 0x90, 0x12, + 0x0, 0x3, 0x70, 0x5, 0x50, 0x0, 0x4c, 0xcc, + 0xcc, 0xcc, 0xcc, 0x0, 0x6, 0x90, 0x0, 0xe0, + 0x0, 0xf0, 0x0, 0x6e, 0xbb, 0xbf, 0xbb, 0xbf, + 0x0, 0x6, 0x90, 0x0, 0xe0, 0x0, 0xf0, 0x0, + 0x69, 0x0, 0xe, 0x0, 0xf, 0x0, 0x6, 0xec, + 0xcc, 0xcc, 0xcc, 0xe0, 0x0, + + /* U+756A "番" */ + 0x0, 0x0, 0x0, 0x1, 0x35, 0x74, 0x0, 0x2, + 0xbb, 0xcc, 0xed, 0x97, 0x62, 0x0, 0x0, 0xb, + 0x20, 0x76, 0x2, 0xe0, 0x0, 0x0, 0x6, 0xa0, + 0x76, 0xb, 0x40, 0x0, 0x1c, 0xcd, 0xec, 0xee, + 0xcf, 0xcc, 0xc2, 0x0, 0x0, 0x4d, 0xaa, 0xd4, + 0x0, 0x0, 0x0, 0x7, 0xd2, 0x76, 0x2d, 0x80, + 0x0, 0x6, 0xea, 0x10, 0x65, 0x1, 0x9f, 0x81, + 0x29, 0x8d, 0xaa, 0xdd, 0xaa, 0xca, 0x81, 0x0, + 0x59, 0x0, 0x76, 0x0, 0x68, 0x0, 0x0, 0x5d, + 0xaa, 0xdd, 0xaa, 0xc8, 0x0, 0x0, 0x59, 0x0, + 0x76, 0x0, 0x68, 0x0, 0x0, 0x5e, 0xbb, 0xbb, + 0xbb, 0xd8, 0x0, + + /* U+756B "畫" */ + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, + 0x59, 0x99, 0xbd, 0x99, 0xae, 0x0, 0x9, 0x99, + 0x99, 0xcd, 0x99, 0xaf, 0x94, 0x0, 0x11, 0x11, + 0x6a, 0x11, 0x2e, 0x0, 0x0, 0x58, 0x88, 0xac, + 0x88, 0x87, 0x0, 0x0, 0x99, 0x99, 0xbd, 0x99, + 0x99, 0x40, 0x0, 0x0, 0x0, 0x6a, 0x0, 0x0, + 0x0, 0x9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x94, + 0x0, 0x6a, 0x88, 0x9a, 0x88, 0x8b, 0x0, 0x0, + 0x7b, 0x88, 0xbd, 0x88, 0x9e, 0x0, 0x0, 0x77, + 0x0, 0x59, 0x0, 0x1e, 0x0, 0x0, 0x38, 0x88, + 0x88, 0x88, 0x87, 0x0, 0xa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xa5, + + /* U+7570 "異" */ + 0x0, 0xbc, 0xbb, 0xde, 0xbb, 0xbf, 0x10, 0x0, + 0xb2, 0x0, 0x59, 0x0, 0xd, 0x10, 0x0, 0xbc, + 0xbb, 0xde, 0xbb, 0xbf, 0x10, 0x0, 0xb2, 0x0, + 0x59, 0x0, 0xd, 0x10, 0x0, 0x8b, 0xec, 0xbb, + 0xbf, 0xcb, 0x0, 0x0, 0x0, 0xa3, 0x0, 0xe, + 0x0, 0x0, 0x2, 0xdd, 0xfe, 0xdd, 0xdf, 0xdd, + 0x80, 0x0, 0x0, 0xa3, 0x0, 0xe, 0x0, 0x0, + 0x1, 0x11, 0xb5, 0x11, 0x1f, 0x11, 0x10, 0xb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb4, 0x0, 0x3, + 0xa9, 0x0, 0x4d, 0x82, 0x0, 0x7, 0xdb, 0x40, + 0x0, 0x0, 0x6d, 0xb1, 0x2, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x30, + + /* U+7576 "當" */ + 0x7, 0x20, 0xc, 0x20, 0x6, 0x50, 0x4, 0xc0, + 0xc, 0x20, 0x1e, 0x10, 0xab, 0xeb, 0xbf, 0xbb, + 0xce, 0xb9, 0xe2, 0x22, 0x22, 0x22, 0x22, 0x3d, + 0xe0, 0xab, 0xbb, 0xbb, 0xb9, 0x1d, 0x40, 0xd0, + 0x0, 0x0, 0x1d, 0x4, 0x0, 0xd7, 0x77, 0x77, + 0x8d, 0x0, 0x0, 0x33, 0x33, 0x33, 0x33, 0x0, + 0xd, 0xbb, 0xbd, 0xcb, 0xbb, 0xd0, 0xc, 0x0, + 0xb, 0x20, 0x0, 0xc0, 0xe, 0xaa, 0xae, 0xba, + 0xaa, 0xe0, 0xc, 0x0, 0xb, 0x20, 0x0, 0xc0, + 0xe, 0xbb, 0xbe, 0xcb, 0xbb, 0xe0, + + /* U+75B2 "疲" */ + 0x0, 0x0, 0x0, 0x8, 0x40, 0x0, 0x0, 0x0, + 0x1a, 0xaa, 0xab, 0xea, 0xaa, 0xa4, 0x0, 0x2c, + 0x22, 0x22, 0x43, 0x22, 0x21, 0xc, 0x2b, 0x0, + 0x0, 0xa2, 0x0, 0x0, 0x9, 0x6b, 0xd, 0xdd, + 0xfd, 0xdd, 0xe1, 0x4, 0x7b, 0xd, 0x0, 0xa2, + 0x3, 0xb0, 0x0, 0x2a, 0xe, 0x0, 0xa2, 0x3, + 0x30, 0x1, 0x98, 0xf, 0xed, 0xcc, 0xcf, 0x10, + 0x2d, 0xa7, 0x1c, 0x39, 0x0, 0x69, 0x0, 0x0, + 0x85, 0x39, 0xb, 0x42, 0xd1, 0x0, 0x0, 0xc1, + 0x76, 0x1, 0xdd, 0x30, 0x0, 0x5, 0xb0, 0xd1, + 0x19, 0xcc, 0xa3, 0x0, 0xb, 0x26, 0x77, 0xd6, + 0x0, 0x4b, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+75C5 "病" */ + 0x0, 0x0, 0x0, 0x4, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5, 0xa0, 0x0, 0x0, 0x0, 0xf, + 0xdd, 0xdd, 0xdd, 0xdd, 0xd7, 0x9, 0xe, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0x5e, 0x6d, 0xdd, + 0xfd, 0xdd, 0xd5, 0x2, 0x6e, 0x0, 0x0, 0xc1, + 0x0, 0x0, 0x0, 0xe, 0x1d, 0xdd, 0xfd, 0xdd, + 0xd0, 0x2, 0xad, 0x1a, 0x0, 0xe0, 0x0, 0xe0, + 0x2d, 0x8b, 0x1a, 0x3, 0xea, 0x0, 0xe0, 0x0, + 0x78, 0x1a, 0x1c, 0x26, 0xb0, 0xe0, 0x0, 0xc3, + 0x1b, 0xb4, 0x0, 0x75, 0xe0, 0x6, 0xc0, 0x1a, + 0x0, 0x0, 0x0, 0xe0, 0xa, 0x20, 0x1a, 0x0, + 0x0, 0xad, 0xa0, + + /* U+75DB "痛" */ + 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, + 0x5, 0x55, 0x5b, 0xa5, 0x55, 0x52, 0x0, 0x2d, + 0x77, 0x77, 0x77, 0x77, 0x73, 0x1c, 0x2b, 0xa, + 0xbb, 0xbb, 0xbb, 0x30, 0x9, 0x6b, 0x0, 0x53, + 0x5, 0xc6, 0x0, 0x3, 0x7b, 0x0, 0x28, 0xed, + 0x10, 0x0, 0x0, 0x2b, 0x3d, 0xbb, 0xec, 0xcb, + 0xd0, 0x2, 0xaa, 0x39, 0x0, 0xd0, 0x0, 0xd0, + 0x3c, 0x88, 0x3e, 0xbb, 0xfb, 0xbb, 0xd0, 0x0, + 0x95, 0x39, 0x0, 0xd0, 0x0, 0xd0, 0x0, 0xd1, + 0x3e, 0xbb, 0xfb, 0xbb, 0xd0, 0x7, 0xa0, 0x39, + 0x0, 0xd0, 0x0, 0xd0, 0xa, 0x10, 0x39, 0x0, + 0xc0, 0x7b, 0xa0, + + /* U+767A "発" */ + 0x0, 0x0, 0x0, 0x6, 0x0, 0x40, 0x0, 0x6, + 0xdd, 0xdf, 0x38, 0x58, 0xa0, 0x0, 0x3, 0x50, + 0x5a, 0x0, 0xe8, 0x4, 0x80, 0x0, 0xa9, 0xd1, + 0x0, 0x4c, 0x79, 0x0, 0x0, 0x5d, 0x20, 0x0, + 0x5, 0xe2, 0x0, 0x2a, 0xbf, 0xee, 0xee, 0xee, + 0xdd, 0x80, 0x54, 0x0, 0x86, 0x0, 0xf0, 0x0, + 0x70, 0x0, 0x0, 0x86, 0x0, 0xf0, 0x0, 0x0, + 0xb, 0xdd, 0xee, 0xdd, 0xfd, 0xdd, 0x40, 0x0, + 0x0, 0xc3, 0x0, 0xf0, 0x0, 0x0, 0x0, 0x4, + 0xd0, 0x0, 0xf0, 0x2, 0x50, 0x0, 0x5e, 0x30, + 0x0, 0xf0, 0x4, 0x90, 0xb, 0xa2, 0x0, 0x0, + 0xbe, 0xde, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+767C "發" */ + 0x0, 0x0, 0x0, 0x6, 0x0, 0x31, 0x0, 0x0, + 0xcc, 0xcf, 0x56, 0x76, 0xa1, 0x0, 0x1, 0xa2, + 0x6a, 0x0, 0xab, 0x6, 0xa0, 0x0, 0x3e, 0x90, + 0x0, 0x7, 0xd9, 0x0, 0x19, 0xff, 0xb9, 0x9, + 0xbb, 0xdc, 0xb3, 0x26, 0x0, 0xd, 0xc, 0x0, + 0xc0, 0x31, 0x0, 0x23, 0x3d, 0x1c, 0x0, 0xc0, + 0x0, 0x0, 0xe9, 0x98, 0xb4, 0x0, 0x7a, 0xa0, + 0x1, 0xb0, 0x0, 0x47, 0x77, 0x77, 0x0, 0x3, + 0xdb, 0xcb, 0x38, 0x33, 0x8a, 0x0, 0x0, 0x0, + 0x1b, 0x8, 0xb5, 0xd1, 0x0, 0x0, 0x0, 0x59, + 0x2, 0xbe, 0x90, 0x0, 0x0, 0x9c, 0xd3, 0xbc, + 0x50, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+767D "白" */ + 0x0, 0x0, 0x62, 0x0, 0x0, 0x0, 0x1, 0xf1, + 0x0, 0x0, 0x33, 0x38, 0xc3, 0x33, 0x33, 0xeb, + 0xbb, 0xbb, 0xbb, 0xbf, 0xe0, 0x0, 0x0, 0x0, + 0xf, 0xe0, 0x0, 0x0, 0x0, 0xf, 0xe0, 0x0, + 0x0, 0x0, 0xf, 0xee, 0xee, 0xee, 0xee, 0xef, + 0xe0, 0x0, 0x0, 0x0, 0xf, 0xe0, 0x0, 0x0, + 0x0, 0xf, 0xe0, 0x0, 0x0, 0x0, 0xf, 0xee, + 0xee, 0xee, 0xee, 0xff, 0xe0, 0x0, 0x0, 0x0, + 0xe, + + /* U+767E "百" */ + 0x1e, 0xee, 0xee, 0xff, 0xee, 0xee, 0xe1, 0x0, + 0x0, 0x0, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x6e, 0xee, + 0xfe, 0xee, 0xe9, 0x0, 0x0, 0x77, 0x0, 0x0, + 0x0, 0x4a, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, + 0x4a, 0x0, 0x0, 0x78, 0x11, 0x11, 0x11, 0x5a, + 0x0, 0x0, 0x7e, 0xcc, 0xcc, 0xcc, 0xda, 0x0, + 0x0, 0x77, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, + 0x77, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x7f, + 0xee, 0xee, 0xee, 0xea, 0x0, 0x0, 0x77, 0x0, + 0x0, 0x0, 0x4a, 0x0, + + /* U+7684 "的" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc2, + 0x0, 0xd, 0x10, 0x0, 0x1, 0xd0, 0x0, 0x2c, + 0x0, 0x0, 0x9c, 0xeb, 0xa0, 0x8e, 0xbb, 0xb9, + 0xd1, 0x11, 0xd0, 0xe3, 0x11, 0x3c, 0xd0, 0x0, + 0xd8, 0x80, 0x0, 0x1c, 0xd0, 0x0, 0xd5, 0x25, + 0x0, 0x2b, 0xdc, 0xcc, 0xe0, 0xd, 0x30, 0x3b, + 0xd0, 0x0, 0xd0, 0x3, 0xd0, 0x3a, 0xd0, 0x0, + 0xd0, 0x0, 0xa6, 0x49, 0xd0, 0x0, 0xd0, 0x0, + 0x10, 0x68, 0xd0, 0x0, 0xd0, 0x0, 0x0, 0x86, + 0xdd, 0xdd, 0xc0, 0x0, 0x0, 0xb3, 0xd0, 0x0, + 0x0, 0x6, 0xcd, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x11, 0x0, + + /* U+7686 "皆" */ + 0xd, 0x20, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x20, + 0x0, 0xd0, 0x5, 0xa0, 0xd, 0xdd, 0xd7, 0xd9, + 0xda, 0x40, 0xd, 0x20, 0x0, 0xd4, 0x0, 0x0, + 0xe, 0x34, 0x76, 0xd1, 0x0, 0x1c, 0x4f, 0xc8, + 0x55, 0x9e, 0xdd, 0xe7, 0x0, 0x0, 0x3b, 0x0, + 0x0, 0x0, 0x7, 0xcc, 0xee, 0xcc, 0xcc, 0x10, + 0x8, 0x50, 0x0, 0x0, 0xd, 0x20, 0x8, 0xdb, + 0xbb, 0xbb, 0xbf, 0x20, 0x8, 0x60, 0x0, 0x0, + 0xd, 0x20, 0x8, 0x50, 0x0, 0x0, 0xd, 0x20, + 0x8, 0xec, 0xcc, 0xcc, 0xcf, 0x20, + + /* U+76BF "皿" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xce, 0xef, 0xee, 0xff, 0xef, 0x50, 0x0, 0xc2, + 0xb, 0x20, 0xa3, 0x9, 0x50, 0x0, 0xc2, 0xb, + 0x20, 0xa3, 0x9, 0x50, 0x0, 0xc2, 0xb, 0x20, + 0xa3, 0x9, 0x50, 0x0, 0xc2, 0xb, 0x20, 0xa3, + 0x9, 0x50, 0x0, 0xc2, 0xb, 0x20, 0xa3, 0x9, + 0x50, 0x0, 0xc2, 0xb, 0x20, 0xa3, 0x9, 0x50, + 0x0, 0xc2, 0xb, 0x20, 0xa3, 0x9, 0x50, 0x0, + 0xc2, 0xb, 0x20, 0xa3, 0x9, 0x50, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfa, + + /* U+76D7 "盗" */ + 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, 0x0, 0x7, + 0xb3, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x3c, + 0x34, 0xec, 0xee, 0xcc, 0xf2, 0x0, 0x0, 0x1d, + 0x20, 0xa7, 0x2, 0xd0, 0x0, 0x0, 0x34, 0x0, + 0xeb, 0x4, 0x50, 0x0, 0x3c, 0x70, 0xa, 0x86, + 0x70, 0x0, 0x9, 0xc3, 0x4, 0xc9, 0x0, 0xaa, + 0x30, 0x5, 0x0, 0x8b, 0x40, 0x0, 0x5, 0xb4, + 0x0, 0x6d, 0xcd, 0xdc, 0xdc, 0xce, 0x0, 0x0, + 0x76, 0xa, 0x30, 0xc1, 0xe, 0x0, 0x0, 0x76, + 0xa, 0x30, 0xc1, 0xe, 0x0, 0x0, 0x76, 0xa, + 0x30, 0xc1, 0xe, 0x0, 0x1d, 0xee, 0xdf, 0xed, + 0xfe, 0xdf, 0xd8, + + /* U+76EE "目" */ + 0xde, 0xee, 0xee, 0xee, 0xec, 0xd1, 0x0, 0x0, + 0x0, 0x2c, 0xd1, 0x0, 0x0, 0x0, 0x2c, 0xdc, + 0xbb, 0xbb, 0xbb, 0xcc, 0xd3, 0x22, 0x22, 0x22, + 0x4c, 0xd1, 0x0, 0x0, 0x0, 0x2c, 0xd1, 0x0, + 0x0, 0x0, 0x2c, 0xde, 0xee, 0xee, 0xee, 0xec, + 0xd1, 0x0, 0x0, 0x0, 0x2c, 0xd1, 0x0, 0x0, + 0x0, 0x2c, 0xde, 0xee, 0xee, 0xee, 0xec, 0xd1, + 0x0, 0x0, 0x0, 0x2c, + + /* U+76F4 "直" */ + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x7, + 0xbb, 0xbb, 0xdd, 0xbb, 0xbb, 0xb1, 0x1, 0x22, + 0x22, 0xb6, 0x22, 0x22, 0x20, 0x0, 0xa, 0xaa, + 0xeb, 0xaa, 0xa6, 0x0, 0x0, 0x1d, 0x22, 0x22, + 0x22, 0x6a, 0x0, 0x0, 0x1e, 0x99, 0x99, 0x99, + 0xba, 0x0, 0x0, 0x1d, 0x22, 0x22, 0x22, 0x6a, + 0x0, 0x0, 0x1e, 0xaa, 0xaa, 0xaa, 0xca, 0x0, + 0x0, 0x1d, 0x11, 0x11, 0x11, 0x5a, 0x0, 0x0, + 0x1e, 0x99, 0x99, 0x99, 0xba, 0x0, 0x0, 0x1d, + 0x11, 0x11, 0x11, 0x6a, 0x0, 0x1, 0x2d, 0x11, + 0x11, 0x11, 0x6a, 0x10, 0x1c, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xc7, + + /* U+76F8 "相" */ + 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe0, 0x5, 0xfe, 0xee, 0xee, 0x0, 0xe, 0x0, + 0x58, 0x0, 0x0, 0xe3, 0xdd, 0xfd, 0xd5, 0x80, + 0x0, 0xe, 0x0, 0x3f, 0x0, 0x5e, 0xcc, 0xcc, + 0xe0, 0x9, 0xf2, 0x5, 0x91, 0x11, 0x1e, 0x0, + 0xce, 0xc0, 0x58, 0x0, 0x0, 0xe0, 0x57, 0xe5, + 0xa5, 0x80, 0x0, 0xe, 0xc, 0x1e, 0x7, 0x5e, + 0xdd, 0xdd, 0xe6, 0x70, 0xe0, 0x5, 0x80, 0x0, + 0xe, 0x10, 0xe, 0x0, 0x58, 0x0, 0x0, 0xe0, + 0x0, 0xe0, 0x5, 0xfd, 0xdd, 0xde, 0x0, 0xe, + 0x0, 0x58, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+770B "看" */ + 0x0, 0x0, 0x0, 0x1, 0x34, 0x77, 0x0, 0x2, + 0xcc, 0xcd, 0xea, 0x87, 0x52, 0x0, 0x0, 0x0, + 0x6, 0x90, 0x0, 0x0, 0x0, 0x1, 0xbb, 0xbf, + 0xcb, 0xbb, 0xbb, 0x40, 0x4, 0x44, 0x6e, 0x44, + 0x44, 0x44, 0x40, 0x16, 0x66, 0xf7, 0x66, 0x66, + 0x66, 0x61, 0x0, 0x9, 0xeb, 0xbb, 0xbb, 0xb8, + 0x0, 0x0, 0x6f, 0x80, 0x0, 0x0, 0x2c, 0x0, + 0x9, 0xb6, 0xda, 0xaa, 0xaa, 0xbc, 0x0, 0x39, + 0x5, 0x80, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x5, + 0xda, 0xaa, 0xaa, 0xbc, 0x0, 0x0, 0x5, 0x80, + 0x0, 0x0, 0x2c, 0x0, 0x0, 0x5, 0xec, 0xcc, + 0xcc, 0xcc, 0x0, + + /* U+771F "真" */ + 0x0, 0x0, 0x0, 0x55, 0x0, 0x0, 0x0, 0x6, + 0x77, 0x77, 0xcb, 0x77, 0x77, 0x60, 0x4, 0x44, + 0x44, 0xc7, 0x44, 0x44, 0x40, 0x0, 0x2b, 0xaa, + 0xdb, 0xaa, 0xb2, 0x0, 0x0, 0x2c, 0x11, 0x11, + 0x11, 0xb3, 0x0, 0x0, 0x2d, 0x88, 0x88, 0x88, + 0xd3, 0x0, 0x0, 0x2e, 0x99, 0x99, 0x99, 0xe3, + 0x0, 0x0, 0x2c, 0x22, 0x22, 0x22, 0xc3, 0x0, + 0x0, 0x2d, 0x66, 0x66, 0x66, 0xd3, 0x0, 0x29, + 0xbe, 0x99, 0x99, 0x99, 0xeb, 0x92, 0x2, 0x22, + 0x74, 0x22, 0x57, 0x32, 0x20, 0x0, 0x5c, 0xa2, + 0x0, 0x28, 0xd9, 0x20, 0xa, 0x82, 0x0, 0x0, + 0x0, 0x5, 0xa0, + + /* U+7720 "眠" */ + 0xfd, 0xde, 0xf, 0xdd, 0xdd, 0xde, 0xe, 0x0, + 0xe0, 0xe0, 0x0, 0x0, 0xe0, 0xe0, 0xe, 0xe, + 0x22, 0x22, 0x2e, 0xf, 0xdd, 0xe0, 0xfb, 0xbf, + 0xbb, 0xa0, 0xe0, 0xe, 0xe, 0x0, 0xc1, 0x0, + 0xe, 0x0, 0xe0, 0xe0, 0xb, 0x30, 0x0, 0xfd, + 0xde, 0xf, 0xdd, 0xee, 0xdd, 0x5e, 0x0, 0xe0, + 0xe0, 0x7, 0x70, 0x0, 0xe0, 0xe, 0xe, 0x0, + 0x4a, 0x0, 0xf, 0xdd, 0xc0, 0xe0, 0x0, 0xe0, + 0x5, 0xc0, 0x0, 0x1e, 0x7a, 0x78, 0x93, 0x70, + 0x0, 0x7, 0xd8, 0x30, 0xb, 0xe2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+773E "眾" */ + 0xb, 0xdd, 0xef, 0xdd, 0xfd, 0xdf, 0x10, 0xb2, + 0x3, 0xa0, 0xd, 0x0, 0xd1, 0xb, 0x42, 0x5b, + 0x22, 0xe2, 0x2d, 0x10, 0x8a, 0xaa, 0xaa, 0xaa, + 0xaa, 0xa0, 0x0, 0x1, 0x11, 0x23, 0x45, 0x78, + 0x0, 0x9d, 0xcc, 0xbd, 0xb8, 0x65, 0x20, 0x0, + 0x7, 0x20, 0x85, 0x1, 0xa0, 0x0, 0x1, 0xe0, + 0x8, 0x50, 0x68, 0x0, 0x0, 0x9d, 0x90, 0x85, + 0xc, 0xc1, 0x0, 0x6c, 0x6, 0xb8, 0x57, 0x84, + 0xc1, 0x7a, 0x10, 0x1, 0x8b, 0xa0, 0x4, 0x90, + 0x0, 0x0, 0x8, 0x50, 0x0, 0x0, + + /* U+7740 "着" */ + 0x0, 0x3, 0x60, 0x0, 0x5, 0x30, 0x0, 0x0, + 0x0, 0xd2, 0x0, 0x2d, 0x10, 0x0, 0x5, 0xcc, + 0xcc, 0xfc, 0xcc, 0xcc, 0x50, 0x0, 0x0, 0x4, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x8a, 0xaf, 0xba, + 0xaa, 0xa8, 0x0, 0x6, 0x66, 0x7e, 0x66, 0x66, + 0x66, 0x60, 0x5, 0x56, 0xf6, 0x55, 0x55, 0x55, + 0x50, 0x0, 0xb, 0xeb, 0xbb, 0xbb, 0xc9, 0x0, + 0x0, 0x9c, 0xc3, 0x33, 0x33, 0x6b, 0x0, 0x1b, + 0x83, 0xd6, 0x66, 0x66, 0x8b, 0x0, 0x37, 0x3, + 0xe9, 0x99, 0x99, 0xbb, 0x0, 0x0, 0x3, 0xb0, + 0x0, 0x0, 0x3b, 0x0, 0x0, 0x3, 0xeb, 0xbb, + 0xbb, 0xcb, 0x0, + + /* U+77E5 "知" */ + 0x0, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, + 0x0, 0x0, 0x38, 0x88, 0x86, 0x8, 0xfe, 0xee, + 0x96, 0xa5, 0x57, 0xc0, 0xd1, 0x86, 0x0, 0x68, + 0x0, 0x2c, 0x78, 0x8, 0x60, 0x6, 0x80, 0x2, + 0xc0, 0x10, 0x86, 0x0, 0x68, 0x0, 0x2c, 0x7e, + 0xef, 0xee, 0xe8, 0x80, 0x2, 0xc0, 0x0, 0xb3, + 0x0, 0x68, 0x0, 0x2c, 0x0, 0xe, 0xa0, 0x6, + 0x80, 0x2, 0xc0, 0x3, 0xb9, 0x80, 0x68, 0x0, + 0x2c, 0x0, 0xb4, 0xc, 0x66, 0x91, 0x14, 0xc0, + 0x7c, 0x0, 0x19, 0x6e, 0xcc, 0xdc, 0x5d, 0x10, + 0x0, 0x6, 0x80, 0x2, 0xa0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+77ED "短" */ + 0x1, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x90, 0x0, 0xad, 0xdd, 0xdd, 0xd6, 0x8, 0xdc, + 0xb8, 0x0, 0x0, 0x0, 0x0, 0xd, 0xe, 0x0, + 0x3d, 0xdd, 0xdd, 0xc0, 0x39, 0xe, 0x0, 0x49, + 0x0, 0x0, 0xe0, 0x2, 0x1e, 0x11, 0x49, 0x0, + 0x0, 0xe0, 0x5d, 0xdf, 0xdc, 0x49, 0x0, 0x0, + 0xe0, 0x0, 0x2d, 0x0, 0x3d, 0xdd, 0xdd, 0xc0, + 0x0, 0x5f, 0x20, 0x5, 0x0, 0x4, 0x30, 0x0, + 0x98, 0xc0, 0x8, 0x50, 0xd, 0x20, 0x1, 0xd0, + 0x79, 0x2, 0xb0, 0x2c, 0x0, 0xa, 0x60, 0x3, + 0x0, 0x80, 0x95, 0x0, 0x3a, 0x0, 0x4, 0xdd, + 0xdd, 0xdd, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+77F3 "石" */ + 0xd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xd1, 0x0, + 0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3f, 0xfe, 0xee, 0xee, + 0xef, 0x30, 0x1, 0xed, 0x50, 0x0, 0x0, 0xb, + 0x30, 0x1d, 0x58, 0x50, 0x0, 0x0, 0xb, 0x30, + 0x46, 0x8, 0x50, 0x0, 0x0, 0xb, 0x30, 0x0, + 0x8, 0x50, 0x0, 0x0, 0xb, 0x30, 0x0, 0x8, + 0xfe, 0xee, 0xee, 0xef, 0x30, 0x0, 0x8, 0x50, + 0x0, 0x0, 0xb, 0x30, + + /* U+7802 "砂" */ + 0x0, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x1d, + 0xef, 0xdc, 0x0, 0xe, 0x0, 0x0, 0x0, 0x77, + 0x0, 0x4, 0xe, 0x6, 0x0, 0x0, 0xb2, 0x0, + 0x1c, 0xe, 0x9, 0x50, 0x0, 0xd0, 0x0, 0x49, + 0xe, 0x1, 0xd0, 0x8, 0xfd, 0xd7, 0x94, 0xe, + 0x0, 0xb3, 0x2e, 0xc0, 0x48, 0xc0, 0xe, 0x0, + 0x21, 0x67, 0xc0, 0x48, 0x0, 0xe, 0x6, 0x80, + 0x1, 0xc0, 0x48, 0x0, 0x9, 0xd, 0x10, 0x1, + 0xc0, 0x48, 0x0, 0x0, 0xc7, 0x0, 0x1, 0xfb, + 0xd8, 0x0, 0x3c, 0x80, 0x0, 0x1, 0xc1, 0x11, + 0x5a, 0xd4, 0x0, 0x0, 0x0, 0x30, 0x5, 0xa4, + 0x0, 0x0, 0x0, + + /* U+7814 "研" */ + 0x1d, 0xef, 0xdb, 0x5e, 0xfe, 0xef, 0xe4, 0x0, + 0x77, 0x0, 0x3, 0xa0, 0xe, 0x0, 0x0, 0xb2, + 0x0, 0x3, 0xa0, 0xe, 0x0, 0x0, 0xd0, 0x0, + 0x3, 0xa0, 0xe, 0x0, 0x5, 0xea, 0xa6, 0x3, + 0xa0, 0xe, 0x0, 0xd, 0xc2, 0x68, 0xbe, 0xfe, + 0xef, 0xe8, 0x3c, 0xb0, 0x48, 0x4, 0x90, 0xe, + 0x0, 0x2, 0xb0, 0x48, 0x6, 0x70, 0xe, 0x0, + 0x1, 0xb0, 0x48, 0x8, 0x50, 0xe, 0x0, 0x1, + 0xeb, 0xd8, 0xd, 0x20, 0xe, 0x0, 0x1, 0xb1, + 0x10, 0x5b, 0x0, 0xe, 0x0, 0x0, 0x30, 0x0, + 0xb2, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+7834 "破" */ + 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x1d, + 0xef, 0xd8, 0x0, 0xd, 0x0, 0x0, 0x0, 0x77, + 0x0, 0x8c, 0xcf, 0xcc, 0xc2, 0x0, 0xb2, 0x0, + 0xa3, 0x1d, 0x11, 0xd0, 0x0, 0xe0, 0x0, 0xa2, + 0xd, 0x1, 0xb0, 0x6, 0xd8, 0x82, 0xb2, 0xd, + 0x1, 0x30, 0xe, 0xd6, 0xc3, 0xbf, 0xcc, 0xcd, + 0x90, 0x4d, 0xa0, 0x93, 0xc9, 0x50, 0x9, 0x30, + 0x3, 0xa0, 0x93, 0xd1, 0xc0, 0x3b, 0x0, 0x2, + 0xa0, 0x94, 0xd0, 0x4b, 0xc1, 0x0, 0x2, 0xeb, + 0xe7, 0xa0, 0x2e, 0xc0, 0x0, 0x2, 0xb1, 0x19, + 0x54, 0xd4, 0x6d, 0x30, 0x0, 0x40, 0xb, 0x4b, + 0x20, 0x3, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+78BA "確" */ + 0x0, 0x0, 0x0, 0x0, 0x5, 0x10, 0x0, 0x8, + 0x88, 0x84, 0x0, 0x1e, 0x10, 0x0, 0x5, 0xaa, + 0x54, 0xfb, 0xed, 0xbb, 0xf0, 0x0, 0xa4, 0x1, + 0xc1, 0xd4, 0x50, 0xd0, 0x0, 0xe0, 0x0, 0x3a, + 0x92, 0xd1, 0x50, 0x2, 0xe7, 0x72, 0x9f, 0xbb, + 0xfb, 0xa0, 0xa, 0xd4, 0xbb, 0xbe, 0x0, 0xd0, + 0x0, 0x2f, 0xb0, 0x94, 0xf, 0xbb, 0xfb, 0xb0, + 0x26, 0xb0, 0x93, 0xe, 0x0, 0xd0, 0x0, 0x0, + 0xb0, 0x93, 0xf, 0xbb, 0xfb, 0xb0, 0x0, 0xea, + 0xd3, 0xe, 0x0, 0xd0, 0x0, 0x0, 0xd5, 0x51, + 0xe, 0x11, 0xe1, 0x11, 0x0, 0x70, 0x0, 0xf, + 0xaa, 0xaa, 0xa7, + + /* U+793A "示" */ + 0x0, 0xce, 0xee, 0xee, 0xee, 0xed, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1d, 0xdd, 0xdd, 0xef, + 0xdd, 0xdd, 0xd2, 0x0, 0x0, 0x0, 0x78, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x10, 0x78, 0x2, 0x70, + 0x0, 0x0, 0x5c, 0x0, 0x78, 0x0, 0xc5, 0x0, + 0x1, 0xd3, 0x0, 0x78, 0x0, 0x2e, 0x10, 0xc, + 0x70, 0x0, 0x78, 0x0, 0x8, 0x90, 0x27, 0x0, + 0x0, 0x88, 0x0, 0x1, 0x80, 0x0, 0x0, 0xce, + 0xe4, 0x0, 0x0, 0x0, + + /* U+793C "礼" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x1, 0xc0, 0x0, 0x0, 0x0, 0xd, + 0x30, 0x1, 0xc0, 0x0, 0x0, 0x1, 0x16, 0x61, + 0x1, 0xc0, 0x0, 0x0, 0xb, 0xcc, 0xdd, 0x1, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0xa4, 0x1, 0xc0, + 0x0, 0x0, 0x0, 0x6, 0xa0, 0x1, 0xc0, 0x0, + 0x0, 0x0, 0x3f, 0x70, 0x1, 0xc0, 0x0, 0x0, + 0x5, 0xdf, 0xb7, 0x1, 0xc0, 0x0, 0x0, 0x4c, + 0x1e, 0xc, 0x51, 0xc0, 0x0, 0x0, 0x0, 0xe, + 0x1, 0x1, 0xc0, 0x0, 0x30, 0x0, 0xe, 0x0, + 0x1, 0xc0, 0x0, 0xb2, 0x0, 0xe, 0x0, 0x1, + 0xd0, 0x0, 0xd0, 0x0, 0xe, 0x0, 0x0, 0xce, + 0xde, 0x90, + + /* U+793E "社" */ + 0x0, 0x57, 0x0, 0x0, 0x8, 0x60, 0x0, 0x0, + 0xd, 0x30, 0x0, 0x8, 0x60, 0x0, 0x1, 0x16, + 0x51, 0x0, 0x8, 0x60, 0x0, 0x2c, 0xcc, 0xde, + 0x0, 0x8, 0x60, 0x0, 0x0, 0x0, 0xb5, 0x1, + 0x18, 0x71, 0x10, 0x0, 0x8, 0xa0, 0x8c, 0xce, + 0xec, 0xc6, 0x0, 0x6f, 0x70, 0x0, 0x8, 0x60, + 0x0, 0x9, 0xde, 0xb8, 0x0, 0x8, 0x60, 0x0, + 0x6a, 0xe, 0xa, 0x10, 0x8, 0x60, 0x0, 0x0, + 0xe, 0x0, 0x0, 0x8, 0x60, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x8, 0x60, 0x0, 0x0, 0xe, 0x0, + 0x22, 0x29, 0x82, 0x22, 0x0, 0xe, 0x3, 0xbb, + 0xbb, 0xbb, 0xb9, + + /* U+7956 "祖" */ + 0x0, 0x46, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x30, 0x2f, 0xee, 0xef, 0x20, 0x6, 0x69, + 0x85, 0x2b, 0x0, 0xb, 0x20, 0x6, 0x66, 0xab, + 0x2b, 0x0, 0xb, 0x20, 0x0, 0x1, 0xe2, 0x2e, + 0xbb, 0xbe, 0x20, 0x0, 0xb, 0x60, 0x2c, 0x22, + 0x2c, 0x20, 0x0, 0x9f, 0xb0, 0x2b, 0x0, 0xb, + 0x20, 0x1b, 0x9e, 0x8b, 0x2b, 0x0, 0xb, 0x20, + 0x37, 0xe, 0x7, 0x2f, 0xdd, 0xdf, 0x20, 0x0, + 0xe, 0x0, 0x2b, 0x0, 0xb, 0x20, 0x0, 0xe, + 0x0, 0x2b, 0x0, 0xb, 0x20, 0x0, 0xe, 0x0, + 0x2c, 0x0, 0xc, 0x30, 0x0, 0xe, 0xd, 0xdd, + 0xdd, 0xdd, 0xd5, + + /* U+795D "祝" */ + 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3c, 0x0, 0x89, 0x99, 0x99, 0x70, 0x1, 0x18, + 0x40, 0xe4, 0x44, 0x45, 0xc0, 0x1c, 0xcc, 0xe6, + 0xe0, 0x0, 0x1, 0xc0, 0x0, 0x1, 0xd0, 0xe0, + 0x0, 0x1, 0xc0, 0x0, 0xb, 0x60, 0xe0, 0x0, + 0x1, 0xc0, 0x0, 0x7f, 0x50, 0xce, 0xed, 0xfd, + 0xa0, 0x9, 0xde, 0xc5, 0x7, 0x70, 0xe0, 0x0, + 0x2b, 0xe, 0x19, 0x9, 0x50, 0xe0, 0x0, 0x0, + 0xe, 0x0, 0xc, 0x20, 0xe0, 0x0, 0x0, 0xe, + 0x0, 0x3d, 0x0, 0xe0, 0x15, 0x0, 0xe, 0x2, + 0xd3, 0x0, 0xe0, 0x39, 0x0, 0xe, 0x2d, 0x40, + 0x0, 0xbc, 0xd4, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+795E "神" */ + 0x0, 0x47, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, + 0xd1, 0x0, 0x0, 0xe0, 0x0, 0x1, 0x16, 0x40, + 0x44, 0x4f, 0x44, 0x40, 0xcc, 0xce, 0x6d, 0x99, + 0xf9, 0x9f, 0x0, 0x1, 0xb0, 0xd0, 0xe, 0x0, + 0xe0, 0x0, 0xa3, 0xd, 0xcc, 0xfc, 0xcf, 0x0, + 0x9f, 0x90, 0xd0, 0xe, 0x0, 0xe1, 0xb9, 0xc8, + 0x8d, 0x0, 0xe0, 0xe, 0x6, 0xc, 0x3, 0xdd, + 0xdf, 0xdd, 0xf0, 0x0, 0xc0, 0xc, 0x0, 0xe0, + 0xb, 0x0, 0xc, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x0, 0xc0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xc, + 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+796D "祭" */ + 0x0, 0x8, 0x30, 0x6, 0x0, 0x0, 0x0, 0x0, + 0x3f, 0xcc, 0xba, 0xdc, 0xcd, 0x50, 0x1, 0xc2, + 0x4, 0x94, 0xa0, 0x2e, 0x10, 0xc, 0x48, 0x8c, + 0x30, 0xd2, 0xc5, 0x0, 0x4, 0x40, 0xb9, 0x0, + 0x4e, 0x80, 0x0, 0x0, 0xab, 0xd1, 0x0, 0xa, + 0xa0, 0x0, 0x1, 0xab, 0x9d, 0xdd, 0xda, 0x9c, + 0x30, 0x3d, 0x60, 0x0, 0x0, 0x0, 0x4, 0xc4, + 0x0, 0xdd, 0xdd, 0xee, 0xdd, 0xdd, 0x30, 0x0, + 0x1, 0x60, 0x68, 0x5, 0x0, 0x0, 0x0, 0x3d, + 0x40, 0x68, 0x6, 0xc2, 0x0, 0x7, 0xd2, 0x0, + 0x78, 0x0, 0x4d, 0x30, 0x3, 0x0, 0x1d, 0xe5, + 0x0, 0x2, 0x20, + + /* U+7981 "禁" */ + 0x0, 0x8, 0x50, 0x0, 0x7, 0x60, 0x0, 0x1, + 0x19, 0x61, 0x1, 0x18, 0x71, 0x10, 0xb, 0xbf, + 0xdb, 0x3b, 0xbf, 0xfb, 0xa0, 0x0, 0x8e, 0xc6, + 0x0, 0x9d, 0xd6, 0x0, 0x8, 0x99, 0x56, 0x4a, + 0x77, 0x69, 0x80, 0x26, 0x7, 0x40, 0x44, 0x6, + 0x50, 0x61, 0x0, 0x49, 0x99, 0x99, 0x99, 0x96, + 0x0, 0x0, 0x12, 0x22, 0x22, 0x22, 0x22, 0x0, + 0x2, 0x22, 0x22, 0x22, 0x22, 0x22, 0x20, 0xa, + 0xaa, 0xaa, 0xcd, 0xaa, 0xaa, 0xa1, 0x0, 0x1b, + 0x10, 0x68, 0x5, 0x80, 0x0, 0x3, 0xc5, 0x0, + 0x68, 0x0, 0x6c, 0x20, 0x9, 0x20, 0x6c, 0xd5, + 0x0, 0x3, 0x70, + + /* U+79C0 "秀" */ + 0x0, 0x0, 0x0, 0x2, 0x46, 0x93, 0x0, 0x3, + 0xcc, 0xcd, 0xec, 0x86, 0x41, 0x0, 0x0, 0x0, + 0x0, 0x76, 0x0, 0x0, 0x0, 0x1d, 0xdd, 0xdd, + 0xee, 0xdd, 0xdd, 0xd0, 0x0, 0x0, 0x4d, 0xa9, + 0xc4, 0x0, 0x0, 0x0, 0x7, 0xd2, 0x76, 0x1c, + 0x80, 0x0, 0x5, 0xd9, 0x10, 0x76, 0x0, 0x8d, + 0x70, 0x4b, 0x6b, 0xbb, 0xbb, 0xb4, 0x1, 0x91, + 0x0, 0x2, 0x6b, 0x22, 0xc2, 0x0, 0x0, 0x0, + 0x0, 0xa6, 0x0, 0xcd, 0xdf, 0x0, 0x0, 0x3, + 0xe0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x4e, 0x40, + 0x0, 0x0, 0x4b, 0x0, 0xb, 0xb3, 0x0, 0x0, + 0xcd, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+79C1 "私" */ + 0x0, 0x0, 0x27, 0x10, 0x5, 0x0, 0x0, 0x8, + 0xbe, 0xc6, 0x10, 0x1e, 0x0, 0x0, 0x3, 0x19, + 0x50, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x8, 0x50, + 0x0, 0x87, 0x0, 0x0, 0x1d, 0xdf, 0xed, 0x90, + 0xc3, 0x0, 0x0, 0x0, 0xe, 0xa0, 0x0, 0xf0, + 0x0, 0x0, 0x0, 0x7e, 0xb9, 0x4, 0xb0, 0xa3, + 0x0, 0x1, 0xc9, 0x5a, 0x59, 0x60, 0x5a, 0x0, + 0xa, 0x58, 0x51, 0x1e, 0x20, 0xe, 0x10, 0x5a, + 0x8, 0x50, 0x3c, 0x0, 0x8, 0x80, 0x10, 0x8, + 0x50, 0xa9, 0x46, 0x9c, 0xe0, 0x0, 0x8, 0x50, + 0xfd, 0xa7, 0x52, 0xd3, 0x0, 0x8, 0x50, 0x0, + 0x0, 0x0, 0x42, + + /* U+79CB "秋" */ + 0x0, 0x15, 0xa6, 0x0, 0xd, 0x0, 0x0, 0x3d, + 0xbf, 0x40, 0x0, 0xd, 0x0, 0x0, 0x0, 0xe, + 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xe, 0x0, + 0x18, 0x1c, 0x1, 0x90, 0x6e, 0xef, 0xee, 0x58, + 0x2b, 0x7, 0x70, 0x0, 0x5f, 0x20, 0x95, 0x4c, + 0xd, 0x10, 0x0, 0xcf, 0xb1, 0xd0, 0x6f, 0x49, + 0x0, 0x5, 0x8e, 0x57, 0x0, 0x8f, 0x20, 0x0, + 0xd, 0x1e, 0x0, 0x0, 0xe6, 0x80, 0x0, 0x96, + 0xe, 0x0, 0x5, 0xc0, 0xc0, 0x0, 0x20, 0xe, + 0x0, 0xc, 0x40, 0x78, 0x0, 0x0, 0xe, 0x0, + 0xb8, 0x0, 0xc, 0x70, 0x0, 0xe, 0x8, 0x70, + 0x0, 0x1, 0xb2, + + /* U+79CD "种" */ + 0x0, 0x3, 0x77, 0x0, 0xc, 0x20, 0x0, 0xb, + 0xdf, 0x71, 0x0, 0xc, 0x20, 0x0, 0x0, 0xd, + 0x10, 0x0, 0xc, 0x20, 0x0, 0x0, 0xd, 0x10, + 0x9e, 0xef, 0xee, 0xe1, 0x1d, 0xdf, 0xec, 0x94, + 0xd, 0x30, 0xd1, 0x0, 0x3f, 0x30, 0x93, 0xc, + 0x20, 0xc1, 0x0, 0xaf, 0xc0, 0x93, 0xc, 0x20, + 0xc1, 0x1, 0xcd, 0x69, 0x95, 0x2d, 0x42, 0xd1, + 0xa, 0x4d, 0x16, 0x9c, 0xbf, 0xcb, 0xf1, 0x4a, + 0xd, 0x10, 0x31, 0xc, 0x20, 0x40, 0x1, 0xd, + 0x10, 0x0, 0xc, 0x20, 0x0, 0x0, 0xd, 0x10, + 0x0, 0xc, 0x20, 0x0, 0x0, 0xd, 0x10, 0x0, + 0xc, 0x20, 0x0, + + /* U+79D1 "科" */ + 0x0, 0x3, 0x86, 0x0, 0x0, 0x1d, 0x0, 0x1b, + 0xdf, 0x61, 0x8, 0x60, 0x1d, 0x0, 0x1, 0xe, + 0x0, 0x0, 0xa9, 0x1d, 0x0, 0x0, 0xe, 0x0, + 0x0, 0x6, 0x1d, 0x0, 0x5d, 0xdf, 0xdd, 0x10, + 0x0, 0x1d, 0x0, 0x0, 0x5f, 0x20, 0x2d, 0x40, + 0x1d, 0x0, 0x0, 0xbf, 0xb1, 0x1, 0xc7, 0x1d, + 0x0, 0x3, 0x9e, 0x4a, 0x0, 0x2, 0x1d, 0x0, + 0xc, 0x2e, 0x2, 0x0, 0x13, 0x6f, 0xb8, 0x68, + 0xe, 0x0, 0xce, 0xda, 0x8e, 0x20, 0x10, 0xe, + 0x0, 0x20, 0x0, 0x1d, 0x0, 0x0, 0xe, 0x0, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x0, 0x1d, 0x0, + + /* U+79D8 "秘" */ + 0x0, 0x2, 0x70, 0x1, 0x70, 0x0, 0x0, 0x7, + 0xde, 0x71, 0x0, 0x8b, 0x5, 0x50, 0x1, 0x2c, + 0x0, 0x0, 0x6, 0x7b, 0x20, 0x0, 0x1c, 0x0, + 0x0, 0x90, 0xc, 0x0, 0x1e, 0xef, 0xe6, 0x31, + 0xd0, 0x58, 0x0, 0x0, 0x6e, 0x0, 0xc1, 0xd0, + 0xbc, 0x40, 0x0, 0xcf, 0x91, 0xb1, 0xd3, 0xb4, + 0xa0, 0x2, 0xcc, 0xb8, 0x81, 0xdb, 0x30, 0xd0, + 0xa, 0x5c, 0x2b, 0x21, 0xfa, 0x0, 0xa3, 0x3c, + 0x1c, 0x3, 0x2, 0xf2, 0x0, 0x32, 0x2, 0x1c, + 0x0, 0x2d, 0xd0, 0x7, 0x30, 0x0, 0x1c, 0x3, + 0xe8, 0xd0, 0xa, 0x20, 0x0, 0x1c, 0x8, 0x50, + 0xcd, 0xdc, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+79FB "移" */ + 0x0, 0x0, 0x30, 0x0, 0x6, 0x0, 0x0, 0x5, + 0x9d, 0xb3, 0x0, 0xba, 0x22, 0x10, 0x4, 0x3e, + 0x0, 0x3c, 0xba, 0xae, 0x80, 0x0, 0xd, 0x2, + 0xb6, 0x70, 0x9d, 0x0, 0x1e, 0xef, 0xe9, 0x0, + 0xaf, 0xc1, 0x0, 0x0, 0x4f, 0x10, 0x5c, 0xfa, + 0x90, 0x0, 0x0, 0xaf, 0xa2, 0xc7, 0x2c, 0x82, + 0x20, 0x1, 0xce, 0x95, 0x1, 0xbc, 0xaa, 0xe5, + 0x8, 0x6d, 0x12, 0x4d, 0x70, 0x2, 0xc0, 0x1d, + 0xd, 0x0, 0x92, 0x98, 0x2c, 0x30, 0x3, 0xd, + 0x0, 0x0, 0xa, 0xe3, 0x0, 0x0, 0xd, 0x0, + 0x5, 0xc9, 0x10, 0x0, 0x0, 0xd, 0x6, 0xc8, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7A0B "程" */ + 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, 0x6, + 0x9d, 0xc6, 0x6e, 0xdd, 0xdd, 0xe0, 0x5, 0x2d, + 0x10, 0x67, 0x0, 0x0, 0xe0, 0x0, 0xc, 0x10, + 0x67, 0x0, 0x0, 0xe0, 0x1d, 0xdf, 0xec, 0x6e, + 0xcc, 0xcc, 0xe0, 0x0, 0x3f, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9e, 0xb0, 0xab, 0xbb, 0xbb, + 0xb4, 0x1, 0xbc, 0x7b, 0x11, 0x1e, 0x11, 0x10, + 0x9, 0x4c, 0x14, 0x0, 0xe, 0x0, 0x0, 0x3b, + 0xc, 0x10, 0x7c, 0xcf, 0xcc, 0xc1, 0x2, 0xc, + 0x10, 0x0, 0xe, 0x0, 0x0, 0x0, 0xc, 0x10, + 0x0, 0xe, 0x0, 0x0, 0x0, 0xc, 0x17, 0xdd, + 0xdf, 0xdd, 0xd9, + + /* U+7A2E "種" */ + 0x0, 0x1, 0x65, 0x0, 0x23, 0x57, 0x80, 0xa, + 0xcf, 0x93, 0xbb, 0xaf, 0x75, 0x20, 0x2, 0xc, + 0x12, 0x66, 0x6e, 0x66, 0x61, 0x0, 0xc, 0x12, + 0x55, 0x5e, 0x55, 0x51, 0x1d, 0xdf, 0xec, 0x8a, + 0xaf, 0xaa, 0xa0, 0x0, 0x3f, 0x20, 0xc1, 0xe, + 0x0, 0xe0, 0x0, 0xaf, 0xa0, 0xca, 0xaf, 0xaa, + 0xf0, 0x1, 0xbc, 0x89, 0xc0, 0xe, 0x0, 0xe0, + 0xa, 0x4c, 0x26, 0xcb, 0xbf, 0xbb, 0xf0, 0x3b, + 0xc, 0x10, 0x0, 0xe, 0x0, 0x0, 0x1, 0xc, + 0x10, 0xbc, 0xcf, 0xcc, 0xc0, 0x0, 0xc, 0x10, + 0x0, 0xe, 0x0, 0x0, 0x0, 0xc, 0x19, 0xcc, + 0xcf, 0xcc, 0xc6, + + /* U+7A4D "積" */ + 0x0, 0x2, 0x75, 0x0, 0xe, 0x0, 0x0, 0xa, + 0xdf, 0x83, 0xaa, 0xaf, 0xaa, 0xa3, 0x1, 0xd, + 0x0, 0x69, 0x9f, 0x99, 0x90, 0x0, 0xd, 0x0, + 0x22, 0x2e, 0x22, 0x21, 0x1e, 0xef, 0xec, 0x88, + 0x88, 0x88, 0x86, 0x0, 0x3f, 0x0, 0x4a, 0xaa, + 0xaa, 0x90, 0x0, 0x9f, 0x80, 0x76, 0x0, 0x0, + 0xd0, 0x1, 0xbd, 0x97, 0x7c, 0xaa, 0xaa, 0xd0, + 0xa, 0x4d, 0x5, 0x7a, 0x66, 0x66, 0xd0, 0x4b, + 0xd, 0x0, 0x78, 0x33, 0x33, 0xd0, 0x1, 0xd, + 0x0, 0x6b, 0xaa, 0xaa, 0xc0, 0x0, 0xd, 0x0, + 0x1a, 0x80, 0x3b, 0x30, 0x0, 0xd, 0x9, 0xb4, + 0x0, 0x2, 0xb6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7A76 "究" */ + 0x0, 0x0, 0x1, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, 0xe, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xe0, 0xe, 0x0, 0x25, + 0x0, 0x61, 0x0, 0xe0, 0x4, 0x18, 0xc2, 0x0, + 0x3b, 0xa2, 0x30, 0x4, 0xd6, 0x2, 0x0, 0x0, + 0x3b, 0x50, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, + 0x0, 0x8, 0xdd, 0xdf, 0xed, 0xdf, 0x10, 0x0, + 0x0, 0x0, 0xe, 0x10, 0xd, 0x10, 0x0, 0x0, + 0x0, 0x3d, 0x0, 0xd, 0x10, 0x0, 0x0, 0x1, + 0xd5, 0x0, 0xd, 0x10, 0x65, 0x0, 0x4d, 0x60, + 0x0, 0xd, 0x10, 0x85, 0xc, 0xb3, 0x0, 0x0, + 0xa, 0xee, 0xd1, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7A7A "空" */ + 0x0, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x60, 0x0, 0x0, 0xee, 0xdd, 0xdd, 0xdd, + 0xdd, 0xee, 0xe0, 0x0, 0x10, 0x0, 0x0, 0xe, + 0xe0, 0xa, 0x80, 0xc, 0x92, 0xb, 0x16, 0xd6, + 0x0, 0x0, 0x5d, 0x91, 0x79, 0x10, 0x0, 0x0, + 0x0, 0x77, 0x6, 0xdd, 0xdd, 0xdd, 0xdd, 0x70, + 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x30, 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, + 0x0, 0x0, 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, + 0xbd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, + + /* U+7A93 "窓" */ + 0x0, 0x0, 0x0, 0x67, 0x0, 0x0, 0x0, 0xa, + 0xbb, 0xbb, 0xcf, 0xbb, 0xbb, 0xb0, 0xe, 0x0, + 0x6, 0x0, 0x30, 0x0, 0xf0, 0x7, 0x3, 0xc6, + 0x0, 0x6c, 0x60, 0x60, 0x2, 0xbb, 0x23, 0xc0, + 0x0, 0x9b, 0x0, 0x0, 0x30, 0x2d, 0x20, 0x66, + 0x1, 0x0, 0x0, 0x3, 0xd3, 0x0, 0x2c, 0x90, + 0x0, 0x0, 0x4f, 0xec, 0xcc, 0xba, 0xb9, 0x0, + 0x0, 0x1, 0x0, 0x61, 0x0, 0x3, 0x0, 0x0, + 0x81, 0xa0, 0x4c, 0x0, 0x69, 0x0, 0x5, 0xa2, + 0xc0, 0x7, 0x80, 0x3c, 0x50, 0xd, 0x22, 0xd0, + 0x0, 0x2, 0xb2, 0xe0, 0x15, 0x0, 0xcd, 0xdd, + 0xde, 0x50, 0x20, + + /* U+7ACB "立" */ + 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x46, 0x0, 0x0, 0x0, 0x9, 0xee, 0xee, + 0xee, 0xee, 0xee, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, 0x0, 0x0, 0x8, 0x70, 0x0, 0x7, + 0xa0, 0x0, 0x0, 0x4, 0xb0, 0x0, 0xb, 0x50, + 0x0, 0x0, 0x0, 0xf0, 0x0, 0xf, 0x10, 0x0, + 0x0, 0x0, 0xc3, 0x0, 0x4b, 0x0, 0x0, 0x0, + 0x0, 0x96, 0x0, 0x96, 0x0, 0x0, 0x0, 0x0, + 0x69, 0x0, 0xe1, 0x0, 0x0, 0x3, 0x33, 0x43, + 0x36, 0xc3, 0x33, 0x30, 0x2b, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xb2, + + /* U+7AD9 "站" */ + 0x0, 0x47, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x3, 0x38, + 0x43, 0x0, 0x1d, 0x0, 0x0, 0x1a, 0xaa, 0xaa, + 0x20, 0x1f, 0xee, 0xe7, 0x4, 0x20, 0x45, 0x0, + 0x1d, 0x0, 0x0, 0x6, 0x50, 0x85, 0x0, 0x1d, + 0x0, 0x0, 0x4, 0x80, 0xa3, 0x0, 0x1d, 0x0, + 0x0, 0x1, 0xb0, 0xc0, 0x6f, 0xee, 0xee, 0xd0, + 0x0, 0xc0, 0xc0, 0x68, 0x0, 0x1, 0xd0, 0x0, + 0x63, 0xb7, 0x88, 0x0, 0x1, 0xd0, 0x2a, 0xdd, + 0x95, 0x78, 0x0, 0x1, 0xd0, 0x15, 0x10, 0x0, + 0x6d, 0xaa, 0xab, 0xd0, 0x0, 0x0, 0x0, 0x69, + 0x22, 0x23, 0xd0, + + /* U+7AE5 "童" */ + 0x0, 0x0, 0x0, 0x49, 0x0, 0x0, 0x0, 0x1, + 0xcc, 0xcc, 0xcf, 0xcc, 0xcc, 0x80, 0x0, 0x0, + 0xc1, 0x0, 0xa, 0x40, 0x0, 0x6, 0x66, 0xca, + 0x66, 0x7f, 0x66, 0x63, 0x6, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x63, 0x0, 0x6a, 0xaa, 0xab, 0xaa, + 0xab, 0x0, 0x0, 0x85, 0x0, 0x3a, 0x0, 0xe, + 0x0, 0x0, 0x8c, 0x99, 0xbe, 0x99, 0x9f, 0x0, + 0x0, 0x89, 0x55, 0x7c, 0x55, 0x5f, 0x0, 0x0, + 0x24, 0x44, 0x7c, 0x44, 0x44, 0x0, 0x1, 0xbb, + 0xbb, 0xce, 0xbb, 0xbb, 0x60, 0x0, 0x0, 0x0, + 0x3a, 0x0, 0x0, 0x0, 0x1c, 0xcc, 0xcc, 0xde, + 0xcc, 0xcc, 0xc7, + + /* U+7AEF "端" */ + 0x0, 0x63, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, + 0x4a, 0x0, 0xe0, 0xd, 0x0, 0xd0, 0x0, 0x9, + 0x0, 0xe0, 0xd, 0x0, 0xd0, 0x1e, 0xee, 0xe8, + 0xe7, 0x7e, 0x78, 0xd0, 0x4, 0x10, 0x70, 0x33, + 0x33, 0x33, 0x30, 0x7, 0x40, 0xc7, 0xdd, 0xdd, + 0xdd, 0xd4, 0x4, 0x70, 0xc0, 0x0, 0x2d, 0x0, + 0x0, 0x2, 0x91, 0xa0, 0xaa, 0xce, 0xaa, 0xa0, + 0x1, 0xb4, 0x70, 0xc2, 0xc2, 0xc2, 0xd0, 0x0, + 0x57, 0x86, 0xc0, 0xc0, 0xc0, 0xc0, 0x8, 0xbe, + 0xa5, 0xc0, 0xc0, 0xc0, 0xc0, 0x7, 0x20, 0x0, + 0xc0, 0xc0, 0xc0, 0xc0, 0x0, 0x0, 0x0, 0xc0, + 0xa0, 0xa7, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7B11 "笑" */ + 0x0, 0x34, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, + 0xb5, 0x0, 0x5, 0xb0, 0x0, 0x0, 0x3, 0xee, + 0xdc, 0xcc, 0xdf, 0xed, 0xd2, 0x1d, 0x34, 0xb0, + 0x99, 0x5, 0xa0, 0x0, 0x14, 0x0, 0x50, 0x52, + 0x46, 0xda, 0x0, 0x2, 0xcd, 0xdd, 0xde, 0xa8, + 0x51, 0x0, 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, + 0x2d, 0xdd, 0xdd, 0xff, 0xdd, 0xdd, 0xd3, 0x0, + 0x0, 0x7, 0xa9, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x4d, 0x10, 0xc6, 0x0, 0x0, 0x0, 0x19, 0xd2, + 0x0, 0x1c, 0xa2, 0x0, 0xc, 0xc6, 0x0, 0x0, + 0x0, 0x6d, 0xc0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, + + /* U+7B26 "符" */ + 0x0, 0x24, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, + 0xa8, 0x22, 0x15, 0xc2, 0x22, 0x20, 0x2, 0xeb, + 0xea, 0x7c, 0xae, 0xba, 0xa0, 0xc, 0x40, 0xd0, + 0x88, 0x4, 0xb0, 0x0, 0x5, 0x2, 0x81, 0x30, + 0x0, 0x71, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, + 0xa3, 0x0, 0x0, 0x7d, 0x1d, 0xdd, 0xdd, 0xfe, + 0xd2, 0x5, 0xec, 0x0, 0x20, 0x0, 0xa3, 0x0, + 0xd, 0x3c, 0x1, 0xd1, 0x0, 0xa3, 0x0, 0x0, + 0x1c, 0x0, 0x6a, 0x0, 0xa3, 0x0, 0x0, 0x1c, + 0x0, 0x9, 0x0, 0xa3, 0x0, 0x0, 0x1c, 0x0, + 0x0, 0x0, 0xb3, 0x0, 0x0, 0x1c, 0x0, 0x0, + 0xdd, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7B2C "第" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, + 0x60, 0x0, 0x1d, 0x0, 0x0, 0x0, 0xec, 0xbb, + 0x97, 0xeb, 0xbb, 0xb0, 0x96, 0x3b, 0x1, 0xd1, + 0x5a, 0x0, 0x4a, 0x0, 0xa0, 0x66, 0x0, 0xa1, + 0x0, 0x5c, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, 0x0, + 0x0, 0x0, 0xb2, 0x0, 0xe, 0x0, 0xb, 0xcc, + 0xcf, 0xdc, 0xcc, 0xf0, 0x0, 0xd0, 0x0, 0xb2, + 0x0, 0x0, 0x0, 0x2c, 0x22, 0x2c, 0x52, 0x22, + 0x21, 0x3, 0xaa, 0xae, 0xfb, 0xaa, 0xae, 0x40, + 0x0, 0x8, 0x9c, 0x20, 0x0, 0xc2, 0x0, 0x3b, + 0x60, 0xb2, 0x1, 0x2e, 0x0, 0x98, 0x10, 0xb, + 0x21, 0xbb, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7B46 "筆" */ + 0x0, 0x67, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, + 0xdd, 0xbb, 0xbc, 0xeb, 0xbb, 0xb4, 0x8, 0x75, + 0xa0, 0xa8, 0xb, 0x50, 0x0, 0x9, 0x0, 0x70, + 0xa6, 0x1, 0x50, 0x0, 0x0, 0x7b, 0xbb, 0xde, + 0xbb, 0xbd, 0x0, 0x0, 0x0, 0x0, 0x78, 0x0, + 0xf, 0x0, 0xb, 0xbb, 0xbb, 0xdd, 0xbb, 0xbf, + 0xb5, 0x0, 0x45, 0x55, 0xab, 0x55, 0x5f, 0x0, + 0x0, 0x34, 0x44, 0x9a, 0x44, 0x44, 0x0, 0x1, + 0xbb, 0xbb, 0xde, 0xbb, 0xbb, 0x40, 0x0, 0x0, + 0x0, 0x68, 0x0, 0x0, 0x0, 0xa, 0xbb, 0xbb, + 0xde, 0xbb, 0xbb, 0xb3, 0x0, 0x0, 0x0, 0x68, + 0x0, 0x0, 0x0, + + /* U+7B49 "等" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x68, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xdd, + 0xbb, 0xb6, 0xfb, 0xbb, 0xb5, 0x6, 0x86, 0x90, + 0x2d, 0x27, 0x90, 0x0, 0x1b, 0x1, 0xa0, 0x79, + 0x0, 0xc0, 0x0, 0x0, 0x8c, 0xcc, 0xde, 0xcc, + 0xcc, 0x30, 0x0, 0x0, 0x0, 0x4b, 0x0, 0x0, + 0x0, 0x2, 0x22, 0x22, 0x6b, 0x22, 0x22, 0x21, + 0x1a, 0xaa, 0xaa, 0xaa, 0xac, 0xda, 0xa6, 0x0, + 0x0, 0x0, 0x0, 0x6, 0x90, 0x0, 0x8, 0xcc, + 0xcc, 0xcc, 0xcd, 0xec, 0xc2, 0x0, 0x4, 0xc3, + 0x0, 0x6, 0x80, 0x0, 0x0, 0x0, 0x2d, 0x30, + 0x6, 0x80, 0x0, 0x0, 0x0, 0x1, 0x8, 0xde, + 0x50, 0x0, + + /* U+7B54 "答" */ + 0x0, 0x24, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, + 0xa7, 0x22, 0x21, 0xe2, 0x22, 0x20, 0x3, 0xdc, + 0xda, 0x9a, 0xbd, 0xda, 0xa1, 0x1d, 0x21, 0xd0, + 0x2a, 0x2, 0xd0, 0x0, 0x3, 0x0, 0x41, 0xca, + 0x0, 0x40, 0x0, 0x0, 0x0, 0x2c, 0x78, 0xb2, + 0x0, 0x0, 0x0, 0x18, 0xe5, 0x11, 0x5d, 0xa4, + 0x0, 0x19, 0xe8, 0xab, 0xbb, 0xbb, 0x5c, 0xd3, + 0x6, 0x1, 0x11, 0x11, 0x11, 0x10, 0x30, 0x0, + 0xf, 0xbb, 0xbb, 0xbb, 0xf1, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, 0xe, 0x11, + 0x11, 0x11, 0xe1, 0x0, 0x0, 0xf, 0xbb, 0xbb, + 0xbb, 0xe1, 0x0, + + /* U+7B56 "策" */ + 0x0, 0x85, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x1, + 0xfc, 0xbb, 0x8a, 0xeb, 0xbb, 0xb1, 0xc, 0x58, + 0x81, 0x8c, 0x1a, 0x61, 0x10, 0x38, 0x1, 0x90, + 0xc7, 0x2, 0x80, 0x0, 0xb, 0xbb, 0xbb, 0xde, + 0xbb, 0xbb, 0xb0, 0x0, 0x0, 0x0, 0x79, 0x0, + 0x0, 0x0, 0x0, 0xdd, 0xdd, 0xee, 0xdd, 0xdd, + 0x20, 0x0, 0xf0, 0x0, 0x68, 0x0, 0xc, 0x20, + 0x0, 0xf0, 0x0, 0xab, 0x0, 0xc, 0x20, 0x0, + 0xe0, 0x9, 0xde, 0xa2, 0xbc, 0x10, 0x0, 0x5, + 0xc5, 0x68, 0x4d, 0x71, 0x0, 0x17, 0xc9, 0x20, + 0x68, 0x1, 0x8e, 0xb2, 0x6, 0x10, 0x0, 0x68, + 0x0, 0x0, 0x50, + + /* U+7B97 "算" */ + 0x0, 0x93, 0x0, 0x2, 0xa0, 0x0, 0x0, 0x3, + 0xfc, 0xcc, 0xab, 0xec, 0xcc, 0xc1, 0x1d, 0x36, + 0x90, 0x8a, 0x5, 0xb0, 0x0, 0x14, 0x4a, 0xd9, + 0xca, 0x9a, 0xd7, 0x0, 0x0, 0x78, 0x11, 0x11, + 0x11, 0x4b, 0x0, 0x0, 0x7c, 0x99, 0x99, 0x99, + 0xbb, 0x0, 0x0, 0x7b, 0x77, 0x77, 0x77, 0x9b, + 0x0, 0x0, 0x78, 0x11, 0x11, 0x11, 0x4b, 0x0, + 0x0, 0x5a, 0xdc, 0xaa, 0xaf, 0xa7, 0x0, 0x0, + 0x0, 0x95, 0x0, 0xf, 0x0, 0x0, 0x2c, 0xcc, + 0xfd, 0xcc, 0xcf, 0xcc, 0xc3, 0x0, 0x1b, 0x90, + 0x0, 0xf, 0x0, 0x0, 0x8, 0xb4, 0x0, 0x0, + 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7BA1 "管" */ + 0x1, 0xc0, 0x0, 0x1, 0xb0, 0x0, 0x0, 0x6e, + 0xbb, 0xb6, 0x6e, 0xbb, 0xba, 0x1d, 0x15, 0x80, + 0x1d, 0x15, 0xa0, 0x4, 0x60, 0x7, 0xb, 0x30, + 0x7, 0x0, 0x9, 0xcb, 0xbb, 0xdd, 0xbb, 0xbc, + 0x70, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x59, 0x7, + 0x5e, 0xbb, 0xbb, 0xbb, 0xe3, 0x60, 0x3, 0xb0, + 0x0, 0x0, 0xe, 0x0, 0x0, 0x3e, 0xbb, 0xbb, + 0xbb, 0xa0, 0x0, 0x3, 0xc1, 0x11, 0x11, 0x11, + 0x10, 0x0, 0x3e, 0x99, 0x99, 0x99, 0xb9, 0x0, + 0x3, 0xb0, 0x0, 0x0, 0x4, 0x90, 0x0, 0x3e, + 0xbb, 0xbb, 0xbb, 0xc9, 0x0, + + /* U+7BC0 "節" */ + 0x0, 0x67, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, + 0xdd, 0xbb, 0xb1, 0xed, 0xcc, 0xc6, 0x8, 0x82, + 0xc0, 0xb, 0x51, 0xd1, 0x0, 0xa, 0x0, 0xa1, + 0x38, 0x0, 0x67, 0x0, 0x2, 0xbb, 0xbb, 0xb0, + 0xab, 0xbb, 0xb0, 0x2, 0xa0, 0x0, 0xe0, 0xe1, + 0x11, 0xe0, 0x2, 0xeb, 0xbb, 0xf0, 0xe0, 0x0, + 0xe0, 0x2, 0xa0, 0x0, 0xe0, 0xe0, 0x0, 0xe0, + 0x2, 0xeb, 0xbb, 0xf0, 0xe0, 0x0, 0xe0, 0x2, + 0xa0, 0x17, 0x0, 0xe0, 0x0, 0xe0, 0x3, 0xa0, + 0x2c, 0x50, 0xe0, 0xaa, 0xd0, 0x7, 0xee, 0xb7, + 0xd1, 0xe0, 0x22, 0x0, 0x3, 0x40, 0x0, 0x41, + 0xe0, 0x0, 0x0, + + /* U+7BC4 "範" */ + 0x0, 0xc1, 0x0, 0x6, 0x80, 0x0, 0x0, 0x6, + 0xfc, 0xcc, 0x9e, 0xec, 0xcc, 0xc4, 0x3d, 0xc, + 0x21, 0xc5, 0xb, 0x50, 0x0, 0x33, 0x8, 0x20, + 0x40, 0x1, 0x50, 0x0, 0x4b, 0xbe, 0xcb, 0xa6, + 0xed, 0xdd, 0xb0, 0x3, 0x3b, 0x53, 0x17, 0x70, + 0x1, 0xc0, 0xd, 0x6c, 0x89, 0x87, 0x70, 0x1, + 0xc0, 0xe, 0xae, 0xbb, 0x87, 0x70, 0x1, 0xc0, + 0xc, 0xa, 0x23, 0x87, 0x70, 0x89, 0xb0, 0xc, + 0xae, 0xba, 0x77, 0x70, 0x55, 0x10, 0x1, 0x1a, + 0x31, 0x17, 0x70, 0x0, 0x32, 0x6a, 0xae, 0xba, + 0xa8, 0x70, 0x0, 0x86, 0x0, 0xa, 0x20, 0x3, + 0xee, 0xde, 0xd1, + + /* U+7C21 "簡" */ + 0x0, 0xb0, 0x0, 0x7, 0x50, 0x0, 0x0, 0x6, + 0xfb, 0xbb, 0x7f, 0xcb, 0xbb, 0xb2, 0x3d, 0x1c, + 0x11, 0xd3, 0xc, 0x50, 0x0, 0x25, 0x37, 0x54, + 0x33, 0x36, 0x83, 0x20, 0xb, 0x86, 0x6e, 0xd, + 0x76, 0x68, 0xa0, 0xb, 0xa9, 0x9e, 0xd, 0x99, + 0x9a, 0xa0, 0xb, 0x53, 0x3d, 0xd, 0x43, 0x36, + 0xa0, 0xb, 0x76, 0x66, 0x5, 0x66, 0x68, 0xa0, + 0xb, 0x20, 0xc9, 0x99, 0xc4, 0x3, 0xa0, 0xb, + 0x20, 0xd0, 0x0, 0xa5, 0x3, 0xa0, 0xb, 0x20, + 0xd8, 0x88, 0xd5, 0x3, 0xa0, 0xb, 0x20, 0xd9, + 0x99, 0xd5, 0x3, 0xa0, 0xb, 0x20, 0x60, 0x0, + 0x5, 0xdd, 0x60, + + /* U+7C73 "米" */ + 0x0, 0x0, 0x0, 0x87, 0x0, 0x1, 0x0, 0x1, + 0xd0, 0x0, 0x87, 0x0, 0xd, 0x30, 0x0, 0x98, + 0x0, 0x87, 0x0, 0x6b, 0x0, 0x0, 0x1e, 0x10, + 0x87, 0x0, 0xe2, 0x0, 0x0, 0x7, 0x40, 0x87, + 0x5, 0x80, 0x0, 0x1, 0x11, 0x11, 0x88, 0x11, + 0x11, 0x10, 0x2d, 0xdd, 0xde, 0xff, 0xed, 0xdd, + 0xd1, 0x0, 0x0, 0xb, 0xcb, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x96, 0x87, 0x69, 0x0, 0x0, 0x0, + 0x9, 0x90, 0x87, 0x9, 0xa0, 0x0, 0x1, 0xba, + 0x0, 0x87, 0x0, 0x8c, 0x20, 0x3e, 0x70, 0x0, + 0x87, 0x0, 0x5, 0xe3, 0x2, 0x0, 0x0, 0x87, + 0x0, 0x0, 0x10, + + /* U+7CBE "精" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x67, 0x0, 0x0, 0xd, 0x0, 0x0, 0x19, 0x67, + 0x75, 0xab, 0xbf, 0xcb, 0xb2, 0xb, 0x67, 0xb0, + 0x0, 0xe, 0x10, 0x0, 0x9, 0x88, 0xa0, 0x5b, + 0xbf, 0xbb, 0xa0, 0x3, 0x89, 0x31, 0x44, 0x4e, + 0x44, 0x42, 0x4b, 0xed, 0xb3, 0x66, 0x66, 0x66, + 0x64, 0x0, 0xdc, 0x0, 0x3b, 0xbb, 0xbb, 0x70, + 0x2, 0xfd, 0x60, 0x58, 0x0, 0x3, 0xa0, 0x8, + 0xa7, 0xd1, 0x5d, 0xaa, 0xac, 0xa0, 0x1d, 0x67, + 0x30, 0x58, 0x0, 0x3, 0xa0, 0x65, 0x67, 0x0, + 0x5d, 0xbb, 0xbc, 0xa0, 0x0, 0x67, 0x0, 0x58, + 0x0, 0x3, 0xa0, 0x0, 0x67, 0x0, 0x58, 0x0, + 0x9c, 0x70, + + /* U+7CD6 "糖" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x0, 0x0, 0x77, 0x0, 0x0, 0x15, 0x85, + 0x71, 0x0, 0x2e, 0x0, 0x0, 0xb, 0x85, 0xc5, + 0xec, 0xcf, 0xcc, 0xc3, 0xb, 0x88, 0x75, 0x83, + 0x4e, 0x44, 0x30, 0x4, 0x97, 0x25, 0x84, 0x5e, + 0x55, 0xc0, 0x4b, 0xed, 0xb5, 0xca, 0xaf, 0xaa, + 0xf6, 0x0, 0xe6, 0x5, 0x70, 0xd, 0x0, 0xc0, + 0x4, 0xfe, 0x27, 0x69, 0xbf, 0xbb, 0xc0, 0xa, + 0xa8, 0xb8, 0x40, 0xd, 0x0, 0x0, 0x3b, 0x85, + 0x3a, 0x2c, 0xce, 0xcc, 0xb0, 0x73, 0x85, 0xc, + 0xd, 0x0, 0x0, 0xd0, 0x0, 0x85, 0x39, 0xd, + 0x0, 0x0, 0xd0, 0x0, 0x85, 0x91, 0xe, 0xcc, + 0xcc, 0xd0, + + /* U+7CFB "系" */ + 0x0, 0x0, 0x0, 0x24, 0x69, 0x90, 0x1, 0xbc, + 0xde, 0xfc, 0x97, 0x41, 0x0, 0x2, 0x10, 0xa7, + 0x0, 0x11, 0x0, 0x0, 0x1, 0xb5, 0x0, 0x4d, + 0x50, 0x0, 0x3, 0xec, 0xaa, 0xcd, 0x20, 0x0, + 0x0, 0x14, 0x36, 0xe9, 0x2, 0x80, 0x0, 0x0, + 0x1a, 0xb2, 0x0, 0xa, 0x80, 0x1, 0x8f, 0xd9, + 0xab, 0xcc, 0xce, 0x50, 0x8, 0x64, 0x33, 0xd0, + 0x0, 0x1c, 0x0, 0x3, 0xd0, 0x1d, 0x7, 0xa0, + 0x0, 0x3, 0xe3, 0x1, 0xd0, 0x7, 0xc1, 0x5, + 0xe3, 0x0, 0x2d, 0x0, 0x6, 0xd1, 0x1, 0x1, + 0xee, 0x90, 0x0, 0x2, 0x0, + + /* U+7D00 "紀" */ + 0x0, 0x7, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0x0, 0x3f, 0xff, 0xff, 0xc0, 0x0, 0xa5, + 0x22, 0x0, 0x0, 0x2, 0xc0, 0x4, 0xa0, 0xb6, + 0x0, 0x0, 0x2, 0xc0, 0x2e, 0x9a, 0xb0, 0x0, + 0x0, 0x2, 0xc0, 0x18, 0x7d, 0x21, 0x2, 0x22, + 0x25, 0xc0, 0x0, 0xc2, 0x59, 0x1f, 0xbb, 0xbc, + 0xc0, 0x1c, 0xcb, 0xce, 0x2e, 0x0, 0x0, 0x20, + 0x7, 0x41, 0x6, 0x2e, 0x0, 0x0, 0x0, 0x6, + 0x19, 0x2a, 0x1e, 0x0, 0x0, 0x0, 0xc, 0xc, + 0xd, 0x2e, 0x0, 0x0, 0x47, 0x1c, 0xb, 0x17, + 0x4e, 0x0, 0x0, 0x68, 0x37, 0x4, 0x0, 0xb, + 0xed, 0xde, 0xd2, + + /* U+7D04 "約" */ + 0x0, 0x5, 0x20, 0x1, 0x60, 0x0, 0x0, 0x2, + 0xd0, 0x0, 0x78, 0x0, 0x0, 0x0, 0xa5, 0x11, + 0xc, 0x30, 0x0, 0x0, 0x69, 0xa, 0x73, 0xfd, + 0xdd, 0xec, 0x4f, 0x9a, 0xb0, 0xc4, 0x0, 0x2, + 0xc2, 0x56, 0xd3, 0x49, 0x0, 0x0, 0x3b, 0x1, + 0xc2, 0x2b, 0x6, 0xa0, 0x4, 0xa2, 0xec, 0xbc, + 0xe1, 0x9, 0x80, 0x4a, 0x26, 0x31, 0x5, 0x10, + 0xc, 0x35, 0x90, 0x71, 0x91, 0xb0, 0x0, 0x10, + 0x78, 0xd, 0xc, 0xb, 0x10, 0x0, 0x9, 0x63, + 0xa0, 0xa2, 0x53, 0x0, 0x0, 0xc3, 0x44, 0x3, + 0x0, 0x0, 0x5e, 0xfb, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+7D19 "紙" */ + 0x0, 0x5, 0x0, 0x0, 0x0, 0x1, 0x30, 0x0, + 0x3c, 0x0, 0x36, 0x8a, 0xdc, 0x70, 0x0, 0xb4, + 0x20, 0xc7, 0x53, 0xd0, 0x0, 0x5, 0x90, 0xc2, + 0xc1, 0x0, 0xd0, 0x0, 0x2e, 0x8a, 0x80, 0xc1, + 0x0, 0xd0, 0x0, 0x27, 0x7d, 0x20, 0xc1, 0x0, + 0xd0, 0x0, 0x1, 0xc2, 0x92, 0xce, 0xdd, 0xfe, + 0xd0, 0x1c, 0xa9, 0xc8, 0xc1, 0x0, 0xc1, 0x0, + 0x29, 0x63, 0x17, 0xc1, 0x0, 0xa2, 0x0, 0x7, + 0x16, 0x82, 0xc1, 0x0, 0x85, 0x0, 0xd, 0xc, + 0x47, 0xc1, 0x0, 0x49, 0x9, 0x2a, 0xc, 0x5, + 0xd5, 0x8c, 0xd, 0x2a, 0x45, 0x3, 0x1, 0xfb, + 0x61, 0x5, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7D20 "素" */ + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x6, + 0xcc, 0xcc, 0xee, 0xcc, 0xcc, 0x70, 0x0, 0x0, + 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x8b, 0xbb, + 0xdd, 0xbb, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x87, + 0x0, 0x0, 0x0, 0x2b, 0xbb, 0xbd, 0xeb, 0xbb, + 0xbb, 0xb3, 0x0, 0x2, 0x99, 0x20, 0x5a, 0x0, + 0x0, 0x0, 0x5d, 0xbb, 0xfe, 0x71, 0x10, 0x0, + 0x0, 0x4, 0x9b, 0x50, 0x4, 0xd4, 0x0, 0x6, + 0xef, 0xdb, 0xce, 0xa9, 0x8c, 0x60, 0x0, 0x4, + 0x70, 0x3a, 0x7, 0x40, 0x20, 0x2, 0xab, 0x10, + 0x4a, 0x1, 0x9b, 0x20, 0xa, 0x40, 0x2d, 0xd6, + 0x0, 0x3, 0x90, + + /* U+7D30 "細" */ + 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, + 0x80, 0xd, 0xfe, 0xfe, 0xef, 0x0, 0xc0, 0x60, + 0xd0, 0xd, 0x0, 0xe0, 0x76, 0x3a, 0xd, 0x0, + 0xd0, 0xe, 0x4f, 0xad, 0x20, 0xd0, 0xd, 0x0, + 0xe1, 0x48, 0x74, 0xd, 0x0, 0xd0, 0xe, 0x2, + 0xb0, 0xa1, 0xde, 0xdf, 0xdd, 0xf2, 0xea, 0xbd, + 0x5d, 0x0, 0xd0, 0xe, 0x16, 0x30, 0x22, 0xd0, + 0xd, 0x0, 0xe0, 0x93, 0x5a, 0xd, 0x0, 0xd0, + 0xe, 0xb, 0x29, 0x64, 0xd0, 0xd, 0x0, 0xe4, + 0x80, 0xb2, 0x5d, 0xed, 0xfd, 0xdf, 0x44, 0x3, + 0x0, 0xd0, 0x0, 0x0, 0xc0, + + /* U+7D39 "紹" */ + 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0x0, 0xbd, 0xee, 0xdd, 0xf1, 0x0, 0xd2, + 0x41, 0x0, 0xa6, 0x0, 0xd0, 0x8, 0x61, 0xd1, + 0x0, 0xe2, 0x0, 0xe0, 0x4f, 0xbe, 0x40, 0x6, + 0xa0, 0x0, 0xd0, 0x12, 0x79, 0x50, 0x6c, 0x12, + 0xac, 0x80, 0x4, 0xb0, 0x75, 0x50, 0x0, 0x21, + 0x0, 0x3f, 0xdc, 0xba, 0x8b, 0xbb, 0xbb, 0x80, + 0x3, 0x0, 0x25, 0xa5, 0x11, 0x14, 0xb0, 0xa, + 0x28, 0x83, 0xa3, 0x0, 0x3, 0xb0, 0xc, 0xb, + 0x48, 0xa3, 0x0, 0x3, 0xb0, 0x2a, 0xc, 0x8, + 0xa5, 0x22, 0x25, 0xb0, 0x45, 0x6, 0x0, 0xac, + 0xaa, 0xab, 0xb0, + + /* U+7D42 "終" */ + 0x0, 0x6, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, + 0x4b, 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, 0xc2, + 0x20, 0xd, 0xcc, 0xcf, 0x40, 0x5, 0x91, 0xe1, + 0xae, 0x50, 0x4d, 0x0, 0x2e, 0x7b, 0x66, 0x91, + 0xd3, 0xd3, 0x0, 0x38, 0x9c, 0x10, 0x0, 0x4f, + 0x70, 0x0, 0x1, 0xc2, 0xc0, 0x4, 0xd8, 0xd4, + 0x0, 0x1c, 0x97, 0xd4, 0xbc, 0x30, 0x2c, 0xa2, + 0x2a, 0x74, 0x65, 0x40, 0xaa, 0x20, 0x51, 0x6, + 0x23, 0x90, 0x0, 0x4, 0xd1, 0x0, 0xc, 0x28, + 0x83, 0x15, 0x0, 0x0, 0x0, 0x2a, 0xa, 0x36, + 0x28, 0xda, 0x40, 0x0, 0x56, 0x6, 0x0, 0x0, + 0x3, 0xad, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x0, + + /* U+7D44 "組" */ + 0x0, 0x8, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4c, 0x0, 0xd, 0xdd, 0xde, 0xa0, 0x0, 0xc2, + 0x34, 0xd, 0x0, 0x3, 0xa0, 0x7, 0x60, 0xd5, + 0xd, 0x0, 0x3, 0xa0, 0x3f, 0xce, 0x90, 0xd, + 0xaa, 0xab, 0xa0, 0x1, 0x6c, 0x53, 0xd, 0x33, + 0x36, 0xa0, 0x3, 0xd1, 0x3b, 0xd, 0x0, 0x3, + 0xa0, 0x2e, 0xdc, 0xce, 0xd, 0x0, 0x3, 0xa0, + 0x5, 0x20, 0x6, 0x1d, 0xdd, 0xde, 0xa0, 0x9, + 0x9, 0x39, 0xd, 0x0, 0x3, 0xa0, 0xd, 0xc, + 0xd, 0xd, 0x0, 0x3, 0xa0, 0x1b, 0xc, 0x7, + 0xd, 0x0, 0x3, 0xa0, 0x47, 0x6, 0x2, 0xdf, + 0xdd, 0xde, 0xf8, + + /* U+7D4C "経" */ + 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6a, 0x1, 0xde, 0xdd, 0xde, 0xb0, 0x0, 0xd2, + 0x52, 0xd, 0x20, 0xc, 0x40, 0x7, 0x81, 0xe2, + 0x5, 0xb0, 0x6b, 0x0, 0x3f, 0x8c, 0x60, 0x0, + 0xab, 0xd1, 0x0, 0x38, 0x9b, 0x20, 0x1, 0xae, + 0xc2, 0x0, 0x2, 0xc1, 0xc3, 0x9b, 0x42, 0x4c, + 0xb4, 0x2e, 0xba, 0xc8, 0x20, 0xc, 0x10, 0x21, + 0x15, 0x20, 0x33, 0x5b, 0xbf, 0xbb, 0x90, 0xb, + 0x47, 0x84, 0x12, 0x2d, 0x42, 0x20, 0xc, 0x29, + 0x38, 0x0, 0xc, 0x10, 0x0, 0x39, 0xb, 0xb, + 0x0, 0xc, 0x10, 0x0, 0x76, 0x9, 0x1, 0xdd, + 0xdf, 0xdd, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7D50 "結" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x78, + 0x0, 0x0, 0xf, 0x0, 0x0, 0x1, 0xd1, 0x53, + 0xdd, 0xdf, 0xdd, 0xd3, 0xa, 0x52, 0xe1, 0x0, + 0xf, 0x0, 0x0, 0x4f, 0xbe, 0x50, 0x0, 0xf, + 0x0, 0x0, 0x1, 0x6b, 0x70, 0x9d, 0xdf, 0xdd, + 0xc0, 0x2, 0xd1, 0x94, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0xaa, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x29, + 0x64, 0x29, 0x6e, 0xdd, 0xde, 0x70, 0x6, 0x14, + 0x90, 0x67, 0x0, 0x6, 0x70, 0xc, 0x1a, 0x65, + 0x67, 0x0, 0x6, 0x70, 0x2a, 0xc, 0x29, 0x68, + 0x22, 0x28, 0x70, 0x55, 0x7, 0x0, 0x6d, 0xaa, + 0xac, 0x70, + + /* U+7D61 "絡" */ + 0x0, 0x5, 0x0, 0x0, 0x34, 0x0, 0x0, 0x0, + 0x3c, 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, 0xc3, + 0x20, 0x7, 0xec, 0xcd, 0xc0, 0x5, 0x90, 0xe2, + 0x6e, 0xb0, 0xb, 0x50, 0x3e, 0x8b, 0x72, 0xd2, + 0x88, 0x8a, 0x0, 0x26, 0x8c, 0x30, 0x0, 0xd, + 0xe0, 0x0, 0x2, 0xc1, 0xc0, 0x1, 0xaa, 0xaa, + 0x10, 0x2d, 0xaa, 0xe5, 0x8d, 0x50, 0x5, 0xe6, + 0x17, 0x41, 0x35, 0x5f, 0xdd, 0xdd, 0xe1, 0x8, + 0x26, 0x92, 0xd, 0x0, 0x0, 0xd0, 0xc, 0x1a, + 0x57, 0xd, 0x0, 0x0, 0xd0, 0x2a, 0xc, 0x19, + 0xd, 0x11, 0x12, 0xd0, 0x45, 0x6, 0x0, 0xf, + 0xbb, 0xbc, 0xd0, + + /* U+7D66 "給" */ + 0x0, 0x7, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, + 0x4b, 0x0, 0x0, 0x2f, 0x60, 0x0, 0x0, 0xc3, + 0x20, 0x0, 0xb6, 0xd2, 0x0, 0x6, 0x81, 0xe2, + 0x8, 0x90, 0x3d, 0x10, 0x3f, 0x8b, 0x60, 0x9d, + 0x0, 0x6, 0xc2, 0x27, 0x9a, 0x36, 0xc9, 0xdd, + 0xdd, 0x5a, 0x3, 0xb0, 0xa4, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0xdc, 0xba, 0x2d, 0xdd, 0xdd, 0x90, + 0x3, 0x0, 0x25, 0x3b, 0x0, 0x3, 0xb0, 0xc, + 0x38, 0x84, 0x3a, 0x0, 0x3, 0xb0, 0xc, 0x1b, + 0x39, 0x3a, 0x0, 0x3, 0xb0, 0x49, 0xc, 0x4, + 0x3e, 0xbb, 0xbc, 0xb0, 0x33, 0x1, 0x0, 0x3b, + 0x22, 0x24, 0xb0, + + /* U+7D71 "統" */ + 0x0, 0x9, 0x0, 0x0, 0x72, 0x0, 0x0, 0x0, + 0x5a, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0xc2, + 0x44, 0xdd, 0xdf, 0xdd, 0xd2, 0x6, 0x81, 0xd1, + 0x1, 0xd2, 0x22, 0x0, 0x3f, 0x9c, 0x60, 0xa, + 0x60, 0x3c, 0x0, 0x27, 0x8c, 0x20, 0x7e, 0x56, + 0x8e, 0x70, 0x1, 0xc1, 0xc2, 0xca, 0x86, 0x53, + 0xd1, 0xb, 0x97, 0xc6, 0x7, 0x31, 0x80, 0x10, + 0x2a, 0x74, 0x48, 0xb, 0x31, 0xc0, 0x0, 0x5, + 0x23, 0x90, 0xd, 0x11, 0xc0, 0x0, 0xc, 0x38, + 0xa1, 0x1d, 0x1, 0xc0, 0x43, 0x1a, 0x1a, 0x43, + 0xa7, 0x1, 0xc0, 0x75, 0x46, 0x6, 0xc, 0xa0, + 0x0, 0xcd, 0xe2, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x0, + + /* U+7D75 "絵" */ + 0x0, 0x8, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, + 0x5a, 0x0, 0x0, 0x7f, 0x20, 0x0, 0x0, 0xc2, + 0x40, 0x2, 0xd4, 0xc0, 0x0, 0x6, 0x71, 0xd0, + 0x1d, 0x30, 0x5c, 0x10, 0x3f, 0xad, 0x42, 0xd6, + 0x0, 0x6, 0xd1, 0x15, 0x98, 0x36, 0x5d, 0xdd, + 0xdc, 0x63, 0x3, 0xa0, 0xa1, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0xdc, 0xc7, 0xdd, 0xdd, 0xdd, 0xd0, + 0x3, 0x0, 0x43, 0x1, 0xd1, 0x0, 0x0, 0xb, + 0x47, 0xb0, 0x9, 0x60, 0x64, 0x0, 0xc, 0x29, + 0x84, 0x2c, 0x0, 0x1c, 0x10, 0x39, 0xb, 0x14, + 0xda, 0x89, 0xae, 0x90, 0x23, 0x1, 0x3, 0x75, + 0x43, 0x10, 0x90, + + /* U+7D93 "經" */ + 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x68, 0x5, 0xdd, 0xdd, 0xdd, 0xd0, 0x0, 0xc1, + 0x50, 0x25, 0x7, 0x3, 0x40, 0x7, 0x63, 0xa0, + 0xb3, 0x4a, 0xc, 0x10, 0x3f, 0xad, 0x24, 0x90, + 0xc1, 0x87, 0x0, 0x14, 0x87, 0x42, 0xc0, 0xb4, + 0x4a, 0x0, 0x3, 0xb0, 0xb0, 0x77, 0x1d, 0x8, + 0x60, 0x2e, 0xcc, 0xe2, 0x6, 0x4, 0x10, 0x60, + 0x15, 0x20, 0x43, 0xdd, 0xdd, 0xdd, 0x70, 0x9, + 0x36, 0xb0, 0x0, 0x3a, 0x0, 0x0, 0xc, 0x29, + 0xa0, 0x0, 0x3a, 0x0, 0x0, 0x2a, 0x1b, 0x51, + 0x0, 0x3a, 0x0, 0x0, 0x56, 0x6, 0xc, 0xdd, + 0xef, 0xdd, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7D9A "続" */ + 0x0, 0x47, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, + 0xb3, 0x0, 0xaa, 0xae, 0xba, 0xa4, 0x2, 0xb0, + 0x81, 0x22, 0x2c, 0x42, 0x21, 0xb, 0x25, 0xb0, + 0x48, 0x8d, 0x98, 0x70, 0x5f, 0xcf, 0x20, 0x24, + 0x44, 0x44, 0x40, 0x0, 0x98, 0x50, 0xbb, 0xbb, + 0xbb, 0xb3, 0x4, 0xc0, 0xd0, 0xd0, 0x0, 0x0, + 0x84, 0x2e, 0xa9, 0xc5, 0x90, 0x60, 0x52, 0x63, + 0x14, 0x10, 0x32, 0x2, 0xb0, 0x93, 0x0, 0x9, + 0x35, 0xa1, 0x4, 0xa0, 0x93, 0x0, 0xc, 0x29, + 0x66, 0xa, 0x60, 0x93, 0x5, 0x2a, 0xa, 0x27, + 0x5d, 0x0, 0x94, 0x1a, 0x45, 0x4, 0x6, 0xd2, + 0x0, 0x5d, 0xd6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7DAD "維" */ + 0x0, 0x5, 0x0, 0x0, 0x41, 0x20, 0x0, 0x0, + 0x4b, 0x0, 0x5, 0xb3, 0xc0, 0x0, 0x0, 0xc2, + 0x20, 0xc, 0x40, 0x91, 0x0, 0x7, 0x81, 0xd1, + 0x5f, 0xdd, 0xfd, 0xd4, 0x3f, 0x9c, 0x51, 0xed, + 0x0, 0xd0, 0x0, 0x2, 0x7a, 0x74, 0x5f, 0xaa, + 0xfa, 0xa0, 0x3, 0xb0, 0x67, 0xd, 0x22, 0xe2, + 0x20, 0x1e, 0xcc, 0xbc, 0xd, 0x0, 0xd0, 0x0, + 0x4, 0x10, 0x24, 0xf, 0xdd, 0xfd, 0xd1, 0xa, + 0x28, 0x65, 0xd, 0x0, 0xd0, 0x0, 0xc, 0xb, + 0x2b, 0xd, 0x0, 0xd0, 0x0, 0x29, 0xc, 0x8, + 0xf, 0xdd, 0xfd, 0xd7, 0x23, 0x2, 0x0, 0xd, + 0x0, 0x0, 0x0, + + /* U+7DB2 "網" */ + 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xb0, 0xf, 0xdd, 0xdd, 0xdf, 0x0, 0xc2, 0x51, + 0xd1, 0x50, 0x61, 0xd0, 0x76, 0x2d, 0xd, 0xa, + 0xb, 0xd, 0x3f, 0xce, 0x50, 0xd7, 0xba, 0xd7, + 0xd0, 0x16, 0xb6, 0xd, 0x13, 0x92, 0x1d, 0x1, + 0xd1, 0xa2, 0xd0, 0xb, 0x0, 0xd1, 0xcb, 0x9d, + 0x6d, 0x7e, 0xcc, 0x7d, 0x18, 0x53, 0x37, 0xd1, + 0xa0, 0x0, 0xd0, 0x62, 0x3a, 0xd, 0x1b, 0x22, + 0x1d, 0xc, 0x28, 0x92, 0xd0, 0x99, 0x95, 0xd2, + 0xa0, 0xa3, 0x3d, 0x0, 0x0, 0xe, 0x24, 0x2, + 0x0, 0xd0, 0x0, 0x3d, 0xa0, + + /* U+7DD1 "緑" */ + 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4c, 0x0, 0x7c, 0xcc, 0xce, 0x60, 0x0, 0xc3, + 0x32, 0x0, 0x0, 0x7, 0x60, 0x6, 0x80, 0xd3, + 0x3c, 0xcc, 0xce, 0x60, 0x3f, 0xac, 0x80, 0x0, + 0x0, 0x7, 0x60, 0x14, 0x6c, 0x41, 0xdd, 0xdd, + 0xde, 0xe6, 0x2, 0xc1, 0x84, 0x20, 0xc, 0x10, + 0x20, 0x2e, 0xbb, 0xd9, 0x7a, 0xc, 0x13, 0xc2, + 0x16, 0x31, 0x18, 0x7, 0x4c, 0xbb, 0x10, 0x9, + 0x35, 0xb0, 0x1, 0xbf, 0xb6, 0x0, 0xc, 0x29, + 0x74, 0x6c, 0x3c, 0x2b, 0x70, 0x39, 0xb, 0x25, + 0x90, 0xc, 0x10, 0x86, 0x44, 0x3, 0x0, 0x3, + 0xcd, 0x0, 0x0, + + /* U+7DD2 "緒" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, 0x78, + 0x0, 0x0, 0x3b, 0x0, 0xa3, 0x0, 0xd1, 0x41, + 0x5d, 0xef, 0xdb, 0xb0, 0x7, 0x71, 0xe1, 0x0, + 0x3b, 0xc, 0x20, 0x3f, 0x8b, 0x60, 0x11, 0x4b, + 0x8a, 0x11, 0x28, 0x9b, 0x21, 0xbb, 0xcf, 0xdb, + 0xb8, 0x1, 0xc0, 0xc1, 0x4, 0xc8, 0x0, 0x0, + 0x2d, 0xba, 0xe8, 0xaf, 0xec, 0xcc, 0xf0, 0x17, + 0x41, 0x37, 0x59, 0x50, 0x0, 0xe0, 0xa, 0x36, + 0xa2, 0x8, 0xdb, 0xbb, 0xf0, 0xc, 0x29, 0x67, + 0x8, 0x50, 0x0, 0xe0, 0x2a, 0x1b, 0x29, 0x8, + 0x71, 0x11, 0xf0, 0x45, 0x7, 0x0, 0x8, 0xca, + 0xaa, 0xe0, + + /* U+7DDA "線" */ + 0x0, 0x5, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, + 0x4b, 0x0, 0x0, 0x6a, 0x0, 0x0, 0x0, 0xb3, + 0x20, 0xbc, 0xbb, 0xbb, 0xe0, 0x4, 0xa1, 0xd0, + 0xb1, 0x0, 0x0, 0xe0, 0x2e, 0x8b, 0x60, 0xbc, + 0xbb, 0xbb, 0xe0, 0x17, 0x8c, 0x20, 0xb1, 0x0, + 0x0, 0xe0, 0x1, 0xc1, 0xb0, 0x9c, 0xcf, 0xcc, + 0xb0, 0x1c, 0xb9, 0xe1, 0x0, 0xe, 0x20, 0x61, + 0x9, 0x53, 0x66, 0xcd, 0x8e, 0xaa, 0x80, 0x7, + 0x35, 0xa0, 0xb, 0x1e, 0xc8, 0x0, 0xc, 0x29, + 0xa0, 0x79, 0xe, 0x1d, 0x30, 0x1b, 0xb, 0x29, + 0x90, 0xe, 0x3, 0xd5, 0x24, 0x1, 0x1, 0x6, + 0xdc, 0x0, 0x1, + + /* U+7DE0 "締" */ + 0x0, 0x1c, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, + 0x78, 0x0, 0xaa, 0xaf, 0xaa, 0xa3, 0x0, 0xd0, + 0x72, 0x2a, 0x32, 0x3c, 0x20, 0x8, 0x52, 0xd0, + 0x7, 0x40, 0x68, 0x0, 0x3f, 0xdf, 0x52, 0xbd, + 0xcb, 0xed, 0xb5, 0x2, 0x7a, 0x52, 0xa0, 0x5, + 0x0, 0x57, 0x2, 0xc0, 0xa4, 0x40, 0xd, 0x0, + 0x23, 0x1d, 0xbb, 0xd8, 0x6d, 0xcf, 0xcc, 0xb0, + 0x17, 0x41, 0x27, 0x84, 0xd, 0x0, 0xd0, 0x8, + 0x35, 0xb0, 0x84, 0xd, 0x0, 0xd0, 0xc, 0x28, + 0x75, 0x84, 0xd, 0x0, 0xd0, 0x2a, 0x1a, 0x37, + 0x63, 0xd, 0x3c, 0x70, 0x45, 0x5, 0x0, 0x0, + 0xd, 0x0, 0x0, + + /* U+7DE9 "緩" */ + 0x0, 0x8, 0x0, 0x1, 0x35, 0x7a, 0x30, 0x0, + 0x77, 0x5, 0xba, 0xa8, 0x56, 0x10, 0x0, 0xc0, + 0x60, 0xb1, 0x85, 0xd, 0x10, 0x8, 0x54, 0x90, + 0x65, 0x37, 0x77, 0x0, 0x4f, 0x9d, 0x12, 0xcc, + 0xcc, 0xed, 0x90, 0x14, 0x96, 0x40, 0x6, 0x70, + 0x0, 0x0, 0x3, 0xa0, 0xa7, 0xce, 0xec, 0xcc, + 0xc1, 0x2e, 0xab, 0xd4, 0xb, 0x30, 0x0, 0x0, + 0x16, 0x30, 0x22, 0xf, 0xdc, 0xce, 0x10, 0x8, + 0x35, 0xa0, 0x5c, 0xc0, 0x5b, 0x0, 0xb, 0x28, + 0x72, 0xc3, 0x7b, 0xd1, 0x0, 0x38, 0xa, 0x2b, + 0xa1, 0x9d, 0xd6, 0x0, 0x43, 0x3, 0xa, 0x6c, + 0x50, 0x2a, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7DF4 "練" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x78, + 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0xd1, 0x27, + 0xdd, 0xdf, 0xdd, 0xd1, 0x8, 0x72, 0xc0, 0x0, + 0x2b, 0x0, 0x0, 0x3f, 0x7c, 0x32, 0xec, 0xce, + 0xcd, 0xa0, 0x26, 0x97, 0x32, 0xa7, 0x2a, 0x38, + 0xa0, 0x3, 0xa0, 0xa2, 0xa5, 0x6a, 0x83, 0xa0, + 0x2f, 0xdb, 0xd5, 0xea, 0xbe, 0xab, 0xa0, 0x3, + 0x0, 0x52, 0x12, 0xee, 0xa1, 0x10, 0xb, 0x37, + 0xa0, 0xa, 0x8b, 0x94, 0x0, 0xc, 0x19, 0x90, + 0x8a, 0x2b, 0xc, 0x40, 0x39, 0xb, 0x38, 0xa0, + 0x2b, 0x1, 0xd0, 0x44, 0x3, 0x0, 0x0, 0x2b, + 0x0, 0x0, + + /* U+7E3D "總" */ + 0x0, 0x25, 0x0, 0x0, 0x37, 0x0, 0x0, 0x0, + 0x95, 0x0, 0x68, 0xca, 0x88, 0x60, 0x1, 0xd0, + 0x60, 0xc4, 0x77, 0x45, 0xb0, 0x8, 0x53, 0xa0, + 0xc0, 0xb9, 0xa6, 0xb0, 0x3f, 0x9d, 0x20, 0xc7, + 0x64, 0xa1, 0xb0, 0x14, 0x87, 0x20, 0xc0, 0x2d, + 0xa1, 0xb0, 0x2, 0xb0, 0xb0, 0xc4, 0x91, 0x43, + 0xb0, 0x1d, 0xbb, 0xd2, 0xcc, 0xcc, 0xcd, 0xb0, + 0x16, 0x20, 0x33, 0x0, 0x17, 0x0, 0x0, 0x5, + 0x23, 0x80, 0x75, 0x3a, 0x48, 0x40, 0xb, 0x38, + 0xa1, 0xb7, 0x51, 0x61, 0xc0, 0xb, 0x1a, 0x58, + 0x77, 0x50, 0xb, 0x84, 0x36, 0x5, 0x2, 0x4, + 0xdc, 0xc9, 0x0, + + /* U+7E3E "績" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x78, + 0x4, 0xbb, 0xbe, 0xbb, 0x90, 0x0, 0xd1, 0x61, + 0x66, 0x7d, 0x66, 0x30, 0x7, 0x72, 0xc0, 0x55, + 0x6d, 0x55, 0x20, 0x3f, 0xad, 0x3a, 0xbb, 0xce, + 0xbb, 0xb3, 0x15, 0x79, 0x30, 0x44, 0x44, 0x44, + 0x20, 0x1, 0xb0, 0xb0, 0xe5, 0x55, 0x59, 0x70, + 0x1d, 0xbb, 0xe2, 0xf9, 0x99, 0x9c, 0x70, 0x6, + 0x31, 0x53, 0xe5, 0x55, 0x59, 0x70, 0x8, 0x35, + 0xa0, 0xe4, 0x44, 0x49, 0x70, 0xb, 0x28, 0xa1, + 0xca, 0xaa, 0xab, 0x50, 0x1a, 0x1a, 0x31, 0x5c, + 0x40, 0x98, 0x0, 0x46, 0x5, 0xc, 0x81, 0x0, + 0x5, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+7E54 "織" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2a, 0x0, 0x28, 0x0, 0xc0, 0x0, 0x0, 0x76, + 0x0, 0xd, 0x10, 0xc4, 0x50, 0x0, 0xd1, 0x29, + 0xdc, 0xda, 0xc0, 0xc0, 0x5, 0x81, 0xc0, 0xa0, + 0xa2, 0xc0, 0x75, 0x1e, 0x9c, 0x45, 0xd5, 0xd5, + 0xd6, 0x63, 0x5, 0x7b, 0x25, 0x55, 0x55, 0xc7, + 0x53, 0x0, 0xb1, 0xa3, 0xcb, 0xc6, 0x93, 0x91, + 0xa, 0xcb, 0xe4, 0x70, 0x47, 0x86, 0xa0, 0x6, + 0x30, 0x54, 0xdb, 0xc7, 0x5d, 0x30, 0x6, 0x44, + 0x93, 0x70, 0x47, 0x4c, 0x0, 0xb, 0x37, 0xa4, + 0xda, 0xc9, 0xcd, 0x9, 0xb, 0x19, 0x66, 0x80, + 0x4f, 0x49, 0x78, 0x17, 0x4, 0x0, 0x0, 0x84, + 0x2, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+7E70 "繰" */ + 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4b, 0x0, 0x2e, 0xbb, 0xca, 0x0, 0x0, 0xb2, + 0x20, 0x2b, 0x0, 0x3a, 0x0, 0x5, 0x82, 0xc0, + 0x1a, 0x99, 0xa7, 0x0, 0x2e, 0xad, 0x35, 0xbb, + 0x94, 0xbb, 0xc0, 0x4, 0x7a, 0x36, 0x40, 0xc5, + 0x60, 0xc0, 0x2, 0xc0, 0xa6, 0xcb, 0xc5, 0xdb, + 0xe0, 0x1d, 0xba, 0xd0, 0x0, 0x28, 0x0, 0x0, + 0x5, 0x20, 0x69, 0xcc, 0xde, 0xcc, 0xc1, 0x9, + 0x47, 0x90, 0x6, 0xcc, 0xb0, 0x0, 0xc, 0x29, + 0x90, 0x5b, 0x4a, 0x5b, 0x0, 0x1b, 0x1a, 0x3b, + 0xa0, 0x3a, 0x5, 0xd2, 0x37, 0x4, 0x3, 0x0, + 0x3a, 0x0, 0x20, + + /* U+7E7C "繼" */ + 0x0, 0x5, 0x0, 0x1, 0x20, 0x13, 0x0, 0x0, + 0x58, 0xa, 0x28, 0x30, 0x83, 0x0, 0x0, 0xb2, + 0x2a, 0x5c, 0xa4, 0xc8, 0x50, 0x3, 0x93, 0x9a, + 0x6a, 0x73, 0x89, 0x20, 0xc, 0x7b, 0x2a, 0x6d, + 0xa7, 0xd8, 0xa0, 0x8, 0x99, 0xa, 0x65, 0x28, + 0x53, 0x70, 0x0, 0xb4, 0x6a, 0xaa, 0xa9, 0xab, + 0x90, 0x9, 0x96, 0xaa, 0x27, 0x30, 0x64, 0x0, + 0xa, 0x75, 0xaa, 0x5c, 0x94, 0xc6, 0x60, 0x5, + 0x35, 0x6a, 0x68, 0x82, 0x7b, 0x20, 0xb, 0x37, + 0xaa, 0x5c, 0x96, 0xb7, 0xb0, 0xb, 0x19, 0x9a, + 0x55, 0x37, 0x63, 0x60, 0x29, 0x8, 0x7, 0xbb, + 0xbb, 0xbb, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7E8C "續" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0x0, 0x0, 0x49, 0x0, 0x0, 0x0, 0x77, + 0xa, 0xaa, 0xce, 0xaa, 0xa1, 0x0, 0xc1, 0x42, + 0x66, 0x9c, 0x66, 0x30, 0x5, 0x83, 0x91, 0x44, + 0x44, 0x44, 0x20, 0x1e, 0x8c, 0x1d, 0xac, 0xca, + 0xea, 0xe0, 0x18, 0x98, 0xd, 0x16, 0x71, 0xb1, + 0xd0, 0x1, 0xb1, 0x97, 0x88, 0x88, 0x88, 0x80, + 0xc, 0xa9, 0xd5, 0xb8, 0x88, 0x8a, 0x70, 0x7, + 0x41, 0x77, 0xb7, 0x77, 0x7a, 0x80, 0x8, 0x46, + 0x96, 0xb7, 0x77, 0x7a, 0x80, 0xc, 0x28, 0xa6, + 0xc9, 0x99, 0x9b, 0x80, 0x1b, 0x1a, 0x40, 0x5c, + 0x20, 0xa8, 0x10, 0x36, 0x4, 0xc, 0x71, 0x0, + 0x4, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+7EDF "统" */ + 0x0, 0x1c, 0x0, 0x0, 0x84, 0x0, 0x0, 0x0, + 0x7a, 0x0, 0x0, 0x4b, 0x0, 0x0, 0x0, 0xd2, + 0x6, 0xdd, 0xde, 0xdd, 0xd1, 0x6, 0x90, 0xb1, + 0x3, 0xd0, 0x0, 0x0, 0x2d, 0x37, 0xb0, 0xd, + 0x30, 0x87, 0x0, 0x8e, 0xcf, 0x20, 0x98, 0x2, + 0x4e, 0x20, 0x0, 0x97, 0x9, 0xff, 0xdb, 0xaa, + 0xb0, 0x5, 0xb0, 0x21, 0x1a, 0x4, 0x60, 0x60, + 0x4f, 0xdd, 0xa0, 0x1d, 0x5, 0x80, 0x0, 0x35, + 0x10, 0x0, 0x3b, 0x5, 0x80, 0x0, 0x0, 0x15, + 0xa0, 0x87, 0x5, 0x80, 0x51, 0x4c, 0xd8, 0x34, + 0xd1, 0x5, 0x90, 0xa2, 0x22, 0x0, 0x6d, 0x30, + 0x2, 0xdd, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+7F3A "缺" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, + 0x60, 0x0, 0x0, 0xe, 0x0, 0x0, 0xa, 0x30, + 0x0, 0x0, 0xe, 0x0, 0x0, 0xe, 0xff, 0xfd, + 0x1, 0x1e, 0x11, 0x0, 0x59, 0x1b, 0x0, 0x4c, + 0xcf, 0xcf, 0x0, 0x72, 0x1b, 0x0, 0x0, 0xe, + 0xe, 0x0, 0x46, 0x7d, 0x66, 0x0, 0xe, 0xe, + 0x0, 0x35, 0x6d, 0x55, 0x22, 0x3d, 0x2e, 0x20, + 0x17, 0x1b, 0x8, 0x6a, 0xbf, 0xca, 0x90, 0x1a, + 0x1b, 0xc, 0x0, 0x7c, 0xa0, 0x0, 0x1a, 0x1b, + 0xc, 0x0, 0xc3, 0xc1, 0x0, 0x1a, 0x4d, 0x6c, + 0x3, 0xd0, 0x68, 0x0, 0x1c, 0xa7, 0x5c, 0x1d, + 0x30, 0xd, 0x50, 0x0, 0x0, 0x0, 0xa5, 0x0, + 0x2, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+7F6E "置" */ + 0x5, 0xdb, 0xbe, 0xbb, 0xeb, 0xbd, 0x70, 0x5, + 0x91, 0x3c, 0x11, 0xc3, 0x17, 0x70, 0x2, 0x77, + 0x77, 0xda, 0x77, 0x77, 0x30, 0xb, 0xbb, 0xbb, + 0xec, 0xbb, 0xbb, 0xa0, 0x0, 0x1, 0x11, 0xe1, + 0x11, 0x10, 0x0, 0x0, 0x4d, 0x88, 0x88, 0x88, + 0xd4, 0x0, 0x0, 0x4d, 0x99, 0x99, 0x99, 0xd4, + 0x0, 0x0, 0x4a, 0x11, 0x11, 0x11, 0xb4, 0x0, + 0x0, 0x4c, 0x88, 0x88, 0x88, 0xd4, 0x0, 0x0, + 0x4d, 0x99, 0x99, 0x99, 0xd4, 0x0, 0x0, 0x49, + 0x0, 0x0, 0x0, 0xa4, 0x0, 0x1b, 0xce, 0xbb, + 0xbb, 0xbb, 0xec, 0xb2, + + /* U+7F8E "美" */ + 0x0, 0x7, 0x50, 0x0, 0x6, 0x60, 0x0, 0x0, + 0x2, 0xe1, 0x0, 0x1e, 0x10, 0x0, 0x8, 0xdd, + 0xfd, 0xdd, 0xef, 0xdd, 0x80, 0x0, 0x0, 0x0, + 0x77, 0x0, 0x0, 0x0, 0x0, 0xcd, 0xdd, 0xee, + 0xdd, 0xdd, 0x0, 0x0, 0x0, 0x0, 0x77, 0x0, + 0x0, 0x0, 0x2b, 0xbb, 0xbb, 0xdd, 0xbb, 0xbb, + 0xb3, 0x1, 0x11, 0x11, 0xb5, 0x11, 0x11, 0x10, + 0xb, 0xcc, 0xcc, 0xfd, 0xcc, 0xcc, 0xc1, 0x0, + 0x0, 0x6, 0xbc, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x5e, 0x22, 0xd6, 0x0, 0x0, 0x3, 0x6c, 0xc2, + 0x0, 0x1b, 0xd7, 0x30, 0x2b, 0x73, 0x0, 0x0, + 0x0, 0x27, 0xb1, + + /* U+7FA9 "義" */ + 0x0, 0x1, 0x30, 0x0, 0x5, 0x20, 0x0, 0x0, + 0x1, 0xd1, 0x0, 0x1d, 0x10, 0x0, 0x7, 0xbb, + 0xbb, 0xdd, 0xbb, 0xbb, 0x70, 0x0, 0x56, 0x66, + 0xba, 0x66, 0x65, 0x0, 0x0, 0x33, 0x33, 0x99, + 0x33, 0x33, 0x0, 0x2b, 0xbb, 0xbb, 0xdd, 0xbb, + 0xbb, 0xb2, 0x4, 0x57, 0x9a, 0x84, 0x81, 0xa3, + 0x0, 0x5, 0x46, 0xb0, 0x3, 0xb0, 0x2b, 0x20, + 0x2b, 0xbc, 0xeb, 0xbc, 0xfc, 0xbc, 0xb3, 0x0, + 0x3, 0xb1, 0x31, 0xa4, 0x29, 0x0, 0x2b, 0xbc, + 0xe9, 0x72, 0x3d, 0xc1, 0x0, 0x0, 0x3, 0xb0, + 0x17, 0xcc, 0xa0, 0x75, 0x0, 0xbc, 0x71, 0xc6, + 0x0, 0x7d, 0xc1, + + /* U+7FD2 "習" */ + 0x3c, 0xcc, 0xcd, 0xac, 0xcc, 0xcc, 0x6, 0x40, + 0xd, 0x7, 0x20, 0xc, 0x2, 0x97, 0x1d, 0x5, + 0xa9, 0x3c, 0x0, 0x3a, 0xbd, 0x0, 0x6c, 0x9c, + 0x2c, 0xa3, 0xd, 0x6d, 0x71, 0xc, 0x1, 0x0, + 0x9, 0x50, 0x0, 0x7, 0x1, 0xbb, 0xbe, 0xcb, + 0xbb, 0xa0, 0x2, 0xc0, 0x0, 0x0, 0x1, 0xe0, + 0x2, 0xea, 0xaa, 0xaa, 0xab, 0xe0, 0x2, 0xc1, + 0x11, 0x11, 0x12, 0xe0, 0x2, 0xc0, 0x0, 0x0, + 0x1, 0xe0, 0x2, 0xfc, 0xcc, 0xcc, 0xcc, 0xe0, + + /* U+8001 "老" */ + 0x0, 0x0, 0x3, 0xb0, 0x0, 0x1, 0x10, 0x0, + 0x0, 0x3, 0xb0, 0x0, 0xb, 0x70, 0x0, 0xbd, + 0xde, 0xfd, 0xdd, 0xba, 0x0, 0x0, 0x0, 0x3, + 0xb0, 0x7, 0xc0, 0x0, 0x0, 0x0, 0x3, 0xb0, + 0x9c, 0x0, 0x0, 0x1e, 0xee, 0xee, 0xfe, 0xfe, + 0xee, 0xe6, 0x0, 0x0, 0x5, 0xd6, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xbd, 0x20, 0x0, 0x51, 0x0, + 0x3, 0xbd, 0x9a, 0x3, 0x9d, 0x92, 0x0, 0x1c, + 0x60, 0x4e, 0xd9, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x4b, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x4b, + 0x0, 0x0, 0x2, 0xd0, 0x0, 0x0, 0x1c, 0xdd, + 0xdd, 0xde, 0x50, + + /* U+8003 "考" */ + 0x0, 0x0, 0x1, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xc0, 0x0, 0xc, 0x20, 0x0, 0x9c, + 0xcd, 0xfc, 0xcc, 0xb4, 0x0, 0x0, 0x0, 0x1, + 0xc0, 0x2c, 0x30, 0x0, 0xc, 0xcc, 0xcc, 0xfc, + 0xfe, 0xcc, 0xc1, 0x0, 0x0, 0x2, 0xbc, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x6f, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x5d, 0xee, 0xbb, 0xbb, 0xb9, 0x0, + 0x2d, 0xb4, 0x96, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0xcc, 0xcc, 0xcc, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0x90, 0x0, 0x0, 0x0, 0x0, 0xad, + 0xdc, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8005 "者" */ + 0x0, 0x0, 0x5, 0x90, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x5, 0x90, 0x0, 0x1d, 0x30, 0x0, 0xdd, + 0xde, 0xed, 0xdd, 0xc4, 0x0, 0x0, 0x0, 0x5, + 0x90, 0xb, 0x60, 0x0, 0x0, 0x0, 0x5, 0x91, + 0xc7, 0x0, 0x0, 0x3d, 0xdd, 0xdd, 0xff, 0xdd, + 0xdd, 0xd3, 0x0, 0x0, 0x3b, 0xa1, 0x0, 0x0, + 0x0, 0x0, 0x4b, 0xff, 0xcc, 0xcc, 0xc6, 0x0, + 0x3d, 0x97, 0xa0, 0x0, 0x0, 0x77, 0x0, 0x0, + 0x4, 0xeb, 0xbb, 0xbb, 0xd7, 0x0, 0x0, 0x4, + 0xa0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x4, 0xa0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x4, 0xfd, 0xdd, + 0xdd, 0xe7, 0x0, + + /* U+800C "而" */ + 0x1e, 0xee, 0xee, 0xff, 0xee, 0xee, 0xe6, 0x0, + 0x0, 0x0, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe1, 0x0, 0x0, 0x0, 0x4, 0xed, 0xee, + 0xfd, 0xee, 0xde, 0xa0, 0x5, 0x90, 0xd, 0x0, + 0xa3, 0x3, 0xb0, 0x5, 0x90, 0xd, 0x0, 0xa3, + 0x3, 0xb0, 0x5, 0x90, 0xd, 0x0, 0xa3, 0x3, + 0xb0, 0x5, 0x90, 0xd, 0x0, 0xa3, 0x3, 0xb0, + 0x5, 0x90, 0xd, 0x0, 0xa3, 0x3, 0xb0, 0x5, + 0x90, 0xd, 0x0, 0xa3, 0x3, 0xb0, 0x5, 0x90, + 0xd, 0x0, 0xa3, 0x4, 0xb0, 0x5, 0x90, 0x8, + 0x0, 0x64, 0xdd, 0x60, + + /* U+8033 "耳" */ + 0x1e, 0xef, 0xfe, 0xee, 0xef, 0xfe, 0xe1, 0x0, + 0xd, 0x10, 0x0, 0x1, 0xe0, 0x0, 0x0, 0xd, + 0x10, 0x0, 0x1, 0xe0, 0x0, 0x0, 0xd, 0xed, + 0xdd, 0xde, 0xe0, 0x0, 0x0, 0xd, 0x10, 0x0, + 0x1, 0xe0, 0x0, 0x0, 0xd, 0x10, 0x0, 0x1, + 0xe0, 0x0, 0x0, 0xd, 0xed, 0xdd, 0xde, 0xe0, + 0x0, 0x0, 0xd, 0x10, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0xd, 0x10, 0x0, 0x13, 0xe4, 0x51, 0x2a, + 0xbf, 0xde, 0xee, 0xdc, 0xfa, 0x92, 0x15, 0x43, + 0x20, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xe0, 0x0, + + /* U+805E "聞" */ + 0xea, 0xaa, 0xf0, 0xbb, 0xaa, 0xbc, 0xe1, 0x11, + 0xe0, 0xb3, 0x11, 0x3c, 0xe9, 0x99, 0xf0, 0xba, + 0x99, 0xac, 0xe5, 0x55, 0xe0, 0xb7, 0x55, 0x6c, + 0xe4, 0x44, 0x40, 0x34, 0x44, 0x5c, 0xe0, 0xae, + 0xbb, 0xbe, 0xb1, 0x1c, 0xe0, 0xd, 0x55, 0x5d, + 0x0, 0x1c, 0xe0, 0xd, 0x44, 0x4d, 0x0, 0x1c, + 0xe0, 0xd, 0xa9, 0x9e, 0x0, 0x1c, 0xe0, 0x3d, + 0x56, 0x7e, 0x99, 0x1c, 0xe0, 0x98, 0x65, 0x4d, + 0x21, 0x2c, 0xe0, 0x0, 0x0, 0x7, 0x1e, 0xe8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+806F "聯" */ + 0x0, 0x0, 0x0, 0x4, 0x0, 0x4, 0x0, 0x1e, + 0xed, 0xf7, 0x39, 0x0, 0x38, 0x0, 0x4, 0x80, + 0xd0, 0xa2, 0x90, 0xa1, 0x80, 0x4, 0x80, 0xd6, + 0xed, 0x47, 0xee, 0x40, 0x4, 0xec, 0xe1, 0x59, + 0x11, 0x49, 0x30, 0x4, 0x80, 0xd3, 0xc3, 0xb2, + 0xc4, 0xa3, 0x4, 0xb5, 0xd6, 0x97, 0x88, 0x86, + 0x47, 0x4, 0xda, 0xd0, 0xb0, 0xc0, 0xc0, 0x60, + 0x4, 0x80, 0xd0, 0xc0, 0xc0, 0xd0, 0xc0, 0x4, + 0x81, 0xe3, 0xd7, 0xd0, 0xe7, 0xd0, 0x1d, 0xec, + 0xe4, 0x56, 0xc0, 0xe5, 0xc0, 0x1, 0x0, 0xd0, + 0x8, 0x60, 0xd0, 0x0, 0x0, 0x0, 0xd0, 0x87, + 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8072 "聲" */ + 0x0, 0x7, 0x50, 0x0, 0x0, 0x0, 0x0, 0x19, + 0x9c, 0xb9, 0x90, 0xea, 0xc7, 0x0, 0x6, 0x9a, + 0xa9, 0x59, 0x70, 0x3c, 0x90, 0x5, 0x99, 0x99, + 0x58, 0xc9, 0x9c, 0x10, 0x8, 0x36, 0x43, 0x80, + 0x68, 0x98, 0x0, 0xc, 0x98, 0x88, 0x54, 0x8d, + 0xd7, 0x30, 0x1b, 0x33, 0x33, 0x4b, 0x64, 0x47, + 0xb0, 0x7, 0x8e, 0x77, 0x77, 0x77, 0xf7, 0x70, + 0x0, 0xf, 0xaa, 0xaa, 0xaa, 0xf0, 0x0, 0x0, + 0xe, 0x44, 0x44, 0x44, 0xf0, 0x0, 0x0, 0xe, + 0x55, 0x55, 0x55, 0xf0, 0x0, 0x1b, 0xbf, 0xcc, + 0xcb, 0xbb, 0xfb, 0xb1, 0x1, 0x0, 0x0, 0x0, + 0x0, 0xe0, 0x0, + + /* U+8077 "職" */ + 0x0, 0x0, 0x0, 0x53, 0x3, 0xb0, 0x0, 0x5f, + 0xde, 0xd0, 0x49, 0x2, 0xb7, 0x10, 0x9, 0x16, + 0x5a, 0xcc, 0xc6, 0xc5, 0x90, 0x9, 0x16, 0x54, + 0x61, 0xb1, 0xc0, 0xa0, 0x9, 0xde, 0x56, 0xb7, + 0x95, 0xd4, 0x40, 0x9, 0x16, 0x66, 0x66, 0x66, + 0xe6, 0x60, 0x9, 0x69, 0x56, 0xbb, 0xc0, 0xd0, + 0x80, 0x9, 0x8b, 0x57, 0x30, 0xb0, 0xc3, 0xa0, + 0x9, 0x16, 0x57, 0xcb, 0xe0, 0xac, 0x20, 0x9, + 0x6a, 0xd7, 0x30, 0xb0, 0x8a, 0x11, 0x6c, 0x89, + 0x57, 0xcb, 0xe0, 0xc9, 0x47, 0x0, 0x6, 0x57, + 0x30, 0x69, 0x2c, 0x84, 0x0, 0x6, 0x50, 0x0, + 0x91, 0x6, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+807D "聽" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x6e, 0xdc, + 0xed, 0xba, 0xbe, 0xaa, 0xa0, 0x9, 0x96, 0xc4, + 0x11, 0x78, 0x11, 0x10, 0x9, 0x63, 0xb4, 0x9b, + 0xec, 0xdb, 0xa0, 0x9, 0xca, 0xd4, 0x90, 0xa0, + 0xa0, 0xc0, 0x9, 0x30, 0x94, 0xa2, 0xb2, 0xb2, + 0xc0, 0x3c, 0xba, 0xd4, 0x79, 0x99, 0x99, 0x70, + 0x25, 0x44, 0x96, 0xbb, 0xbb, 0xbb, 0xb3, 0x16, + 0xd6, 0x94, 0x11, 0x83, 0x11, 0x10, 0x8, 0xe7, + 0x94, 0x56, 0x4c, 0x8, 0x20, 0x1, 0xc1, 0x94, + 0xba, 0x26, 0x34, 0xb0, 0x26, 0xeb, 0xa9, 0x7a, + 0x20, 0xc, 0x93, 0x36, 0x41, 0x97, 0x16, 0xdc, + 0xc7, 0x10, + + /* U+8089 "肉" */ + 0x0, 0x0, 0x9, 0x50, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x30, 0x0, 0x0, 0xbd, 0xdd, 0xdf, 0xed, + 0xdd, 0xd2, 0xd2, 0x0, 0x5e, 0x10, 0x0, 0xb2, + 0xd1, 0x0, 0xca, 0xd4, 0x0, 0xb2, 0xd1, 0xa, + 0x90, 0x2c, 0x90, 0xb2, 0xd2, 0xd6, 0xb, 0x20, + 0x93, 0xb2, 0xd1, 0x0, 0x1e, 0x0, 0x0, 0xb2, + 0xd1, 0x0, 0xab, 0xc2, 0x0, 0xb2, 0xd1, 0x9, + 0xa0, 0x4d, 0x40, 0xb2, 0xd3, 0xd7, 0x0, 0x2, + 0xd2, 0xb2, 0xd1, 0x0, 0x0, 0x0, 0x0, 0xc2, + 0xd1, 0x0, 0x0, 0x0, 0xee, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+80A9 "肩" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x50, 0x0, 0x0, 0x0, 0x9a, 0xaa, + 0xbf, 0xaa, 0xa9, 0x0, 0xe, 0x32, 0x22, 0x22, + 0x22, 0xe0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0xe, + 0x0, 0xe, 0xdc, 0xcc, 0xcc, 0xcc, 0xd0, 0x0, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x1f, + 0xbb, 0xbb, 0xbb, 0xe3, 0x1, 0xc1, 0xd0, 0x0, + 0x0, 0xb, 0x30, 0x3b, 0x1f, 0xaa, 0xaa, 0xaa, + 0xe3, 0x7, 0x71, 0xd0, 0x0, 0x0, 0xb, 0x30, + 0xc3, 0x1f, 0xbb, 0xbb, 0xbb, 0xe3, 0x4c, 0x1, + 0xd0, 0x0, 0x0, 0xb, 0x31, 0x20, 0x1d, 0x0, + 0x0, 0x8c, 0xc1, + + /* U+80AF "肯" */ + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x78, 0x11, 0x11, 0x0, 0x0, 0xe, + 0x0, 0x7d, 0xbb, 0xb8, 0x0, 0x0, 0xe, 0x0, + 0x77, 0x0, 0x0, 0x0, 0xd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5e, 0xcc, 0xcc, 0xcc, 0xe5, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x95, 0x0, + 0x0, 0x5e, 0xbb, 0xbb, 0xbb, 0xe5, 0x0, 0x0, + 0x59, 0x0, 0x0, 0x0, 0x95, 0x0, 0x0, 0x5e, + 0xcc, 0xcc, 0xcc, 0xe5, 0x0, 0x0, 0x59, 0x0, + 0x0, 0x0, 0x95, 0x0, 0x0, 0x59, 0x0, 0x0, + 0x9c, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+80B2 "育" */ + 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, 0x0, 0x1, + 0x11, 0x11, 0x8a, 0x11, 0x11, 0x10, 0x1c, 0xcc, + 0xdf, 0xcc, 0xdd, 0xcc, 0xc2, 0x0, 0x5, 0xc3, + 0x0, 0x2b, 0x50, 0x0, 0x0, 0xbf, 0xbc, 0xcd, + 0xcc, 0xd9, 0x0, 0x0, 0x33, 0x21, 0x0, 0x0, + 0x8, 0x20, 0x0, 0x2e, 0xcc, 0xcc, 0xcc, 0xe3, + 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0xa4, 0x0, + 0x0, 0x2e, 0xbb, 0xbb, 0xbb, 0xe4, 0x0, 0x0, + 0x2c, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x2e, + 0xbb, 0xbb, 0xbb, 0xe4, 0x0, 0x0, 0x2c, 0x0, + 0x0, 0x0, 0xa4, 0x0, 0x0, 0x2c, 0x0, 0x3, + 0xcb, 0xd1, 0x0, + + /* U+80CC "背" */ + 0x0, 0x0, 0x3b, 0x1, 0xd0, 0x2, 0x0, 0x9, + 0xbb, 0xcb, 0x1, 0xe5, 0xbc, 0x20, 0x0, 0x0, + 0x4b, 0x1, 0xf7, 0x20, 0x0, 0x1, 0x36, 0xab, + 0x1, 0xe0, 0x0, 0xa0, 0x2b, 0x85, 0x5b, 0x0, + 0xdc, 0xcc, 0xb0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0xbb, 0xbb, 0xbb, 0xf2, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0xc2, 0x0, + 0x0, 0x1f, 0xbb, 0xbb, 0xbb, 0xe2, 0x0, 0x0, + 0x1d, 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x1f, + 0xbb, 0xbb, 0xbb, 0xe2, 0x0, 0x0, 0x1d, 0x0, + 0x0, 0x0, 0xc2, 0x0, 0x0, 0x1d, 0x0, 0x0, + 0x6c, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+80F8 "胸" */ + 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0xa, + 0xed, 0xd0, 0x5a, 0x0, 0x0, 0x0, 0xa, 0x20, + 0xd0, 0xce, 0xdd, 0xdd, 0xe4, 0xa, 0x20, 0xd7, + 0xa0, 0x0, 0x0, 0x85, 0xa, 0xed, 0xed, 0x27, + 0x8, 0x21, 0x85, 0xb, 0x20, 0xd4, 0x88, 0x5a, + 0x1a, 0x85, 0xb, 0x10, 0xd3, 0x80, 0xd5, 0x1a, + 0x85, 0xc, 0xcb, 0xd3, 0x83, 0xaa, 0x1a, 0x85, + 0xc, 0x21, 0xd3, 0x9c, 0x17, 0x6a, 0x85, 0xc, + 0x0, 0xd3, 0xa3, 0x0, 0x5a, 0x94, 0xc, 0x0, + 0xd3, 0xec, 0xcc, 0xca, 0xa4, 0x48, 0x0, 0xd0, + 0x0, 0x0, 0x0, 0xc2, 0x73, 0x7d, 0x90, 0x0, + 0x1, 0xdd, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+80FD "能" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x86, 0x0, 0xb, 0x30, 0x0, 0x0, 0x1, 0xd0, + 0xb3, 0xb, 0x30, 0x39, 0x10, 0xa, 0x60, 0x3c, + 0xb, 0x9c, 0xb4, 0x0, 0x3f, 0xcc, 0xce, 0x4b, + 0x70, 0x0, 0x0, 0x1, 0x0, 0x2, 0x2b, 0x30, + 0x0, 0xb0, 0xa, 0xcc, 0xcc, 0x9, 0xb8, 0x89, + 0xd0, 0xc, 0x10, 0xe, 0x3, 0x54, 0x44, 0x10, + 0xc, 0xcb, 0xbf, 0xb, 0x30, 0x5, 0x10, 0xc, + 0x10, 0xe, 0xb, 0x67, 0xda, 0x20, 0xc, 0xcb, + 0xbf, 0xb, 0xa4, 0x0, 0x0, 0xc, 0x10, 0xe, + 0xb, 0x30, 0x0, 0x81, 0xc, 0x10, 0xe, 0xb, + 0x40, 0x0, 0xc1, 0xc, 0x15, 0xdb, 0x5, 0xdd, + 0xdd, 0x90, + + /* U+8131 "脱" */ + 0x0, 0x0, 0x0, 0x4, 0x0, 0x5, 0x0, 0xa, + 0xed, 0xf0, 0xc, 0x30, 0x3c, 0x0, 0xa, 0x20, + 0xd0, 0x5, 0x90, 0xb4, 0x0, 0xa, 0x20, 0xd0, + 0xcc, 0xcc, 0xec, 0x40, 0xa, 0xdd, 0xf0, 0xe0, + 0x0, 0x6, 0x50, 0xa, 0x20, 0xd0, 0xe0, 0x0, + 0x6, 0x50, 0xb, 0x10, 0xd0, 0xe8, 0x88, 0x8b, + 0x50, 0xb, 0xcb, 0xf0, 0x37, 0xc4, 0xe4, 0x10, + 0xc, 0x21, 0xd0, 0x5, 0x90, 0xe0, 0x0, 0xc, + 0x0, 0xd0, 0x9, 0x60, 0xe0, 0x0, 0xc, 0x0, + 0xd0, 0x1e, 0x10, 0xe0, 0x61, 0x48, 0x0, 0xd0, + 0xb7, 0x0, 0xe0, 0xa2, 0x74, 0x4d, 0xbb, 0x80, + 0x0, 0xad, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+814A "腊" */ + 0x0, 0x0, 0x0, 0xe, 0x0, 0xe0, 0x0, 0xa, + 0xed, 0xe0, 0xe, 0x0, 0xe0, 0x0, 0xa, 0x20, + 0xd6, 0xdf, 0xdd, 0xfd, 0x80, 0xa, 0x20, 0xd0, + 0xe, 0x0, 0xe0, 0x0, 0xa, 0xed, 0xe0, 0xe, + 0x0, 0xe0, 0x0, 0xb, 0x30, 0xd9, 0xdd, 0xdd, + 0xdd, 0xd0, 0xb, 0x20, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x87, 0xd0, 0xcd, 0xcc, 0xce, 0x0, + 0xc, 0x65, 0xd0, 0xc1, 0x0, 0xe, 0x0, 0xc, + 0x0, 0xd0, 0xcc, 0xbb, 0xce, 0x0, 0xc, 0x0, + 0xd0, 0xc1, 0x0, 0xe, 0x0, 0x48, 0x0, 0xd0, + 0xc3, 0x22, 0x2e, 0x0, 0x92, 0x7d, 0x80, 0xcb, + 0xaa, 0xad, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8155 "腕" */ + 0x0, 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, 0xa, + 0xed, 0xc0, 0x11, 0x79, 0x11, 0x10, 0xa, 0x10, + 0xc9, 0xcb, 0xbb, 0xbb, 0xe3, 0xa, 0x10, 0xc9, + 0x50, 0x0, 0x0, 0xa3, 0xa, 0xcb, 0xc2, 0xb3, + 0x3, 0x55, 0x60, 0xa, 0x31, 0xc0, 0xdb, 0xda, + 0x76, 0xc0, 0xb, 0x10, 0xc4, 0x80, 0xba, 0x20, + 0xc0, 0xb, 0x76, 0xdc, 0x74, 0x9a, 0x20, 0xc0, + 0xc, 0x76, 0xd5, 0x3e, 0x5a, 0x20, 0xc0, 0xc, + 0x0, 0xc0, 0xb, 0x1a, 0x7b, 0x60, 0x1c, 0x0, + 0xc0, 0x3a, 0xa, 0x20, 0x21, 0x58, 0x0, 0xc1, + 0xc2, 0x9, 0x30, 0x65, 0x73, 0x7d, 0x9a, 0x50, + 0x5, 0xcb, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8166 "腦" */ + 0x0, 0x0, 0x0, 0x14, 0x4, 0x0, 0x50, 0xa, + 0xed, 0xd0, 0xa4, 0x2b, 0x7, 0x60, 0xa, 0x20, + 0xd4, 0xb0, 0xb2, 0x3b, 0x0, 0xa, 0x20, 0xd3, + 0xb0, 0x94, 0x3c, 0x0, 0xa, 0xdd, 0xd0, 0x77, + 0xc, 0x14, 0xa0, 0xb, 0x20, 0xd0, 0x6, 0x59, + 0x20, 0x60, 0xb, 0x10, 0xd0, 0xaa, 0xec, 0xaa, + 0x90, 0xc, 0xcb, 0xd0, 0xe1, 0x20, 0x71, 0xd0, + 0xc, 0x21, 0xd0, 0xd2, 0xc7, 0xa0, 0xd0, 0xc, + 0x0, 0xd0, 0xd0, 0x5f, 0x50, 0xd0, 0xc, 0x0, + 0xd0, 0xd6, 0xb2, 0xc2, 0xd0, 0x38, 0x0, 0xd0, + 0xe4, 0x11, 0x21, 0xd0, 0x73, 0x7d, 0x90, 0xfb, + 0xbb, 0xbb, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8170 "腰" */ + 0xb, 0xdd, 0xc8, 0xdd, 0xfd, 0xfd, 0xd2, 0xb, + 0x10, 0xc0, 0x1, 0xb0, 0xc0, 0x0, 0xb, 0x10, + 0xc4, 0xed, 0xfc, 0xfd, 0xb0, 0xb, 0xdd, 0xc4, + 0x80, 0xa0, 0xc0, 0xc0, 0xb, 0x10, 0xc4, 0x80, + 0xa0, 0xc0, 0xc0, 0xb, 0x10, 0xc3, 0xcc, 0xcc, + 0xcc, 0x90, 0xc, 0x76, 0xc0, 0x1, 0xd0, 0x0, + 0x0, 0xc, 0x66, 0xc7, 0xcf, 0xdc, 0xdf, 0xd4, + 0xc, 0x0, 0xc0, 0x4c, 0x0, 0x4b, 0x0, 0xc, + 0x0, 0xc0, 0x8c, 0x74, 0xd3, 0x0, 0x48, 0x0, + 0xc0, 0x1, 0xbe, 0xd6, 0x0, 0x83, 0x7d, 0x96, + 0xcb, 0x60, 0x18, 0xd1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+819D "膝" */ + 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0xa, + 0xed, 0xe1, 0x22, 0x2e, 0x22, 0x20, 0xa, 0x20, + 0xd5, 0xab, 0xff, 0xfb, 0xa3, 0xa, 0x20, 0xd0, + 0x1b, 0x7d, 0x6a, 0x0, 0xa, 0xdd, 0xe9, 0xd4, + 0x8, 0x4, 0xc1, 0xa, 0x20, 0xd2, 0x0, 0xad, + 0x50, 0x20, 0xb, 0x10, 0xd0, 0x3b, 0x60, 0x99, + 0x10, 0xb, 0xcb, 0xea, 0xc3, 0xa, 0x5, 0xc6, + 0xc, 0x21, 0xd1, 0x5a, 0xd, 0xb, 0x20, 0xc, + 0x0, 0xd0, 0x8, 0x6e, 0xb4, 0x0, 0xc, 0x0, + 0xd0, 0x19, 0xbe, 0xa8, 0x0, 0x48, 0x0, 0xd7, + 0xc4, 0xd, 0x6, 0xc0, 0x73, 0x6d, 0xa0, 0x4, + 0xba, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+81C9 "臉" */ + 0x0, 0x0, 0x0, 0x0, 0x35, 0x0, 0x0, 0xa, + 0xed, 0xd0, 0x2, 0xec, 0x20, 0x0, 0xa, 0x20, + 0xd0, 0x4b, 0x22, 0xc7, 0x10, 0xa, 0x31, 0xd7, + 0xbd, 0xcc, 0xc8, 0xd0, 0xa, 0xcc, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x20, 0xd4, 0xbb, 0x57, + 0xbb, 0x50, 0xb, 0x10, 0xd5, 0x43, 0x79, 0x14, + 0x60, 0xb, 0x98, 0xd5, 0x43, 0x79, 0x14, 0x60, + 0xc, 0x66, 0xd4, 0xbb, 0x57, 0xbb, 0x50, 0xc, + 0x0, 0xd0, 0x45, 0x0, 0x94, 0x0, 0xc, 0x0, + 0xd0, 0xb8, 0x0, 0xf5, 0x0, 0x49, 0x0, 0xd5, + 0x88, 0x7a, 0x7b, 0x70, 0x74, 0x9d, 0xab, 0x0, + 0x68, 0x0, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+81EA "自" */ + 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x1, 0xe0, + 0x0, 0x0, 0xce, 0xee, 0xfe, 0xee, 0xec, 0xd1, + 0x0, 0x0, 0x0, 0x1e, 0xd1, 0x0, 0x0, 0x0, + 0x1e, 0xde, 0xdd, 0xdd, 0xdd, 0xee, 0xd1, 0x0, + 0x0, 0x0, 0x1e, 0xd1, 0x0, 0x0, 0x0, 0x1e, + 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xd1, 0x0, 0x0, + 0x0, 0x1e, 0xd1, 0x0, 0x0, 0x0, 0x1e, 0xdd, + 0xcc, 0xcc, 0xcc, 0xde, 0xd2, 0x11, 0x11, 0x11, + 0x2d, + + /* U+81F3 "至" */ + 0xd, 0xee, 0xef, 0xee, 0xee, 0xee, 0xb0, 0x0, + 0x0, 0x8b, 0x0, 0x1, 0x0, 0x0, 0x0, 0x5, + 0xd0, 0x0, 0x4d, 0x20, 0x0, 0x0, 0x4d, 0x10, + 0x0, 0x15, 0xe3, 0x0, 0x1, 0xfe, 0xdd, 0xdd, + 0xcb, 0xae, 0x20, 0x0, 0x10, 0x0, 0x44, 0x0, + 0x4, 0x30, 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, + 0x0, 0x0, 0xee, 0xee, 0xff, 0xee, 0xee, 0x10, + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x2, 0x22, + 0x22, 0x88, 0x22, 0x22, 0x20, 0x2b, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xb3, + + /* U+81FA "臺" */ + 0x0, 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0x1a, + 0xaa, 0xaa, 0xdd, 0xaa, 0xaa, 0xa1, 0x1, 0xaa, + 0xaa, 0xdc, 0xaa, 0xaa, 0x10, 0x0, 0x24, 0x44, + 0x44, 0x44, 0x42, 0x0, 0x0, 0x79, 0x55, 0x55, + 0x55, 0xa7, 0x0, 0x0, 0x6b, 0x99, 0x99, 0x99, + 0xb6, 0x0, 0x5, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x50, 0xd, 0x54, 0x44, 0x44, 0x44, 0x45, 0xd0, + 0x9, 0x59, 0xce, 0xa9, 0xbf, 0xa4, 0x90, 0x0, + 0xb, 0xd8, 0xa9, 0x79, 0xb5, 0x0, 0x0, 0x79, + 0x99, 0xcc, 0x99, 0x99, 0x0, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x0, 0x0, 0x1b, 0xbb, 0xbb, 0xdd, + 0xbb, 0xbb, 0xb1, + + /* U+8207 "與" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0x97, 0x50, 0x0, 0x0, 0x0, 0x0, 0xca, + 0x47, 0x50, 0xa, 0xde, 0x50, 0x0, 0xb0, 0x7, + 0xdc, 0x80, 0x9, 0x50, 0x0, 0xd4, 0x37, 0x50, + 0x2, 0x3b, 0x40, 0x0, 0xd6, 0x57, 0xdc, 0x75, + 0x7d, 0x40, 0x0, 0xc0, 0x1, 0x3, 0x90, 0xa, + 0x40, 0x0, 0xdc, 0xa7, 0x43, 0x99, 0xcf, 0x30, + 0x0, 0xc0, 0x7, 0x43, 0x90, 0xb, 0x30, 0x0, + 0xc0, 0x7, 0x43, 0x90, 0xc, 0x20, 0x1d, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xd7, 0x0, 0x0, 0x93, + 0x0, 0x49, 0x10, 0x0, 0x0, 0x4d, 0x70, 0x0, + 0x5, 0xd9, 0x10, 0x9, 0xa2, 0x0, 0x0, 0x0, + 0x7, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+8208 "興" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xda, 0x8c, 0xbb, 0xc8, 0xce, 0x40, 0x8, 0x50, + 0x66, 0x22, 0x66, 0x7, 0x40, 0x8, 0xa6, 0x77, + 0x77, 0x66, 0x5a, 0x40, 0x7, 0xa5, 0x76, 0x99, + 0x67, 0x6b, 0x30, 0x7, 0x70, 0x66, 0x66, 0x66, + 0x8, 0x30, 0x6, 0xec, 0x96, 0x66, 0x68, 0xbd, + 0x20, 0x6, 0x80, 0x66, 0xaa, 0x66, 0x19, 0x20, + 0x5, 0x80, 0x65, 0x0, 0x56, 0x9, 0x10, 0x7d, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xd1, 0x0, 0x1, + 0x92, 0x0, 0x59, 0x10, 0x0, 0x0, 0x6e, 0x60, + 0x0, 0x5, 0xd7, 0x0, 0x2d, 0x81, 0x0, 0x0, + 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8209 "舉" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xc4, 0x80, 0x0, 0x0, 0x0, 0x0, 0xba, + 0x54, 0xc7, 0x4b, 0xbe, 0x20, 0x0, 0xda, 0x93, + 0x92, 0x9, 0xae, 0x10, 0x0, 0xc0, 0x2, 0x9c, + 0x40, 0xd, 0x10, 0x0, 0xbb, 0xa4, 0x37, 0x4a, + 0xaf, 0x0, 0x0, 0xb1, 0x6, 0x47, 0x40, 0xe, + 0x0, 0xc, 0xcc, 0xfc, 0xcc, 0xcf, 0xdc, 0xc7, + 0x0, 0xa, 0x60, 0x76, 0x4, 0xc2, 0x0, 0x3, + 0xc6, 0xcc, 0xee, 0xcc, 0x5c, 0x81, 0xa, 0x20, + 0x0, 0x77, 0x0, 0x0, 0x65, 0x0, 0xac, 0xcc, + 0xee, 0xcc, 0xcc, 0x40, 0x0, 0x0, 0x0, 0x77, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77, 0x0, + 0x0, 0x0, + + /* U+822A "航" */ + 0x0, 0x8, 0x0, 0x0, 0x62, 0x0, 0x0, 0x0, + 0x2d, 0x0, 0x0, 0x6b, 0x0, 0x0, 0x8, 0xde, + 0xca, 0x22, 0x3d, 0x32, 0x20, 0x9, 0x41, 0xc, + 0x9a, 0xaa, 0xaa, 0xa3, 0x9, 0x4b, 0x1c, 0x1, + 0x11, 0x10, 0x0, 0x9, 0x35, 0x2c, 0xe, 0xaa, + 0xbb, 0x0, 0x4e, 0xdc, 0xcc, 0xe, 0x0, 0x2b, + 0x0, 0xa, 0x42, 0xc, 0xe, 0x0, 0x2b, 0x0, + 0xa, 0x3b, 0x1c, 0xd, 0x0, 0x2b, 0x0, 0xb, + 0x18, 0x5c, 0xd, 0x0, 0x2b, 0x0, 0xd, 0x0, + 0x1c, 0x2b, 0x0, 0x2b, 0x15, 0x2c, 0x0, 0x1c, + 0x76, 0x0, 0x2b, 0x28, 0x57, 0x7, 0xd9, 0xc0, + 0x0, 0xd, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+822C "般" */ + 0x0, 0x4, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2b, 0x42, 0x0, 0xfc, 0xce, 0x0, 0x3, 0xd9, + 0x9e, 0x10, 0xd0, 0xd, 0x0, 0x3, 0xa5, 0xc, + 0x13, 0xb0, 0xd, 0x0, 0x3, 0xa6, 0x5c, 0x2c, + 0x60, 0xb, 0xc6, 0x3, 0xa0, 0x1c, 0x14, 0x0, + 0x0, 0x0, 0x6d, 0xfd, 0xdf, 0x1c, 0xdd, 0xdd, + 0xa0, 0x4, 0x91, 0xc, 0x16, 0x90, 0x5, 0x70, + 0x6, 0x7a, 0x1c, 0x10, 0xe1, 0xc, 0x20, 0x7, + 0x63, 0x8c, 0x10, 0x6b, 0x69, 0x0, 0xb, 0x30, + 0xc, 0x10, 0xb, 0xe1, 0x0, 0x1e, 0x0, 0xc, + 0x12, 0xad, 0x9d, 0x50, 0x59, 0x4, 0xdc, 0x2d, + 0x70, 0x2, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8239 "船" */ + 0x0, 0xa, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0x0, 0x4, 0xfd, 0xdd, 0x0, 0x9, 0xdc, + 0xce, 0x4, 0x90, 0xd, 0x0, 0x9, 0x45, 0xd, + 0x5, 0x80, 0xd, 0x0, 0x9, 0x3b, 0x1d, 0x8, + 0x50, 0xd, 0x0, 0x9, 0x33, 0x2d, 0x3d, 0x0, + 0xd, 0x72, 0x6e, 0xcb, 0xbe, 0x31, 0x0, 0x1, + 0x41, 0xa, 0x44, 0xd, 0xc, 0xdd, 0xdd, 0x70, + 0xa, 0x2c, 0x1d, 0xd, 0x0, 0x5, 0x80, 0xb, + 0x15, 0x5d, 0xd, 0x0, 0x5, 0x80, 0xd, 0x0, + 0xd, 0xd, 0x0, 0x5, 0x80, 0x2b, 0x0, 0xd, + 0xd, 0xaa, 0xac, 0x80, 0x74, 0x4, 0xda, 0xd, + 0x33, 0x37, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+826F "良" */ + 0x0, 0x0, 0x35, 0x0, 0x0, 0x0, 0x2, 0x22, + 0x5d, 0x22, 0x22, 0x0, 0x4e, 0xaa, 0xaa, 0xaa, + 0xbd, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x1d, 0x0, + 0x4e, 0xcc, 0xcc, 0xcc, 0xcd, 0x0, 0x4b, 0x0, + 0x0, 0x0, 0x1d, 0x0, 0x4b, 0x0, 0x0, 0x0, + 0x2d, 0x0, 0x4f, 0xcc, 0xfc, 0xcc, 0xca, 0x0, + 0x4b, 0x0, 0x98, 0x0, 0x9, 0x70, 0x4b, 0x0, + 0xd, 0x54, 0xc7, 0x0, 0x4b, 0x0, 0x2, 0xde, + 0x20, 0x0, 0x4b, 0x27, 0xb2, 0x1a, 0xc4, 0x0, + 0xaf, 0xc7, 0x30, 0x0, 0x4b, 0xe4, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+8272 "色" */ + 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xfb, 0xbb, 0xb5, 0x0, 0x0, 0x0, 0x1e, + 0x42, 0x25, 0xe1, 0x0, 0x0, 0x2, 0xd6, 0x0, + 0x1d, 0x30, 0x0, 0x0, 0x3e, 0xfe, 0xee, 0xff, + 0xee, 0xed, 0x0, 0x45, 0xc1, 0x0, 0xc2, 0x0, + 0xe, 0x0, 0x0, 0xc1, 0x0, 0xc2, 0x0, 0xe, + 0x0, 0x0, 0xc4, 0x22, 0xc5, 0x22, 0x2e, 0x0, + 0x0, 0xcb, 0xbb, 0xbb, 0xbb, 0xbe, 0x0, 0x0, + 0xc1, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0xc1, + 0x0, 0x0, 0x0, 0x0, 0xa4, 0x0, 0xb4, 0x0, + 0x0, 0x0, 0x1, 0xe1, 0x0, 0x4d, 0xdd, 0xdd, + 0xdd, 0xde, 0x70, + + /* U+8282 "节" */ + 0x0, 0x0, 0xd1, 0x0, 0x1e, 0x0, 0x0, 0x0, + 0x0, 0xd1, 0x0, 0x1e, 0x0, 0x0, 0x3e, 0xee, + 0xfe, 0xee, 0xef, 0xee, 0xe3, 0x0, 0x0, 0xd1, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x2, 0x0, 0x0, 0x9, 0xee, 0xee, 0xee, 0xee, + 0xec, 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, 0x2d, + 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, 0x2d, 0x0, + 0x0, 0x0, 0xe, 0x10, 0x0, 0x2d, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x2d, 0x0, 0x0, 0x0, + 0xe, 0x10, 0x8c, 0xea, 0x0, 0x0, 0x0, 0xe, + 0x10, 0x12, 0x10, 0x0, 0x0, 0x0, 0xe, 0x10, + 0x0, 0x0, 0x0, + + /* U+82B1 "花" */ + 0x0, 0x0, 0xb3, 0x0, 0x2c, 0x0, 0x0, 0x2, + 0x22, 0xc5, 0x22, 0x4d, 0x22, 0x20, 0x1c, 0xcc, + 0xfd, 0xcc, 0xcf, 0xcc, 0xc1, 0x0, 0x0, 0xb3, + 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x90, 0x8, + 0x30, 0x0, 0x0, 0x0, 0x8, 0x90, 0xa, 0x40, + 0x4, 0x20, 0x0, 0x3f, 0x10, 0xa, 0x41, 0x9d, + 0x30, 0x3, 0xef, 0x0, 0xa, 0xad, 0x70, 0x0, + 0xd, 0x4e, 0x0, 0x7e, 0x91, 0x0, 0x0, 0x0, + 0xe, 0x8, 0x7b, 0x40, 0x0, 0x0, 0x0, 0xe, + 0x0, 0xa, 0x40, 0x0, 0x74, 0x0, 0xe, 0x0, + 0xa, 0x50, 0x0, 0xa4, 0x0, 0xe, 0x0, 0x5, + 0xee, 0xee, 0xc0, + + /* U+82E5 "若" */ + 0x0, 0x0, 0xe0, 0x0, 0xe, 0x0, 0x0, 0x1, + 0x11, 0xe1, 0x11, 0x1f, 0x11, 0x10, 0x1b, 0xbb, + 0xfb, 0xbb, 0xbf, 0xbb, 0xb2, 0x0, 0x0, 0xa1, + 0x80, 0xa, 0x0, 0x0, 0x0, 0x0, 0x7, 0x90, + 0x0, 0x0, 0x0, 0x3d, 0xdd, 0xef, 0xed, 0xdd, + 0xdd, 0xd3, 0x0, 0x0, 0x8a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0xe1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3e, 0xed, 0xdd, 0xdd, 0xdf, 0x0, 0x8, + 0xe9, 0x80, 0x0, 0x0, 0xe, 0x0, 0x39, 0x15, + 0x80, 0x0, 0x0, 0xe, 0x0, 0x0, 0x5, 0xda, + 0xaa, 0xaa, 0xaf, 0x0, 0x0, 0x5, 0x92, 0x22, + 0x22, 0x2e, 0x0, + + /* U+82E6 "苦" */ + 0x0, 0x0, 0xe0, 0x0, 0xe, 0x0, 0x0, 0x3, + 0x33, 0xf3, 0x33, 0x3f, 0x33, 0x30, 0xa, 0xaa, + 0xfa, 0xaa, 0xaf, 0xaa, 0xa1, 0x0, 0x0, 0xb0, + 0x32, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x87, + 0x0, 0x0, 0x0, 0x1d, 0xdd, 0xdd, 0xfe, 0xdd, + 0xdd, 0xd1, 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, + 0x0, 0x7e, 0xdd, 0xee, 0xdd, 0xea, 0x0, 0x0, + 0x76, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x76, + 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x7d, 0xaa, + 0xaa, 0xaa, 0xca, 0x0, 0x0, 0x78, 0x22, 0x22, + 0x22, 0x6a, 0x0, + + /* U+82F1 "英" */ + 0x0, 0x0, 0xe0, 0x0, 0xe, 0x0, 0x0, 0x2, + 0x22, 0xe2, 0x22, 0x2e, 0x22, 0x20, 0xa, 0xaa, + 0xfa, 0xaa, 0xaf, 0xaa, 0xa0, 0x0, 0x0, 0xa0, + 0x75, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x86, + 0x0, 0x0, 0x0, 0x0, 0xbd, 0xdd, 0xee, 0xdd, + 0xdc, 0x0, 0x0, 0xb2, 0x0, 0x86, 0x0, 0x2c, + 0x0, 0x0, 0xb2, 0x0, 0x96, 0x0, 0x2c, 0x0, + 0x2d, 0xfe, 0xdd, 0xfe, 0xdd, 0xef, 0xd3, 0x0, + 0x0, 0x2, 0xdc, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x3d, 0x42, 0xd4, 0x0, 0x0, 0x0, 0x4a, 0xd3, + 0x0, 0x2d, 0xa3, 0x0, 0x2e, 0xa5, 0x0, 0x0, + 0x0, 0x5b, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8336 "茶" */ + 0x0, 0x1, 0xd0, 0x0, 0xe, 0x0, 0x0, 0x1, + 0x12, 0xd1, 0x11, 0x1f, 0x11, 0x10, 0x1c, 0xcc, + 0xfc, 0xcc, 0xcf, 0xcc, 0xc1, 0x0, 0x1, 0x90, + 0xab, 0xa, 0x0, 0x0, 0x0, 0x0, 0x9, 0x66, + 0xb1, 0x0, 0x0, 0x0, 0x2, 0xb5, 0x22, 0x4d, + 0x50, 0x0, 0x2, 0x9c, 0x40, 0x77, 0x2, 0xbc, + 0x50, 0x2d, 0x72, 0x22, 0x99, 0x22, 0x26, 0xd4, + 0x0, 0x6b, 0xbb, 0xdd, 0xbb, 0xb6, 0x0, 0x0, + 0x3, 0x50, 0x77, 0x8, 0x10, 0x0, 0x0, 0x2d, + 0x20, 0x77, 0x4, 0xd3, 0x0, 0x6, 0xd3, 0x0, + 0x77, 0x0, 0x2d, 0x40, 0x2, 0x10, 0xd, 0xe4, + 0x0, 0x1, 0x0, + + /* U+8377 "荷" */ + 0x0, 0x0, 0xe0, 0x0, 0xe, 0x0, 0x0, 0x1c, + 0xcc, 0xfc, 0xcc, 0xcf, 0xcc, 0xc2, 0x0, 0x0, + 0xe1, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x4, 0x90, + 0x0, 0x5, 0x0, 0x0, 0x0, 0xe, 0x4d, 0xdd, + 0xdd, 0xdd, 0xd4, 0x0, 0x99, 0x0, 0x0, 0x0, + 0xe, 0x0, 0x7, 0xf6, 0x9, 0xaa, 0xa5, 0xe, + 0x0, 0x5d, 0x96, 0xe, 0x11, 0x68, 0xe, 0x0, + 0x12, 0x76, 0xd, 0x0, 0x58, 0xe, 0x0, 0x0, + 0x76, 0xe, 0x11, 0x68, 0xe, 0x0, 0x0, 0x76, + 0xe, 0xaa, 0xa5, 0xe, 0x0, 0x0, 0x76, 0x1, + 0x0, 0x0, 0xe, 0x0, 0x0, 0x76, 0x0, 0x0, + 0x4d, 0xd9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+83D3 "菓" */ + 0x0, 0x0, 0xe0, 0x0, 0x1d, 0x0, 0x0, 0x1d, + 0xdd, 0xfd, 0xdd, 0xdf, 0xdd, 0xd2, 0x0, 0x0, + 0xd0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x8b, 0xbb, + 0xbb, 0xbb, 0xb9, 0x0, 0x0, 0xb2, 0x0, 0x86, + 0x0, 0x1c, 0x0, 0x0, 0xbb, 0xaa, 0xdd, 0xaa, + 0xbc, 0x0, 0x0, 0xb2, 0x0, 0x86, 0x0, 0x1c, + 0x0, 0x0, 0xbc, 0xbb, 0xed, 0xbb, 0xcc, 0x0, + 0x0, 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, 0x2d, + 0xdd, 0xdf, 0xff, 0xed, 0xdd, 0xd3, 0x0, 0x1, + 0xaa, 0x97, 0xb8, 0x0, 0x0, 0x4, 0xac, 0x50, + 0x86, 0x6, 0xc9, 0x30, 0x3a, 0x30, 0x0, 0x86, + 0x0, 0x4, 0xb3, + + /* U+83DC "菜" */ + 0x0, 0x0, 0xd1, 0x0, 0x2c, 0x0, 0x0, 0x1d, + 0xdd, 0xfd, 0xdd, 0xdf, 0xdd, 0xd2, 0x0, 0x0, + 0xd1, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x1, 0x43, + 0x45, 0x79, 0xca, 0x0, 0x7, 0xcb, 0xba, 0x98, + 0x64, 0x12, 0x0, 0x0, 0x91, 0x0, 0xd0, 0x0, + 0x1e, 0x10, 0x0, 0x5b, 0x0, 0x85, 0x0, 0xb4, + 0x0, 0x0, 0x4, 0x0, 0x76, 0x0, 0x50, 0x0, + 0x2d, 0xdd, 0xdd, 0xee, 0xdd, 0xdd, 0xd3, 0x0, + 0x0, 0x3c, 0xbb, 0xc2, 0x0, 0x0, 0x0, 0x7, + 0xd2, 0x87, 0x2d, 0x60, 0x0, 0x18, 0xe9, 0x10, + 0x87, 0x1, 0x9e, 0x91, 0x18, 0x10, 0x0, 0x87, + 0x0, 0x1, 0x70, + + /* U+843D "落" */ + 0x0, 0x0, 0xe0, 0x0, 0x1d, 0x0, 0x0, 0x1d, + 0xdd, 0xfd, 0xdd, 0xdf, 0xdd, 0xd2, 0x0, 0x0, + 0xe0, 0x1, 0x1d, 0x0, 0x0, 0x2, 0xa1, 0x30, + 0x3e, 0x13, 0x0, 0x0, 0x0, 0x5d, 0x31, 0xdb, + 0xbb, 0xcf, 0x20, 0x0, 0x1, 0x2d, 0xbb, 0x10, + 0xb8, 0x0, 0x1d, 0x60, 0x74, 0x5, 0xdc, 0x70, + 0x0, 0x1, 0xa5, 0x0, 0x29, 0xcb, 0xb4, 0x0, + 0x0, 0x0, 0x5d, 0xb3, 0x0, 0x4b, 0xd4, 0x0, + 0xc, 0x36, 0xeb, 0xbb, 0xbf, 0x20, 0x0, 0x97, + 0x4, 0x90, 0x0, 0xd, 0x10, 0x7, 0xb0, 0x4, + 0xa1, 0x11, 0x1d, 0x10, 0xa, 0x10, 0x4, 0xea, + 0xaa, 0xaf, 0x10, + + /* U+8449 "葉" */ + 0x0, 0x0, 0xd0, 0x0, 0x1d, 0x0, 0x0, 0x2c, + 0xcc, 0xfc, 0xcc, 0xcf, 0xcc, 0xc3, 0x0, 0x1, + 0xd0, 0x30, 0x1d, 0x10, 0x0, 0x0, 0x4a, 0x10, + 0xe0, 0x2, 0xe0, 0x0, 0x2c, 0xde, 0xcc, 0xfc, + 0xcc, 0xfc, 0xc2, 0x0, 0x4a, 0x0, 0xe2, 0x22, + 0xf0, 0x0, 0x0, 0x4a, 0x0, 0x66, 0x66, 0x60, + 0x0, 0x0, 0x4e, 0xcc, 0xcc, 0xcc, 0xcc, 0x90, + 0x0, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x2b, + 0xbb, 0xbc, 0xee, 0xcb, 0xbb, 0xb3, 0x0, 0x0, + 0x7b, 0xaa, 0xc6, 0x0, 0x0, 0x4, 0x9c, 0x60, + 0x76, 0x8, 0xc8, 0x30, 0x3a, 0x40, 0x0, 0x76, + 0x0, 0x5, 0xa3, + + /* U+8457 "著" */ + 0x0, 0x0, 0xe0, 0x0, 0x1d, 0x0, 0x0, 0x2d, + 0xdd, 0xfd, 0xdd, 0xdf, 0xdd, 0xd1, 0x0, 0x0, + 0xe1, 0x20, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x15, + 0x80, 0x1, 0xc, 0x10, 0x0, 0xcc, 0xce, 0xec, + 0xcd, 0xb3, 0x0, 0x0, 0x0, 0x5, 0x80, 0x5c, + 0x20, 0x0, 0x2d, 0xdd, 0xdd, 0xff, 0xdd, 0xdd, + 0xd2, 0x0, 0x0, 0x4b, 0xb3, 0x0, 0x0, 0x0, + 0x3, 0x9e, 0xeb, 0xbb, 0xbb, 0xbd, 0x0, 0x3b, + 0x67, 0x80, 0x0, 0x0, 0xd, 0x0, 0x0, 0x6, + 0xda, 0xaa, 0xaa, 0xad, 0x0, 0x0, 0x6, 0x80, + 0x0, 0x0, 0xd, 0x0, 0x0, 0x6, 0xeb, 0xbb, + 0xbb, 0xcd, 0x0, + + /* U+8535 "蔵" */ + 0x0, 0x0, 0xe0, 0x0, 0x3b, 0x0, 0x0, 0x7d, + 0xdd, 0xfd, 0xdd, 0xdf, 0xdd, 0xd1, 0x0, 0x0, + 0xe0, 0x0, 0x27, 0x3a, 0x0, 0x3, 0x44, 0x44, + 0x44, 0x6b, 0x49, 0x60, 0xa, 0xa8, 0x88, 0x88, + 0x9e, 0x88, 0x70, 0xa, 0x39, 0x99, 0x99, 0x2d, + 0x5, 0x20, 0xa, 0x3c, 0x9, 0x30, 0xd, 0xe, + 0x10, 0xa, 0x3e, 0x9c, 0xaa, 0xc, 0x6b, 0x0, + 0xb, 0x2c, 0x0, 0xb, 0xa, 0xe3, 0x0, 0xc, + 0x1e, 0x9b, 0xac, 0x7, 0xb0, 0x0, 0xd, 0xc, + 0x9, 0x20, 0x2e, 0xc0, 0x0, 0x59, 0xa, 0xaa, + 0xad, 0xb2, 0xc5, 0x54, 0x62, 0x0, 0x0, 0x1a, + 0x10, 0x2d, 0xc1, + + /* U+8584 "薄" */ + 0x0, 0x0, 0xe0, 0x0, 0x1d, 0x0, 0x0, 0x2c, + 0xcc, 0xfc, 0xcc, 0xdf, 0xcc, 0xc3, 0x0, 0x0, + 0xd0, 0x0, 0x4c, 0x46, 0x0, 0x5, 0xd6, 0x69, + 0x99, 0xe9, 0x9d, 0xb1, 0x0, 0x18, 0x13, 0x33, + 0xc4, 0x33, 0x20, 0x3, 0x0, 0x1e, 0x88, 0xe9, + 0x8b, 0x80, 0x2c, 0xb1, 0x1e, 0x88, 0xe9, 0x8b, + 0x80, 0x0, 0x73, 0x1c, 0x0, 0xc1, 0x5, 0x80, + 0x0, 0x0, 0x1e, 0x88, 0xe9, 0xbb, 0x80, 0x0, + 0x48, 0x8b, 0x99, 0x99, 0xea, 0xa3, 0x0, 0xc1, + 0x15, 0xc2, 0x22, 0xd2, 0x20, 0x7, 0x70, 0x0, + 0x7a, 0x0, 0xd0, 0x0, 0xa, 0x0, 0x0, 0x1, + 0x4c, 0xd0, 0x0, + + /* U+85AC "薬" */ + 0x0, 0x0, 0xd0, 0x0, 0x1d, 0x0, 0x0, 0x2d, + 0xdd, 0xfd, 0xdd, 0xdf, 0xdd, 0xd2, 0x0, 0x0, + 0xd0, 0x53, 0x1d, 0x0, 0x0, 0x6, 0x80, 0x6a, + 0xeb, 0xa7, 0x8, 0x80, 0x0, 0x99, 0x75, 0x0, + 0x59, 0xa8, 0x0, 0x0, 0x2, 0x7c, 0xaa, 0xc9, + 0x20, 0x0, 0x0, 0x5c, 0x95, 0x0, 0x4a, 0xc8, + 0x0, 0x1d, 0xa2, 0x7c, 0xaa, 0xc9, 0x7, 0xd0, + 0x2, 0x0, 0x1, 0x87, 0x10, 0x0, 0x20, 0x2d, + 0xdd, 0xde, 0xff, 0xed, 0xdd, 0xd2, 0x0, 0x0, + 0x8a, 0x88, 0xc7, 0x0, 0x0, 0x2, 0x8c, 0x50, + 0x76, 0x6, 0xc8, 0x30, 0x2b, 0x40, 0x0, 0x76, + 0x0, 0x4, 0xa2, + + /* U+85DD "藝" */ + 0x0, 0x0, 0xc1, 0x0, 0x1c, 0x0, 0x0, 0x2b, + 0xbb, 0xfc, 0xbb, 0xcf, 0xbb, 0xb2, 0x0, 0x2, + 0xa0, 0x0, 0x1a, 0x0, 0x0, 0x2, 0x9b, 0xc9, + 0x32, 0x4d, 0x43, 0x0, 0x9, 0x9b, 0xb9, 0x94, + 0x8d, 0x7c, 0x0, 0x4, 0xa4, 0x29, 0x77, 0xb9, + 0xc, 0x0, 0xa, 0x9b, 0xc9, 0x90, 0xbd, 0x4c, + 0x12, 0x0, 0x6, 0x94, 0x56, 0xa0, 0x1b, 0x74, + 0xa, 0x98, 0x76, 0x58, 0x0, 0x2, 0x80, 0x0, + 0x49, 0x99, 0x99, 0x99, 0x95, 0x0, 0x29, 0x99, + 0xab, 0x99, 0x9a, 0x99, 0x92, 0x0, 0x5, 0xc3, + 0x0, 0xb, 0x70, 0x0, 0x2, 0xbf, 0x99, 0xaa, + 0xaa, 0xdc, 0x20, 0x0, 0x43, 0x21, 0x0, 0x0, + 0x2, 0x40, + + /* U+8607 "蘇" */ + 0x0, 0x0, 0xd1, 0x0, 0x2c, 0x0, 0x0, 0x2d, + 0xdd, 0xfd, 0xdd, 0xdf, 0xdd, 0xd2, 0x0, 0x14, + 0xc1, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x8c, 0x74, + 0x0, 0x26, 0xac, 0x50, 0x3, 0xc4, 0xb6, 0x9, + 0x99, 0x90, 0x0, 0x2f, 0xdb, 0xfb, 0x80, 0x5, + 0x80, 0x0, 0x1a, 0x44, 0x61, 0xbc, 0xcd, 0xec, + 0xc3, 0x7, 0xbb, 0xca, 0xb1, 0x1d, 0xf3, 0x10, + 0x7, 0x44, 0x61, 0xb0, 0x5d, 0xba, 0x0, 0x5, + 0xbb, 0xbb, 0x81, 0xc6, 0x89, 0x40, 0x5, 0x35, + 0x74, 0x5c, 0x55, 0x81, 0xd2, 0xb, 0x1a, 0x83, + 0xc5, 0x5, 0x80, 0x32, 0x47, 0x6, 0x22, 0x30, + 0x5, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8655 "處" */ + 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0xbb, 0xbb, 0x70, 0x0, 0x0, + 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0xfc, 0xcc, + 0xce, 0xcc, 0xcc, 0xe6, 0x0, 0xd0, 0x1, 0x4c, + 0x45, 0x62, 0xd1, 0x0, 0xd2, 0xa9, 0x9d, 0x64, + 0x31, 0x81, 0x0, 0xd0, 0x15, 0xa, 0x98, 0x89, + 0x90, 0x1, 0xc0, 0x9c, 0x96, 0x3a, 0xa8, 0x0, + 0x2, 0xb4, 0xe1, 0x76, 0x67, 0x1d, 0x0, 0x3, + 0xcc, 0x96, 0xd1, 0x93, 0xd, 0x8, 0x7, 0x60, + 0xe, 0x73, 0xd0, 0xd, 0xa7, 0xb, 0x20, 0xaa, + 0xd5, 0x20, 0x0, 0x10, 0x1c, 0x4c, 0x60, 0x29, + 0xcd, 0xcc, 0xc9, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+884C "行" */ + 0x0, 0x4, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3e, 0x20, 0x7e, 0xee, 0xee, 0xe5, 0x5, 0xe3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x20, 0x74, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2e, 0x21, 0xee, 0xee, + 0xef, 0xeb, 0x4, 0xed, 0x0, 0x0, 0x0, 0x4a, + 0x0, 0x2e, 0x4d, 0x0, 0x0, 0x0, 0x4a, 0x0, + 0x1, 0xd, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, + 0xd, 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0xd, + 0x0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0xd, 0x0, + 0x0, 0x0, 0x5a, 0x0, 0x0, 0xd, 0x0, 0x0, + 0xad, 0xe5, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8853 "術" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x68, 0x0, 0xb2, 0x0, 0x0, 0x0, 0x2, 0xd0, + 0x0, 0xb4, 0xa3, 0xdd, 0xd1, 0x1d, 0x40, 0x0, + 0xb1, 0x84, 0x0, 0x0, 0x35, 0xb, 0x33, 0xc5, + 0x42, 0x0, 0x0, 0x0, 0x88, 0xbc, 0xfc, 0xc7, + 0x11, 0x10, 0x3, 0xf1, 0x5, 0xf1, 0x7, 0xbf, + 0xb3, 0x2e, 0xf0, 0xa, 0xf9, 0x30, 0xe, 0x0, + 0x86, 0xd0, 0xc, 0xc3, 0xc0, 0xe, 0x0, 0x0, + 0xd0, 0x86, 0xb1, 0x76, 0xe, 0x0, 0x0, 0xd2, + 0xd0, 0xb1, 0xa, 0xe, 0x0, 0x0, 0xd8, 0x30, + 0xb1, 0x0, 0xe, 0x0, 0x0, 0xd0, 0x0, 0xb1, + 0x0, 0xe, 0x0, 0x0, 0xd0, 0x0, 0xb1, 0x9, + 0xeb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+8868 "表" */ + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x5, + 0xaa, 0xaa, 0xdc, 0xaa, 0xaa, 0x60, 0x1, 0x22, + 0x22, 0x98, 0x22, 0x22, 0x10, 0x0, 0x12, 0x22, + 0x98, 0x22, 0x22, 0x0, 0x0, 0x8a, 0xaa, 0xdc, + 0xaa, 0xaa, 0x0, 0x0, 0x0, 0x0, 0x87, 0x0, + 0x0, 0x0, 0xc, 0xcc, 0xce, 0xff, 0xcc, 0xcc, + 0xc0, 0x0, 0x0, 0x5d, 0x2b, 0x40, 0x4, 0x30, + 0x0, 0x2a, 0xd1, 0x4, 0xd0, 0x7b, 0x10, 0x2b, + 0xda, 0xa0, 0x0, 0x9d, 0x80, 0x0, 0x4, 0x5, + 0xa0, 0x0, 0xb, 0x90, 0x0, 0x0, 0x5, 0xb5, + 0xad, 0x20, 0x9d, 0x60, 0x0, 0xa, 0xe9, 0x40, + 0x0, 0x2, 0xa2, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+88AB "被" */ + 0x0, 0x82, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x9, + 0x0, 0x67, 0x7f, 0x77, 0x72, 0x3d, 0xdd, 0xf1, + 0xd7, 0x7f, 0x77, 0xd3, 0x0, 0x3, 0xa0, 0xd0, + 0xe, 0x0, 0xd0, 0x0, 0xc, 0x21, 0xd0, 0xe, + 0x1, 0x40, 0x0, 0x7d, 0x77, 0xef, 0xdd, 0xde, + 0xa0, 0x5, 0xfe, 0xb0, 0xe8, 0x50, 0x9, 0x50, + 0x2d, 0x5a, 0xa4, 0xd1, 0xc0, 0x1d, 0x0, 0x1, + 0x3a, 0x13, 0xb0, 0x79, 0xc4, 0x0, 0x0, 0x3a, + 0x7, 0x70, 0x1e, 0xc0, 0x0, 0x0, 0x3a, 0xd, + 0x14, 0xd6, 0x9c, 0x40, 0x0, 0x3a, 0x37, 0x7a, + 0x20, 0x3, 0xb5, + + /* U+88CF "裏" */ + 0x0, 0x0, 0x0, 0x74, 0x0, 0x0, 0x0, 0xa, + 0xbb, 0xbb, 0xde, 0xbb, 0xbb, 0xb2, 0x0, 0x13, + 0x33, 0x33, 0x33, 0x32, 0x0, 0x0, 0x6a, 0x66, + 0xaa, 0x66, 0x8b, 0x0, 0x0, 0x6c, 0x99, 0xcc, + 0x99, 0xab, 0x0, 0x0, 0x67, 0x0, 0x77, 0x0, + 0x4b, 0x0, 0x0, 0x39, 0x99, 0xcc, 0x99, 0x96, + 0x0, 0x1, 0x88, 0x88, 0xcc, 0x88, 0x88, 0x30, + 0xa, 0xaa, 0xaa, 0xcc, 0xaa, 0xaa, 0xa4, 0x1, + 0x11, 0x7c, 0x5a, 0x71, 0x28, 0x30, 0x5, 0x9b, + 0xd0, 0x0, 0xb9, 0xa4, 0x0, 0x6, 0x12, 0xd3, + 0x69, 0x47, 0xc6, 0x20, 0x0, 0x8, 0xb8, 0x52, + 0x0, 0x16, 0xb5, + + /* U+88DC "補" */ + 0x2, 0x90, 0x0, 0x0, 0x85, 0x86, 0x0, 0x0, + 0xc4, 0x0, 0x0, 0x85, 0xa, 0x70, 0x0, 0x34, + 0x19, 0x99, 0xdc, 0x9a, 0xc1, 0x1d, 0xde, 0x75, + 0x55, 0xb9, 0x55, 0x50, 0x0, 0xc, 0x11, 0x22, + 0xa7, 0x22, 0x10, 0x0, 0x58, 0x2a, 0xba, 0xdc, + 0xac, 0x90, 0x0, 0xd7, 0xab, 0x30, 0x85, 0x4, + 0x90, 0xb, 0xfd, 0x3a, 0xdc, 0xed, 0xcd, 0x90, + 0x68, 0xc3, 0x8a, 0x30, 0x85, 0x4, 0x90, 0x0, + 0xc1, 0xa, 0xdc, 0xed, 0xcd, 0x90, 0x0, 0xc1, + 0xa, 0x30, 0x85, 0x4, 0x90, 0x0, 0xc1, 0xa, + 0x30, 0x85, 0x4, 0x90, 0x0, 0xc1, 0xa, 0x30, + 0x85, 0x8d, 0x60, + + /* U+88E1 "裡" */ + 0x0, 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3c, 0x0, 0x8e, 0xce, 0xdc, 0xf3, 0x0, 0x7, + 0x10, 0x85, 0x9, 0x30, 0xa3, 0x1d, 0xdd, 0xf5, + 0x86, 0x1a, 0x51, 0xb3, 0x0, 0x2, 0xb0, 0x8c, + 0xad, 0xba, 0xe3, 0x0, 0xa, 0x15, 0x85, 0x9, + 0x30, 0xa3, 0x0, 0x7e, 0xa6, 0x8d, 0xce, 0xdc, + 0xe3, 0x6, 0xbc, 0xd1, 0x0, 0xa, 0x40, 0x0, + 0x4b, 0x3a, 0x5b, 0x0, 0x9, 0x30, 0x0, 0x0, + 0x2a, 0x2, 0x7d, 0xdf, 0xed, 0xd4, 0x0, 0x2a, + 0x0, 0x0, 0x9, 0x30, 0x0, 0x0, 0x2a, 0x0, + 0x0, 0x9, 0x30, 0x0, 0x0, 0x2a, 0x1, 0xdd, + 0xde, 0xdd, 0xdb, + + /* U+88FD "製" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xc0, 0xd0, 0x0, 0x0, 0x0, 0xc0, 0x7, 0xea, + 0xfa, 0xa4, 0xd, 0x0, 0xc0, 0xa, 0x31, 0xd1, + 0x11, 0xd, 0x0, 0xc0, 0x18, 0x88, 0xe8, 0x88, + 0xd, 0x0, 0xc0, 0x4, 0xaa, 0xfa, 0xa5, 0xd, + 0x0, 0xc0, 0x6, 0x60, 0xd0, 0x38, 0x8, 0x0, + 0xc0, 0x6, 0x60, 0xc2, 0xb5, 0x0, 0x77, 0x80, + 0x0, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0xc, + 0xcc, 0xcd, 0xff, 0xcc, 0xcc, 0xc7, 0x0, 0x1, + 0x8b, 0x36, 0x90, 0x1a, 0x60, 0x18, 0xcd, 0xa0, + 0x0, 0xab, 0xa2, 0x0, 0x4, 0x5, 0x92, 0x69, + 0x7, 0xc6, 0x10, 0x0, 0xb, 0xd9, 0x51, 0x0, + 0x17, 0xc6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+8907 "複" */ + 0x0, 0x30, 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x2e, 0x11, 0x11, 0x11, 0x0, 0x7, + 0x0, 0xbc, 0xbb, 0xbb, 0xb7, 0xd, 0xdd, 0xe7, + 0xe5, 0x55, 0x55, 0x40, 0x0, 0x3, 0x86, 0xd5, + 0x44, 0x44, 0xe0, 0x0, 0xc, 0x23, 0xba, 0xaa, + 0xaa, 0xe0, 0x0, 0x7e, 0xa3, 0xb5, 0x44, 0x44, + 0xe0, 0x6, 0xcd, 0xb0, 0x48, 0xe6, 0x55, 0x50, + 0x1c, 0x3a, 0x84, 0x1d, 0xeb, 0xbb, 0x90, 0x0, + 0x2a, 0x3, 0xcd, 0x40, 0x2d, 0x30, 0x0, 0x2a, + 0x9, 0x22, 0xd9, 0xd4, 0x0, 0x0, 0x2a, 0x0, + 0x27, 0xdb, 0xd8, 0x30, 0x0, 0x2a, 0x1d, 0xb6, + 0x10, 0x18, 0xca, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+897F "西" */ + 0x2e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe1, 0x0, + 0x0, 0xd, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0xe0, 0x0, 0x0, 0x5, 0xdd, 0xdf, + 0xdd, 0xfd, 0xdd, 0x60, 0x5, 0x80, 0xc, 0x0, + 0xe0, 0x7, 0x70, 0x5, 0x80, 0x49, 0x0, 0xe0, + 0x7, 0x70, 0x5, 0x80, 0xc2, 0x0, 0xe0, 0x7, + 0x70, 0x5, 0xac, 0x50, 0x0, 0xad, 0xde, 0x70, + 0x5, 0x92, 0x0, 0x0, 0x0, 0x7, 0x70, 0x5, + 0x80, 0x0, 0x0, 0x0, 0x7, 0x70, 0x5, 0xfe, + 0xee, 0xee, 0xee, 0xef, 0x70, 0x5, 0x80, 0x0, + 0x0, 0x0, 0x7, 0x70, + + /* U+8981 "要" */ + 0xd, 0xdd, 0xdf, 0xdd, 0xfd, 0xdd, 0xd0, 0x0, + 0x0, 0x2b, 0x0, 0xd0, 0x0, 0x0, 0x4, 0xec, + 0xdf, 0xcc, 0xfc, 0xce, 0x60, 0x4, 0x90, 0x2b, + 0x0, 0xd0, 0x8, 0x60, 0x4, 0x90, 0x2b, 0x0, + 0xd0, 0x8, 0x60, 0x3, 0xcc, 0xce, 0xdc, 0xcc, + 0xcc, 0x40, 0x0, 0x0, 0x1d, 0x20, 0x0, 0x0, + 0x0, 0x3c, 0xcd, 0xfd, 0xcc, 0xce, 0xec, 0xc3, + 0x0, 0x6, 0xb0, 0x0, 0x1e, 0x20, 0x0, 0x0, + 0x1d, 0xc8, 0x54, 0xd5, 0x0, 0x0, 0x0, 0x0, + 0x3b, 0xfd, 0xe9, 0x40, 0x0, 0xb, 0xcc, 0xb7, + 0x10, 0x15, 0xae, 0x70, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+898B "見" */ + 0x0, 0x2f, 0xdd, 0xdd, 0xdd, 0xdd, 0x0, 0x0, + 0x2b, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x2f, + 0xcc, 0xcc, 0xcc, 0xdd, 0x0, 0x0, 0x2b, 0x0, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0x2e, 0xbb, 0xbb, + 0xbb, 0xcd, 0x0, 0x0, 0x2c, 0x11, 0x11, 0x11, + 0x2d, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x1d, + 0x0, 0x0, 0x2d, 0xef, 0xdd, 0xfd, 0xdb, 0x0, + 0x0, 0x0, 0x69, 0x0, 0xd1, 0x0, 0x0, 0x0, + 0x0, 0xd3, 0x0, 0xd1, 0x0, 0x9, 0x0, 0x4d, + 0x80, 0x0, 0xd1, 0x0, 0x2c, 0xd, 0xb4, 0x0, + 0x0, 0x9f, 0xee, 0xf6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+898F "規" */ + 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0x0, 0x6e, 0xdd, 0xde, 0xb0, 0x4, 0x6d, + 0x44, 0x67, 0x0, 0x3, 0xb0, 0x17, 0x8e, 0x76, + 0x6e, 0xcc, 0xcd, 0xb0, 0x0, 0x1c, 0x0, 0x67, + 0x0, 0x3, 0xb0, 0x0, 0x1c, 0x0, 0x6b, 0x77, + 0x79, 0xb0, 0x6d, 0xef, 0xdd, 0x7a, 0x55, 0x57, + 0xb0, 0x0, 0x3b, 0x0, 0x68, 0x0, 0x4, 0xb0, + 0x0, 0x5f, 0x50, 0x4d, 0xec, 0xfc, 0x90, 0x0, + 0x95, 0xc4, 0x6, 0x80, 0xe0, 0x0, 0x1, 0xd0, + 0x2c, 0xb, 0x30, 0xe0, 0x24, 0xa, 0x70, 0x0, + 0x7b, 0x0, 0xe0, 0x48, 0x4a, 0x0, 0xc, 0x90, + 0x0, 0xbd, 0xe3, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, + + /* U+8996 "視" */ + 0x0, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0x10, 0xf, 0xcc, 0xcd, 0xc0, 0x4, 0x48, + 0x63, 0xd, 0x0, 0x2, 0xc0, 0x8, 0x88, 0xbc, + 0xf, 0xbb, 0xbc, 0xc0, 0x0, 0x0, 0xd2, 0xd, + 0x0, 0x2, 0xc0, 0x0, 0x9, 0x60, 0xf, 0xbb, + 0xbc, 0xc0, 0x0, 0x6f, 0xa0, 0xd, 0x0, 0x2, + 0xc0, 0x8, 0xce, 0xa9, 0xd, 0x22, 0x24, 0xc0, + 0x4a, 0xe, 0xa, 0x1a, 0xea, 0xfa, 0x80, 0x0, + 0xe, 0x0, 0x0, 0xc0, 0xe0, 0x0, 0x0, 0xe, + 0x0, 0x4, 0x90, 0xe0, 0x12, 0x0, 0xe, 0x0, + 0x2d, 0x20, 0xe0, 0x39, 0x0, 0xe, 0x7, 0xc2, + 0x0, 0xad, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+899A "覚" */ + 0x0, 0x72, 0x1, 0xa0, 0x0, 0x57, 0x0, 0x0, + 0x4d, 0x0, 0xa5, 0x2, 0xe2, 0x0, 0xa, 0xbe, + 0xbb, 0xcb, 0xbd, 0xdb, 0xa0, 0xd, 0x11, 0x11, + 0x11, 0x11, 0x11, 0xe0, 0xd, 0x9, 0xaa, 0xaa, + 0xaa, 0x90, 0xe0, 0x0, 0xe, 0x0, 0x0, 0x0, + 0xe0, 0x0, 0x0, 0xe, 0x99, 0x99, 0x99, 0xe0, + 0x0, 0x0, 0xe, 0x44, 0x44, 0x44, 0xe0, 0x0, + 0x0, 0xe, 0x44, 0x44, 0x44, 0xe0, 0x0, 0x0, + 0xe, 0xaa, 0xaa, 0xaa, 0xe0, 0x0, 0x0, 0x0, + 0x69, 0x1, 0xd0, 0x0, 0x31, 0x0, 0x17, 0xd1, + 0x1, 0xd0, 0x0, 0x85, 0x3d, 0xc7, 0x10, 0x0, + 0xbd, 0xdd, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+89AA "親" */ + 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x2b, 0x62, 0x1a, 0xdc, 0xce, 0xa0, 0x9, 0xa8, + 0x8b, 0x6a, 0x20, 0x5, 0xa0, 0x0, 0xb0, 0xd, + 0xa, 0xdc, 0xcd, 0xa0, 0x1, 0xb2, 0x68, 0x1a, + 0x20, 0x5, 0xa0, 0x49, 0x9c, 0xc9, 0x9a, 0xb9, + 0x9c, 0xa0, 0x0, 0x6, 0x60, 0xa, 0x42, 0x27, + 0xa0, 0x2b, 0xbd, 0xdb, 0x9a, 0x20, 0x5, 0xa0, + 0x3, 0x58, 0x84, 0x28, 0xfd, 0xfd, 0x90, 0x3, + 0xa6, 0x6b, 0x10, 0xd0, 0xd0, 0x0, 0xb, 0x36, + 0x64, 0x92, 0xc0, 0xd0, 0x23, 0x17, 0x6, 0x60, + 0x19, 0x60, 0xd0, 0x48, 0x0, 0x8d, 0x40, 0xb9, + 0x0, 0xab, 0xd4, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x1, 0x10, + + /* U+89BA "覺" */ + 0x0, 0x0, 0x61, 0x14, 0x0, 0x0, 0x0, 0x0, + 0x79, 0x31, 0xcb, 0x2a, 0xac, 0x0, 0x0, 0xab, + 0x93, 0x46, 0x29, 0xab, 0x0, 0x0, 0x9a, 0x81, + 0xbc, 0x18, 0x9a, 0x0, 0x1, 0x97, 0x47, 0xa7, + 0x44, 0x7a, 0x10, 0xd, 0x99, 0x99, 0x99, 0x99, + 0x99, 0xe0, 0x9, 0xb, 0x88, 0x88, 0x88, 0xb0, + 0xa0, 0x0, 0xe, 0x99, 0x99, 0x99, 0xe0, 0x0, + 0x0, 0xe, 0x44, 0x44, 0x44, 0xe0, 0x0, 0x0, + 0xe, 0x44, 0x44, 0x44, 0xe0, 0x0, 0x0, 0x9, + 0xbd, 0x99, 0xe9, 0x90, 0x10, 0x0, 0x3, 0xc3, + 0x1, 0xd0, 0x0, 0x75, 0x2a, 0xca, 0x30, 0x0, + 0xcc, 0xbc, 0xc1, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+89C0 "觀" */ + 0x0, 0x65, 0x9, 0x20, 0x0, 0x0, 0x0, 0xb, + 0xdd, 0xbe, 0xc7, 0xbb, 0xbb, 0xd0, 0x0, 0x65, + 0x8, 0x20, 0xb0, 0x0, 0xb0, 0x9, 0x9c, 0x4b, + 0xb4, 0xba, 0xaa, 0xd0, 0xa, 0x1a, 0x46, 0x64, + 0xb0, 0x0, 0xb0, 0x5, 0xa8, 0x48, 0x72, 0xbb, + 0xaa, 0xd0, 0x0, 0xd5, 0xa8, 0x42, 0xb0, 0x0, + 0xb0, 0x7, 0xd6, 0xaa, 0x63, 0xb7, 0x66, 0xc0, + 0x2c, 0xea, 0xcc, 0xa1, 0x3d, 0x4c, 0x30, 0x1, + 0xc2, 0x88, 0x20, 0xb, 0xb, 0x0, 0x0, 0xd6, + 0xaa, 0x61, 0x38, 0xb, 0x5, 0x0, 0xe9, 0xcc, + 0x94, 0xb3, 0xb, 0x9, 0x0, 0xc1, 0x11, 0x18, + 0x70, 0xc, 0xc6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+89D2 "角" */ + 0x0, 0x3, 0xa0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0xec, 0xcc, 0xc1, 0x0, 0x0, 0xa8, 0x0, 0x6, + 0x80, 0x0, 0x1c, 0xfb, 0xbb, 0xbf, 0xbb, 0xb2, + 0xb9, 0xe2, 0x22, 0xf2, 0x22, 0xc3, 0x1, 0xd0, + 0x0, 0xe0, 0x0, 0xb3, 0x1, 0xfd, 0xdd, 0xfd, + 0xdd, 0xf3, 0x2, 0xd0, 0x0, 0xe0, 0x0, 0xb3, + 0x4, 0xc0, 0x0, 0xe0, 0x0, 0xb3, 0x5, 0xed, + 0xdd, 0xfd, 0xdd, 0xf3, 0xa, 0x50, 0x0, 0xe0, + 0x0, 0xb3, 0x1e, 0x0, 0x0, 0xe0, 0x0, 0xc3, + 0x95, 0x0, 0x0, 0xe0, 0xbe, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+89E3 "解" */ + 0x0, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xfb, 0xb3, 0xc, 0xdf, 0xcd, 0xc0, 0x7, 0x70, + 0xc2, 0x0, 0x68, 0x2, 0xb0, 0x1f, 0x77, 0xd6, + 0x0, 0xd2, 0x4, 0x90, 0x8f, 0x6c, 0x5c, 0x3c, + 0x90, 0xbd, 0x40, 0xa, 0x2a, 0xa, 0x25, 0x51, + 0x60, 0x0, 0xa, 0xae, 0x9e, 0x14, 0xa3, 0xb0, + 0x0, 0xa, 0x4b, 0x2b, 0x1b, 0xdd, 0xfd, 0xa0, + 0xb, 0x3b, 0x1b, 0x3b, 0x3, 0xb0, 0x0, 0xc, + 0x8d, 0x8d, 0x2b, 0xbc, 0xeb, 0xb2, 0xc, 0xa, + 0xa, 0x11, 0x14, 0xb1, 0x10, 0x39, 0xa, 0xb, + 0x10, 0x3, 0xb0, 0x0, 0x83, 0x4, 0xac, 0x0, + 0x3, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+89E6 "触" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc1, 0x0, 0x0, 0xd, 0x10, 0x0, 0x1, 0xfb, + 0xb3, 0x0, 0xd, 0x10, 0x0, 0x6, 0x80, 0xc1, + 0x0, 0xe, 0x20, 0x0, 0xe, 0x31, 0xb0, 0xf, + 0xff, 0xff, 0xc0, 0x8f, 0xce, 0xbf, 0xc, 0xc, + 0x0, 0xc0, 0x1c, 0x1b, 0xc, 0xc, 0xc, 0x0, + 0xc0, 0xa, 0xce, 0xbf, 0xc, 0xc, 0x0, 0xc0, + 0xb, 0x1b, 0xc, 0xe, 0x9e, 0xaa, 0xc0, 0xb, + 0x1b, 0xc, 0x4, 0x4e, 0x54, 0x30, 0xc, 0xce, + 0xbf, 0x0, 0xd, 0x19, 0x10, 0xc, 0xb, 0xc, + 0x0, 0xd, 0x15, 0x80, 0x3b, 0xb, 0xc, 0x37, + 0x8f, 0xcd, 0xe0, 0x85, 0xb, 0x7b, 0x59, 0x74, + 0x20, 0x75, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+8A00 "言" */ + 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0x10, 0x0, 0x0, 0x1d, 0xdd, + 0xdd, 0xdf, 0xdd, 0xdd, 0xd5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xcc, 0xcc, + 0xcc, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xaa, 0xaa, 0xaa, 0xa3, + 0x0, 0x0, 0x1, 0x11, 0x11, 0x11, 0x10, 0x0, + 0x0, 0x1, 0x11, 0x11, 0x11, 0x10, 0x0, 0x0, + 0x2f, 0xbb, 0xbb, 0xbb, 0xd7, 0x0, 0x0, 0x2c, + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x2c, 0x11, + 0x11, 0x11, 0x87, 0x0, 0x0, 0x2e, 0xaa, 0xaa, + 0xaa, 0xc7, 0x0, + + /* U+8A08 "計" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3b, 0x0, 0x0, 0xb, 0x30, 0x0, 0x0, 0xd, + 0x30, 0x0, 0xb, 0x30, 0x0, 0x2, 0x26, 0x32, + 0x10, 0xb, 0x30, 0x0, 0xa, 0xaa, 0xaa, 0x70, + 0xb, 0x30, 0x0, 0x2, 0x66, 0x66, 0x0, 0xb, + 0x30, 0x0, 0x2, 0x44, 0x44, 0x4c, 0xcf, 0xdc, + 0xc2, 0x5, 0xcc, 0xcc, 0x0, 0xb, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0x4, + 0xcc, 0xcd, 0x10, 0xb, 0x30, 0x0, 0x5, 0x70, + 0xb, 0x10, 0xb, 0x30, 0x0, 0x5, 0x70, 0xb, + 0x10, 0xb, 0x30, 0x0, 0x5, 0xec, 0xcf, 0x10, + 0xb, 0x30, 0x0, 0x5, 0x70, 0x0, 0x0, 0xb, + 0x30, 0x0, + + /* U+8A0A "訊" */ + 0x0, 0x54, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0x0, 0xde, 0xfe, 0xef, 0x20, 0x2, 0x26, + 0x22, 0x0, 0xd0, 0xc, 0x20, 0x1a, 0xaa, 0xa9, + 0x0, 0xd0, 0xc, 0x20, 0x3, 0x66, 0x62, 0x0, + 0xd0, 0xc, 0x20, 0x2, 0x44, 0x41, 0x0, 0xd0, + 0xc, 0x20, 0x6, 0xcc, 0xc5, 0xdd, 0xfd, 0xac, + 0x20, 0x0, 0x0, 0x0, 0x0, 0xe0, 0xb, 0x20, + 0x7, 0xcc, 0xc5, 0x0, 0xd0, 0xa, 0x30, 0x8, + 0x20, 0x66, 0x0, 0xd0, 0x9, 0x30, 0x8, 0x20, + 0x66, 0x0, 0xd0, 0x8, 0x57, 0x8, 0xdc, 0xd6, + 0x0, 0xd0, 0x4, 0xb8, 0x8, 0x30, 0x0, 0x0, + 0xd0, 0x0, 0x93, 0x0, 0x0, 0x0, 0x0, 0x20, + 0x0, 0x0, + + /* U+8A0E "討" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x85, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x1d, + 0x0, 0x0, 0x0, 0x1d, 0x0, 0x29, 0x9a, 0x99, + 0x0, 0x0, 0x1d, 0x0, 0x13, 0x33, 0x33, 0x9a, + 0xaa, 0xbf, 0xa6, 0x8, 0xbb, 0xb5, 0x33, 0x33, + 0x4e, 0x32, 0x1, 0x11, 0x10, 0x1, 0x0, 0x1d, + 0x0, 0x8, 0xcc, 0xc5, 0xc, 0x20, 0x1d, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xc0, 0x1d, 0x0, 0x9, + 0xcc, 0xc6, 0x0, 0xc3, 0x1d, 0x0, 0xb, 0x10, + 0x67, 0x0, 0x31, 0x1d, 0x0, 0xb, 0x10, 0x67, + 0x0, 0x0, 0x1d, 0x0, 0xb, 0xcc, 0xd7, 0x0, + 0x0, 0x2d, 0x0, 0xb, 0x10, 0x0, 0x0, 0x7e, + 0xe7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+8A13 "訓" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, + 0x70, 0x0, 0xb1, 0x0, 0xe, 0x0, 0x1e, 0x0, + 0xc, 0x11, 0xc0, 0xe0, 0x22, 0x62, 0x10, 0xc1, + 0x1c, 0xe, 0x2a, 0xaa, 0xa9, 0xc, 0x11, 0xc0, + 0xe0, 0x36, 0x66, 0x20, 0xc1, 0x1c, 0xe, 0x2, + 0x44, 0x41, 0xd, 0x1, 0xc0, 0xe0, 0x7c, 0xcc, + 0x40, 0xd0, 0x1c, 0xe, 0x0, 0x0, 0x0, 0xd, + 0x1, 0xc0, 0xe0, 0x8c, 0xcc, 0x60, 0xd0, 0x1c, + 0xe, 0x9, 0x30, 0x57, 0x3b, 0x1, 0xc0, 0xe0, + 0x93, 0x5, 0x77, 0x70, 0x1c, 0xe, 0x9, 0xdc, + 0xd8, 0xd1, 0x0, 0x50, 0xe0, 0x93, 0x0, 0x58, + 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A18 "記" */ + 0x0, 0x73, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0x0, 0x7e, 0xee, 0xef, 0x30, 0x49, 0x9b, + 0x99, 0x0, 0x0, 0xb, 0x30, 0x12, 0x22, 0x22, + 0x0, 0x0, 0xb, 0x30, 0x9, 0xcc, 0xc4, 0x0, + 0x0, 0xb, 0x30, 0x0, 0x0, 0x0, 0x27, 0x77, + 0x7d, 0x30, 0xb, 0xbb, 0xb7, 0x5c, 0x66, 0x6d, + 0x30, 0x0, 0x0, 0x0, 0x59, 0x0, 0x1, 0x0, + 0xb, 0xcc, 0xc5, 0x59, 0x0, 0x0, 0x0, 0xd, + 0x0, 0x66, 0x59, 0x0, 0x0, 0x40, 0xd, 0x0, + 0x66, 0x59, 0x0, 0x0, 0xd0, 0xe, 0xaa, 0xd6, + 0x4a, 0x0, 0x0, 0xd0, 0xd, 0x11, 0x10, 0x1d, + 0xee, 0xee, 0x70, + + /* U+8A2A "訪" */ + 0x0, 0x31, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x49, 0x0, 0x0, 0xc, 0x10, 0x0, 0x2, 0x28, + 0x21, 0x1, 0x18, 0x61, 0x10, 0x1a, 0xaa, 0xa9, + 0x9c, 0xfd, 0xcc, 0xc6, 0x3, 0x66, 0x61, 0x0, + 0xd0, 0x0, 0x0, 0x2, 0x44, 0x41, 0x0, 0xe3, + 0x33, 0x20, 0x6, 0xcc, 0xc3, 0x0, 0xe9, 0x9a, + 0xc0, 0x0, 0x0, 0x0, 0x2, 0xb0, 0x1, 0xc0, + 0x7, 0xcc, 0xc4, 0x5, 0x80, 0x2, 0xb0, 0x8, + 0x20, 0x74, 0xb, 0x30, 0x3, 0xa0, 0x8, 0x20, + 0x74, 0x2d, 0x0, 0x5, 0x80, 0x8, 0xdc, 0xe6, + 0xd4, 0x0, 0x8, 0x60, 0x8, 0x20, 0x8, 0x70, + 0xa, 0xec, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A2D "設" */ + 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x69, 0x0, 0xd, 0xdd, 0xea, 0x0, 0x2, 0x29, + 0x22, 0xe, 0x0, 0x3a, 0x0, 0x3a, 0xaa, 0xaa, + 0x1c, 0x0, 0x3a, 0x0, 0x4, 0x66, 0x62, 0x87, + 0x0, 0x2c, 0x52, 0x3, 0x44, 0x45, 0xa0, 0x0, + 0x5, 0x62, 0x8, 0xcc, 0xc6, 0x99, 0x99, 0x99, + 0x60, 0x0, 0x0, 0x0, 0x99, 0x44, 0x4b, 0x60, + 0x9, 0xcc, 0xc5, 0x1d, 0x10, 0x2e, 0x0, 0xb, + 0x10, 0x76, 0x5, 0xc3, 0xd3, 0x0, 0xb, 0x10, + 0x76, 0x0, 0xbf, 0x80, 0x0, 0xb, 0xcc, 0xe6, + 0x5c, 0xc5, 0xdb, 0x51, 0xb, 0x10, 0x7, 0xe7, + 0x0, 0x7, 0xe7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A31 "許" */ + 0x0, 0x54, 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, + 0x2a, 0x0, 0xc, 0x20, 0x0, 0x0, 0x49, 0xac, + 0x99, 0x2f, 0xdd, 0xdd, 0xd1, 0x12, 0x22, 0x22, + 0xa6, 0xe, 0x10, 0x0, 0x9, 0xbb, 0xb9, 0xd0, + 0xd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x20, 0xd, + 0x10, 0x0, 0x9, 0xbb, 0xb6, 0x88, 0x8f, 0x88, + 0x83, 0x0, 0x0, 0x0, 0x66, 0x6e, 0x76, 0x63, + 0xa, 0xcc, 0xc6, 0x0, 0xd, 0x10, 0x0, 0xc, + 0x0, 0x57, 0x0, 0xd, 0x10, 0x0, 0xc, 0x0, + 0x57, 0x0, 0xd, 0x10, 0x0, 0xc, 0xbb, 0xd7, + 0x0, 0xd, 0x10, 0x0, 0xb, 0x11, 0x10, 0x0, + 0xd, 0x10, 0x0, + + /* U+8A33 "訳" */ + 0x0, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3b, 0x0, 0x9, 0x99, 0x99, 0x80, 0x2, 0x28, + 0x22, 0xd, 0x55, 0x55, 0xd0, 0x2a, 0xaa, 0xa9, + 0xc, 0x0, 0x0, 0xd0, 0x3, 0x66, 0x62, 0xc, + 0x0, 0x0, 0xd0, 0x2, 0x44, 0x41, 0xe, 0x55, + 0x55, 0xd0, 0x7, 0xcc, 0xc5, 0x1d, 0x78, 0xd7, + 0x60, 0x0, 0x0, 0x0, 0x2a, 0x0, 0xe0, 0x0, + 0x8, 0xcc, 0xc6, 0x48, 0x0, 0xa5, 0x0, 0x9, + 0x30, 0x57, 0x76, 0x0, 0x5b, 0x0, 0x9, 0x30, + 0x57, 0xb3, 0x0, 0xe, 0x40, 0x9, 0xdc, 0xda, + 0xd0, 0x0, 0x5, 0xe4, 0x9, 0x30, 0x7, 0x60, + 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A34 "訴" */ + 0x0, 0x22, 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, + 0x3c, 0x0, 0x1, 0x59, 0xdb, 0x40, 0x2, 0x28, + 0x32, 0xf, 0x84, 0x10, 0x0, 0x1a, 0xaa, 0xa9, + 0xe, 0x0, 0x0, 0x0, 0x3, 0x66, 0x62, 0xe, + 0x11, 0x11, 0x10, 0x2, 0x44, 0x41, 0xf, 0xaa, + 0xec, 0xa4, 0x7, 0xcc, 0xc4, 0x1d, 0x0, 0xb4, + 0x0, 0x0, 0x0, 0x0, 0x2c, 0xc8, 0xc4, 0x0, + 0x7, 0xcc, 0xc4, 0x3a, 0x7, 0xfa, 0x10, 0x8, + 0x30, 0x75, 0x78, 0x0, 0xba, 0xe3, 0x8, 0x30, + 0x75, 0xd3, 0x0, 0xb4, 0x10, 0x8, 0xdc, 0xeb, + 0xd0, 0x0, 0xb4, 0x0, 0x8, 0x40, 0x6, 0x40, + 0x0, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x10, 0x0, + + /* U+8A55 "評" */ + 0x0, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3c, 0x0, 0x8e, 0xef, 0xee, 0xe2, 0x2, 0x26, + 0x22, 0x0, 0xd, 0x10, 0x0, 0x1a, 0xaa, 0xa9, + 0x29, 0xd, 0x13, 0xb0, 0x3, 0x66, 0x62, 0xc, + 0xd, 0x17, 0x60, 0x2, 0x44, 0x41, 0xb, 0x1d, + 0x1c, 0x10, 0x6, 0xcc, 0xc4, 0x2, 0xd, 0x13, + 0x0, 0x0, 0x0, 0x1, 0xff, 0xff, 0xff, 0xf6, + 0x7, 0xcc, 0xc4, 0x0, 0xd, 0x10, 0x0, 0x9, + 0x30, 0x75, 0x0, 0xd, 0x10, 0x0, 0x9, 0x30, + 0x75, 0x0, 0xd, 0x10, 0x0, 0x9, 0xdc, 0xe5, + 0x0, 0xd, 0x10, 0x0, 0x9, 0x30, 0x0, 0x0, + 0xd, 0x10, 0x0, + + /* U+8A66 "試" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x3, 0xb6, 0x0, 0x0, 0x96, + 0x0, 0x0, 0x3, 0xaa, 0x20, 0x36, 0x77, 0x60, + 0x0, 0x3, 0xb2, 0x40, 0x36, 0x66, 0x68, 0xee, + 0xee, 0xfe, 0xe0, 0x7, 0x88, 0x60, 0x0, 0x1, + 0xb0, 0x0, 0x2, 0x33, 0x20, 0x11, 0x11, 0xc0, + 0x0, 0xb, 0xcc, 0xa8, 0xcf, 0xc5, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x0, 0xd0, 0x0, 0xc, + 0xcc, 0xa0, 0xd, 0x0, 0xc1, 0x0, 0xd, 0x0, + 0xd0, 0xd, 0x1, 0x93, 0x0, 0xd, 0x0, 0xd1, + 0x5f, 0xcb, 0x75, 0x91, 0xe, 0xcc, 0xd9, 0x94, + 0x0, 0x2a, 0xb0, 0xd, 0x0, 0x0, 0x0, 0x0, + 0xa, 0xa0, + + /* U+8A71 "話" */ + 0x0, 0x32, 0x0, 0x0, 0x0, 0x2, 0x30, 0x0, + 0x3c, 0x0, 0x25, 0x8b, 0xda, 0x50, 0x2, 0x28, + 0x32, 0x47, 0x4d, 0x10, 0x0, 0x2a, 0xaa, 0xa9, + 0x0, 0xc, 0x10, 0x0, 0x3, 0x66, 0x62, 0x34, + 0x4d, 0x54, 0x43, 0x2, 0x44, 0x42, 0x57, 0x7e, + 0x87, 0x75, 0x7, 0xcc, 0xc5, 0x0, 0xc, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x1d, 0x31, 0x10, + 0x8, 0xcc, 0xc7, 0x2e, 0xcc, 0xcc, 0xe0, 0x9, + 0x30, 0x48, 0x29, 0x0, 0x0, 0xe0, 0x9, 0x30, + 0x48, 0x29, 0x0, 0x0, 0xe0, 0x9, 0x85, 0x98, + 0x2a, 0x22, 0x22, 0xe0, 0x9, 0x86, 0x63, 0x2e, + 0xbb, 0xbb, 0xd0, + + /* U+8A72 "該" */ + 0x0, 0x41, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x0, 0xb, 0x30, 0x0, 0x2, 0x29, + 0x22, 0x68, 0x8b, 0xb8, 0x84, 0x3a, 0xaa, 0xa9, + 0x34, 0xa9, 0x44, 0x42, 0x4, 0x66, 0x62, 0x1, + 0xc0, 0x6, 0x0, 0x3, 0x44, 0x41, 0x1c, 0x63, + 0x98, 0x0, 0x8, 0xcc, 0xc4, 0x6a, 0x8d, 0xb0, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x8b, 0x5, 0xc0, + 0x9, 0xcc, 0xc5, 0x2a, 0x70, 0x2d, 0x20, 0xb, + 0x10, 0x66, 0x92, 0x2, 0xe4, 0x0, 0xb, 0x10, + 0x66, 0x0, 0x6d, 0xb8, 0x0, 0xb, 0xcc, 0xd6, + 0x5c, 0xb1, 0xb, 0x90, 0xb, 0x10, 0x9, 0xd5, + 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A73 "詳" */ + 0x0, 0x44, 0x0, 0x6, 0x0, 0x5, 0x40, 0x0, + 0x1d, 0x0, 0xc, 0x20, 0xd, 0x20, 0x15, 0x59, + 0x55, 0x5, 0x70, 0x48, 0x0, 0x16, 0x66, 0x66, + 0x8d, 0xdf, 0xdd, 0xd2, 0x5, 0x88, 0x83, 0x0, + 0xd, 0x0, 0x0, 0x1, 0x33, 0x31, 0x1, 0x1e, + 0x11, 0x10, 0x7, 0xcc, 0xc4, 0x3c, 0xcf, 0xcc, + 0x90, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x8, 0xdc, 0xd7, 0x0, 0xd, 0x0, 0x0, 0x9, + 0x30, 0x58, 0xce, 0xef, 0xee, 0xe5, 0x9, 0x30, + 0x58, 0x0, 0xd, 0x0, 0x0, 0x9, 0xdc, 0xd8, + 0x0, 0xd, 0x0, 0x0, 0x9, 0x30, 0x0, 0x0, + 0xd, 0x0, 0x0, + + /* U+8A8C "誌" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x95, 0x0, 0x0, 0x0, 0x87, + 0x0, 0x0, 0x95, 0x0, 0x0, 0x12, 0x37, 0x24, + 0x88, 0xca, 0x88, 0x70, 0x5a, 0xaa, 0xa4, 0x66, + 0xc9, 0x66, 0x50, 0x6, 0x66, 0x40, 0x0, 0x95, + 0x0, 0x0, 0x4, 0x44, 0x33, 0x88, 0xdb, 0x88, + 0x50, 0xc, 0xcc, 0x81, 0x33, 0xb3, 0x33, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x6c, 0x10, 0x0, 0xc, + 0xcc, 0x92, 0x4d, 0x5, 0x38, 0x0, 0xc, 0x0, + 0xb5, 0x6d, 0x0, 0xa, 0x40, 0xc, 0x0, 0xb8, + 0x3d, 0x0, 0xa4, 0xb0, 0xd, 0x66, 0xba, 0xd, + 0x10, 0xc0, 0xb0, 0xd, 0x66, 0x50, 0x7, 0xcc, + 0x80, 0x0, + + /* U+8A8D "認" */ + 0x0, 0x51, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4a, 0x0, 0x8c, 0xce, 0xdc, 0xf0, 0x2, 0x28, + 0x21, 0x7, 0xa, 0x20, 0xd0, 0x2a, 0xaa, 0xa8, + 0x3a, 0xc, 0x0, 0xd0, 0x3, 0x66, 0x62, 0x91, + 0x77, 0x0, 0xd0, 0x2, 0x44, 0x41, 0x6, 0xb0, + 0x46, 0xb0, 0x7, 0xcc, 0xc4, 0x99, 0x10, 0x56, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x0, 0x0, + 0x8, 0xcc, 0xc5, 0x53, 0xa8, 0x46, 0x40, 0x9, + 0x20, 0x66, 0xb2, 0xb1, 0x51, 0xc0, 0x9, 0x20, + 0x67, 0xb1, 0xb0, 0x7, 0x94, 0x9, 0xdc, 0xdb, + 0x51, 0xb0, 0xc, 0x23, 0x9, 0x30, 0x0, 0x0, + 0xce, 0xea, 0x0, + + /* U+8A95 "誕" */ + 0x3, 0x30, 0x0, 0x0, 0x0, 0x4, 0x30, 0x3, + 0xb0, 0x5d, 0xf6, 0x7a, 0xe9, 0x30, 0x35, 0xa5, + 0x10, 0xc0, 0x52, 0xc0, 0x0, 0x46, 0x66, 0x13, + 0x80, 0x0, 0xc0, 0x0, 0x1c, 0xca, 0xb, 0x31, + 0xb0, 0xc2, 0x20, 0x0, 0x0, 0x4b, 0xc7, 0xb0, + 0xcb, 0x90, 0x1c, 0xca, 0x0, 0x65, 0xb0, 0xc0, + 0x0, 0x0, 0x0, 0x36, 0x83, 0xb0, 0xc0, 0x0, + 0x2c, 0xcb, 0x1b, 0xb0, 0xb0, 0xc0, 0x0, 0x38, + 0xc, 0xa, 0xa0, 0xb6, 0xe6, 0x60, 0x38, 0xc, + 0x9, 0xc0, 0x45, 0x55, 0x50, 0x3d, 0xbd, 0x4c, + 0x4c, 0x30, 0x0, 0x0, 0x39, 0x1, 0xd2, 0x3, + 0xad, 0xdd, 0xc0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A98 "誘" */ + 0x0, 0x70, 0x0, 0x1, 0x24, 0x6a, 0x40, 0x0, + 0x85, 0x1, 0xca, 0x9e, 0x52, 0x0, 0x58, 0x9b, + 0x82, 0x22, 0x2e, 0x22, 0x20, 0x23, 0x33, 0x35, + 0xaa, 0xff, 0xea, 0xa3, 0xb, 0xbb, 0x70, 0x9, + 0x7d, 0x97, 0x0, 0x0, 0x0, 0x1, 0xb9, 0xd, + 0xb, 0x90, 0xb, 0xbb, 0x8c, 0x60, 0xa, 0x0, + 0x94, 0x1, 0x11, 0x11, 0xdd, 0xdd, 0xd2, 0x0, + 0xb, 0xbb, 0x80, 0x8, 0x50, 0xe0, 0x0, 0x1c, + 0x12, 0xa0, 0xb, 0x21, 0xcc, 0xf0, 0x1b, 0x1, + 0xa0, 0x1d, 0x0, 0x0, 0xd0, 0x1e, 0xbb, 0xa1, + 0xc5, 0x0, 0x2, 0xc0, 0x1a, 0x0, 0xb, 0x60, + 0x4, 0xcd, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8A9E "語" */ + 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0x0, 0xac, 0xee, 0xcc, 0xc1, 0x4, 0x49, + 0x54, 0x0, 0xa3, 0x0, 0x0, 0x16, 0x66, 0x66, + 0x6c, 0xfd, 0xcc, 0x0, 0x5, 0x88, 0x83, 0x0, + 0xd0, 0xd, 0x0, 0x1, 0x33, 0x31, 0x3, 0xa0, + 0xd, 0x0, 0x7, 0xcc, 0xc7, 0xcd, 0xdc, 0xce, + 0xc5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xcc, 0xc7, 0x6e, 0xdd, 0xde, 0x80, 0x9, + 0x30, 0x48, 0x66, 0x0, 0x5, 0x80, 0x9, 0x30, + 0x48, 0x66, 0x0, 0x5, 0x80, 0x9, 0x85, 0x88, + 0x68, 0x22, 0x27, 0x80, 0x9, 0x97, 0x74, 0x6d, + 0xaa, 0xac, 0x80, + + /* U+8AAA "說" */ + 0x0, 0x52, 0x0, 0x2, 0x40, 0x62, 0x0, 0x0, + 0x3b, 0x0, 0xa, 0x30, 0x3b, 0x0, 0x15, 0x59, + 0x53, 0x3b, 0x0, 0x9, 0x50, 0x17, 0x77, 0x77, + 0xd1, 0x0, 0x0, 0xc5, 0x5, 0x77, 0x74, 0x7e, + 0xdd, 0xdd, 0xa3, 0x2, 0x33, 0x30, 0x38, 0x0, + 0x5, 0x90, 0x7, 0xcc, 0xc2, 0x38, 0x0, 0x5, + 0x90, 0x0, 0x0, 0x0, 0x3e, 0xcc, 0xcd, 0x90, + 0x8, 0xcc, 0xc3, 0x3, 0xc1, 0xe1, 0x0, 0xa, + 0x20, 0x74, 0x4, 0xa0, 0xe0, 0x0, 0xa, 0x20, + 0x74, 0xa, 0x50, 0xe0, 0x25, 0xa, 0xcc, 0xe5, + 0x8c, 0x0, 0xe0, 0x48, 0x9, 0x20, 0x7, 0xa1, + 0x0, 0x9d, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8AAC "説" */ + 0x0, 0x44, 0x0, 0x7, 0x0, 0x5, 0x40, 0x0, + 0x2d, 0x0, 0x9, 0x60, 0xd, 0x30, 0x15, 0x59, + 0x54, 0x2, 0xb0, 0x4b, 0x0, 0x16, 0x66, 0x65, + 0x6d, 0xdd, 0xee, 0xc0, 0x5, 0x88, 0x82, 0x66, + 0x0, 0x1, 0xd0, 0x1, 0x33, 0x31, 0x66, 0x0, + 0x1, 0xd0, 0x7, 0xcc, 0xc4, 0x69, 0x44, 0x45, + 0xd0, 0x0, 0x0, 0x0, 0x49, 0xf9, 0xf9, 0x80, + 0x8, 0xcc, 0xc6, 0x2, 0xc0, 0xd0, 0x0, 0x9, + 0x30, 0x67, 0x6, 0x80, 0xd0, 0x0, 0x9, 0x30, + 0x67, 0xc, 0x30, 0xd0, 0x25, 0x9, 0xdc, 0xd7, + 0x9a, 0x0, 0xd0, 0x38, 0x9, 0x30, 0x8, 0xb1, + 0x0, 0x9d, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8AAD "読" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x86, + 0x4, 0xaa, 0xbe, 0xaa, 0xa0, 0x47, 0x88, 0x71, + 0x22, 0x4c, 0x22, 0x20, 0x59, 0x99, 0x90, 0x0, + 0x3c, 0x0, 0x0, 0x4, 0x44, 0x20, 0xbb, 0xbb, + 0xbb, 0x60, 0x5, 0x55, 0x32, 0x77, 0x77, 0x77, + 0x70, 0xc, 0xcc, 0x76, 0x82, 0x22, 0x22, 0xd0, + 0x0, 0x0, 0x6, 0x64, 0x30, 0x70, 0xc0, 0xd, + 0xcc, 0x90, 0x7, 0x60, 0xd0, 0x0, 0xc, 0x1, + 0xb0, 0xa, 0x40, 0xd0, 0x0, 0xc, 0x1, 0xb0, + 0x1e, 0x0, 0xd0, 0x42, 0xf, 0xcc, 0xb1, 0xc7, + 0x0, 0xd0, 0x83, 0xd, 0x0, 0xc, 0x90, 0x0, + 0xbd, 0xd0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, + + /* U+8AB0 "誰" */ + 0x0, 0x32, 0x0, 0x0, 0x51, 0x20, 0x0, 0x0, + 0x3c, 0x0, 0x5, 0xb3, 0xb0, 0x0, 0x2, 0x28, + 0x32, 0xb, 0x40, 0x90, 0x0, 0x2a, 0xaa, 0xa9, + 0x4f, 0xdd, 0xfd, 0xd3, 0x3, 0x66, 0x63, 0xdc, + 0x0, 0xd0, 0x0, 0x2, 0x44, 0x45, 0x9e, 0x77, + 0xe7, 0x50, 0x7, 0xcc, 0xc5, 0x1d, 0x44, 0xe4, + 0x30, 0x0, 0x0, 0x0, 0xc, 0x0, 0xd0, 0x0, + 0x9, 0xdc, 0xd8, 0xf, 0xdd, 0xfd, 0xb0, 0x9, + 0x30, 0x48, 0xc, 0x0, 0xd0, 0x0, 0x9, 0x30, + 0x48, 0xd, 0x0, 0xd0, 0x0, 0x9, 0xdc, 0xd8, + 0xf, 0xdd, 0xdd, 0xd3, 0x9, 0x30, 0x0, 0xc, + 0x0, 0x0, 0x0, + + /* U+8AB2 "課" */ + 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2c, 0x0, 0x9d, 0xcf, 0xcc, 0xf0, 0x4, 0x49, + 0x54, 0x93, 0xd, 0x0, 0xe0, 0x17, 0x77, 0x76, + 0x9d, 0xcf, 0xcc, 0xf0, 0x5, 0x88, 0x83, 0x93, + 0xd, 0x0, 0xe0, 0x1, 0x33, 0x31, 0x9a, 0x8e, + 0x88, 0xf0, 0x7, 0xcc, 0xc5, 0x12, 0x2e, 0x22, + 0x20, 0x0, 0x0, 0x0, 0x88, 0x8f, 0x88, 0x83, + 0x8, 0xcc, 0xc7, 0x55, 0xbf, 0xe5, 0x52, 0x9, + 0x30, 0x48, 0x4, 0xce, 0x88, 0x0, 0x9, 0x30, + 0x48, 0x4d, 0x1e, 0xb, 0x80, 0x9, 0xdc, 0xdc, + 0xd2, 0xe, 0x0, 0xa8, 0x9, 0x30, 0x0, 0x10, + 0xe, 0x0, 0x0, + + /* U+8ABF "調" */ + 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, + 0x40, 0xe, 0xdd, 0xdd, 0xdc, 0x46, 0x88, 0x60, + 0xc0, 0x8, 0x0, 0xc2, 0x44, 0x44, 0xc, 0x8b, + 0xeb, 0x2c, 0xa, 0xaa, 0x60, 0xc0, 0xb, 0x0, + 0xc0, 0x11, 0x11, 0xc, 0x56, 0xd6, 0x3c, 0x1c, + 0xcc, 0x70, 0xc4, 0x55, 0x52, 0xc0, 0x0, 0x0, + 0xb, 0x46, 0x66, 0xc, 0xd, 0xcc, 0x81, 0xaa, + 0x55, 0xc0, 0xc0, 0xb0, 0x1a, 0x38, 0xa0, 0xa, + 0xc, 0xb, 0x1, 0xa8, 0x4a, 0xaa, 0xa0, 0xc0, + 0xec, 0xcb, 0xd0, 0x50, 0x0, 0xc, 0xb, 0x0, + 0x86, 0x0, 0x0, 0x7c, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, + + /* U+8AC7 "談" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x83, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x3b, + 0x0, 0x9, 0x1c, 0x1, 0x90, 0x2, 0x27, 0x21, + 0x57, 0x3b, 0x9, 0x50, 0x2a, 0xaa, 0xa6, 0xc1, + 0x7a, 0x2a, 0x0, 0x4, 0x66, 0x60, 0x1, 0xe9, + 0xc4, 0x0, 0x2, 0x44, 0x40, 0x6d, 0x60, 0x2c, + 0x90, 0x7, 0xcc, 0xc2, 0x52, 0x2b, 0x0, 0x72, + 0x0, 0x0, 0x0, 0x8, 0x3a, 0x1, 0xa0, 0x8, + 0xcc, 0xc3, 0x67, 0x5a, 0x9, 0x60, 0xa, 0x20, + 0x75, 0xd0, 0x9f, 0x4a, 0x0, 0xa, 0x20, 0x74, + 0x3, 0xe4, 0xc0, 0x0, 0xa, 0xcc, 0xe5, 0x7e, + 0x60, 0x8e, 0x51, 0xa, 0x20, 0x7, 0xe5, 0x0, + 0x4, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+8ACB "請" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x65, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x1d, + 0x0, 0x8b, 0xbf, 0xbb, 0xb5, 0x4, 0x48, 0x43, + 0x0, 0xe, 0x0, 0x0, 0x18, 0x88, 0x87, 0x3b, + 0xbf, 0xbb, 0xb2, 0x4, 0x77, 0x72, 0x66, 0x6e, + 0x66, 0x64, 0x2, 0x33, 0x31, 0x44, 0x44, 0x44, + 0x43, 0x7, 0xcc, 0xc4, 0xd, 0xbb, 0xbb, 0xc0, + 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0xe0, 0x8, + 0xcc, 0xc5, 0xf, 0xaa, 0xaa, 0xe0, 0x9, 0x20, + 0x66, 0xe, 0x44, 0x44, 0xe0, 0x9, 0x20, 0x66, + 0xe, 0x44, 0x44, 0xe0, 0x9, 0xdc, 0xd6, 0xd, + 0x0, 0x0, 0xe0, 0x8, 0x20, 0x0, 0xd, 0x0, + 0x9c, 0xa0, + + /* U+8AD6 "論" */ + 0x0, 0x80, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, + 0x96, 0x0, 0x0, 0xae, 0x20, 0x0, 0x15, 0x78, + 0x50, 0x9, 0xa3, 0xd2, 0x0, 0x27, 0x77, 0x61, + 0xbb, 0x0, 0x3e, 0x60, 0x6, 0x88, 0x7e, 0xad, + 0xdd, 0xdc, 0xd8, 0x3, 0x33, 0x23, 0x0, 0x0, + 0x0, 0x0, 0xa, 0xcc, 0x64, 0xcc, 0xcc, 0xcc, + 0xc0, 0x0, 0x0, 0x5, 0x80, 0xa0, 0xb0, 0xc0, + 0xc, 0xdd, 0x85, 0x80, 0xa0, 0xb0, 0xc0, 0xc, + 0x2, 0xa5, 0xed, 0xec, 0xfc, 0xe0, 0xc, 0x2, + 0xa5, 0x80, 0xa0, 0xb0, 0xc0, 0xd, 0xcd, 0xa5, + 0x80, 0xa0, 0xb0, 0xc0, 0xc, 0x0, 0x5, 0x80, + 0xa0, 0xb8, 0x90, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8AF8 "諸" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x74, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x3b, + 0x0, 0x0, 0x87, 0x0, 0xb3, 0x2, 0x27, 0x21, + 0xbf, 0xff, 0xfd, 0xa0, 0x2a, 0xaa, 0xa6, 0x0, + 0x87, 0x1d, 0x10, 0x2, 0x44, 0x41, 0x11, 0x98, + 0xb8, 0x11, 0x4, 0x77, 0x74, 0xbb, 0xcf, 0xcb, + 0xb8, 0x5, 0x99, 0x91, 0x5, 0xd5, 0x0, 0x0, + 0x0, 0x11, 0x12, 0xbf, 0xcc, 0xcc, 0xe0, 0x8, + 0xcb, 0xc7, 0x5e, 0x0, 0x0, 0xe0, 0x9, 0x20, + 0x83, 0xe, 0xbb, 0xbb, 0xe0, 0x9, 0x20, 0x83, + 0xe, 0x0, 0x0, 0xe0, 0x9, 0x76, 0xb3, 0xe, + 0x11, 0x11, 0xe0, 0x8, 0x87, 0x71, 0xe, 0xaa, + 0xaa, 0xe0, + + /* U+8B02 "謂" */ + 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3c, 0x0, 0xac, 0xbf, 0xbb, 0xd6, 0x2, 0x28, + 0x31, 0xa2, 0xd, 0x0, 0x86, 0x2a, 0xaa, 0xa8, + 0xab, 0xaf, 0xaa, 0xd6, 0x3, 0x66, 0x62, 0xa4, + 0x2d, 0x22, 0x96, 0x2, 0x44, 0x41, 0x57, 0x77, + 0x77, 0x73, 0x7, 0xcc, 0xc4, 0x2b, 0xbb, 0xbb, + 0xa0, 0x0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0xe0, + 0x8, 0xcc, 0xc5, 0x2e, 0xbb, 0xbb, 0xe0, 0x9, + 0x30, 0x66, 0x2b, 0x0, 0x0, 0xe0, 0x9, 0x30, + 0x66, 0x2e, 0xaa, 0xaa, 0xe0, 0x9, 0xdc, 0xd6, + 0x2a, 0x0, 0x0, 0xe0, 0x9, 0x30, 0x0, 0x2a, + 0x0, 0x9c, 0x90, + + /* U+8B1B "講" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0, 0x0, 0xc, 0x20, 0xa0, 0x0, 0x0, 0x78, + 0x6, 0xae, 0xba, 0xea, 0x70, 0x36, 0x68, 0x61, + 0x1c, 0x31, 0xb1, 0x10, 0x47, 0x77, 0x72, 0xbe, + 0xcb, 0xeb, 0x50, 0x8, 0x88, 0x52, 0x2c, 0x52, + 0xb2, 0x20, 0x3, 0x33, 0x27, 0x88, 0x9e, 0x88, + 0x80, 0xc, 0xcc, 0x70, 0xaa, 0xae, 0xaa, 0x10, + 0x0, 0x0, 0x0, 0xe1, 0x2c, 0x1c, 0x20, 0xd, + 0xcc, 0x90, 0xfa, 0xbe, 0xae, 0x20, 0xa, 0x0, + 0xb0, 0xe0, 0x2c, 0xc, 0x30, 0xa, 0x0, 0xb8, + 0xf9, 0x99, 0x9e, 0xa0, 0xe, 0xcc, 0xb0, 0xe0, + 0x0, 0xb, 0x20, 0xb, 0x0, 0x0, 0xe0, 0x1, + 0xbd, 0x10, + + /* U+8B1D "謝" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa0, 0x0, 0x49, 0x0, 0x0, 0xd0, 0x0, 0x94, + 0x0, 0x75, 0x0, 0x0, 0xd0, 0x2, 0x66, 0x2a, + 0xdc, 0xc0, 0x0, 0xd0, 0x7, 0x77, 0x4a, 0x53, + 0xc7, 0x99, 0xf7, 0x6, 0xbb, 0x3a, 0x75, 0xc1, + 0x11, 0xe1, 0x0, 0x0, 0xa, 0x64, 0xc6, 0x20, + 0xd0, 0x6, 0xbb, 0x4a, 0x97, 0xc5, 0x80, 0xd0, + 0x0, 0x0, 0x1d, 0x87, 0xc0, 0xd0, 0xd0, 0x7, + 0xcc, 0x56, 0x6e, 0xc0, 0xa1, 0xd0, 0x9, 0x15, + 0x50, 0xa6, 0xc0, 0x0, 0xd0, 0x9, 0x15, 0x8c, + 0x60, 0xc0, 0x0, 0xd0, 0x9, 0xbd, 0x72, 0x0, + 0xc0, 0x0, 0xd0, 0x9, 0x20, 0x0, 0x6d, 0x90, + 0xad, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+8B58 "識" */ + 0x0, 0xa0, 0x0, 0x54, 0x5, 0x80, 0x0, 0x0, + 0x85, 0x0, 0x3a, 0x4, 0x89, 0x10, 0x2, 0x46, + 0x2a, 0xcc, 0xd7, 0x95, 0x80, 0x7, 0x77, 0x62, + 0x82, 0x93, 0x90, 0x80, 0x7, 0xbb, 0x6b, 0xec, + 0xcc, 0xea, 0xa2, 0x0, 0x0, 0x2, 0x22, 0x23, + 0xb2, 0x20, 0x7, 0xbb, 0x57, 0xcb, 0xe0, 0xc0, + 0xa0, 0x0, 0x0, 0x8, 0x30, 0xc0, 0xd6, 0x70, + 0x7, 0xcc, 0x58, 0xcb, 0xf0, 0xcb, 0x0, 0x9, + 0x14, 0x78, 0x30, 0xc0, 0xb7, 0x0, 0x9, 0x13, + 0x78, 0xba, 0xe4, 0xf5, 0x42, 0x9, 0xbc, 0x78, + 0x40, 0xac, 0x4c, 0x92, 0x8, 0x20, 0x0, 0x0, + 0x91, 0x9, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8B70 "議" */ + 0x0, 0x30, 0x0, 0x13, 0x0, 0x6, 0x0, 0x0, + 0xc0, 0x0, 0x2c, 0x21, 0x78, 0x10, 0x12, 0x85, + 0x24, 0x99, 0xbd, 0x99, 0x90, 0x37, 0x77, 0x60, + 0x88, 0xad, 0x88, 0x50, 0xa, 0xbb, 0x72, 0x22, + 0x5b, 0x22, 0x20, 0x0, 0x0, 0xa, 0xbb, 0xbb, + 0xbb, 0xb3, 0xb, 0xbb, 0x74, 0x8a, 0xa5, 0x67, + 0x30, 0x0, 0x0, 0x2, 0x2d, 0x3, 0x80, 0xa0, + 0xb, 0xcc, 0x7b, 0xbf, 0xbc, 0xeb, 0xb3, 0xb, + 0x2, 0x90, 0xd, 0x32, 0xc3, 0x50, 0xb, 0x2, + 0x9a, 0xbe, 0x72, 0xbb, 0x0, 0xe, 0xbc, 0x90, + 0xd, 0x6, 0xc8, 0x25, 0x9, 0x0, 0x4, 0xbb, + 0x46, 0xa, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8B77 "護" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x66, 0x0, 0x0, 0xd0, 0xd, 0x0, 0x0, 0xd, + 0x3, 0xbb, 0xfb, 0xbf, 0xb4, 0x19, 0x9a, 0x97, + 0x8, 0x65, 0x15, 0x0, 0x18, 0x88, 0x86, 0x3e, + 0x15, 0x90, 0x0, 0x2, 0x44, 0x41, 0xcd, 0x99, + 0xe9, 0x80, 0x3, 0x55, 0x56, 0xbd, 0x77, 0xe7, + 0x40, 0x7, 0xcc, 0xc3, 0x2d, 0x99, 0xe9, 0x50, + 0x0, 0x0, 0x0, 0x2c, 0x44, 0xe4, 0x40, 0x8, + 0xdd, 0xd3, 0x1b, 0x66, 0x66, 0x61, 0x9, 0x30, + 0x83, 0xbd, 0xcb, 0xbc, 0x60, 0x9, 0x30, 0x83, + 0x2, 0xb5, 0x6a, 0x0, 0x9, 0xdc, 0xe3, 0x15, + 0x9e, 0xf8, 0x20, 0x9, 0x30, 0x4, 0xfc, 0x60, + 0x19, 0xf6, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, + + /* U+8B8A "變" */ + 0x0, 0x50, 0x0, 0x50, 0x0, 0x23, 0x0, 0x2, + 0x91, 0x25, 0xc6, 0x50, 0xa2, 0x20, 0x1b, 0x3b, + 0x35, 0x55, 0x57, 0x86, 0x70, 0x39, 0xd4, 0x8, + 0x88, 0x58, 0xb9, 0x30, 0x1a, 0x7a, 0x48, 0x88, + 0x56, 0xc5, 0xc0, 0x38, 0x54, 0x5a, 0x99, 0x57, + 0x53, 0x71, 0x37, 0x97, 0x39, 0x1, 0x8b, 0x37, + 0xa0, 0x64, 0xa3, 0x5c, 0x9a, 0x7b, 0x9, 0x71, + 0x30, 0x5, 0xd0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x6f, 0xcb, 0xbb, 0xbd, 0xfb, 0x90, 0x2c, 0xa5, + 0xb5, 0x0, 0x7d, 0x20, 0x0, 0x3, 0x0, 0x1b, + 0xee, 0xb2, 0x0, 0x0, 0x48, 0xac, 0xc7, 0x33, + 0x8c, 0xec, 0x91, 0x24, 0x20, 0x0, 0x0, 0x0, + 0x2, 0x40, + + /* U+8B93 "讓" */ + 0x0, 0x70, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, + 0xa3, 0x8, 0xbb, 0xcf, 0xbb, 0xb3, 0x37, 0x98, + 0x61, 0x66, 0x60, 0x66, 0x50, 0x24, 0x44, 0x42, + 0x92, 0xd1, 0xb2, 0xc0, 0x9, 0xbb, 0x62, 0xbb, + 0xd1, 0xda, 0xa0, 0x0, 0x0, 0x2, 0x5d, 0x65, + 0xa8, 0x50, 0xa, 0xbb, 0x63, 0x6d, 0x76, 0xa9, + 0x60, 0x1, 0x11, 0x2, 0xae, 0xba, 0xdc, 0x80, + 0xa, 0xaa, 0x60, 0xb, 0x30, 0x85, 0x0, 0xc, + 0x35, 0x8a, 0xac, 0xfd, 0xca, 0xb4, 0xb, 0x2, + 0x96, 0x9d, 0x11, 0xc8, 0x80, 0xd, 0xbc, 0x82, + 0x1d, 0x69, 0x5e, 0x60, 0xb, 0x0, 0x0, 0x5b, + 0x73, 0x3, 0xc5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8BA1 "计" */ + 0x0, 0x71, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, + 0x6c, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x7, + 0x80, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0x14, 0x44, 0x0, 0x0, + 0x5a, 0x0, 0x0, 0x3a, 0xad, 0xe, 0xff, 0xff, + 0xff, 0xf4, 0x0, 0x1d, 0x0, 0x0, 0x5a, 0x0, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0x5a, 0x0, 0x0, + 0x0, 0x1d, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, + 0x1d, 0x3, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x1e, + 0xb7, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x7e, 0x40, + 0x0, 0x5a, 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, + 0x5a, 0x0, 0x0, + + /* U+8BDE "诞" */ + 0x2, 0x0, 0x0, 0x0, 0x0, 0x3, 0x30, 0xb, + 0x70, 0xcd, 0xf5, 0x6a, 0xea, 0x40, 0x1, 0xe3, + 0x1, 0xc2, 0x63, 0xd0, 0x0, 0x0, 0x43, 0x7, + 0x60, 0x0, 0xd0, 0x0, 0x23, 0x30, 0xc, 0x0, + 0x80, 0xd0, 0x0, 0x59, 0xf0, 0x8d, 0xd4, 0xc0, + 0xed, 0xd0, 0x0, 0xd0, 0x0, 0x82, 0xc0, 0xd0, + 0x0, 0x0, 0xd0, 0x72, 0xb0, 0xc0, 0xd0, 0x0, + 0x0, 0xd0, 0x58, 0xc0, 0xc0, 0xd0, 0x0, 0x0, + 0xd0, 0x2d, 0x90, 0xc1, 0xd1, 0x10, 0x0, 0xda, + 0x7b, 0x80, 0xbb, 0xbb, 0xb2, 0x1, 0xf7, 0x4b, + 0xaa, 0x20, 0x0, 0x0, 0x4, 0x42, 0xd1, 0x5, + 0xbd, 0xdd, 0xd3, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, + + /* U+8C50 "豐" */ + 0x0, 0x0, 0x10, 0x66, 0x1, 0x0, 0x0, 0x5, + 0x77, 0xc7, 0x77, 0x7c, 0x77, 0x60, 0x5, 0x78, + 0xd8, 0x66, 0x8d, 0x87, 0x60, 0x5, 0x74, 0xb4, + 0x77, 0x4b, 0x48, 0x60, 0x5, 0x74, 0xb4, 0x77, + 0x4b, 0x48, 0x60, 0x4, 0xbb, 0xbb, 0xbb, 0xbb, + 0xbb, 0x40, 0x7, 0x77, 0x77, 0x77, 0x77, 0x77, + 0x70, 0x3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x30, + 0x0, 0x5d, 0xaa, 0xaa, 0xaa, 0xc7, 0x0, 0x0, + 0x58, 0x0, 0x0, 0x0, 0x67, 0x0, 0x0, 0x3a, + 0xfa, 0xaa, 0xae, 0xb5, 0x0, 0x0, 0x0, 0xc3, + 0x0, 0x2c, 0x0, 0x0, 0x2b, 0xbb, 0xdd, 0xbb, + 0xdd, 0xbb, 0xb2, + + /* U+8C61 "象" */ + 0x0, 0x0, 0x75, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xfc, 0xcc, 0xb0, 0x0, 0x0, 0x0, 0x8b, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x1c, 0xfc, 0xbb, + 0xcf, 0xbb, 0xbc, 0x0, 0x3, 0xe0, 0x0, 0xa5, + 0x0, 0xe, 0x0, 0x0, 0xeb, 0xbc, 0xfb, 0xbb, + 0xbe, 0x0, 0x0, 0x6, 0xcd, 0x60, 0x0, 0x37, + 0x0, 0xa, 0xd7, 0x4, 0xf6, 0x19, 0xc2, 0x0, + 0x2, 0x3, 0xa9, 0x2e, 0xcc, 0x40, 0x0, 0x5, + 0xd9, 0x21, 0xac, 0x92, 0xd0, 0x0, 0x0, 0x3, + 0x9b, 0x23, 0xc0, 0x7c, 0x10, 0x6, 0xda, 0x40, + 0x7, 0xa0, 0x6, 0xe1, 0x2, 0x10, 0xc, 0xec, + 0x10, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8CA0 "負" */ + 0x0, 0x0, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xfc, 0xcc, 0xc1, 0x0, 0x0, 0x0, 0x8b, + 0x0, 0x7, 0xa0, 0x0, 0x0, 0x1b, 0xfc, 0xbb, + 0xcf, 0xcb, 0xb8, 0x0, 0x16, 0xb4, 0x0, 0x0, + 0x0, 0x4b, 0x0, 0x0, 0xba, 0x99, 0x99, 0x99, + 0xbb, 0x0, 0x0, 0xb5, 0x22, 0x22, 0x22, 0x5b, + 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x3b, 0x0, + 0x0, 0xbc, 0xbb, 0xbb, 0xbb, 0xcb, 0x0, 0x0, + 0xb3, 0x0, 0x0, 0x0, 0x3b, 0x0, 0x0, 0x9c, + 0xcc, 0xcc, 0xcc, 0xc9, 0x0, 0x0, 0x17, 0xc3, + 0x0, 0x4b, 0x61, 0x0, 0x1c, 0xc7, 0x0, 0x0, + 0x1, 0x6d, 0x90, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, + + /* U+8CA1 "財" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x0, 0xe, + 0xcc, 0xcf, 0x0, 0x0, 0x3b, 0x0, 0xe, 0x0, + 0xe, 0x0, 0x0, 0x3b, 0x0, 0xe, 0x44, 0x4f, + 0x12, 0x22, 0x5c, 0x21, 0xe, 0x66, 0x6f, 0x5b, + 0xbb, 0xee, 0xb6, 0xe, 0x0, 0xe, 0x0, 0x1, + 0xeb, 0x0, 0xe, 0xbb, 0xbf, 0x0, 0x9, 0x8b, + 0x0, 0xe, 0x0, 0xe, 0x0, 0x3b, 0x3b, 0x0, + 0xe, 0x0, 0xe, 0x1, 0xc2, 0x3b, 0x0, 0xb, + 0xcc, 0xcc, 0x1c, 0x50, 0x3b, 0x0, 0x2, 0xb0, + 0x84, 0x85, 0x0, 0x3b, 0x0, 0xb, 0x50, 0x1d, + 0x10, 0x0, 0x3b, 0x0, 0x59, 0x0, 0x3, 0x10, + 0x2e, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8CA7 "貧" */ + 0x0, 0x5, 0x70, 0x2, 0x80, 0x0, 0x0, 0x7, + 0xb1, 0x0, 0x6, 0xc2, 0x0, 0x6d, 0xcc, 0xcc, + 0xcc, 0xcf, 0xda, 0x22, 0x10, 0x7, 0x80, 0x0, + 0xe0, 0x52, 0x3, 0x7c, 0x70, 0x5a, 0xb8, 0x0, + 0x5, 0xbf, 0xba, 0xaa, 0xaa, 0xa9, 0x0, 0x3, + 0xb0, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x3e, 0x99, + 0x99, 0x99, 0xad, 0x0, 0x3, 0xc3, 0x33, 0x33, + 0x34, 0xd0, 0x0, 0x3c, 0x55, 0x55, 0x55, 0x6d, + 0x0, 0x3, 0xea, 0xaa, 0xaa, 0xaa, 0xd0, 0x0, + 0x2, 0x87, 0x0, 0x2a, 0x62, 0x0, 0x7c, 0x93, + 0x0, 0x0, 0x15, 0xbb, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+8CA9 "販" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x60, 0xd, + 0xcc, 0xf0, 0x8c, 0xcb, 0xa7, 0x40, 0xd, 0x0, + 0xd0, 0xb2, 0x0, 0x0, 0x0, 0xd, 0xbb, 0xf0, + 0xb2, 0x0, 0x0, 0x0, 0xd, 0x0, 0xd0, 0xba, + 0x99, 0x99, 0x60, 0xd, 0x0, 0xd0, 0xbe, 0x75, + 0x59, 0x80, 0xd, 0xbb, 0xf0, 0xb8, 0x70, 0xa, + 0x40, 0xd, 0x0, 0xd0, 0xd2, 0xc0, 0xe, 0x0, + 0xd, 0x11, 0xd0, 0xd0, 0x95, 0x68, 0x0, 0x8, + 0xaa, 0xa1, 0xd0, 0x1c, 0xd1, 0x0, 0x3, 0x64, + 0x45, 0x80, 0xc, 0xc0, 0x0, 0xc, 0x31, 0xcc, + 0x30, 0xaa, 0x9a, 0x0, 0x29, 0x0, 0x8a, 0x1d, + 0x80, 0x8, 0xd1, 0x0, 0x0, 0x1, 0x2, 0x0, + 0x0, 0x20, + + /* U+8CAC "責" */ + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x4, + 0xbb, 0xbb, 0xdd, 0xbb, 0xbb, 0x50, 0x0, 0x56, + 0x66, 0xbb, 0x66, 0x66, 0x0, 0x0, 0x34, 0x44, + 0xa9, 0x44, 0x44, 0x0, 0x1b, 0xbb, 0xbb, 0xdd, + 0xbb, 0xbb, 0xb2, 0x0, 0x24, 0x44, 0x44, 0x44, + 0x42, 0x0, 0x0, 0x7a, 0x55, 0x55, 0x55, 0x8a, + 0x0, 0x0, 0x7c, 0x99, 0x99, 0x99, 0xba, 0x0, + 0x0, 0x78, 0x22, 0x22, 0x22, 0x6a, 0x0, 0x0, + 0x7b, 0x66, 0x66, 0x66, 0x9a, 0x0, 0x0, 0x7c, + 0xaa, 0xaa, 0xaa, 0xba, 0x0, 0x0, 0x15, 0xa4, + 0x0, 0x4a, 0x61, 0x0, 0xb, 0xb6, 0x10, 0x0, + 0x0, 0x5b, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8CB7 "買" */ + 0x1, 0xfc, 0xcf, 0xcc, 0xfc, 0xcd, 0xa0, 0x1, + 0xb0, 0xd, 0x0, 0xc0, 0x3, 0xa0, 0x1, 0xec, + 0xcf, 0xcc, 0xfc, 0xcd, 0xa0, 0x0, 0x13, 0x33, + 0x33, 0x33, 0x33, 0x0, 0x0, 0x4c, 0x66, 0x66, + 0x66, 0x7d, 0x0, 0x0, 0x4d, 0x99, 0x99, 0x99, + 0xad, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x1d, + 0x0, 0x0, 0x4e, 0xaa, 0xaa, 0xaa, 0xad, 0x0, + 0x0, 0x4a, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, + 0x4c, 0xaa, 0xaa, 0xaa, 0xbc, 0x0, 0x0, 0x5, + 0xb7, 0x0, 0x4b, 0x72, 0x0, 0x9, 0xd8, 0x10, + 0x0, 0x0, 0x4b, 0xc2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+8CB8 "貸" */ + 0x0, 0x0, 0x96, 0xd, 0x6, 0xb5, 0x0, 0x0, + 0xa, 0xa0, 0x9, 0x61, 0x4a, 0x41, 0x5, 0xdd, + 0x5b, 0xcc, 0xfb, 0x98, 0x71, 0x9, 0x28, 0x50, + 0x0, 0x3d, 0x40, 0x44, 0x0, 0x7, 0x40, 0x0, + 0x2, 0xae, 0xd2, 0x0, 0x2b, 0xaa, 0xaa, 0xaa, + 0xaa, 0x0, 0x0, 0x3c, 0x22, 0x22, 0x22, 0x3d, + 0x0, 0x0, 0x3d, 0x66, 0x66, 0x66, 0x7d, 0x0, + 0x0, 0x3e, 0x99, 0x99, 0x99, 0xad, 0x0, 0x0, + 0x3b, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x2c, + 0xaa, 0xaa, 0xaa, 0xab, 0x0, 0x0, 0x4, 0xa7, + 0x0, 0x2b, 0x72, 0x0, 0x8, 0xd8, 0x20, 0x0, + 0x0, 0x4b, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8CBB "費" */ + 0x0, 0x0, 0xd, 0x0, 0xd0, 0x0, 0x0, 0x5, + 0xaa, 0xaf, 0xaa, 0xfa, 0xac, 0x60, 0x0, 0x7a, + 0xaf, 0xaa, 0xfa, 0xac, 0x60, 0x0, 0xe1, 0x1e, + 0x0, 0xd1, 0x0, 0x0, 0x0, 0xab, 0xfc, 0xaa, + 0xfb, 0xaa, 0xe3, 0x1, 0x5c, 0xe4, 0x33, 0xd4, + 0x4a, 0xc0, 0xb, 0xbd, 0x66, 0x66, 0x66, 0x7d, + 0x0, 0x0, 0x3e, 0x99, 0x99, 0x99, 0xad, 0x0, + 0x0, 0x3c, 0x22, 0x22, 0x22, 0x3d, 0x0, 0x0, + 0x3d, 0x66, 0x66, 0x66, 0x7d, 0x0, 0x0, 0x3e, + 0x99, 0x99, 0x99, 0xad, 0x0, 0x0, 0x15, 0xb5, + 0x0, 0x4b, 0x84, 0x0, 0xb, 0xb7, 0x10, 0x0, + 0x0, 0x38, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8CBF "貿" */ + 0x0, 0x0, 0x37, 0x10, 0x0, 0x0, 0x0, 0x0, + 0xdb, 0x95, 0x1c, 0xcf, 0xcd, 0xb0, 0x0, 0xe0, + 0x36, 0x0, 0x4a, 0x3, 0xa0, 0x0, 0xe2, 0x6f, + 0x40, 0xc3, 0x6, 0x80, 0x4, 0xfa, 0x63, 0xad, + 0x52, 0xbb, 0x20, 0x0, 0x5a, 0xaa, 0xba, 0xaa, + 0xa6, 0x0, 0x0, 0x68, 0x11, 0x11, 0x11, 0x59, + 0x0, 0x0, 0x6b, 0x77, 0x77, 0x77, 0xa9, 0x0, + 0x0, 0x6c, 0x99, 0x99, 0x99, 0xb9, 0x0, 0x0, + 0x68, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x6c, + 0xaa, 0xaa, 0xaa, 0xb9, 0x0, 0x0, 0x4, 0xa4, + 0x0, 0x3a, 0x61, 0x0, 0xb, 0xc8, 0x10, 0x0, + 0x0, 0x5b, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8CC3 "賃" */ + 0x0, 0x0, 0x91, 0x1, 0x23, 0x57, 0x20, 0x0, + 0x2d, 0x53, 0xa9, 0xbc, 0x53, 0x10, 0x19, 0xce, + 0x1b, 0xbb, 0xcd, 0xbb, 0xb6, 0x7, 0xe, 0x0, + 0x0, 0x59, 0x0, 0x0, 0x0, 0xe, 0x5, 0xbb, + 0xce, 0xbb, 0xa0, 0x0, 0x6, 0x44, 0x44, 0x44, + 0x44, 0x0, 0x0, 0x3d, 0x55, 0x55, 0x55, 0x5f, + 0x0, 0x0, 0x3e, 0x99, 0x99, 0x99, 0x9f, 0x0, + 0x0, 0x3c, 0x22, 0x22, 0x22, 0x2e, 0x0, 0x0, + 0x3d, 0x66, 0x66, 0x66, 0x6f, 0x0, 0x0, 0x3e, + 0x99, 0x99, 0x99, 0x9f, 0x0, 0x0, 0x2, 0x88, + 0x0, 0x19, 0x62, 0x0, 0x8, 0xc9, 0x40, 0x0, + 0x0, 0x5a, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8CC7 "資" */ + 0x0, 0x40, 0x0, 0x19, 0x0, 0x0, 0x0, 0x1, + 0x8d, 0x80, 0xae, 0xbb, 0xbb, 0xb0, 0x0, 0x0, + 0x3a, 0x70, 0x87, 0x6, 0x80, 0x0, 0x27, 0xa1, + 0x7, 0xa9, 0x74, 0x0, 0xc, 0xb5, 0x8, 0xc6, + 0x0, 0x6c, 0x90, 0x0, 0x2b, 0xab, 0xaa, 0xaa, + 0xaa, 0x30, 0x0, 0x3b, 0x22, 0x22, 0x22, 0x3d, + 0x0, 0x0, 0x3d, 0x66, 0x66, 0x66, 0x7d, 0x0, + 0x0, 0x3e, 0x99, 0x99, 0x99, 0xad, 0x0, 0x0, + 0x3a, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x3c, + 0xaa, 0xaa, 0xaa, 0xab, 0x0, 0x0, 0x5, 0xb7, + 0x0, 0x1b, 0x94, 0x0, 0x9, 0xc7, 0x10, 0x0, + 0x0, 0x39, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8CEA "質" */ + 0x0, 0x1, 0x37, 0x30, 0x1, 0x36, 0x30, 0x0, + 0xe9, 0x74, 0x11, 0xe9, 0x74, 0x10, 0x0, 0xfb, + 0xbb, 0xb2, 0xeb, 0xbb, 0xb7, 0x4, 0x90, 0xa2, + 0x7, 0x70, 0xd0, 0x0, 0xc, 0x20, 0x72, 0x1b, + 0x0, 0xa0, 0x0, 0x0, 0x2c, 0xaa, 0xaa, 0xaa, + 0xc5, 0x0, 0x0, 0x3b, 0x33, 0x33, 0x33, 0xb6, + 0x0, 0x0, 0x3c, 0x55, 0x55, 0x55, 0xc6, 0x0, + 0x0, 0x3d, 0x99, 0x99, 0x99, 0xd6, 0x0, 0x0, + 0x39, 0x0, 0x0, 0x0, 0x96, 0x0, 0x0, 0x2c, + 0xaa, 0xaa, 0xaa, 0xc5, 0x0, 0x0, 0x16, 0xb4, + 0x0, 0x1b, 0x94, 0x0, 0xa, 0xc7, 0x0, 0x0, + 0x0, 0x38, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8CFD "賽" */ + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0xf, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf0, 0xd, 0x0, + 0x74, 0x0, 0x48, 0x0, 0xd0, 0x1, 0x79, 0xdb, + 0x99, 0xbd, 0x97, 0x10, 0x0, 0x47, 0xca, 0x77, + 0xac, 0x74, 0x0, 0x2b, 0xbb, 0xed, 0xbb, 0xde, + 0xbb, 0xb2, 0x0, 0x9, 0xc3, 0x33, 0x39, 0xb1, + 0x0, 0x6, 0xdf, 0x66, 0x66, 0x66, 0xfc, 0x92, + 0x27, 0x1d, 0x88, 0x88, 0x88, 0xe0, 0x51, 0x0, + 0xd, 0x77, 0x77, 0x78, 0xe0, 0x0, 0x0, 0xd, + 0x88, 0x88, 0x88, 0xe0, 0x0, 0x0, 0x27, 0xc6, + 0x0, 0x7b, 0x83, 0x0, 0xa, 0x95, 0x0, 0x0, + 0x0, 0x39, 0x60, + + /* U+8D39 "费" */ + 0x0, 0x0, 0xd, 0x0, 0xb2, 0x0, 0x0, 0x5, + 0xbb, 0xbf, 0xbb, 0xec, 0xbc, 0x90, 0x0, 0x0, + 0xd, 0x0, 0xc2, 0x4, 0x90, 0x0, 0xdb, 0xaf, + 0xaa, 0xeb, 0xaa, 0x60, 0x0, 0xf0, 0xd, 0x0, + 0xb2, 0x0, 0x0, 0x2, 0xab, 0xfc, 0xaa, 0xeb, + 0xaa, 0xd5, 0x3, 0x7c, 0x80, 0x0, 0x81, 0x6, + 0x81, 0x9, 0x8e, 0xcc, 0xcc, 0xcc, 0xcb, 0x0, + 0x0, 0x2c, 0x0, 0x23, 0x0, 0x1d, 0x0, 0x0, + 0x2c, 0x0, 0x95, 0x0, 0x1d, 0x0, 0x0, 0x2c, + 0x4, 0xc4, 0x62, 0x1d, 0x0, 0x0, 0x15, 0xab, + 0x11, 0x6b, 0xc8, 0x20, 0x2d, 0xc9, 0x30, 0x0, + 0x0, 0x6, 0xc4, + + /* U+8D64 "赤" */ + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x9e, + 0xee, 0xff, 0xee, 0xea, 0x0, 0x0, 0x0, 0x0, + 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x77, + 0x0, 0x0, 0x0, 0xd, 0xee, 0xef, 0xee, 0xfe, + 0xee, 0xe0, 0x0, 0x0, 0xf, 0x0, 0xa4, 0x0, + 0x0, 0x0, 0x77, 0xf, 0x0, 0xa4, 0x68, 0x0, + 0x1, 0xe1, 0x2d, 0x0, 0xa4, 0xd, 0x30, 0xb, + 0x60, 0x69, 0x0, 0xa4, 0x4, 0xd0, 0x27, 0x0, + 0xe3, 0x0, 0xa4, 0x0, 0x92, 0x0, 0x1c, 0x80, + 0x0, 0xb4, 0x0, 0x0, 0x0, 0x87, 0x0, 0x8e, + 0xd2, 0x0, 0x0, + + /* U+8D70 "走" */ + 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0xcd, + 0xdd, 0xee, 0xdd, 0xdd, 0x0, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x87, + 0x0, 0x0, 0x0, 0x1d, 0xdd, 0xdd, 0xee, 0xdd, + 0xdd, 0xd1, 0x0, 0x3, 0x0, 0x77, 0x0, 0x0, + 0x0, 0x0, 0xf, 0x0, 0x77, 0x0, 0x0, 0x0, + 0x0, 0x3c, 0x0, 0x7e, 0xdd, 0xdd, 0x20, 0x0, + 0x7f, 0x30, 0x77, 0x0, 0x0, 0x0, 0x0, 0xd4, + 0xc1, 0x77, 0x0, 0x0, 0x0, 0x8, 0x90, 0x5e, + 0xc8, 0x10, 0x0, 0x0, 0x3c, 0x0, 0x1, 0x7c, + 0xef, 0xee, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8D77 "起" */ + 0x0, 0x8, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x50, 0x5, 0xdd, 0xdd, 0xe0, 0xc, 0xde, + 0xed, 0x90, 0x0, 0x0, 0xe0, 0x0, 0x8, 0x50, + 0x0, 0x0, 0x0, 0xe0, 0x14, 0x4a, 0x84, 0x40, + 0x0, 0x0, 0xe0, 0x28, 0x8a, 0xd8, 0x84, 0xfd, + 0xdd, 0xe0, 0x2, 0x14, 0x90, 0x3, 0xb0, 0x0, + 0x10, 0x8, 0x54, 0xa2, 0x23, 0xb0, 0x0, 0x0, + 0x9, 0x44, 0xda, 0x93, 0xb0, 0x0, 0x25, 0xa, + 0x94, 0x90, 0x3, 0xc0, 0x0, 0x59, 0xc, 0xc9, + 0x90, 0x0, 0xbd, 0xdd, 0xc3, 0xd, 0x1e, 0xb2, + 0x0, 0x0, 0x0, 0x0, 0x59, 0x0, 0x8c, 0xee, + 0xee, 0xee, 0xe9, 0x12, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8D85 "超" */ + 0x0, 0x8, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x50, 0x2c, 0xdf, 0xcc, 0xf3, 0xa, 0xde, + 0xed, 0x70, 0x3c, 0x0, 0xc2, 0x0, 0x8, 0x50, + 0x0, 0x87, 0x0, 0xd1, 0x1, 0x19, 0x61, 0x13, + 0xd1, 0x12, 0xe0, 0xb, 0xbd, 0xdb, 0xbc, 0x20, + 0x9b, 0x50, 0x3, 0x25, 0x70, 0x7, 0xa9, 0x99, + 0x90, 0x7, 0x65, 0xda, 0x7a, 0x40, 0x0, 0xe0, + 0x8, 0x65, 0x93, 0x2a, 0x40, 0x0, 0xe0, 0x9, + 0xb5, 0x70, 0xa, 0x40, 0x0, 0xe0, 0xb, 0xda, + 0x70, 0x8, 0xcc, 0xcc, 0xb0, 0xd, 0x2e, 0xa2, + 0x0, 0x0, 0x0, 0x0, 0x3a, 0x1, 0x8c, 0xee, + 0xee, 0xee, 0xe8, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8D8A "越" */ + 0x0, 0x6, 0x60, 0x0, 0x1, 0xc7, 0x10, 0x0, + 0x6, 0x60, 0x0, 0x0, 0xc3, 0xb0, 0x8, 0xde, + 0xed, 0x80, 0x1, 0xd0, 0x60, 0x0, 0x17, 0x71, + 0xc, 0xcc, 0xfc, 0xc5, 0x0, 0x7, 0x60, 0xc, + 0x10, 0xd0, 0x10, 0x2d, 0xdd, 0xfd, 0xbc, 0x10, + 0xc0, 0xc0, 0x0, 0x13, 0xa0, 0xc, 0x10, 0xb5, + 0x90, 0x5, 0x73, 0xb2, 0x1c, 0x12, 0x8d, 0x20, + 0x6, 0x73, 0xea, 0x7d, 0xba, 0x6b, 0x12, 0x7, + 0xd3, 0xa0, 0x3c, 0x34, 0xcc, 0x46, 0x9, 0x9c, + 0xa0, 0x0, 0x8d, 0x16, 0xe1, 0xc, 0xb, 0xd5, + 0x0, 0x30, 0x0, 0x0, 0x39, 0x0, 0x6b, 0xee, + 0xee, 0xee, 0xe5, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8DA3 "趣" */ + 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x3, 0xee, 0xdf, 0x50, 0x0, 0xa, 0xdf, + 0xd9, 0x84, 0xc, 0xac, 0xe4, 0x0, 0xd, 0x0, + 0x8c, 0xac, 0x20, 0xa2, 0x1a, 0xaf, 0xaa, 0x84, + 0xc, 0xb1, 0xd0, 0x2, 0x2a, 0x62, 0x86, 0x2c, + 0x4a, 0xc0, 0x3, 0x38, 0x40, 0x8b, 0x9c, 0xb, + 0x80, 0x7, 0x58, 0xec, 0x84, 0xc, 0x9, 0x90, + 0x7, 0x68, 0x40, 0x87, 0x8f, 0x5d, 0xc0, 0x8, + 0xc9, 0x45, 0xda, 0x5c, 0x87, 0x75, 0xb, 0xae, + 0x41, 0x0, 0xc, 0xb0, 0x23, 0xc, 0xc, 0xa3, + 0x0, 0x5, 0x0, 0x0, 0x58, 0x0, 0x7b, 0xee, + 0xee, 0xee, 0xe9, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8DB3 "足" */ + 0x0, 0xde, 0xee, 0xee, 0xee, 0xee, 0x0, 0x0, + 0xd1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0xd1, + 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0xd1, 0x0, + 0x0, 0x0, 0x1e, 0x0, 0x0, 0xbe, 0xee, 0xfe, + 0xee, 0xec, 0x0, 0x0, 0x0, 0x0, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0x2d, 0x0, 0xd1, 0x0, 0x0, + 0x0, 0x0, 0x6a, 0x0, 0xde, 0xee, 0xec, 0x0, + 0x0, 0xae, 0x10, 0xd1, 0x0, 0x0, 0x0, 0x1, + 0xe6, 0xa0, 0xd1, 0x0, 0x0, 0x0, 0x9, 0x80, + 0x8c, 0xe2, 0x0, 0x0, 0x0, 0x5b, 0x0, 0x3, + 0x9d, 0xee, 0xee, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+8DDF "跟" */ + 0xd, 0xcc, 0xd7, 0xdd, 0xdd, 0xde, 0xa0, 0xd, + 0x0, 0x47, 0xd0, 0x0, 0x3, 0xa0, 0xd, 0x0, + 0x47, 0xd8, 0x88, 0x89, 0xa0, 0xd, 0xcc, 0xd7, + 0xd4, 0x33, 0x36, 0xa0, 0x0, 0xd, 0x0, 0xd0, + 0x0, 0x3, 0xa0, 0x6, 0xd, 0x0, 0xde, 0xee, + 0xee, 0xa0, 0xc, 0xd, 0xd8, 0xd0, 0x58, 0x0, + 0x30, 0xc, 0xd, 0x0, 0xd0, 0xd, 0x19, 0xb1, + 0xc, 0xd, 0x0, 0xd0, 0x8, 0xe6, 0x0, 0xc, + 0xe, 0x78, 0xd0, 0x0, 0xd5, 0x0, 0x4e, 0xda, + 0x51, 0xe6, 0x98, 0x2e, 0x80, 0x23, 0x0, 0x1, + 0xe9, 0x40, 0x1, 0xa6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+8DEF "路" */ + 0x0, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, 0xd, + 0xdd, 0xdb, 0x3, 0xd1, 0x10, 0x0, 0xd, 0x0, + 0x2b, 0xb, 0xdb, 0xce, 0x0, 0xd, 0x0, 0x2b, + 0x7e, 0x80, 0x87, 0x0, 0xd, 0xdd, 0xdd, 0xe1, + 0xa7, 0xd0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x1f, + 0x50, 0x0, 0x7, 0xd, 0x0, 0x1, 0xb7, 0xd3, + 0x0, 0xc, 0xd, 0xdb, 0x7d, 0x30, 0x2d, 0x90, + 0xc, 0xd, 0x3, 0x9f, 0xdd, 0xdf, 0x80, 0xc, + 0xd, 0x0, 0xd, 0x0, 0xb, 0x20, 0xc, 0xd, + 0x58, 0xd, 0x0, 0xb, 0x20, 0x3e, 0xdd, 0x95, + 0xd, 0x11, 0x1c, 0x20, 0x35, 0x10, 0x0, 0xf, + 0xbb, 0xbe, 0x20, + + /* U+8EAB "身" */ + 0x0, 0x0, 0x0, 0x53, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x22, 0xe3, 0x22, 0x10, 0x0, 0x0, 0xf, + 0xbb, 0xbb, 0xbb, 0xd0, 0x0, 0x0, 0xe, 0x0, + 0x0, 0x1, 0xd0, 0x0, 0x0, 0xf, 0xbb, 0xbb, + 0xbc, 0xd0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x1, + 0xd0, 0x60, 0x0, 0xf, 0xbb, 0xbb, 0xbc, 0xd9, + 0x70, 0x0, 0xe, 0x0, 0x0, 0x1, 0xf8, 0x0, + 0xb, 0xde, 0xdd, 0xdd, 0xef, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xc5, 0xd0, 0x0, 0x0, 0x0, + 0x5, 0xd7, 0x1, 0xd0, 0x0, 0x0, 0x39, 0xd9, + 0x10, 0x1, 0xd0, 0x0, 0x1d, 0xb5, 0x0, 0xc, + 0xee, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8ECA "車" */ + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x6, + 0xaa, 0xaa, 0xce, 0xaa, 0xaa, 0xa0, 0x1, 0x22, + 0x22, 0x7a, 0x22, 0x22, 0x20, 0x0, 0x6b, 0xbb, + 0xce, 0xbb, 0xbb, 0x0, 0x0, 0x95, 0x11, 0x6a, + 0x11, 0x1f, 0x0, 0x0, 0x94, 0x0, 0x59, 0x0, + 0xe, 0x0, 0x0, 0x9d, 0xbb, 0xde, 0xbb, 0xbf, + 0x0, 0x0, 0x94, 0x0, 0x59, 0x0, 0xe, 0x0, + 0x0, 0x9d, 0xcc, 0xde, 0xcc, 0xce, 0x0, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x1d, 0xdd, + 0xdd, 0xef, 0xdd, 0xdd, 0xd6, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x59, + 0x0, 0x0, 0x0, + + /* U+8EDF "軟" */ + 0x0, 0x8, 0x30, 0x0, 0xb2, 0x0, 0x0, 0x0, + 0x8, 0x30, 0x0, 0xe0, 0x0, 0x0, 0x3d, 0xde, + 0xed, 0xa1, 0xe0, 0x0, 0x0, 0x0, 0x9, 0x40, + 0x5, 0xfd, 0xdd, 0xe1, 0xc, 0xbd, 0xcc, 0x6a, + 0x40, 0x0, 0xd0, 0xb, 0x8, 0x35, 0x9d, 0xb, + 0x32, 0xb0, 0xc, 0xbd, 0xcc, 0x84, 0xc, 0x34, + 0x60, 0xb, 0x8, 0x35, 0x60, 0xe, 0x80, 0x0, + 0x9, 0xbd, 0xcb, 0x40, 0x1f, 0xd0, 0x0, 0x0, + 0x8, 0x30, 0x0, 0x88, 0xb2, 0x0, 0x5d, 0xde, + 0xed, 0xd3, 0xe1, 0x4b, 0x0, 0x0, 0x8, 0x30, + 0x2d, 0x40, 0xb, 0x80, 0x0, 0x8, 0x30, 0xb3, + 0x0, 0x0, 0xa4, + + /* U+8EE2 "転" */ + 0x0, 0x7, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x50, 0x2, 0x88, 0x88, 0x80, 0xd, 0xde, + 0xed, 0xc2, 0x77, 0x77, 0x70, 0x0, 0x8, 0x60, + 0x0, 0x0, 0x0, 0x0, 0xa, 0xbd, 0xcc, 0x90, + 0x0, 0x0, 0x0, 0xa, 0x16, 0x43, 0x95, 0x55, + 0x55, 0x53, 0xa, 0xbd, 0xcc, 0x97, 0x7d, 0xa7, + 0x74, 0xa, 0x16, 0x43, 0x90, 0x1e, 0x10, 0x0, + 0x7, 0xbd, 0xdb, 0x60, 0x6a, 0x5, 0x0, 0x0, + 0x7, 0x50, 0x0, 0xd3, 0xa, 0x50, 0x2d, 0xde, + 0xed, 0xc6, 0xa0, 0x3, 0xc0, 0x0, 0x7, 0x50, + 0x1e, 0x98, 0xab, 0xf3, 0x0, 0x7, 0x50, 0x7, + 0x53, 0x20, 0x67, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8EFD "軽" */ + 0x0, 0x8, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x84, 0x0, 0xce, 0xdd, 0xdf, 0x20, 0xd, + 0xde, 0xed, 0xa1, 0xd0, 0x2, 0xc0, 0x0, 0x0, + 0x95, 0x0, 0x8, 0x80, 0xb5, 0x0, 0xc, 0xad, + 0xcc, 0x80, 0xc, 0xb9, 0x0, 0x0, 0xb0, 0x73, + 0x38, 0x2, 0xbe, 0x90, 0x0, 0xc, 0xad, 0xcc, + 0xba, 0xd5, 0x17, 0xe8, 0x0, 0xb0, 0x73, 0x39, + 0x40, 0x1d, 0x0, 0x30, 0x8, 0xbd, 0xcb, 0x63, + 0x56, 0xe5, 0x51, 0x0, 0x0, 0x84, 0x0, 0x58, + 0x8e, 0x88, 0x20, 0x2d, 0xde, 0xed, 0xb0, 0x1, + 0xd0, 0x0, 0x0, 0x0, 0x84, 0x0, 0x0, 0x1d, + 0x0, 0x0, 0x0, 0x8, 0x40, 0x7d, 0xdd, 0xfd, + 0xdc, 0x0, + + /* U+8F03 "較" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x1c, + 0x0, 0x0, 0xd, 0x20, 0x0, 0x3d, 0xdf, 0xdd, + 0x67, 0x7a, 0x87, 0x71, 0x0, 0x2d, 0x0, 0x46, + 0x75, 0x67, 0x51, 0xe, 0xae, 0xac, 0x6, 0xa0, + 0x2c, 0x0, 0xc, 0xb, 0xc, 0x1d, 0x10, 0x6, + 0xa0, 0xe, 0xae, 0xac, 0xa7, 0x60, 0x46, 0xa2, + 0xc, 0xb, 0xc, 0x0, 0xd0, 0xb4, 0x0, 0xb, + 0xbf, 0xb8, 0x0, 0x79, 0xd0, 0x0, 0x0, 0x1c, + 0x0, 0x0, 0xf, 0x60, 0x0, 0x5d, 0xdf, 0xdd, + 0x10, 0x8d, 0xd1, 0x0, 0x0, 0x1c, 0x0, 0x1a, + 0xa0, 0x5d, 0x40, 0x0, 0x1c, 0x0, 0xc5, 0x0, + 0x2, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+8F09 "載" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x0, 0x86, 0x46, 0x0, 0x5, 0xcc, + 0xfc, 0xc7, 0x86, 0xb, 0x60, 0x0, 0x0, 0xd0, + 0x0, 0x86, 0x0, 0x80, 0xb, 0xbb, 0xfb, 0xbb, + 0xdd, 0xbb, 0xb5, 0x2, 0x22, 0xd2, 0x22, 0x89, + 0x23, 0x31, 0x7, 0xbb, 0xfb, 0xba, 0x49, 0x4, + 0x90, 0x1, 0x44, 0xe4, 0x42, 0x3b, 0xa, 0x40, + 0x5, 0x84, 0xc4, 0x69, 0x1d, 0x1d, 0x0, 0x5, + 0xb8, 0xe8, 0xa9, 0xd, 0xb5, 0x0, 0x5, 0xa6, + 0xd6, 0x89, 0xa, 0xc0, 0x0, 0x0, 0x22, 0xd2, + 0x21, 0x2e, 0xb0, 0x38, 0xa, 0xbb, 0xfb, 0xbd, + 0xc3, 0xd4, 0x67, 0x0, 0x0, 0xd0, 0x1b, 0x10, + 0x2d, 0xd2, + + /* U+8F15 "輕" */ + 0x0, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x8d, 0xdd, 0xdd, 0xd2, 0x3d, 0xdf, + 0xdc, 0x5, 0x3, 0x20, 0x50, 0x0, 0x1c, 0x0, + 0x1c, 0xb, 0x17, 0x70, 0xe, 0xae, 0xac, 0x84, + 0x58, 0x1c, 0x0, 0xb, 0xa, 0xb, 0xa3, 0x67, + 0x2c, 0x0, 0xe, 0xbe, 0xbc, 0x1c, 0xb, 0x27, + 0x70, 0xb, 0xa, 0xb, 0x7, 0x23, 0x60, 0xa0, + 0xb, 0xbf, 0xb8, 0x49, 0x99, 0x99, 0x80, 0x0, + 0xc, 0x0, 0x13, 0x3e, 0x43, 0x30, 0x5d, 0xdf, + 0xdd, 0x10, 0xd, 0x10, 0x0, 0x0, 0xc, 0x0, + 0x0, 0xd, 0x10, 0x0, 0x0, 0xc, 0x3, 0xcc, + 0xcf, 0xdc, 0xc4, + + /* U+8F2A "輪" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0xd, + 0x0, 0x0, 0x7f, 0x80, 0x0, 0x2d, 0xdf, 0xdc, + 0x3, 0xe2, 0xb7, 0x0, 0x3, 0x3d, 0x32, 0x3e, + 0x30, 0xb, 0x80, 0xc, 0x6d, 0x7c, 0xeb, 0xcc, + 0xcc, 0xa7, 0xc, 0x2b, 0x3a, 0x10, 0x0, 0x0, + 0x0, 0xd, 0x8d, 0x9a, 0x8d, 0xdd, 0xdc, 0xc0, + 0xb, 0xb, 0x1a, 0xa2, 0x91, 0xb0, 0xc0, 0xa, + 0xbf, 0xb7, 0xa2, 0x91, 0xb0, 0xc0, 0x0, 0xd, + 0x0, 0xae, 0xfe, 0xfe, 0xe0, 0x4d, 0xdf, 0xdc, + 0xa2, 0x91, 0xb0, 0xc0, 0x0, 0xd, 0x0, 0xa2, + 0x91, 0xb0, 0xc0, 0x0, 0xd, 0x0, 0xa2, 0x91, + 0xb7, 0xa0, + + /* U+8F38 "輸" */ + 0x0, 0x1c, 0x0, 0x0, 0xb, 0x10, 0x0, 0x0, + 0x1c, 0x0, 0x0, 0x9d, 0xb0, 0x0, 0x2d, 0xdf, + 0xdb, 0x8, 0xb0, 0x7b, 0x10, 0x0, 0x2c, 0x1, + 0xc9, 0x0, 0x6, 0xd4, 0xd, 0xae, 0xba, 0x2b, + 0xbb, 0xbb, 0x31, 0xc, 0x1b, 0x39, 0x58, 0x85, + 0x20, 0x80, 0xd, 0x9e, 0xa9, 0x94, 0x49, 0x81, + 0xb0, 0xb, 0xb, 0x19, 0x9a, 0xa9, 0x81, 0xb0, + 0xb, 0xbe, 0xb7, 0x93, 0x39, 0x81, 0xb0, 0x1, + 0x2c, 0x11, 0x9a, 0xa9, 0x81, 0xb0, 0x3b, 0xbe, + 0xba, 0x93, 0x49, 0x81, 0xb0, 0x0, 0x1b, 0x0, + 0x91, 0x29, 0x0, 0xb0, 0x0, 0x1b, 0x0, 0x92, + 0xa6, 0x1b, 0xc0, 0x0, 0x1, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+8F9B "辛" */ + 0x0, 0x0, 0x0, 0x91, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, 0x3, 0xdd, + 0xdd, 0xee, 0xdd, 0xdd, 0x40, 0x0, 0x4, 0x80, + 0x0, 0x7, 0x60, 0x0, 0x0, 0x1, 0xe0, 0x0, + 0xd, 0x20, 0x0, 0x1, 0x11, 0xb4, 0x11, 0x5c, + 0x11, 0x10, 0x2c, 0xcc, 0xcc, 0xee, 0xcc, 0xcc, + 0xc3, 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x7, + 0xee, 0xee, 0xff, 0xee, 0xee, 0x90, 0x0, 0x0, + 0x0, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x87, + 0x0, 0x0, 0x0, + + /* U+8F9E "辞" */ + 0x0, 0x1, 0x55, 0x0, 0x17, 0x0, 0x0, 0x3a, + 0xdf, 0x84, 0x0, 0xb, 0x20, 0x0, 0x12, 0x1d, + 0x0, 0x8d, 0xdd, 0xdd, 0xd0, 0x0, 0x1d, 0x0, + 0x9, 0x10, 0xc, 0x0, 0x59, 0xae, 0x99, 0x6, + 0x70, 0x3b, 0x0, 0x24, 0x6e, 0x44, 0x2, 0x80, + 0x85, 0x0, 0x0, 0x1d, 0x0, 0xdd, 0xdf, 0xed, + 0xd3, 0x2, 0x3d, 0x21, 0x0, 0xd, 0x10, 0x0, + 0xf, 0xbb, 0xca, 0x0, 0xd, 0x10, 0x0, 0xd, + 0x0, 0x2a, 0xad, 0xdf, 0xdd, 0xd0, 0xd, 0x0, + 0x2a, 0x0, 0xd, 0x10, 0x0, 0xf, 0xdd, 0xda, + 0x0, 0xd, 0x10, 0x0, 0xd, 0x0, 0x15, 0x0, + 0xd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+8FA6 "辦" */ + 0x0, 0x90, 0x0, 0xc0, 0x0, 0x83, 0x0, 0x1, + 0xb4, 0x10, 0xc0, 0x1, 0x5a, 0x10, 0x2b, 0xbb, + 0x90, 0xc0, 0x9, 0xba, 0xb3, 0x9, 0x7, 0x4c, + 0xfc, 0x75, 0x50, 0xc0, 0x9, 0x3a, 0x11, 0xb3, + 0x93, 0x92, 0x90, 0x5, 0x3b, 0x1, 0xa3, 0x90, + 0x85, 0x60, 0x3c, 0xed, 0xb2, 0x93, 0x9b, 0xce, + 0xc5, 0x0, 0x93, 0x4, 0x73, 0x80, 0x1b, 0x0, + 0x1b, 0xec, 0x86, 0x53, 0x86, 0xae, 0x93, 0x0, + 0xb2, 0xa, 0x24, 0x81, 0x4c, 0x20, 0x0, 0xc0, + 0xc, 0x5, 0x70, 0x1b, 0x0, 0x3, 0x90, 0x57, + 0x7, 0x50, 0x1b, 0x0, 0xb, 0x10, 0xa0, 0xad, + 0x20, 0x1b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8FB2 "農" */ + 0x0, 0x0, 0xe, 0x0, 0xe0, 0x0, 0x0, 0x0, + 0xaa, 0xaf, 0xaa, 0xfa, 0xab, 0x0, 0x0, 0xd0, + 0xe, 0x0, 0xe0, 0xe, 0x0, 0x0, 0xea, 0xaf, + 0xaa, 0xfa, 0xaf, 0x0, 0x0, 0xe6, 0x6f, 0x66, + 0xf6, 0x6f, 0x0, 0x0, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x0, 0x0, 0xfb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xa0, 0x0, 0xd2, 0x77, 0x77, 0x77, 0x74, 0x0, + 0x1, 0xc1, 0x22, 0x22, 0x22, 0x21, 0x0, 0x3, + 0xeb, 0xfb, 0xce, 0xbb, 0xbd, 0xb2, 0x5, 0x80, + 0xe0, 0xb, 0x63, 0xaa, 0x0, 0xb, 0x40, 0xe1, + 0x46, 0xaf, 0x60, 0x0, 0x3c, 0x5, 0xfb, 0x72, + 0x3, 0xad, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, + + /* U+8FBA "辺" */ + 0x5, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xe3, 0xc, 0xdd, 0xdd, 0xdd, 0xa0, 0x0, 0x3e, + 0x10, 0x3, 0xc0, 0x3, 0xb0, 0x0, 0x1, 0x0, + 0x4, 0xa0, 0x3, 0xb0, 0x0, 0x0, 0x0, 0x6, + 0x80, 0x4, 0xa0, 0x0, 0x0, 0x0, 0xa, 0x40, + 0x4, 0xa0, 0x1d, 0xdd, 0x0, 0xe, 0x0, 0x5, + 0x90, 0x0, 0xd, 0x0, 0x79, 0x0, 0x6, 0x80, + 0x0, 0xd, 0x4, 0xe1, 0x0, 0x9, 0x60, 0x0, + 0xd, 0x1d, 0x20, 0x9, 0xce, 0x10, 0x0, 0x7f, + 0x20, 0x0, 0x0, 0x10, 0x0, 0x7, 0xc7, 0xd6, + 0x0, 0x0, 0x0, 0x0, 0xd, 0x10, 0x18, 0xdd, + 0xcd, 0xdd, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8FBC "込" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xc1, 0x0, 0x2d, 0x20, 0x0, 0x0, 0x0, 0x5c, + 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, 0x4, 0x0, + 0x0, 0xc6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xec, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xba, + 0x30, 0x0, 0x1d, 0xdd, 0x0, 0x9, 0x64, 0xa0, + 0x0, 0x0, 0xd, 0x0, 0x2e, 0x0, 0xe1, 0x0, + 0x0, 0xd, 0x0, 0xc6, 0x0, 0x7b, 0x0, 0x0, + 0xd, 0x1b, 0x90, 0x0, 0xb, 0xb1, 0x0, 0x5e, + 0x37, 0x0, 0x0, 0x0, 0x62, 0x8, 0xa4, 0xb8, + 0x32, 0x11, 0x22, 0x32, 0x9, 0x0, 0x4, 0x9a, + 0xbb, 0xbb, 0xa5, + + /* U+8FCE "迎" */ + 0x0, 0x0, 0x0, 0x2a, 0x60, 0x0, 0x0, 0x7, + 0x80, 0xa, 0xb4, 0xd, 0xdd, 0xd0, 0x0, 0x7c, + 0xd, 0x0, 0xd, 0x0, 0xd0, 0x0, 0x3, 0xd, + 0x0, 0xd, 0x0, 0xd0, 0x0, 0x0, 0xd, 0x0, + 0xd, 0x0, 0xd0, 0x1d, 0xd9, 0xd, 0x0, 0xd, + 0x0, 0xd0, 0x0, 0x3a, 0xd, 0x0, 0xd, 0x0, + 0xd0, 0x0, 0x3a, 0xd, 0x0, 0x2d, 0x0, 0xd0, + 0x0, 0x3a, 0xf, 0xae, 0x5d, 0x0, 0xe0, 0x0, + 0x3a, 0x4b, 0x40, 0xd, 0x3c, 0x90, 0x0, 0x4c, + 0x0, 0x0, 0xd, 0x0, 0x0, 0x5, 0xb6, 0xb4, + 0x0, 0x4, 0x0, 0x0, 0xd, 0x10, 0x18, 0xdd, + 0xcd, 0xde, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8FD1 "近" */ + 0x2, 0x20, 0x0, 0x1, 0x23, 0x69, 0x90, 0x2, + 0xd3, 0x0, 0xec, 0xa9, 0x74, 0x0, 0x0, 0x3d, + 0x10, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfb, + 0xbb, 0xbb, 0xb6, 0xd, 0xdb, 0x0, 0xf1, 0x11, + 0xe1, 0x10, 0x0, 0x1d, 0x1, 0xc0, 0x0, 0xe0, + 0x0, 0x0, 0xd, 0x3, 0xa0, 0x0, 0xe0, 0x0, + 0x0, 0xd, 0x8, 0x70, 0x0, 0xe0, 0x0, 0x0, + 0xd, 0xe, 0x20, 0x0, 0xe0, 0x0, 0x0, 0x9e, + 0x56, 0x0, 0x0, 0xa0, 0x0, 0xa, 0x80, 0xa9, + 0x31, 0x0, 0x1, 0x33, 0xa, 0x0, 0x4, 0xac, + 0xdd, 0xdd, 0xc6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8FD4 "返" */ + 0x1, 0x0, 0x0, 0x0, 0x2, 0x47, 0x10, 0xc, + 0x50, 0xb, 0xdd, 0xdb, 0x97, 0x20, 0x1, 0xd3, + 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0xe, + 0x33, 0x33, 0x33, 0x0, 0x0, 0x0, 0xe, 0x99, + 0x99, 0xae, 0x0, 0x5b, 0xb2, 0xe, 0x23, 0x0, + 0x98, 0x0, 0x12, 0xc3, 0x1c, 0x2d, 0x53, 0xe1, + 0x0, 0x0, 0xb3, 0x4a, 0x1, 0xbe, 0x40, 0x0, + 0x0, 0xb3, 0x95, 0x3, 0xdb, 0xb0, 0x0, 0x0, + 0xb5, 0xd2, 0x9d, 0x30, 0x8c, 0x10, 0x2, 0xe7, + 0x21, 0x60, 0x0, 0x5, 0x0, 0x2d, 0x39, 0xa3, + 0x10, 0x0, 0x13, 0x50, 0x74, 0x0, 0x39, 0xcd, + 0xed, 0xdc, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8FEB "迫" */ + 0x4, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x8, + 0xb0, 0x0, 0x3, 0xc0, 0x0, 0x0, 0x0, 0xa9, + 0xc, 0xde, 0xfd, 0xdd, 0x10, 0x0, 0x2, 0xe, + 0x10, 0x0, 0xe, 0x10, 0x0, 0x0, 0xe, 0x10, + 0x0, 0xe, 0x10, 0x7c, 0xc2, 0xe, 0x10, 0x0, + 0xe, 0x10, 0x12, 0xc3, 0xe, 0xdc, 0xcc, 0xcf, + 0x10, 0x0, 0xb3, 0xe, 0x10, 0x0, 0xe, 0x10, + 0x0, 0xb3, 0xe, 0x10, 0x0, 0xe, 0x10, 0x0, + 0xb3, 0xe, 0xdd, 0xdd, 0xdf, 0x10, 0x3, 0xe7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e, 0x6b, 0xa3, + 0x0, 0x0, 0x0, 0x10, 0x96, 0x0, 0x5c, 0xee, + 0xee, 0xff, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+8FFD "追" */ + 0x0, 0x0, 0x0, 0x0, 0x43, 0x0, 0x0, 0x5, + 0xa0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x7a, + 0x0, 0xfb, 0xbb, 0xbf, 0x0, 0x0, 0x3, 0x0, + 0xd0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0xfa, + 0xaa, 0xaf, 0x0, 0x1f, 0xfd, 0x0, 0xd2, 0x22, + 0x22, 0x0, 0x0, 0x1d, 0x0, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x0, 0xfc, 0xcc, 0xce, 0x70, + 0x0, 0xd, 0x0, 0xd0, 0x0, 0x6, 0x70, 0x0, + 0xd, 0x0, 0xd0, 0x0, 0x6, 0x70, 0x0, 0x1d, + 0x0, 0xcc, 0xcc, 0xcc, 0x60, 0x3, 0xda, 0xa2, + 0x0, 0x0, 0x0, 0x1, 0xd, 0x20, 0x4b, 0xdd, + 0xcd, 0xde, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x11, + 0x0, 0x0, + + /* U+9000 "退" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xb0, 0x1, 0xfc, 0xcc, 0xcf, 0x0, 0x0, 0x7b, + 0x1, 0xd0, 0x0, 0xe, 0x0, 0x0, 0x6, 0x1, + 0xfb, 0xbb, 0xbf, 0x0, 0x0, 0x0, 0x1, 0xd0, + 0x0, 0xe, 0x0, 0xd, 0xdb, 0x1, 0xfc, 0xcc, + 0xcf, 0x0, 0x0, 0x1c, 0x1, 0xd0, 0x31, 0x4, + 0xb0, 0x0, 0x1c, 0x1, 0xd0, 0x3c, 0x8a, 0x10, + 0x0, 0x1c, 0x1, 0xd0, 0x3, 0xc3, 0x0, 0x0, + 0x1c, 0x5, 0xfb, 0xc3, 0x1c, 0x30, 0x0, 0x5e, + 0x25, 0x61, 0x0, 0x2, 0x50, 0x7, 0xb3, 0xb7, + 0x20, 0x0, 0x1, 0x22, 0xb, 0x0, 0x5, 0xbc, + 0xdd, 0xdd, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9001 "送" */ + 0x4, 0x0, 0x2, 0x40, 0x0, 0x35, 0x0, 0x9, + 0x90, 0x1, 0xd1, 0x0, 0xb4, 0x0, 0x0, 0xb6, + 0x0, 0x64, 0x4, 0xb0, 0x0, 0x0, 0x12, 0x4d, + 0xdd, 0xfd, 0xdd, 0x80, 0x0, 0x0, 0x0, 0x0, + 0xe0, 0x0, 0x0, 0x7e, 0xe3, 0x0, 0x0, 0xf0, + 0x0, 0x0, 0x0, 0xb3, 0xae, 0xee, 0xfe, 0xee, + 0xe0, 0x0, 0xb3, 0x0, 0x4, 0xf7, 0x0, 0x0, + 0x0, 0xb3, 0x0, 0xd, 0x4b, 0x80, 0x0, 0x0, + 0xb3, 0x2, 0xc7, 0x0, 0xa8, 0x0, 0x1, 0xd5, + 0x5d, 0x50, 0x0, 0xb, 0x30, 0x2d, 0x6b, 0x82, + 0x0, 0x0, 0x0, 0x10, 0x96, 0x0, 0x6c, 0xee, + 0xde, 0xef, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9003 "逃" */ + 0x2, 0x0, 0x0, 0xd, 0xd, 0x0, 0x0, 0x7, + 0xb0, 0x43, 0xd, 0xd, 0x3, 0x60, 0x0, 0x8a, + 0x2c, 0xd, 0xd, 0xb, 0x40, 0x0, 0x4, 0x9, + 0x5d, 0xd, 0x4a, 0x0, 0x0, 0x0, 0x2, 0x2d, + 0xd, 0x41, 0x0, 0x1d, 0xd9, 0x0, 0x2d, 0xd, + 0x60, 0x0, 0x0, 0x3a, 0x8, 0xcd, 0xd, 0x8b, + 0x10, 0x0, 0x3a, 0x97, 0x4a, 0xd, 0x5, 0xb0, + 0x0, 0x3a, 0x0, 0x95, 0xd, 0x0, 0x20, 0x0, + 0x3a, 0x5, 0xc0, 0xd, 0x0, 0x84, 0x0, 0x3b, + 0x3b, 0x0, 0x6, 0xcd, 0xa0, 0x3, 0xb8, 0x82, + 0x0, 0x0, 0x0, 0x11, 0xd, 0x20, 0x3a, 0xdd, + 0xcd, 0xdf, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x11, + 0x0, 0x0, + + /* U+900F "透" */ + 0x2, 0x0, 0x0, 0x1, 0x24, 0x68, 0x50, 0x8, + 0xb0, 0x9, 0xa9, 0xad, 0x53, 0x0, 0x0, 0x99, + 0x0, 0x0, 0x3a, 0x0, 0x0, 0x0, 0x7, 0x4b, + 0xbc, 0xff, 0xdb, 0xb6, 0x0, 0x0, 0x0, 0x1b, + 0x9c, 0xb2, 0x0, 0x2, 0x21, 0x5, 0xc4, 0x3a, + 0x1c, 0x70, 0xb, 0xca, 0x7a, 0x76, 0x78, 0x61, + 0x86, 0x0, 0x3a, 0x1, 0x5b, 0x95, 0xd1, 0x10, + 0x0, 0x3a, 0x0, 0xd, 0x20, 0xaa, 0xe0, 0x0, + 0x3a, 0x0, 0x99, 0x0, 0x0, 0xc0, 0x0, 0x3c, + 0x3e, 0x80, 0x1, 0xbc, 0x60, 0x3, 0xed, 0xd6, + 0x0, 0x0, 0x0, 0x0, 0xd, 0x50, 0x3a, 0xed, + 0xdd, 0xde, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9010 "逐" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, + 0x30, 0xcc, 0xcd, 0xfc, 0xcc, 0xa0, 0x2, 0xd2, + 0x0, 0x3d, 0x40, 0x0, 0x0, 0x0, 0x31, 0x18, + 0xca, 0x60, 0xb, 0x40, 0x0, 0x0, 0xc5, 0x5, + 0xf3, 0xb5, 0x0, 0x7d, 0xd3, 0x0, 0x89, 0x4f, + 0x50, 0x0, 0x0, 0xb3, 0x6d, 0x50, 0x9f, 0xd2, + 0x0, 0x0, 0xb3, 0x20, 0x9, 0x7c, 0x3d, 0x20, + 0x0, 0xb3, 0x5, 0xd5, 0xc, 0x13, 0xc0, 0x0, + 0xb4, 0xca, 0x10, 0xe, 0x0, 0x10, 0x0, 0xc5, + 0x10, 0x29, 0xc8, 0x0, 0x0, 0x1c, 0x9b, 0x93, + 0x14, 0x30, 0x1, 0x20, 0x67, 0x0, 0x49, 0xcd, + 0xdd, 0xdd, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9019 "這" */ + 0x0, 0x0, 0x0, 0x0, 0x90, 0x0, 0x0, 0x6, + 0x70, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0x9c, + 0x5c, 0xcc, 0xcc, 0xcc, 0xc3, 0x0, 0x5, 0x0, + 0x23, 0x33, 0x33, 0x0, 0x0, 0x0, 0x0, 0x67, + 0x77, 0x77, 0x0, 0xd, 0xd9, 0x0, 0x56, 0x66, + 0x66, 0x0, 0x0, 0x3b, 0x0, 0x33, 0x33, 0x33, + 0x0, 0x0, 0x3b, 0x0, 0xbb, 0xbb, 0xbb, 0x10, + 0x0, 0x3b, 0x0, 0xe0, 0x0, 0xd, 0x10, 0x0, + 0x3b, 0x0, 0xe0, 0x0, 0xd, 0x10, 0x0, 0x5c, + 0x0, 0xcb, 0xbb, 0xbc, 0x10, 0x5, 0xb6, 0xc4, + 0x0, 0x0, 0x0, 0x0, 0xd, 0x10, 0x18, 0xdd, + 0xcd, 0xde, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+901A "通" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x50, 0xb, 0xcc, 0xcc, 0xcf, 0xa0, 0x1, 0xc5, + 0x0, 0x2a, 0x41, 0xaa, 0x0, 0x0, 0x1b, 0x0, + 0x2, 0x8e, 0xa0, 0x0, 0x0, 0x0, 0xe, 0xbb, + 0xcf, 0xbb, 0xf0, 0x5, 0x54, 0xe, 0x0, 0x1c, + 0x0, 0xe0, 0x18, 0x9c, 0xe, 0xbb, 0xbe, 0xbb, + 0xf0, 0x0, 0x2c, 0xe, 0x0, 0x1c, 0x0, 0xe0, + 0x0, 0x2c, 0xe, 0xbb, 0xcf, 0xbb, 0xf0, 0x0, + 0x2c, 0xe, 0x0, 0x1c, 0x0, 0xe0, 0x0, 0x4d, + 0xe, 0x0, 0x1c, 0x3b, 0xd0, 0x5, 0xb5, 0xb5, + 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x18, 0xcc, + 0xcc, 0xdd, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+901F "速" */ + 0x0, 0x0, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x7, + 0x90, 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, 0xb7, + 0x5c, 0xcc, 0xfd, 0xcc, 0xc7, 0x0, 0x1b, 0x0, + 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, 0xd, 0xcc, + 0xec, 0xcc, 0xe0, 0x1a, 0xaa, 0xd, 0x0, 0xb2, + 0x0, 0xe0, 0x0, 0xe, 0xd, 0xbb, 0xec, 0xbb, + 0xe0, 0x0, 0xe, 0x0, 0x8, 0xfe, 0x40, 0x0, + 0x0, 0xe, 0x0, 0x4b, 0xb5, 0xd7, 0x0, 0x0, + 0xe, 0x6, 0xd1, 0xb2, 0xb, 0x90, 0x0, 0xe, + 0x4b, 0x10, 0xb2, 0x0, 0x91, 0x3, 0xdb, 0xb4, + 0x0, 0x71, 0x0, 0x0, 0xd, 0x30, 0x29, 0xdd, + 0xcc, 0xdd, 0xe9, 0x0, 0x0, 0x0, 0x0, 0x11, + 0x0, 0x0, + + /* U+9020 "造" */ + 0x1, 0x0, 0x0, 0x63, 0x3b, 0x0, 0x0, 0x6, + 0xc0, 0x0, 0xe2, 0x3b, 0x0, 0x0, 0x0, 0x8a, + 0x6, 0xfd, 0xdf, 0xdd, 0x80, 0x0, 0x7, 0x2e, + 0x20, 0x3b, 0x0, 0x0, 0x0, 0x0, 0x14, 0x0, + 0x3b, 0x0, 0x0, 0x2, 0x21, 0x5c, 0xcc, 0xcc, + 0xcc, 0xc3, 0x1b, 0xca, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3a, 0x2, 0xfc, 0xcc, 0xcf, 0x20, + 0x0, 0x3a, 0x2, 0xb0, 0x0, 0xc, 0x20, 0x0, + 0x3a, 0x2, 0xb0, 0x0, 0xc, 0x20, 0x0, 0x3b, + 0x1, 0xcc, 0xcc, 0xcc, 0x10, 0x3, 0xda, 0x92, + 0x0, 0x0, 0x0, 0x1, 0xd, 0x20, 0x4b, 0xdd, + 0xcd, 0xde, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x11, + 0x0, 0x0, + + /* U+9023 "連" */ + 0x9, 0x10, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x6, + 0xb0, 0x99, 0x9a, 0xe9, 0x99, 0x70, 0x0, 0xa7, + 0x22, 0x25, 0xc2, 0x22, 0x20, 0x0, 0x11, 0x3b, + 0xbc, 0xeb, 0xbb, 0x0, 0x0, 0x0, 0x48, 0x2, + 0xc0, 0xd, 0x0, 0x8e, 0xf3, 0x4d, 0xbb, 0xeb, + 0xbf, 0x0, 0x0, 0xb3, 0x48, 0x2, 0xc0, 0xd, + 0x0, 0x0, 0xb3, 0x4d, 0xbc, 0xeb, 0xbd, 0x0, + 0x0, 0xb3, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, + 0xb6, 0xcc, 0xcd, 0xfc, 0xcc, 0xc0, 0x1, 0xd5, + 0x0, 0x2, 0xc0, 0x0, 0x0, 0x2d, 0x5c, 0x71, + 0x0, 0x10, 0x0, 0x21, 0x95, 0x0, 0x6d, 0xed, + 0xde, 0xef, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+902E "逮" */ + 0x8, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xa, + 0x80, 0x3b, 0xbb, 0xfb, 0xba, 0x0, 0x0, 0xd2, + 0x0, 0x0, 0xd0, 0xe, 0x0, 0x0, 0x13, 0xbb, + 0xbb, 0xfb, 0xbf, 0xb1, 0x0, 0x0, 0x0, 0x0, + 0xd0, 0xe, 0x0, 0x8d, 0xf2, 0x4b, 0xbc, 0xfb, + 0xbc, 0x0, 0x0, 0xb2, 0x36, 0x0, 0xd0, 0x9, + 0x10, 0x0, 0xb2, 0xa, 0x60, 0xe3, 0xa6, 0x0, + 0x0, 0xb2, 0x0, 0x7b, 0xec, 0xa0, 0x0, 0x0, + 0xb3, 0x4c, 0x92, 0xd0, 0x7c, 0x20, 0x0, 0xc3, + 0x92, 0x1, 0xd0, 0x4, 0x70, 0x1c, 0x5b, 0x61, + 0x4b, 0x60, 0x0, 0x0, 0x95, 0x0, 0x6c, 0xed, + 0xde, 0xef, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9031 "週" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, + 0x80, 0xd, 0xcc, 0xdc, 0xcc, 0xd0, 0x0, 0xa9, + 0xd, 0x0, 0xc0, 0x0, 0xd0, 0x0, 0x6, 0xd, + 0x4b, 0xeb, 0xb2, 0xd0, 0x0, 0x0, 0xd, 0x12, + 0xc3, 0x20, 0xd0, 0x7, 0x75, 0xd, 0x37, 0x77, + 0x72, 0xd0, 0x5, 0x7a, 0xd, 0x1b, 0xbb, 0x80, + 0xd0, 0x0, 0x3a, 0xd, 0x19, 0x1, 0xc0, 0xd0, + 0x0, 0x3a, 0x49, 0x1a, 0x34, 0xc0, 0xd0, 0x0, + 0x3a, 0xa5, 0x7, 0x77, 0x50, 0xd0, 0x0, 0x4d, + 0x80, 0x0, 0x0, 0xbc, 0x90, 0x4, 0xe8, 0xc5, + 0x0, 0x0, 0x0, 0x0, 0xd, 0x30, 0x18, 0xdd, + 0xcc, 0xdd, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+9032 "進" */ + 0x5, 0x10, 0x0, 0x36, 0x26, 0x0, 0x0, 0x5, + 0xe2, 0x0, 0xb3, 0xe, 0x10, 0x0, 0x0, 0x5d, + 0x3, 0xfa, 0xad, 0xca, 0xa4, 0x0, 0x1, 0xd, + 0xc2, 0x2e, 0x22, 0x21, 0x0, 0x0, 0xbc, 0xb0, + 0xd, 0x0, 0x0, 0x3, 0x43, 0x83, 0xeb, 0xbf, + 0xbb, 0xb0, 0x8, 0xbb, 0x2, 0xb0, 0xd, 0x0, + 0x0, 0x0, 0x3b, 0x2, 0xec, 0xcf, 0xcc, 0xc0, + 0x0, 0x3b, 0x2, 0xb0, 0xd, 0x0, 0x0, 0x0, + 0x3b, 0x2, 0xea, 0xaf, 0xaa, 0xa7, 0x0, 0x6d, + 0x10, 0x22, 0x22, 0x22, 0x21, 0x6, 0xe9, 0xd7, + 0x10, 0x0, 0x0, 0x2, 0xd, 0x30, 0x18, 0xdf, + 0xee, 0xef, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, + + /* U+9045 "遅" */ + 0x5, 0x40, 0xc, 0xbb, 0xbb, 0xbb, 0xf0, 0x1, + 0xb9, 0xc, 0x10, 0x0, 0x0, 0xe0, 0x0, 0x7, + 0x1c, 0xbd, 0xbb, 0xbd, 0xb0, 0x0, 0x0, 0xc, + 0x17, 0x50, 0x3b, 0x0, 0xc, 0xc9, 0xd, 0x8c, + 0xdc, 0xdc, 0xb0, 0x0, 0x4b, 0xd, 0x0, 0xe, + 0x0, 0x0, 0x0, 0x3b, 0xd, 0x3b, 0xbf, 0xbb, + 0x80, 0x0, 0x3b, 0x3a, 0x0, 0xe, 0x0, 0x0, + 0x0, 0x3b, 0x86, 0xbb, 0xbf, 0xbb, 0xb3, 0x0, + 0x4c, 0x90, 0x0, 0xe, 0x0, 0x0, 0x5, 0xc7, + 0xb4, 0x0, 0x4, 0x0, 0x0, 0xd, 0x10, 0x29, + 0xdd, 0xcd, 0xde, 0xf5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+904A "遊" */ + 0x0, 0x0, 0x3, 0x40, 0x3, 0x80, 0x0, 0x9, + 0x40, 0x1, 0xc0, 0xa, 0x92, 0x22, 0x1, 0xc5, + 0xcc, 0xfd, 0xbe, 0x99, 0x96, 0x0, 0x14, 0xc, + 0x0, 0x87, 0x33, 0x30, 0x0, 0x0, 0xc, 0xaa, + 0x35, 0x78, 0xe2, 0x2f, 0xfa, 0xc, 0x29, 0x40, + 0xc, 0x30, 0x0, 0x3a, 0xc, 0x9, 0x30, 0xc, + 0x0, 0x0, 0x3a, 0xb, 0xa, 0x6c, 0xcf, 0xc9, + 0x0, 0x3a, 0x48, 0xb, 0x20, 0xc, 0x0, 0x0, + 0x3a, 0xb2, 0xc, 0x0, 0xc, 0x0, 0x0, 0x6d, + 0x72, 0xca, 0x6, 0xca, 0x0, 0x6, 0xb4, 0xb6, + 0x0, 0x0, 0x0, 0x1, 0xd, 0x10, 0x7, 0xcd, + 0xdd, 0xde, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+904B "運" */ + 0x6, 0x50, 0x8c, 0xbb, 0xbb, 0xbb, 0xd6, 0x1, + 0xd3, 0x83, 0x0, 0x91, 0x0, 0x76, 0x0, 0x29, + 0x48, 0xbb, 0xfb, 0xbb, 0x63, 0x0, 0x0, 0x5, + 0x66, 0xe7, 0x66, 0x40, 0x2, 0x22, 0xd, 0x33, + 0xd4, 0x35, 0xa0, 0x1a, 0xbb, 0xd, 0xaa, 0xfa, + 0xab, 0xa0, 0x0, 0x2b, 0xd, 0x33, 0xd4, 0x36, + 0xa0, 0x0, 0x2b, 0x5, 0x66, 0xe7, 0x66, 0x40, + 0x0, 0x2b, 0x6c, 0xcc, 0xfc, 0xcc, 0xc6, 0x0, + 0x9e, 0x30, 0x0, 0xd1, 0x0, 0x0, 0xa, 0x81, + 0xb9, 0x31, 0x50, 0x1, 0x23, 0xa, 0x0, 0x4, + 0xab, 0xcc, 0xcc, 0xb8, + + /* U+904E "過" */ + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, + 0x90, 0x1, 0xeb, 0xbb, 0xe8, 0x0, 0x0, 0xb9, + 0x1, 0xc1, 0x10, 0x98, 0x0, 0x0, 0x4, 0x1, + 0xe9, 0xc0, 0x98, 0x0, 0x0, 0x0, 0x1, 0xb0, + 0x80, 0x98, 0x0, 0x8d, 0xf3, 0x2d, 0xdc, 0xdc, + 0xdd, 0xa0, 0x0, 0xb3, 0x3a, 0x0, 0x0, 0x2, + 0xb0, 0x0, 0xb3, 0x3a, 0x1e, 0xbe, 0x12, 0xb0, + 0x0, 0xb3, 0x3a, 0x1a, 0xa, 0x12, 0xb0, 0x0, + 0xb3, 0x3a, 0x1e, 0xad, 0x12, 0xb0, 0x3, 0xe6, + 0x3a, 0x5, 0x0, 0xbc, 0x80, 0x2d, 0x3a, 0x92, + 0x0, 0x0, 0x0, 0x11, 0x94, 0x0, 0x5c, 0xed, + 0xde, 0xef, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9053 "道" */ + 0x0, 0x0, 0x0, 0x63, 0x0, 0x54, 0x0, 0x8, + 0x90, 0x0, 0x2b, 0x0, 0xd1, 0x0, 0x0, 0xa7, + 0x4c, 0xcd, 0xdd, 0xec, 0xc3, 0x0, 0x5, 0x0, + 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x2, 0xcb, + 0xeb, 0xbd, 0x0, 0xb, 0xb9, 0x2, 0xb0, 0x0, + 0xd, 0x0, 0x2, 0x2d, 0x2, 0xea, 0xaa, 0xaf, + 0x0, 0x0, 0xd, 0x2, 0xb0, 0x0, 0xd, 0x0, + 0x0, 0xd, 0x2, 0xeb, 0xbb, 0xbf, 0x0, 0x0, + 0xd, 0x2, 0xb0, 0x0, 0xd, 0x0, 0x0, 0x2e, + 0x2, 0xbb, 0xbb, 0xbb, 0x0, 0x4, 0xc6, 0xb4, + 0x0, 0x0, 0x0, 0x0, 0xc, 0x10, 0x19, 0xdc, + 0xcc, 0xde, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9054 "達" */ + 0x3, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xc, + 0x60, 0x1b, 0xbb, 0xfb, 0xbb, 0x20, 0x1, 0xd4, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x32, 0xbb, + 0xcb, 0xfb, 0xcb, 0xb1, 0x0, 0x0, 0x0, 0xc0, + 0x0, 0xd0, 0x0, 0x13, 0x30, 0x47, 0xd8, 0x79, + 0xc7, 0x60, 0x5a, 0xe2, 0x24, 0x44, 0xf4, 0x44, + 0x30, 0x0, 0xb2, 0x1b, 0xbb, 0xfb, 0xbb, 0x40, + 0x0, 0xb2, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x0, + 0xb2, 0x9b, 0xbb, 0xfb, 0xbb, 0xb0, 0x2, 0xe7, + 0x0, 0x0, 0xe0, 0x0, 0x0, 0x1d, 0x27, 0xb4, + 0x10, 0x40, 0x1, 0x31, 0x55, 0x0, 0x28, 0xbc, + 0xdd, 0xcc, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9055 "違" */ + 0x1, 0x0, 0x0, 0x4, 0x60, 0x0, 0x0, 0x8, + 0xa0, 0xa, 0xad, 0xda, 0xa5, 0x0, 0x0, 0x99, + 0x0, 0x1e, 0x0, 0x48, 0x0, 0x0, 0x4, 0x9b, + 0xbb, 0xbb, 0xbb, 0xb2, 0x0, 0x0, 0x7, 0xaa, + 0xaa, 0xaa, 0x0, 0x6, 0x64, 0xb, 0x10, 0x0, + 0xe, 0x0, 0x7, 0x9a, 0x9, 0xa9, 0x9c, 0x9c, + 0x0, 0x0, 0x3a, 0x36, 0x66, 0x6e, 0x66, 0x60, + 0x0, 0x3a, 0x1d, 0x43, 0x3e, 0x33, 0x30, 0x0, + 0x3a, 0x1f, 0xaa, 0xaf, 0xaa, 0x90, 0x0, 0x5c, + 0x0, 0x0, 0xe, 0x0, 0x0, 0x6, 0xd9, 0xc4, + 0x0, 0x7, 0x0, 0x0, 0x1d, 0x10, 0x29, 0xdd, + 0xcc, 0xde, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+9060 "遠" */ + 0x0, 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0x7, + 0x90, 0xa, 0xbb, 0xec, 0xbb, 0x50, 0x0, 0x8d, + 0x10, 0x0, 0xb3, 0x0, 0x0, 0x0, 0x4, 0x8b, + 0xbb, 0xdc, 0xbb, 0xb3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x96, 0x8, 0xca, 0xaa, + 0xae, 0x10, 0x3, 0x6b, 0x8, 0x50, 0x0, 0xc, + 0x10, 0x0, 0x3b, 0x5, 0xbc, 0xfb, 0xbb, 0x60, + 0x0, 0x3b, 0x0, 0x3d, 0xec, 0x5b, 0x40, 0x0, + 0x3b, 0x29, 0xc2, 0xc3, 0x9a, 0x0, 0x0, 0x4c, + 0x55, 0x0, 0xc2, 0x4, 0x80, 0x5, 0xc8, 0xb4, + 0x0, 0x51, 0x0, 0x0, 0xd, 0x10, 0x29, 0xdd, + 0xcd, 0xde, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9069 "適" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x15, + 0x0, 0x0, 0x4, 0x80, 0x0, 0x0, 0xb, 0x80, + 0xbb, 0xbb, 0xfb, 0xbb, 0xb0, 0x0, 0xc5, 0x0, + 0xc1, 0x2, 0xd0, 0x0, 0x0, 0x10, 0x36, 0xc8, + 0x6b, 0xb6, 0x30, 0x0, 0x0, 0x79, 0x55, 0xd5, + 0x59, 0x70, 0x36, 0x61, 0x77, 0xaa, 0xea, 0xa6, + 0x70, 0x59, 0xe2, 0x76, 0x0, 0xb0, 0x6, 0x70, + 0x0, 0xb2, 0x76, 0x4a, 0xca, 0x46, 0x70, 0x0, + 0xb2, 0x76, 0x65, 0x5, 0x56, 0x70, 0x0, 0xb2, + 0x76, 0x6b, 0x99, 0x36, 0x70, 0x2, 0xe7, 0x65, + 0x0, 0x0, 0xac, 0x30, 0x1d, 0x17, 0xb4, 0x10, + 0x0, 0x1, 0x30, 0x55, 0x0, 0x28, 0xbc, 0xdd, + 0xcc, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+9078 "選" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x90, 0x3d, 0xab, 0x5c, 0xaa, 0xe0, 0x0, 0x9b, + 0x3d, 0xab, 0x5c, 0xaa, 0xf0, 0x0, 0x4, 0x39, + 0x0, 0x4c, 0x0, 0x23, 0x0, 0x0, 0x1c, 0xbb, + 0x78, 0xba, 0xb3, 0x6, 0x64, 0x0, 0xc, 0x0, + 0xc0, 0x0, 0x7, 0x9a, 0x1b, 0xbf, 0xbb, 0xfb, + 0xa0, 0x0, 0x3a, 0x0, 0xd, 0x0, 0xd0, 0x0, + 0x0, 0x3a, 0x8b, 0xbf, 0xbb, 0xfb, 0xb5, 0x0, + 0x3a, 0x0, 0x3a, 0x2, 0xa2, 0x0, 0x0, 0x4c, + 0x19, 0xb1, 0x0, 0x2b, 0x80, 0x4, 0xd8, 0xc8, + 0x0, 0x0, 0x0, 0x40, 0xd, 0x20, 0x18, 0xdd, + 0xcc, 0xdd, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x11, + 0x0, 0x0, + + /* U+907F "避" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x60, 0x0, 0x1d, + 0x10, 0xcc, 0xcd, 0x0, 0xc0, 0x0, 0x5, 0xb0, + 0xc0, 0xd, 0x8c, 0xcc, 0xc0, 0x0, 0x81, 0xc0, + 0xd, 0x9, 0x7, 0x40, 0x0, 0x0, 0xdc, 0xcd, + 0xb, 0xc, 0x0, 0x1, 0x10, 0xd1, 0x11, 0x7a, + 0x9d, 0x80, 0x6b, 0xf0, 0xd4, 0x44, 0x44, 0xe4, + 0x40, 0x0, 0xd3, 0xea, 0x7d, 0x1, 0xd1, 0x10, + 0x0, 0xd8, 0xa6, 0xb, 0x7b, 0xfb, 0xa0, 0x0, + 0xd9, 0x56, 0xb, 0x0, 0xd0, 0x0, 0x1, 0xe3, + 0x4c, 0xbd, 0x0, 0xd0, 0x0, 0x2d, 0xad, 0x93, + 0x0, 0x0, 0x0, 0x10, 0x85, 0x0, 0x5a, 0xcd, + 0xdd, 0xdd, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9084 "還" */ + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x60, 0xca, 0xcb, 0x9e, 0x9c, 0x50, 0x0, 0xc4, + 0xc2, 0x76, 0x1c, 0x18, 0x50, 0x0, 0x12, 0x68, + 0x88, 0x88, 0x88, 0x30, 0x0, 0x3, 0x99, 0x99, + 0x99, 0x99, 0x91, 0x7c, 0xe3, 0x39, 0x99, 0x99, + 0x99, 0x0, 0x0, 0xb3, 0x48, 0x0, 0x0, 0xe, + 0x0, 0x0, 0xb3, 0x4c, 0x9a, 0xa9, 0x9e, 0x0, + 0x0, 0xb3, 0x2, 0xa8, 0x55, 0x3b, 0x20, 0x0, + 0xb5, 0xb9, 0xe0, 0x7, 0xe3, 0x0, 0x1, 0xd4, + 0x0, 0xe9, 0xb1, 0x2c, 0x50, 0x1d, 0x6c, 0x74, + 0x83, 0x0, 0x0, 0x20, 0x96, 0x0, 0x7d, 0xed, + 0xdd, 0xef, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+908A "邊" */ + 0x7, 0x10, 0x0, 0x2, 0xa0, 0x0, 0x0, 0x6, + 0xc0, 0xe, 0x88, 0x88, 0x8e, 0x0, 0x0, 0x7a, + 0xe, 0x88, 0x88, 0x8e, 0x0, 0x0, 0x1, 0xe, + 0x77, 0x77, 0x7e, 0x0, 0x11, 0x10, 0xc, 0x78, + 0x87, 0x7c, 0x0, 0x6a, 0xe3, 0x99, 0x9a, 0xf9, + 0x99, 0x90, 0x0, 0xb3, 0xb1, 0x92, 0x16, 0x70, + 0xb0, 0x0, 0xb3, 0x2c, 0x43, 0xd2, 0x78, 0x10, + 0x0, 0xb4, 0x88, 0xbd, 0x88, 0x88, 0x80, 0x0, + 0xb3, 0x0, 0xbb, 0x99, 0xa4, 0x0, 0x1, 0xd5, + 0x3b, 0x80, 0x0, 0x92, 0x0, 0x2d, 0x5c, 0xd4, + 0x0, 0x49, 0x60, 0x11, 0x95, 0x0, 0x6c, 0xed, + 0xde, 0xef, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+90A3 "那" */ + 0x3d, 0xdf, 0xdd, 0xf0, 0xdd, 0xde, 0xe1, 0x0, + 0xe, 0x0, 0xe0, 0xe0, 0x4, 0xb0, 0x0, 0xe, + 0x0, 0xe0, 0xe0, 0xc, 0x20, 0xd, 0xdf, 0xdd, + 0xf0, 0xe0, 0x5a, 0x0, 0x0, 0x1d, 0x0, 0xe0, + 0xe0, 0xc4, 0x0, 0x0, 0x2b, 0x0, 0xe0, 0xe0, + 0x2c, 0x20, 0x3, 0x6b, 0x33, 0xe0, 0xe0, 0x4, + 0xa0, 0x1a, 0xdc, 0xaa, 0xe0, 0xe0, 0x0, 0xd0, + 0x0, 0xb3, 0x0, 0xe0, 0xe0, 0x0, 0xe0, 0x1, + 0xe0, 0x1, 0xd0, 0xe4, 0xde, 0x70, 0xa, 0x70, + 0x4, 0xc0, 0xe0, 0x0, 0x0, 0x2c, 0x3, 0xff, + 0x50, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x20, 0x0, 0x0, + + /* U+90AA "邪" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0xdd, 0xdf, 0xe8, 0xae, 0xee, 0xf3, 0x0, 0x30, + 0xe, 0x0, 0xa3, 0x2, 0xd0, 0x3, 0xb0, 0xe, + 0x0, 0xa3, 0x9, 0x50, 0x4, 0x80, 0xe, 0x0, + 0xa3, 0x1d, 0x0, 0x7, 0x82, 0x2e, 0x21, 0xa3, + 0x86, 0x0, 0x7, 0xbb, 0xdf, 0xc8, 0xa3, 0x4b, + 0x10, 0x0, 0x1, 0xdf, 0x0, 0xa3, 0x4, 0xb0, + 0x0, 0xc, 0x4e, 0x0, 0xa3, 0x0, 0xc1, 0x0, + 0xa7, 0xe, 0x0, 0xa3, 0x0, 0xc2, 0x1b, 0x70, + 0xe, 0x0, 0xa4, 0xcd, 0xb0, 0x36, 0x0, 0xe, + 0x0, 0xa3, 0x11, 0x0, 0x0, 0xb, 0xeb, 0x0, + 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+90E8 "部" */ + 0x0, 0x3, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xd0, 0x0, 0x2f, 0xdd, 0xf1, 0xb, 0xdd, + 0xdd, 0xd9, 0x2a, 0x2, 0xc0, 0x0, 0xc1, 0x0, + 0xd0, 0x2a, 0x8, 0x60, 0x0, 0x87, 0x6, 0x90, + 0x2a, 0xd, 0x0, 0x0, 0x38, 0xb, 0x30, 0x3a, + 0x49, 0x0, 0x3c, 0xcc, 0xcc, 0xcc, 0x3a, 0x1c, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x2a, 0x3, 0xb0, + 0x6, 0xed, 0xdd, 0xe5, 0x2a, 0x0, 0xd0, 0x6, + 0x70, 0x0, 0x85, 0x2a, 0x0, 0xe0, 0x6, 0x70, + 0x0, 0x85, 0x2a, 0x9c, 0x70, 0x6, 0xdb, 0xbb, + 0xe5, 0x2a, 0x0, 0x0, 0x6, 0x71, 0x11, 0x95, + 0x2a, 0x0, 0x0, + + /* U+90F5 "郵" */ + 0x0, 0x0, 0x3, 0x64, 0x0, 0x0, 0x0, 0x2b, + 0xcd, 0xea, 0x73, 0x7e, 0xdd, 0xf2, 0x0, 0x2, + 0xa0, 0x0, 0x76, 0x2, 0xd0, 0x2c, 0xcd, 0xfc, + 0xcb, 0x76, 0x8, 0x60, 0x4, 0x82, 0xa0, 0xb0, + 0x76, 0xd, 0x0, 0x4, 0x82, 0xa0, 0xb0, 0x76, + 0x4a, 0x0, 0x7d, 0xed, 0xfc, 0xfc, 0x86, 0xc, + 0x30, 0x4, 0x82, 0xa0, 0xb0, 0x76, 0x3, 0xc0, + 0x19, 0xb8, 0xd6, 0xd6, 0x76, 0x0, 0xd0, 0x14, + 0x46, 0xc4, 0x44, 0x76, 0x0, 0xd1, 0x0, 0x2, + 0xa0, 0x24, 0x76, 0xad, 0xb0, 0x38, 0xac, 0xfd, + 0xb8, 0x76, 0x11, 0x0, 0x35, 0x31, 0x0, 0x0, + 0x76, 0x0, 0x0, + + /* U+90FD "都" */ + 0x0, 0x7, 0x60, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x60, 0x2b, 0x7f, 0xee, 0xf3, 0x9, 0xde, + 0xed, 0xc2, 0x76, 0x2, 0xd0, 0x0, 0x7, 0x66, + 0x70, 0x76, 0x9, 0x50, 0x3a, 0xad, 0xdf, 0xba, + 0x76, 0x1d, 0x0, 0x2, 0x27, 0xe3, 0x22, 0x76, + 0x77, 0x0, 0x0, 0x5f, 0x30, 0x0, 0x76, 0x1c, + 0x30, 0x9, 0xfc, 0xcc, 0xe4, 0x76, 0x2, 0xd0, + 0x48, 0xd0, 0x0, 0xa4, 0x76, 0x0, 0xc1, 0x0, + 0xdc, 0xcc, 0xe4, 0x76, 0x0, 0xc2, 0x0, 0xd0, + 0x0, 0xa4, 0x76, 0x9c, 0xb0, 0x0, 0xdd, 0xcc, + 0xe4, 0x76, 0x10, 0x0, 0x0, 0xd0, 0x0, 0xa4, + 0x76, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+914D "配" */ + 0x1, 0x11, 0x11, 0x10, 0x0, 0x0, 0x0, 0x1c, + 0xce, 0xec, 0xc3, 0xee, 0xee, 0xf0, 0x0, 0x18, + 0x82, 0x0, 0x0, 0x0, 0xe0, 0xa, 0xde, 0xed, + 0x90, 0x0, 0x0, 0xe0, 0xc, 0x8, 0x90, 0xb0, + 0x0, 0x0, 0xe0, 0xc, 0x8, 0x90, 0xb1, 0xcc, + 0xcc, 0xf0, 0xc, 0x45, 0x90, 0xb2, 0xc2, 0x22, + 0xe0, 0xc, 0x90, 0x49, 0xb2, 0xc0, 0x0, 0x40, + 0xc, 0x0, 0x0, 0xb2, 0xc0, 0x0, 0x0, 0xc, + 0xbb, 0xbb, 0xb2, 0xc0, 0x0, 0x10, 0xc, 0x0, + 0x0, 0xb2, 0xc0, 0x0, 0x67, 0xc, 0xcc, 0xcc, + 0xb2, 0xc0, 0x0, 0x85, 0xc, 0x0, 0x0, 0xa0, + 0xce, 0xee, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9152 "酒" */ + 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, + 0xe5, 0xdd, 0xdf, 0xdf, 0xed, 0xd5, 0x0, 0x25, + 0x0, 0xd, 0xb, 0x20, 0x0, 0x0, 0x0, 0x0, + 0xd, 0xb, 0x20, 0x0, 0x26, 0x0, 0x6e, 0xdf, + 0xdf, 0xdd, 0xd0, 0x1a, 0xd2, 0x67, 0xb, 0xb, + 0x1, 0xd0, 0x0, 0x40, 0x67, 0x39, 0xb, 0x1, + 0xd0, 0x0, 0x0, 0x6a, 0xc1, 0x6, 0xcc, 0xd0, + 0x0, 0x2a, 0x69, 0x10, 0x0, 0x1, 0xd0, 0x0, + 0xa4, 0x6e, 0xdd, 0xdd, 0xdd, 0xd0, 0x3, 0xc0, + 0x67, 0x0, 0x0, 0x1, 0xd0, 0xc, 0x40, 0x6d, + 0xaa, 0xaa, 0xaa, 0xd0, 0x7, 0x0, 0x69, 0x22, + 0x22, 0x23, 0xc0, + + /* U+9154 "酔" */ + 0x0, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x1c, + 0xde, 0xfc, 0xa0, 0x1d, 0x0, 0x0, 0x0, 0x46, + 0xa0, 0xa, 0xbe, 0xaf, 0x0, 0x8, 0xbc, 0xe9, + 0x60, 0x68, 0xd, 0x2, 0xc, 0x48, 0xa4, 0xa0, + 0xb3, 0xd, 0xa, 0xb, 0x26, 0x82, 0xa7, 0xd0, + 0xc, 0xa8, 0xb, 0x54, 0x92, 0xbc, 0x22, 0x90, + 0x20, 0xc, 0x90, 0x5a, 0xa0, 0x3, 0xa0, 0x0, + 0xc, 0x10, 0x2, 0xa9, 0x9a, 0xd9, 0x96, 0xd, + 0xcc, 0xcc, 0xa3, 0x36, 0xb3, 0x32, 0xb, 0x0, + 0x2, 0xa0, 0x3, 0xa0, 0x0, 0xd, 0xcc, 0xcc, + 0xa0, 0x3, 0xa0, 0x0, 0xb, 0x0, 0x2, 0xa0, + 0x3, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9178 "酸" */ + 0x0, 0x0, 0x0, 0x0, 0x5, 0x10, 0x0, 0x1c, + 0xed, 0xfc, 0x70, 0x4c, 0x19, 0x0, 0x0, 0x64, + 0xa0, 0x3, 0xd2, 0x1a, 0x80, 0xb, 0xed, 0xfc, + 0x4a, 0xb9, 0x87, 0xc2, 0xb, 0x34, 0x85, 0x50, + 0x67, 0xc, 0x10, 0xb, 0x43, 0x85, 0x54, 0xd0, + 0x4, 0xc0, 0xb, 0x71, 0x95, 0x7e, 0x3b, 0x0, + 0x76, 0xc, 0x80, 0x7b, 0x61, 0x8d, 0x88, 0x70, + 0xb, 0x0, 0x5, 0x55, 0xf5, 0x39, 0x80, 0xd, + 0xbb, 0xbd, 0x7c, 0x5c, 0x2e, 0x10, 0xb, 0x0, + 0x5, 0x50, 0x9, 0xf3, 0x0, 0xd, 0xcc, 0xcd, + 0x50, 0x7c, 0x9c, 0x30, 0xb, 0x0, 0x5, 0x9d, + 0x70, 0x3, 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+91AB "醫" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0xad, 0xaa, 0xa1, 0xca, 0xb9, 0x0, 0xb, 0x6b, + 0xa7, 0x56, 0xa0, 0x2c, 0x80, 0xb, 0x99, 0xd9, + 0x96, 0xaa, 0xab, 0x20, 0xb, 0x13, 0xc9, 0x1, + 0xa4, 0x67, 0x0, 0xb, 0x7a, 0x35, 0x80, 0x4e, + 0xe5, 0x0, 0x5, 0x77, 0x77, 0x78, 0x81, 0x7, + 0x50, 0x6a, 0xaa, 0xad, 0xcb, 0xea, 0xaa, 0xa1, + 0x0, 0x88, 0x8c, 0xb9, 0xd8, 0x88, 0x0, 0x1, + 0xc1, 0x4c, 0x22, 0xb2, 0x2d, 0x0, 0x1, 0xc9, + 0x82, 0x0, 0x68, 0x8e, 0x0, 0x1, 0xe7, 0x77, + 0x77, 0x77, 0x7e, 0x0, 0x1, 0xe9, 0x99, 0x99, + 0x99, 0x9e, 0x0, + + /* U+91CD "重" */ + 0x0, 0x0, 0x0, 0x1, 0x34, 0x66, 0x0, 0x0, + 0xac, 0xcc, 0xdd, 0x97, 0x53, 0x0, 0x4, 0x44, + 0x44, 0x8b, 0x44, 0x44, 0x41, 0x7, 0x77, 0x77, + 0xac, 0x77, 0x77, 0x72, 0x0, 0x6a, 0xaa, 0xcd, + 0xaa, 0xaa, 0x0, 0x0, 0x94, 0x0, 0x59, 0x0, + 0xe, 0x0, 0x0, 0x9c, 0xaa, 0xcd, 0xaa, 0xaf, + 0x0, 0x0, 0x94, 0x0, 0x59, 0x0, 0xe, 0x0, + 0x0, 0x7b, 0xbb, 0xcd, 0xbb, 0xbc, 0x0, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0xcc, + 0xcc, 0xde, 0xcc, 0xcc, 0x70, 0x0, 0x0, 0x0, + 0x59, 0x0, 0x0, 0x0, 0xc, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xc5, + + /* U+91CE "野" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0xcd, 0xec, 0xf7, 0xdd, 0xdd, 0xf4, 0xc, 0x5, + 0x70, 0xc0, 0x10, 0x9, 0x90, 0xe, 0xbd, 0xdb, + 0xf0, 0x5e, 0xb9, 0x0, 0xc, 0x5, 0x70, 0xc0, + 0x2, 0xd8, 0x0, 0xc, 0x5, 0x70, 0xc4, 0x55, + 0x6f, 0x73, 0xb, 0xcd, 0xec, 0xc6, 0x9a, 0xe9, + 0xc8, 0x0, 0x6, 0x70, 0x0, 0x1, 0xd0, 0xc2, + 0xd, 0xde, 0xed, 0xd0, 0x1, 0xd1, 0x90, 0x0, + 0x6, 0x70, 0x0, 0x1, 0xd0, 0x0, 0x0, 0x6, + 0x81, 0x42, 0x1, 0xd0, 0x0, 0x39, 0xbe, 0xeb, + 0x93, 0x1, 0xd0, 0x0, 0x25, 0x20, 0x0, 0x3, + 0xee, 0x80, 0x0, + + /* U+91CF "量" */ + 0x0, 0x5d, 0x99, 0x99, 0x99, 0xba, 0x0, 0x0, + 0x5d, 0x99, 0x99, 0x99, 0xba, 0x0, 0x0, 0x5b, + 0x66, 0x66, 0x66, 0x8a, 0x0, 0x0, 0x24, 0x44, + 0x44, 0x44, 0x43, 0x0, 0xa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xa4, 0x0, 0x79, 0x77, 0x9a, 0x77, + 0x7b, 0x10, 0x0, 0x9b, 0x99, 0xbd, 0x99, 0x9e, + 0x10, 0x0, 0x95, 0x11, 0x6a, 0x11, 0x1d, 0x10, + 0x0, 0x47, 0x77, 0xac, 0x77, 0x77, 0x0, 0x0, + 0xaa, 0xaa, 0xcd, 0xaa, 0xaa, 0x40, 0x0, 0x0, + 0x0, 0x49, 0x0, 0x0, 0x0, 0x2b, 0xbb, 0xbb, + 0xde, 0xbb, 0xbb, 0xb6, + + /* U+91D1 "金" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xdc, 0x40, 0x0, 0x0, 0x0, 0x0, 0x8d, + 0x10, 0xa8, 0x0, 0x0, 0x0, 0x4d, 0x90, 0x0, + 0x8, 0xd5, 0x0, 0x3d, 0xcb, 0xbb, 0xbb, 0xbb, + 0x9a, 0xd3, 0x3, 0x1, 0x22, 0x98, 0x22, 0x10, + 0x20, 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, + 0x5, 0xdd, 0xdd, 0xee, 0xdd, 0xdd, 0x60, 0x0, + 0x5, 0x0, 0x87, 0x0, 0x50, 0x0, 0x0, 0xc, + 0x20, 0x87, 0x2, 0xd0, 0x0, 0x0, 0x5, 0x90, + 0x87, 0xa, 0x40, 0x0, 0x0, 0x0, 0x80, 0x87, + 0x8, 0x0, 0x0, 0xd, 0xdd, 0xdd, 0xfe, 0xdd, + 0xdd, 0xd0, + + /* U+91DD "針" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x90, 0x0, 0x3, 0xb0, 0x0, 0x0, 0x2e, + 0xd5, 0x0, 0x3, 0xb0, 0x0, 0x1, 0xc5, 0x2d, + 0x60, 0x3, 0xb0, 0x0, 0xc, 0x90, 0x1, 0x90, + 0x3, 0xb0, 0x0, 0x8, 0xce, 0xec, 0x10, 0x3, + 0xb0, 0x0, 0x0, 0x6, 0x60, 0x4c, 0xcd, 0xec, + 0xc8, 0xb, 0xce, 0xec, 0x70, 0x3, 0xb0, 0x0, + 0x0, 0x6, 0x62, 0x10, 0x3, 0xb0, 0x0, 0x5, + 0x56, 0x6a, 0x20, 0x3, 0xb0, 0x0, 0x1, 0x96, + 0x6b, 0x0, 0x3, 0xb0, 0x0, 0x0, 0x66, 0x76, + 0x30, 0x3, 0xb0, 0x0, 0x6, 0x9d, 0xc9, 0x40, + 0x3, 0xb0, 0x0, 0x6, 0x30, 0x0, 0x0, 0x3, + 0xb0, 0x0, + + /* U+9244 "鉄" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x40, 0x3, 0x1e, 0x0, 0x0, 0x0, 0x4e, + 0xc1, 0xb, 0x2e, 0x0, 0x0, 0x2, 0xd2, 0x5d, + 0x1e, 0x2e, 0x32, 0x10, 0x2e, 0x50, 0x5, 0x5f, + 0xdf, 0xdd, 0x90, 0x17, 0xde, 0xd8, 0x77, 0xe, + 0x0, 0x0, 0x0, 0x9, 0x20, 0x51, 0xe, 0x0, + 0x0, 0xb, 0xce, 0xdc, 0x7a, 0xaf, 0xaa, 0xa0, + 0x1, 0x9, 0x24, 0x13, 0x4f, 0x63, 0x30, 0x5, + 0x59, 0x2b, 0x0, 0x5f, 0x80, 0x0, 0x2, 0x89, + 0x66, 0x0, 0xb3, 0xd0, 0x0, 0x0, 0x49, 0x78, + 0x27, 0xa0, 0x97, 0x0, 0x9, 0xcc, 0x95, 0x8c, + 0x10, 0x1c, 0x70, 0x4, 0x0, 0x2, 0x90, 0x0, + 0x0, 0x91, + + /* U+925B "鉛" */ + 0x0, 0x7, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4f, 0x90, 0x1, 0xfd, 0xde, 0x0, 0x2, 0xd2, + 0x8c, 0x11, 0xb0, 0xd, 0x0, 0x3e, 0x40, 0x5, + 0x64, 0xa0, 0xd, 0x0, 0x38, 0xcf, 0xd8, 0x7, + 0x60, 0xd, 0x0, 0x0, 0xc, 0x10, 0x2d, 0x0, + 0xc, 0x73, 0xa, 0xae, 0xba, 0xa3, 0x0, 0x1, + 0x41, 0x2, 0x1c, 0x23, 0xb, 0xdd, 0xdd, 0x80, + 0xa, 0xc, 0x1c, 0xc, 0x10, 0x4, 0x80, 0x7, + 0x4c, 0x57, 0xc, 0x10, 0x4, 0x80, 0x2, 0x2c, + 0x57, 0x2c, 0x10, 0x4, 0x80, 0x29, 0xcd, 0xa6, + 0x1c, 0xdc, 0xcd, 0x80, 0x14, 0x10, 0x0, 0xc, + 0x20, 0x5, 0x80, + + /* U+9280 "銀" */ + 0x0, 0x5, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3f, 0x70, 0x2f, 0xdd, 0xdd, 0xe0, 0x2, 0xc2, + 0xa9, 0x2b, 0x0, 0x0, 0xe0, 0x2e, 0x40, 0x9, + 0x4d, 0x44, 0x44, 0xe0, 0x18, 0xcf, 0xc5, 0x2d, + 0x77, 0x77, 0xe0, 0x0, 0xd, 0x0, 0x2b, 0x0, + 0x0, 0xe0, 0x1b, 0xbf, 0xba, 0x2f, 0xdd, 0xdd, + 0xe0, 0x2, 0x1d, 0x14, 0x2b, 0xb, 0x0, 0x31, + 0x9, 0x2d, 0x2a, 0x2b, 0x5, 0x67, 0xc2, 0x5, + 0x5d, 0x64, 0x2b, 0x0, 0xe9, 0x0, 0x1, 0x5d, + 0x44, 0x2b, 0x0, 0x7b, 0x0, 0x6, 0xaf, 0xc9, + 0x3d, 0x8c, 0x2a, 0xb1, 0x7, 0x40, 0x0, 0x8b, + 0x61, 0x0, 0x86, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9322 "錢" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x0, 0xb2, 0x97, 0x0, 0x0, 0x8e, + 0x80, 0x0, 0x94, 0x7, 0x30, 0x4, 0xd1, 0xa9, + 0x4a, 0xde, 0xee, 0xc4, 0x2e, 0x30, 0x8, 0x24, + 0x3c, 0x9, 0x20, 0x29, 0xcf, 0xc4, 0x0, 0xa, + 0xc4, 0x11, 0x0, 0xb, 0x0, 0x39, 0xb7, 0xa8, + 0x85, 0x1c, 0xcf, 0xca, 0x22, 0x90, 0x77, 0x40, + 0x1, 0xb, 0x2, 0x0, 0xd0, 0x29, 0x30, 0xa, + 0xb, 0x46, 0x48, 0xec, 0xcc, 0xc5, 0x7, 0x3b, + 0x82, 0x23, 0x69, 0xa, 0x20, 0x2, 0x2c, 0x54, + 0x0, 0xc, 0xc4, 0x1, 0x17, 0xbe, 0xa5, 0x4, + 0xab, 0xd2, 0x29, 0x6, 0x20, 0x0, 0x99, 0x30, + 0x3c, 0xd3, + + /* U+932F "錯" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x0, 0x2, 0xa0, 0xd, 0x0, 0x0, 0x7e, + 0x80, 0x2, 0xa0, 0xd, 0x0, 0x4, 0xd1, 0x9a, + 0x7d, 0xfd, 0xdf, 0xd1, 0x3f, 0x41, 0x27, 0x2, + 0xa0, 0xd, 0x0, 0x17, 0xbe, 0xb4, 0x2, 0xa0, + 0xd, 0x0, 0x0, 0xc, 0x0, 0xad, 0xdd, 0xdd, + 0xd6, 0xa, 0xae, 0xa8, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x2c, 0x23, 0xe, 0xcc, 0xcd, 0xa0, 0xa, + 0xc, 0x37, 0xd, 0x0, 0x3, 0xa0, 0x7, 0x2c, + 0x73, 0xe, 0xcc, 0xcd, 0xa0, 0x3, 0x3c, 0x42, + 0xd, 0x0, 0x3, 0xa0, 0x3, 0x7e, 0xd9, 0xd, + 0x22, 0x25, 0xa0, 0x19, 0x62, 0x0, 0xe, 0xaa, + 0xab, 0x90, + + /* U+9332 "録" */ + 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5f, 0x40, 0x3c, 0xcc, 0xcd, 0xa0, 0x2, 0xd3, + 0xc8, 0x0, 0x0, 0x2, 0xa0, 0x2e, 0x40, 0xa, + 0x1c, 0xcc, 0xcc, 0xa0, 0x29, 0xcf, 0xc4, 0x0, + 0x0, 0x2, 0xa0, 0x0, 0xb, 0x0, 0xab, 0xbc, + 0xbb, 0xd7, 0x1c, 0xcf, 0xca, 0x21, 0xd, 0x0, + 0x22, 0x1, 0xb, 0x2, 0x2c, 0xd, 0x3, 0xc2, + 0xa, 0xb, 0x46, 0x4, 0x5e, 0xca, 0x0, 0x7, + 0x2b, 0x82, 0x2, 0xcf, 0x98, 0x0, 0x3, 0x2c, + 0x54, 0x7d, 0x2d, 0xa, 0xa1, 0x17, 0xae, 0xb7, + 0x91, 0xd, 0x0, 0x59, 0x6, 0x20, 0x0, 0x1, + 0xcc, 0x0, 0x0, + + /* U+9577 "長" */ + 0x0, 0xa, 0xdc, 0xcc, 0xcc, 0xcb, 0x0, 0x0, + 0xa, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, + 0xdc, 0xcc, 0xcc, 0xc5, 0x0, 0x0, 0xa, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xdc, 0xcc, + 0xcc, 0xc5, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x1d, 0xdf, 0xdd, 0xee, 0xdd, 0xdd, + 0xd5, 0x0, 0xc, 0x10, 0x4b, 0x0, 0x1b, 0x40, + 0x0, 0xc, 0x10, 0xa, 0x87, 0xc4, 0x0, 0x0, + 0xc, 0x10, 0x1, 0xbd, 0x10, 0x0, 0x0, 0xe, + 0x68, 0xcb, 0x7, 0xe8, 0x30, 0x0, 0x4d, 0x94, + 0x0, 0x0, 0x17, 0xc7, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+9589 "閉" */ + 0xdc, 0xbb, 0xe0, 0xbc, 0xbb, 0xcd, 0xd1, 0x0, + 0xe0, 0xb2, 0x0, 0x1d, 0xdb, 0xbb, 0xe0, 0xbc, + 0xbb, 0xbd, 0xd1, 0x0, 0xe0, 0xb2, 0x0, 0x1d, + 0xdb, 0xbb, 0xa0, 0x8b, 0xbb, 0xbd, 0xd1, 0x0, + 0x0, 0x90, 0x0, 0x1d, 0xd1, 0xbc, 0xcc, 0xfc, + 0xc2, 0x1d, 0xd1, 0x0, 0xa, 0xf0, 0x0, 0x1d, + 0xd1, 0x0, 0x97, 0xd0, 0x0, 0x1d, 0xd1, 0x1b, + 0x80, 0xd0, 0x0, 0x1d, 0xd1, 0xd5, 0x0, 0xd0, + 0x0, 0x2d, 0xd1, 0x0, 0x3c, 0xb0, 0xce, 0xe8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+958B "開" */ + 0xeb, 0xbb, 0xe1, 0x9d, 0xbb, 0xcc, 0xe0, 0x0, + 0xb1, 0x95, 0x0, 0x1c, 0xea, 0xaa, 0xe1, 0x9c, + 0xaa, 0xbc, 0xe3, 0x33, 0xc1, 0x97, 0x22, 0x4c, + 0xe6, 0x66, 0x60, 0x47, 0x77, 0x8c, 0xe0, 0x8c, + 0xcc, 0xcc, 0xc3, 0x1c, 0xe0, 0x2, 0xb0, 0x3a, + 0x0, 0x1c, 0xe0, 0x2, 0xb0, 0x3a, 0x0, 0x1c, + 0xe0, 0xcd, 0xec, 0xde, 0xc7, 0x1c, 0xe0, 0x6, + 0x70, 0x3a, 0x0, 0x1c, 0xe0, 0xc, 0x20, 0x3a, + 0x0, 0x2c, 0xe0, 0x85, 0x0, 0x3a, 0x3e, 0xe8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9593 "間" */ + 0xdc, 0xbb, 0xf0, 0xbc, 0xbb, 0xcd, 0xd1, 0x0, + 0xc0, 0xb2, 0x0, 0x1d, 0xdb, 0xbb, 0xf0, 0xbc, + 0xbb, 0xbd, 0xd1, 0x0, 0xc0, 0xb2, 0x0, 0x1d, + 0xdb, 0xbb, 0xb0, 0x8b, 0xbb, 0xbd, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0x1d, 0xd1, 0xd, 0xbb, 0xbe, + 0x50, 0x1d, 0xd1, 0xd, 0x0, 0xa, 0x50, 0x1d, + 0xd1, 0xd, 0xbb, 0xbe, 0x50, 0x1d, 0xd1, 0xd, + 0x0, 0xa, 0x50, 0x1d, 0xd1, 0xd, 0xbb, 0xbc, + 0x40, 0x1d, 0xd1, 0x9, 0x0, 0x0, 0x7e, 0xe8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+95A2 "関" */ + 0xeb, 0xbb, 0xf1, 0x9c, 0xbb, 0xbc, 0xe0, 0x0, + 0xc1, 0x94, 0x0, 0x1c, 0xea, 0xaa, 0xe1, 0x9c, + 0xaa, 0xbc, 0xe1, 0x11, 0xd1, 0x95, 0x11, 0x3c, + 0xe9, 0x9a, 0x90, 0x5b, 0x99, 0xac, 0xe0, 0x7, + 0x60, 0x1c, 0x0, 0x1c, 0xe0, 0x8b, 0xbe, 0xbb, + 0xb2, 0x1c, 0xe0, 0x0, 0xc, 0x10, 0x0, 0x1c, + 0xe0, 0xab, 0xcf, 0xdb, 0xb5, 0x1c, 0xe0, 0x0, + 0x99, 0xc5, 0x0, 0x1c, 0xe0, 0x6c, 0x70, 0xa, + 0x80, 0x1c, 0xe0, 0x30, 0x0, 0x0, 0x2c, 0xd8, + + /* U+95DC "關" */ + 0xeb, 0xbb, 0xf0, 0x8c, 0xbb, 0xbe, 0xe4, 0x44, + 0xe0, 0x88, 0x44, 0x4e, 0xe4, 0x44, 0xe0, 0x88, + 0x44, 0x4e, 0xeb, 0xbb, 0xf0, 0x8c, 0xbb, 0xbe, + 0xe0, 0x19, 0x10, 0x29, 0x10, 0xe, 0xe0, 0xd9, + 0xa1, 0xd9, 0xa0, 0xe, 0xe0, 0x4a, 0x70, 0x4a, + 0x70, 0xe, 0xe1, 0xfb, 0xb7, 0xfb, 0xc4, 0xe, + 0xe0, 0x60, 0x63, 0x80, 0x61, 0xe, 0xe0, 0xa4, + 0xb2, 0xb4, 0xc0, 0xe, 0xe0, 0x25, 0xe0, 0xb3, + 0x80, 0xe, 0xe0, 0x1b, 0x30, 0xb0, 0xc, 0xe9, + + /* U+95F0 "闰" */ + 0x15, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x60, + 0xdd, 0xdd, 0xdd, 0xde, 0x0, 0xd3, 0x0, 0x0, + 0x0, 0xe, 0x90, 0x10, 0x0, 0x0, 0x0, 0xe, + 0xe0, 0x7c, 0xce, 0xec, 0xc6, 0xe, 0xe0, 0x0, + 0x5, 0x80, 0x0, 0xe, 0xe0, 0x0, 0x5, 0x80, + 0x0, 0xe, 0xe0, 0x1c, 0xcd, 0xec, 0xc0, 0xe, + 0xe0, 0x0, 0x5, 0x80, 0x0, 0xe, 0xe0, 0x0, + 0x5, 0x80, 0x0, 0xe, 0xe0, 0xbc, 0xcd, 0xec, + 0xc7, 0xe, 0xe0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0xe0, 0x0, 0x0, 0x0, 0x8e, 0xe9, + + /* U+9633 "阳" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdd, 0xdf, + 0x2d, 0xed, 0xdd, 0xeb, 0xd0, 0x3a, 0xd, 0x0, + 0x0, 0x2b, 0xd0, 0xb2, 0xd, 0x0, 0x0, 0x2b, + 0xd3, 0xa0, 0xd, 0x0, 0x0, 0x2b, 0xd1, 0xc3, + 0xd, 0x0, 0x0, 0x2b, 0xd0, 0x1d, 0xd, 0xee, + 0xee, 0xeb, 0xd0, 0xb, 0x2d, 0x0, 0x0, 0x2b, + 0xd0, 0xe, 0x2d, 0x0, 0x0, 0x2b, 0xd8, 0xd8, + 0xd, 0x0, 0x0, 0x2b, 0xd0, 0x0, 0xd, 0x0, + 0x0, 0x2b, 0xd0, 0x0, 0xd, 0xee, 0xee, 0xeb, + 0xd0, 0x0, 0xd, 0x0, 0x0, 0x2a, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+9644 "附" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1c, 0x0, 0xe, 0x0, 0xdd, 0xdb, 0x6, + 0x80, 0x0, 0xe0, 0xd, 0x6, 0x70, 0xc2, 0x0, + 0xe, 0x0, 0xd0, 0xb1, 0x4f, 0x4b, 0xbb, 0xfb, + 0x3d, 0x1b, 0xe, 0xe1, 0x22, 0x2e, 0x20, 0xd0, + 0xc7, 0x8d, 0x1, 0x0, 0xe0, 0xd, 0x5, 0x80, + 0xd0, 0xc1, 0xe, 0x0, 0xd0, 0x2b, 0xd, 0x5, + 0x80, 0xe0, 0xd, 0x2, 0xb0, 0xd0, 0xd, 0xe, + 0x0, 0xd5, 0xd5, 0xd, 0x0, 0x20, 0xe0, 0xd, + 0x0, 0x0, 0xd0, 0x0, 0xe, 0x0, 0xd0, 0x0, + 0xd, 0x0, 0x0, 0xe0, 0xd, 0x0, 0x0, 0xc0, + 0x9, 0xeb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+964D "降" */ + 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0xd, 0xdd, + 0xe0, 0xb, 0xeb, 0xbb, 0x10, 0xd0, 0x58, 0x1b, + 0xd2, 0x7, 0xd0, 0xd, 0xc, 0x19, 0x53, 0xd7, + 0xd2, 0x0, 0xd3, 0xb0, 0x0, 0x2c, 0xf8, 0x0, + 0xd, 0xb, 0x36, 0xbc, 0x41, 0x8d, 0xa2, 0xd0, + 0x2b, 0x62, 0x0, 0xe0, 0x4, 0xd, 0x0, 0xd3, + 0xdd, 0xdf, 0xdd, 0x90, 0xd1, 0x2d, 0x6, 0x0, + 0xe0, 0x0, 0xd, 0x5b, 0x43, 0xa0, 0xe, 0x0, + 0x0, 0xd0, 0x0, 0x7d, 0xdd, 0xfd, 0xdd, 0x2d, + 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0xd0, 0x0, + 0x0, 0x0, 0xe0, 0x0, 0x0, + + /* U+9650 "限" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xdd, + 0xf1, 0xed, 0xdd, 0xdf, 0x0, 0xd0, 0x1c, 0xe, + 0x0, 0x0, 0xe0, 0xd, 0x8, 0x50, 0xfa, 0xaa, + 0xaf, 0x0, 0xd0, 0xd0, 0xe, 0x11, 0x11, 0xe0, + 0xd, 0x7, 0x60, 0xe0, 0x0, 0xe, 0x0, 0xd0, + 0xd, 0xf, 0xdd, 0xdd, 0xf0, 0xd, 0x0, 0xc1, + 0xe0, 0x76, 0x0, 0x30, 0xd0, 0xd, 0x1e, 0x2, + 0xc2, 0xc6, 0xd, 0x2d, 0x70, 0xe0, 0xa, 0xc3, + 0x0, 0xd0, 0x0, 0xe, 0x0, 0x2d, 0x10, 0xd, + 0x0, 0x0, 0xf6, 0xa6, 0x5d, 0x40, 0xd0, 0x0, + 0x4d, 0x83, 0x0, 0x3a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+9662 "院" */ + 0x0, 0x0, 0x0, 0x6, 0x20, 0x0, 0xd, 0xdd, + 0xe0, 0x0, 0x5a, 0x0, 0x0, 0xd0, 0x49, 0xad, + 0xdd, 0xdd, 0xdf, 0x3d, 0xb, 0x2a, 0x30, 0x0, + 0x0, 0xa3, 0xd1, 0xc0, 0x47, 0xbb, 0xbb, 0xb5, + 0x1d, 0xa, 0x40, 0x11, 0x11, 0x11, 0x0, 0xd0, + 0x2b, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0xd7, + 0xde, 0xed, 0xfd, 0xd4, 0xd0, 0x1d, 0x0, 0xb3, + 0x1c, 0x0, 0xd, 0x4c, 0x50, 0xe, 0x1, 0xc0, + 0x0, 0xd0, 0x0, 0x5, 0xb0, 0x1c, 0x3, 0x2d, + 0x0, 0x4, 0xe2, 0x1, 0xc0, 0x66, 0xd0, 0x7, + 0xc3, 0x0, 0xd, 0xde, 0x22, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+9664 "除" */ + 0x0, 0x0, 0x0, 0x0, 0x70, 0x0, 0xd, 0xde, + 0xd0, 0x0, 0x9e, 0x30, 0x0, 0xd0, 0x67, 0x0, + 0x9a, 0x2d, 0x40, 0xd, 0xc, 0x3, 0xd8, 0x0, + 0x1c, 0x91, 0xd3, 0xa0, 0xa8, 0xaa, 0xaa, 0xa7, + 0x3d, 0xb, 0x30, 0x12, 0x4d, 0x22, 0x0, 0xd0, + 0x3a, 0x0, 0x1, 0xd0, 0x0, 0xd, 0x0, 0xdb, + 0xdd, 0xdf, 0xdd, 0xd4, 0xd0, 0x2c, 0x11, 0x12, + 0xd1, 0x21, 0xd, 0x7c, 0x40, 0x94, 0x1d, 0x1c, + 0x10, 0xd0, 0x0, 0x4c, 0x1, 0xd0, 0x4b, 0xd, + 0x0, 0x1d, 0x10, 0x1d, 0x0, 0x94, 0xd0, 0x0, + 0x0, 0xcd, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+9678 "陸" */ + 0x0, 0x0, 0x0, 0xb, 0x30, 0x0, 0xd, 0xdd, + 0xe0, 0x11, 0xb4, 0x11, 0x0, 0xd0, 0x49, 0x5b, + 0xbe, 0xcb, 0xb4, 0xd, 0xa, 0x30, 0x0, 0xb3, + 0x0, 0x0, 0xd1, 0xc0, 0xdd, 0xdf, 0xed, 0xdd, + 0xd, 0xb, 0x30, 0x6, 0x2, 0x70, 0x0, 0xd0, + 0x3a, 0xa, 0x70, 0x8, 0xb0, 0xd, 0x0, 0xda, + 0x60, 0x61, 0x5, 0x80, 0xd0, 0x1d, 0x10, 0xb, + 0x30, 0x0, 0xd, 0x4c, 0x57, 0xdd, 0xfd, 0xdd, + 0x50, 0xd0, 0x0, 0x0, 0xb, 0x30, 0x0, 0xd, + 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, 0xd0, 0xb, + 0xdd, 0xdf, 0xed, 0xdd, 0x20, + + /* U+967D "陽" */ + 0xdd, 0xdd, 0xd, 0xbb, 0xbb, 0xf0, 0xd, 0x4, + 0x90, 0xd0, 0x0, 0xd, 0x0, 0xd0, 0x93, 0xd, + 0xaa, 0xaa, 0xf0, 0xd, 0xc, 0x0, 0xd4, 0x44, + 0x4e, 0x0, 0xd0, 0xc1, 0x5, 0x66, 0x66, 0x60, + 0xd, 0x4, 0xac, 0xcc, 0xcc, 0xcc, 0xc2, 0xd0, + 0xd, 0x8, 0x60, 0x0, 0x0, 0xd, 0x1, 0xe2, + 0xed, 0xed, 0xed, 0xa0, 0xd4, 0xc9, 0xc2, 0x94, + 0x57, 0x49, 0xd, 0x0, 0x22, 0x4a, 0xc, 0x15, + 0x80, 0xd0, 0x0, 0x5b, 0x9, 0x60, 0x85, 0xd, + 0x0, 0x7, 0x3, 0x80, 0xcd, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+968E "階" */ + 0x0, 0x0, 0x58, 0x0, 0xd0, 0x0, 0xd, 0xdd, + 0xd5, 0x80, 0xd, 0x0, 0x51, 0xc0, 0x48, 0x5e, + 0xdd, 0xd7, 0xb8, 0x1c, 0x9, 0x25, 0x80, 0xd, + 0x60, 0x0, 0xc0, 0xb0, 0x68, 0x2, 0xd1, 0x2, + 0x8c, 0x9, 0x2b, 0xec, 0x9b, 0xa9, 0xb6, 0xc0, + 0x2a, 0x31, 0xb, 0x22, 0x21, 0xc, 0x0, 0xc2, + 0xcc, 0xfc, 0xcc, 0x90, 0xc1, 0x5c, 0x2b, 0x0, + 0x0, 0x3b, 0xc, 0x18, 0x22, 0xea, 0xaa, 0xab, + 0xb0, 0xc0, 0x0, 0x2b, 0x11, 0x11, 0x4b, 0xc, + 0x0, 0x2, 0xb0, 0x0, 0x3, 0xb0, 0xc0, 0x0, + 0x2e, 0xcc, 0xcc, 0xcb, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+969B "際" */ + 0x0, 0x0, 0x4, 0x20, 0x20, 0x0, 0xd, 0xde, + 0xc0, 0xdb, 0xac, 0x88, 0x92, 0xd0, 0x57, 0x68, + 0xb, 0x77, 0x2d, 0x2d, 0xb, 0x5c, 0x3b, 0x82, + 0xb6, 0x90, 0xd1, 0xb1, 0x66, 0xb1, 0xa, 0xc0, + 0xd, 0xc, 0x10, 0xb6, 0x0, 0x1c, 0x10, 0xd0, + 0x49, 0xa9, 0xcc, 0xcc, 0x9c, 0x2d, 0x0, 0xc3, + 0x0, 0x0, 0x0, 0x21, 0xd0, 0x2c, 0x5c, 0xcd, + 0xdc, 0xca, 0xd, 0x5c, 0x40, 0x20, 0x49, 0x2, + 0x0, 0xd0, 0x0, 0x3b, 0x4, 0x90, 0xa5, 0xd, + 0x0, 0xd, 0x20, 0x49, 0x0, 0xd1, 0xd0, 0x0, + 0x20, 0x9d, 0x60, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+969C "障" */ + 0x0, 0x0, 0x0, 0x3, 0x40, 0x0, 0xf, 0xdd, + 0xe5, 0xcc, 0xde, 0xcc, 0x60, 0xd0, 0x48, 0x0, + 0xc0, 0x8, 0x0, 0xd, 0x9, 0x38, 0x8d, 0x98, + 0xd8, 0x80, 0xd0, 0xb0, 0x55, 0x55, 0x55, 0x55, + 0xd, 0xa, 0x30, 0xca, 0xaa, 0xac, 0x0, 0xd0, + 0x2a, 0xe, 0x33, 0x33, 0xe0, 0xd, 0x0, 0xd0, + 0xe6, 0x66, 0x6f, 0x0, 0xd1, 0x4d, 0xf, 0xaa, + 0xaa, 0xf0, 0xd, 0x2a, 0x40, 0x0, 0x1d, 0x0, + 0x0, 0xd0, 0x1, 0xcc, 0xcd, 0xfc, 0xcc, 0x2d, + 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0xd0, 0x0, + 0x0, 0x1, 0xd0, 0x0, 0x0, + + /* U+96A3 "隣" */ + 0x0, 0x0, 0x4, 0x2, 0xb0, 0x20, 0xd, 0xde, + 0xa0, 0xb5, 0x2b, 0xc, 0x10, 0xd0, 0x86, 0x3, + 0x92, 0xc5, 0x40, 0xd, 0xd, 0xa, 0xbc, 0xff, + 0xdb, 0xb0, 0xd4, 0x90, 0x1, 0xa9, 0xca, 0x50, + 0xd, 0x2c, 0x8, 0xb3, 0x2b, 0x7, 0xc1, 0xd0, + 0x76, 0x9, 0x40, 0x20, 0xb0, 0xd, 0x3, 0xa1, + 0xfc, 0xb7, 0xbf, 0xb2, 0xd0, 0x5a, 0xa4, 0xc, + 0x32, 0xd0, 0xd, 0x7a, 0x68, 0x97, 0x87, 0x2d, + 0x0, 0xd0, 0x0, 0x3, 0xe0, 0x9c, 0xfc, 0x4d, + 0x0, 0x1, 0xc3, 0x0, 0xd, 0x0, 0xd0, 0x0, + 0xc3, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+96A8 "隨" */ + 0x0, 0x0, 0x0, 0x1, 0x50, 0x0, 0xd, 0xde, + 0xb7, 0x5, 0x9a, 0x55, 0x51, 0xc0, 0x76, 0xa3, + 0x4e, 0x54, 0x44, 0x1c, 0xc, 0x2, 0x45, 0xaa, + 0xeb, 0x80, 0xc2, 0xa0, 0x2, 0xc6, 0x6d, 0x76, + 0x2c, 0xc, 0x6d, 0x71, 0x33, 0x33, 0x31, 0xc0, + 0x67, 0x48, 0x1d, 0xaa, 0xb9, 0xc, 0x2, 0xa4, + 0x81, 0xd6, 0x68, 0xa0, 0xc0, 0x3a, 0x48, 0x1c, + 0x33, 0x6a, 0xc, 0x6c, 0x34, 0x81, 0xea, 0xab, + 0xa0, 0xc0, 0x0, 0x48, 0x1b, 0x0, 0x49, 0xc, + 0x0, 0x1a, 0xa7, 0x80, 0x29, 0x30, 0xc0, 0x7, + 0x30, 0x5b, 0xdd, 0xdd, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+96BB "隻" */ + 0x0, 0x7, 0x20, 0x24, 0x0, 0x0, 0x0, 0x4, + 0xd0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0xdc, 0xbb, + 0xce, 0xbb, 0xbb, 0x0, 0xbf, 0x64, 0x46, 0xc4, + 0x44, 0x20, 0x89, 0xb7, 0x55, 0x7d, 0x55, 0x53, + 0x0, 0xb, 0xba, 0xab, 0xea, 0xaa, 0x60, 0x0, + 0xb2, 0x0, 0x2b, 0x0, 0x0, 0x0, 0xb, 0xcb, + 0xbb, 0xcb, 0xbb, 0xb3, 0x1, 0x52, 0x11, 0x11, + 0x11, 0x10, 0x0, 0x9a, 0xed, 0xaa, 0xaa, 0xcd, + 0x10, 0x0, 0x2, 0xc8, 0x10, 0x6c, 0x20, 0x0, + 0x0, 0x1, 0xaf, 0xec, 0x30, 0x0, 0x3a, 0xbd, + 0xc8, 0x32, 0x7b, 0xed, 0x81, 0x31, 0x0, 0x0, + 0x0, 0x0, 0x11, + + /* U+96C6 "集" */ + 0x0, 0x3, 0x40, 0x24, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0x30, 0x1d, 0x0, 0x0, 0x0, 0x0, 0xad, + 0xcc, 0xcf, 0xcc, 0xcc, 0x40, 0xa, 0xf9, 0x44, + 0x6d, 0x44, 0x44, 0x0, 0x38, 0x99, 0x55, 0x6d, + 0x55, 0x54, 0x0, 0x0, 0x8d, 0xbb, 0xbe, 0xbb, + 0xb9, 0x0, 0x0, 0x85, 0x0, 0x1c, 0x0, 0x0, + 0x0, 0x0, 0x8d, 0xcc, 0xdd, 0xcc, 0xcc, 0xa0, + 0x0, 0x11, 0x0, 0x76, 0x0, 0x0, 0x0, 0x2c, + 0xcc, 0xce, 0xff, 0xec, 0xcc, 0xc3, 0x0, 0x1, + 0x9b, 0x99, 0xb9, 0x10, 0x0, 0x3, 0x9d, 0x50, + 0x76, 0x5, 0xca, 0x40, 0x3b, 0x40, 0x0, 0x76, + 0x0, 0x3, 0x92, + + /* U+96D1 "雑" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x48, 0x0, 0x0, 0x94, 0xb0, 0x0, 0x6, 0x8b, + 0x62, 0x2, 0xc0, 0x86, 0x0, 0x7, 0xba, 0xa6, + 0xc, 0xda, 0xaa, 0xa3, 0x0, 0xb2, 0x66, 0x7e, + 0x83, 0xc5, 0x30, 0x3, 0xb0, 0x66, 0x37, 0x60, + 0xa2, 0x0, 0x2c, 0x20, 0x4c, 0xc7, 0xca, 0xeb, + 0xa1, 0x2, 0x8, 0x40, 0x6, 0x72, 0xb4, 0x20, + 0x1c, 0xce, 0xdc, 0x96, 0x60, 0xa2, 0x0, 0x0, + 0x38, 0x43, 0x6, 0xec, 0xfd, 0xc2, 0x4, 0x88, + 0x4d, 0x6, 0x60, 0xa2, 0x0, 0x1d, 0x18, 0x47, + 0x86, 0x60, 0xa2, 0x0, 0x15, 0x8, 0x40, 0x26, + 0xca, 0xeb, 0xa4, 0x0, 0xbe, 0x20, 0x6, 0x82, + 0x22, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+96D6 "雖" */ + 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0xc, + 0xcc, 0xce, 0x1, 0xb4, 0x90, 0x0, 0xc, 0x10, + 0xd, 0x7, 0x72, 0xa4, 0x20, 0xc, 0xcb, 0xbe, + 0xd, 0x99, 0xf9, 0x90, 0x0, 0xe, 0x0, 0x8f, + 0x0, 0xe0, 0x0, 0x6, 0x6e, 0x66, 0xbd, 0x0, + 0xe0, 0x0, 0xd, 0x7e, 0x7c, 0x2d, 0xcc, 0xfc, + 0xb0, 0xb, 0xc, 0xa, 0x1d, 0x0, 0xe0, 0x0, + 0xd, 0x6d, 0x6c, 0x1d, 0x22, 0xe2, 0x20, 0x5, + 0x5e, 0x56, 0xd, 0xaa, 0xfa, 0x90, 0x0, 0xd, + 0xc, 0xd, 0x0, 0xe0, 0x0, 0x4b, 0xce, 0xcc, + 0x5d, 0xbb, 0xfb, 0xb2, 0x11, 0x0, 0x2, 0x5d, + 0x11, 0x11, 0x10, + + /* U+96D9 "雙" */ + 0x0, 0x33, 0x50, 0x0, 0x33, 0x40, 0x0, 0x0, + 0xb2, 0xb3, 0x0, 0xb2, 0xb2, 0x0, 0x4, 0xfa, + 0xeb, 0xa4, 0xfa, 0xeb, 0xa2, 0x1d, 0xe7, 0xd8, + 0x7d, 0xe7, 0xe7, 0x60, 0x2, 0xd2, 0xb3, 0x23, + 0xd2, 0xc2, 0x20, 0x0, 0xfa, 0xea, 0x70, 0xea, + 0xea, 0x90, 0x0, 0xe7, 0xd8, 0x71, 0xe7, 0xe7, + 0x73, 0x0, 0x22, 0x22, 0x20, 0x22, 0x33, 0x21, + 0x4, 0xce, 0xdc, 0xcc, 0xcc, 0xf8, 0x0, 0x0, + 0x2, 0xd4, 0x0, 0x9, 0xc0, 0x0, 0x0, 0x0, + 0x1b, 0xc6, 0xd9, 0x0, 0x0, 0x0, 0x2, 0x5a, + 0xec, 0xeb, 0x85, 0x10, 0xc, 0xeb, 0x84, 0x0, + 0x5, 0x9b, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+96E2 "離" */ + 0x0, 0x5, 0x10, 0x0, 0x23, 0x30, 0x0, 0x5, + 0x5a, 0x95, 0x51, 0x84, 0xd1, 0x0, 0x17, 0x76, + 0x77, 0x71, 0xc0, 0x65, 0x0, 0x8, 0x49, 0x86, + 0xa5, 0xfd, 0xed, 0xd3, 0x8, 0x39, 0xc4, 0xad, + 0xb0, 0xa2, 0x0, 0x8, 0x64, 0x6, 0xa5, 0xb1, + 0xa3, 0x10, 0x6, 0xbc, 0xdb, 0x70, 0xeb, 0xec, + 0xb0, 0x3, 0x38, 0x83, 0x31, 0xb0, 0xa2, 0x0, + 0xe, 0x8e, 0x88, 0xd2, 0xc2, 0xb5, 0x20, 0xc, + 0x29, 0x62, 0xa2, 0xea, 0xeb, 0xa0, 0xc, 0xaa, + 0x89, 0xa2, 0xb0, 0xa2, 0x0, 0xc, 0x0, 0x1, + 0xa2, 0xeb, 0xec, 0xb5, 0xc, 0x0, 0xb, 0xc1, + 0xc1, 0x11, 0x10, 0x1, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, + + /* U+96E3 "難" */ + 0x0, 0xc0, 0x1b, 0x0, 0x94, 0x70, 0x0, 0x3c, + 0xfb, 0xce, 0xb0, 0xd0, 0xe1, 0x0, 0x0, 0xd4, + 0x5b, 0x4, 0xa0, 0x74, 0x0, 0x0, 0x5b, 0x74, + 0xc, 0xec, 0xfd, 0xc3, 0xd, 0xad, 0xbc, 0xbf, + 0x60, 0xc1, 0x0, 0xc, 0x9, 0x24, 0xda, 0x83, + 0xd4, 0x30, 0x9, 0xae, 0xca, 0x56, 0xc9, 0xea, + 0x91, 0x6, 0x7c, 0x97, 0x46, 0x60, 0xc1, 0x0, + 0x3, 0x4b, 0x64, 0x26, 0xa6, 0xd7, 0x60, 0x4b, + 0xbe, 0xcb, 0xb6, 0xa6, 0xd7, 0x61, 0x0, 0x4e, + 0x91, 0x6, 0x60, 0xc1, 0x0, 0x3, 0xd2, 0x4c, + 0x26, 0xdb, 0xfc, 0xb4, 0x2b, 0x20, 0x2, 0x16, + 0x71, 0x11, 0x10, + + /* U+96E8 "雨" */ + 0x1e, 0xee, 0xee, 0xff, 0xee, 0xee, 0xe6, 0x0, + 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x59, 0x0, 0x0, 0x0, 0x6, 0xfe, 0xee, + 0xff, 0xee, 0xee, 0xc0, 0x6, 0x70, 0x0, 0x59, + 0x0, 0x2, 0xc0, 0x6, 0x77, 0xa2, 0x59, 0x6b, + 0x32, 0xc0, 0x6, 0x70, 0x3a, 0x59, 0x2, 0xa3, + 0xc0, 0x6, 0x73, 0x0, 0x59, 0x40, 0x2, 0xc0, + 0x6, 0x76, 0xc3, 0x59, 0x5c, 0x42, 0xc0, 0x6, + 0x70, 0x19, 0x59, 0x1, 0x92, 0xc0, 0x6, 0x70, + 0x0, 0x59, 0x0, 0x2, 0xc0, 0x6, 0x70, 0x0, + 0x48, 0x4, 0xdd, 0x70, + + /* U+96EA "雪" */ + 0x1c, 0xcc, 0xce, 0xdc, 0xcc, 0xc1, 0x22, 0x22, + 0x2c, 0x52, 0x22, 0x22, 0xea, 0xaa, 0xae, 0xba, + 0xaa, 0xae, 0xd2, 0x66, 0x3b, 0x36, 0x66, 0x1d, + 0xc1, 0x44, 0x2b, 0x34, 0x44, 0x1c, 0x7, 0xbb, + 0x6b, 0x3b, 0xbb, 0x70, 0x0, 0x0, 0x3, 0x10, + 0x0, 0x0, 0x7, 0xbb, 0xbb, 0xbb, 0xbd, 0x80, + 0x0, 0x0, 0x0, 0x0, 0x7, 0x80, 0x4, 0xbb, + 0xbb, 0xbb, 0xbd, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x80, 0xb, 0xcc, 0xcc, 0xcc, 0xcd, 0x80, + + /* U+96F2 "雲" */ + 0x1, 0xbb, 0xbb, 0xed, 0xbb, 0xbb, 0x10, 0x3, + 0x33, 0x33, 0xa8, 0x33, 0x33, 0x30, 0xd, 0x77, + 0x77, 0xba, 0x77, 0x77, 0xe0, 0xd, 0x2a, 0xa7, + 0x86, 0x8a, 0xa2, 0xd0, 0x9, 0x0, 0x0, 0x86, + 0x0, 0x0, 0x90, 0x0, 0x6a, 0xa7, 0x86, 0x8a, + 0xa6, 0x0, 0x0, 0x35, 0x55, 0x66, 0x55, 0x53, + 0x0, 0x0, 0x34, 0x44, 0x44, 0x44, 0x42, 0x0, + 0x2c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc3, 0x0, + 0x1, 0xe3, 0x0, 0xd, 0x40, 0x0, 0x0, 0x1d, + 0x50, 0x0, 0x15, 0xf4, 0x0, 0x0, 0xbf, 0xcc, + 0xcc, 0xba, 0x9e, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x0, + + /* U+96FB "電" */ + 0x1b, 0xbb, 0xbe, 0xcb, 0xbb, 0xb0, 0x5, 0x66, + 0x66, 0xd8, 0x66, 0x66, 0x40, 0xd4, 0x44, 0x4c, + 0x64, 0x44, 0x5c, 0xd, 0x39, 0x95, 0xb3, 0x89, + 0x92, 0xc0, 0x34, 0x77, 0x4b, 0x36, 0x77, 0x43, + 0x0, 0x13, 0x31, 0x72, 0x23, 0x31, 0x0, 0xb, + 0xcb, 0xbe, 0xcb, 0xbc, 0xa0, 0x0, 0xb6, 0x44, + 0xd6, 0x44, 0x7a, 0x0, 0xb, 0x65, 0x5d, 0x65, + 0x57, 0xa0, 0x0, 0xbb, 0xbb, 0xeb, 0xbb, 0xca, + 0x41, 0xa, 0x10, 0xb, 0x20, 0x0, 0xa, 0x30, + 0x0, 0x0, 0x6d, 0xcc, 0xcc, 0xc0, + + /* U+9700 "需" */ + 0x1, 0xcc, 0xcc, 0xed, 0xcc, 0xcc, 0x10, 0x6, + 0x66, 0x66, 0xba, 0x66, 0x66, 0x60, 0xd, 0x33, + 0x33, 0x98, 0x33, 0x33, 0xe0, 0xd, 0x3a, 0xa7, + 0x76, 0x8a, 0xa3, 0xe0, 0x2, 0x47, 0x75, 0x76, + 0x67, 0x74, 0x20, 0x0, 0x23, 0x32, 0x54, 0x33, + 0x32, 0x0, 0xc, 0xcc, 0xcc, 0xed, 0xcc, 0xcc, + 0xc1, 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, + 0x0, 0xfc, 0xcf, 0xcc, 0xfc, 0xce, 0x50, 0x0, + 0xe0, 0xd, 0x0, 0xc1, 0x9, 0x50, 0x0, 0xe0, + 0xd, 0x0, 0xc1, 0x9, 0x50, 0x0, 0xe0, 0xc, + 0x0, 0xb1, 0xad, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+9707 "震" */ + 0x1, 0xbb, 0xbb, 0xdd, 0xbb, 0xbb, 0x10, 0x5, + 0x66, 0x66, 0xba, 0x66, 0x66, 0x50, 0xd, 0x33, + 0x33, 0x98, 0x33, 0x33, 0xd0, 0xa, 0x29, 0x96, + 0x76, 0x79, 0x93, 0xa0, 0x0, 0x6a, 0xa7, 0x76, + 0x8a, 0xa7, 0x0, 0x0, 0xbb, 0xbb, 0xdc, 0xbb, + 0xbb, 0x80, 0x0, 0xc2, 0x44, 0x44, 0x44, 0x44, + 0x0, 0x1, 0xc2, 0x55, 0x55, 0x55, 0x55, 0x0, + 0x3, 0xeb, 0xda, 0xad, 0xba, 0xab, 0xa2, 0x5, + 0x80, 0xe0, 0x5, 0xc1, 0x5b, 0x10, 0xc, 0x31, + 0xe1, 0x35, 0x5d, 0xd5, 0x10, 0x49, 0x7, 0xeb, + 0x85, 0x10, 0x49, 0xc2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+9752 "青" */ + 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, 0x2, + 0xbb, 0xbb, 0xdd, 0xbb, 0xbb, 0x40, 0x0, 0x0, + 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x8b, 0xbb, + 0xdd, 0xbb, 0xb9, 0x0, 0x4, 0x44, 0x44, 0xa9, + 0x44, 0x44, 0x40, 0x16, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x61, 0x0, 0x1b, 0xbb, 0xbb, 0xbb, 0xb3, + 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0xa4, 0x0, + 0x0, 0x2e, 0xaa, 0xaa, 0xaa, 0xe4, 0x0, 0x0, + 0x2c, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x2e, + 0xaa, 0xaa, 0xaa, 0xe4, 0x0, 0x0, 0x2c, 0x0, + 0x0, 0x0, 0xa4, 0x0, 0x0, 0x2c, 0x0, 0x0, + 0x8b, 0xc1, 0x0, + + /* U+9759 "静" */ + 0x0, 0x9, 0x40, 0x0, 0x74, 0x0, 0x0, 0x9, + 0x9d, 0xb9, 0x70, 0xea, 0x97, 0x0, 0x2, 0x2a, + 0x62, 0x27, 0x94, 0xa9, 0x0, 0x8, 0xbe, 0xcb, + 0x8e, 0x1, 0xd0, 0x0, 0x0, 0x9, 0x40, 0xb, + 0xff, 0xff, 0xd0, 0x2b, 0xbb, 0xbb, 0xa0, 0xe, + 0x0, 0xd0, 0x2, 0x77, 0x77, 0x37, 0x7f, 0x77, + 0xe5, 0x6, 0x83, 0x3b, 0x44, 0x4e, 0x44, 0xe3, + 0x6, 0xdb, 0xbe, 0x31, 0x2e, 0x22, 0xd0, 0x6, + 0x60, 0x9, 0x36, 0xbf, 0xbb, 0xd0, 0x6, 0xda, + 0xae, 0x30, 0xe, 0x0, 0x30, 0x6, 0x60, 0x9, + 0x30, 0xe, 0x0, 0x0, 0x6, 0x60, 0xbd, 0x14, + 0xdc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+975E "非" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0xe1, 0x0, 0x0, 0x0, 0x0, + 0xf, 0x0, 0xe1, 0x0, 0x0, 0xa, 0xcc, 0xcf, + 0x0, 0xec, 0xcc, 0xc1, 0x1, 0x22, 0x2f, 0x0, + 0xe3, 0x22, 0x20, 0x0, 0x0, 0xf, 0x0, 0xe1, + 0x0, 0x0, 0x2, 0x33, 0x3f, 0x0, 0xe4, 0x22, + 0x20, 0x7, 0xaa, 0xaf, 0x0, 0xeb, 0xbb, 0x90, + 0x0, 0x0, 0xf, 0x0, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0xe1, 0x0, 0x0, 0x2e, 0xee, + 0xef, 0x0, 0xee, 0xee, 0xe5, 0x0, 0x0, 0xf, + 0x0, 0xe1, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, + 0xe1, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0xe1, + 0x0, 0x0, + + /* U+9762 "面" */ + 0x2e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe2, 0x0, + 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe0, 0x0, 0x0, 0x0, 0x8, 0xed, 0xee, + 0xdd, 0xfe, 0xde, 0x80, 0x8, 0x60, 0x75, 0x0, + 0x85, 0x6, 0x80, 0x8, 0x60, 0x7d, 0xbb, 0xd5, + 0x6, 0x80, 0x8, 0x60, 0x76, 0x0, 0x85, 0x6, + 0x80, 0x8, 0x60, 0x75, 0x0, 0x85, 0x6, 0x80, + 0x8, 0x60, 0x7d, 0xcc, 0xe5, 0x6, 0x80, 0x8, + 0x60, 0x75, 0x0, 0x85, 0x6, 0x80, 0x8, 0xdb, + 0xdd, 0xbb, 0xed, 0xbd, 0x80, 0x8, 0x71, 0x11, + 0x11, 0x11, 0x18, 0x80, + + /* U+9769 "革" */ + 0x0, 0x0, 0xe0, 0x0, 0xa, 0x40, 0x0, 0x9, + 0xbb, 0xfb, 0xbb, 0xbe, 0xcb, 0xb2, 0x1, 0x11, + 0xe2, 0x11, 0x1b, 0x51, 0x10, 0x0, 0x0, 0xe9, + 0x99, 0x9d, 0x40, 0x0, 0x0, 0x0, 0x22, 0x7b, + 0x22, 0x0, 0x0, 0x0, 0x6c, 0xcc, 0xde, 0xcc, + 0xcc, 0x0, 0x0, 0x86, 0x0, 0x5a, 0x0, 0xf, + 0x0, 0x0, 0x86, 0x0, 0x5a, 0x0, 0xf, 0x0, + 0x0, 0x6c, 0xcc, 0xde, 0xcc, 0xcc, 0x0, 0x0, + 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0x1d, 0xdd, + 0xdd, 0xef, 0xdd, 0xdd, 0xd6, 0x0, 0x0, 0x0, + 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, + 0x0, 0x0, 0x0, + + /* U+9774 "靴" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x70, 0xc0, 0x2, 0xb0, 0xd0, 0x0, 0x3b, 0xc9, + 0xe9, 0x7, 0x70, 0xd0, 0x0, 0x6, 0x82, 0xd2, + 0xc, 0x20, 0xd0, 0x10, 0x4, 0xc9, 0xd0, 0x3f, + 0x0, 0xd0, 0xc4, 0x0, 0x4c, 0x20, 0xcf, 0x0, + 0xd8, 0xa0, 0xb, 0xce, 0xb9, 0xbe, 0x0, 0xfd, + 0x10, 0xb, 0xa, 0x47, 0x1d, 0x4, 0xf2, 0x0, + 0xb, 0xa, 0x47, 0xd, 0x6d, 0xd0, 0x0, 0xb, + 0xce, 0xc5, 0xd, 0x41, 0xd0, 0x0, 0x0, 0x1a, + 0x0, 0xd, 0x0, 0xd0, 0x0, 0x4d, 0xdf, 0xdc, + 0xd, 0x0, 0xd0, 0x8, 0x0, 0x1a, 0x0, 0xd, + 0x0, 0xe0, 0x1a, 0x0, 0x1a, 0x0, 0xd, 0x0, + 0xbe, 0xe5, 0x0, 0x1, 0x0, 0x2, 0x0, 0x0, + 0x0, + + /* U+97F3 "音" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, 0x4, 0xaa, + 0xaa, 0xce, 0xaa, 0xaa, 0x50, 0x1, 0x26, 0x82, + 0x22, 0x28, 0x82, 0x10, 0x0, 0x2, 0xe0, 0x0, + 0xc, 0x40, 0x0, 0x0, 0x0, 0xc3, 0x0, 0x3d, + 0x0, 0x0, 0x3d, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4e, 0xcc, 0xcc, 0xcc, 0xe6, 0x0, 0x0, + 0x4a, 0x0, 0x0, 0x0, 0x86, 0x0, 0x0, 0x4e, + 0xcc, 0xcc, 0xcc, 0xe6, 0x0, 0x0, 0x4a, 0x0, + 0x0, 0x0, 0x86, 0x0, 0x0, 0x4a, 0x0, 0x0, + 0x0, 0x96, 0x0, 0x0, 0x4e, 0xcc, 0xcc, 0xcc, + 0xe6, 0x0, + + /* U+97FF "響" */ + 0x0, 0x22, 0x0, 0x33, 0x0, 0x0, 0x0, 0x1, + 0xa3, 0x4b, 0x99, 0xd5, 0xeb, 0xe3, 0xa, 0xba, + 0xb, 0x99, 0xd5, 0xa2, 0x90, 0x5, 0xc5, 0xbc, + 0x33, 0xa5, 0xa2, 0xa1, 0x7, 0x6b, 0x7c, 0x68, + 0xd3, 0xa0, 0x57, 0x1, 0x99, 0x1f, 0xca, 0x88, + 0xa8, 0xb2, 0xb, 0x40, 0x14, 0x5a, 0x2, 0x90, + 0x0, 0x0, 0x57, 0xd9, 0x77, 0x7e, 0x87, 0x10, + 0xa, 0xaa, 0xcd, 0xaa, 0xce, 0xaa, 0xa4, 0x0, + 0x5, 0x55, 0x55, 0x55, 0x52, 0x0, 0x0, 0x1d, + 0x44, 0x44, 0x44, 0x88, 0x0, 0x0, 0x1e, 0x88, + 0x88, 0x88, 0xb8, 0x0, 0x0, 0x1e, 0x99, 0x99, + 0x99, 0xb7, 0x0, + + /* U+9803 "頃" */ + 0xd, 0x0, 0x1c, 0xcc, 0xfd, 0xcc, 0x80, 0xd, + 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, 0xd, 0x0, + 0x7, 0xcc, 0xeb, 0xbc, 0x20, 0xf, 0xcc, 0xa9, + 0x50, 0x0, 0xb, 0x30, 0xd, 0x0, 0x9, 0xdb, + 0xbb, 0xbe, 0x30, 0xd, 0x0, 0x9, 0x50, 0x0, + 0xb, 0x30, 0xd, 0x0, 0x9, 0xcb, 0xbb, 0xbe, + 0x30, 0xd, 0x5, 0xb9, 0x50, 0x0, 0xb, 0x30, + 0x2e, 0xda, 0x39, 0x61, 0x11, 0x1c, 0x30, 0x8b, + 0x20, 0x6, 0xaa, 0xaa, 0xaa, 0x20, 0x0, 0x0, + 0x2, 0xc6, 0x3, 0xc3, 0x0, 0x0, 0x1, 0xbc, + 0x40, 0x0, 0x2c, 0x90, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x0, 0x20, + + /* U+9805 "項" */ + 0x0, 0x0, 0x4, 0xcc, 0xcf, 0xdc, 0xc7, 0x1c, + 0xdf, 0xc8, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x2b, + 0x0, 0x7c, 0xde, 0xcc, 0xc0, 0x0, 0x2b, 0x0, + 0x94, 0x0, 0x0, 0xe0, 0x0, 0x2b, 0x0, 0x9c, + 0xbb, 0xbb, 0xf0, 0x0, 0x2b, 0x0, 0x94, 0x0, + 0x0, 0xe0, 0x0, 0x2b, 0x3, 0x9b, 0xaa, 0xaa, + 0xf0, 0x0, 0x4e, 0xeb, 0x95, 0x11, 0x11, 0xe0, + 0x2c, 0xe9, 0x20, 0x95, 0x0, 0x0, 0xe0, 0x16, + 0x0, 0x0, 0x6b, 0xbb, 0xbb, 0xb0, 0x0, 0x0, + 0x0, 0x2c, 0x50, 0x5a, 0x20, 0x0, 0x0, 0x1b, + 0xc4, 0x0, 0x4, 0xd5, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, 0x11, + + /* U+9808 "須" */ + 0x0, 0x2, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3d, 0x39, 0xcc, 0xee, 0xcc, 0xc1, 0x8, 0xd2, + 0x0, 0x0, 0x97, 0x0, 0x0, 0x48, 0x0, 0x1, + 0xdb, 0xdc, 0xbc, 0x80, 0x0, 0x1, 0x61, 0xc0, + 0x0, 0x4, 0xa0, 0x0, 0x2d, 0x41, 0xfb, 0xbb, + 0xbc, 0xa0, 0x7, 0xd4, 0x1, 0xc0, 0x0, 0x4, + 0xa0, 0x29, 0x10, 0x1, 0xfb, 0xbb, 0xbc, 0xa0, + 0x0, 0x0, 0x83, 0xc0, 0x0, 0x4, 0xa0, 0x0, + 0x7, 0xa1, 0xd1, 0x11, 0x16, 0xa0, 0x0, 0x5d, + 0x0, 0x9a, 0x99, 0x99, 0x60, 0x9, 0xc2, 0x0, + 0x6c, 0x10, 0xa7, 0x0, 0x69, 0x0, 0x6d, 0x91, + 0x0, 0x7, 0xd2, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x20, + + /* U+9817 "頗" */ + 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x0, 0x2c, 0xce, 0xec, 0xc1, 0xb, 0xcf, + 0xcc, 0xa0, 0x9, 0x50, 0x0, 0xc, 0xb, 0x5, + 0x89, 0xce, 0xcc, 0xa0, 0xc, 0xb, 0x6, 0x3c, + 0x10, 0x0, 0xd0, 0xc, 0xcf, 0xdd, 0x2c, 0xcb, + 0xbb, 0xd0, 0xc, 0x20, 0xe, 0xc, 0x10, 0x0, + 0xd0, 0xc, 0x98, 0x4b, 0xc, 0xba, 0xab, 0xd0, + 0xc, 0xd, 0xe5, 0xc, 0x10, 0x0, 0xd0, 0xc, + 0x4, 0xf3, 0xc, 0x20, 0x1, 0xd0, 0x3a, 0xc, + 0x9d, 0x18, 0xba, 0xaa, 0x90, 0x77, 0x99, 0x6, + 0x33, 0xd1, 0x2b, 0x10, 0x75, 0x90, 0x0, 0xac, + 0x30, 0x4, 0xd2, 0x0, 0x0, 0x0, 0x30, 0x0, + 0x0, 0x20, + + /* U+9818 "領" */ + 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6e, 0x10, 0xbc, 0xcf, 0xdc, 0xc1, 0x1, 0xd4, + 0xd1, 0x0, 0x1d, 0x0, 0x0, 0x1d, 0x40, 0x3c, + 0x5c, 0xcd, 0xbc, 0x80, 0x95, 0x65, 0x4, 0x67, + 0x0, 0x3, 0xa0, 0x0, 0xd, 0x10, 0x5d, 0xbb, + 0xbc, 0xa0, 0x5, 0x57, 0x54, 0x57, 0x0, 0x3, + 0xa0, 0x6, 0x66, 0x9b, 0x5d, 0xbb, 0xbc, 0xa0, + 0x0, 0x0, 0x95, 0x58, 0x0, 0x3, 0xa0, 0x2, + 0x12, 0xd0, 0x58, 0x11, 0x14, 0xa0, 0x4, 0xdb, + 0x40, 0x3a, 0xaa, 0xaa, 0x70, 0x0, 0x3e, 0x10, + 0x9, 0x80, 0x69, 0x0, 0x0, 0x4, 0x66, 0xd7, + 0x0, 0x6, 0xd1, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x20, + + /* U+982D "頭" */ + 0x0, 0x0, 0x0, 0x1, 0x11, 0x11, 0x10, 0x1d, + 0xdd, 0xdd, 0x8b, 0xbe, 0xdb, 0xb5, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x40, 0x0, 0x8, 0xcc, 0xcc, + 0x1b, 0xcc, 0xcb, 0xe0, 0xa, 0x20, 0xc, 0x1b, + 0x10, 0x0, 0xe0, 0xa, 0x20, 0xc, 0x1b, 0xcb, + 0xbb, 0xf0, 0x9, 0xbb, 0xbd, 0x1b, 0x10, 0x0, + 0xe0, 0x2, 0x40, 0x35, 0xb, 0xba, 0xaa, 0xf0, + 0x1, 0xb0, 0x77, 0xb, 0x10, 0x0, 0xe0, 0x0, + 0xd0, 0xa3, 0xb, 0x20, 0x0, 0xe0, 0x0, 0x70, + 0xa5, 0x48, 0xaa, 0xaa, 0xa0, 0x18, 0xbd, 0xb8, + 0x33, 0xc1, 0x1b, 0x20, 0x6, 0x20, 0x1, 0xac, + 0x20, 0x2, 0xd5, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x11, + + /* U+983C "頼" */ + 0x0, 0x9, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0x40, 0x3d, 0xde, 0xed, 0xd6, 0xc, 0xce, + 0xdc, 0x80, 0x8, 0x60, 0x0, 0x0, 0x9, 0x40, + 0x7, 0xce, 0xcc, 0xc0, 0xb, 0xbd, 0xcc, 0x79, + 0x40, 0x0, 0xe0, 0xb, 0x8, 0x33, 0x89, 0xcb, + 0xbb, 0xf0, 0xc, 0x4a, 0x77, 0x89, 0x40, 0x0, + 0xe0, 0x5, 0x7f, 0xa6, 0x39, 0xca, 0xaa, 0xf0, + 0x0, 0x6f, 0xe3, 0x9, 0x40, 0x0, 0xe0, 0x1, + 0xca, 0x5c, 0x29, 0x40, 0x0, 0xe0, 0xb, 0x59, + 0x43, 0x56, 0xba, 0xaa, 0xa0, 0x38, 0x9, 0x40, + 0x4, 0xd2, 0xb, 0x50, 0x0, 0x9, 0x40, 0xa8, + 0x10, 0x0, 0x97, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+984C "題" */ + 0x7, 0xcb, 0xbe, 0x3b, 0xbc, 0xdb, 0xb5, 0x7, + 0x84, 0x4d, 0x11, 0x2a, 0x72, 0x20, 0x7, 0x84, + 0x4d, 0x18, 0xa7, 0x77, 0xd0, 0x7, 0xcb, 0xbe, + 0x18, 0xb8, 0x88, 0xd0, 0x0, 0x0, 0x0, 0x8, + 0x62, 0x22, 0xd0, 0x4b, 0xbc, 0xcb, 0xb8, 0xca, + 0xaa, 0xd0, 0x1, 0x28, 0x40, 0x8, 0x50, 0x0, + 0xd0, 0x6, 0x68, 0xb9, 0x76, 0xba, 0xaa, 0xa0, + 0x8, 0x78, 0x51, 0x10, 0xa2, 0xb, 0x20, 0xa, + 0xdb, 0x40, 0x2c, 0x60, 0x3, 0xd2, 0xc, 0x1d, + 0x92, 0x44, 0x0, 0x0, 0x33, 0x48, 0x0, 0x5a, + 0xcc, 0xcc, 0xcc, 0xc7, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+9854 "顔" */ + 0x0, 0x6, 0x20, 0x0, 0x0, 0x0, 0x0, 0x3, + 0x38, 0x93, 0x2c, 0xce, 0xec, 0xc3, 0x19, 0xd9, + 0x9d, 0x80, 0x7, 0x70, 0x0, 0x0, 0xd0, 0x1d, + 0x7, 0xcd, 0xcb, 0xd0, 0x4, 0xb7, 0x9a, 0x58, + 0x40, 0x0, 0xd0, 0xd, 0x76, 0x79, 0x68, 0xdb, + 0xbb, 0xf0, 0xd, 0x5, 0xb5, 0x8, 0x40, 0x0, + 0xd0, 0xd, 0x56, 0x5, 0x18, 0xcb, 0xbb, 0xf0, + 0xd, 0x0, 0x89, 0x8, 0x50, 0x0, 0xd0, 0xd, + 0x3c, 0x60, 0x8, 0x51, 0x11, 0xd0, 0x1c, 0x11, + 0x8, 0x75, 0xaa, 0xaa, 0xa0, 0x57, 0x3, 0xb7, + 0x1, 0xc3, 0x1c, 0x30, 0x52, 0xaa, 0x20, 0x7d, + 0x40, 0x2, 0xd4, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x10, + + /* U+9858 "願" */ + 0xc, 0xdd, 0xfd, 0xd8, 0xcd, 0xfc, 0xc3, 0xc, + 0x0, 0xd0, 0x0, 0x5, 0x90, 0x0, 0xc, 0x4b, + 0xeb, 0xb2, 0xcd, 0xdb, 0xb0, 0xc, 0x46, 0x0, + 0xc2, 0x90, 0x0, 0xd0, 0xc, 0x4d, 0xbb, 0xe2, + 0xeb, 0xbb, 0xe0, 0xc, 0x46, 0x0, 0xc2, 0x90, + 0x0, 0xd0, 0xd, 0x4c, 0x99, 0xe2, 0xea, 0xaa, + 0xe0, 0xc, 0x1, 0xc1, 0x12, 0xa0, 0x0, 0xd0, + 0xd, 0x37, 0xc1, 0xa2, 0xa0, 0x0, 0xd0, 0x39, + 0x74, 0xc0, 0xb3, 0xbb, 0xaa, 0x90, 0x75, 0x90, + 0xc0, 0x33, 0xb6, 0xa, 0x50, 0x51, 0x9, 0xc0, + 0x2c, 0x40, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+985E "類" */ + 0x4, 0x8, 0x41, 0x10, 0x0, 0x0, 0x0, 0x7, + 0x58, 0x48, 0x5d, 0xde, 0xed, 0xd6, 0x2, 0x79, + 0x68, 0x10, 0x9, 0x50, 0x0, 0xa, 0xbf, 0xca, + 0x87, 0xce, 0xcb, 0xc0, 0x0, 0x9c, 0xd6, 0x9, + 0x30, 0x0, 0xe0, 0x9, 0x48, 0x56, 0x89, 0xcb, + 0xbb, 0xf0, 0x0, 0x4, 0x39, 0x9, 0x30, 0x0, + 0xe0, 0x0, 0x8, 0x55, 0x69, 0xcb, 0xbb, 0xf0, + 0x1f, 0xff, 0xff, 0xd9, 0x30, 0x0, 0xe0, 0x0, + 0xb, 0x40, 0x9, 0x41, 0x11, 0xe0, 0x0, 0x1e, + 0xd4, 0x6, 0xaa, 0xaa, 0xa0, 0x2, 0xd5, 0x2c, + 0x52, 0xc2, 0x1b, 0x30, 0x1d, 0x50, 0x0, 0xac, + 0x30, 0x2, 0xc5, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x1, + + /* U+986F "顯" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0xaa, 0xaa, 0xf5, 0xcd, 0xfc, 0xc1, 0xd, 0x55, + 0x55, 0xe0, 0x4, 0xa0, 0x0, 0xd, 0x44, 0x44, + 0xe0, 0xdc, 0xdb, 0xb0, 0xd, 0xaa, 0xaa, 0xf0, + 0xc0, 0x0, 0xc0, 0x5, 0x60, 0xb, 0x0, 0xfb, + 0xbb, 0xd0, 0x1c, 0x58, 0x98, 0xb1, 0xc0, 0x0, + 0xc0, 0x17, 0xe2, 0x5b, 0x80, 0xfb, 0xbb, 0xd0, + 0x9, 0x48, 0x3a, 0x75, 0xc0, 0x0, 0xc0, 0x4f, + 0xdc, 0xdd, 0xaa, 0xc1, 0x11, 0xc0, 0x4, 0x13, + 0x40, 0x82, 0xaa, 0xaa, 0x90, 0xc, 0x29, 0x82, + 0xa2, 0x49, 0x9, 0x30, 0x58, 0xb, 0x34, 0x1a, + 0xb1, 0x1, 0xd2, 0x1, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x10, + + /* U+98A8 "風" */ + 0x0, 0xce, 0xee, 0xee, 0xee, 0xeb, 0x0, 0x0, + 0xc1, 0x0, 0x2, 0x55, 0x2c, 0x0, 0x0, 0xc5, + 0xbb, 0xfa, 0x74, 0x2c, 0x0, 0x0, 0xc1, 0x0, + 0xc1, 0x0, 0x1c, 0x0, 0x0, 0xc2, 0xdc, 0xfc, + 0xcb, 0x1c, 0x0, 0x0, 0xd1, 0xa0, 0xc1, 0xc, + 0x1c, 0x0, 0x0, 0xe1, 0xa0, 0xc1, 0xc, 0xd, + 0x0, 0x0, 0xd1, 0xec, 0xfc, 0xcc, 0xd, 0x0, + 0x3, 0xb0, 0x0, 0xc1, 0x34, 0xd, 0x0, 0x7, + 0x70, 0x0, 0xc2, 0x3d, 0x1c, 0x17, 0xd, 0x1c, + 0xdd, 0xdb, 0xab, 0x89, 0x78, 0x48, 0x0, 0x0, + 0x0, 0x0, 0x62, 0xe4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+98DB "飛" */ + 0x6, 0xdd, 0xdd, 0xdd, 0xdf, 0x8, 0x50, 0x0, + 0x0, 0x62, 0x90, 0xb, 0xa9, 0x0, 0x5, 0x9d, + 0x92, 0xe0, 0x8, 0xbc, 0x80, 0x5, 0x6a, 0x0, + 0xe0, 0x2, 0xd0, 0x40, 0x0, 0x3a, 0x0, 0xe0, + 0x0, 0x9a, 0x93, 0x4d, 0xef, 0xdd, 0xfd, 0xdd, + 0x24, 0x70, 0x0, 0x59, 0x0, 0xe0, 0xb, 0x38, + 0x80, 0x0, 0x87, 0x0, 0xe0, 0x9, 0xca, 0x0, + 0x0, 0xb4, 0x0, 0xe0, 0x7, 0xab, 0xa0, 0x1, + 0xe0, 0x0, 0xe0, 0x3, 0xb0, 0x30, 0xb, 0x70, + 0x0, 0xe0, 0x0, 0xc4, 0x27, 0x4b, 0x0, 0x0, + 0xe0, 0x0, 0x2c, 0xe3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+98DF "食" */ + 0x0, 0x0, 0x0, 0x46, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xdd, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x6b, 0x51, 0xc8, 0x0, 0x0, 0x0, 0x3c, 0x90, + 0x96, 0x8, 0xe8, 0x10, 0x2c, 0xcf, 0xcc, 0xcd, + 0xcc, 0xf9, 0xe4, 0x3, 0xe, 0x0, 0x0, 0x0, + 0xe0, 0x0, 0x0, 0xf, 0xbb, 0xbb, 0xbb, 0xe0, + 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe0, 0x0, + 0x0, 0xf, 0xcc, 0xcc, 0xcc, 0xe4, 0x0, 0x0, + 0xe, 0x0, 0x66, 0x2, 0xb7, 0x0, 0x0, 0xe, + 0x0, 0x18, 0xde, 0x30, 0x0, 0x0, 0xf, 0x47, + 0xa5, 0x2a, 0xb2, 0x0, 0x0, 0x3e, 0xa6, 0x30, + 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+98EF "飯" */ + 0x0, 0x1a, 0x0, 0x0, 0x0, 0x2, 0x30, 0x0, + 0xbb, 0xa0, 0x8, 0xab, 0xca, 0x60, 0x1b, 0x71, + 0x6c, 0x1d, 0x20, 0x0, 0x0, 0xa6, 0xc, 0x4, + 0x1d, 0x0, 0x0, 0x0, 0x8, 0xbe, 0xb8, 0xe, + 0xdd, 0xdd, 0xa0, 0xb, 0x10, 0xb, 0xd, 0xc0, + 0x3, 0x90, 0xb, 0xbb, 0xbb, 0xd, 0x93, 0x7, + 0x60, 0xb, 0x10, 0xb, 0xc, 0x48, 0xc, 0x20, + 0xb, 0xcb, 0xcb, 0x1b, 0xc, 0x4b, 0x0, 0xb, + 0x10, 0x70, 0x3a, 0x6, 0xe3, 0x0, 0xb, 0x11, + 0xc4, 0x66, 0x6, 0xf3, 0x0, 0xe, 0xcb, 0x5b, + 0xb2, 0x5c, 0x3d, 0x40, 0x29, 0x20, 0x3, 0xb4, + 0xb1, 0x2, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+98F2 "飲" */ + 0x0, 0x4, 0x90, 0x0, 0x29, 0x0, 0x0, 0x0, + 0x2, 0xdc, 0x80, 0x6, 0x90, 0x0, 0x0, 0x6, + 0xd3, 0x18, 0xc1, 0x98, 0x33, 0x32, 0x3, 0xc2, + 0x59, 0x5, 0x1d, 0xaa, 0xab, 0xb0, 0x2, 0xbc, + 0xfb, 0x75, 0xb0, 0x40, 0x67, 0x0, 0x3a, 0x0, + 0x3a, 0xc4, 0x1d, 0x9, 0x30, 0x3, 0xeb, 0xbc, + 0xa2, 0x2, 0xd0, 0x70, 0x0, 0x3a, 0x0, 0x3a, + 0x0, 0x5f, 0x20, 0x0, 0x3, 0xeb, 0xbc, 0x90, + 0x9, 0xe7, 0x0, 0x0, 0x3a, 0x1, 0x60, 0x1, + 0xe3, 0xc0, 0x0, 0x3, 0xa0, 0x3e, 0x20, 0xa8, + 0xa, 0x50, 0x0, 0x6e, 0xc9, 0x6a, 0xac, 0x0, + 0x2e, 0x30, 0x8, 0x60, 0x0, 0x9a, 0x0, 0x0, + 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+9928 "館" */ + 0x0, 0x7, 0x0, 0x0, 0x6, 0x0, 0x0, 0x9, + 0xd6, 0x0, 0x0, 0xc1, 0x0, 0x9, 0x90, 0x98, + 0xac, 0xcc, 0xcc, 0xc9, 0x81, 0xb0, 0x8b, 0x0, + 0x0, 0xb, 0x8, 0xbf, 0xb7, 0x2b, 0x99, 0x9a, + 0x20, 0xb0, 0x1, 0xa0, 0xc0, 0x0, 0xc0, 0xb, + 0xaa, 0xba, 0xc, 0x11, 0x1c, 0x0, 0xb2, 0x23, + 0xa0, 0xdb, 0xbb, 0x80, 0xb, 0x99, 0xaa, 0xc, + 0x0, 0x0, 0x0, 0xb2, 0x26, 0x10, 0xdb, 0xbb, + 0xd4, 0xb, 0x0, 0xc1, 0xc, 0x0, 0x7, 0x40, + 0xd8, 0xb8, 0x90, 0xc2, 0x22, 0x94, 0x2a, 0x30, + 0x6, 0xd, 0xaa, 0xac, 0x40, + + /* U+9996 "首" */ + 0x0, 0x4, 0x80, 0x0, 0x2, 0xa0, 0x0, 0x0, + 0x0, 0xd4, 0x0, 0xc, 0x40, 0x0, 0x1d, 0xdd, + 0xed, 0xdd, 0xef, 0xdd, 0xd5, 0x0, 0x0, 0x0, + 0x88, 0x0, 0x0, 0x0, 0x0, 0x5b, 0xbb, 0xed, + 0xbb, 0xb9, 0x0, 0x0, 0x68, 0x11, 0x11, 0x11, + 0x4c, 0x0, 0x0, 0x67, 0x0, 0x0, 0x0, 0x2c, + 0x0, 0x0, 0x6e, 0xcc, 0xcc, 0xcc, 0xdc, 0x0, + 0x0, 0x67, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, + 0x6e, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x67, + 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x6e, 0xcc, + 0xcc, 0xcc, 0xdc, 0x0, 0x0, 0x68, 0x0, 0x0, + 0x0, 0x3c, 0x0, + + /* U+9999 "香" */ + 0x0, 0x0, 0x0, 0x13, 0x58, 0xb4, 0x0, 0x0, + 0xbd, 0xdd, 0xec, 0x85, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x77, 0x0, 0x0, 0x0, 0x2b, 0xbb, 0xbb, + 0xdd, 0xbb, 0xbb, 0xb2, 0x1, 0x11, 0x4d, 0xaa, + 0xd4, 0x11, 0x10, 0x0, 0x4, 0xd2, 0x77, 0x2c, + 0x50, 0x0, 0x2, 0x9c, 0x20, 0x77, 0x1, 0xac, + 0x40, 0x2e, 0x8a, 0xaa, 0xaa, 0xaa, 0xa6, 0xb3, + 0x0, 0x1d, 0x11, 0x11, 0x11, 0xb4, 0x0, 0x0, + 0x1d, 0x11, 0x11, 0x11, 0xb4, 0x0, 0x0, 0x1e, + 0x99, 0x99, 0x99, 0xd4, 0x0, 0x0, 0x1c, 0x0, + 0x0, 0x0, 0xa4, 0x0, 0x0, 0x1f, 0xcc, 0xcc, + 0xcc, 0xe4, 0x0, + + /* U+99C4 "駄" */ + 0x0, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0xd, + 0xce, 0xdc, 0x20, 0xe, 0x0, 0x0, 0xd, 0xa, + 0x20, 0x0, 0xe, 0x0, 0x0, 0xd, 0xbe, 0xcb, + 0x0, 0xe, 0x0, 0x0, 0xd, 0xa, 0x20, 0x7e, + 0xef, 0xee, 0xe1, 0xd, 0xbe, 0xcb, 0x0, 0xf, + 0x70, 0x0, 0xd, 0xa, 0x20, 0x0, 0x2e, 0xa0, + 0x0, 0xd, 0xce, 0xcc, 0x40, 0x67, 0xc0, 0x0, + 0x0, 0x1, 0x48, 0x40, 0xa3, 0xa2, 0x0, 0x9, + 0x88, 0x9a, 0x31, 0xd1, 0x58, 0x0, 0x37, 0x78, + 0x2d, 0x19, 0x9c, 0x2e, 0x0, 0x63, 0x40, 0xd, + 0x5c, 0x7, 0x98, 0x90, 0x0, 0x8, 0xc9, 0xa2, + 0x0, 0x20, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+99C5 "駅" */ + 0xb, 0xcf, 0xdc, 0x74, 0xed, 0xdd, 0xe0, 0xb, + 0xb, 0x10, 0x4, 0x80, 0x0, 0xd0, 0xb, 0xce, + 0xcb, 0x14, 0x80, 0x0, 0xd0, 0xb, 0xb, 0x10, + 0x4, 0x80, 0x0, 0xd0, 0xb, 0xce, 0xcc, 0x14, + 0xb5, 0x55, 0xe0, 0xb, 0xb, 0x10, 0x5, 0xc8, + 0xd7, 0x70, 0xb, 0xce, 0xcc, 0x86, 0x70, 0xd0, + 0x0, 0x1, 0x0, 0x42, 0xa7, 0x50, 0xb3, 0x0, + 0x9, 0x78, 0x77, 0x99, 0x40, 0x68, 0x0, 0x9, + 0x78, 0x9, 0x7d, 0x10, 0x1d, 0x10, 0x64, 0x40, + 0x9, 0xac, 0x0, 0x7, 0xa0, 0x0, 0x7, 0xcc, + 0xa4, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+9A12 "騒" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, + 0xce, 0xcc, 0x5e, 0xdc, 0xce, 0x80, 0xb, 0xb, + 0x0, 0x6, 0x90, 0x2d, 0x0, 0xb, 0xcf, 0xca, + 0x0, 0x9a, 0xc2, 0x0, 0xb, 0xb, 0x0, 0x5, + 0xcb, 0xd8, 0x20, 0xb, 0xcf, 0xca, 0xaa, 0x3a, + 0x6, 0xc5, 0xb, 0xb, 0x0, 0x16, 0x6e, 0x66, + 0x50, 0xb, 0xce, 0xcc, 0x6a, 0x5e, 0x65, 0xd0, + 0x1, 0x1, 0x2a, 0x67, 0xd, 0x0, 0xd0, 0x9, + 0x77, 0xab, 0x4c, 0xcf, 0xcc, 0xb0, 0x19, 0x78, + 0x3d, 0x0, 0xd, 0x9, 0x20, 0x64, 0x41, 0xd, + 0x2, 0x3e, 0x7a, 0xd0, 0x0, 0x8, 0xc8, 0x7a, + 0x97, 0x54, 0x76, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9A13 "験" */ + 0x0, 0x0, 0x0, 0x0, 0x1e, 0x80, 0x0, 0xb, + 0xce, 0xdc, 0x20, 0x9b, 0xe3, 0x0, 0xb, 0xa, + 0x10, 0x5, 0xd0, 0x4d, 0x20, 0xb, 0xce, 0xdb, + 0x6d, 0x20, 0x5, 0xe4, 0xb, 0xa, 0x10, 0x85, + 0xce, 0xdc, 0x34, 0xb, 0xbe, 0xcb, 0x0, 0xa, + 0x40, 0x0, 0xb, 0x1b, 0x20, 0x3d, 0xbe, 0xcb, + 0xe0, 0xa, 0xac, 0xaa, 0x79, 0xa, 0x30, 0xd0, + 0x2, 0x2, 0x48, 0x8e, 0xbe, 0xcb, 0xe0, 0x9, + 0x78, 0x9a, 0x30, 0x1d, 0xc0, 0x0, 0x19, 0x78, + 0x2c, 0x10, 0xa6, 0x77, 0x0, 0x64, 0x40, 0xd, + 0x1a, 0xa0, 0xc, 0x80, 0x0, 0x7, 0xc9, 0xa7, + 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9A57 "驗" */ + 0x0, 0x0, 0x0, 0x0, 0x9, 0x30, 0x0, 0xc, + 0xcf, 0xcb, 0x0, 0x8c, 0xb1, 0x0, 0xc, 0xc, + 0x0, 0x9, 0xa0, 0x3c, 0x40, 0xc, 0xae, 0xa8, + 0xdb, 0xcc, 0xcc, 0xa6, 0xc, 0xc, 0x0, 0x10, + 0x0, 0x0, 0x0, 0xc, 0xcf, 0xc7, 0x4a, 0xa4, + 0x9a, 0xa0, 0xc, 0xc, 0x0, 0x65, 0x46, 0xa0, + 0xb0, 0xc, 0x9e, 0x99, 0x65, 0x46, 0xa0, 0xb0, + 0x2, 0x35, 0x3c, 0x4a, 0xa4, 0x9a, 0xa0, 0x9, + 0x97, 0x6c, 0x7, 0x50, 0xc, 0x0, 0x27, 0x78, + 0x4c, 0xe, 0x80, 0x4c, 0x0, 0x63, 0x41, 0x1a, + 0x79, 0x89, 0xc9, 0xb0, 0x0, 0x6, 0xc7, 0xb0, + 0x7, 0x70, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9AD4 "體" */ + 0x0, 0x0, 0x0, 0xb, 0xc, 0x0, 0x4, 0xec, + 0xcc, 0x6, 0xd7, 0xd6, 0x60, 0x4d, 0xa1, 0xc1, + 0x8a, 0x2b, 0x1c, 0x4, 0x79, 0x1c, 0x1c, 0xda, + 0xd9, 0xe0, 0xcd, 0xdb, 0xe8, 0xab, 0x6c, 0x5d, + 0xc, 0x0, 0x2, 0xb5, 0x55, 0x55, 0x50, 0x6e, + 0xdd, 0xc5, 0xcc, 0xcc, 0xcc, 0x43, 0x80, 0x2c, + 0x3, 0x33, 0x33, 0x20, 0x3d, 0xbb, 0xc0, 0xb6, + 0x66, 0x9a, 0x3, 0x80, 0x2c, 0xa, 0x22, 0x26, + 0xa0, 0x3d, 0xbb, 0xc0, 0x7a, 0x78, 0xd5, 0x3, + 0x80, 0x2c, 0x1, 0xa0, 0x4a, 0x0, 0x38, 0x3d, + 0x76, 0xbf, 0xbe, 0xdb, 0x60, + + /* U+9AD8 "高" */ + 0x0, 0x0, 0x0, 0x83, 0x0, 0x0, 0x0, 0x5, + 0x55, 0x55, 0xab, 0x55, 0x55, 0x50, 0x17, 0x77, + 0x77, 0x77, 0x77, 0x77, 0x70, 0x0, 0xb, 0xbb, + 0xbb, 0xbb, 0xb1, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x0, 0xd1, 0x0, 0x0, 0xf, 0x99, 0x99, 0x99, + 0xf1, 0x0, 0x0, 0x2, 0x22, 0x22, 0x22, 0x20, + 0x0, 0x9, 0xdc, 0xcc, 0xcc, 0xcc, 0xcd, 0xa0, + 0x9, 0x40, 0x11, 0x11, 0x11, 0x4, 0xa0, 0x9, + 0x40, 0xf9, 0x99, 0x9d, 0x4, 0xa0, 0x9, 0x40, + 0xd0, 0x0, 0xd, 0x4, 0xa0, 0x9, 0x40, 0xfb, + 0xbb, 0xb9, 0x4, 0xa0, 0x9, 0x40, 0x60, 0x0, + 0x0, 0x8c, 0x60, + + /* U+9AEA "髪" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, + 0xd9, 0x99, 0x93, 0x3, 0xaa, 0x10, 0x0, 0xd9, + 0x88, 0x80, 0x87, 0x22, 0x40, 0x0, 0xd8, 0x88, + 0x80, 0x4, 0xaa, 0x20, 0xa, 0xdc, 0xab, 0xa8, + 0x57, 0x20, 0x40, 0x1, 0xb5, 0x28, 0xa0, 0x1, + 0x5c, 0x80, 0x7, 0xb9, 0x88, 0x84, 0xaa, 0x61, + 0x0, 0x5, 0x55, 0x6f, 0x65, 0x55, 0x55, 0x51, + 0x5, 0x55, 0xc9, 0x55, 0x55, 0x55, 0x50, 0x0, + 0x4, 0xfb, 0xaa, 0xaa, 0xa0, 0x0, 0x0, 0x1d, + 0x4b, 0x50, 0x1b, 0x60, 0x0, 0x3, 0xd5, 0x2, + 0xcd, 0xf6, 0x0, 0x0, 0x3d, 0x3a, 0xdb, 0x72, + 0x48, 0xcc, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9B5A "魚" */ + 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xec, 0xcd, 0xf1, 0x0, 0x0, 0x0, 0x6c, + 0x0, 0xa, 0x70, 0x0, 0x0, 0x8, 0xfd, 0xbb, + 0xcf, 0xcb, 0xb9, 0x0, 0x5c, 0xe1, 0x0, 0xb5, + 0x0, 0x2d, 0x0, 0x0, 0xd0, 0x0, 0xa4, 0x0, + 0x1d, 0x0, 0x0, 0xdc, 0xcc, 0xed, 0xcc, 0xcd, + 0x0, 0x0, 0xd0, 0x0, 0xa4, 0x0, 0x1d, 0x0, + 0x0, 0xda, 0xaa, 0xec, 0xaa, 0xbd, 0x0, 0x0, + 0x42, 0x22, 0x22, 0x22, 0x34, 0x0, 0x1, 0xd0, + 0x3a, 0x3, 0xb0, 0x2d, 0x20, 0xb, 0x60, 0x2c, + 0x0, 0xd2, 0x5, 0xd0, 0x48, 0x0, 0x9, 0x0, + 0x63, 0x0, 0x93, + + /* U+9CE5 "鳥" */ + 0x0, 0x0, 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, + 0x7b, 0xbc, 0xeb, 0xbb, 0xb0, 0x0, 0x0, 0xb3, + 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xbb, 0xaa, + 0xaa, 0xaa, 0xf0, 0x0, 0x0, 0xb3, 0x0, 0x0, + 0x0, 0xe0, 0x0, 0x0, 0xbc, 0xbb, 0xbb, 0xbb, + 0xb0, 0x0, 0x0, 0xb7, 0x55, 0x55, 0x55, 0x55, + 0x50, 0x0, 0xb7, 0x44, 0x44, 0x44, 0x44, 0x40, + 0x0, 0xbc, 0xbb, 0xbb, 0xbb, 0xbb, 0x70, 0x1, + 0x30, 0x10, 0x20, 0x41, 0x6, 0x80, 0x6, 0x71, + 0xb0, 0xb2, 0x49, 0x7, 0x70, 0xd, 0x10, 0xd0, + 0x66, 0x5, 0xa, 0x40, 0x46, 0x0, 0x50, 0x0, + 0xa, 0xcc, 0x0, + + /* U+9E97 "麗" */ + 0xa, 0xaa, 0xaa, 0x75, 0xaa, 0xaa, 0xa2, 0x5, + 0xb9, 0x9b, 0x40, 0xc9, 0x99, 0xa0, 0x6, 0x69, + 0x27, 0x50, 0xc4, 0x80, 0xc0, 0x4, 0x41, 0x45, + 0xa8, 0x80, 0x50, 0x80, 0x6, 0xc9, 0xae, 0xaa, + 0xcc, 0x99, 0x91, 0x6, 0xc9, 0xae, 0x99, 0xcc, + 0x99, 0x80, 0x6, 0x70, 0x1c, 0x0, 0x76, 0x1, + 0xc0, 0x8, 0xda, 0xae, 0xaa, 0xcc, 0xaa, 0xc0, + 0x9, 0x47, 0x60, 0x0, 0xb2, 0x4, 0x60, 0xb, + 0x27, 0xda, 0xa6, 0xbb, 0xa6, 0x20, 0x1d, 0x7, + 0x60, 0x22, 0xb2, 0x0, 0x38, 0x66, 0xd, 0xcb, + 0x84, 0x7c, 0xbb, 0xc4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+9EBC "麼" */ + 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x1, + 0x77, 0x77, 0x7e, 0x87, 0x77, 0x72, 0x2, 0xd5, + 0x57, 0x55, 0x55, 0x75, 0x51, 0x2, 0xb2, 0x4d, + 0x43, 0x34, 0xd4, 0x40, 0x2, 0xb4, 0x9f, 0xa5, + 0x6c, 0xfb, 0x70, 0x2, 0xb0, 0xae, 0xb4, 0x3b, + 0xdb, 0x10, 0x3, 0xb9, 0x7c, 0x7, 0xc1, 0xc2, + 0xc3, 0x3, 0xa4, 0xa, 0x6, 0x10, 0x90, 0x11, + 0x4, 0x90, 0x4, 0xa3, 0x7, 0x50, 0x0, 0x6, + 0x70, 0xce, 0x9a, 0xd6, 0x41, 0x0, 0x9, 0x40, + 0x14, 0xb9, 0x10, 0x3b, 0x0, 0xe, 0x14, 0xbe, + 0x99, 0xab, 0xbe, 0x50, 0x2a, 0x5, 0x65, 0x32, + 0x10, 0x0, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9EC4 "黄" */ + 0x0, 0x0, 0x86, 0x0, 0xe, 0x0, 0x0, 0x0, + 0xaa, 0xdc, 0xaa, 0xaf, 0xaa, 0x50, 0x0, 0x22, + 0x97, 0x22, 0x2e, 0x22, 0x10, 0x0, 0x0, 0x86, + 0x0, 0xe, 0x0, 0x0, 0x1d, 0xdd, 0xdd, 0xef, + 0xdd, 0xdd, 0xd5, 0x0, 0x0, 0x0, 0x5a, 0x0, + 0x0, 0x0, 0x0, 0x8d, 0xbb, 0xce, 0xbb, 0xbe, + 0x0, 0x0, 0x85, 0x0, 0x59, 0x0, 0xe, 0x0, + 0x0, 0x8c, 0xaa, 0xce, 0xaa, 0xae, 0x0, 0x0, + 0x85, 0x0, 0x59, 0x0, 0xe, 0x0, 0x0, 0x5b, + 0xbb, 0xbb, 0xbb, 0xba, 0x0, 0x0, 0x3, 0xa8, + 0x0, 0x2c, 0x71, 0x0, 0x7, 0xdb, 0x40, 0x0, + 0x0, 0x5c, 0xb1, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x20, + + /* U+9ED2 "黒" */ + 0x0, 0xac, 0xbb, 0xdd, 0xbb, 0xcc, 0x0, 0x0, + 0xa3, 0x0, 0x76, 0x0, 0x2c, 0x0, 0x0, 0xac, + 0xbb, 0xdd, 0xbb, 0xcc, 0x0, 0x0, 0xa3, 0x0, + 0x76, 0x0, 0x2c, 0x0, 0x0, 0xac, 0xcc, 0xed, + 0xcc, 0xcb, 0x0, 0x0, 0x0, 0x0, 0x76, 0x0, + 0x0, 0x0, 0x0, 0xcc, 0xcc, 0xee, 0xcc, 0xcc, + 0x20, 0x0, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, + 0x2c, 0xcc, 0xcc, 0xdd, 0xcc, 0xcc, 0xc3, 0x0, + 0x71, 0x3, 0x1, 0x30, 0x16, 0x0, 0x3, 0xd0, + 0xd, 0x1, 0xd0, 0xb, 0x60, 0xd, 0x20, 0xd, + 0x0, 0xb3, 0x1, 0xd1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+9EDE "點" */ + 0x0, 0x0, 0x0, 0x0, 0xb, 0x20, 0x0, 0xd, + 0xbd, 0xbc, 0x80, 0xb, 0x20, 0x0, 0xb, 0x58, + 0x38, 0x80, 0xb, 0x20, 0x0, 0xb, 0x88, 0x76, + 0x80, 0xb, 0x98, 0x81, 0xb, 0x38, 0x53, 0x80, + 0xb, 0x64, 0x41, 0xa, 0xbe, 0xcb, 0x60, 0xb, + 0x20, 0x0, 0x4, 0x4b, 0x64, 0x20, 0xb, 0x20, + 0x0, 0x7, 0x7d, 0x97, 0x5a, 0xdd, 0xdd, 0xe0, + 0x1, 0x2b, 0x64, 0x5a, 0x20, 0x0, 0xe0, 0x3b, + 0xa9, 0x88, 0x5a, 0x20, 0x0, 0xe0, 0x8, 0x43, + 0x86, 0x6a, 0x20, 0x0, 0xe0, 0xb, 0x37, 0x91, + 0x8a, 0xba, 0xaa, 0xe0, 0x46, 0x3, 0x0, 0xa, + 0x52, 0x22, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9EE8 "黨" */ + 0x0, 0x9, 0x20, 0x77, 0x2, 0xb0, 0x0, 0x7, + 0x8b, 0xd8, 0xcb, 0x8c, 0xb8, 0x70, 0xd, 0x33, + 0x33, 0x33, 0x33, 0x34, 0xd0, 0xa, 0x9, 0xa8, + 0x88, 0x8a, 0x90, 0x90, 0x0, 0x7, 0x98, 0x88, + 0x89, 0x60, 0x0, 0x0, 0x79, 0x99, 0x99, 0x99, + 0x98, 0x0, 0x0, 0xb1, 0x91, 0x76, 0x27, 0xd, + 0x0, 0x0, 0xb9, 0xba, 0xcb, 0xb9, 0x9d, 0x0, + 0x0, 0x55, 0x55, 0xa9, 0x55, 0x55, 0x10, 0x0, + 0x44, 0x44, 0xa9, 0x44, 0x44, 0x10, 0x1a, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xa1, 0x0, 0xa3, 0x8, + 0x1, 0x80, 0x2b, 0x10, 0xa, 0x70, 0xd, 0x0, + 0xc1, 0x5, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9F13 "鼓" */ + 0x0, 0x9, 0x40, 0x0, 0x1, 0xc0, 0x0, 0x2a, + 0xad, 0xca, 0x90, 0x1, 0xc0, 0x0, 0x2, 0x2a, + 0x62, 0x2b, 0xbb, 0xfb, 0xb6, 0x7, 0x8c, 0xa8, + 0x52, 0x24, 0xd2, 0x21, 0x3, 0x44, 0x44, 0x20, + 0x1, 0xc0, 0x0, 0x7, 0xbb, 0xbb, 0x49, 0xab, + 0xea, 0xa2, 0xa, 0x30, 0x8, 0x57, 0xb2, 0x23, + 0xe0, 0xa, 0x30, 0x8, 0x50, 0xe0, 0x5, 0xa0, + 0x8, 0xcc, 0xcc, 0x40, 0x97, 0xc, 0x30, 0x1, + 0x90, 0x1a, 0x0, 0x1d, 0x99, 0x0, 0x0, 0xd0, + 0x67, 0x0, 0x9, 0xf2, 0x0, 0x3, 0x99, 0xdd, + 0xc2, 0xbb, 0x7d, 0x40, 0x39, 0x75, 0x20, 0x7d, + 0x60, 0x3, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+9F3B "鼻" */ + 0x0, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x99, 0xca, 0x99, 0xc0, 0x0, 0x0, 0x1e, + 0x88, 0x88, 0x88, 0xe0, 0x0, 0x0, 0x1d, 0x44, + 0x44, 0x44, 0xe0, 0x0, 0x0, 0x1d, 0x33, 0x33, + 0x33, 0xe0, 0x0, 0x0, 0x9, 0x99, 0x99, 0x99, + 0x90, 0x0, 0x3, 0xb9, 0x99, 0xba, 0x99, 0x9b, + 0x30, 0x4, 0xc7, 0x77, 0xbb, 0x77, 0x7d, 0x30, + 0x4, 0xb5, 0x55, 0xaa, 0x55, 0x5c, 0x30, 0x1, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x10, 0x2c, 0xcc, + 0xfc, 0xcc, 0xdf, 0xcc, 0xc3, 0x0, 0x8, 0x90, + 0x0, 0x1d, 0x0, 0x0, 0xa, 0xb6, 0x0, 0x0, + 0x1d, 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, 0xb, 0x10, 0x9, 0x70, 0x2, 0xd0, 0x0, + 0x95, 0x0, 0xe, 0x0, 0x1, 0xd0, 0x0, 0x2b, + 0x0, 0x1, 0xc0, 0x0, 0xe, 0x0, 0x0, 0xb3, + 0x0, 0x5, 0xa0, 0x0, 0xc, 0x30, 0x0, 0x2d, + 0x10, 0x0, 0x20, + + /* U+FF09 ")" */ + 0x1b, 0x0, 0x0, 0x79, 0x0, 0x0, 0xd2, 0x0, + 0x5, 0x90, 0x0, 0xe, 0x0, 0x0, 0xd1, 0x0, + 0xb, 0x20, 0x0, 0xc1, 0x0, 0xe, 0x0, 0x3, + 0xb0, 0x0, 0xa5, 0x0, 0x3c, 0x0, 0x1d, 0x20, + 0x0, 0x20, 0x0, + + /* U+FF0C "," */ + 0x0, 0x4, 0xf6, 0x2c, 0xa0, 0x77, 0x6b, 0x4, + 0x0, + + /* U+FF11 "1" */ + 0x0, 0x1, 0x30, 0x0, 0x7, 0xcf, 0xe0, 0x0, + 0x1, 0x26, 0xe0, 0x0, 0x0, 0x4, 0xe0, 0x0, + 0x0, 0x4, 0xe0, 0x0, 0x0, 0x4, 0xe0, 0x0, + 0x0, 0x4, 0xe0, 0x0, 0x0, 0x4, 0xe0, 0x0, + 0x0, 0x4, 0xe0, 0x0, 0x0, 0x4, 0xe0, 0x0, + 0x4f, 0xff, 0xff, 0xfe, + + /* U+FF12 "2" */ + 0x0, 0x2, 0x20, 0x0, 0x3, 0xde, 0xde, 0x50, + 0x3e, 0x30, 0x4, 0xf1, 0x1, 0x0, 0x0, 0xd5, + 0x0, 0x0, 0x0, 0xe3, 0x0, 0x0, 0x5, 0xd0, + 0x0, 0x0, 0x2f, 0x40, 0x0, 0x2, 0xe6, 0x0, + 0x0, 0x3e, 0x60, 0x0, 0x5, 0xe4, 0x0, 0x0, + 0x4f, 0xff, 0xff, 0xfe +}; + + +/*--------------------- + * 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 = 50, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 0, .adv_w = 70, .box_w = 3, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 17, .adv_w = 102, .box_w = 5, .box_h = 4, .ofs_x = 1, .ofs_y = 7}, + {.bitmap_index = 27, .adv_w = 123, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 71, .adv_w = 123, .box_w = 7, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120, .adv_w = 205, .box_w = 13, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 192, .adv_w = 150, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 247, .adv_w = 60, .box_w = 2, .box_h = 4, .ofs_x = 1, .ofs_y = 7}, + {.bitmap_index = 251, .adv_w = 74, .box_w = 4, .box_h = 15, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 281, .adv_w = 74, .box_w = 4, .box_h = 15, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 311, .adv_w = 103, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 6}, + {.bitmap_index = 326, .adv_w = 123, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 358, .adv_w = 60, .box_w = 3, .box_h = 5, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 366, .adv_w = 77, .box_w = 5, .box_h = 1, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 369, .adv_w = 60, .box_w = 2, .box_h = 2, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 371, .adv_w = 88, .box_w = 6, .box_h = 14, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 413, .adv_w = 123, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 452, .adv_w = 123, .box_w = 6, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 485, .adv_w = 123, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 524, .adv_w = 123, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 563, .adv_w = 123, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 607, .adv_w = 123, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 646, .adv_w = 123, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 690, .adv_w = 123, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 734, .adv_w = 123, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 778, .adv_w = 123, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 817, .adv_w = 60, .box_w = 2, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 825, .adv_w = 60, .box_w = 3, .box_h = 11, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 842, .adv_w = 123, .box_w = 8, .box_h = 7, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 870, .adv_w = 123, .box_w = 8, .box_h = 4, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 886, .adv_w = 123, .box_w = 8, .box_h = 7, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 914, .adv_w = 105, .box_w = 6, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 947, .adv_w = 209, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1032, .adv_w = 135, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1082, .adv_w = 146, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1126, .adv_w = 142, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1176, .adv_w = 153, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1220, .adv_w = 131, .box_w = 7, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1259, .adv_w = 122, .box_w = 7, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1298, .adv_w = 153, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1348, .adv_w = 162, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1392, .adv_w = 64, .box_w = 2, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1403, .adv_w = 119, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1442, .adv_w = 143, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1486, .adv_w = 120, .box_w = 7, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1525, .adv_w = 180, .box_w = 9, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1575, .adv_w = 161, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1619, .adv_w = 165, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1674, .adv_w = 140, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1718, .adv_w = 165, .box_w = 10, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1783, .adv_w = 140, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1827, .adv_w = 132, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1871, .adv_w = 133, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1915, .adv_w = 160, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1959, .adv_w = 127, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2003, .adv_w = 195, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2069, .adv_w = 126, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2113, .adv_w = 117, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2157, .adv_w = 135, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2201, .adv_w = 74, .box_w = 4, .box_h = 14, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 2229, .adv_w = 88, .box_w = 6, .box_h = 14, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 2271, .adv_w = 74, .box_w = 4, .box_h = 14, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 2299, .adv_w = 123, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 2320, .adv_w = 125, .box_w = 8, .box_h = 1, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2324, .adv_w = 135, .box_w = 4, .box_h = 4, .ofs_x = 2, .ofs_y = 9}, + {.bitmap_index = 2332, .adv_w = 125, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2360, .adv_w = 138, .box_w = 7, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2399, .adv_w = 113, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2427, .adv_w = 138, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2471, .adv_w = 123, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2503, .adv_w = 71, .box_w = 5, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2533, .adv_w = 125, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 2577, .adv_w = 135, .box_w = 7, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2616, .adv_w = 60, .box_w = 2, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2627, .adv_w = 60, .box_w = 4, .box_h = 14, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 2655, .adv_w = 121, .box_w = 7, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2694, .adv_w = 62, .box_w = 3, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2711, .adv_w = 206, .box_w = 11, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2755, .adv_w = 136, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2783, .adv_w = 135, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2815, .adv_w = 138, .box_w = 7, .box_h = 11, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 2854, .adv_w = 138, .box_w = 8, .box_h = 11, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 2898, .adv_w = 85, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2918, .adv_w = 104, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2942, .adv_w = 83, .box_w = 5, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2967, .adv_w = 135, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2995, .adv_w = 114, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3023, .adv_w = 177, .box_w = 11, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3067, .adv_w = 109, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3095, .adv_w = 115, .box_w = 7, .box_h = 11, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 3134, .adv_w = 105, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3162, .adv_w = 74, .box_w = 5, .box_h = 14, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 3197, .adv_w = 59, .box_w = 2, .box_h = 16, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 3213, .adv_w = 74, .box_w = 5, .box_h = 14, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 3248, .adv_w = 123, .box_w = 8, .box_h = 2, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 3256, .adv_w = 224, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3269, .adv_w = 224, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3282, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3348, .adv_w = 224, .box_w = 5, .box_h = 10, .ofs_x = 9, .ofs_y = 2}, + {.bitmap_index = 3373, .adv_w = 224, .box_w = 5, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3398, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 3453, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3531, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 3581, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3647, .adv_w = 224, .box_w = 10, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 3712, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 3762, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3834, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3912, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 4003, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 4094, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 4160, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 4245, .adv_w = 224, .box_w = 9, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 4304, .adv_w = 224, .box_w = 10, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 4369, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 4447, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 4532, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 4587, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 4665, .adv_w = 224, .box_w = 11, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 4737, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 4815, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 4875, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 4935, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5013, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 5098, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 5176, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 5267, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5339, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5411, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5489, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5574, .adv_w = 224, .box_w = 11, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5646, .adv_w = 224, .box_w = 10, .box_h = 9, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 5691, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 5751, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 5842, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5914, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5986, .adv_w = 224, .box_w = 10, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 6051, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 6129, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6214, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6286, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 6364, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6449, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6521, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6599, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6684, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6769, .adv_w = 224, .box_w = 13, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6841, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6926, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7004, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 7088, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 7172, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 7256, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 7326, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 7403, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 7473, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7551, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7636, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7721, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 7787, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7865, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7937, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8009, .adv_w = 224, .box_w = 11, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8081, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 8142, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 8227, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 8277, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 8361, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 8411, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8483, .adv_w = 224, .box_w = 10, .box_h = 13, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 8548, .adv_w = 224, .box_w = 9, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 8607, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8673, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 8764, .adv_w = 224, .box_w = 11, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 8836, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8921, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8993, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 9077, .adv_w = 224, .box_w = 10, .box_h = 9, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 9122, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 9194, .adv_w = 224, .box_w = 11, .box_h = 10, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 9249, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 9315, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 9387, .adv_w = 224, .box_w = 11, .box_h = 9, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 9437, .adv_w = 224, .box_w = 13, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 9502, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 9574, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 9640, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 9725, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 9803, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 9888, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 9966, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 10057, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 10129, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 10220, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 10275, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 10353, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 10431, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 10522, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 10594, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 10679, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 10751, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 10842, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 10920, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 11011, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 11077, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 11155, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 11246, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 11318, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 11368, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 11440, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 11512, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 11597, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 4, .ofs_y = -1}, + {.bitmap_index = 11645, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 4, .ofs_y = -1}, + {.bitmap_index = 11693, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 11771, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 11831, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 11909, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 11969, .adv_w = 224, .box_w = 12, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 12029, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 12120, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 12204, .adv_w = 224, .box_w = 9, .box_h = 11, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 12254, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 12332, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 12404, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 12464, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 12555, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 12640, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 12717, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 12787, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 12865, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 12956, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 13041, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 13107, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 13167, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 13245, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 13317, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 13383, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 13444, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 13529, .adv_w = 224, .box_w = 10, .box_h = 8, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 13569, .adv_w = 224, .box_w = 8, .box_h = 9, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 13605, .adv_w = 224, .box_w = 10, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 13660, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 13732, .adv_w = 224, .box_w = 8, .box_h = 12, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 13780, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 13858, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 13924, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 13974, .adv_w = 224, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 14040, .adv_w = 224, .box_w = 11, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 14106, .adv_w = 224, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 14167, .adv_w = 224, .box_w = 12, .box_h = 2, .ofs_x = 1, .ofs_y = 4}, + {.bitmap_index = 14179, .adv_w = 224, .box_w = 14, .box_h = 2, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 14193, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 14284, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 14375, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 14473, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 14550, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 14641, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 14725, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 14809, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 14900, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 14984, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 15068, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 15152, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 15243, .adv_w = 224, .box_w = 11, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 15315, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 15406, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 15504, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 15602, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 15693, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 15791, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 15882, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 15980, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 16071, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 16143, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 16234, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 16325, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 16416, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 16486, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 16570, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 16661, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 16752, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 16850, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 16948, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 17039, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 17130, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17235, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17333, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 17424, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17515, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 17613, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17711, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 17809, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 17914, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18012, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 18103, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18201, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 18299, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 18390, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18488, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 18579, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18677, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 18775, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 18866, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 18957, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 19048, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 19139, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 19230, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 19321, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19419, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 19510, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 19601, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19699, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19804, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 19895, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19986, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 20084, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 20175, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20266, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20371, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20469, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 20560, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20658, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20756, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 20847, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20945, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 21036, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 21127, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 21212, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 21303, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 21401, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 21499, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 21597, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 21702, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 21800, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 21898, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 21989, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 22080, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 22178, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 22269, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22367, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 22458, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22563, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22661, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22759, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22857, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22955, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23046, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23137, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23235, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23333, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23431, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23529, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23627, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23725, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23823, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23921, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 23999, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 24097, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24188, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24279, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24377, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24475, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24573, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 24664, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24755, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 24833, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 24905, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 24989, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 25073, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 25151, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 25229, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25327, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25425, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 25516, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25614, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25712, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 25790, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25888, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25973, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 26058, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26149, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26240, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26331, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26422, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26513, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26604, .adv_w = 224, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26702, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26800, .adv_w = 224, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26898, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26989, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27080, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27185, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 27269, .adv_w = 224, .box_w = 12, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 27359, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 27450, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27541, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 27625, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27723, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27814, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27912, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28003, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28101, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28199, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28304, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28409, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28507, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28605, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28703, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28801, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 28892, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 28990, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 29081, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 29159, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 29231, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 29322, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 29413, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 29504, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 29595, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 29686, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29784, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29882, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 29973, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30071, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 30143, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30234, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30325, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 30409, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30507, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 30598, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30696, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30794, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 30878, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 30962, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 31053, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31144, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31235, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31333, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 31405, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 31496, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31587, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31672, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31763, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 31841, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 31925, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 32010, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32108, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 32199, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32290, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 32362, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 32447, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 32538, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 32629, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 32701, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 32786, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 32864, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 32948, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 33026, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 33111, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 33202, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 33287, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33372, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 33457, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 33548, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 33639, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 33724, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 33815, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 33887, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33978, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 34069, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 34160, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 34245, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 34323, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 34414, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 34505, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 34596, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 34687, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 34765, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 34849, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 34927, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 35012, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 35090, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 35181, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35272, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 35344, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 35416, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 35488, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 35560, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 35632, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 35704, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 35776, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 35848, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 35920, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 35992, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 36083, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 36174, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 36265, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 36356, .adv_w = 224, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36454, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36559, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 36650, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 36741, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 36839, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36937, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 37028, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37126, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37224, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37329, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 37427, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37532, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 37630, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 37721, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 37812, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 37903, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 37994, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38085, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38183, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38288, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 38372, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 38450, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 38548, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 38633, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38731, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38829, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 38920, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39011, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39109, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 39200, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39298, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39396, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 39487, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39585, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 39676, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39774, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39879, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39984, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40075, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 40160, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40258, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 40349, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40447, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40552, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 40650, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40755, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40853, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40951, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 41049, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 41140, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 41238, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 41343, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 41441, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 41539, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 41623, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 41708, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 41799, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 41890, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 41981, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42079, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42177, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 42268, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 42346, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 42437, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 42522, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 42613, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 42704, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42802, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 42880, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 42958, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43056, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 43141, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 43232, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 43330, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 43428, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 43519, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 43597, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43702, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 43793, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 43884, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 43982, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 44080, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 44158, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44256, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 44347, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 44438, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 44529, .adv_w = 224, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44627, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 44718, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 44816, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 44914, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45012, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 45103, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45201, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 45292, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45390, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 45481, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 45559, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45657, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45762, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 45846, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 45924, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46015, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 46093, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46184, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46275, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 46359, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46450, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 46535, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 46626, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 46717, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46808, .adv_w = 224, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46906, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 46983, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 47074, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 47165, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 47243, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 47321, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 47419, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 47510, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 47601, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 47692, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 47777, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47875, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 47973, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48071, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 48162, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 48253, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 48331, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 48416, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 48500, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 48591, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 48682, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48780, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 48871, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48969, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49067, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49165, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49263, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 49354, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49445, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49543, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49648, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49753, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49858, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49956, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 50047, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 50138, .adv_w = 224, .box_w = 11, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 50215, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 50300, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50385, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50483, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50581, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 50659, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50757, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 50848, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50946, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51031, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51122, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51220, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51318, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51409, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51500, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51598, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51689, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51780, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51871, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51956, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52047, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52138, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52229, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52320, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52411, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52509, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52600, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 52685, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52776, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52867, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52951, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 53036, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53127, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53225, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53316, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53400, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53491, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53582, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53673, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53764, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53855, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53939, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 54030, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 54128, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 54226, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54324, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 54409, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54507, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54612, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 54703, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54801, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54899, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 54990, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55095, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55193, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55291, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55382, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55480, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 55571, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55669, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55767, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55865, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55963, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56061, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56159, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56257, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 56342, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56440, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 56538, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 56629, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 56720, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 56811, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56916, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 57014, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 57112, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57217, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 57308, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57406, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 57504, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57602, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57700, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57805, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57903, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 57994, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58092, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58190, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58288, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 58379, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58477, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58575, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 58666, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58764, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58869, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58967, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 59058, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59156, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59254, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59352, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 59443, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59541, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 59632, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 59723, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59821, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59919, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60017, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60115, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 60206, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 60297, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60395, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60500, .adv_w = 224, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 60598, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 60689, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 60774, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60872, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60970, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61068, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61173, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61271, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61369, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61467, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 61527, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 61611, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 61695, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 61780, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61871, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 61949, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62034, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 62125, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 62209, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 62300, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 62391, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 62476, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62567, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 62651, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 62736, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 62827, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 62918, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 63002, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 63087, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 63172, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 63257, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 63341, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 63426, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 63511, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63602, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 63680, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 63758, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63849, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 63940, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 64018, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 64109, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 64193, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 64284, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64362, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 64453, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64538, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64629, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 64720, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64811, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64902, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 64993, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65084, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65175, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65266, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65364, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65462, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65560, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65665, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65756, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65847, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65938, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66029, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66120, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66211, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66302, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66386, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66477, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66568, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66659, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66750, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66848, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66946, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67051, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 67149, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67247, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67360, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67458, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 67549, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 67640, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 67738, .adv_w = 224, .box_w = 15, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 67836, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 67934, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68039, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68144, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68235, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68326, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68417, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68515, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68606, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68697, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68788, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68879, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 68977, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 69068, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69173, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69278, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 69369, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69467, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69565, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69663, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69761, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 69846, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69951, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 70042, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 70126, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70224, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70322, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70420, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 70511, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70609, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 70700, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70791, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70882, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 70973, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71071, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71169, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71260, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71358, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71456, .adv_w = 224, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 71554, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 71639, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 71724, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 71809, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 71900, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71998, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72096, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72194, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 72285, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 72376, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72474, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 72565, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72663, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72761, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72859, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 72944, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 73035, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73133, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 73218, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 73309, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73407, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 73498, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73596, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73694, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 73785, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73883, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 73968, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 74059, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74157, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74255, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 74346, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 74437, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74535, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 74620, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 74711, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 74802, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74900, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 74991, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75082, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75180, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75278, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75383, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75481, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75579, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 75670, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75761, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 75852, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 75950, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76048, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 76139, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76237, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 76328, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76426, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76531, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76629, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 76720, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76818, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76916, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77014, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 77105, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 77203, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77301, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77406, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 77497, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 77588, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77686, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 77777, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 77862, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 77953, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 78044, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78149, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 78240, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 78331, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78429, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78534, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78639, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78737, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78835, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 78926, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79024, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79122, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79213, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79311, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79409, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 79493, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79584, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 79675, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 79766, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 79857, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79962, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 80060, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 80145, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 80217, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 80295, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 80373, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 80458, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 80543, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 80621, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 80693, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 80784, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 80869, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 80960, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 81051, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81142, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 81220, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81318, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 81409, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 81500, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81598, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81696, .adv_w = 224, .box_w = 10, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 81761, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 81845, .adv_w = 224, .box_w = 12, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 81935, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 82013, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 82090, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 82181, .adv_w = 224, .box_w = 10, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 82241, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 82332, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82423, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 82514, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 82605, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 82690, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 82768, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 82859, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82950, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83048, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 83132, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 83223, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83314, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83412, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 83503, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 83587, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 83685, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 83776, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 83867, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83965, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84056, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84147, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84238, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84336, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84427, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84518, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84609, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84700, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84798, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 84896, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84987, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 85078, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85176, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85274, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 85352, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 85443, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 85534, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 85625, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 85716, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85814, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85912, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86010, .adv_w = 224, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86108, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86199, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86297, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86388, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86479, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86577, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86662, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86753, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86844, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86935, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 87026, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 87124, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 87222, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 87307, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 87398, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87489, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87587, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 87678, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 87763, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 87854, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87952, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 88043, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88141, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 88239, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 88330, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 88421, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88519, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 88610, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88708, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88806, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 88897, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 88982, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 89073, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 89171, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 89262, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 89353, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89451, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 89549, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 89640, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89745, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89850, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 89941, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90039, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90144, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90242, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90347, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 90431, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 90522, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 90613, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 90685, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 90776, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90874, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 90965, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 91049, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 91133, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 91211, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91309, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 91400, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91498, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 91596, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 91680, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 91771, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91869, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 91960, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92058, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92156, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 92254, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92352, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92450, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92548, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92646, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92737, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92835, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92933, .adv_w = 224, .box_w = 10, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 92998, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 93082, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 93173, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93278, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93376, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 93474, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93572, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93670, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93768, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 93852, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 93943, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 94034, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 94125, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 94216, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 94307, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94405, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 94496, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94594, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 94685, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 94776, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 94867, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 94958, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 95049, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 95140, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 95231, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 95322, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95420, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95518, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95616, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95714, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95819, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95917, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 96008, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 96099, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 96190, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 96281, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96386, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96484, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 96568, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96659, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96750, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96848, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96946, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97044, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97142, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97240, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97338, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 97422, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97520, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97625, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 97716, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 97814, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97912, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98017, .adv_w = 224, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98115, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 98206, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98304, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98402, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 98493, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98591, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98689, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 98780, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 98878, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 98969, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99067, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 99158, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 99256, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 99347, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99445, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99543, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 99634, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99732, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99830, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99935, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 100026, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 100117, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100208, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100313, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 100411, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100509, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 100607, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 100698, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 100796, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100901, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100999, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101097, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101202, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101300, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101398, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 101489, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101587, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 101678, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101776, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101874, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101972, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 102063, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102161, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102259, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102350, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102448, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102546, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102644, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102742, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102840, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102938, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 103029, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 103120, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 103211, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103309, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103407, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103505, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103603, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103701, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103792, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103883, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.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 = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 104163, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 104254, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104352, .adv_w = 224, .box_w = 15, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 104450, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104555, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 104653, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 104744, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 104842, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104940, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 105031, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105129, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105227, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105325, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105423, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 105514, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105612, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105710, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105808, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105906, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106004, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106102, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106200, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106298, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106396, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106494, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106592, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106690, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106788, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106886, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106984, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107082, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107180, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107278, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107369, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107467, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 107551, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107649, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107747, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107845, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107943, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108041, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108146, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108244, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108342, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108440, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108538, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108629, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108727, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 108818, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 108909, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109007, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109105, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 109196, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109294, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109392, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 109483, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 109574, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 109665, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 109749, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 109847, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 109945, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 110043, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 110134, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 110232, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 110330, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 110428, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 110519, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 110610, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 110688, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 110766, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 110844, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 110916, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 110988, .adv_w = 224, .box_w = 12, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 111066, .adv_w = 224, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 111150, .adv_w = 224, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 111248, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 111333, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 111424, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 111515, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 111606, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 111691, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 111776, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 111867, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 111958, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 112043, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 112134, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 112225, .adv_w = 224, .box_w = 13, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112316, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 112407, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112512, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 112603, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112701, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112799, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 112890, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 112974, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 113046, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113137, .adv_w = 224, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 113215, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113306, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113397, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 113488, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113586, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 113684, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 113768, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 113859, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113964, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 114062, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 114153, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 114244, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114335, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114433, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114531, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114629, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114727, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114825, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114916, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115014, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115105, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115203, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115301, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115392, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115483, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115581, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115679, .adv_w = 224, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115784, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 115869, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 115960, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 116051, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116149, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116240, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116338, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116436, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116534, .adv_w = 224, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 116619, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 116710, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116808, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 116899, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 116990, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117081, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117179, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117277, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117368, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117466, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117564, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117662, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 117753, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 117866, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 117943, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 118034, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 118111, .adv_w = 154, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 118166, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118271, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118376, .adv_w = 252, .box_w = 16, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 118480, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118585, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 118673, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118778, .adv_w = 112, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 118820, .adv_w = 168, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 118886, .adv_w = 252, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118998, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 119075, .adv_w = 154, .box_w = 10, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 119150, .adv_w = 196, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 119220, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 119318, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 119403, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 119488, .adv_w = 196, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 119558, .adv_w = 196, .box_w = 14, .box_h = 13, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 119649, .adv_w = 140, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 119708, .adv_w = 140, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 119767, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 119852, .adv_w = 196, .box_w = 13, .box_h = 4, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 119878, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 119966, .adv_w = 280, .box_w = 18, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120101, .adv_w = 252, .box_w = 17, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 120229, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 120320, .adv_w = 196, .box_w = 13, .box_h = 8, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 120372, .adv_w = 196, .box_w = 13, .box_h = 8, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 120424, .adv_w = 280, .box_w = 18, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 120523, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 120600, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120705, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 120818, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 120903, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121001, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 121086, .adv_w = 196, .box_w = 13, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 121164, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 121241, .adv_w = 140, .box_w = 10, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 121316, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121414, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121512, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 121600, .adv_w = 224, .box_w = 16, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 121720, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121803, .adv_w = 280, .box_w = 18, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 121920, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 122010, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 122100, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 122190, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 122280, .adv_w = 280, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 122370, .adv_w = 280, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 122478, .adv_w = 196, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122568, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122666, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 122779, .adv_w = 280, .box_w = 18, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 122878, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122961, .adv_w = 225, .box_w = 15, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 123036, .adv_w = 224, .box_w = 5, .box_h = 14, .ofs_x = 9, .ofs_y = -2}, + {.bitmap_index = 123071, .adv_w = 224, .box_w = 5, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123106, .adv_w = 224, .box_w = 3, .box_h = 6, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 123115, .adv_w = 224, .box_w = 8, .box_h = 11, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 123159, .adv_w = 224, .box_w = 8, .box_h = 11, .ofs_x = 3, .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 = 95, .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 = 96, + .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 = 108, + .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 = 132, + .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 = 175, + .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 = 247, + .unicode_list = unicode_list_5, .glyph_id_ofs_list = NULL, .list_length = 1187, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + } +}; + +/*----------------- + * KERNING + *----------------*/ + + +/*Map glyph_ids to kern left classes*/ +static const uint8_t kern_left_class_mapping[] = { + 0, 0, 0, 1, 0, 0, 0, 0, + 1, 2, 0, 0, 0, 3, 4, 3, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 6, 0, 0, 0, + 0, 0, 7, 8, 9, 10, 11, 12, + 13, 0, 0, 14, 15, 16, 0, 0, + 10, 17, 10, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 2, 27, 0, 0, + 0, 0, 28, 29, 30, 0, 31, 32, + 33, 34, 0, 0, 35, 36, 34, 34, + 29, 29, 37, 38, 39, 40, 37, 41, + 42, 43, 44, 45, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 46, 47, 48, + 49, 50, 0, 51, 0, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 0, + 62, 63, 0, 64, 65, 0, 66, 67, + 67, 68, 69, 0, 70, 71, 72, 73, + 74, 75, 76, 0, 77, 78, 79, 80, + 81, 82, 82, 83, 0, 84, 85, 86, + 86, 87, 88, 89, 0, 0, 90, 91, + 79, 0, 67, 92, 93, 94, 0, 95, + 0, 96, 97, 98, 99, 100, 0, 101, + 0, 102, 58, 103, 0, 104, 105, 0, + 0, 106, 107, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 0, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 0, + 134, 135, 136, 137, 138, 0, 139, 0, + 140, 141, 142, 115, 0, 0, 0, 0, + 143, 0, 144, 145, 0, 46, 146, 147, + 0, 148, 149, 150, 151, 152, 0, 153, + 154, 0, 155, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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 +}; + +/*Map glyph_ids to kern right classes*/ +static const uint8_t kern_right_class_mapping[] = { + 0, 0, 1, 2, 0, 0, 0, 0, + 2, 0, 3, 4, 0, 5, 6, 7, + 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 10, 0, 0, 0, + 11, 0, 12, 0, 13, 0, 0, 0, + 13, 0, 0, 14, 0, 0, 0, 0, + 13, 0, 13, 0, 15, 16, 17, 18, + 19, 20, 21, 22, 0, 23, 3, 0, + 0, 0, 24, 0, 25, 25, 25, 26, + 27, 0, 28, 29, 0, 0, 30, 30, + 25, 30, 25, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 0, 0, 3, 0, + 39, 40, 0, 0, 0, 0, 41, 42, + 43, 44, 45, 0, 46, 47, 48, 49, + 50, 51, 52, 0, 0, 53, 53, 53, + 53, 0, 0, 54, 55, 56, 56, 57, + 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 0, 0, 0, 69, + 70, 71, 71, 72, 72, 72, 73, 74, + 75, 76, 76, 76, 0, 0, 0, 77, + 78, 0, 0, 79, 80, 81, 82, 0, + 83, 84, 0, 85, 86, 87, 88, 0, + 71, 0, 89, 90, 91, 92, 93, 94, + 95, 0, 96, 96, 0, 0, 97, 98, + 0, 99, 100, 100, 101, 102, 103, 103, + 104, 105, 106, 106, 107, 108, 109, 106, + 89, 110, 111, 112, 113, 114, 115, 106, + 116, 117, 118, 119, 120, 0, 0, 0, + 121, 122, 123, 124, 125, 0, 0, 0, + 126, 127, 128, 129, 0, 130, 131, 132, + 0, 0, 133, 0, 134, 135, 0, 0, + 136, 0, 137, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 138, + 0, 0 +}; + +/*Kern values between classes*/ +static const int8_t kern_class_values[] = { + 0, 0, 0, 0, -28, 0, -28, 0, + 0, 0, 0, -13, 0, -23, -2, 0, + 0, 0, 0, -2, 0, 0, 0, 0, + -8, 0, 0, 0, 0, 0, -5, 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, -5, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 20, 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, -23, 0, -33, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -25, -5, -16, -8, 0, + -22, 0, 0, 0, -3, 0, 0, 0, + 6, 0, 0, -11, 0, -8, -5, 0, + -5, 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, -5, -4, -11, 0, -5, + -2, -6, -16, -5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -7, 0, -2, + 0, -3, 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, -10, -2, -20, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -6, + -8, 0, -2, 7, 7, 0, 0, 3, + -5, 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, -13, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -6, 0, + 0, 0, 0, 0, 0, 0, 1, 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, -13, 0, -24, + 0, 0, 0, 0, 0, 0, -6, -2, + -2, 0, 0, -13, -4, -3, 0, 1, + -3, -2, -10, 6, 0, -2, 0, 0, + 0, 0, 6, -3, -2, -2, -1, -1, + -2, 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, -8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -4, -3, -6, 0, -1, + -1, -1, -3, -1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -2, 0, -3, + -2, -2, -3, 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, -6, 0, 0, + 0, 0, 0, 0, -7, -2, -6, -4, + -3, -1, -1, -1, -2, -2, 0, 0, + 0, 0, -5, 0, 0, 0, 0, -6, + -2, -3, -2, 0, -3, 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, -9, 0, 0, + 0, -4, 0, 0, 0, -2, 0, -9, + 0, -6, 0, -2, -2, -4, -5, -5, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -3, 0, -2, + 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, -2, 0, 0, 0, + 0, 0, 0, -6, 0, -2, 0, -7, + -2, 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, -17, 0, -17, -18, 0, 0, + 0, -9, -2, -35, -5, 0, 0, 1, + 1, -6, 1, -8, 0, -8, -3, 0, + -6, 0, 0, -5, -5, -2, -4, -4, + -4, -6, -4, -6, 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, -7, 0, 0, 0, 0, + 0, 0, 0, -1, 0, 0, 0, -5, + 0, -3, -1, 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, -6, 0, + -6, 0, 0, 0, 0, 0, 0, -10, + 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, -5, 0, -10, + 0, -6, 0, 0, 0, 0, -2, -2, + -5, 0, -2, -4, -3, -3, -2, 0, + -4, 0, 0, 0, -2, 0, 0, 0, + -2, 0, 0, -8, -4, -4, -4, -4, + -4, -3, 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, -20, + 0, -37, 0, -14, 0, 0, 0, 0, + -7, 1, -6, 0, -5, -30, -7, -19, + -14, 0, -19, 0, -20, 0, -3, -3, + -1, 0, 0, 0, 0, -5, -2, -8, + -8, 0, -8, 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, -27, -9, -27, -20, + 0, 0, 0, -13, 0, -37, -2, -6, + 0, 0, 0, -6, -2, -20, 0, -11, + -6, 0, -8, 0, 0, 0, -2, 0, + 0, 0, 0, -3, 0, -5, 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, -2, 0, -8, + 0, 0, 0, 0, 0, -1, 0, -4, + -3, -3, 0, 2, 2, -1, 0, -2, + 0, -1, -2, 0, -1, 0, 0, 0, + 0, 0, 0, 0, 0, -2, 0, -2, + 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, -4, + 0, 3, 0, 0, 0, 0, 0, 0, + 0, -3, -3, -5, 0, 0, 0, 0, + -3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -6, 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, -26, -18, -26, -23, -5, -5, + 0, -10, -6, -32, -10, 0, 0, 0, + 0, -5, -3, -14, 0, -18, -16, -4, + -18, 0, 0, -12, -15, -4, -12, -9, + -9, -10, -9, -19, 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, -4, 0, -4, -8, + 0, 0, 0, -4, 0, -11, -2, 0, + 0, -1, 0, -2, -3, 0, 0, -1, + 0, 0, -2, 0, 0, 0, -1, 0, + 0, 0, 0, -2, 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, -16, -5, + -16, -12, 0, 0, 0, -3, -2, -18, + -2, 0, -2, 2, 0, 0, 0, -5, + 0, -5, -4, 0, -5, 0, 0, -5, + -3, 0, -8, -2, -2, -4, -2, -6, + 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, + -8, -2, -8, -8, 0, 0, 0, 0, + -2, -17, -2, 0, 0, 0, 0, 0, + 0, -2, 0, -4, 0, 0, -4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -2, 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, -2, + 0, -2, 0, -6, 0, 0, 0, 0, + 0, 1, -4, 0, -3, -5, -2, 0, + 0, 0, 0, 0, 0, -2, -2, -4, + 0, 0, 0, 0, 0, -4, -2, -4, + -3, -2, -4, -3, 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, -22, -16, -22, -17, + -6, -6, -2, -3, -3, -25, -4, -3, + -2, 0, 0, 0, 0, -7, 0, -17, + -10, 0, -15, 0, 0, -10, -10, -6, + -8, -3, -6, -8, -3, -11, 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, -9, + 0, 0, 0, 0, 0, -2, -5, -9, + -8, 0, -2, -2, -2, 0, -3, -4, + 0, -4, -6, -5, -4, 0, 0, 0, + 0, -3, -6, -4, -4, -6, -4, 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, -22, -8, -13, -8, 0, + -18, 0, 0, 0, 0, 0, 9, 0, + 18, 0, 0, 0, 0, -5, -2, 0, + 4, 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, -14, 0, 0, 0, 0, 0, 0, + -2, 0, 0, 0, 0, -6, 0, -4, + -1, 0, -6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -3, 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, -8, 0, -7, -2, 2, -2, 0, + 0, 0, -2, 0, 0, 0, 0, -14, + 0, -5, 0, -1, -11, 0, -6, -4, + 0, 0, 0, 0, 0, 0, 0, -4, + 0, -1, -1, -4, -1, -1, 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, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -5, 0, -3, 0, 0, -6, 0, + 0, -2, -5, 0, -2, 0, 0, 0, + 0, -2, 0, 2, 2, 2, 2, 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, -9, + 0, 2, 0, 0, 0, 0, -2, 0, + 0, -5, -5, -6, 0, -4, -2, 0, + -6, 0, -4, -4, 0, 0, -2, 0, + 0, 0, 0, -2, 0, 2, 2, -2, + 2, 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, 4, 10, + 13, 0, -12, -3, -12, -4, 0, 0, + 7, 0, 0, 0, 0, 12, 0, 17, + 12, 9, 15, 0, 17, -5, -2, 0, + -4, 0, -2, 0, -1, 0, 0, 4, + 0, -1, 0, -3, 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, 4, -9, 0, 0, 0, 13, + 0, 0, -9, 0, 0, 0, 0, -6, + 0, 0, 0, 0, -3, 0, 0, -4, + -3, 0, 0, 0, 9, 0, 0, 0, + 0, -1, -1, 0, 4, -3, 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, -9, 0, 0, + 0, 0, 0, 0, -2, 0, 0, 0, + 0, -6, 0, -2, 0, 0, -4, 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, -5, + 4, -10, 4, 0, 4, 4, -2, 0, + 0, 0, 0, -8, 0, 0, 0, 0, + -3, 0, 0, -2, -4, 0, -2, 0, + -2, 0, 0, -5, -3, 0, 0, -2, + 0, -2, 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, 2, 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, -6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -5, + 0, -3, 0, 0, -8, 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, -13, -6, + -13, -9, 7, 7, 0, -3, 0, -13, + 0, 0, 0, 0, 0, 0, 0, -2, + 4, -6, -2, 0, -2, 0, 0, 0, + -1, 0, 0, 7, 5, 0, 7, -1, + 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, -13, + 0, 2, 0, 0, 0, 0, -2, 0, + 0, 0, 0, -6, 0, -2, 0, 0, + -5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -5, 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, 2, -6, 2, 3, 4, 4, + -6, 0, 0, 0, 0, -3, 0, 0, + 0, 0, -1, 0, 0, -5, -3, 0, + -2, 0, 0, 0, -2, -5, 0, 0, + 0, -4, 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, -3, -8, -2, -8, -5, + 0, 0, 0, -3, 0, -10, 0, -5, + 0, -2, 0, 0, -3, -2, 0, -5, + -1, 0, 0, 0, -2, 0, 0, 0, + 0, 0, 0, 0, 0, -6, 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, -3, -9, 0, + -9, -2, 0, 0, 0, -1, 0, -8, + 0, -6, 0, -2, 0, -3, -6, 0, + 0, -2, -1, 0, 0, 0, -2, 0, + 0, 0, 0, 0, 0, 0, 0, -4, + 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, -3, 0, 0, -6, + 2, -3, -2, 0, 0, 2, 0, 0, + -2, 0, -1, -9, 0, -4, 0, -2, + -8, 0, 0, -2, -4, 0, 0, 0, + 0, 0, 0, -6, 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, -8, 0, -8, -4, 0, 0, + 0, 0, 0, -10, 0, -5, 0, -1, + 0, -1, -2, 0, 0, -5, -1, 0, + 0, 0, -2, 0, 0, 0, 0, 0, + 0, -3, 0, -6, 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, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -7, + 0, 0, 0, 0, -8, 0, 0, -6, + -2, 0, -2, 0, 0, 0, 0, 0, + -2, -1, 0, 0, -1, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -4, -4, 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, 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, -4, -4, 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, -2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, 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, -4, -4, 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, 0, + 0, 0, 0, 0, 0, 0, 0, -7, + -7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -4, 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, -13, 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, -4, -4, -4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -22, 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, -7, -7, -7, -7, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -7, -7, -11, -7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -16, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -7, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, -4, 0, -4, + -4, 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, -4, -4, 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, -9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -11, 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, -13, + 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, -4, -4, + 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, -11, 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, -13, 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, + -16, -11, 0, -9, 0, -4, -7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -4, + 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, -7, 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, -11, -11, 0, -4, 0, 0, + -4, 0, 0, 0, 0, 0, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, + -9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -4, 0, -7, -11, 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, -13, 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, -4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -7, -7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, -4, 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, -7, + 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, -7, 0, + 0, 0, 0, -4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, + 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, -4, 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, -11, 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, + -11, -11, 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, -11, 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, -16, -11, 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, -22, 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, -4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -4, -4, 0, 0, 0, + 0, 0, -16, 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, -11, + 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, 2, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 2, + 2, 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, 2, 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, -9, 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, -4, -4, 0, 0, 0, 0, 0, + 0, -13, -13, -7, -7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -4, 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, -18, -22, 0, -4, + 0, 0, -9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -9, 0, 0, 2, 2, 0, + 0, 0, 0, 0, 0, 0, -4, -4, + -4, -16, 0, 0, 0, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -13, 0, 0, 0, 0, 0, + 0, -16, -20, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -9, + 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, -16, -22, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -11, 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, -16, 0, 0, 0, + 0, 0, 0, -16, -16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -11, 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, 4, + 4, 0, 0, 0, 0, 0, 0, 0, + 0, 7, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -11, 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, 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, -11, 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, -7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -13, 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, -4, + 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, -7, -7, + 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, -4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -13, + 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, -11, 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, -11, 0, 0, 0, 0, 7, 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, -9, -9, 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, -11, 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, -7, -7, 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, -9, + 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, -11, -7, + -7, 0, 0, 0, 0, -7, 0, 0, + -7, -7, -7, -7, 0, 0, 0, 0, + -7, 0, 0, 0, -13, -4, -4, 0, + 0, 0, 0, 0, 0, -4, -4, 0, + 0, 0, 0, 0, -11, 0, -11, 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, -16, 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, + -9, -9, -2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 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, -9, 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, -9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -7, 0, + 0, -7, -7, 0, -7, 0, 0, 0, + -7, -9, -9, -7, -7, 0, 0, -7, + -2, 0, 0, 0, 0, 0, 0, -11, + 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, -9, 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, -11, -11, 0, 0, + 0, 0, 0, 0, 0, 0, -7, -7, + -7, -7, -7, 0, 0, 0, -7, 0, + 0, 0, 0, -7, -7, -4, -4, 0, + 0, -4, 0, 0, 0, 0, 0, 0, + 0, -11, 0, -7, 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, -11, + 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, -7, 0, + 0, 0, 0, 0, 0, 0, 0, -4, + 0, 0, -4, -4, -4, 2, 2, 0, + -4, 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, -11, 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, -4, -4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -4, 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, -2, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -9, 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, -7, 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, -13, + 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, -4, -4, 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, + 4, 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, 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, -7, -7, 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, -11, 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, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -16, + 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, -7, 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, -4, 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, 2, 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, -11, 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, -16, -16, -11, -11, 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, -7, 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, -9, -9, 0, + -9, 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, -7, + 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, -9, + -9, -9, -9, 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, -7, 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, 2, 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, -9, -9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -7, 0, 0, 0, 0, + -9, 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, -11, 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, -7, 0, 0, 0, + -4, -7, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -4, 0, + 0, 0, 0, -9, 0, -9, -9, -4, + -4, 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, -9, + 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, -4, + 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, -11, 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, + -7, -2, 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, -9, 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, -4, -11, 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, -4, -7, -7, 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, -11, 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, -7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -4, -7, 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, -4, -4, -4, + 0, 0, 0, 0, 0, 0, 0, -7, + -7, 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, -7, 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, + -9, -4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, + 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, -16, 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, -9, -9, 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, -4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -9, 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, 2, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -4, -4, -7, -7, 0, + 0, 0, 0, 0, 0, 0, 2, 2, + 2, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -11, 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, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -11, -11, 0, -7, 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, -22, -22, 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, -4, -7, 0, + 0, 0, 0, 0, -7, -4, -4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -11, + 0, 0, 0, 0, -11, -11, 0, 0, + 0, 0, -9, 0, 0, -4, 0, 0, + 0, 0, 0, 0, 0, 0, -4, 0, + -20, -9, -9, -4, 0, 0, 0, -4, + -4, 0, -4, -16, -11, 0, 0, 0, + 0, -2, 0, -9, -13, -22, 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, -4, -4, 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, -2, -2, + -2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, -4, -4, + 0, 0, 0, 0, 0, -7, -7, 0, + 0, -9, -9, 0, -4, 0, 0, 0, + -4, 0, 0, -4, -4, -4, 0, 0, + 0, 0, 0, 0, 0, -4, 0, 0, + -7, 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, -7, -4, + 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, + 0, 0, 0, 0, 0, 0, 0, 0, + -13, -13, 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, -4, -4, 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, -7, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -11, 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, -4, 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, -7, 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, -9, -9, 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, -7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -16, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -7, 0, -7, + 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, -7, -7, + 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, -9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -16, 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, + -20, -18, 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, -2, + 0, 0, -9, -9, 0, 0, 0, 0, + 0, -7, -4, 0, 0, -9, -9, 0, + 0, 0, 0, 0, 0, 0, -13, -11, + -11, -11, 0, 0, 0, 0, 0, 0, + 0, -18, -9, 0, 0, 0, 0, -7, + 0, 0, 0, -20, 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, -16, -18, 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, -4, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -16, 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, -18, -20, 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, -4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, -4, 0, 0, + 0, 0, -13, -9, -9, -9, 0, 0, + 0, -7, -7, 0, -7, -16, -7, 0, + 0, 0, 0, 0, -4, -7, 0, -22, + 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, -18, -18, + 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, -7, -4, 0, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -7, -4, -4, -4, + 0, 0, 0, 0, 0, 0, -2, -11, + -7, 0, 0, 0, 0, 0, 0, 0, + 0, -16, 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, -9, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 4, 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, -20, -20, 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, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -4, -9, -9, -9, 0, 0, + 0, 0, 0, 0, 0, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -16, + 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, -18, -16, + 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, -2, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -13, 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, + -4, -4, 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, -7, + -7, -7, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -7, 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, -7, -7, 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, -4, + -4, 0, 0, 0, 0, 0, 0, 0, + -4, -13, -13, -13, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -11, 0, -16, + 0, 0, 0, 0, 0, -7, 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, -16, -16, -7, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -4, 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, + -2, -2, 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, -7, 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, -13, -13, 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, + -7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -16, 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, -7, -7, 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, -7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -7, 0, + 0, 0, 0, 0, 0, 0, 0, -11, + 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, -11, -7, + 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, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -7, 0, 0, 0, 0, 0, 0, 0, + 0, -11, 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, + -13, -11, 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, -7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -4, 0, -2, 0, 0, 0, 0, + 0, 0, 0, -7, 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, -2, -2, 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, -11, 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, -18, -7, 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, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -11, + 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, -7, -7, + 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, -13, 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, -7, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -7, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -9, 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, + -7, -7, 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, -16, 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, -4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -11, 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, -4, -4, 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, -7, 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, -9, -4, 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, -4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -4, + 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, -11, -11, + 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, -11, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -7, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -18, 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, -4, 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, -4, -4, 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, -4, 0, -9, 0, + 0, -4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -4, + 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, -4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 7, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 11, + 0, 2, 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, 7, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 11, 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, -4, 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, -9, -9, 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, + -4, 0, 0, 0, 0, 0, 0, 0, + -2, 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, -7, 0, 0, + 0, 0, 0, 0, 0, 4, 0, -4, + 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, -7, -7, + 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, -7, 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, -11, 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, + -7, -7, 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, -7, 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, -4, 0, 0, + 0, 0, 0, -11, 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, -11, -7, 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, + -7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -11, 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, -13, -13, + -13, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -11, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -7, 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, + -18, -18, 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, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -18, -4, + -4, -4, 0, 0, 0, 0, 0, 0, + 0, -7, -4, 0, 0, 0, 0, 0, + 0, 0, 0, -16, 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, -4, 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, -4, 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, -4, 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, -4, -4, + -4, 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, -4, -4, + 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, -4, -4, + -4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -4, -2, -2, -2, + 0, 0, 0, 0, 0, 0, 0, -7, + -7, 0, 0, 0, 0, 0, 0, 0, + 0, -11, 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, + -13, -9, 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, -7, 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, -7, 0, 0, 0, -4, + 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, -4, 0, 0, 0, 0, + 0, 0, 0, -4, 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, 0, -4, 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, -13, -13, + 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, -7, 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, -11, -2, -4, -4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -11, 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, + -13, -13, 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, -4, -4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -4, -11, 0, + 0, 0, -7, -7, -7, 0, 0, 0, + 0, -4, -7, 0, 0, 0, 0, 0, + 0, 0, 0, -11, 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, -2, -2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -13, -13, 0, 0, 0, + 0, 0, 0, 0, -9, -9, -9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -9, -9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -4, -4, -4, -11, -11, 0, 0, 0, + 0, -4, 0, 0, 0, 0, 0, 0, + -13, -4, -2, -2, -13, -13, -13, 0, + 0, 0, 0, -7, -9, 0, 0, 0, + 0, 0, 0, -11, 0, 0 +}; + + +/*Collect the kern class' data in one place*/ +static const lv_font_fmt_txt_kern_classes_t kern_classes = { + .class_pair_values = kern_class_values, + .left_class_mapping = kern_left_class_mapping, + .right_class_mapping = kern_right_class_mapping, + .left_class_cnt = 155, + .right_class_cnt = 138, +}; + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LV_VERSION_CHECK(8, 0, 0) +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +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 = &kern_classes, + .kern_scale = 16, + .cmap_num = 6, + .bpp = 4, + .kern_classes = 1, + .bitmap_format = 0, +#if LV_VERSION_CHECK(8, 0, 0) + .cache = &cache +#endif +}; + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LVGL_VERSION_MAJOR >= 8 +const lv_font_t lv_font_source_han_sans_sc_14_cjk = { +#else +lv_font_t lv_font_source_han_sans_sc_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 = 17, /*The maximum line height required by the font*/ + .base_line = 4, /*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_SOURCE_HAN_SANS_SC_14_CJK*/ + diff --git a/lib/libesp32_lvgl/lvgl/src/font/lv_font_source_han_sans_sc_16_cjk.c b/lib/libesp32_lvgl/lvgl/src/font/lv_font_source_han_sans_sc_16_cjk.c new file mode 100644 index 000000000..b35aeef15 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/font/lv_font_source_han_sans_sc_16_cjk.c @@ -0,0 +1,27593 @@ +/******************************************************************************* + * Size: 16 px + * Bpp: 4 + * Opts: --no-compress --no-prefilter --bpp 4 --size 16 --font SourceHanSansSC-Normal.otf -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_source_han_sans_sc_16_cjk.c --force-fast-kern-format + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE + #include "lvgl.h" +#else + #include "../../lvgl.h" +#endif + +#ifndef LV_FONT_SOURCE_HAN_SANS_SC_16_CJK + #define LV_FONT_SOURCE_HAN_SANS_SC_16_CJK 1 +#endif + +#if LV_FONT_SOURCE_HAN_SANS_SC_16_CJK + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + + /* U+0021 "!" */ + 0x2f, 0x21, 0xf2, 0x1f, 0x11, 0xf1, 0xf, 0x0, + 0xf0, 0xf, 0x0, 0xf0, 0x9, 0x0, 0x0, 0x4f, + 0x43, 0xe3, + + /* U+0022 "\"" */ + 0x8d, 0x8, 0xd8, 0xc0, 0x8c, 0x7b, 0x7, 0xb5, + 0xa0, 0x59, 0x24, 0x2, 0x40, + + /* U+0023 "#" */ + 0x0, 0xd, 0x0, 0xb2, 0x0, 0x2, 0xb0, 0xd, + 0x0, 0x0, 0x48, 0x0, 0xd0, 0x0, 0xff, 0xff, + 0xff, 0xf3, 0x0, 0x85, 0x3, 0xa0, 0x0, 0xa, + 0x30, 0x58, 0x0, 0x0, 0xc1, 0x7, 0x60, 0x5, + 0xef, 0xfe, 0xff, 0xd0, 0x0, 0xd0, 0xa, 0x20, + 0x0, 0x1c, 0x0, 0xc1, 0x0, 0x3, 0xa0, 0xd, + 0x0, 0x0, 0x58, 0x0, 0xd0, 0x0, + + /* U+0024 "$" */ + 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xf0, 0x0, + 0x0, 0x6e, 0xfe, 0x80, 0x3, 0xf5, 0x3, 0xc3, + 0x8, 0xc0, 0x0, 0x0, 0x7, 0xd0, 0x0, 0x0, + 0x2, 0xf9, 0x0, 0x0, 0x0, 0x4e, 0xe5, 0x0, + 0x0, 0x0, 0x9f, 0x90, 0x0, 0x0, 0x4, 0xf6, + 0x0, 0x0, 0x0, 0xba, 0x0, 0x0, 0x0, 0xaa, + 0xc, 0x71, 0x2, 0xf5, 0x3, 0xcf, 0xef, 0x80, + 0x0, 0x1, 0xf0, 0x0, 0x0, 0x0, 0xf0, 0x0, + + /* U+0025 "%" */ + 0x3, 0xcd, 0x90, 0x0, 0x3, 0xb0, 0x0, 0xe, + 0x20, 0xa7, 0x0, 0xb, 0x20, 0x0, 0x3c, 0x0, + 0x3c, 0x0, 0x4a, 0x0, 0x0, 0x5a, 0x0, 0x2d, + 0x0, 0xc2, 0x0, 0x0, 0x3c, 0x0, 0x4c, 0x5, + 0x81, 0xbd, 0x80, 0xd, 0x30, 0xb6, 0xd, 0x1b, + 0x60, 0xa6, 0x2, 0xbc, 0x80, 0x77, 0x1e, 0x0, + 0x3c, 0x0, 0x0, 0x1, 0xd0, 0x3c, 0x0, 0x1e, + 0x0, 0x0, 0x8, 0x60, 0x3c, 0x0, 0x1e, 0x0, + 0x0, 0x1c, 0x0, 0x1e, 0x0, 0x3c, 0x0, 0x0, + 0x95, 0x0, 0xb, 0x50, 0xa7, 0x0, 0x2, 0xc0, + 0x0, 0x1, 0xcd, 0x90, + + /* U+0026 "&" */ + 0x0, 0xa, 0xed, 0x30, 0x0, 0x0, 0x8, 0xb0, + 0x6d, 0x0, 0x0, 0x0, 0xc5, 0x2, 0xe0, 0x0, + 0x0, 0xb, 0x60, 0x89, 0x0, 0x0, 0x0, 0x7b, + 0x9b, 0x0, 0x0, 0x0, 0x4, 0xfa, 0x0, 0x0, + 0x61, 0x5, 0xea, 0xe1, 0x0, 0x4e, 0x1, 0xf5, + 0xa, 0xb0, 0xa, 0x80, 0x5f, 0x0, 0xc, 0xb4, + 0xe1, 0x4, 0xf1, 0x0, 0xc, 0xf7, 0x0, 0xd, + 0xc3, 0x26, 0xec, 0xf8, 0x10, 0x1a, 0xee, 0xb4, + 0x4, 0xc4, + + /* U+0027 "'" */ + 0x8d, 0x8c, 0x7b, 0x5a, 0x24, + + /* U+0028 "(" */ + 0x0, 0x0, 0x0, 0x86, 0x1, 0xe0, 0x7, 0x80, + 0xd, 0x30, 0x1f, 0x0, 0x4c, 0x0, 0x6a, 0x0, + 0x79, 0x0, 0x79, 0x0, 0x6a, 0x0, 0x4c, 0x0, + 0x1f, 0x0, 0xd, 0x30, 0x7, 0x90, 0x1, 0xe0, + 0x0, 0x86, 0x0, 0x0, + + /* U+0029 ")" */ + 0x1, 0x0, 0x2d, 0x0, 0xa, 0x50, 0x4, 0xc0, + 0x0, 0xe2, 0x0, 0xa6, 0x0, 0x79, 0x0, 0x5b, + 0x0, 0x4c, 0x0, 0x5c, 0x0, 0x6b, 0x0, 0x89, + 0x0, 0xb5, 0x0, 0xe2, 0x4, 0xc0, 0xb, 0x50, + 0x2c, 0x0, 0x0, 0x0, + + /* U+002A "*" */ + 0x0, 0xc1, 0x0, 0x53, 0xd5, 0x60, 0x6d, 0xfe, + 0x81, 0x8, 0xdd, 0x0, 0xc, 0x19, 0x50, 0x0, + 0x0, 0x0, + + /* U+002B "+" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, 0x2e, + 0x0, 0x0, 0x6f, 0xff, 0xff, 0xff, 0x20, 0x0, + 0x2e, 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, + + /* U+002C "," */ + 0x7, 0xc1, 0x8, 0xf5, 0x0, 0xc4, 0x5, 0xc0, + 0xa, 0x0, + + /* U+002D "-" */ + 0x3e, 0xee, 0xb0, 0x11, 0x11, + + /* U+002E "." */ + 0x0, 0xa, 0xe0, 0x8d, 0x0, + + /* U+002F "/" */ + 0x0, 0x0, 0xe, 0x0, 0x0, 0x5, 0x90, 0x0, + 0x0, 0xa4, 0x0, 0x0, 0xe, 0x0, 0x0, 0x4, + 0xb0, 0x0, 0x0, 0x96, 0x0, 0x0, 0xe, 0x10, + 0x0, 0x3, 0xc0, 0x0, 0x0, 0x87, 0x0, 0x0, + 0xd, 0x20, 0x0, 0x2, 0xd0, 0x0, 0x0, 0x68, + 0x0, 0x0, 0xb, 0x30, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0x59, 0x0, 0x0, 0xa, 0x40, 0x0, 0x0, + + /* U+0030 "0" */ + 0x0, 0x4c, 0xeb, 0x20, 0x3, 0xf6, 0x29, 0xe0, + 0x9, 0xa0, 0x0, 0xd6, 0xf, 0x50, 0x0, 0x8b, + 0xf, 0x20, 0x0, 0x6d, 0x2f, 0x10, 0x0, 0x5f, + 0x2f, 0x10, 0x0, 0x5e, 0xf, 0x20, 0x0, 0x6d, + 0xe, 0x50, 0x0, 0x8b, 0x9, 0xa0, 0x0, 0xd6, + 0x2, 0xf7, 0x29, 0xe0, 0x0, 0x4c, 0xeb, 0x20, + + /* U+0031 "1" */ + 0x5, 0x9f, 0x50, 0x0, 0xaa, 0xf5, 0x0, 0x0, + 0xe, 0x50, 0x0, 0x0, 0xe5, 0x0, 0x0, 0xe, + 0x50, 0x0, 0x0, 0xe5, 0x0, 0x0, 0xe, 0x50, + 0x0, 0x0, 0xe5, 0x0, 0x0, 0xe, 0x50, 0x0, + 0x0, 0xe5, 0x0, 0x11, 0x1f, 0x61, 0x18, 0xff, + 0xff, 0xfb, + + /* U+0032 "2" */ + 0x1, 0x9d, 0xea, 0x10, 0x1e, 0x93, 0x3b, 0xd0, + 0x3, 0x0, 0x1, 0xf3, 0x0, 0x0, 0x0, 0xe5, + 0x0, 0x0, 0x1, 0xf3, 0x0, 0x0, 0x6, 0xe0, + 0x0, 0x0, 0xe, 0x60, 0x0, 0x0, 0xac, 0x0, + 0x0, 0x8, 0xe1, 0x0, 0x0, 0x7e, 0x30, 0x0, + 0x8, 0xf4, 0x11, 0x11, 0x4f, 0xff, 0xff, 0xff, + + /* U+0033 "3" */ + 0x1, 0x9d, 0xfc, 0x30, 0xc, 0x93, 0x3a, 0xf2, + 0x0, 0x0, 0x0, 0xe6, 0x0, 0x0, 0x0, 0xf5, + 0x0, 0x0, 0x2a, 0xb0, 0x0, 0x2f, 0xfb, 0x0, + 0x0, 0x2, 0x4b, 0xd1, 0x0, 0x0, 0x0, 0xba, + 0x0, 0x0, 0x0, 0x7d, 0x3, 0x0, 0x0, 0xab, + 0x3f, 0x84, 0x28, 0xf4, 0x3, 0xad, 0xfc, 0x40, + + /* U+0034 "4" */ + 0x0, 0x0, 0x1e, 0xa0, 0x0, 0x0, 0x9, 0xfa, + 0x0, 0x0, 0x3, 0xf9, 0xa0, 0x0, 0x0, 0xd8, + 0x8a, 0x0, 0x0, 0x6e, 0x8, 0xa0, 0x0, 0x1f, + 0x40, 0x8a, 0x0, 0xa, 0xa0, 0x8, 0xa0, 0x3, + 0xf1, 0x0, 0x8a, 0x0, 0xaf, 0xee, 0xef, 0xfe, + 0x31, 0x11, 0x11, 0x9b, 0x10, 0x0, 0x0, 0x8, + 0xa0, 0x0, 0x0, 0x0, 0x8a, 0x0, + + /* U+0035 "5" */ + 0x4, 0xff, 0xff, 0xf5, 0x5, 0xe1, 0x11, 0x10, + 0x6, 0xc0, 0x0, 0x0, 0x7, 0xb0, 0x0, 0x0, + 0x8, 0xca, 0xdb, 0x40, 0x5, 0x93, 0x39, 0xf3, + 0x0, 0x0, 0x0, 0xbb, 0x0, 0x0, 0x0, 0x7d, + 0x0, 0x0, 0x0, 0x7d, 0x2, 0x0, 0x0, 0xc9, + 0x4f, 0x83, 0x3a, 0xe1, 0x3, 0xbe, 0xeb, 0x20, + + /* U+0036 "6" */ + 0x0, 0x8, 0xde, 0xb2, 0x0, 0xc, 0xb4, 0x27, + 0x70, 0x5, 0xd0, 0x0, 0x0, 0x0, 0xb6, 0x0, + 0x0, 0x0, 0xf, 0x49, 0xed, 0x70, 0x0, 0xfd, + 0x61, 0x3e, 0x70, 0xf, 0x50, 0x0, 0x6d, 0x0, + 0xf4, 0x0, 0x3, 0xf0, 0xd, 0x70, 0x0, 0x3f, + 0x0, 0x7d, 0x0, 0x7, 0xc0, 0x1, 0xe9, 0x24, + 0xf4, 0x0, 0x1, 0xbe, 0xd5, 0x0, + + /* U+0037 "7" */ + 0x3f, 0xff, 0xff, 0xff, 0x0, 0x11, 0x11, 0x1c, + 0x90, 0x0, 0x0, 0x4, 0xe0, 0x0, 0x0, 0x0, + 0xd5, 0x0, 0x0, 0x0, 0x4e, 0x0, 0x0, 0x0, + 0xb, 0x80, 0x0, 0x0, 0x0, 0xf3, 0x0, 0x0, + 0x0, 0x3f, 0x0, 0x0, 0x0, 0x7, 0xd0, 0x0, + 0x0, 0x0, 0x9b, 0x0, 0x0, 0x0, 0xa, 0xa0, + 0x0, 0x0, 0x0, 0xc9, 0x0, 0x0, + + /* U+0038 "8" */ + 0x0, 0x5d, 0xfd, 0x50, 0x0, 0x4f, 0x40, 0x5f, + 0x30, 0x9, 0x90, 0x0, 0x98, 0x0, 0x8a, 0x0, + 0x9, 0x80, 0x2, 0xe4, 0x0, 0xd3, 0x0, 0x5, + 0xfb, 0xa6, 0x0, 0x3, 0xd4, 0x8f, 0xa0, 0x0, + 0xe5, 0x0, 0x1c, 0xa0, 0x3f, 0x0, 0x0, 0x5f, + 0x2, 0xf1, 0x0, 0x5, 0xe0, 0xb, 0xc3, 0x3, + 0xd8, 0x0, 0x8, 0xdf, 0xd7, 0x0, + + /* U+0039 "9" */ + 0x0, 0x8e, 0xe9, 0x0, 0xa, 0xc2, 0x2a, 0xc0, + 0x1f, 0x20, 0x0, 0xd5, 0x3f, 0x0, 0x0, 0x8a, + 0x2f, 0x10, 0x0, 0x7c, 0xc, 0xb1, 0x17, 0xee, + 0x1, 0xae, 0xd7, 0x7d, 0x0, 0x0, 0x0, 0x8b, + 0x0, 0x0, 0x0, 0xc8, 0x0, 0x0, 0x3, 0xf1, + 0xb, 0x72, 0x5e, 0x80, 0x3, 0xbf, 0xd6, 0x0, + + /* U+003A ":" */ + 0x8d, 0xa, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0xe0, 0x8d, 0x0, + + /* U+003B ";" */ + 0x8, 0xd0, 0xa, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xc1, + 0x8, 0xf5, 0x0, 0xc4, 0x5, 0xc0, 0xa, 0x0, + + /* U+003C "<" */ + 0x0, 0x0, 0x0, 0x5, 0x10, 0x0, 0x2, 0x8e, + 0xd1, 0x0, 0x5b, 0xe9, 0x30, 0x4, 0xeb, 0x50, + 0x0, 0x0, 0x3d, 0xc6, 0x0, 0x0, 0x0, 0x4, + 0xaf, 0xa3, 0x0, 0x0, 0x0, 0x17, 0xed, 0x10, + 0x0, 0x0, 0x0, 0x41, + + /* U+003D "=" */ + 0x6f, 0xff, 0xff, 0xff, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0xff, 0xff, 0xff, 0x20, + + /* U+003E ">" */ + 0x33, 0x0, 0x0, 0x0, 0x3, 0xed, 0x61, 0x0, + 0x0, 0x0, 0x4a, 0xfa, 0x30, 0x0, 0x0, 0x1, + 0x6d, 0xd1, 0x0, 0x0, 0x17, 0xdc, 0x10, 0x5, + 0xbe, 0x93, 0x0, 0x4e, 0xc6, 0x0, 0x0, 0x3, + 0x30, 0x0, 0x0, 0x0, + + /* U+003F "?" */ + 0x3, 0xbe, 0xd6, 0x1, 0xd6, 0x26, 0xf4, 0x0, + 0x0, 0xc, 0x90, 0x0, 0x0, 0xe6, 0x0, 0x0, + 0x6e, 0x0, 0x0, 0x3f, 0x30, 0x0, 0xc, 0x70, + 0x0, 0x1, 0xf1, 0x0, 0x0, 0x5, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4f, 0x40, 0x0, 0x3, + 0xe3, 0x0, + + /* U+0040 "@" */ + 0x0, 0x0, 0x6, 0xce, 0xec, 0x81, 0x0, 0x0, + 0x0, 0x2c, 0x93, 0x0, 0x27, 0xe4, 0x0, 0x0, + 0x2e, 0x40, 0x0, 0x0, 0x3, 0xe1, 0x0, 0xc, + 0x50, 0x0, 0x0, 0x0, 0x8, 0x80, 0x7, 0xa0, + 0x0, 0x7c, 0xba, 0x40, 0x2c, 0x0, 0xc3, 0x0, + 0x99, 0x3, 0xf1, 0x0, 0xe0, 0xf, 0x0, 0x2e, + 0x0, 0x1e, 0x0, 0xe, 0x1, 0xe0, 0x7, 0x90, + 0x4, 0xb0, 0x1, 0xd0, 0xf, 0x0, 0x88, 0x0, + 0x79, 0x0, 0x68, 0x0, 0xc3, 0x5, 0xc0, 0x3c, + 0xb0, 0x3c, 0x0, 0x8, 0xa0, 0x8, 0xc9, 0x8, + 0xca, 0x10, 0x0, 0xd, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2d, 0xa3, 0x10, 0x15, 0x20, + 0x0, 0x0, 0x0, 0x6, 0xad, 0xec, 0x71, 0x0, + 0x0, + + /* U+0041 "A" */ + 0x0, 0x1, 0xfb, 0x0, 0x0, 0x0, 0x6, 0xbf, + 0x0, 0x0, 0x0, 0xc, 0x5c, 0x50, 0x0, 0x0, + 0x1f, 0x7, 0xb0, 0x0, 0x0, 0x6b, 0x2, 0xf0, + 0x0, 0x0, 0xc6, 0x0, 0xd5, 0x0, 0x1, 0xf1, + 0x0, 0x8b, 0x0, 0x6, 0xfe, 0xee, 0xff, 0x10, + 0xc, 0x81, 0x11, 0x2e, 0x50, 0x1f, 0x20, 0x0, + 0x9, 0xb0, 0x6d, 0x0, 0x0, 0x5, 0xf1, 0xc8, + 0x0, 0x0, 0x0, 0xf6, + + /* U+0042 "B" */ + 0x5f, 0xff, 0xfd, 0x70, 0x5, 0xf0, 0x11, 0x5e, + 0x90, 0x5f, 0x0, 0x0, 0x6e, 0x5, 0xf0, 0x0, + 0x5, 0xd0, 0x5f, 0x0, 0x3, 0xd7, 0x5, 0xfe, + 0xef, 0xfa, 0x0, 0x5f, 0x11, 0x24, 0xbd, 0x15, + 0xf0, 0x0, 0x0, 0xd8, 0x5f, 0x0, 0x0, 0xa, + 0xa5, 0xf0, 0x0, 0x0, 0xd7, 0x5f, 0x11, 0x14, + 0xbe, 0x15, 0xff, 0xff, 0xd9, 0x10, + + /* U+0043 "C" */ + 0x0, 0x3, 0xae, 0xea, 0x20, 0x0, 0x6f, 0x95, + 0x49, 0xe1, 0x2, 0xf6, 0x0, 0x0, 0x10, 0xa, + 0xc0, 0x0, 0x0, 0x0, 0xd, 0x70, 0x0, 0x0, + 0x0, 0xf, 0x50, 0x0, 0x0, 0x0, 0xf, 0x50, + 0x0, 0x0, 0x0, 0xd, 0x70, 0x0, 0x0, 0x0, + 0xa, 0xc0, 0x0, 0x0, 0x0, 0x2, 0xf6, 0x0, + 0x0, 0x30, 0x0, 0x7f, 0x94, 0x49, 0xf3, 0x0, + 0x4, 0xbe, 0xea, 0x30, + + /* U+0044 "D" */ + 0x5f, 0xff, 0xda, 0x30, 0x5, 0xf1, 0x24, 0x9f, + 0x60, 0x5f, 0x0, 0x0, 0x6f, 0x25, 0xf0, 0x0, + 0x0, 0xd9, 0x5f, 0x0, 0x0, 0x8, 0xc5, 0xf0, + 0x0, 0x0, 0x6e, 0x5f, 0x0, 0x0, 0x7, 0xe5, + 0xf0, 0x0, 0x0, 0x9c, 0x5f, 0x0, 0x0, 0xd, + 0x95, 0xf0, 0x0, 0x7, 0xf1, 0x5f, 0x12, 0x5a, + 0xf6, 0x5, 0xff, 0xfd, 0xa3, 0x0, + + /* U+0045 "E" */ + 0x5f, 0xff, 0xff, 0xf4, 0x5f, 0x11, 0x11, 0x10, + 0x5f, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x0, + 0x5f, 0x0, 0x0, 0x0, 0x5f, 0xff, 0xff, 0x70, + 0x5f, 0x22, 0x22, 0x10, 0x5f, 0x0, 0x0, 0x0, + 0x5f, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x0, + 0x5f, 0x22, 0x22, 0x21, 0x5f, 0xff, 0xff, 0xf7, + + /* U+0046 "F" */ + 0x5f, 0xff, 0xff, 0xf4, 0x5f, 0x11, 0x11, 0x10, + 0x5f, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x0, + 0x5f, 0x0, 0x0, 0x0, 0x5f, 0xff, 0xff, 0x70, + 0x5f, 0x22, 0x22, 0x10, 0x5f, 0x0, 0x0, 0x0, + 0x5f, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x0, + 0x5f, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x0, + + /* U+0047 "G" */ + 0x0, 0x2, 0xad, 0xeb, 0x50, 0x0, 0x6f, 0xa5, + 0x47, 0xe5, 0x1, 0xf7, 0x0, 0x0, 0x10, 0x9, + 0xd0, 0x0, 0x0, 0x0, 0xd, 0x80, 0x0, 0x0, + 0x0, 0xf, 0x50, 0x0, 0x0, 0x0, 0xf, 0x50, + 0x0, 0xff, 0xfb, 0xd, 0x70, 0x0, 0x22, 0x9b, + 0xa, 0xd0, 0x0, 0x0, 0x7b, 0x2, 0xf6, 0x0, + 0x0, 0x7b, 0x0, 0x6f, 0xa5, 0x36, 0xda, 0x0, + 0x3, 0xad, 0xec, 0x70, + + /* U+0048 "H" */ + 0x5f, 0x0, 0x0, 0x6, 0xe5, 0xf0, 0x0, 0x0, + 0x6e, 0x5f, 0x0, 0x0, 0x6, 0xe5, 0xf0, 0x0, + 0x0, 0x6e, 0x5f, 0x0, 0x0, 0x6, 0xe5, 0xff, + 0xff, 0xff, 0xfe, 0x5f, 0x22, 0x22, 0x27, 0xe5, + 0xf0, 0x0, 0x0, 0x6e, 0x5f, 0x0, 0x0, 0x6, + 0xe5, 0xf0, 0x0, 0x0, 0x6e, 0x5f, 0x0, 0x0, + 0x6, 0xe5, 0xf0, 0x0, 0x0, 0x6e, + + /* U+0049 "I" */ + 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, + 0x5f, 0x5f, 0x5f, 0x5f, + + /* U+004A "J" */ + 0x0, 0x0, 0x6, 0xe0, 0x0, 0x0, 0x6e, 0x0, + 0x0, 0x6, 0xe0, 0x0, 0x0, 0x6e, 0x0, 0x0, + 0x6, 0xe0, 0x0, 0x0, 0x6e, 0x0, 0x0, 0x6, + 0xe0, 0x0, 0x0, 0x6e, 0x0, 0x0, 0x7, 0xd0, + 0x40, 0x0, 0xab, 0x2e, 0x93, 0x6f, 0x50, 0x3a, + 0xed, 0x70, + + /* U+004B "K" */ + 0x5f, 0x0, 0x0, 0x5f, 0x30, 0x5f, 0x0, 0x3, + 0xf5, 0x0, 0x5f, 0x0, 0x1e, 0x80, 0x0, 0x5f, + 0x0, 0xcb, 0x0, 0x0, 0x5f, 0xa, 0xf1, 0x0, + 0x0, 0x5f, 0x7f, 0xe7, 0x0, 0x0, 0x5f, 0xf5, + 0x6e, 0x10, 0x0, 0x5f, 0x70, 0xd, 0x90, 0x0, + 0x5f, 0x0, 0x4, 0xf2, 0x0, 0x5f, 0x0, 0x0, + 0xbb, 0x0, 0x5f, 0x0, 0x0, 0x3f, 0x40, 0x5f, + 0x0, 0x0, 0x9, 0xd0, + + /* U+004C "L" */ + 0x5f, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x0, + 0x5f, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x0, + 0x5f, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x0, + 0x5f, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x0, + 0x5f, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x0, + 0x5f, 0x22, 0x22, 0x20, 0x5f, 0xff, 0xff, 0xf2, + + /* U+004D "M" */ + 0x5f, 0x60, 0x0, 0x0, 0x9f, 0x35, 0xfc, 0x0, + 0x0, 0xe, 0xf3, 0x5b, 0xe2, 0x0, 0x4, 0xce, + 0x35, 0xc9, 0x70, 0x0, 0x97, 0xe3, 0x5c, 0x4d, + 0x0, 0xe, 0x1f, 0x35, 0xd0, 0xe2, 0x5, 0xb0, + 0xf3, 0x5d, 0x9, 0x80, 0xa6, 0xf, 0x35, 0xd0, + 0x3d, 0xe, 0x10, 0xf3, 0x5d, 0x0, 0xd8, 0xa0, + 0xf, 0x35, 0xd0, 0x7, 0xf5, 0x0, 0xf3, 0x5d, + 0x0, 0x2b, 0x0, 0xf, 0x35, 0xd0, 0x0, 0x0, + 0x0, 0xf3, + + /* U+004E "N" */ + 0x5f, 0x40, 0x0, 0x6, 0xd5, 0xfd, 0x0, 0x0, + 0x6d, 0x5c, 0xc6, 0x0, 0x6, 0xd5, 0xc4, 0xe0, + 0x0, 0x6d, 0x5d, 0xc, 0x80, 0x6, 0xd5, 0xe0, + 0x3f, 0x20, 0x6d, 0x5e, 0x0, 0xaa, 0x6, 0xd5, + 0xe0, 0x1, 0xf4, 0x5d, 0x5e, 0x0, 0x7, 0xc4, + 0xd5, 0xe0, 0x0, 0xe, 0x9d, 0x5e, 0x0, 0x0, + 0x5f, 0xd5, 0xe0, 0x0, 0x0, 0xcd, + + /* U+004F "O" */ + 0x0, 0x4, 0xbe, 0xda, 0x20, 0x0, 0x7, 0xf8, + 0x45, 0xaf, 0x40, 0x2, 0xf5, 0x0, 0x0, 0x8e, + 0x0, 0xac, 0x0, 0x0, 0x0, 0xf6, 0xd, 0x70, + 0x0, 0x0, 0xb, 0xa0, 0xf5, 0x0, 0x0, 0x0, + 0x9c, 0xf, 0x50, 0x0, 0x0, 0x9, 0xc0, 0xd7, + 0x0, 0x0, 0x0, 0xb9, 0xa, 0xc0, 0x0, 0x0, + 0x1f, 0x60, 0x2f, 0x60, 0x0, 0x9, 0xe0, 0x0, + 0x7f, 0x94, 0x5a, 0xf4, 0x0, 0x0, 0x4b, 0xed, + 0xa2, 0x0, + + /* U+0050 "P" */ + 0x5f, 0xff, 0xed, 0x70, 0x5, 0xf1, 0x12, 0x6e, + 0xa0, 0x5f, 0x0, 0x0, 0x4f, 0x5, 0xf0, 0x0, + 0x2, 0xf2, 0x5f, 0x0, 0x0, 0x4f, 0x5, 0xf0, + 0x0, 0x4d, 0x90, 0x5f, 0xff, 0xfe, 0x80, 0x5, + 0xf2, 0x21, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x0, + 0x5, 0xf0, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, + 0x0, 0x5, 0xf0, 0x0, 0x0, 0x0, + + /* U+0051 "Q" */ + 0x0, 0x4, 0xbe, 0xda, 0x20, 0x0, 0x0, 0x7f, + 0x94, 0x5a, 0xf4, 0x0, 0x2, 0xf6, 0x0, 0x0, + 0x9e, 0x0, 0x9, 0xd0, 0x0, 0x0, 0x1f, 0x60, + 0xd, 0x80, 0x0, 0x0, 0xb, 0x90, 0xf, 0x50, + 0x0, 0x0, 0x9, 0xb0, 0xf, 0x50, 0x0, 0x0, + 0x8, 0xc0, 0xe, 0x70, 0x0, 0x0, 0xa, 0xa0, + 0xb, 0xa0, 0x0, 0x0, 0xd, 0x80, 0x5, 0xf1, + 0x0, 0x0, 0x5f, 0x10, 0x0, 0xcd, 0x10, 0x3, + 0xe9, 0x0, 0x0, 0xb, 0xfc, 0xdf, 0x80, 0x0, + 0x0, 0x0, 0x1b, 0xe1, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xeb, 0x30, 0x0, 0x0, 0x0, 0x0, 0x2b, + 0xff, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + + /* U+0052 "R" */ + 0x5f, 0xff, 0xfd, 0x80, 0x5, 0xf1, 0x12, 0x5d, + 0xa0, 0x5f, 0x0, 0x0, 0x4f, 0x15, 0xf0, 0x0, + 0x1, 0xf3, 0x5f, 0x0, 0x0, 0x4f, 0x15, 0xf0, + 0x0, 0x3d, 0xa0, 0x5f, 0xee, 0xff, 0x90, 0x5, + 0xf1, 0x1a, 0xd0, 0x0, 0x5f, 0x0, 0x1e, 0x70, + 0x5, 0xf0, 0x0, 0x6f, 0x10, 0x5f, 0x0, 0x0, + 0xca, 0x5, 0xf0, 0x0, 0x3, 0xf4, + + /* U+0053 "S" */ + 0x0, 0x3b, 0xee, 0xa2, 0x0, 0x2f, 0xa5, 0x49, + 0xf2, 0x8, 0xc0, 0x0, 0x1, 0x0, 0x8d, 0x0, + 0x0, 0x0, 0x3, 0xfa, 0x20, 0x0, 0x0, 0x3, + 0xcf, 0xa3, 0x0, 0x0, 0x0, 0x4b, 0xf9, 0x0, + 0x0, 0x0, 0x4, 0xf7, 0x0, 0x0, 0x0, 0xa, + 0xb0, 0x61, 0x0, 0x0, 0xc9, 0xc, 0xe7, 0x44, + 0xaf, 0x20, 0x7, 0xbe, 0xea, 0x20, + + /* U+0054 "T" */ + 0x7f, 0xff, 0xff, 0xff, 0xf0, 0x1, 0x11, 0xe7, + 0x11, 0x10, 0x0, 0x0, 0xe6, 0x0, 0x0, 0x0, + 0x0, 0xe6, 0x0, 0x0, 0x0, 0x0, 0xe6, 0x0, + 0x0, 0x0, 0x0, 0xe6, 0x0, 0x0, 0x0, 0x0, + 0xe6, 0x0, 0x0, 0x0, 0x0, 0xe6, 0x0, 0x0, + 0x0, 0x0, 0xe6, 0x0, 0x0, 0x0, 0x0, 0xe6, + 0x0, 0x0, 0x0, 0x0, 0xe6, 0x0, 0x0, 0x0, + 0x0, 0xe6, 0x0, 0x0, + + /* U+0055 "U" */ + 0x6e, 0x0, 0x0, 0x6, 0xd6, 0xe0, 0x0, 0x0, + 0x6d, 0x6e, 0x0, 0x0, 0x6, 0xd6, 0xe0, 0x0, + 0x0, 0x6d, 0x6e, 0x0, 0x0, 0x6, 0xd6, 0xe0, + 0x0, 0x0, 0x6d, 0x6e, 0x0, 0x0, 0x6, 0xd5, + 0xf0, 0x0, 0x0, 0x7c, 0x3f, 0x10, 0x0, 0x9, + 0xa0, 0xe7, 0x0, 0x0, 0xe7, 0x6, 0xf7, 0x35, + 0xcd, 0x0, 0x5, 0xcf, 0xe9, 0x10, + + /* U+0056 "V" */ + 0xc9, 0x0, 0x0, 0x6, 0xe0, 0x7d, 0x0, 0x0, + 0xb, 0x90, 0x2f, 0x20, 0x0, 0xf, 0x40, 0xd, + 0x70, 0x0, 0x4f, 0x0, 0x8, 0xb0, 0x0, 0x9a, + 0x0, 0x3, 0xf0, 0x0, 0xe5, 0x0, 0x0, 0xe5, + 0x2, 0xf0, 0x0, 0x0, 0x9a, 0x7, 0xb0, 0x0, + 0x0, 0x4e, 0xc, 0x60, 0x0, 0x0, 0xf, 0x4f, + 0x10, 0x0, 0x0, 0xa, 0xdc, 0x0, 0x0, 0x0, + 0x5, 0xf7, 0x0, 0x0, + + /* U+0057 "W" */ + 0x7e, 0x0, 0x0, 0xbb, 0x0, 0x0, 0xe6, 0x3f, + 0x10, 0x0, 0xff, 0x0, 0x1, 0xf2, 0xf, 0x40, + 0x3, 0xcd, 0x30, 0x4, 0xf0, 0xd, 0x70, 0x7, + 0x99, 0x70, 0x7, 0xc0, 0x9, 0xa0, 0xb, 0x56, + 0xb0, 0xa, 0x80, 0x6, 0xd0, 0xf, 0x12, 0xf0, + 0xd, 0x50, 0x3, 0xf0, 0x3d, 0x0, 0xe4, 0x1f, + 0x20, 0x0, 0xf3, 0x79, 0x0, 0xa7, 0x3f, 0x0, + 0x0, 0xc6, 0xa5, 0x0, 0x6b, 0x6b, 0x0, 0x0, + 0x99, 0xe1, 0x0, 0x2e, 0x98, 0x0, 0x0, 0x5e, + 0xe0, 0x0, 0xe, 0xe5, 0x0, 0x0, 0x2f, 0xa0, + 0x0, 0xa, 0xf2, 0x0, + + /* U+0058 "X" */ + 0x3f, 0x30, 0x0, 0x2f, 0x30, 0xab, 0x0, 0xa, + 0xb0, 0x2, 0xf4, 0x2, 0xf2, 0x0, 0x8, 0xc0, + 0xb9, 0x0, 0x0, 0x1e, 0x8f, 0x10, 0x0, 0x0, + 0x7f, 0x80, 0x0, 0x0, 0xa, 0xfa, 0x0, 0x0, + 0x3, 0xe3, 0xf3, 0x0, 0x0, 0xc8, 0x9, 0xc0, + 0x0, 0x5e, 0x0, 0x1f, 0x50, 0xd, 0x70, 0x0, + 0x8d, 0x7, 0xe0, 0x0, 0x0, 0xe7, + + /* U+0059 "Y" */ + 0xca, 0x0, 0x0, 0x3f, 0x24, 0xf1, 0x0, 0xb, + 0xa0, 0xc, 0x80, 0x2, 0xf2, 0x0, 0x5e, 0x0, + 0x9a, 0x0, 0x0, 0xd6, 0x1f, 0x20, 0x0, 0x5, + 0xd8, 0xb0, 0x0, 0x0, 0xd, 0xf3, 0x0, 0x0, + 0x0, 0x8d, 0x0, 0x0, 0x0, 0x7, 0xd0, 0x0, + 0x0, 0x0, 0x7d, 0x0, 0x0, 0x0, 0x7, 0xd0, + 0x0, 0x0, 0x0, 0x7d, 0x0, 0x0, + + /* U+005A "Z" */ + 0x9, 0xff, 0xff, 0xff, 0xc0, 0x11, 0x11, 0x14, + 0xf5, 0x0, 0x0, 0x0, 0xbb, 0x0, 0x0, 0x0, + 0x5f, 0x10, 0x0, 0x0, 0x1e, 0x70, 0x0, 0x0, + 0x9, 0xc0, 0x0, 0x0, 0x3, 0xf3, 0x0, 0x0, + 0x0, 0xd9, 0x0, 0x0, 0x0, 0x7e, 0x0, 0x0, + 0x0, 0x2f, 0x50, 0x0, 0x0, 0xc, 0xc2, 0x22, + 0x22, 0x12, 0xff, 0xff, 0xff, 0xfd, + + /* U+005B "[" */ + 0x4e, 0xc9, 0x4a, 0x0, 0x4a, 0x0, 0x4a, 0x0, + 0x4a, 0x0, 0x4a, 0x0, 0x4a, 0x0, 0x4a, 0x0, + 0x4a, 0x0, 0x4a, 0x0, 0x4a, 0x0, 0x4a, 0x0, + 0x4a, 0x0, 0x4a, 0x0, 0x4a, 0x0, 0x4d, 0xb9, + + /* U+005C "\\" */ + 0xa5, 0x0, 0x0, 0x5, 0xa0, 0x0, 0x0, 0xe, + 0x0, 0x0, 0x0, 0xb4, 0x0, 0x0, 0x6, 0x80, + 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0xc2, 0x0, + 0x0, 0x7, 0x70, 0x0, 0x0, 0x2c, 0x0, 0x0, + 0x0, 0xd1, 0x0, 0x0, 0x8, 0x60, 0x0, 0x0, + 0x3b, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xa, + 0x50, 0x0, 0x0, 0x5a, 0x0, 0x0, 0x0, 0xe0, + + /* U+005D "]" */ + 0x6c, 0xd9, 0x0, 0x59, 0x0, 0x59, 0x0, 0x59, + 0x0, 0x59, 0x0, 0x59, 0x0, 0x59, 0x0, 0x59, + 0x0, 0x59, 0x0, 0x59, 0x0, 0x59, 0x0, 0x59, + 0x0, 0x59, 0x0, 0x59, 0x0, 0x59, 0x5b, 0xc8, + + /* U+005E "^" */ + 0x0, 0x6f, 0x20, 0x0, 0xc, 0xb8, 0x0, 0x2, + 0xe2, 0xe0, 0x0, 0x88, 0xc, 0x50, 0xe, 0x20, + 0x6b, 0x5, 0xc0, 0x0, 0xf1, 0xb6, 0x0, 0xa, + 0x70, + + /* U+005F "_" */ + 0xbe, 0xee, 0xee, 0xee, 0xa0, + + /* U+0060 "`" */ + 0x0, 0x0, 0x3b, 0x0, 0x1d, 0x90, 0x1, 0xd6, + 0x0, 0x14, + + /* U+0061 "a" */ + 0x0, 0x7c, 0xfd, 0x50, 0x6, 0xb4, 0x27, 0xf2, + 0x0, 0x0, 0x0, 0xe7, 0x0, 0x1, 0x47, 0xe9, + 0x0, 0xae, 0x96, 0xc9, 0xb, 0xa0, 0x0, 0xa9, + 0xf, 0x40, 0x0, 0xb9, 0xd, 0xb2, 0x3b, 0xe9, + 0x3, 0xcf, 0xc4, 0x79, + + /* U+0062 "b" */ + 0x7c, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, + 0x7c, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, + 0x7c, 0x4b, 0xfc, 0x40, 0x7f, 0xc4, 0x28, 0xf3, + 0x7d, 0x0, 0x0, 0xba, 0x7c, 0x0, 0x0, 0x7d, + 0x7c, 0x0, 0x0, 0x6e, 0x7c, 0x0, 0x0, 0x8c, + 0x7d, 0x0, 0x0, 0xe8, 0x7f, 0xa3, 0x3b, 0xe1, + 0x79, 0x6d, 0xea, 0x10, + + /* U+0063 "c" */ + 0x0, 0x2a, 0xee, 0x90, 0x2, 0xfa, 0x33, 0xa2, + 0xb, 0xb0, 0x0, 0x0, 0xf, 0x50, 0x0, 0x0, + 0x1f, 0x30, 0x0, 0x0, 0xf, 0x50, 0x0, 0x0, + 0xc, 0xb0, 0x0, 0x0, 0x3, 0xf9, 0x33, 0x96, + 0x0, 0x3b, 0xed, 0x91, + + /* U+0064 "d" */ + 0x0, 0x0, 0x0, 0xf, 0x50, 0x0, 0x0, 0x0, + 0xf5, 0x0, 0x0, 0x0, 0xf, 0x50, 0x0, 0x0, + 0x0, 0xf5, 0x0, 0x3b, 0xfd, 0x5e, 0x50, 0x2f, + 0x93, 0x3b, 0xf5, 0xb, 0xb0, 0x0, 0xf, 0x50, + 0xf5, 0x0, 0x0, 0xf5, 0x1f, 0x30, 0x0, 0xf, + 0x50, 0xf5, 0x0, 0x0, 0xf5, 0xd, 0xa0, 0x0, + 0xf, 0x50, 0x5f, 0x83, 0x5d, 0xf5, 0x0, 0x5d, + 0xfb, 0x3c, 0x50, + + /* U+0065 "e" */ + 0x0, 0x2b, 0xed, 0x60, 0x0, 0x2f, 0x72, 0x4d, + 0x60, 0xb, 0x90, 0x0, 0x5d, 0x0, 0xf3, 0x0, + 0x1, 0xf0, 0x1f, 0xff, 0xff, 0xff, 0x10, 0xf3, + 0x0, 0x0, 0x0, 0xb, 0x90, 0x0, 0x0, 0x0, + 0x2f, 0x82, 0x25, 0x50, 0x0, 0x2b, 0xee, 0xb3, + 0x0, + + /* U+0066 "f" */ + 0x0, 0x5d, 0xd5, 0x1, 0xf8, 0x31, 0x4, 0xf1, + 0x0, 0x4, 0xf0, 0x0, 0x7f, 0xff, 0xe0, 0x5, + 0xf1, 0x10, 0x4, 0xf0, 0x0, 0x4, 0xf0, 0x0, + 0x4, 0xf0, 0x0, 0x4, 0xf0, 0x0, 0x4, 0xf0, + 0x0, 0x4, 0xf0, 0x0, 0x4, 0xf0, 0x0, + + /* U+0067 "g" */ + 0x0, 0x6d, 0xff, 0xff, 0x80, 0x5e, 0x30, 0x6f, + 0x20, 0xb, 0x80, 0x0, 0xc6, 0x0, 0xb8, 0x0, + 0xc, 0x50, 0x4, 0xe3, 0x6, 0xe1, 0x0, 0xd, + 0xce, 0xb2, 0x0, 0x7, 0x80, 0x0, 0x0, 0x0, + 0x8c, 0x21, 0x10, 0x0, 0x2, 0xff, 0xff, 0xfc, + 0x20, 0xb6, 0x0, 0x2, 0xe9, 0x1f, 0x10, 0x0, + 0xb, 0x80, 0xe9, 0x10, 0x7, 0xe2, 0x2, 0xae, + 0xed, 0x92, 0x0, + + /* U+0068 "h" */ + 0x7c, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, + 0x7c, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, + 0x7c, 0x2a, 0xed, 0x40, 0x7e, 0xd6, 0x3b, 0xe0, + 0x7e, 0x10, 0x2, 0xf3, 0x7c, 0x0, 0x0, 0xf4, + 0x7c, 0x0, 0x0, 0xf4, 0x7c, 0x0, 0x0, 0xf4, + 0x7c, 0x0, 0x0, 0xf4, 0x7c, 0x0, 0x0, 0xf4, + 0x7c, 0x0, 0x0, 0xf4, + + /* U+0069 "i" */ + 0x8d, 0x6, 0xa0, 0x0, 0x0, 0x0, 0x7c, 0x7, + 0xc0, 0x7c, 0x7, 0xc0, 0x7c, 0x7, 0xc0, 0x7c, + 0x7, 0xc0, 0x7c, 0x0, + + /* U+006A "j" */ + 0x0, 0x8d, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7d, 0x0, 0x7, 0xd0, 0x0, + 0x7d, 0x0, 0x7, 0xd0, 0x0, 0x7d, 0x0, 0x7, + 0xd0, 0x0, 0x7d, 0x0, 0x7, 0xd0, 0x0, 0x7d, + 0x0, 0x7, 0xd0, 0x0, 0x8c, 0x1, 0x2d, 0x90, + 0x7f, 0xc1, 0x0, + + /* U+006B "k" */ + 0x7c, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, + 0x7c, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, + 0x7c, 0x0, 0xb, 0xb0, 0x7c, 0x0, 0x8d, 0x10, + 0x7c, 0x4, 0xf2, 0x0, 0x7c, 0x2e, 0x70, 0x0, + 0x7d, 0xcd, 0xc0, 0x0, 0x7f, 0xa0, 0xe6, 0x0, + 0x7e, 0x0, 0x5e, 0x10, 0x7c, 0x0, 0xc, 0x90, + 0x7c, 0x0, 0x3, 0xf3, + + /* U+006C "l" */ + 0x7c, 0x7, 0xc0, 0x7c, 0x7, 0xc0, 0x7c, 0x7, + 0xc0, 0x7c, 0x7, 0xc0, 0x7c, 0x7, 0xc0, 0x7c, + 0x6, 0xe1, 0x2d, 0x90, + + /* U+006D "m" */ + 0x79, 0x2b, 0xea, 0x11, 0x9e, 0xd4, 0x7, 0xdc, + 0x53, 0xdb, 0xc7, 0x3a, 0xe0, 0x7e, 0x10, 0x6, + 0xf3, 0x0, 0x1f, 0x37, 0xc0, 0x0, 0x4f, 0x0, + 0x0, 0xf4, 0x7c, 0x0, 0x3, 0xf0, 0x0, 0xf, + 0x47, 0xc0, 0x0, 0x3f, 0x0, 0x0, 0xf4, 0x7c, + 0x0, 0x3, 0xf0, 0x0, 0xf, 0x47, 0xc0, 0x0, + 0x3f, 0x0, 0x0, 0xf4, 0x7c, 0x0, 0x3, 0xf0, + 0x0, 0xf, 0x40, + + /* U+006E "n" */ + 0x79, 0x2a, 0xed, 0x40, 0x7d, 0xd6, 0x3b, 0xe0, + 0x7e, 0x10, 0x2, 0xf3, 0x7c, 0x0, 0x0, 0xf4, + 0x7c, 0x0, 0x0, 0xf4, 0x7c, 0x0, 0x0, 0xf4, + 0x7c, 0x0, 0x0, 0xf4, 0x7c, 0x0, 0x0, 0xf4, + 0x7c, 0x0, 0x0, 0xf4, + + /* U+006F "o" */ + 0x0, 0x2b, 0xed, 0x80, 0x0, 0x2f, 0x93, 0x4d, + 0xc0, 0xb, 0xb0, 0x0, 0x1f, 0x50, 0xf5, 0x0, + 0x0, 0xb9, 0x1f, 0x30, 0x0, 0x9, 0xb0, 0xf5, + 0x0, 0x0, 0xa9, 0xb, 0xa0, 0x0, 0x1f, 0x50, + 0x2f, 0x93, 0x4c, 0xc0, 0x0, 0x2b, 0xed, 0x80, + 0x0, + + /* U+0070 "p" */ + 0x7a, 0x4b, 0xfc, 0x40, 0x7f, 0xc4, 0x28, 0xf3, + 0x7d, 0x0, 0x0, 0xba, 0x7c, 0x0, 0x0, 0x7d, + 0x7c, 0x0, 0x0, 0x6e, 0x7c, 0x0, 0x0, 0x8c, + 0x7d, 0x0, 0x0, 0xe8, 0x7f, 0xa3, 0x3b, 0xe1, + 0x7c, 0x6d, 0xeb, 0x10, 0x7c, 0x0, 0x0, 0x0, + 0x7c, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, + 0x7c, 0x0, 0x0, 0x0, + + /* U+0071 "q" */ + 0x0, 0x3b, 0xfd, 0x6c, 0x50, 0x2f, 0x93, 0x3b, + 0xf5, 0xb, 0xb0, 0x0, 0xf, 0x50, 0xf5, 0x0, + 0x0, 0xf5, 0x1f, 0x30, 0x0, 0xf, 0x50, 0xf5, + 0x0, 0x0, 0xf5, 0xd, 0xa0, 0x0, 0xf, 0x50, + 0x5f, 0x83, 0x5d, 0xf5, 0x0, 0x5d, 0xfb, 0x3e, + 0x50, 0x0, 0x0, 0x0, 0xf5, 0x0, 0x0, 0x0, + 0xf, 0x50, 0x0, 0x0, 0x0, 0xf5, 0x0, 0x0, + 0x0, 0xf, 0x50, + + /* U+0072 "r" */ + 0x79, 0x3d, 0xf0, 0x7c, 0xc5, 0x30, 0x7f, 0x30, + 0x0, 0x7d, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x7c, + 0x0, 0x0, 0x7c, 0x0, 0x0, 0x7c, 0x0, 0x0, + 0x7c, 0x0, 0x0, + + /* U+0073 "s" */ + 0x2, 0xbe, 0xe9, 0x10, 0xcb, 0x22, 0x82, 0xf, + 0x50, 0x0, 0x0, 0x9e, 0x60, 0x0, 0x0, 0x5d, + 0xe7, 0x0, 0x0, 0x4, 0xe8, 0x0, 0x0, 0x8, + 0xc3, 0xd5, 0x14, 0xd8, 0x5, 0xcf, 0xe8, 0x0, + + /* U+0074 "t" */ + 0x0, 0x70, 0x0, 0x1, 0xf0, 0x0, 0x2, 0xf0, + 0x0, 0x8f, 0xff, 0xf6, 0x4, 0xf2, 0x10, 0x3, + 0xf0, 0x0, 0x3, 0xf0, 0x0, 0x3, 0xf0, 0x0, + 0x3, 0xf0, 0x0, 0x3, 0xf2, 0x0, 0x0, 0xf9, + 0x22, 0x0, 0x5e, 0xe7, + + /* U+0075 "u" */ + 0x9a, 0x0, 0x2, 0xf1, 0x9a, 0x0, 0x2, 0xf1, + 0x9a, 0x0, 0x2, 0xf1, 0x9a, 0x0, 0x2, 0xf1, + 0x9a, 0x0, 0x2, 0xf1, 0x9b, 0x0, 0x2, 0xf1, + 0x8d, 0x0, 0x6, 0xf1, 0x4f, 0x73, 0x8b, 0xf1, + 0x8, 0xed, 0x80, 0xf1, + + /* U+0076 "v" */ + 0x9b, 0x0, 0x0, 0x7c, 0x4f, 0x10, 0x0, 0xc7, + 0xe, 0x50, 0x2, 0xf1, 0x9, 0xb0, 0x7, 0xc0, + 0x3, 0xf0, 0xc, 0x60, 0x0, 0xd5, 0x1f, 0x10, + 0x0, 0x8a, 0x6b, 0x0, 0x0, 0x2e, 0xb6, 0x0, + 0x0, 0xd, 0xf1, 0x0, + + /* U+0077 "w" */ + 0x6e, 0x0, 0x6, 0xf2, 0x0, 0x2f, 0x12, 0xf2, + 0x0, 0xad, 0x60, 0x6, 0xd0, 0xe, 0x60, 0xe, + 0x6a, 0x0, 0xa9, 0x0, 0x9a, 0x3, 0xc2, 0xf0, + 0xe, 0x50, 0x5, 0xe0, 0x78, 0xe, 0x32, 0xf1, + 0x0, 0x1f, 0x2b, 0x40, 0xa7, 0x6c, 0x0, 0x0, + 0xc5, 0xe0, 0x6, 0xb9, 0x80, 0x0, 0x8, 0xcc, + 0x0, 0x2f, 0xd4, 0x0, 0x0, 0x4f, 0x80, 0x0, + 0xdf, 0x0, 0x0, + + /* U+0078 "x" */ + 0x3f, 0x30, 0x5, 0xe1, 0x9, 0xc0, 0xd, 0x60, + 0x1, 0xe5, 0x6c, 0x0, 0x0, 0x6e, 0xe3, 0x0, + 0x0, 0x1f, 0xd0, 0x0, 0x0, 0xaa, 0xe5, 0x0, + 0x3, 0xf1, 0x6e, 0x0, 0xd, 0x70, 0xc, 0x90, + 0x7d, 0x0, 0x3, 0xf3, + + /* U+0079 "y" */ + 0x9b, 0x0, 0x0, 0x7d, 0x3f, 0x10, 0x0, 0xc7, + 0xd, 0x70, 0x1, 0xf2, 0x7, 0xc0, 0x6, 0xd0, + 0x1, 0xf2, 0xb, 0x70, 0x0, 0xb8, 0xf, 0x20, + 0x0, 0x4d, 0x4d, 0x0, 0x0, 0xe, 0xc7, 0x0, + 0x0, 0x8, 0xf2, 0x0, 0x0, 0x6, 0xd0, 0x0, + 0x0, 0xd, 0x50, 0x0, 0x2, 0x8d, 0x0, 0x0, + 0x4f, 0xc2, 0x0, 0x0, + + /* U+007A "z" */ + 0xe, 0xff, 0xff, 0xd0, 0x1, 0x11, 0x2f, 0x50, + 0x0, 0x0, 0xbb, 0x0, 0x0, 0x5, 0xf1, 0x0, + 0x0, 0x1e, 0x60, 0x0, 0x0, 0xac, 0x0, 0x0, + 0x4, 0xf2, 0x0, 0x0, 0xe, 0x81, 0x11, 0x10, + 0x6f, 0xff, 0xff, 0xf0, + + /* U+007B "{" */ + 0x0, 0x6e, 0xa0, 0xe, 0x40, 0x0, 0xf1, 0x0, + 0xf, 0x10, 0x0, 0xe1, 0x0, 0xe, 0x20, 0x3, + 0xf0, 0x5, 0xf6, 0x0, 0x3, 0xe0, 0x0, 0xe, + 0x10, 0x0, 0xe2, 0x0, 0xf, 0x10, 0x0, 0xf1, + 0x0, 0xf, 0x10, 0x0, 0xd5, 0x0, 0x4, 0xc9, + + /* U+007C "|" */ + 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, + 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, + 0x59, 0x59, + + /* U+007D "}" */ + 0x6d, 0xa0, 0x0, 0xf, 0x30, 0x0, 0xc4, 0x0, + 0xc, 0x40, 0x0, 0xd3, 0x0, 0xd, 0x30, 0x0, + 0xa7, 0x0, 0x2, 0xfa, 0x0, 0xa8, 0x0, 0xd, + 0x30, 0x0, 0xd3, 0x0, 0xd, 0x30, 0x0, 0xc4, + 0x0, 0xc, 0x40, 0x1, 0xe2, 0x5, 0xc8, 0x0, + + /* U+007E "~" */ + 0x3, 0xca, 0x10, 0x3, 0x1, 0xd3, 0x7d, 0x34, + 0xd0, 0x4, 0x0, 0x4d, 0xc2, 0x0, + + /* U+3001 "、" */ + 0x4, 0x10, 0x0, 0xc, 0xd1, 0x0, 0x0, 0xbd, + 0x10, 0x0, 0xc, 0xd1, 0x0, 0x1, 0x91, + + /* U+3002 "。" */ + 0x1, 0xac, 0x80, 0xc, 0x30, 0x87, 0xc, 0x0, + 0x1b, 0xc, 0x20, 0x78, 0x2, 0xcc, 0xa0, + + /* U+3005 "々" */ + 0x0, 0x0, 0x2, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9a, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x6, 0xe2, 0x11, + 0x11, 0x10, 0x0, 0x0, 0xdf, 0xff, 0xff, 0xff, + 0x20, 0x0, 0x6d, 0x0, 0x0, 0x7, 0xb0, 0x0, + 0x1e, 0x40, 0x0, 0x0, 0xe4, 0x0, 0xb, 0xa0, + 0x0, 0x0, 0x7c, 0x0, 0x9, 0xd0, 0x24, 0x0, + 0x2f, 0x30, 0x1, 0xb2, 0x5, 0xeb, 0x3c, 0x80, + 0x0, 0x0, 0x0, 0x1, 0x9f, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3d, 0xd2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x0, + + /* U+300C "「" */ + 0xcf, 0xff, 0xf3, 0xc4, 0x0, 0x0, 0xc4, 0x0, + 0x0, 0xc4, 0x0, 0x0, 0xc4, 0x0, 0x0, 0xc4, + 0x0, 0x0, 0xc4, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0xc4, 0x0, 0x0, 0xc4, 0x0, 0x0, 0x41, 0x0, + 0x0, + + /* U+300D "」" */ + 0x0, 0x0, 0x14, 0x0, 0x0, 0x4c, 0x0, 0x0, + 0x4c, 0x0, 0x0, 0x4c, 0x0, 0x0, 0x4c, 0x0, + 0x0, 0x4c, 0x0, 0x0, 0x4c, 0x0, 0x0, 0x4c, + 0x0, 0x0, 0x4c, 0x0, 0x0, 0x4c, 0x3f, 0xff, + 0xfc, + + /* U+3041 "ぁ" */ + 0x0, 0x0, 0x36, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x69, 0x1, 0x35, 0x20, 0x8, 0xed, 0xef, 0xed, + 0xca, 0x30, 0x0, 0x0, 0xa5, 0x0, 0x71, 0x0, + 0x0, 0x0, 0xba, 0xad, 0xf8, 0x10, 0x0, 0xa, + 0xf7, 0x28, 0x99, 0xd1, 0x0, 0xc8, 0xb3, 0x1e, + 0x10, 0x88, 0x8, 0x80, 0xa5, 0xb7, 0x0, 0x4b, + 0xe, 0x0, 0x8d, 0x90, 0x0, 0x89, 0xe, 0x23, + 0xcd, 0x0, 0x4, 0xf2, 0x7, 0xec, 0x6b, 0x16, + 0xae, 0x40, 0x0, 0x0, 0x0, 0x9, 0x50, 0x0, + + /* U+3042 "あ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x20, 0x2, 0x55, 0x0, 0x9, 0xdc, 0xbf, + 0xde, 0xfe, 0xc6, 0x0, 0x1, 0x33, 0x4f, 0x21, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x0, 0xb, + 0x50, 0x0, 0x0, 0x0, 0x3e, 0xbd, 0xef, 0xb3, + 0x0, 0x0, 0x6, 0xed, 0x20, 0x79, 0x4e, 0x50, + 0x0, 0x8d, 0x5c, 0x0, 0xe1, 0x2, 0xe1, 0x5, + 0xc1, 0x1e, 0x9, 0x80, 0x0, 0xd4, 0xd, 0x30, + 0xf, 0x6d, 0x0, 0x0, 0xe3, 0x1f, 0x0, 0xe, + 0xe1, 0x0, 0x4, 0xf0, 0x1f, 0x55, 0xcf, 0x60, + 0x0, 0x3e, 0x60, 0x6, 0xcb, 0x67, 0x61, 0x6a, + 0xf6, 0x0, 0x0, 0x0, 0x0, 0x1, 0xa6, 0x10, + 0x0, + + /* U+3043 "ぃ" */ + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x20, + 0x0, 0x0, 0x64, 0x0, 0xe, 0x10, 0x0, 0x0, + 0x5e, 0x0, 0xe, 0x20, 0x0, 0x0, 0xc, 0x60, + 0xd, 0x20, 0x0, 0x0, 0x6, 0xc0, 0xc, 0x30, + 0x0, 0x0, 0x1, 0xf1, 0xa, 0x60, 0x3, 0x0, + 0x0, 0xd5, 0x7, 0xa0, 0xb, 0x60, 0x0, 0xa7, + 0x2, 0xf3, 0x3f, 0x10, 0x0, 0x20, 0x0, 0x8f, + 0xf7, 0x0, 0x0, 0x0, 0x0, 0x3, 0x30, 0x0, + 0x0, 0x0, + + /* U+3044 "い" */ + 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x60, + 0x0, 0x0, 0x0, 0x80, 0x0, 0xd5, 0x0, 0x0, + 0x0, 0xc, 0x90, 0xd, 0x50, 0x0, 0x0, 0x0, + 0x2f, 0x10, 0xc5, 0x0, 0x0, 0x0, 0x0, 0xb8, + 0xb, 0x60, 0x0, 0x0, 0x0, 0x5, 0xd0, 0xa8, + 0x0, 0x0, 0x0, 0x0, 0x1f, 0x27, 0xa0, 0x0, + 0x20, 0x0, 0x0, 0xd5, 0x4e, 0x0, 0xa, 0x70, + 0x0, 0xa, 0x80, 0xe4, 0x1, 0xf3, 0x0, 0x0, + 0x53, 0x8, 0xe5, 0xbb, 0x0, 0x0, 0x0, 0x0, + 0xa, 0xfd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+3046 "う" */ + 0x0, 0x16, 0x31, 0x0, 0x0, 0x0, 0x2, 0xad, + 0xff, 0xed, 0x60, 0x0, 0x0, 0x0, 0x2, 0x31, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x26, + 0x9b, 0xcc, 0x91, 0x2, 0xff, 0xb7, 0x53, 0x4b, + 0xe1, 0x5, 0x0, 0x0, 0x0, 0xb, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, 0x0, + 0xa, 0xb0, 0x0, 0x0, 0x0, 0x0, 0xe6, 0x0, + 0x0, 0x0, 0x0, 0xcc, 0x0, 0x0, 0x0, 0x6, + 0xec, 0x10, 0x0, 0x8, 0xcf, 0xe5, 0x0, 0x0, + 0x0, 0x56, 0x20, 0x0, 0x0, + + /* U+3047 "ぇ" */ + 0x0, 0x7d, 0xa8, 0x64, 0x0, 0x0, 0x0, 0x14, + 0x57, 0x70, 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, + 0x0, 0xdd, 0xef, 0xef, 0xc0, 0x0, 0x4, 0x21, + 0x7, 0xc1, 0x0, 0x0, 0x0, 0x6, 0xb0, 0x0, + 0x0, 0x0, 0x6, 0xf9, 0x0, 0x0, 0x0, 0x5, + 0xc3, 0xb6, 0x0, 0x0, 0x4, 0xd1, 0x5, 0xb0, + 0x0, 0x4, 0xe3, 0x0, 0x1e, 0x52, 0x43, 0x75, + 0x0, 0x0, 0x5c, 0xdc, 0x40, + + /* U+3048 "え" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xcf, 0xec, 0xa8, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x14, 0x68, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x34, + 0x68, 0x10, 0x0, 0x0, 0xff, 0xed, 0xcb, 0xed, + 0x20, 0x0, 0x0, 0x10, 0x0, 0x7, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x78, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xe8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7b, 0x4d, 0x60, 0x0, 0x0, 0x0, 0x7, + 0xb0, 0x6, 0xb0, 0x0, 0x0, 0x0, 0x7c, 0x0, + 0x2, 0xf0, 0x0, 0x0, 0x7, 0xe1, 0x0, 0x0, + 0xdb, 0x56, 0x84, 0x8, 0x40, 0x0, 0x0, 0x29, + 0xcc, 0xa4, + + /* U+304A "お" */ + 0x0, 0x0, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe3, 0x37, 0x50, 0xd8, 0x0, 0x3, 0xed, + 0xef, 0xfd, 0xa4, 0x1, 0xae, 0x40, 0x2, 0x22, + 0xf1, 0x0, 0x0, 0x0, 0x4d, 0x0, 0x0, 0xf, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf5, + 0x8b, 0xcb, 0x81, 0x0, 0x0, 0x0, 0x7f, 0xb7, + 0x43, 0x49, 0xe2, 0x0, 0x1, 0xca, 0xf1, 0x0, + 0x0, 0x9, 0xa0, 0x0, 0xc7, 0xe, 0x10, 0x0, + 0x0, 0x6c, 0x0, 0x2e, 0x0, 0xe2, 0x0, 0x0, + 0xb, 0x90, 0x0, 0xe5, 0xf, 0x20, 0x0, 0x4b, + 0xe1, 0x0, 0x3, 0xef, 0xe0, 0xd, 0xff, 0xa1, + 0x0, 0x0, 0x0, 0x41, 0x0, 0x32, 0x0, 0x0, + 0x0, + + /* U+304B "か" */ + 0x0, 0x0, 0x35, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa9, 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, + 0xc, 0x72, 0x20, 0x2, 0xf3, 0x0, 0x8c, 0xde, + 0xfe, 0xdf, 0xe2, 0x7, 0xb0, 0x3, 0x42, 0x4e, + 0x0, 0x9, 0x90, 0xe, 0x40, 0x0, 0x7, 0xa0, + 0x0, 0x5b, 0x0, 0x7b, 0x0, 0x0, 0xd5, 0x0, + 0x6, 0xa0, 0x1, 0xf2, 0x0, 0x2f, 0x0, 0x0, + 0x79, 0x0, 0x4, 0x0, 0x9, 0x90, 0x0, 0x9, + 0x80, 0x0, 0x0, 0x1, 0xf1, 0x0, 0x0, 0xd5, + 0x0, 0x0, 0x0, 0x99, 0x1, 0x0, 0x5f, 0x0, + 0x0, 0x0, 0x3f, 0x10, 0x6f, 0xef, 0x70, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x13, 0x10, 0x0, 0x0, + 0x0, + + /* U+304C "が" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, + 0x0, 0x0, 0x6, 0x20, 0x0, 0x3, 0x66, 0x90, + 0x0, 0x0, 0xe, 0x50, 0x0, 0x0, 0xd1, 0xc2, + 0x0, 0x0, 0xf, 0x20, 0x0, 0x3, 0x64, 0x0, + 0x0, 0x0, 0x2f, 0x22, 0x10, 0xa, 0xa0, 0x0, + 0xc, 0xcd, 0xff, 0xed, 0xfa, 0x1, 0xe3, 0x0, + 0x5, 0x32, 0xa8, 0x0, 0x1f, 0x30, 0x7c, 0x0, + 0x0, 0x0, 0xe3, 0x0, 0xc, 0x50, 0xe, 0x40, + 0x0, 0x3, 0xe0, 0x0, 0xd, 0x40, 0x8, 0xb0, + 0x0, 0x9, 0x90, 0x0, 0xe, 0x20, 0x2, 0x40, + 0x0, 0x1f, 0x20, 0x0, 0xf, 0x10, 0x0, 0x0, + 0x0, 0x7a, 0x0, 0x0, 0x4e, 0x0, 0x0, 0x0, + 0x1, 0xe2, 0x1, 0x0, 0xb9, 0x0, 0x0, 0x0, + 0x9, 0xa0, 0xd, 0xef, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0x10, 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, + + /* U+304D "き" */ + 0x0, 0x0, 0x2, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe3, 0x47, 0x60, 0xf, 0xfe, 0xee, 0xff, + 0xc9, 0x40, 0x0, 0x1, 0x11, 0x6b, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0x0, 0x2, 0x26, 0x43, + 0x34, 0x4d, 0xab, 0xfa, 0x3b, 0xbc, 0xcb, 0xbb, + 0xf6, 0x30, 0x0, 0x0, 0x0, 0x0, 0xd4, 0x0, + 0x1, 0x0, 0x0, 0x11, 0x4d, 0x0, 0xa, 0x80, + 0x0, 0x5c, 0xef, 0x40, 0xd, 0x30, 0x0, 0x0, + 0x1, 0x0, 0xd, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xe7, 0x31, 0x12, 0x44, 0x0, 0x0, 0x4b, + 0xef, 0xfd, 0xc7, 0x0, + + /* U+304E "ぎ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, + 0x0, 0x0, 0xc2, 0x0, 0x93, 0xa4, 0x0, 0x0, + 0x0, 0xc5, 0x25, 0x7c, 0x1a, 0xe, 0xed, 0xdd, + 0xff, 0xeb, 0x55, 0x0, 0x0, 0x12, 0x22, 0x4d, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x20, + 0x2, 0x0, 0x16, 0x54, 0x34, 0x4c, 0xbb, 0xed, + 0x0, 0x2b, 0xbc, 0xcc, 0xba, 0xf7, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa7, 0x0, 0x0, 0x0, + 0x10, 0x0, 0x1, 0x2e, 0x10, 0x0, 0x7, 0xb0, + 0x0, 0x3c, 0xef, 0x70, 0x0, 0xb, 0x50, 0x0, + 0x0, 0x1, 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xf8, 0x31, 0x12, 0x34, + 0x0, 0x0, 0x0, 0x3a, 0xdf, 0xfe, 0xd9, 0x0, + 0x0, + + /* U+304F "く" */ + 0x0, 0x0, 0x0, 0x3, 0x70, 0x0, 0x0, 0x0, + 0x2e, 0xb0, 0x0, 0x0, 0x3, 0xe9, 0x0, 0x0, + 0x0, 0x5f, 0x60, 0x0, 0x0, 0x8, 0xe3, 0x0, + 0x0, 0x0, 0xbc, 0x10, 0x0, 0x0, 0x7, 0xe0, + 0x0, 0x0, 0x0, 0x5, 0xf3, 0x0, 0x0, 0x0, + 0x0, 0x7f, 0x50, 0x0, 0x0, 0x0, 0x5, 0xf8, + 0x0, 0x0, 0x0, 0x0, 0x3e, 0xb0, 0x0, 0x0, + 0x0, 0x2, 0xdc, 0x10, 0x0, 0x0, 0x0, 0x1d, + 0xd1, 0x0, 0x0, 0x0, 0x1, 0xb2, + + /* U+3050 "ぐ" */ + 0x0, 0x0, 0x0, 0x5, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x4f, 0x80, 0x0, 0x0, 0x0, 0x6, 0xf6, + 0x0, 0x0, 0x0, 0x0, 0x8e, 0x40, 0x6, 0x30, + 0x0, 0xb, 0xd2, 0x5, 0x82, 0xd0, 0x1, 0xda, + 0x0, 0x0, 0xd2, 0x73, 0xb, 0xb0, 0x0, 0x0, + 0x33, 0x0, 0x9, 0xd1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xae, 0x30, 0x0, 0x0, 0x0, 0x0, 0x7, + 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0x80, + 0x0, 0x0, 0x0, 0x0, 0x3, 0xfa, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3e, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xb1, 0x0, + + /* U+3051 "け" */ + 0x4, 0xb0, 0x0, 0x0, 0x2, 0xf1, 0x0, 0x7, + 0xb0, 0x0, 0x0, 0x0, 0xf1, 0x0, 0x9, 0x80, + 0x0, 0x0, 0x0, 0xf1, 0x0, 0xb, 0x50, 0x0, + 0x0, 0x0, 0xf3, 0x45, 0xc, 0x30, 0x9, 0xfe, + 0xef, 0xff, 0xe9, 0xd, 0x20, 0x0, 0x12, 0x21, + 0xf2, 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0xf1, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xf1, 0x0, + 0xf, 0x2a, 0x0, 0x0, 0x1, 0xf0, 0x0, 0xd, + 0x87, 0x0, 0x0, 0x3, 0xd0, 0x0, 0xc, 0xf2, + 0x0, 0x0, 0x9, 0x90, 0x0, 0x9, 0xe0, 0x0, + 0x0, 0x4f, 0x20, 0x0, 0x5, 0xc0, 0x0, 0x6, + 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x50, + 0x0, 0x0, + + /* U+3052 "げ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x23, 0x0, 0x0, 0x0, 0x35, 0x53, 0xc1, 0x8, + 0xa0, 0x0, 0x0, 0x6, 0xc3, 0xa6, 0x60, 0xa7, + 0x0, 0x0, 0x0, 0x5c, 0x7, 0x0, 0xd, 0x40, + 0x0, 0x0, 0x4, 0xc1, 0x43, 0x0, 0xf2, 0x0, + 0xcf, 0xee, 0xff, 0xfd, 0x70, 0xf, 0x0, 0x1, + 0x12, 0x25, 0xd0, 0x0, 0x1, 0xf0, 0x0, 0x0, + 0x0, 0x4c, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, + 0x4, 0xc0, 0x0, 0x2, 0xe2, 0x80, 0x0, 0x0, + 0x6b, 0x0, 0x0, 0xf, 0x84, 0x0, 0x0, 0x8, + 0x80, 0x0, 0x0, 0xee, 0x0, 0x0, 0x0, 0xe5, + 0x0, 0x0, 0xc, 0xb0, 0x0, 0x0, 0x9c, 0x0, + 0x0, 0x0, 0x89, 0x0, 0x1, 0xaf, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3b, 0x20, 0x0, 0x0, + 0x0, + + /* U+3053 "こ" */ + 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x2, 0xff, + 0xff, 0xff, 0xff, 0x40, 0x0, 0x1, 0x22, 0x22, + 0x10, 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, 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, + 0xf, 0x10, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x10, + 0x0, 0x0, 0x0, 0x0, 0xc, 0xc3, 0x0, 0x0, + 0x1, 0x42, 0x1, 0xaf, 0xfe, 0xef, 0xff, 0xe4, + 0x0, 0x0, 0x24, 0x43, 0x21, 0x0, + + /* U+3054 "ご" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x82, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb4, 0x95, 0x6, 0xfd, 0xdd, + 0xdd, 0xef, 0x36, 0x0, 0x1, 0x34, 0x45, 0x44, + 0x32, 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, 0x1c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4d, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1f, 0xa2, 0x0, 0x0, + 0x1, 0x40, 0x0, 0x3, 0xbf, 0xfd, 0xef, 0xff, + 0xd1, 0x0, 0x0, 0x1, 0x34, 0x43, 0x20, 0x0, + 0x0, + + /* U+3055 "さ" */ + 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x99, 0x0, 0x0, 0x1, 0x0, 0x0, 0x3e, + 0x36, 0xa8, 0x6f, 0xff, 0xef, 0xff, 0xea, 0x73, + 0x0, 0x11, 0x21, 0x7, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xe1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8a, 0x0, 0x0, 0x0, 0x0, 0x13, 0x2e, 0x40, + 0x7, 0xa0, 0x0, 0x5c, 0xef, 0xa0, 0xc, 0x40, + 0x0, 0x0, 0x0, 0x0, 0xe, 0x30, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xeb, 0x64, 0x45, 0x69, 0x0, 0x0, 0x17, + 0xbc, 0xdc, 0xb9, 0x0, + + /* U+3056 "ざ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x26, 0x50, 0x0, + 0x0, 0x0, 0xb2, 0x2, 0xc1, 0xd1, 0x0, 0x0, + 0x0, 0xb6, 0x0, 0x86, 0x42, 0x0, 0x0, 0x0, + 0x6b, 0x26, 0xa6, 0x0, 0x9f, 0xfe, 0xde, 0xff, + 0xeb, 0x83, 0x0, 0x1, 0x22, 0x32, 0x1a, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb7, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x11, 0x2e, 0x10, 0x0, 0x9, + 0x80, 0x0, 0x8e, 0xff, 0x80, 0x0, 0xe, 0x30, + 0x0, 0x0, 0x2, 0x10, 0x0, 0x1f, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xf8, 0x32, 0x12, 0x46, + 0x0, 0x0, 0x0, 0x4a, 0xdf, 0xfe, 0xda, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+3057 "し" */ + 0xf, 0x50, 0x0, 0x0, 0x0, 0x0, 0xf, 0x30, + 0x0, 0x0, 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, + 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, 0x0, 0x0, + 0xf, 0x10, 0x0, 0x0, 0x0, 0x0, 0xf, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x1f, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2f, 0x0, + 0x0, 0x0, 0x0, 0x50, 0x1f, 0x10, 0x0, 0x0, + 0x6, 0xf1, 0xf, 0x40, 0x0, 0x0, 0x7f, 0x50, + 0x8, 0xe6, 0x34, 0x6d, 0xe4, 0x0, 0x0, 0x7d, + 0xfe, 0xb6, 0x0, 0x0, + + /* U+3058 "じ" */ + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x10, + 0x0, 0x0, 0x80, 0x0, 0x2f, 0x0, 0x0, 0xa0, + 0xa7, 0x0, 0x2f, 0x0, 0x0, 0x97, 0x1e, 0x10, + 0x3e, 0x0, 0x0, 0x1d, 0x1, 0x0, 0x3e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d, 0x0, + 0x0, 0x0, 0x0, 0x20, 0x5d, 0x0, 0x0, 0x0, + 0x7, 0xe0, 0x2f, 0x10, 0x0, 0x0, 0x8f, 0x40, + 0xc, 0xc4, 0x24, 0x7e, 0xd3, 0x0, 0x1, 0x9e, + 0xfd, 0xb5, 0x0, 0x0, + + /* U+3059 "す" */ + 0x0, 0x0, 0x0, 0x4, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x12, 0x33, + 0x34, 0x47, 0xf5, 0x55, 0x54, 0x6e, 0xdc, 0xcb, + 0xbb, 0xfa, 0xab, 0xba, 0x0, 0x0, 0x0, 0x2, + 0xe0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0xfe, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0xc8, 0x4, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0xf0, 0x0, 0xe4, 0x0, 0x0, + 0x0, 0x0, 0xe7, 0x3, 0xf5, 0x0, 0x0, 0x0, + 0x0, 0x4e, 0xee, 0xf3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8e, 0x30, 0x0, 0x0, 0x0, 0x0, 0x9e, 0xc2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x53, 0x0, 0x0, + 0x0, 0x0, + + /* U+305A "ず" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x25, 0x0, + 0x0, 0x0, 0x0, 0xf, 0x22, 0xd1, 0xe1, 0x0, + 0x0, 0x0, 0x0, 0xf2, 0xb, 0x59, 0x50, 0x0, + 0x1, 0x11, 0x2f, 0x42, 0x67, 0x30, 0x2f, 0xff, + 0xfe, 0xed, 0xfd, 0xdd, 0xee, 0x10, 0x10, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xcc, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x4, 0xd3, + 0x4f, 0x30, 0x0, 0x0, 0x0, 0x0, 0xa6, 0x0, + 0x98, 0x0, 0x0, 0x0, 0x0, 0xa, 0x70, 0xb, + 0x90, 0x0, 0x0, 0x0, 0x0, 0x5e, 0x66, 0xf8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, 0x9f, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3b, 0xd1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8e, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+305B "せ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, + 0x0, 0xc, 0x20, 0x0, 0xb, 0x60, 0x0, 0x0, + 0x0, 0xf2, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, + 0xf, 0x20, 0x0, 0xb, 0x50, 0x0, 0x0, 0x2, + 0xf6, 0x68, 0x9b, 0xee, 0xef, 0x66, 0xff, 0xdf, + 0xa8, 0x76, 0x4c, 0x61, 0x10, 0x1, 0x0, 0xf1, + 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0xf, 0x10, + 0x0, 0xd, 0x20, 0x0, 0x0, 0x0, 0xf1, 0x1, + 0xed, 0xe0, 0x0, 0x0, 0x0, 0xf, 0x10, 0x1, + 0x31, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb, 0x90, 0x0, 0x0, + 0x12, 0x0, 0x0, 0x0, 0x3d, 0xfe, 0xef, 0xff, + 0xa0, 0x0, 0x0, 0x0, 0x2, 0x33, 0x22, 0x10, + 0x0, + + /* U+305C "ぜ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, 0x21, 0x70, + 0x0, 0x1, 0xc1, 0x0, 0x0, 0xb6, 0xa3, 0xc1, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0xb5, 0x3a, 0x42, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0x0, 0x1, 0xf5, 0x57, 0x8a, 0xee, 0xdf, 0x60, + 0x7e, 0xff, 0xfc, 0xb9, 0x76, 0xd7, 0x22, 0x0, + 0x34, 0x21, 0xf0, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x0, 0xd3, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x43, 0xf2, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x1, 0xbd, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd8, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x4e, 0xfe, 0xee, 0xff, 0xa0, 0x0, + 0x0, 0x0, 0x0, 0x23, 0x33, 0x21, 0x0, 0x0, + + /* U+305D "そ" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + 0xa, 0xdd, 0xef, 0xff, 0xb0, 0x0, 0x0, 0x2, + 0x31, 0x11, 0xbb, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0x80, 0x0, 0x0, 0x0, 0x0, 0x3, 0xe6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6e, 0x30, 0x1, + 0x23, 0x30, 0x15, 0x7b, 0xfe, 0xef, 0xfd, 0xcc, + 0xc0, 0x3b, 0x97, 0x54, 0xc7, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xfc, + 0x75, 0x40, 0x0, 0x0, 0x0, 0x0, 0x16, 0xab, + 0x90, 0x0, + + /* U+305E "ぞ" */ + 0x0, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, + 0x3e, 0xee, 0xff, 0xff, 0x30, 0x0, 0x0, 0x3, + 0x21, 0x5, 0xe5, 0x13, 0x80, 0x0, 0x0, 0x0, + 0x6e, 0x30, 0xd2, 0xc3, 0x0, 0x0, 0x9, 0xc1, + 0x0, 0x59, 0x22, 0x0, 0x1, 0xca, 0x0, 0x0, + 0x13, 0x10, 0x35, 0x7e, 0xfc, 0xde, 0xfe, 0xdd, + 0x70, 0xab, 0x97, 0x57, 0xd4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2d, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x97, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xfa, + 0x65, 0x20, 0x0, 0x0, 0x0, 0x0, 0x49, 0xab, + 0x30, 0x0, + + /* U+305F "た" */ + 0x0, 0x0, 0x2b, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6c, 0x47, 0x80, 0x0, 0x0, 0x1f, 0xff, 0xff, + 0xda, 0x60, 0x0, 0x0, 0x1, 0x21, 0xd5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0xf1, 0x2, 0xcd, + 0xed, 0xc3, 0x0, 0x5, 0xd0, 0x0, 0x43, 0x23, + 0x41, 0x0, 0xa, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4e, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0xa9, + 0x0, 0x3d, 0x0, 0x0, 0x0, 0x1, 0xf3, 0x0, + 0x1f, 0x40, 0x0, 0x11, 0x8, 0xd0, 0x0, 0x6, + 0xef, 0xef, 0xf7, 0x2, 0x30, 0x0, 0x0, 0x1, + 0x22, 0x0, + + /* U+3060 "だ" */ + 0x0, 0x0, 0x93, 0x0, 0x0, 0x0, 0x70, 0x0, + 0x0, 0xf, 0x30, 0x0, 0x8, 0x57, 0x80, 0x0, + 0x1, 0xf2, 0x47, 0x0, 0x1d, 0x1a, 0xc, 0xdd, + 0xef, 0xfc, 0xa0, 0x0, 0x41, 0x0, 0x23, 0x3a, + 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc5, + 0x0, 0xab, 0xcc, 0xb8, 0x0, 0x0, 0x1f, 0x10, + 0x5, 0x54, 0x45, 0x40, 0x0, 0x6, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb7, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0x30, 0xb, 0x30, + 0x0, 0x0, 0x0, 0x6, 0xd0, 0x0, 0xf1, 0x0, + 0x0, 0x0, 0x0, 0xc8, 0x0, 0xd, 0x70, 0x0, + 0x0, 0x0, 0x4f, 0x20, 0x0, 0x4e, 0xfd, 0xdf, + 0xf0, 0x2, 0x50, 0x0, 0x0, 0x2, 0x34, 0x31, + 0x0, + + /* U+3061 "ち" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x98, + 0x0, 0x0, 0x0, 0x0, 0x53, 0x2b, 0x73, 0x57, + 0xad, 0x90, 0xc, 0xdd, 0xfd, 0xcb, 0x97, 0x52, + 0x0, 0x0, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa6, + 0x28, 0xac, 0xb7, 0x10, 0x0, 0x1f, 0xbc, 0x85, + 0x24, 0xbd, 0x10, 0x7, 0xf8, 0x0, 0x0, 0x0, + 0xc7, 0x0, 0x66, 0x0, 0x0, 0x0, 0x9, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd6, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xdd, 0x0, 0x0, 0x9, 0xcb, + 0xcf, 0xe9, 0x10, 0x0, 0x0, 0x35, 0x55, 0x20, + 0x0, 0x0, + + /* U+3063 "っ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0x8b, 0xef, 0xd8, 0x0, 0x39, 0xee, 0x95, 0x20, + 0x3c, 0xb0, 0x3a, 0x40, 0x0, 0x0, 0x1, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x0, 0x0, + 0x1b, 0xb0, 0x0, 0x0, 0x0, 0x27, 0xeb, 0x0, + 0x0, 0x1, 0xef, 0xea, 0x40, 0x0, 0x0, 0x0, + 0x31, 0x0, 0x0, 0x0, + + /* U+3064 "つ" */ + 0x0, 0x0, 0x0, 0x1, 0x21, 0x0, 0x0, 0x0, + 0x1, 0x6a, 0xef, 0xef, 0xe7, 0x0, 0x27, 0xcf, + 0xb7, 0x20, 0x0, 0x4d, 0x80, 0x8d, 0x71, 0x0, + 0x0, 0x0, 0x3, 0xf2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x4, 0xed, 0x10, 0x0, + 0x0, 0x25, 0x7a, 0xee, 0x80, 0x0, 0x0, 0x0, + 0x6d, 0xb8, 0x50, 0x0, 0x0, + + /* U+3065 "づ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x1b, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x5a, 0x3c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb2, 0x30, 0x0, 0x0, + 0x59, 0xce, 0xfe, 0xa2, 0x0, 0x1, 0x6b, 0xfd, + 0x84, 0x20, 0x28, 0xf3, 0x0, 0xcd, 0x82, 0x0, + 0x0, 0x0, 0x7, 0xe0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1f, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5e, + 0xc0, 0x0, 0x0, 0x0, 0x35, 0x6a, 0xee, 0x70, + 0x0, 0x0, 0x0, 0xa, 0xeb, 0x94, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+3066 "て" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x34, 0x50, 0x36, + 0x79, 0xbc, 0xef, 0xff, 0xfd, 0xc1, 0x7b, 0x97, + 0x53, 0x28, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xf1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6f, 0x93, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xbf, 0xf9, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x32, 0x0, + + /* U+3067 "で" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0x30, 0x25, + 0x68, 0x9b, 0xce, 0xff, 0xfe, 0xd0, 0x9c, 0xa8, + 0x65, 0x39, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8b, 0x0, 0x11, 0x80, 0x0, 0x0, 0x3, 0xe0, + 0x0, 0xc2, 0xa5, 0x0, 0x0, 0xa, 0x70, 0x0, + 0x3b, 0x15, 0x0, 0x0, 0xd, 0x30, 0x0, 0x1, + 0x0, 0x0, 0x0, 0xf, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8f, 0x82, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xbf, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x31, 0x0, + + /* U+3068 "と" */ + 0x5, 0x0, 0x0, 0x0, 0x0, 0x1, 0xf3, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xa0, 0x0, 0x0, 0x35, + 0x0, 0x3f, 0x10, 0x2, 0xaf, 0x70, 0x0, 0xb9, + 0x18, 0xf9, 0x10, 0x0, 0x3, 0xfe, 0xa1, 0x0, + 0x0, 0x0, 0xad, 0x30, 0x0, 0x0, 0x0, 0xba, + 0x0, 0x0, 0x0, 0x0, 0x6d, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x70, 0x0, 0x0, 0x0, 0x0, 0xa9, + 0x0, 0x0, 0x0, 0x0, 0x5, 0xf7, 0x10, 0x0, + 0x0, 0x32, 0x5, 0xdf, 0xee, 0xef, 0xff, 0x50, + 0x0, 0x13, 0x43, 0x21, 0x0, + + /* U+3069 "ど" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x40, 0x6, + 0x90, 0x0, 0x0, 0x2, 0xc1, 0xd0, 0x3, 0xf1, + 0x0, 0x0, 0x0, 0x96, 0x63, 0x0, 0xc7, 0x0, + 0x0, 0x4b, 0x12, 0x0, 0x0, 0x5e, 0x0, 0x3c, + 0xd5, 0x0, 0x0, 0x0, 0xd, 0x8a, 0xe6, 0x0, + 0x0, 0x0, 0x0, 0x9, 0xf8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9d, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x5, 0xfb, 0x75, 0x56, + 0x79, 0xb0, 0x0, 0x0, 0x27, 0xac, 0xcb, 0xb9, + 0x70, 0x0, + + /* U+306A "な" */ + 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8b, 0x59, 0x10, 0x30, 0x0, 0x6f, 0xff, 0xfd, + 0xa7, 0x2, 0xeb, 0x20, 0x1, 0x13, 0xe0, 0x0, + 0x0, 0x8, 0xf7, 0x0, 0xa, 0x70, 0x0, 0x17, + 0x0, 0x34, 0x0, 0x2f, 0x10, 0x0, 0x2e, 0x0, + 0x0, 0x0, 0xa9, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x4, 0xf1, 0x0, 0x0, 0xf, 0x0, 0x0, 0x1e, + 0x70, 0x5, 0xbc, 0xbf, 0x20, 0x0, 0x18, 0x0, + 0x6d, 0x52, 0x4f, 0xf9, 0x0, 0x0, 0x0, 0xb5, + 0x0, 0xf, 0x3c, 0xd1, 0x0, 0x0, 0x8b, 0x11, + 0x8e, 0x0, 0x80, 0x0, 0x0, 0x9, 0xef, 0xc3, + 0x0, 0x0, + + /* U+306B "に" */ + 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xd0, + 0x0, 0x36, 0x55, 0x56, 0x70, 0x6a, 0x0, 0x5, + 0xbc, 0xcc, 0xba, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x16, 0x0, + 0x30, 0x0, 0x0, 0x0, 0xe6, 0xa0, 0x2e, 0x0, + 0x0, 0x0, 0xd, 0xe4, 0x3, 0xd0, 0x0, 0x0, + 0x0, 0xbe, 0x0, 0x1e, 0xa5, 0x45, 0x78, 0x59, + 0xb0, 0x0, 0x29, 0xcd, 0xdc, 0xa4, 0x35, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+306C "ぬ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, 0x0, 0x95, + 0x0, 0x1, 0xf2, 0x0, 0x0, 0x0, 0x7, 0xa0, + 0x4b, 0xff, 0xde, 0x91, 0x0, 0x0, 0x2e, 0x8d, + 0x65, 0xc0, 0x8, 0xe1, 0x0, 0x0, 0xeb, 0x0, + 0x88, 0x0, 0x9, 0xa0, 0x0, 0x7e, 0xb0, 0xc, + 0x40, 0x0, 0x2e, 0x0, 0x1e, 0x2e, 0x22, 0xf0, + 0x0, 0x0, 0xf0, 0x7, 0x90, 0x7b, 0x99, 0x0, + 0x0, 0x1f, 0x0, 0x95, 0x0, 0xdf, 0x13, 0xcd, + 0xb9, 0xc0, 0xb, 0x50, 0x1d, 0x60, 0xe3, 0x3, + 0xde, 0x10, 0x8d, 0x8e, 0x90, 0x1f, 0x10, 0x5e, + 0x8e, 0x10, 0x8a, 0x50, 0x0, 0x8f, 0xec, 0x30, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, + + /* U+306D "ね" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x79, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x78, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x6, 0x79, 0xdd, 0x2, 0xaf, 0xee, 0x40, 0x0, + 0x9, 0x97, 0xc7, 0x6d, 0x60, 0x4, 0xf1, 0x0, + 0x0, 0x0, 0xad, 0xc1, 0x0, 0x0, 0xa8, 0x0, + 0x0, 0x2, 0xf9, 0x0, 0x0, 0x0, 0x6a, 0x0, + 0x0, 0xc, 0xf2, 0x0, 0x0, 0x0, 0x5b, 0x0, + 0x0, 0x9a, 0xe2, 0x0, 0x1, 0x10, 0x6a, 0x0, + 0x5, 0xd0, 0xe2, 0x1, 0xcd, 0xde, 0xd9, 0x0, + 0x1f, 0x30, 0xe2, 0xa, 0x70, 0x2, 0xff, 0x40, + 0x4, 0x0, 0xe2, 0xa, 0x80, 0x19, 0xd4, 0xe2, + 0x0, 0x0, 0xf3, 0x2, 0xcf, 0xfd, 0x20, 0x10, + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+306E "の" */ + 0x0, 0x0, 0x1, 0x45, 0x31, 0x0, 0x0, 0x0, + 0x1, 0x9f, 0xdf, 0xcf, 0xb2, 0x0, 0x0, 0x4e, + 0x81, 0x4f, 0x0, 0x7f, 0x30, 0x1, 0xe5, 0x0, + 0x7b, 0x0, 0x5, 0xd0, 0xb, 0x90, 0x0, 0xb8, + 0x0, 0x0, 0xc6, 0x1f, 0x10, 0x0, 0xe5, 0x0, + 0x0, 0x89, 0x4d, 0x0, 0x2, 0xf1, 0x0, 0x0, + 0x7b, 0x4d, 0x0, 0x8, 0xb0, 0x0, 0x0, 0x99, + 0x2f, 0x10, 0x1e, 0x50, 0x0, 0x0, 0xe5, 0xc, + 0xa2, 0xbc, 0x0, 0x0, 0x9, 0xc0, 0x2, 0xef, + 0xd1, 0x0, 0x2, 0xbe, 0x20, 0x0, 0x2, 0x0, + 0x8, 0xdf, 0x90, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x30, 0x0, 0x0, + + /* U+306F "は" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x5d, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x0, 0x7, + 0xa0, 0x0, 0x0, 0x2, 0xf0, 0x0, 0x0, 0x97, + 0x0, 0x12, 0x11, 0x3f, 0x35, 0x50, 0xb, 0x40, + 0x6, 0xef, 0xff, 0xfd, 0xb7, 0x0, 0xd2, 0x0, + 0x0, 0x0, 0x2f, 0x0, 0x0, 0xe, 0x0, 0x0, + 0x0, 0x1, 0xf0, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x1f, 0x4, 0x0, 0x0, + 0x10, 0xf1, 0x0, 0x0, 0xf7, 0x60, 0x2b, 0xec, + 0xef, 0x70, 0x0, 0xf, 0xd0, 0xc, 0x50, 0x0, + 0xfc, 0xe4, 0x0, 0xdb, 0x0, 0xd5, 0x0, 0x4f, + 0x5, 0xe1, 0xa, 0x70, 0x4, 0xee, 0xdf, 0x70, + 0x0, 0x0, 0x22, 0x0, 0x0, 0x23, 0x10, 0x0, + 0x0, + + /* U+3070 "ば" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x24, 0x93, 0x7, + 0xb0, 0x0, 0x0, 0x4, 0xe1, 0xc3, 0xa0, 0x97, + 0x0, 0x0, 0x0, 0x4d, 0x8, 0x23, 0xc, 0x40, + 0x1, 0x21, 0x15, 0xd3, 0x65, 0x0, 0xe2, 0x0, + 0x7e, 0xff, 0xff, 0xdb, 0x60, 0xf, 0x0, 0x0, + 0x0, 0x3, 0xd0, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0x3d, 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, + 0x2, 0xe0, 0x0, 0x3, 0xc1, 0x20, 0x0, 0x0, + 0x1f, 0x0, 0x0, 0x3d, 0x74, 0x1, 0x9d, 0xed, + 0xf2, 0x0, 0x2, 0xec, 0x0, 0xd6, 0x10, 0x3f, + 0xe9, 0x0, 0x1f, 0xa0, 0x1f, 0x0, 0x3, 0xf1, + 0xcc, 0x0, 0xf6, 0x0, 0xda, 0x54, 0xcb, 0x0, + 0x70, 0xb, 0x40, 0x1, 0x8c, 0xc9, 0x10, 0x0, + 0x0, + + /* U+3071 "ぱ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0xaa, 0x40, + 0xab, 0x0, 0x0, 0x0, 0x4e, 0x37, 0xa, 0xc, + 0x70, 0x0, 0x0, 0x4, 0xd0, 0x9a, 0x30, 0xd4, + 0x0, 0x12, 0x11, 0x5d, 0x36, 0x50, 0xf, 0x20, + 0x7, 0xef, 0xff, 0xfd, 0xb6, 0x1, 0xf0, 0x0, + 0x0, 0x0, 0x3d, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x3, 0xd0, 0x0, 0x3, 0xd0, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x3c, 0x12, 0x0, 0x0, + 0x1, 0xf0, 0x0, 0x3, 0xd7, 0x40, 0x19, 0xde, + 0xdf, 0x20, 0x0, 0x2e, 0xc0, 0xd, 0x61, 0x3, + 0xfe, 0x80, 0x2, 0xfa, 0x1, 0xf0, 0x0, 0x3f, + 0x1c, 0xb0, 0xf, 0x60, 0xd, 0xa5, 0x4c, 0xb0, + 0x6, 0x0, 0xc4, 0x0, 0x18, 0xcc, 0x91, 0x0, + 0x0, + + /* U+3072 "ひ" */ + 0x0, 0x0, 0x2, 0x50, 0x1, 0x50, 0x0, 0x0, + 0xab, 0xdf, 0xfc, 0x0, 0x1f, 0x0, 0x0, 0x7, + 0x53, 0xb9, 0x0, 0x0, 0xe5, 0x0, 0x0, 0x0, + 0x7b, 0x0, 0x0, 0xd, 0xa0, 0x0, 0x0, 0x1e, + 0x10, 0x0, 0x0, 0xcf, 0x20, 0x0, 0x8, 0x90, + 0x0, 0x0, 0xb, 0xab, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x0, 0xb3, 0xd8, 0x0, 0x2f, 0x0, 0x0, + 0x0, 0xc, 0x23, 0xe0, 0x4, 0xd0, 0x0, 0x0, + 0x0, 0xe0, 0x0, 0x0, 0x4e, 0x0, 0x0, 0x0, + 0x6a, 0x0, 0x0, 0x1, 0xf4, 0x0, 0x0, 0x2e, + 0x50, 0x0, 0x0, 0x7, 0xe7, 0x33, 0x7e, 0x90, + 0x0, 0x0, 0x0, 0x5, 0xce, 0xec, 0x50, 0x0, + 0x0, 0x0, + + /* U+3073 "び" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x41, 0xa0, 0x0, + 0x0, 0x3, 0x20, 0x3, 0x3a, 0x4a, 0x35, 0xac, + 0xdf, 0xf6, 0x0, 0x89, 0x2b, 0x22, 0x36, 0x44, + 0xe3, 0x0, 0x5, 0xe0, 0x0, 0x0, 0x0, 0xd5, + 0x0, 0x0, 0x3f, 0x30, 0x0, 0x0, 0x7a, 0x0, + 0x0, 0x2, 0xfb, 0x0, 0x0, 0xe, 0x20, 0x0, + 0x0, 0x1c, 0xc4, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x1, 0xc2, 0xe2, 0x0, 0x98, 0x0, 0x0, 0x0, + 0x3b, 0x7, 0x80, 0xb, 0x60, 0x0, 0x0, 0x7, + 0x80, 0x0, 0x0, 0xa7, 0x0, 0x0, 0x0, 0xd3, + 0x0, 0x0, 0x7, 0xc0, 0x0, 0x0, 0x7e, 0x0, + 0x0, 0x0, 0xd, 0xb4, 0x34, 0xaf, 0x30, 0x0, + 0x0, 0x0, 0x19, 0xdf, 0xea, 0x20, 0x0, 0x0, + 0x0, + + /* U+3074 "ぴ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xcb, 0x20, + 0x0, 0x0, 0x11, 0x0, 0x12, 0xb0, 0x2a, 0x37, + 0x8b, 0xdf, 0x80, 0x9, 0x9a, 0x35, 0x85, 0xa8, + 0x7f, 0x50, 0x0, 0x5d, 0x19, 0x80, 0x0, 0xb, + 0x70, 0x0, 0x4, 0xf3, 0x0, 0x0, 0x6, 0xb0, + 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x0, 0xe3, 0x0, + 0x0, 0x1, 0xde, 0x30, 0x0, 0x4c, 0x0, 0x0, + 0x0, 0x1b, 0x4e, 0x20, 0x8, 0x90, 0x0, 0x0, + 0x3, 0xb0, 0x89, 0x0, 0xb6, 0x0, 0x0, 0x0, + 0x79, 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, 0xc, + 0x40, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x7, 0xd0, + 0x0, 0x0, 0x0, 0xdb, 0x43, 0x4a, 0xe2, 0x0, + 0x0, 0x0, 0x1, 0x9d, 0xfe, 0xa2, 0x0, 0x0, + 0x0, + + /* U+3075 "ふ" */ + 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xae, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xcd, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3f, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x64, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x71, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9d, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x9, 0xb0, 0x2, 0xe1, 0x0, + 0x0, 0x0, 0x61, 0x0, 0xc7, 0x0, 0x8a, 0x0, + 0x0, 0x9, 0xd2, 0x0, 0x2f, 0x10, 0xe, 0x40, + 0x2, 0xcc, 0x10, 0x0, 0xd, 0x50, 0x7, 0xc0, + 0x1f, 0x80, 0x2, 0x0, 0x2f, 0x40, 0x1, 0xf2, + 0x2, 0x0, 0xe, 0xfe, 0xfa, 0x0, 0x0, 0x10, + 0x0, 0x0, 0x0, 0x23, 0x10, 0x0, 0x0, 0x0, + + /* U+3076 "ぶ" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xeb, 0x30, 0x0, 0x3, 0x0, + 0x0, 0x0, 0x0, 0x7, 0xf9, 0x4, 0x57, 0x80, + 0x0, 0x0, 0x0, 0x0, 0x7f, 0x21, 0xd1, 0xc1, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x53, 0x0, + 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xe7, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2e, 0x40, 0x8, 0x90, 0x0, + 0x0, 0x0, 0x50, 0x4, 0xe2, 0x0, 0xe4, 0x0, + 0x0, 0x1b, 0xb0, 0x0, 0x8b, 0x0, 0x5e, 0x0, + 0x4, 0xea, 0x0, 0x0, 0x3f, 0x0, 0xd, 0x50, + 0x6f, 0x60, 0x0, 0x0, 0x5f, 0x0, 0x7, 0xc0, + 0x12, 0x0, 0x4e, 0xcd, 0xf7, 0x0, 0x0, 0x10, + 0x0, 0x0, 0x2, 0x44, 0x10, 0x0, 0x0, 0x0, + + /* U+3077 "ぷ" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xeb, 0x30, 0x0, 0x29, 0x60, + 0x0, 0x0, 0x0, 0x7, 0xf9, 0x0, 0xc2, 0x86, + 0x0, 0x0, 0x0, 0x0, 0x7f, 0x20, 0xc0, 0x38, + 0x0, 0x0, 0x0, 0x0, 0xb3, 0x0, 0x7c, 0xb1, + 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xe6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2e, 0x40, 0x5, 0xd0, 0x0, + 0x0, 0x0, 0x40, 0x4, 0xe2, 0x0, 0xb9, 0x0, + 0x0, 0xb, 0xb0, 0x0, 0x9a, 0x0, 0x2f, 0x30, + 0x4, 0xda, 0x0, 0x0, 0x3f, 0x0, 0x9, 0xa0, + 0x6f, 0x60, 0x0, 0x0, 0x5f, 0x0, 0x2, 0xf2, + 0x12, 0x0, 0x4e, 0xcd, 0xf7, 0x0, 0x0, 0x20, + 0x0, 0x0, 0x2, 0x44, 0x20, 0x0, 0x0, 0x0, + + /* U+3078 "へ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xfb, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5f, 0x5c, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xf5, 0x1, 0xd9, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0x80, 0x0, 0x2e, 0x70, 0x0, 0x0, + 0x0, 0xcb, 0x0, 0x0, 0x3, 0xf6, 0x0, 0x0, + 0xc, 0xe1, 0x0, 0x0, 0x0, 0x5f, 0x50, 0x0, + 0x4, 0x30, 0x0, 0x0, 0x0, 0x7, 0xf4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+3079 "べ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x63, 0x5c, 0x0, + 0x0, 0x0, 0x4, 0xb5, 0x0, 0x4c, 0xb, 0x60, + 0x0, 0x0, 0x3f, 0x9f, 0x50, 0xb, 0x51, 0x10, + 0x0, 0x1, 0xe6, 0x4, 0xf3, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x90, 0x0, 0x7e, 0x20, 0x0, 0x0, + 0x0, 0xac, 0x0, 0x0, 0x9, 0xd1, 0x0, 0x0, + 0xa, 0xe1, 0x0, 0x0, 0x0, 0xbd, 0x10, 0x0, + 0xa, 0x40, 0x0, 0x0, 0x0, 0xc, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xdc, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x40, + + /* U+307A "ぺ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6, 0x85, 0xb0, 0x0, + 0x0, 0x3, 0x70, 0x0, 0xa1, 0xc, 0x0, 0x0, + 0x3, 0xfd, 0xd1, 0x7, 0x73, 0xb0, 0x0, 0x1, + 0xe6, 0xb, 0xb0, 0x8, 0xa1, 0x0, 0x0, 0xc9, + 0x0, 0xd, 0xa0, 0x0, 0x0, 0x0, 0xac, 0x0, + 0x0, 0x1e, 0x70, 0x0, 0x0, 0x9e, 0x10, 0x0, + 0x0, 0x3f, 0x60, 0x0, 0x1e, 0x40, 0x0, 0x0, + 0x0, 0x5f, 0x50, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x6f, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7f, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x73, + + /* U+307B "ほ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5d, 0x0, 0x3, 0x33, 0x33, 0x45, 0x20, 0x7, + 0xa0, 0x0, 0xcc, 0xcd, 0xea, 0x93, 0x0, 0x97, + 0x0, 0x0, 0x0, 0x4b, 0x0, 0x0, 0xc, 0x40, + 0x0, 0x0, 0x4, 0xb0, 0x1, 0x0, 0xd2, 0x0, + 0x3e, 0xdd, 0xef, 0xff, 0xb0, 0xf, 0x0, 0x0, + 0x22, 0x26, 0xc1, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x4c, 0x0, 0x0, 0x1f, 0x15, 0x0, 0x0, + 0x3, 0xc0, 0x0, 0x0, 0xf7, 0x60, 0x1a, 0xdd, + 0xee, 0x40, 0x0, 0xf, 0xd0, 0xb, 0x70, 0x2, + 0xfb, 0xd3, 0x0, 0xdb, 0x0, 0xb6, 0x0, 0x6d, + 0x5, 0xe1, 0xa, 0x70, 0x2, 0xcf, 0xee, 0x50, + 0x1, 0x0, 0x22, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, + + /* U+307C "ぼ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x41, 0xa0, 0xe, + 0x30, 0x2, 0x21, 0x12, 0x3a, 0x4b, 0x21, 0xf0, + 0x0, 0xcd, 0xde, 0xfc, 0xb9, 0x22, 0x3d, 0x0, + 0x0, 0x0, 0x2d, 0x0, 0x0, 0x6, 0xa0, 0x0, + 0x0, 0x2, 0xd0, 0x0, 0x0, 0x78, 0x0, 0x3, + 0x33, 0x4e, 0x45, 0x60, 0x9, 0x60, 0x0, 0xcc, + 0xdd, 0xfb, 0xa8, 0x0, 0xa5, 0x0, 0x0, 0x0, + 0x1e, 0x0, 0x0, 0xb, 0x42, 0x0, 0x0, 0x1, + 0xf0, 0x0, 0x0, 0xb6, 0xb0, 0x4, 0x9b, 0xaf, + 0x20, 0x0, 0xa, 0xc6, 0x6, 0xc5, 0x24, 0xfe, + 0x91, 0x0, 0x9f, 0x20, 0xa5, 0x0, 0x1f, 0x2b, + 0xd2, 0x7, 0xe0, 0x6, 0xc6, 0x39, 0xd0, 0x9, + 0x10, 0x4c, 0x0, 0x5, 0xbc, 0xa2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+307D "ぽ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xaa, 0x30, + 0x92, 0x0, 0x11, 0x11, 0x12, 0xb4, 0x48, 0xf, + 0x10, 0xc, 0xdd, 0xef, 0xca, 0x77, 0x3, 0xd0, + 0x0, 0x0, 0x2, 0xd0, 0x0, 0x0, 0x5b, 0x0, + 0x0, 0x0, 0x2d, 0x0, 0x0, 0x7, 0x80, 0x0, + 0x33, 0x34, 0xe4, 0x56, 0x0, 0x97, 0x0, 0xc, + 0xcd, 0xdf, 0xba, 0x80, 0xa, 0x50, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0x0, 0xb4, 0x20, 0x0, 0x0, + 0x1f, 0x0, 0x0, 0xb, 0x6b, 0x0, 0x49, 0xba, + 0xf2, 0x0, 0x0, 0xac, 0x60, 0x6c, 0x52, 0x4f, + 0xe9, 0x10, 0x9, 0xf2, 0xa, 0x50, 0x1, 0xf2, + 0xbd, 0x20, 0x7e, 0x0, 0x6c, 0x63, 0x9d, 0x0, + 0x91, 0x4, 0xc0, 0x0, 0x5b, 0xca, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+307E "ま" */ + 0x0, 0x0, 0x1, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0x0, 0x21, 0xe, 0xed, 0xcc, 0xfd, + 0xff, 0xe4, 0x0, 0x12, 0x34, 0xf2, 0x10, 0x0, + 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, 0x5, 0x32, + 0x12, 0xf3, 0x46, 0x84, 0xb, 0xcd, 0xee, 0xfd, + 0xca, 0x94, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf1, 0x0, 0x0, 0x1, 0x9d, + 0xee, 0xf8, 0x10, 0x0, 0xb, 0x81, 0x0, 0xfb, + 0xf9, 0x10, 0xf, 0x10, 0x0, 0xf2, 0x2b, 0xe4, + 0xb, 0xa3, 0x38, 0xe0, 0x0, 0x77, 0x1, 0x8c, + 0xca, 0x30, 0x0, 0x0, + + /* U+307F "み" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5c, 0xcd, 0xef, 0x80, 0x0, 0x0, 0x0, 0x24, + 0x32, 0x3f, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe3, + 0x0, 0x4, 0x10, 0x0, 0x0, 0x5, 0xd0, 0x0, + 0xc, 0x40, 0x0, 0x2a, 0xcf, 0xfb, 0x83, 0xd, + 0x20, 0x7, 0xd6, 0x5e, 0x25, 0x8e, 0xdf, 0x10, + 0x4d, 0x0, 0xa7, 0x0, 0x0, 0x7f, 0xc3, 0x95, + 0x2, 0xf1, 0x0, 0x0, 0x99, 0x9d, 0xb7, 0xc, + 0x80, 0x0, 0x3, 0xf2, 0x1, 0x5f, 0xec, 0x0, + 0x0, 0x2d, 0x70, 0x0, 0x1, 0x30, 0x0, 0x6, + 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0x40, + 0x0, 0x0, + + /* U+3080 "む" */ + 0x0, 0x5, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x36, + 0xd6, 0xac, 0x0, 0xa2, 0x0, 0x3b, 0xce, 0xfa, + 0x74, 0x0, 0x6e, 0x50, 0x0, 0x4, 0xc0, 0x0, + 0x0, 0x3, 0xe5, 0x0, 0x8d, 0xc0, 0x0, 0x0, + 0x0, 0x32, 0xa, 0x85, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0x0, 0xf0, 0x0, 0x0, 0x2, 0x0, 0xf, + 0x57, 0xb0, 0x0, 0x0, 0xf, 0x30, 0x5, 0xef, + 0x50, 0x0, 0x0, 0xf, 0x30, 0x0, 0xc, 0x50, + 0x0, 0x0, 0x2f, 0x10, 0x0, 0xa, 0xc5, 0x44, + 0x57, 0xeb, 0x0, 0x0, 0x1, 0x8b, 0xdc, 0xc9, + 0x50, 0x0, + + /* U+3081 "め" */ + 0x0, 0x0, 0x0, 0x0, 0x52, 0x0, 0x0, 0x0, + 0x70, 0x0, 0x0, 0xe4, 0x0, 0x0, 0x0, 0xf2, + 0x0, 0x1, 0xf0, 0x0, 0x0, 0x0, 0xa7, 0x4b, + 0xef, 0xfc, 0x70, 0x0, 0x0, 0x6f, 0xc5, 0x1a, + 0x74, 0xcc, 0x0, 0x1, 0xdf, 0x20, 0xf, 0x10, + 0xb, 0x80, 0xc, 0x78, 0x90, 0x6b, 0x0, 0x2, + 0xf0, 0x5c, 0x1, 0xf2, 0xe4, 0x0, 0x0, 0xf2, + 0xa8, 0x0, 0x8e, 0xb0, 0x0, 0x0, 0xf2, 0xb5, + 0x0, 0x4f, 0x70, 0x0, 0x3, 0xf0, 0x9a, 0x3, + 0xe8, 0xe1, 0x0, 0xd, 0x80, 0x2e, 0xfe, 0x40, + 0x0, 0x4, 0xdc, 0x0, 0x0, 0x30, 0x0, 0xa, + 0xef, 0x70, 0x0, 0x0, 0x0, 0x0, 0x4, 0x30, + 0x0, 0x0, + + /* U+3082 "も" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2f, 0x0, 0x0, 0x0, 0x0, 0x6, 0x41, 0x3d, + 0x0, 0x0, 0x0, 0x0, 0x9, 0xdf, 0xff, 0xef, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0x8a, 0x22, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x97, 0x0, 0x0, 0x0, + 0x0, 0x25, 0x20, 0xb5, 0x0, 0x0, 0x78, 0x0, + 0x3b, 0xef, 0xfd, 0xde, 0xe0, 0x1e, 0x40, 0x0, + 0x1, 0xf5, 0x32, 0x10, 0x7, 0xb0, 0x0, 0x0, + 0xf1, 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0xf1, + 0x0, 0x0, 0x4, 0xe0, 0x0, 0x0, 0xc6, 0x0, + 0x0, 0xc, 0x90, 0x0, 0x0, 0x4f, 0x84, 0x57, + 0xec, 0x0, 0x0, 0x0, 0x3, 0xad, 0xca, 0x50, + 0x0, + + /* U+3083 "ゃ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2d, 0x20, 0x0, 0x0, 0x0, 0x67, 0x0, + 0x5b, 0x0, 0x0, 0x0, 0x2, 0xf1, 0x5, 0xad, + 0xfc, 0x40, 0x0, 0xa, 0xce, 0xa5, 0x10, 0x5f, + 0x10, 0x5b, 0xef, 0x20, 0x0, 0x0, 0xd4, 0xb, + 0x60, 0xa7, 0x2, 0x0, 0x3f, 0x10, 0x0, 0x3, + 0xe0, 0xbf, 0xee, 0x50, 0x0, 0x0, 0xd, 0x40, + 0x11, 0x0, 0x0, 0x0, 0x0, 0x7a, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+3084 "や" */ + 0x0, 0x0, 0x0, 0x27, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x20, 0x1, 0xba, 0x0, 0x0, 0x0, 0x0, + 0x4f, 0x10, 0x0, 0xa4, 0x10, 0x0, 0x0, 0x0, + 0xb8, 0x0, 0x6b, 0xfe, 0xfd, 0x30, 0x0, 0x2, + 0xf9, 0xea, 0x51, 0x0, 0x6e, 0x10, 0x5, 0xbf, + 0xc1, 0x0, 0x0, 0x0, 0xd4, 0xe, 0xd6, 0x3f, + 0x10, 0x0, 0x0, 0xe, 0x30, 0x30, 0x0, 0xc6, + 0x6, 0x74, 0x5c, 0xc0, 0x0, 0x0, 0x6, 0xd0, + 0x4b, 0xdb, 0x80, 0x0, 0x0, 0x0, 0xf, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x94, 0x0, 0x0, + 0x0, + + /* U+3085 "ゅ" */ + 0x0, 0x0, 0x7, 0x60, 0x0, 0x6, 0xa0, 0x0, + 0x6a, 0x0, 0x0, 0x87, 0x2, 0xae, 0xfe, 0xc4, + 0xa, 0x55, 0xd4, 0x3c, 0x4, 0xe3, 0xb7, 0xc0, + 0x2, 0xd0, 0x6, 0x9c, 0xe1, 0x0, 0x2c, 0x0, + 0x4b, 0xba, 0x9, 0x4, 0xa0, 0x8, 0x9a, 0x70, + 0xba, 0x88, 0x6, 0xe2, 0x78, 0x0, 0x9f, 0xff, + 0xc3, 0x0, 0x0, 0x7, 0xc2, 0x0, 0x0, 0x0, + 0x7, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, + + /* U+3086 "ゆ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x70, 0x0, 0x0, 0x25, 0x0, 0x0, + 0x89, 0x0, 0x0, 0x6, 0x90, 0x0, 0x6, 0xb1, + 0x0, 0x0, 0x87, 0x0, 0x5c, 0xff, 0xde, 0x60, + 0xa, 0x50, 0xbb, 0x33, 0xd0, 0x2c, 0x80, 0xb4, + 0xb7, 0x0, 0x2e, 0x0, 0x1f, 0x1c, 0x89, 0x0, + 0x2, 0xe0, 0x0, 0xd4, 0xce, 0x0, 0x0, 0x3d, + 0x0, 0xe, 0x3b, 0x90, 0x97, 0x5, 0xc0, 0x3, + 0xf0, 0xa7, 0x1, 0xe8, 0x98, 0x5, 0xe6, 0x7, + 0x90, 0x1, 0xaf, 0xef, 0xd5, 0x0, 0x0, 0x0, + 0x7, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x6, 0xe2, + 0x0, 0x0, 0x0, 0x0, 0x1, 0xa2, 0x0, 0x0, + 0x0, 0x0, + + /* U+3087 "ょ" */ + 0x0, 0x0, 0x57, 0x0, 0x0, 0x0, 0x0, 0x6a, + 0x0, 0x0, 0x0, 0x0, 0x6b, 0x34, 0x54, 0x0, + 0x0, 0x6e, 0xbb, 0x96, 0x0, 0x0, 0x6a, 0x0, + 0x0, 0x0, 0x0, 0x6a, 0x0, 0x0, 0x0, 0x2, + 0x6b, 0x0, 0x0, 0x2c, 0xec, 0xdf, 0x92, 0x0, + 0xc5, 0x0, 0x4d, 0x7e, 0x90, 0xb8, 0x11, 0xab, + 0x1, 0xba, 0x1a, 0xef, 0xc3, 0x0, 0x1, + + /* U+3088 "よ" */ + 0x0, 0x0, 0x8, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x6, 0xb2, 0x34, 0x53, + 0x0, 0x0, 0x6, 0xfe, 0xdc, 0xb5, 0x0, 0x0, + 0x6, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x5, 0xc0, 0x0, 0x0, + 0x0, 0x1, 0x26, 0xc0, 0x0, 0x0, 0x9, 0xee, + 0xef, 0xf8, 0x20, 0x0, 0xaa, 0x10, 0x4, 0xe9, + 0xfb, 0x10, 0xd4, 0x0, 0x6, 0xe0, 0x1a, 0xe4, + 0x8d, 0x63, 0x6d, 0xa0, 0x0, 0x77, 0x6, 0xbd, + 0xc8, 0x10, 0x0, 0x0, + + /* U+3089 "ら" */ + 0x0, 0x5, 0x20, 0x0, 0x0, 0x0, 0x0, 0xb, + 0xfe, 0xb8, 0x51, 0x0, 0x0, 0x0, 0x3, 0x69, + 0xb2, 0x0, 0x5, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x90, 0x0, 0x0, 0x0, 0x0, 0xa, 0x70, + 0x0, 0x0, 0x0, 0x0, 0xc, 0x50, 0x7c, 0xff, + 0xd8, 0x0, 0xe, 0x7e, 0x83, 0x0, 0x2b, 0xb0, + 0xf, 0xe4, 0x0, 0x0, 0x0, 0xe3, 0x2d, 0x20, + 0x0, 0x0, 0x0, 0xd5, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x4e, 0xa0, + 0x0, 0x2a, 0x99, 0xbe, 0xf8, 0x0, 0x0, 0x8, + 0x98, 0x74, 0x0, 0x0, + + /* U+308A "り" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x60, 0x0, + 0x0, 0x0, 0xe, 0x30, 0x5b, 0xc7, 0x0, 0xf, + 0x9, 0xc5, 0x5d, 0x90, 0x2e, 0x6a, 0x0, 0x1, + 0xf2, 0x3d, 0xc0, 0x0, 0x0, 0xb7, 0x4f, 0x50, + 0x0, 0x0, 0x8a, 0x5f, 0x10, 0x0, 0x0, 0x7b, + 0x5d, 0x0, 0x0, 0x0, 0x99, 0x4e, 0x0, 0x0, + 0x0, 0xc6, 0x13, 0x0, 0x0, 0x2, 0xf3, 0x0, + 0x0, 0x0, 0xd, 0x90, 0x0, 0x0, 0x5, 0xdc, + 0x0, 0x0, 0x39, 0xde, 0x60, 0x0, 0x0, 0x18, + 0x30, 0x0, 0x0, + + /* U+308B "る" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x1, + 0xee, 0xef, 0xff, 0xfd, 0x0, 0x0, 0x3, 0x21, + 0x0, 0x9d, 0x20, 0x0, 0x0, 0x0, 0x0, 0xbc, + 0x10, 0x0, 0x0, 0x0, 0x1, 0xda, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xe9, 0x1, 0x0, 0x0, 0x0, + 0x5, 0xff, 0xcc, 0xde, 0x91, 0x0, 0x7, 0xf8, + 0x20, 0x0, 0x8, 0xd1, 0xa, 0xd3, 0x0, 0x0, + 0x0, 0xa, 0x80, 0x61, 0x2, 0x9a, 0x60, 0x0, + 0x6b, 0x0, 0x0, 0xe6, 0x3b, 0xa0, 0x8, 0x90, + 0x0, 0x3e, 0x0, 0x1f, 0x34, 0xe3, 0x0, 0x0, + 0xd9, 0x43, 0xdd, 0xf6, 0x0, 0x0, 0x1, 0x8c, + 0xdb, 0x81, 0x0, + + /* U+308C "れ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x58, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x7, 0x9a, 0xdd, 0x2, 0xaf, 0xfd, 0x0, 0x0, + 0x7, 0x75, 0x96, 0x6d, 0x50, 0xe, 0x50, 0x0, + 0x0, 0x0, 0x8c, 0xc1, 0x0, 0xb, 0x60, 0x0, + 0x0, 0x1, 0xea, 0x0, 0x0, 0xc, 0x40, 0x0, + 0x0, 0xb, 0xf2, 0x0, 0x0, 0xe, 0x20, 0x0, + 0x0, 0x8a, 0xe2, 0x0, 0x0, 0xf, 0x0, 0x0, + 0x5, 0xd0, 0xe2, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x2f, 0x30, 0xe2, 0x0, 0x0, 0x3d, 0x0, 0x11, + 0x4, 0x0, 0xe2, 0x0, 0x0, 0x2f, 0x46, 0xe4, + 0x0, 0x0, 0xf3, 0x0, 0x0, 0xa, 0xfd, 0x50, + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+308D "ろ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xcc, 0xcd, 0xde, 0xf7, 0x0, 0x0, 0x24, 0x33, + 0x22, 0xcc, 0x10, 0x0, 0x0, 0x0, 0x0, 0xca, + 0x0, 0x0, 0x0, 0x0, 0x1, 0xd9, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xd7, 0x11, 0x0, 0x0, 0x0, + 0x3, 0xef, 0xed, 0xee, 0x70, 0x0, 0x5, 0xfb, + 0x30, 0x0, 0x2b, 0xa0, 0x8, 0xf6, 0x0, 0x0, + 0x0, 0xf, 0x31, 0xd3, 0x0, 0x0, 0x0, 0x0, + 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x2c, 0xc0, 0x0, 0x0, + 0x66, 0x68, 0xbf, 0xb1, 0x0, 0x0, 0xa, 0xba, + 0xa6, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+308F "わ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xa0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xef, + 0xfc, 0x1, 0x69, 0xa8, 0x30, 0x0, 0x32, 0xa, + 0x57, 0xea, 0x65, 0x8e, 0x80, 0x0, 0x0, 0xde, + 0xb1, 0x0, 0x0, 0x1e, 0x40, 0x0, 0x6f, 0x70, + 0x0, 0x0, 0x0, 0x89, 0x0, 0x2e, 0xf2, 0x0, + 0x0, 0x0, 0x7, 0xb0, 0xd, 0x6e, 0x20, 0x0, + 0x0, 0x0, 0xa8, 0xa, 0xb0, 0xe2, 0x0, 0x0, + 0x0, 0x4f, 0x32, 0xe1, 0xe, 0x20, 0x0, 0x0, + 0x7f, 0x60, 0x1, 0x0, 0xe2, 0x0, 0x4b, 0xfc, + 0x30, 0x0, 0x0, 0xf, 0x30, 0x2, 0x72, 0x0, + 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+3092 "を" */ + 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0x0, 0x2, 0x20, 0x0, 0x1d, 0xcb, + 0xcf, 0xde, 0xfe, 0xa0, 0x0, 0x3, 0x34, 0xe6, + 0x21, 0x0, 0x0, 0x0, 0x0, 0x5, 0xb0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x1e, 0x8b, 0xb5, 0x0, + 0x4b, 0xd0, 0x0, 0xce, 0x73, 0x5f, 0x7c, 0xd6, + 0x10, 0xa, 0xd1, 0x0, 0x3e, 0xc4, 0x0, 0x0, + 0x2c, 0x10, 0x8, 0xcc, 0x50, 0x0, 0x0, 0x0, + 0x0, 0xaa, 0xa, 0x60, 0x0, 0x0, 0x0, 0x3, + 0xe0, 0x9, 0x50, 0x0, 0x0, 0x0, 0x5, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xf8, 0x43, + 0x34, 0x58, 0x0, 0x0, 0x0, 0x39, 0xde, 0xdd, + 0xca, 0x0, + + /* U+3093 "ん" */ + 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6e, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x7a, 0xc5, 0x0, 0x0, + 0x0, 0x0, 0x7f, 0xa4, 0x6f, 0x0, 0x0, 0x0, + 0x0, 0xea, 0x0, 0xe, 0x30, 0x0, 0x14, 0x7, + 0xd0, 0x0, 0xd, 0x30, 0x0, 0x7b, 0xe, 0x50, + 0x0, 0xd, 0x40, 0x1, 0xe4, 0x5e, 0x0, 0x0, + 0xc, 0x80, 0x1c, 0xa0, 0xc8, 0x0, 0x0, 0x6, + 0xfe, 0xfa, 0x0, 0x11, 0x0, 0x0, 0x0, 0x24, + 0x10, 0x0, + + /* U+30A1 "ァ" */ + 0x2e, 0xdd, 0xdd, 0xdd, 0xdd, 0xd7, 0x3, 0x33, + 0x33, 0x33, 0x35, 0xf3, 0x0, 0x0, 0x8, 0x40, + 0xd, 0x70, 0x0, 0x0, 0xc, 0x52, 0xd8, 0x0, + 0x0, 0x0, 0xd, 0x44, 0x70, 0x0, 0x0, 0x0, + 0xf, 0x10, 0x0, 0x0, 0x0, 0x0, 0x6d, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xe4, 0x0, 0x0, 0x0, + 0x0, 0x3e, 0x90, 0x0, 0x0, 0x0, 0x1, 0xc7, + 0x0, 0x0, 0x0, 0x0, + + /* U+30A2 "ア" */ + 0x43, 0x22, 0x22, 0x22, 0x22, 0x23, 0x1f, 0xee, + 0xee, 0xee, 0xee, 0xee, 0xf9, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5f, 0x10, 0x0, 0x0, 0x63, 0x0, + 0x2e, 0x50, 0x0, 0x0, 0xc, 0x60, 0x4e, 0x60, + 0x0, 0x0, 0x0, 0xc6, 0x3f, 0x50, 0x0, 0x0, + 0x0, 0xd, 0x50, 0x20, 0x0, 0x0, 0x0, 0x1, + 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x1c, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x5e, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x5, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30A3 "ィ" */ + 0x0, 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, + 0x0, 0xb, 0xd1, 0x0, 0x0, 0x0, 0x3d, 0xb1, + 0x0, 0x0, 0x0, 0x7f, 0x70, 0x0, 0x0, 0x17, + 0xed, 0xe0, 0x0, 0x5, 0xbf, 0xb3, 0x3e, 0x0, + 0x0, 0x67, 0x10, 0x3, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x3, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x4e, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xf0, 0x0, 0x0, + + /* U+30A4 "イ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xf6, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xf6, 0x0, 0x0, 0x0, 0x0, 0x4c, 0xd2, 0x0, + 0x0, 0x0, 0x3, 0xbf, 0xf5, 0x0, 0x0, 0x1, + 0x7c, 0xf8, 0x1e, 0x50, 0x0, 0x6, 0xfd, 0x71, + 0x0, 0xe5, 0x0, 0x0, 0x13, 0x0, 0x0, 0xe, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x62, 0x0, 0x0, + + /* U+30A6 "ウ" */ + 0x0, 0x0, 0xf, 0x50, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x40, 0x0, 0x0, 0x11, 0x11, 0x1e, 0x51, + 0x11, 0x10, 0xef, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0xe3, 0x0, 0x0, 0x0, 0x0, 0xc8, 0xe3, 0x0, + 0x0, 0x0, 0x0, 0xf4, 0xe3, 0x0, 0x0, 0x0, + 0x3, 0xf1, 0xc3, 0x0, 0x0, 0x0, 0xa, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x1f, 0x30, 0x0, 0x0, + 0x0, 0x1, 0xda, 0x0, 0x0, 0x0, 0x0, 0x1d, + 0xd1, 0x0, 0x0, 0x0, 0x18, 0xfb, 0x10, 0x0, + 0x0, 0xa, 0xfe, 0x50, 0x0, 0x0, 0x0, 0x4, + 0x40, 0x0, 0x0, 0x0, + + /* U+30A7 "ェ" */ + 0x2, 0x11, 0x11, 0x11, 0x11, 0x10, 0xe, 0xfe, + 0xef, 0xfe, 0xef, 0x90, 0x0, 0x0, 0xd, 0x40, + 0x0, 0x0, 0x0, 0x0, 0xd, 0x40, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x40, 0x0, 0x0, 0x0, 0x0, + 0xd, 0x40, 0x0, 0x0, 0x0, 0x0, 0xd, 0x40, + 0x0, 0x0, 0x11, 0x11, 0x1d, 0x51, 0x11, 0x10, + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+30A8 "エ" */ + 0x4, 0x54, 0x44, 0x44, 0x44, 0x45, 0x30, 0xb, + 0xcc, 0xcc, 0xfd, 0xcc, 0xcc, 0x80, 0x0, 0x0, + 0x0, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd5, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd5, 0x0, 0x0, 0x0, 0xdf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x31, + + /* U+30AA "オ" */ + 0x0, 0x0, 0x0, 0x0, 0xf3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe3, 0x0, 0x0, 0x3d, 0xcc, 0xcc, + 0xcc, 0xfd, 0xcc, 0xd1, 0x15, 0x44, 0x44, 0x4b, + 0xf7, 0x44, 0x50, 0x0, 0x0, 0x0, 0x4e, 0xe3, + 0x0, 0x0, 0x0, 0x0, 0x3, 0xf4, 0xd4, 0x0, + 0x0, 0x0, 0x0, 0x4f, 0x50, 0xd4, 0x0, 0x0, + 0x0, 0x7, 0xf5, 0x0, 0xd4, 0x0, 0x0, 0x2, + 0xbe, 0x30, 0x0, 0xd4, 0x0, 0x0, 0x6f, 0xa1, + 0x0, 0x0, 0xd4, 0x0, 0x0, 0x14, 0x0, 0x0, + 0x0, 0xd5, 0x0, 0x0, 0x0, 0x0, 0xa, 0xed, + 0xf2, 0x0, 0x0, 0x0, 0x0, 0x1, 0x33, 0x10, + 0x0, 0x0, + + /* U+30AB "カ" */ + 0x0, 0x0, 0x3, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xe0, 0x0, 0x0, 0x0, 0xdc, 0xcc, 0xdf, 0xcc, + 0xcc, 0xd5, 0x5, 0x44, 0x49, 0xc4, 0x44, 0x4c, + 0x70, 0x0, 0x0, 0x98, 0x0, 0x0, 0xb6, 0x0, + 0x0, 0xc, 0x40, 0x0, 0xb, 0x50, 0x0, 0x2, + 0xf1, 0x0, 0x0, 0xc4, 0x0, 0x0, 0x8a, 0x0, + 0x0, 0xe, 0x30, 0x0, 0x2f, 0x30, 0x0, 0x0, + 0xf1, 0x0, 0xc, 0xa0, 0x0, 0x0, 0x3f, 0x0, + 0x1c, 0xd0, 0x0, 0x10, 0x8, 0xb0, 0xd, 0xc1, + 0x0, 0xb, 0xff, 0xf4, 0x0, 0x20, 0x0, 0x0, + 0x1, 0x20, 0x0, + + /* U+30AC "ガ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x0, + 0x0, 0x0, 0x5e, 0x0, 0x5, 0x85, 0xa0, 0x0, + 0x0, 0x4, 0xd0, 0x0, 0xe, 0x1d, 0x20, 0x0, + 0x0, 0x4d, 0x0, 0x0, 0x85, 0x10, 0x3, 0x32, + 0x27, 0xd2, 0x22, 0x23, 0x0, 0x0, 0xfe, 0xee, + 0xff, 0xee, 0xee, 0xf7, 0x0, 0x0, 0x0, 0x9, + 0x80, 0x0, 0xb, 0x60, 0x0, 0x0, 0x0, 0xc5, + 0x0, 0x0, 0xc5, 0x0, 0x0, 0x0, 0x1f, 0x10, + 0x0, 0xd, 0x40, 0x0, 0x0, 0x7, 0xb0, 0x0, + 0x0, 0xe3, 0x0, 0x0, 0x1, 0xe4, 0x0, 0x0, + 0xf, 0x10, 0x0, 0x0, 0xbb, 0x0, 0x0, 0x3, + 0xf0, 0x0, 0x0, 0xae, 0x10, 0x0, 0x0, 0x8b, + 0x0, 0x0, 0xdd, 0x20, 0x0, 0xde, 0xef, 0x40, + 0x0, 0x3, 0x0, 0x0, 0x1, 0x33, 0x10, 0x0, + 0x0, + + /* U+30AD "キ" */ + 0x0, 0x0, 0x6, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xa0, 0x3, 0x56, 0x0, 0x0, 0x13, 0x6a, + 0xfd, 0xff, 0xc9, 0x0, 0x1f, 0xfe, 0xc9, 0xf5, + 0x10, 0x0, 0x0, 0x4, 0x10, 0x0, 0xe4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb7, 0x0, 0x0, + 0x30, 0x0, 0x0, 0x0, 0x9c, 0x7a, 0xdf, 0xf3, + 0x16, 0x8a, 0xdf, 0xff, 0xa7, 0x42, 0x0, 0x1d, + 0xa7, 0x41, 0x1f, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x70, + 0x0, 0x0, + + /* U+30AE "ギ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, + 0x0, 0x0, 0x30, 0x0, 0x8, 0x49, 0x60, 0x0, + 0x0, 0x1f, 0x20, 0x0, 0x2d, 0x1b, 0x0, 0x0, + 0x0, 0xd5, 0x0, 0x2, 0x71, 0x0, 0x0, 0x0, + 0x2c, 0xb9, 0xcf, 0xf8, 0x0, 0x4, 0xbd, 0xff, + 0xee, 0x75, 0x20, 0x0, 0x0, 0x27, 0x42, 0x4, + 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd6, + 0x46, 0x9c, 0xe0, 0x0, 0x24, 0x79, 0xcf, 0xfd, + 0xb8, 0x63, 0x0, 0x7f, 0xda, 0x85, 0x9b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe5, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa, 0x60, 0x0, 0x0, + 0x0, + + /* U+30AF "ク" */ + 0x0, 0x0, 0x0, 0x71, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4f, 0x20, 0x0, 0x0, 0x0, 0x0, 0xc, + 0xb3, 0x33, 0x34, 0x10, 0x0, 0x8, 0xec, 0xcc, + 0xcc, 0xfb, 0x0, 0x5, 0xf2, 0x0, 0x0, 0xf, + 0x50, 0x5, 0xf4, 0x0, 0x0, 0x5, 0xe0, 0x9, + 0xe4, 0x0, 0x0, 0x0, 0xc8, 0x0, 0x82, 0x0, + 0x0, 0x0, 0x6e, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x1f, 0x50, 0x0, 0x0, 0x0, 0x0, 0x2d, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x3e, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x7f, 0x90, 0x0, 0x0, 0x0, 0x28, + 0xed, 0x40, 0x0, 0x0, 0x0, 0x3, 0xb5, 0x0, + 0x0, 0x0, 0x0, + + /* U+30B0 "グ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x32, 0x0, 0x4, 0x47, 0x70, + 0x0, 0x0, 0x0, 0xd8, 0x0, 0x1, 0xd1, 0xd1, + 0x0, 0x0, 0x6, 0xe1, 0x0, 0x1, 0x73, 0x0, + 0x0, 0x0, 0x1e, 0xff, 0xff, 0xff, 0xe0, 0x0, + 0x0, 0x0, 0xc9, 0x0, 0x0, 0x9, 0xb0, 0x0, + 0x0, 0xc, 0xb0, 0x0, 0x0, 0xe, 0x50, 0x0, + 0x3, 0xda, 0x0, 0x0, 0x0, 0x5e, 0x0, 0x0, + 0x8, 0x80, 0x0, 0x0, 0x1, 0xe6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x9, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7f, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0xf4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xbe, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x9f, 0xa1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30B1 "ケ" */ + 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, + 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xb5, + 0x55, 0x55, 0x55, 0x53, 0x0, 0x4f, 0xcc, 0xcc, + 0xfd, 0xcc, 0xc7, 0x1, 0xe7, 0x0, 0x0, 0xf4, + 0x0, 0x0, 0xc, 0xc0, 0x0, 0x1, 0xf1, 0x0, + 0x0, 0x8d, 0x10, 0x0, 0x4, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1f, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xbc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, + 0xe1, 0x0, 0x0, 0x0, 0x0, 0x2, 0xbe, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x91, 0x0, 0x0, + 0x0, 0x0, + + /* U+30B2 "ゲ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x2, 0x2a, 0x40, + 0x0, 0x0, 0x4f, 0x10, 0x0, 0x4, 0xb2, 0xd0, + 0x0, 0x0, 0x9b, 0x0, 0x0, 0x0, 0xa3, 0x30, + 0x0, 0x0, 0xe7, 0x22, 0x22, 0x22, 0x23, 0x10, + 0x0, 0x6, 0xff, 0xff, 0xff, 0xff, 0xff, 0x50, + 0x0, 0x2f, 0x50, 0x0, 0x2f, 0x0, 0x0, 0x0, + 0x1, 0xda, 0x0, 0x0, 0x5d, 0x0, 0x0, 0x0, + 0xc, 0xc0, 0x0, 0x0, 0x7b, 0x0, 0x0, 0x0, + 0x1, 0x10, 0x0, 0x0, 0xd7, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xf1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xad, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1b, 0xe2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6b, 0x10, 0x0, 0x0, 0x0, 0x0, + + /* U+30B3 "コ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0xfe, + 0xee, 0xee, 0xee, 0xf4, 0x13, 0x32, 0x22, 0x22, + 0x22, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe4, 0x9f, 0xff, 0xff, 0xff, + 0xff, 0xf4, 0x23, 0x33, 0x33, 0x33, 0x33, 0xe4, + + /* U+30B4 "ゴ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc, 0x1a, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x5, 0xa1, 0xb0, 0x24, 0x33, 0x33, + 0x33, 0x33, 0x70, 0x0, 0x7f, 0xee, 0xee, 0xee, + 0xee, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf2, 0x0, 0x34, 0x44, 0x44, 0x44, + 0x44, 0xf2, 0x0, 0xae, 0xee, 0xee, 0xee, 0xee, + 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb2, + 0x0, + + /* U+30B5 "サ" */ + 0x0, 0x4, 0xc0, 0x0, 0x6, 0xc0, 0x0, 0x0, + 0x0, 0x4d, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, + 0x4, 0xd0, 0x0, 0x5, 0xc0, 0x0, 0x1, 0x10, + 0x5d, 0x0, 0x0, 0x6c, 0x1, 0x10, 0xaf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x5d, + 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x4, 0xd0, + 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, 0x4d, 0x0, + 0x0, 0x7a, 0x0, 0x0, 0x0, 0x5, 0xd0, 0x0, + 0xa, 0x80, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, + 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8d, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x5, 0xdd, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x27, 0x0, 0x0, 0x0, + 0x0, + + /* U+30B6 "ザ" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x40, 0x24, 0x40, + 0x0, 0x0, 0xf3, 0x0, 0x1, 0xf1, 0xc2, 0xb0, + 0x0, 0x0, 0xe3, 0x0, 0x1, 0xf0, 0x66, 0x60, + 0x0, 0x0, 0xe3, 0x0, 0x1, 0xf0, 0x0, 0x0, + 0x4f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x50, + 0x2, 0x21, 0xe5, 0x11, 0x13, 0xf2, 0x22, 0x0, + 0x0, 0x0, 0xe3, 0x0, 0x2, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0xe3, 0x0, 0x3, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0xf3, 0x0, 0x5, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x30, 0x0, 0xb, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2f, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xe8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0x9f, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x93, 0x0, 0x0, 0x0, 0x0, + + /* U+30B7 "シ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9f, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xc0, 0x0, 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x20, 0xc, 0xe6, 0x0, 0x0, 0x0, + 0x0, 0xc6, 0x0, 0x5e, 0x90, 0x0, 0x0, 0x8, + 0xe1, 0x0, 0x1, 0x20, 0x0, 0x0, 0x7f, 0x30, + 0x0, 0x0, 0x0, 0x0, 0xa, 0xf3, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xdd, 0x20, 0x0, 0x0, 0x0, + 0x1, 0x7f, 0x90, 0x0, 0x0, 0x0, 0x4, 0x9f, + 0xd5, 0x0, 0x0, 0x0, 0x3, 0xff, 0xb4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+30B8 "ジ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x60, 0x0, + 0x0, 0xc8, 0x0, 0x0, 0x29, 0xd, 0x40, 0x0, + 0x3, 0xcd, 0x30, 0x0, 0xc4, 0x3c, 0x0, 0x0, + 0x0, 0x8c, 0x0, 0x3, 0xa0, 0x0, 0x4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x10, 0x3, 0xeb, 0x20, + 0x0, 0x0, 0x0, 0xd, 0x20, 0x1, 0x9f, 0x50, + 0x0, 0x0, 0xa, 0xd0, 0x0, 0x0, 0x42, 0x0, + 0x0, 0x8, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3d, + 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x38, 0xfd, 0x50, 0x0, + 0x0, 0x0, 0x6, 0xff, 0xb5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+30B9 "ス" */ + 0x0, 0x22, 0x11, 0x11, 0x12, 0x20, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0xf1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4f, 0x10, 0x0, 0x0, 0x0, 0x0, 0x1, 0xe6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xbd, 0xf6, 0x0, 0x0, + 0x0, 0x0, 0x1c, 0xc1, 0x4f, 0x70, 0x0, 0x0, + 0x3, 0xdb, 0x0, 0x4, 0xf8, 0x0, 0x1, 0x8f, + 0x80, 0x0, 0x0, 0x4f, 0x60, 0x1e, 0xb2, 0x0, + 0x0, 0x0, 0x6, 0xf1, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x20, + + /* U+30BA "ズ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7, 0x66, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1d, 0x1a, 0x0, 0x4f, + 0xff, 0xff, 0xff, 0xff, 0x61, 0x0, 0x1, 0x32, + 0x22, 0x22, 0x29, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3f, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, + 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0xed, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x2d, 0xa0, 0xad, + 0x20, 0x0, 0x0, 0x0, 0x4e, 0x90, 0x0, 0xae, + 0x20, 0x0, 0x1, 0x9f, 0x70, 0x0, 0x0, 0xbd, + 0x10, 0x5, 0xfb, 0x20, 0x0, 0x0, 0x0, 0xdb, + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, + 0x0, + + /* U+30BB "セ" */ + 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf1, 0x0, 0x2, 0x69, 0xa0, 0x0, 0x0, + 0x1f, 0x79, 0xcf, 0xeb, 0xea, 0x0, 0x7a, 0xcf, + 0xfc, 0x85, 0x20, 0x3f, 0x10, 0xa, 0x85, 0x2f, + 0x10, 0x0, 0xd, 0x60, 0x0, 0x0, 0x0, 0xf1, + 0x0, 0xb, 0xa0, 0x0, 0x0, 0x0, 0xf, 0x10, + 0x3, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xf1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xf6, 0x0, 0x0, + 0x2, 0x20, 0x0, 0x0, 0x7, 0xfe, 0xde, 0xff, + 0xf6, 0x0, 0x0, 0x0, 0x0, 0x23, 0x32, 0x10, + 0x0, + + /* U+30BC "ゼ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, + 0x0, 0x0, 0x13, 0x0, 0x0, 0x5, 0x57, 0x80, + 0x0, 0x0, 0x4f, 0x0, 0x0, 0x1, 0xd1, 0xb1, + 0x0, 0x0, 0x4e, 0x0, 0x0, 0x0, 0x42, 0x0, + 0x0, 0x0, 0x3e, 0x0, 0x0, 0x25, 0x97, 0x0, + 0x0, 0x0, 0x4e, 0x59, 0xcf, 0xeb, 0xf7, 0x0, + 0x17, 0x9c, 0xff, 0xb8, 0x52, 0x6, 0xd0, 0x0, + 0xc, 0x85, 0x6e, 0x0, 0x0, 0x1e, 0x40, 0x0, + 0x0, 0x0, 0x3e, 0x0, 0x0, 0xd8, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x0, 0x6, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2f, 0x20, 0x0, 0x0, 0x21, 0x0, + 0x0, 0x0, 0xb, 0xfd, 0xdd, 0xef, 0xf3, 0x0, + 0x0, 0x0, 0x0, 0x23, 0x44, 0x32, 0x0, 0x0, + + /* U+30BD "ソ" */ + 0x11, 0x0, 0x0, 0x0, 0x0, 0x83, 0xac, 0x0, + 0x0, 0x0, 0x0, 0xf4, 0x1f, 0x50, 0x0, 0x0, + 0x4, 0xf0, 0x7, 0xe0, 0x0, 0x0, 0x8, 0xb0, + 0x0, 0xe8, 0x0, 0x0, 0xd, 0x70, 0x0, 0x54, + 0x0, 0x0, 0x5e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd8, 0x0, 0x0, 0x0, 0x0, 0x8, 0xe1, 0x0, + 0x0, 0x0, 0x0, 0x6f, 0x30, 0x0, 0x0, 0x0, + 0x7, 0xf4, 0x0, 0x0, 0x0, 0x2, 0xbf, 0x50, + 0x0, 0x0, 0x0, 0x5f, 0xc2, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + + /* U+30BF "タ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0x30, 0x0, 0x0, 0x0, 0x0, 0x9, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xff, 0xee, + 0xee, 0xf9, 0x0, 0x1, 0xe7, 0x11, 0x11, 0x2d, + 0x70, 0x0, 0xc9, 0x0, 0x0, 0x3, 0xf1, 0x2, + 0xca, 0x4, 0x0, 0x0, 0x9a, 0x2, 0xe8, 0x0, + 0xbe, 0x40, 0x3f, 0x20, 0x2, 0x0, 0x0, 0x6f, + 0xac, 0x80, 0x0, 0x0, 0x0, 0x0, 0x2e, 0xf4, + 0x0, 0x0, 0x0, 0x0, 0xa, 0xe9, 0xf6, 0x0, + 0x0, 0x0, 0x1c, 0xc1, 0x5, 0x40, 0x0, 0x2, + 0x9f, 0xa0, 0x0, 0x0, 0x0, 0x8, 0xfc, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+30C0 "ダ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x21, 0x0, 0x3, 0x38, 0x60, 0x0, + 0x0, 0xb, 0xb0, 0x0, 0x2d, 0x1d, 0x10, 0x0, + 0x3, 0xf3, 0x11, 0x11, 0xa4, 0x10, 0x0, 0x0, + 0xdf, 0xee, 0xee, 0xff, 0x20, 0x0, 0x0, 0xab, + 0x0, 0x0, 0x6, 0xd0, 0x0, 0x0, 0x9d, 0x10, + 0x0, 0x0, 0xc7, 0x0, 0x0, 0xad, 0x23, 0x60, + 0x0, 0x3f, 0x10, 0x0, 0xab, 0x0, 0x3d, 0xc2, + 0xd, 0x80, 0x0, 0x0, 0x0, 0x0, 0x9, 0xfb, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xfc, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x7, 0xf6, 0xce, + 0x10, 0x0, 0x0, 0x0, 0x1a, 0xe3, 0x0, 0x50, + 0x0, 0x0, 0x1, 0x9f, 0xc2, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xfd, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30C1 "チ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x12, 0x35, 0x8b, 0xfa, 0x0, 0x2, 0xff, + 0xed, 0xdf, 0x85, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x4d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4d, + 0x0, 0x0, 0x0, 0x12, 0x22, 0x22, 0x5e, 0x22, + 0x22, 0x21, 0x8f, 0xee, 0xee, 0xff, 0xee, 0xee, + 0xf9, 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x99, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xf5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6, 0x20, 0x0, 0x0, + 0x0, 0x0, + + /* U+30C3 "ッ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, + 0x3e, 0x0, 0x0, 0x82, 0xe, 0x50, 0xd, 0x40, + 0x1, 0xf3, 0x7, 0xb0, 0x7, 0xa0, 0x5, 0xd0, + 0x1, 0xf2, 0x2, 0x60, 0xb, 0x80, 0x0, 0x61, + 0x0, 0x0, 0x4f, 0x10, 0x0, 0x0, 0x0, 0x0, + 0xd7, 0x0, 0x0, 0x0, 0x0, 0x1c, 0xb0, 0x0, + 0x0, 0x0, 0x2, 0xdb, 0x0, 0x0, 0x0, 0x2, + 0x9f, 0x90, 0x0, 0x0, 0x0, 0xc, 0xb3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30C4 "ツ" */ + 0x0, 0x0, 0x8, 0x60, 0x0, 0x0, 0x30, 0x2d, + 0x0, 0x6, 0xd0, 0x0, 0x3, 0xf2, 0xd, 0x60, + 0x0, 0xf3, 0x0, 0x7, 0xd0, 0x6, 0xd0, 0x0, + 0xa9, 0x0, 0xb, 0x80, 0x1, 0xf3, 0x0, 0x34, + 0x0, 0x1f, 0x30, 0x0, 0x84, 0x0, 0x0, 0x0, + 0x8b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xdb, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0x18, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x7, 0xfd, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x1, 0x40, 0x0, + 0x0, 0x0, 0x0, + + /* U+30C6 "テ" */ + 0x0, 0x6e, 0xee, 0xee, 0xee, 0xee, 0x0, 0x0, + 0x12, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7e, 0xee, 0xee, 0xee, + 0xee, 0xee, 0xeb, 0x13, 0x22, 0x22, 0x4f, 0x32, + 0x22, 0x22, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4f, 0x60, 0x0, 0x0, 0x0, 0x0, 0x9, 0xf6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x20, 0x0, + 0x0, 0x0, 0x0, + + /* U+30C7 "デ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x65, 0x90, 0x0, + 0x55, 0x44, 0x44, 0x45, 0x3d, 0x2c, 0x20, 0xb, + 0xbb, 0xbb, 0xbb, 0xb6, 0x45, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0xc2, 0x4, 0x54, 0x44, 0x4b, + 0xa4, 0x44, 0x45, 0x10, 0x0, 0x0, 0x0, 0xb7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xf1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xab, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8e, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xcd, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+30C8 "ト" */ + 0x6e, 0x0, 0x0, 0x0, 0x5, 0xd0, 0x0, 0x0, + 0x0, 0x5d, 0x0, 0x0, 0x0, 0x5, 0xd0, 0x0, + 0x0, 0x0, 0x5f, 0x72, 0x0, 0x0, 0x5, 0xfc, + 0xfc, 0x61, 0x0, 0x5d, 0x1, 0x7e, 0xf9, 0x25, + 0xd0, 0x0, 0x5, 0xc7, 0x5d, 0x0, 0x0, 0x0, + 0x5, 0xd0, 0x0, 0x0, 0x0, 0x5d, 0x0, 0x0, + 0x0, 0x5, 0xe0, 0x0, 0x0, 0x0, 0x5b, 0x0, + 0x0, 0x0, 0x0, + + /* U+30C9 "ド" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2f, 0x30, 0x0, + 0x23, 0xc0, 0x1f, 0x20, 0x2, 0xd1, 0xa6, 0xf, + 0x10, 0x0, 0x79, 0x15, 0xf, 0x10, 0x0, 0x3, + 0x0, 0xf, 0xa4, 0x0, 0x0, 0x0, 0xf, 0xae, + 0xe9, 0x30, 0x0, 0xf, 0x20, 0x5b, 0xfc, 0x50, + 0xf, 0x20, 0x0, 0x29, 0xb0, 0xf, 0x20, 0x0, + 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, 0x0, 0x1f, + 0x20, 0x0, 0x0, 0x0, 0x1f, 0x20, 0x0, 0x0, + 0x0, 0x1b, 0x20, 0x0, 0x0, 0x0, + + /* U+30CA "ナ" */ + 0x0, 0x0, 0x0, 0x3f, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2f, 0x0, 0x0, 0x0, 0x5c, 0xcc, 0xcc, 0xdf, + 0xcc, 0xcc, 0xc9, 0x25, 0x55, 0x55, 0x7f, 0x55, + 0x55, 0x53, 0x0, 0x0, 0x0, 0x4e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xcd, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xa0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+30CB "ニ" */ + 0x1, 0x43, 0x33, 0x33, 0x33, 0x33, 0x0, 0x3, + 0xfe, 0xee, 0xee, 0xee, 0xeb, 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, + 0x35, 0x44, 0x44, 0x44, 0x44, 0x44, 0x50, 0x9f, + 0xee, 0xee, 0xee, 0xee, 0xee, 0xf1, + + /* U+30CD "ネ" */ + 0x0, 0x0, 0x0, 0x7d, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x1, 0x32, + 0x22, 0x7c, 0x22, 0x22, 0x0, 0x7, 0xee, 0xee, + 0xee, 0xee, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x8, 0xf4, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xce, 0x21, 0x10, 0x0, + 0x0, 0x5, 0xbe, 0xcb, 0x7, 0xf7, 0x0, 0x3a, + 0xed, 0x70, 0x6b, 0x0, 0x3d, 0xd3, 0x19, 0x30, + 0x0, 0x6b, 0x0, 0x0, 0x86, 0x0, 0x0, 0x0, + 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7b, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x69, 0x0, + 0x0, 0x0, + + /* U+30CE "ノ" */ + 0x0, 0x0, 0x0, 0x0, 0x9, 0x60, 0x0, 0x0, + 0x0, 0x0, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x5f, + 0x0, 0x0, 0x0, 0x0, 0xb, 0x90, 0x0, 0x0, + 0x0, 0x3, 0xf2, 0x0, 0x0, 0x0, 0x0, 0xca, + 0x0, 0x0, 0x0, 0x0, 0x6f, 0x10, 0x0, 0x0, + 0x0, 0x4f, 0x60, 0x0, 0x0, 0x0, 0x5f, 0x90, + 0x0, 0x0, 0x0, 0x7f, 0x80, 0x0, 0x0, 0x5, + 0xde, 0x50, 0x0, 0x0, 0x5, 0xf9, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30CF "ハ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa6, 0x0, 0x7c, 0x0, 0x0, 0x0, 0x0, + 0xf4, 0x0, 0x1f, 0x40, 0x0, 0x0, 0x2, 0xf0, + 0x0, 0x9, 0xb0, 0x0, 0x0, 0x6, 0xc0, 0x0, + 0x2, 0xf2, 0x0, 0x0, 0xc, 0x70, 0x0, 0x0, + 0xb9, 0x0, 0x0, 0x1f, 0x20, 0x0, 0x0, 0x5f, + 0x0, 0x0, 0x8c, 0x0, 0x0, 0x0, 0xe, 0x50, + 0x1, 0xf5, 0x0, 0x0, 0x0, 0x9, 0xb0, 0x9, + 0xd0, 0x0, 0x0, 0x0, 0x3, 0xf1, 0x3f, 0x40, + 0x0, 0x0, 0x0, 0x0, 0xe6, 0x48, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x75, + + /* U+30D0 "バ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x29, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3b, 0x2d, 0x0, 0x0, + 0x9, 0x20, 0x7, 0x60, 0xa4, 0x40, 0x0, 0x1, + 0xf2, 0x0, 0x5e, 0x0, 0x0, 0x0, 0x0, 0x4e, + 0x0, 0x0, 0xd6, 0x0, 0x0, 0x0, 0x8, 0xa0, + 0x0, 0x7, 0xd0, 0x0, 0x0, 0x0, 0xd6, 0x0, + 0x0, 0x1f, 0x40, 0x0, 0x0, 0x3f, 0x10, 0x0, + 0x0, 0x9b, 0x0, 0x0, 0x9, 0xb0, 0x0, 0x0, + 0x3, 0xf1, 0x0, 0x1, 0xf4, 0x0, 0x0, 0x0, + 0xd, 0x70, 0x0, 0x9c, 0x0, 0x0, 0x0, 0x0, + 0x7d, 0x0, 0x3f, 0x40, 0x0, 0x0, 0x0, 0x3, + 0xf2, 0x9, 0xa0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+30D1 "パ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xcb, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x29, 0x0, + 0x0, 0x74, 0x0, 0x59, 0xc, 0x26, 0x80, 0x0, + 0xe, 0x60, 0x2, 0xf3, 0x29, 0x80, 0x0, 0x1, + 0xf2, 0x0, 0xa, 0xa0, 0x0, 0x0, 0x0, 0x5e, + 0x0, 0x0, 0x3f, 0x20, 0x0, 0x0, 0xa, 0x90, + 0x0, 0x0, 0xc9, 0x0, 0x0, 0x0, 0xf4, 0x0, + 0x0, 0x5, 0xf0, 0x0, 0x0, 0x5e, 0x0, 0x0, + 0x0, 0xe, 0x60, 0x0, 0xd, 0x70, 0x0, 0x0, + 0x0, 0x9c, 0x0, 0x5, 0xf1, 0x0, 0x0, 0x0, + 0x3, 0xf2, 0x1, 0xe7, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x70, 0x6d, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x99, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+30D2 "ヒ" */ + 0x13, 0x0, 0x0, 0x0, 0x0, 0x3, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xe0, 0x0, 0x0, 0x17, 0xd0, 0x3e, 0x0, + 0x5, 0xaf, 0xc6, 0x3, 0xf7, 0xbf, 0xd8, 0x20, + 0x0, 0x3f, 0xb6, 0x20, 0x0, 0x0, 0x3, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x3f, + 0x0, 0x0, 0x0, 0x0, 0x1, 0xf9, 0x42, 0x23, + 0x35, 0x76, 0x4, 0xbe, 0xff, 0xee, 0xdc, 0x70, + + /* U+30D3 "ビ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x43, 0xa0, 0xe4, 0x0, 0x0, 0x0, + 0xc2, 0xb4, 0xe3, 0x0, 0x0, 0x0, 0x4a, 0x12, + 0xe3, 0x0, 0x0, 0x0, 0x70, 0x0, 0xe3, 0x0, + 0x4, 0x9f, 0xc1, 0x0, 0xe5, 0x59, 0xee, 0x93, + 0x0, 0x0, 0xef, 0xc8, 0x30, 0x0, 0x0, 0x0, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd8, 0x0, 0x0, 0x0, 0x14, 0x0, 0x5e, 0xfe, + 0xde, 0xff, 0xff, 0x0, 0x0, 0x23, 0x43, 0x32, + 0x10, 0x0, + + /* U+30D4 "ピ" */ + 0x0, 0x0, 0x0, 0x0, 0x2c, 0xc4, 0xf4, 0x0, + 0x0, 0x0, 0x92, 0xb, 0xe3, 0x0, 0x0, 0x0, + 0x85, 0x3b, 0xe3, 0x0, 0x0, 0x0, 0x78, 0x91, + 0xe3, 0x0, 0x3, 0x9e, 0xd1, 0x0, 0xe4, 0x49, + 0xee, 0x93, 0x0, 0x0, 0xef, 0xd8, 0x40, 0x0, + 0x0, 0x0, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd8, 0x0, 0x0, 0x0, 0x14, 0x0, + 0x5e, 0xfe, 0xde, 0xff, 0xff, 0x0, 0x0, 0x23, + 0x43, 0x32, 0x10, 0x0, + + /* U+30D5 "フ" */ + 0x12, 0x11, 0x11, 0x11, 0x11, 0x20, 0x9f, 0xff, + 0xff, 0xff, 0xff, 0xf8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe5, 0x0, 0x0, 0x0, 0x0, 0x3, 0xf1, + 0x0, 0x0, 0x0, 0x0, 0x7, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x7d, 0x0, 0x0, 0x0, 0x0, 0x2, 0xf5, 0x0, + 0x0, 0x0, 0x0, 0x2d, 0x90, 0x0, 0x0, 0x0, + 0x5, 0xe8, 0x0, 0x0, 0x0, 0x5, 0xcf, 0x70, + 0x0, 0x0, 0x0, 0xcf, 0x92, 0x0, 0x0, 0x0, + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + + /* U+30D6 "ブ" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x5, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x6, 0x92, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc2, 0x62, 0xdf, 0xff, 0xff, + 0xff, 0xff, 0xf4, 0x0, 0x22, 0x22, 0x22, 0x22, + 0x23, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x9d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xf4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0x80, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xe7, 0x0, 0x0, 0x0, 0x0, 0x4, 0xbf, 0x70, + 0x0, 0x0, 0x0, 0x1, 0xef, 0xa2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+30D7 "プ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4b, 0xa3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb0, 0x1a, 0xdf, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0xa4, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, + 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2f, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xf3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3f, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x16, 0xde, + 0x50, 0x0, 0x0, 0x0, 0x1, 0xee, 0x81, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+30D9 "ベ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7, 0x35, 0xc0, 0x0, + 0x0, 0x4, 0xb5, 0x0, 0x4c, 0xb, 0x50, 0x0, + 0x3, 0xfb, 0xf6, 0x0, 0xb4, 0x10, 0x0, 0x1, + 0xe7, 0x4, 0xf6, 0x0, 0x0, 0x0, 0x0, 0xca, + 0x0, 0x4, 0xf5, 0x0, 0x0, 0x0, 0xbd, 0x0, + 0x0, 0x5, 0xf5, 0x0, 0x0, 0xbe, 0x20, 0x0, + 0x0, 0x6, 0xf4, 0x0, 0x7, 0x40, 0x0, 0x0, + 0x0, 0x8, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x11, + + /* U+30DA "ペ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x92, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0x63, 0xc0, 0x0, + 0x0, 0xa, 0xe5, 0x0, 0xa2, 0xc, 0x0, 0x0, + 0x9, 0xd8, 0xf5, 0x3, 0xcb, 0x60, 0x0, 0x6, + 0xe1, 0x5, 0xf5, 0x0, 0x10, 0x0, 0x4, 0xf3, + 0x0, 0x5, 0xf4, 0x0, 0x0, 0x3, 0xf7, 0x0, + 0x0, 0x7, 0xf3, 0x0, 0x1, 0xfa, 0x0, 0x0, + 0x0, 0x8, 0xe2, 0x0, 0x6, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, + + /* U+30DB "ホ" */ + 0x0, 0x0, 0x0, 0x4f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0x0, 0xf, 0xee, 0xee, + 0xff, 0xee, 0xee, 0xf7, 0x3, 0x22, 0x22, 0x5e, + 0x22, 0x22, 0x21, 0x0, 0x0, 0x0, 0x3e, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x30, 0x3e, 0x0, 0x55, + 0x0, 0x0, 0x4e, 0x10, 0x3e, 0x0, 0x3f, 0x20, + 0x0, 0xd6, 0x0, 0x3e, 0x0, 0x8, 0xc0, 0xb, + 0xb0, 0x0, 0x3e, 0x0, 0x0, 0xe6, 0x3c, 0x10, + 0x0, 0x3e, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, + 0x4e, 0x0, 0x0, 0x0, 0x0, 0x0, 0xae, 0xfb, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x20, 0x0, + 0x0, 0x0, + + /* U+30DC "ボ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x9, 0x0, + 0x0, 0x0, 0x0, 0xe4, 0x0, 0xb4, 0x87, 0x0, + 0x0, 0x0, 0xe, 0x40, 0x2, 0xc0, 0x60, 0x34, + 0x33, 0x33, 0xe7, 0x33, 0x34, 0x40, 0xa, 0xdc, + 0xcc, 0xcf, 0xdc, 0xcc, 0xdb, 0x0, 0x0, 0x0, + 0x0, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x40, 0x0, 0x0, 0x0, 0x0, 0x8a, 0x0, + 0xe4, 0x2, 0xe1, 0x0, 0x0, 0x2f, 0x20, 0xe, + 0x40, 0x9, 0xb0, 0x0, 0xd, 0x80, 0x0, 0xe4, + 0x0, 0xe, 0x50, 0xb, 0xc0, 0x0, 0xe, 0x40, + 0x0, 0x6e, 0x10, 0x71, 0x0, 0x0, 0xe4, 0x0, + 0x0, 0x60, 0x0, 0x0, 0x24, 0x4f, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xcd, 0xa0, 0x0, 0x0, + 0x0, + + /* U+30DD "ポ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xaa, 0x30, + 0x0, 0x0, 0x0, 0xc3, 0x0, 0xb0, 0x2a, 0x0, + 0x0, 0x0, 0xe, 0x40, 0x8, 0x8a, 0x50, 0x34, + 0x33, 0x33, 0xe7, 0x33, 0x35, 0x50, 0xa, 0xdc, + 0xcc, 0xcf, 0xdc, 0xcc, 0xdc, 0x0, 0x0, 0x0, + 0x0, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x40, 0x0, 0x0, 0x0, 0x0, 0x8a, 0x0, + 0xe4, 0x2, 0xe1, 0x0, 0x0, 0x2f, 0x20, 0xe, + 0x40, 0x9, 0xc0, 0x0, 0xd, 0x80, 0x0, 0xe4, + 0x0, 0xe, 0x70, 0xb, 0xc0, 0x0, 0xe, 0x40, + 0x0, 0x5f, 0x20, 0x71, 0x0, 0x0, 0xe4, 0x0, + 0x0, 0x60, 0x0, 0x0, 0x24, 0x4f, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xcd, 0xa0, 0x0, 0x0, + 0x0, + + /* U+30DE "マ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x2, 0x21, + 0x11, 0x11, 0x11, 0x17, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1e, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcb, 0x0, 0x0, 0x7, 0x10, 0x0, 0xb, + 0xd0, 0x0, 0x0, 0xa, 0xe3, 0x0, 0xad, 0x10, + 0x0, 0x0, 0x0, 0x8f, 0x6c, 0xc1, 0x0, 0x0, + 0x0, 0x0, 0x6, 0xfd, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5f, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8f, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x0, 0x0, + + /* U+30DF "ミ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xeb, + 0x85, 0x10, 0x0, 0x0, 0x13, 0x69, 0xdf, 0xd9, + 0x40, 0x0, 0x0, 0x0, 0x14, 0x99, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3b, 0x85, 0x10, 0x0, + 0x0, 0x2, 0x69, 0xdf, 0xd9, 0x50, 0x0, 0x0, + 0x0, 0x4, 0x9e, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x4f, + 0xea, 0x73, 0x0, 0x0, 0x0, 0x14, 0x8b, 0xff, + 0xb6, 0x10, 0x0, 0x0, 0x0, 0x38, 0xdf, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x20, + + /* U+30E0 "ム" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2f, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc7, 0x0, 0x2, 0x30, + 0x0, 0x0, 0x2, 0xf1, 0x0, 0x6, 0xe1, 0x0, + 0x0, 0x7, 0xc0, 0x0, 0x0, 0xb9, 0x0, 0x0, + 0xd, 0x60, 0x0, 0x0, 0x3f, 0x20, 0x0, 0x3f, + 0x10, 0x23, 0x57, 0x9f, 0xa0, 0x7a, 0xdf, 0xef, + 0xfe, 0xca, 0x87, 0xf3, 0x68, 0x65, 0x31, 0x0, + 0x0, 0x0, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x32, + + /* U+30E1 "メ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe5, 0x0, 0x0, 0x71, 0x0, 0x0, + 0x5e, 0x0, 0x0, 0xb, 0xe5, 0x0, 0xd, 0x80, + 0x0, 0x0, 0x6, 0xf9, 0x6, 0xe0, 0x0, 0x0, + 0x0, 0x2, 0xdd, 0xe5, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, 0xbd, + 0x8f, 0x40, 0x0, 0x0, 0x0, 0xbd, 0x10, 0x8f, + 0x50, 0x0, 0x1, 0xbd, 0x10, 0x0, 0x7f, 0x60, + 0x5, 0xeb, 0x10, 0x0, 0x0, 0x76, 0xb, 0xf7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+30E2 "モ" */ + 0x0, 0x22, 0x11, 0x11, 0x11, 0x12, 0x0, 0x1, + 0xff, 0xef, 0xfe, 0xee, 0xff, 0x30, 0x0, 0x0, + 0x7, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xb0, + 0x0, 0x0, 0x0, 0x1f, 0xee, 0xef, 0xfe, 0xee, + 0xee, 0xe7, 0x3, 0x32, 0x29, 0xc2, 0x22, 0x22, + 0x31, 0x0, 0x0, 0x7, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xe2, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, + 0xbf, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0x22, 0x11, 0x0, + + /* U+30E3 "ャ" */ + 0x0, 0x9, 0x20, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x7, 0xa0, 0x14, + 0x7b, 0xe9, 0x2, 0x5a, 0xfe, 0xeb, 0x76, 0xf2, + 0x6e, 0xb7, 0xe4, 0x0, 0xc, 0x70, 0x0, 0x0, + 0xa8, 0x0, 0xab, 0x0, 0x0, 0x0, 0x5c, 0x4, + 0xc1, 0x0, 0x0, 0x0, 0x1f, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, + + /* U+30E4 "ヤ" */ + 0x0, 0x6, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xd0, 0x0, 0x0, 0x14, 0x82, 0x0, 0x1, 0xf4, + 0x58, 0xbe, 0xfd, 0xf4, 0x46, 0x9c, 0xff, 0xb8, + 0x52, 0xa, 0xa0, 0xab, 0x85, 0x9b, 0x0, 0x0, + 0x6e, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x5, 0xf3, + 0x0, 0x0, 0x0, 0xf, 0x40, 0x4f, 0x50, 0x0, + 0x0, 0x0, 0xb, 0x80, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaa, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46, 0x0, + 0x0, 0x0, + + /* U+30E5 "ュ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdf, + 0xff, 0xff, 0xfc, 0x0, 0x0, 0x22, 0x22, 0x22, + 0x8c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf3, 0x0, 0x12, 0x22, 0x22, 0x23, 0xf3, 0x22, + 0x5f, 0xee, 0xee, 0xee, 0xee, 0xfd, + + /* U+30E7 "ョ" */ + 0x7e, 0xee, 0xee, 0xee, 0xe2, 0x12, 0x21, 0x11, + 0x11, 0xe2, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x0, 0x0, 0xe2, 0x2f, 0xfe, 0xee, 0xee, + 0xf2, 0x1, 0x11, 0x11, 0x11, 0xe2, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x0, 0xe2, + 0xbf, 0xee, 0xee, 0xee, 0xf2, 0x11, 0x11, 0x11, + 0x11, 0xe3, + + /* U+30E8 "ヨ" */ + 0x1, 0x11, 0x11, 0x11, 0x11, 0x10, 0x4f, 0xff, + 0xff, 0xff, 0xff, 0xf3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xf3, 0x3, 0x33, + 0x33, 0x33, 0x33, 0xf3, 0xb, 0xed, 0xdd, 0xdd, + 0xdd, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xf3, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf3, 0x35, 0x55, 0x55, 0x55, + 0x55, 0xf3, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x51, + + /* U+30E9 "ラ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2f, + 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x22, 0x11, + 0x11, 0x12, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x12, 0x11, 0x11, 0x11, 0x11, 0x21, + 0x9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb9, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1f, 0x30, 0x0, 0x0, 0x0, 0x0, + 0xa, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xf1, + 0x0, 0x0, 0x0, 0x0, 0x8, 0xf5, 0x0, 0x0, + 0x0, 0x0, 0x4c, 0xe4, 0x0, 0x0, 0x0, 0x8, + 0xee, 0x81, 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, + 0x0, 0x0, 0x0, + + /* U+30EA "リ" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0x0, 0x0, + 0x0, 0xf5, 0x4e, 0x0, 0x0, 0x0, 0xe4, 0x3e, + 0x0, 0x0, 0x0, 0xe4, 0x3e, 0x0, 0x0, 0x0, + 0xe4, 0x3e, 0x0, 0x0, 0x0, 0xf4, 0x3e, 0x0, + 0x0, 0x0, 0xf3, 0x4e, 0x0, 0x0, 0x1, 0xf2, + 0x3b, 0x0, 0x0, 0x3, 0xf0, 0x0, 0x0, 0x0, + 0x9, 0xa0, 0x0, 0x0, 0x0, 0x5f, 0x30, 0x0, + 0x0, 0x7, 0xf6, 0x0, 0x0, 0x7, 0xee, 0x40, + 0x0, 0x0, 0x4, 0x50, 0x0, 0x0, + + /* U+30EB "ル" */ + 0x0, 0x0, 0xc5, 0x0, 0xd5, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x50, 0xd, 0x50, 0x0, 0x0, 0x0, + 0x0, 0xc5, 0x0, 0xd5, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x50, 0xd, 0x50, 0x0, 0x0, 0x0, 0x0, + 0xd4, 0x0, 0xd5, 0x0, 0x0, 0x0, 0x0, 0xe, + 0x30, 0xd, 0x50, 0x0, 0x0, 0x0, 0x0, 0xf1, + 0x0, 0xd5, 0x0, 0x0, 0x10, 0x0, 0x3f, 0x0, + 0xd, 0x50, 0x0, 0xb9, 0x0, 0xa, 0xa0, 0x0, + 0xd5, 0x0, 0xbc, 0x0, 0x2, 0xf2, 0x0, 0xd, + 0x51, 0xcc, 0x0, 0x1, 0xda, 0x0, 0x0, 0xdb, + 0xf9, 0x0, 0x0, 0xbc, 0x0, 0x0, 0xd, 0xd3, + 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, + + /* U+30EC "レ" */ + 0x4d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e, 0x0, + 0x0, 0x0, 0x0, 0x51, 0x3e, 0x0, 0x0, 0x0, + 0x6, 0xf3, 0x3e, 0x0, 0x0, 0x0, 0x8f, 0x40, + 0x3e, 0x0, 0x0, 0x2c, 0xd3, 0x0, 0x3e, 0x0, + 0x2a, 0xf9, 0x0, 0x0, 0x3f, 0x6c, 0xfa, 0x20, + 0x0, 0x0, 0x3f, 0xc7, 0x10, 0x0, 0x0, 0x0, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30ED "ロ" */ + 0xcf, 0xee, 0xee, 0xee, 0xee, 0xf4, 0xc7, 0x22, + 0x22, 0x22, 0x22, 0xe4, 0xc5, 0x0, 0x0, 0x0, + 0x0, 0xe3, 0xc5, 0x0, 0x0, 0x0, 0x0, 0xe3, + 0xc5, 0x0, 0x0, 0x0, 0x0, 0xe3, 0xc5, 0x0, + 0x0, 0x0, 0x0, 0xe3, 0xc5, 0x0, 0x0, 0x0, + 0x0, 0xe3, 0xc5, 0x0, 0x0, 0x0, 0x0, 0xe3, + 0xc5, 0x0, 0x0, 0x0, 0x0, 0xe3, 0xcf, 0xff, + 0xff, 0xff, 0xff, 0xf4, 0xd7, 0x22, 0x22, 0x22, + 0x22, 0xe4, + + /* U+30EF "ワ" */ + 0x22, 0x22, 0x22, 0x22, 0x22, 0x20, 0xef, 0xff, + 0xff, 0xff, 0xff, 0xfa, 0xe4, 0x0, 0x0, 0x0, + 0x0, 0xc8, 0xe4, 0x0, 0x0, 0x0, 0x0, 0xe5, + 0xe4, 0x0, 0x0, 0x0, 0x1, 0xf2, 0xe4, 0x0, + 0x0, 0x0, 0x6, 0xe0, 0x31, 0x0, 0x0, 0x0, + 0xd, 0x90, 0x0, 0x0, 0x0, 0x0, 0x5f, 0x10, + 0x0, 0x0, 0x0, 0x2, 0xf7, 0x0, 0x0, 0x0, + 0x0, 0x4e, 0xa0, 0x0, 0x0, 0x0, 0x19, 0xf8, + 0x0, 0x0, 0x0, 0xa, 0xfc, 0x30, 0x0, 0x0, + 0x0, 0x3, 0x30, 0x0, 0x0, 0x0, + + /* U+30F3 "ン" */ + 0x6, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xce, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0x60, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0x50, 0x0, + 0x0, 0x56, 0x0, 0x0, 0x40, 0x0, 0x0, 0xe, + 0x70, 0x0, 0x0, 0x0, 0x0, 0xa, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x2c, + 0xc1, 0x0, 0x0, 0x0, 0x2, 0xaf, 0xa0, 0x0, + 0x0, 0x2, 0x6b, 0xfc, 0x30, 0x0, 0x0, 0x6, + 0xfe, 0x93, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+30F6 "ヶ" */ + 0x0, 0x5, 0x50, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x70, 0x0, 0x0, 0x0, 0x0, 0x2f, 0x21, 0x11, + 0x11, 0x11, 0x0, 0xaf, 0xff, 0xff, 0xff, 0xf9, + 0x5, 0xe1, 0x0, 0x3e, 0x0, 0x0, 0x5f, 0x40, + 0x0, 0x5b, 0x0, 0x0, 0x55, 0x0, 0x0, 0x98, + 0x0, 0x0, 0x0, 0x0, 0x1, 0xf2, 0x0, 0x0, + 0x0, 0x0, 0xa, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0x8e, 0x10, 0x0, 0x0, 0x0, 0xb, 0xd2, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, + + /* U+30FC "ー" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, + 0xfe, 0xee, 0xee, 0xee, 0xef, 0xf1, 0x35, 0x54, + 0x44, 0x44, 0x44, 0x45, 0x50, + + /* U+4E00 "一" */ + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0x3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x31, + + /* U+4E03 "七" */ + 0x0, 0x0, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5c, 0x0, 0x35, 0x8b, 0xdf, 0x50, 0x3, 0x5a, + 0xfd, 0xfe, 0xc9, 0x64, 0x10, 0xcf, 0xeb, 0xbd, + 0x31, 0x0, 0x0, 0x0, 0x2, 0x0, 0x5, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5c, 0x0, 0x0, + 0x0, 0x3b, 0x0, 0x0, 0x5, 0xd0, 0x0, 0x0, + 0x5, 0xc0, 0x0, 0x0, 0x3f, 0x42, 0x22, 0x23, + 0xb9, 0x0, 0x0, 0x0, 0x8d, 0xee, 0xee, 0xdb, + 0x10, + + /* U+4E07 "万" */ + 0x1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0xff, 0xff, 0xff, 0xf7, 0x0, + 0x0, 0x0, 0xf, 0x31, 0x11, 0x11, 0xa7, 0x0, + 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, 0xb6, 0x0, + 0x0, 0x0, 0x6a, 0x0, 0x0, 0x0, 0xc5, 0x0, + 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, 0xd3, 0x0, + 0x0, 0x5, 0xd0, 0x0, 0x0, 0x0, 0xf1, 0x0, + 0x0, 0x2e, 0x30, 0x0, 0x0, 0x2, 0xf0, 0x0, + 0x4, 0xe6, 0x0, 0x0, 0x0, 0x7, 0xc0, 0x0, + 0x2e, 0x40, 0x0, 0x0, 0xef, 0xfe, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4E08 "丈" */ + 0x0, 0x0, 0x0, 0x0, 0xd5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x50, 0x0, 0x0, 0x11, + 0x11, 0x11, 0x11, 0xd5, 0x11, 0x11, 0xe, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, 0x1, + 0x0, 0x0, 0xf3, 0x0, 0x0, 0x0, 0x7, 0xa0, + 0x0, 0x1f, 0x10, 0x0, 0x0, 0x0, 0x1f, 0x0, + 0x2, 0xe0, 0x0, 0x0, 0x0, 0x0, 0xb6, 0x0, + 0x5c, 0x0, 0x0, 0x0, 0x0, 0x4, 0xe1, 0xa, + 0x80, 0x0, 0x0, 0x0, 0x0, 0x9, 0xb2, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xf9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4, 0xdf, 0xd5, 0x0, + 0x0, 0x0, 0x0, 0x4a, 0xe6, 0x6, 0xec, 0x51, + 0x0, 0x8, 0xed, 0x81, 0x0, 0x0, 0x6c, 0xfd, + 0xa0, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34, + 0x0, + + /* U+4E09 "三" */ + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x1, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xdd, 0xdd, 0xdd, 0xdd, + 0xda, 0x0, 0x0, 0x33, 0x33, 0x33, 0x33, 0x33, + 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, 0xef, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+4E0A "上" */ + 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0x11, 0x11, 0x11, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0xff, 0xff, 0xff, 0x10, + 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0xcc, 0xcc, 0xdf, 0xcc, 0xcc, 0xcc, 0xc2, + 0x4, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x40, + + /* U+4E0B "下" */ + 0x1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0xde, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x44, 0xdd, 0x40, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x30, 0x7, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x28, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, + + /* U+4E0D "不" */ + 0x2, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x10, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0x0, 0x0, 0x0, 0x1, 0xf5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9f, 0x82, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9, 0xdb, 0x8a, 0xd3, 0x0, 0x0, + 0x0, 0x0, 0xad, 0x1a, 0x80, 0x6e, 0x70, 0x0, + 0x0, 0x3d, 0xc1, 0xa, 0x80, 0x2, 0xdb, 0x10, + 0x9, 0xf7, 0x0, 0xa, 0x80, 0x0, 0xb, 0xd1, + 0x9, 0x20, 0x0, 0xa, 0x80, 0x0, 0x0, 0x40, + 0x0, 0x0, 0x0, 0xa, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x80, 0x0, 0x0, 0x0, + + /* U+4E13 "专" */ + 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x9c, 0xcc, 0xee, 0xcc, 0xcc, 0xc8, 0x0, 0x2, + 0x33, 0x4f, 0x43, 0x33, 0x33, 0x20, 0x0, 0x0, + 0x5, 0xb0, 0x0, 0x0, 0x0, 0x0, 0xcc, 0xcc, + 0xee, 0xcc, 0xcc, 0xcc, 0xca, 0x4, 0x44, 0x5f, + 0x44, 0x44, 0x44, 0x44, 0x30, 0x0, 0x6, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xce, 0xdd, + 0xdd, 0xdd, 0xd4, 0x0, 0x0, 0x2, 0x22, 0x22, + 0x23, 0xda, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xca, 0x0, 0x0, 0x0, 0x6, 0x72, 0x1, 0xc9, + 0x0, 0x0, 0x0, 0x0, 0x28, 0xed, 0xda, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4a, 0xf9, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xa9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4E14 "且" */ + 0x0, 0x9, 0xff, 0xff, 0xff, 0xff, 0xb0, 0x0, + 0x0, 0x9, 0x80, 0x0, 0x0, 0x6, 0xb0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x5, 0xb0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x5, 0xb0, 0x0, + 0x0, 0x9, 0xdb, 0xbb, 0xbb, 0xbd, 0xb0, 0x0, + 0x0, 0x9, 0xa4, 0x44, 0x44, 0x48, 0xb0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x5, 0xb0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x5, 0xb0, 0x0, + 0x0, 0x9, 0xa4, 0x44, 0x44, 0x48, 0xb0, 0x0, + 0x0, 0x9, 0xdb, 0xbb, 0xbb, 0xbd, 0xb0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x5, 0xb0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x5, 0xb0, 0x0, + 0x4, 0x4b, 0xa4, 0x44, 0x44, 0x48, 0xd4, 0x40, + 0x1b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb1, + + /* U+4E16 "世" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, + 0x0, 0xc, 0x40, 0x9, 0x60, 0x5, 0xb0, 0x0, + 0x0, 0xc, 0x40, 0x9, 0x60, 0x5, 0xb0, 0x0, + 0x0, 0xc, 0x40, 0x9, 0x60, 0x5, 0xb0, 0x0, + 0x2, 0x2d, 0x62, 0x2a, 0x82, 0x27, 0xc2, 0x20, + 0x2d, 0xdf, 0xed, 0xdf, 0xed, 0xde, 0xfd, 0xd2, + 0x0, 0xc, 0x40, 0x9, 0x60, 0x5, 0xb0, 0x0, + 0x0, 0xc, 0x40, 0x9, 0x60, 0x5, 0xb0, 0x0, + 0x0, 0xc, 0x40, 0x9, 0x60, 0x5, 0xb0, 0x0, + 0x0, 0xc, 0x40, 0x9, 0x70, 0x6, 0xb0, 0x0, + 0x0, 0xc, 0x40, 0x9, 0xee, 0xee, 0xb0, 0x0, + 0x0, 0xc, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, + 0x0, 0x0, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0, + + /* U+4E21 "両" */ + 0x1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x0, 0x0, 0xa, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x60, 0x0, 0x0, 0x0, + 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, + 0x3, 0xc0, 0x0, 0xa, 0x70, 0x0, 0xc, 0x40, + 0x3, 0xc0, 0x73, 0xa, 0x60, 0x44, 0xb, 0x40, + 0x3, 0xc0, 0x95, 0xa, 0x60, 0x77, 0xb, 0x40, + 0x3, 0xc0, 0x95, 0xa, 0x60, 0x77, 0xb, 0x40, + 0x3, 0xc0, 0x95, 0xa, 0x60, 0x77, 0xb, 0x40, + 0x3, 0xc0, 0x9d, 0xce, 0xec, 0xe7, 0xb, 0x40, + 0x3, 0xc0, 0x12, 0x22, 0x22, 0x21, 0xb, 0x40, + 0x3, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x40, + 0x3, 0xc0, 0x0, 0x0, 0x0, 0x2f, 0xfd, 0x10, + + /* U+4E26 "並" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x2, 0x10, 0x0, + 0x0, 0x4, 0xe1, 0x0, 0x0, 0xd, 0x60, 0x0, + 0x0, 0x0, 0xa9, 0x0, 0x0, 0x6c, 0x0, 0x0, + 0x1, 0x11, 0x3b, 0x11, 0x11, 0xd4, 0x11, 0x10, + 0xa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, + 0x0, 0x0, 0x4, 0xc0, 0xd, 0x20, 0x0, 0x0, + 0x0, 0x51, 0x4, 0xc0, 0xd, 0x20, 0x27, 0x0, + 0x0, 0x97, 0x4, 0xc0, 0xd, 0x20, 0x7a, 0x0, + 0x0, 0x3d, 0x4, 0xc0, 0xd, 0x20, 0xc5, 0x0, + 0x0, 0xd, 0x34, 0xc0, 0xd, 0x22, 0xe0, 0x0, + 0x0, 0x9, 0x74, 0xc0, 0xd, 0x29, 0x80, 0x0, + 0x0, 0x4, 0x54, 0xc0, 0xd, 0x28, 0x10, 0x0, + 0x0, 0x0, 0x4, 0xc0, 0xd, 0x20, 0x0, 0x0, + 0x1c, 0xcc, 0xcd, 0xfc, 0xcf, 0xdc, 0xcc, 0xc1, + 0x4, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x40, + + /* U+4E2D "中" */ + 0x0, 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, 0x2c, 0xcc, + 0xcc, 0xdf, 0xcc, 0xcc, 0xcb, 0x3e, 0x44, 0x44, + 0x7f, 0x44, 0x44, 0x6e, 0x3d, 0x0, 0x0, 0x3e, + 0x0, 0x0, 0x2e, 0x3d, 0x0, 0x0, 0x3e, 0x0, + 0x0, 0x2e, 0x3d, 0x0, 0x0, 0x3e, 0x0, 0x0, + 0x2e, 0x3d, 0x11, 0x11, 0x4e, 0x11, 0x11, 0x4e, + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x2a, + 0x0, 0x0, 0x3e, 0x0, 0x0, 0x29, 0x0, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e, 0x0, + 0x0, 0x0, + + /* U+4E3B "主" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9c, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xd2, 0x0, 0x0, 0x0, + 0x0, 0x11, 0x11, 0x11, 0xa9, 0x11, 0x11, 0x0, + 0x5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x24, 0x44, 0x4b, 0xa4, 0x44, 0x42, 0x0, + 0x0, 0x7c, 0xcc, 0xce, 0xec, 0xcc, 0xc8, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x2, 0x22, 0x22, 0x2a, 0x92, 0x22, 0x22, 0x20, + 0x1e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe2, + + /* U+4E45 "久" */ + 0x0, 0x0, 0x5, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5d, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xdf, 0xff, 0xff, 0xa0, 0x0, 0x0, + 0x0, 0x6, 0xd1, 0x11, 0x1c, 0x60, 0x0, 0x0, + 0x0, 0x2e, 0x40, 0x0, 0x1f, 0x10, 0x0, 0x0, + 0x0, 0xca, 0x0, 0x0, 0x8b, 0x0, 0x0, 0x0, + 0xb, 0xc0, 0x0, 0x0, 0xe8, 0x0, 0x0, 0x0, + 0x2a, 0x10, 0x0, 0x9, 0xee, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4f, 0x2c, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xe6, 0x3, 0xf2, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x80, 0x0, 0x8d, 0x10, 0x0, + 0x0, 0x5, 0xf8, 0x0, 0x0, 0xb, 0xd1, 0x0, + 0x3, 0xcf, 0x50, 0x0, 0x0, 0x0, 0xae, 0x60, + 0xd, 0x91, 0x0, 0x0, 0x0, 0x0, 0x5, 0xd2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4E4B "之" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1e, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x11, 0x11, 0x11, 0xa3, 0x11, 0x10, 0x0, + 0x5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4, 0xf4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4f, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xe4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9d, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3d, 0xa1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6d, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xe4, 0xad, 0x73, 0x21, 0x12, 0x23, 0x41, + 0xc, 0x20, 0x3, 0x9d, 0xef, 0xff, 0xed, 0xd1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4E4E "乎" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x12, 0x35, 0x68, 0xad, 0xf6, 0x0, + 0x0, 0xef, 0xed, 0xcd, 0xe8, 0x63, 0x0, 0x0, + 0x0, 0x4, 0x0, 0x6, 0xb0, 0x0, 0x64, 0x0, + 0x0, 0xe, 0x20, 0x6, 0xb0, 0x0, 0xe4, 0x0, + 0x0, 0x7, 0xa0, 0x6, 0xb0, 0x6, 0xc0, 0x0, + 0x0, 0x1, 0xf0, 0x6, 0xb0, 0xe, 0x30, 0x0, + 0x0, 0x0, 0x30, 0x6, 0xb0, 0x3, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x2, 0x22, 0x22, 0x28, 0xb2, 0x22, 0x22, 0x20, + 0x0, 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x11, 0x18, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xaf, 0xfd, 0x40, 0x0, 0x0, 0x0, + + /* U+4E4F "乏" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0x23, 0x57, 0x9b, 0xed, 0x0, + 0x0, 0xef, 0xfe, 0xdc, 0xa9, 0x75, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1e, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0x50, 0x0, 0x0, 0x0, + 0x1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x0, + 0x0, 0x11, 0x11, 0x11, 0x11, 0x19, 0xe1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9d, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1c, 0xb1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5, 0xe7, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x4, 0xcc, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x9f, 0xdd, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xc0, 0x8e, 0x71, 0x0, 0x0, 0x1, 0x31, + 0xd, 0x20, 0x3, 0xae, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+4E57 "乗" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x12, 0x34, 0x56, 0x89, 0xbe, 0xe5, 0x0, + 0x0, 0xcc, 0xba, 0x9d, 0xb5, 0x31, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x3, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0x50, + 0x0, 0x1, 0xf0, 0x9, 0x80, 0xf, 0x10, 0x0, + 0x0, 0x0, 0xf0, 0x9, 0x70, 0xf, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x0, 0xf0, 0x9, 0x70, 0xf, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x9, 0x70, 0xf, 0x0, 0x0, + 0x6, 0xee, 0xee, 0xff, 0xff, 0xee, 0xee, 0x80, + 0x0, 0x0, 0x5, 0xdc, 0xcd, 0x40, 0x0, 0x0, + 0x0, 0x4, 0xba, 0x19, 0x71, 0xba, 0x30, 0x0, + 0x18, 0xeb, 0x40, 0x9, 0x70, 0x6, 0xcd, 0x71, + 0x6, 0x20, 0x0, 0x9, 0x70, 0x0, 0x3, 0x80, + + /* U+4E5D "九" */ + 0x0, 0x0, 0x2, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x11, 0x15, 0xe1, 0x11, 0x11, 0x0, 0x0, + 0x6, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, + 0x0, 0x0, 0x6, 0xb0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0x8, 0x90, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x70, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0xf, 0x20, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0x5d, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0xd6, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0xa, 0xb0, 0x0, 0x0, 0x2e, 0x0, 0x3b, + 0x1, 0xbd, 0x10, 0x0, 0x0, 0x2f, 0x10, 0x6a, + 0xd, 0x90, 0x0, 0x0, 0x0, 0xc, 0xff, 0xf4, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4E5F "也" */ + 0x0, 0x2, 0x10, 0x1, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x40, 0x1, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x40, 0x1, 0xe0, 0x2, 0x78, 0x0, + 0x0, 0xb, 0x40, 0x2, 0xf8, 0xdd, 0xbc, 0x0, + 0x0, 0xb, 0x55, 0xae, 0xf7, 0x20, 0x5b, 0x0, + 0x2, 0x7e, 0xfb, 0x63, 0xe0, 0x0, 0x5b, 0x0, + 0x8e, 0x9d, 0x50, 0x1, 0xe0, 0x0, 0x6a, 0x0, + 0x0, 0xb, 0x40, 0x1, 0xe0, 0x0, 0x88, 0x0, + 0x0, 0xb, 0x40, 0x1, 0xe0, 0x12, 0xd3, 0x0, + 0x0, 0xb, 0x40, 0x1, 0xe0, 0xcc, 0x80, 0x0, + 0x0, 0xb, 0x40, 0x1, 0xe0, 0x0, 0x0, 0x90, + 0x0, 0xb, 0x50, 0x0, 0x30, 0x0, 0x2, 0xe0, + 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, 0x9, 0xb0, + 0x0, 0x2, 0xcf, 0xff, 0xff, 0xff, 0xfc, 0x20, + + /* U+4E86 "了" */ + 0x1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x3f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6e, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xe9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4d, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4d, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6c, + 0x0, 0x0, 0x0, 0x0, 0x7, 0xff, 0xe6, 0x0, + 0x0, 0x0, + + /* U+4E88 "予" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6f, 0xff, 0xff, 0xff, 0xff, 0xf5, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xda, 0x0, 0x0, 0x0, + 0x9, 0x30, 0x3, 0xe9, 0x0, 0x0, 0x0, 0x0, + 0x8f, 0xb7, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x19, 0xfc, 0x10, 0x0, 0x0, 0x33, 0x33, 0x33, + 0x36, 0xef, 0x43, 0x33, 0xb, 0xcc, 0xcc, 0xcd, + 0xfc, 0xcc, 0xcd, 0xf2, 0x0, 0x0, 0x0, 0x3d, + 0x0, 0x0, 0xd6, 0x0, 0x0, 0x0, 0x3, 0xd0, + 0x0, 0xa9, 0x0, 0x0, 0x0, 0x0, 0x3d, 0x0, + 0x18, 0x0, 0x0, 0x0, 0x0, 0x3, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3d, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x5, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xef, 0xe8, 0x0, 0x0, 0x0, + 0x0, + + /* U+4E89 "争" */ + 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8f, 0xee, 0xee, 0xf8, 0x0, 0x0, + 0x0, 0x8, 0xc1, 0x0, 0x5, 0xe1, 0x0, 0x0, + 0x0, 0xad, 0x20, 0x0, 0x3f, 0x40, 0x0, 0x0, + 0x4, 0xce, 0xee, 0xef, 0xfe, 0xee, 0xf5, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0xb5, 0x0, + 0x2, 0x22, 0x22, 0x2a, 0xa2, 0x22, 0xc7, 0x21, + 0x1c, 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xfe, 0xc7, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0xb5, 0x0, + 0x0, 0x22, 0x22, 0x2a, 0xa2, 0x22, 0xc5, 0x0, + 0x0, 0x9c, 0xcc, 0xce, 0xec, 0xcc, 0xc4, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5f, 0xfd, 0x40, 0x0, 0x0, 0x0, + + /* U+4E8B "事" */ + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0xc, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xd0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0xcc, 0xce, 0xec, 0xcc, 0xf5, 0x0, + 0x0, 0x3c, 0x0, 0x9, 0x70, 0x0, 0xb5, 0x0, + 0x0, 0x2c, 0xcc, 0xce, 0xec, 0xcc, 0xc4, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x9c, 0xcc, 0xce, 0xec, 0xcc, 0xe9, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x79, 0x0, + 0x2d, 0xdd, 0xdd, 0xdf, 0xed, 0xdd, 0xef, 0xd3, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x79, 0x0, + 0x0, 0xbd, 0xdd, 0xdf, 0xed, 0xdd, 0xe9, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x56, 0x0, + 0x0, 0x0, 0x1d, 0xee, 0x40, 0x0, 0x0, 0x0, + + /* U+4E8C "二" */ + 0x0, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0, + 0x0, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xfb, 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, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, + 0x1c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc1, + + /* U+4E94 "五" */ + 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0x11, 0x11, 0x8b, 0x11, 0x11, 0x11, 0x0, + 0x0, 0x0, 0x0, 0x98, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x11, 0xe4, 0x11, 0x11, 0x0, 0x0, + 0x0, 0x2f, 0xff, 0xff, 0xff, 0xff, 0x60, 0x0, + 0x0, 0x0, 0x3, 0xe0, 0x0, 0xd, 0x40, 0x0, + 0x0, 0x0, 0x6, 0xb0, 0x0, 0xe, 0x30, 0x0, + 0x0, 0x0, 0x9, 0x80, 0x0, 0xf, 0x10, 0x0, + 0x0, 0x0, 0xc, 0x50, 0x0, 0x1f, 0x0, 0x0, + 0x0, 0x0, 0xf, 0x20, 0x0, 0x3e, 0x0, 0x0, + 0x1e, 0xee, 0xef, 0xee, 0xee, 0xff, 0xee, 0xe2, + 0x2, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x20, + + /* U+4E9B "些" */ + 0x0, 0x0, 0xb5, 0x0, 0x2e, 0x0, 0x0, 0x0, + 0x2, 0xa0, 0xb5, 0x0, 0x2e, 0x0, 0x7d, 0x20, + 0x3, 0xc0, 0xbe, 0xdc, 0x2e, 0x9f, 0xa3, 0x0, + 0x3, 0xc0, 0xb7, 0x22, 0x2f, 0x61, 0x0, 0x0, + 0x3, 0xc0, 0xb5, 0x0, 0x2e, 0x0, 0x0, 0x40, + 0x3, 0xc0, 0xb5, 0x0, 0x2e, 0x0, 0x0, 0xc3, + 0x3, 0xc1, 0xb9, 0x79, 0x2f, 0x32, 0x23, 0xe0, + 0x2d, 0xfe, 0xca, 0x87, 0x9, 0xdd, 0xdd, 0x70, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x0, + 0x0, 0x1, 0x11, 0x11, 0x11, 0x11, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + + /* U+4EA1 "亡" */ + 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xd2, 0x0, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0xb, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, + 0x0, 0x1, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, + + /* U+4EA4 "交" */ + 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x50, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x17, 0xb1, 0x11, 0x11, 0x10, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, + 0x0, 0x0, 0x5, 0x0, 0x0, 0x40, 0x0, 0x0, + 0x0, 0x0, 0xc9, 0x0, 0x0, 0x8d, 0x30, 0x0, + 0x0, 0x2c, 0x90, 0x0, 0x0, 0x5, 0xe6, 0x0, + 0x6, 0xf7, 0x27, 0x0, 0x0, 0x83, 0x3e, 0x70, + 0x3, 0x40, 0xe, 0x30, 0x2, 0xf1, 0x3, 0x50, + 0x0, 0x0, 0x6, 0xc0, 0xb, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xaa, 0x9c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5, 0xea, 0xae, 0x60, 0x0, 0x0, + 0x0, 0x27, 0xcd, 0x40, 0x3, 0xdd, 0x84, 0x0, + 0xd, 0xfa, 0x50, 0x0, 0x0, 0x4, 0x9e, 0xe1, + 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+4EA6 "亦" */ + 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0, + 0xc, 0xcc, 0xcc, 0xcc, 0xdc, 0xcc, 0xcc, 0xc0, + 0x3, 0x33, 0x36, 0xe3, 0x37, 0xd3, 0x33, 0x30, + 0x0, 0x0, 0x3, 0xd0, 0x4, 0xc0, 0x0, 0x0, + 0x0, 0xe, 0x13, 0xd0, 0x4, 0xc2, 0xc0, 0x0, + 0x0, 0x6b, 0x4, 0xc0, 0x4, 0xc0, 0xc6, 0x0, + 0x0, 0xc6, 0x6, 0xb0, 0x4, 0xc0, 0x3e, 0x0, + 0x5, 0xe0, 0xa, 0x70, 0x4, 0xc0, 0xb, 0x60, + 0xc, 0x50, 0xe, 0x30, 0x4, 0xc0, 0x5, 0xc0, + 0x0, 0x0, 0x7c, 0x0, 0x4, 0xc0, 0x0, 0x60, + 0x0, 0x2, 0xf3, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0x0, 0x2d, 0x80, 0x1, 0x16, 0xb0, 0x0, 0x0, + 0x0, 0xb8, 0x0, 0xd, 0xfe, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4EAC "京" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xf2, 0x0, 0x0, 0x0, 0x2, + 0x22, 0x22, 0x29, 0xb2, 0x22, 0x22, 0x20, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xee, + 0xee, 0xee, 0xee, 0xee, 0x10, 0x0, 0xe, 0x10, + 0x0, 0x0, 0x0, 0xf1, 0x0, 0x0, 0xe1, 0x0, + 0x0, 0x0, 0xf, 0x10, 0x0, 0xe, 0x20, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0xde, 0xee, 0xff, + 0xee, 0xee, 0x10, 0x0, 0x0, 0x0, 0x8, 0x90, + 0x0, 0x0, 0x0, 0x0, 0xb8, 0x0, 0x89, 0x0, + 0xa9, 0x0, 0x0, 0x9b, 0x0, 0x8, 0x90, 0x0, + 0xc9, 0x0, 0xbb, 0x0, 0x0, 0x89, 0x0, 0x0, + 0xd8, 0x3, 0x0, 0x2f, 0xfe, 0x50, 0x0, 0x1, + 0x20, + + /* U+4EBA "人" */ + 0x0, 0x0, 0x0, 0xb, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5e, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x98, 0xc5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf3, 0x7a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0xd0, 0x1e, 0x20, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x50, 0x8, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x9c, 0x0, 0x1, 0xe6, 0x0, 0x0, + 0x0, 0x8, 0xe1, 0x0, 0x0, 0x3f, 0x50, 0x0, + 0x0, 0x8f, 0x30, 0x0, 0x0, 0x5, 0xf7, 0x0, + 0x2d, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x2d, 0xd0, + 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, + + /* U+4EC0 "什" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa6, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x2, 0xe0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xb, 0x80, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x3f, 0x20, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x1, 0xef, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0xc, 0x8e, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x2b, 0xe, 0x11, 0x11, 0x17, 0xb1, 0x11, 0x10, + 0x0, 0xe, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4ECA "今" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8d, 0xc8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9, 0xd1, 0xb, 0x90, 0x0, 0x0, + 0x0, 0x1, 0xbc, 0x10, 0x0, 0xbc, 0x20, 0x0, + 0x0, 0x5e, 0xa0, 0x6a, 0x0, 0x9, 0xf6, 0x0, + 0x2c, 0xe4, 0x0, 0x9, 0xd1, 0x0, 0x4e, 0xd2, + 0x6, 0x0, 0x0, 0x0, 0x8d, 0x0, 0x0, 0x50, + 0x0, 0x14, 0x44, 0x44, 0x46, 0x44, 0x41, 0x0, + 0x0, 0x4c, 0xcc, 0xcc, 0xcc, 0xcd, 0xf4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xab, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7, 0xe1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4f, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xf5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x50, 0x0, 0x0, 0x0, + + /* U+4ECB "介" */ + 0x0, 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xf3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8c, 0x5e, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x9, 0xd1, 0x6, 0xe4, 0x0, 0x0, + 0x0, 0x2, 0xcb, 0x10, 0x0, 0x4e, 0x91, 0x0, + 0x2, 0x9f, 0x80, 0x0, 0x0, 0x2, 0xbe, 0x81, + 0x1e, 0xa2, 0x15, 0x0, 0x0, 0x16, 0x4, 0xb8, + 0x1, 0x0, 0x4d, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0x4d, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0x5c, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0x8a, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0xd6, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x8, 0xd0, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x9e, 0x30, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x4, 0xc2, 0x0, 0x0, 0x0, 0x2e, 0x0, 0x0, + + /* U+4ECD "仍" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0x1e, 0xff, 0xee, 0xef, 0x60, 0x0, 0x9, + 0x80, 0x1, 0xf0, 0x0, 0xd2, 0x0, 0x2, 0xf3, + 0x0, 0x2e, 0x0, 0xe, 0x0, 0x0, 0xcf, 0x30, + 0x3, 0xd0, 0x4, 0xb0, 0x0, 0x8c, 0xc3, 0x0, + 0x4c, 0x0, 0x8e, 0xdd, 0x56, 0x2c, 0x30, 0x6, + 0xa0, 0x1, 0x22, 0xb5, 0x0, 0xc3, 0x0, 0x88, + 0x0, 0x0, 0xb, 0x50, 0xc, 0x30, 0xb, 0x50, + 0x0, 0x0, 0xc4, 0x0, 0xc3, 0x1, 0xf1, 0x0, + 0x0, 0xd, 0x20, 0xc, 0x30, 0x6b, 0x0, 0x0, + 0x0, 0xf1, 0x0, 0xc3, 0xd, 0x60, 0x0, 0x0, + 0x2f, 0x0, 0xc, 0x39, 0xb0, 0x0, 0x0, 0x7, + 0xb0, 0x0, 0xc5, 0xd1, 0x0, 0x5, 0xff, 0xe4, + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4ED5 "仕" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x98, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0x2, 0xf1, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0xa, 0x90, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0x3f, 0x20, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0xdf, 0x11, 0x11, 0x17, 0xa1, 0x11, 0x10, + 0xb, 0xbf, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xf5, + 0x6d, 0x1f, 0x10, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x1, 0xf, 0x10, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0xf, 0x12, 0x44, 0x49, 0xb4, 0x44, 0x40, + 0x0, 0xf, 0x18, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, + + /* U+4ED6 "他" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa6, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0x2, 0xe0, 0x2c, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x2d, 0x0, 0xe1, 0x4, 0x70, + 0x0, 0x4e, 0x0, 0x2d, 0x0, 0xe9, 0xee, 0xd0, + 0x1, 0xed, 0x0, 0x2e, 0x4b, 0xf9, 0x32, 0xd0, + 0x1d, 0x9d, 0x1, 0x8f, 0xd6, 0xe1, 0x2, 0xd0, + 0x39, 0x2d, 0x3f, 0xbe, 0x0, 0xe1, 0x3, 0xd0, + 0x0, 0x2d, 0x0, 0x2d, 0x0, 0xe1, 0x3, 0xc0, + 0x0, 0x2d, 0x0, 0x2d, 0x0, 0xe1, 0x5, 0xb0, + 0x0, 0x2d, 0x0, 0x2d, 0x0, 0xe3, 0xfe, 0x40, + 0x0, 0x2d, 0x0, 0x2d, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0x2e, 0x0, 0x10, 0x0, 0x65, + 0x0, 0x2d, 0x0, 0x1f, 0x10, 0x0, 0x1, 0xb6, + 0x0, 0x2d, 0x0, 0x9, 0xff, 0xff, 0xff, 0xc1, + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4ED8 "付" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa7, 0x0, 0x0, 0x1, 0xf0, 0x0, + 0x0, 0x2, 0xf1, 0x0, 0x0, 0x1, 0xf0, 0x0, + 0x0, 0xa, 0x90, 0x0, 0x0, 0x1, 0xf0, 0x0, + 0x0, 0x3f, 0x2a, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0xdf, 0x11, 0x22, 0x22, 0x23, 0xf2, 0x20, + 0xb, 0xbf, 0x10, 0x0, 0x0, 0x1, 0xf0, 0x0, + 0x2c, 0xf, 0x10, 0x5b, 0x0, 0x1, 0xf0, 0x0, + 0x0, 0xf, 0x10, 0xd, 0x60, 0x1, 0xf0, 0x0, + 0x0, 0xf, 0x10, 0x3, 0xf1, 0x1, 0xf0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0xa8, 0x1, 0xf0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x10, 0x1, 0xf0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x0, 0x1, 0xf0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x1, 0x13, 0xf0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x6f, 0xfe, 0x80, 0x0, + + /* U+4EE3 "代" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6a, 0x0, 0x4c, 0x5, 0x70, 0x0, + 0x0, 0x0, 0xe4, 0x0, 0x3d, 0x0, 0xb9, 0x0, + 0x0, 0x8, 0xb0, 0x0, 0x2e, 0x0, 0xb, 0x70, + 0x0, 0x2f, 0x30, 0x0, 0x1f, 0x0, 0x0, 0x0, + 0x1, 0xef, 0x20, 0x2, 0x4f, 0x8a, 0xce, 0xf0, + 0x1c, 0x9e, 0x2e, 0xfd, 0xbf, 0x95, 0x31, 0x0, + 0x9a, 0xe, 0x20, 0x0, 0xb, 0x50, 0x0, 0x0, + 0x10, 0xe, 0x20, 0x0, 0x8, 0x80, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x1, 0xf1, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0xc6, 0x0, 0x63, + 0x0, 0xe, 0x20, 0x0, 0x0, 0x6e, 0x10, 0xa4, + 0x0, 0xe, 0x20, 0x0, 0x0, 0xb, 0xc5, 0xe1, + 0x0, 0xe, 0x20, 0x0, 0x0, 0x1, 0xbf, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4EE4 "令" */ + 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9c, 0xba, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1b, 0xa0, 0x9, 0xc2, 0x0, 0x0, + 0x0, 0x5, 0xe8, 0x25, 0x0, 0x6e, 0x70, 0x0, + 0x3, 0xbd, 0x40, 0x2d, 0x70, 0x3, 0xdd, 0x50, + 0x2e, 0x70, 0x0, 0x1, 0xd6, 0x0, 0x7, 0xe3, + 0x0, 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, + 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x80, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x1, 0xd9, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xb2, 0x1d, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9f, 0xd9, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xea, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1c, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + + /* U+4EE5 "以" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x15, 0x0, 0x0, 0x0, 0x0, 0xa8, 0x0, 0x3, + 0xe0, 0x8, 0x90, 0x0, 0xb, 0x60, 0x0, 0x3e, + 0x0, 0xe, 0x50, 0x0, 0xc5, 0x0, 0x3, 0xe0, + 0x0, 0x4e, 0x0, 0xe, 0x30, 0x0, 0x3e, 0x0, + 0x0, 0xb5, 0x0, 0xf1, 0x0, 0x3, 0xe0, 0x0, + 0x0, 0x0, 0x3e, 0x0, 0x0, 0x3e, 0x0, 0x0, + 0x0, 0x7, 0xa0, 0x0, 0x3, 0xe0, 0x0, 0x0, + 0x0, 0xc6, 0x0, 0x0, 0x3e, 0x0, 0x4, 0x0, + 0x2f, 0x0, 0x0, 0x3, 0xe0, 0x7e, 0xb0, 0xb, + 0xf3, 0x0, 0x0, 0x6f, 0xeb, 0x30, 0x6, 0xd5, + 0xe3, 0x0, 0xe, 0xb3, 0x0, 0x6, 0xe2, 0x5, + 0xf3, 0x0, 0x20, 0x0, 0x3b, 0xe3, 0x0, 0x7, + 0xe1, 0x0, 0x0, 0x1e, 0x91, 0x0, 0x0, 0xa, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4EEE "仮" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x1, 0x25, 0x8c, 0x70, + 0x0, 0x6, 0xc0, 0xae, 0xec, 0xb9, 0x63, 0x0, + 0x0, 0xe, 0x50, 0xc3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6e, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xfd, 0x0, 0xc6, 0x22, 0x22, 0x23, 0x0, + 0xd, 0xcd, 0x0, 0xde, 0xfd, 0xdd, 0xdf, 0x60, + 0x4c, 0x3d, 0x0, 0xe3, 0xe1, 0x0, 0xe, 0x10, + 0x0, 0x2d, 0x0, 0xf2, 0x87, 0x0, 0x5c, 0x0, + 0x0, 0x2d, 0x1, 0xf0, 0x2e, 0x10, 0xc5, 0x0, + 0x0, 0x2d, 0x3, 0xd0, 0x8, 0xa8, 0xb0, 0x0, + 0x0, 0x2d, 0x7, 0xa0, 0x0, 0xdf, 0x10, 0x0, + 0x0, 0x2d, 0xc, 0x50, 0x7, 0xee, 0x80, 0x0, + 0x0, 0x2d, 0x4d, 0x4, 0xcc, 0x11, 0xcc, 0x40, + 0x0, 0x2d, 0x85, 0x3d, 0x50, 0x0, 0x6, 0xd3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4EF6 "件" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x5, 0x4, 0xc0, 0x0, 0x0, + 0x0, 0x5, 0xc0, 0x4c, 0x4, 0xc0, 0x0, 0x0, + 0x0, 0xc, 0x50, 0x89, 0x15, 0xc1, 0x11, 0x0, + 0x0, 0x4f, 0x0, 0xdf, 0xff, 0xff, 0xff, 0x70, + 0x0, 0xde, 0x4, 0xd0, 0x4, 0xc0, 0x0, 0x0, + 0xa, 0xce, 0xb, 0x60, 0x4, 0xc0, 0x0, 0x0, + 0x2d, 0x2e, 0x5, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0x1, 0x1e, 0x2, 0x22, 0x26, 0xd2, 0x22, 0x20, + 0x0, 0x1e, 0xc, 0xdd, 0xde, 0xfd, 0xdd, 0xd2, + 0x0, 0x1e, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, + + /* U+4EFB "任" */ + 0x0, 0x0, 0x35, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, 0xc6, 0x0, 0x1, 0x58, 0xcf, 0x40, + 0x0, 0x5, 0xe5, 0xac, 0xff, 0xe8, 0x40, 0x0, + 0x0, 0xd, 0x62, 0x52, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x8f, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x4, 0xff, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x3f, 0x5f, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x47, 0xf, 0x3b, 0xbb, 0xbd, 0xeb, 0xbb, 0xb4, + 0x0, 0xf, 0x24, 0x44, 0x48, 0xc4, 0x44, 0x41, + 0x0, 0xf, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xf, 0x12, 0x33, 0x37, 0xc3, 0x33, 0x30, + 0x0, 0xf, 0x17, 0xdd, 0xdd, 0xdd, 0xdd, 0xd1, + + /* U+4EFD "份" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe4, 0x0, 0xb4, 0x7, 0x70, 0x0, + 0x0, 0x5, 0xd0, 0x2, 0xe0, 0x4, 0xc0, 0x0, + 0x0, 0xc, 0x50, 0x9, 0x80, 0x0, 0xe2, 0x0, + 0x0, 0x4f, 0x0, 0x1f, 0x20, 0x0, 0x7b, 0x0, + 0x0, 0xee, 0x0, 0xb9, 0x0, 0x0, 0xe, 0x60, + 0xa, 0xde, 0xa, 0xd1, 0x0, 0x0, 0x4, 0xf5, + 0x1c, 0x3e, 0xb, 0x7f, 0xff, 0xff, 0xfd, 0x45, + 0x0, 0x2e, 0x0, 0x0, 0x5b, 0x0, 0x3d, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x88, 0x0, 0x4c, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0xc4, 0x0, 0x5b, 0x0, + 0x0, 0x2e, 0x0, 0x3, 0xe0, 0x0, 0x79, 0x0, + 0x0, 0x2e, 0x0, 0xd, 0x60, 0x0, 0x97, 0x0, + 0x0, 0x2e, 0x1, 0xba, 0x0, 0x11, 0xd4, 0x0, + 0x0, 0x2e, 0x8, 0x80, 0x1, 0xee, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4F01 "企" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7d, 0xc7, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8, 0xc1, 0x1d, 0x70, 0x0, 0x0, + 0x0, 0x1, 0xbb, 0x0, 0x1, 0xba, 0x10, 0x0, + 0x0, 0x6e, 0x90, 0x5, 0x90, 0x8, 0xe8, 0x0, + 0x2d, 0xc2, 0x0, 0x6, 0xb0, 0x0, 0x2b, 0xe3, + 0x4, 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x40, + 0x0, 0xa, 0x60, 0x6, 0xb1, 0x11, 0x10, 0x0, + 0x0, 0xa, 0x60, 0x6, 0xfd, 0xdd, 0xd5, 0x0, + 0x0, 0xa, 0x60, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x60, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x60, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x60, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0xb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + + /* U+4F0A "伊" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd4, 0x11, 0x11, 0x11, 0x11, 0x0, + 0x0, 0x5, 0xc3, 0xee, 0xff, 0xee, 0xef, 0x10, + 0x0, 0xe, 0x40, 0x0, 0x4c, 0x0, 0xe, 0x10, + 0x0, 0x8e, 0x0, 0x0, 0x4c, 0x0, 0xe, 0x10, + 0x6, 0xfe, 0x4b, 0xbb, 0xdf, 0xbb, 0xbf, 0xc3, + 0x4f, 0x5e, 0x14, 0x44, 0x7d, 0x44, 0x4f, 0x51, + 0x35, 0x1e, 0x0, 0x0, 0x4c, 0x0, 0xe, 0x10, + 0x0, 0x1e, 0x0, 0x0, 0x5b, 0x0, 0xe, 0x10, + 0x0, 0x1e, 0x7, 0xee, 0xff, 0xee, 0xef, 0x10, + 0x0, 0x1e, 0x0, 0x0, 0xc6, 0x0, 0xe, 0x10, + 0x0, 0x1e, 0x0, 0x2, 0xe1, 0x0, 0x5, 0x0, + 0x0, 0x1e, 0x0, 0x1d, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x3, 0xd8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x1d, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4F11 "休" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x98, 0x0, 0xc, 0x40, 0x0, 0x0, + 0x0, 0x2, 0xf2, 0x0, 0xc, 0x40, 0x0, 0x0, + 0x0, 0xa, 0xa0, 0x0, 0xc, 0x40, 0x0, 0x0, + 0x0, 0x3f, 0x31, 0x11, 0x1c, 0x51, 0x11, 0x10, + 0x1, 0xef, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0xc, 0xbf, 0x0, 0x0, 0xaf, 0xf4, 0x0, 0x0, + 0x7c, 0xf, 0x0, 0x2, 0xed, 0x8d, 0x0, 0x0, + 0x1, 0xf, 0x0, 0xa, 0x6c, 0x4b, 0x60, 0x0, + 0x0, 0xf, 0x0, 0x3d, 0xc, 0x43, 0xe1, 0x0, + 0x0, 0xf, 0x1, 0xe5, 0xc, 0x40, 0x9b, 0x0, + 0x0, 0xf, 0x2c, 0x90, 0xc, 0x40, 0xc, 0xa0, + 0x0, 0xf, 0x7a, 0x0, 0xc, 0x40, 0x1, 0xc2, + 0x0, 0xf, 0x10, 0x0, 0xc, 0x40, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, + + /* U+4F1A "会" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xf1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3e, 0xd8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0xf6, 0xc, 0xa1, 0x0, 0x0, + 0x0, 0x0, 0x9e, 0x50, 0x0, 0x9e, 0x50, 0x0, + 0x0, 0x6e, 0xe5, 0x33, 0x33, 0x38, 0xec, 0x40, + 0xc, 0xd5, 0x7c, 0xcc, 0xcc, 0xcc, 0x17, 0xe4, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, + 0x5, 0xee, 0xee, 0xff, 0xee, 0xee, 0xee, 0xd0, + 0x0, 0x0, 0x2, 0xf5, 0x0, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x1d, 0x80, 0x0, 0x8b, 0x0, 0x0, + 0x0, 0x0, 0xc9, 0x0, 0x0, 0x9, 0xb0, 0x0, + 0x0, 0x1c, 0xd5, 0x67, 0x9a, 0xbd, 0xf9, 0x0, + 0x0, 0x7f, 0xdb, 0xa8, 0x76, 0x43, 0x2e, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + + /* U+4F1D "伝" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xc0, 0xbf, 0xff, 0xff, 0xff, 0x30, + 0x0, 0xd, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xde, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0xee, 0x2, 0x33, 0x33, 0x33, 0x33, 0x30, + 0x1e, 0x3e, 0xa, 0xcc, 0xef, 0xcc, 0xcc, 0xc1, + 0x1, 0x1e, 0x0, 0x0, 0xc7, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x4, 0xe0, 0x1, 0x40, 0x0, + 0x0, 0x1e, 0x0, 0xc, 0x70, 0x1, 0xe1, 0x0, + 0x0, 0x1e, 0x0, 0x6d, 0x0, 0x0, 0x7a, 0x0, + 0x0, 0x1e, 0x2, 0xf6, 0x45, 0x78, 0xaf, 0x30, + 0x0, 0x1e, 0x9, 0xfd, 0xb9, 0x76, 0x47, 0xb0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa0, + + /* U+4F38 "伸" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd1, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0x6, 0xb0, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0xe, 0x3b, 0xee, 0xef, 0xfe, 0xee, 0xe2, + 0x0, 0x7e, 0xc, 0x40, 0x2, 0xe0, 0x0, 0xe2, + 0x3, 0xfd, 0xc, 0x30, 0x1, 0xe0, 0x0, 0xe2, + 0x1e, 0x7d, 0xc, 0xdc, 0xcc, 0xfc, 0xcc, 0xf2, + 0x38, 0x2d, 0xc, 0x63, 0x34, 0xf3, 0x33, 0xf2, + 0x0, 0x2d, 0xc, 0x30, 0x1, 0xe0, 0x0, 0xe2, + 0x0, 0x2d, 0xc, 0x40, 0x2, 0xe0, 0x0, 0xe2, + 0x0, 0x2d, 0xc, 0xfe, 0xef, 0xfe, 0xee, 0xf2, + 0x0, 0x2d, 0x7, 0x10, 0x1, 0xe0, 0x0, 0x61, + 0x0, 0x2d, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, + + /* U+4F3C "似" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xc0, 0x50, 0x0, 0x0, 0xf, 0x0, + 0x0, 0xc, 0x50, 0xf1, 0xa3, 0x0, 0x1f, 0x0, + 0x0, 0x3e, 0x0, 0xf1, 0x6a, 0x0, 0x2e, 0x0, + 0x0, 0xab, 0x0, 0xf1, 0xe, 0x20, 0x3d, 0x0, + 0x4, 0xfb, 0x0, 0xf1, 0x8, 0x80, 0x5b, 0x0, + 0x1e, 0x9b, 0x0, 0xf1, 0x3, 0xe0, 0x79, 0x0, + 0x49, 0x4b, 0x0, 0xf1, 0x0, 0x10, 0xa6, 0x0, + 0x0, 0x4b, 0x0, 0xf1, 0x0, 0x0, 0xd4, 0x0, + 0x0, 0x4b, 0x0, 0xf1, 0x4, 0x22, 0xfa, 0x0, + 0x0, 0x4b, 0x0, 0xf2, 0x9d, 0x29, 0xae, 0x20, + 0x0, 0x4b, 0x0, 0xfe, 0x90, 0x1f, 0x28, 0xa0, + 0x0, 0x4b, 0x5, 0xe4, 0x0, 0xb9, 0x1, 0xf1, + 0x0, 0x4b, 0x0, 0x20, 0xa, 0xc0, 0x0, 0xb7, + 0x0, 0x4b, 0x0, 0x0, 0x1a, 0x10, 0x0, 0x21, + + /* U+4F46 "但" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xd0, 0xef, 0xff, 0xff, 0xff, 0x10, + 0x0, 0xd, 0x60, 0xe3, 0x0, 0x0, 0xf, 0x10, + 0x0, 0x7f, 0x0, 0xe3, 0x0, 0x0, 0xf, 0x10, + 0x2, 0xfe, 0x0, 0xe3, 0x0, 0x0, 0xf, 0x10, + 0x1e, 0x9e, 0x0, 0xef, 0xff, 0xff, 0xff, 0x10, + 0x3a, 0x2e, 0x0, 0xe4, 0x0, 0x0, 0x1f, 0x10, + 0x0, 0x2e, 0x0, 0xe3, 0x0, 0x0, 0xf, 0x10, + 0x0, 0x2e, 0x0, 0xe3, 0x0, 0x0, 0xf, 0x10, + 0x0, 0x2e, 0x0, 0xed, 0xcc, 0xcc, 0xcf, 0x10, + 0x0, 0x2e, 0x0, 0x23, 0x33, 0x33, 0x33, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0x3, 0x33, 0x33, 0x33, 0x33, 0x31, + 0x0, 0x2e, 0x1c, 0xcc, 0xcc, 0xcc, 0xcc, 0xc6, + + /* U+4F4D "位" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb5, 0x0, 0xc, 0x40, 0x0, 0x0, + 0x0, 0x3, 0xe0, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0xb, 0x80, 0x33, 0x36, 0x83, 0x33, 0x10, + 0x0, 0x3f, 0x12, 0xcc, 0xcc, 0xcc, 0xcc, 0x50, + 0x0, 0xdf, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0xa, 0xcf, 0x0, 0x1f, 0x0, 0x0, 0xd4, 0x0, + 0x3d, 0x2f, 0x0, 0xe, 0x20, 0x0, 0xf1, 0x0, + 0x1, 0xf, 0x0, 0xb, 0x50, 0x2, 0xe0, 0x0, + 0x0, 0xf, 0x0, 0x8, 0x90, 0x5, 0xb0, 0x0, + 0x0, 0xf, 0x0, 0x5, 0xb0, 0x8, 0x80, 0x0, + 0x0, 0xf, 0x0, 0x3, 0xe0, 0xb, 0x40, 0x0, + 0x0, 0xf, 0x0, 0x1, 0xc0, 0xf, 0x0, 0x0, + 0x0, 0xf, 0x3, 0x33, 0x33, 0x6d, 0x33, 0x30, + 0x0, 0xf, 0xb, 0xcc, 0xcc, 0xcc, 0xcc, 0xc1, + + /* U+4F4E "低" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, 0xe3, 0x0, 0x1, 0x58, 0xde, 0x20, + 0x0, 0x5, 0xc0, 0x8c, 0xfe, 0xdd, 0x30, 0x0, + 0x0, 0xd, 0x50, 0xe4, 0x10, 0x4c, 0x0, 0x0, + 0x0, 0x5f, 0x0, 0xe1, 0x0, 0x3d, 0x0, 0x0, + 0x1, 0xee, 0x0, 0xe1, 0x0, 0x2e, 0x0, 0x0, + 0xb, 0xce, 0x0, 0xe2, 0x0, 0x2f, 0x0, 0x0, + 0x4d, 0x2e, 0x0, 0xef, 0xff, 0xff, 0xff, 0xf3, + 0x2, 0x1e, 0x0, 0xe1, 0x0, 0xd, 0x20, 0x0, + 0x0, 0x1e, 0x0, 0xe1, 0x0, 0xb, 0x40, 0x0, + 0x0, 0x1e, 0x0, 0xe1, 0x0, 0x8, 0x70, 0x0, + 0x0, 0x1e, 0x0, 0xe1, 0x2, 0x24, 0xb0, 0x21, + 0x0, 0x1e, 0x0, 0xe1, 0x3, 0xc0, 0xf2, 0x75, + 0x0, 0x1e, 0x0, 0xf8, 0xb6, 0xa5, 0x8c, 0xc2, + 0x0, 0x1e, 0x5, 0xd7, 0x30, 0x36, 0x9, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4F4F "住" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb6, 0x0, 0x1e, 0x20, 0x0, 0x0, + 0x0, 0x3, 0xf0, 0x0, 0x7, 0xb0, 0x0, 0x0, + 0x0, 0xc, 0x80, 0x0, 0x2, 0xa1, 0x0, 0x0, + 0x0, 0x5f, 0x1a, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x2, 0xef, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x1d, 0xaf, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x19, 0x1f, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xf, 0x1, 0xcc, 0xcd, 0xfc, 0xcc, 0x70, + 0x0, 0xf, 0x0, 0x33, 0x37, 0xc3, 0x33, 0x20, + 0x0, 0xf, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xf, 0x1, 0x11, 0x16, 0xc1, 0x11, 0x10, + 0x0, 0xf, 0xe, 0xee, 0xee, 0xee, 0xee, 0xe4, + + /* U+4F53 "体" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd2, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0x6, 0xc0, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0xd, 0x40, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0x5e, 0xf, 0xff, 0xff, 0xff, 0xff, 0xf6, + 0x2, 0xfd, 0x0, 0x0, 0x6f, 0xe9, 0x0, 0x0, + 0xc, 0xbd, 0x0, 0x0, 0xd8, 0x9d, 0x10, 0x0, + 0x1b, 0x2d, 0x0, 0x6, 0x97, 0x96, 0x90, 0x0, + 0x0, 0x2d, 0x0, 0xe, 0x17, 0x90, 0xe2, 0x0, + 0x0, 0x2d, 0x0, 0xa8, 0x7, 0x90, 0x7c, 0x0, + 0x0, 0x2d, 0x7, 0xd0, 0x7, 0x90, 0xc, 0x90, + 0x0, 0x2d, 0x5e, 0x5e, 0xef, 0xfe, 0xe5, 0xd7, + 0x0, 0x2d, 0x2, 0x0, 0x7, 0x90, 0x0, 0x10, + 0x0, 0x2d, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0x0, 0x6, 0x90, 0x0, 0x0, + + /* U+4F55 "何" */ + 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x8b, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0x1f, 0x20, 0x11, 0x11, 0x11, 0x2f, 0x10, + 0x0, 0x8e, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, + 0x2, 0xfe, 0x0, 0x33, 0x33, 0x20, 0xf, 0x0, + 0xd, 0xce, 0x3, 0xeb, 0xbc, 0xb0, 0xf, 0x0, + 0x1c, 0x2e, 0x3, 0xb0, 0x4, 0xb0, 0xf, 0x0, + 0x0, 0x2e, 0x3, 0xb0, 0x4, 0xb0, 0xf, 0x0, + 0x0, 0x2e, 0x3, 0xb0, 0x4, 0xb0, 0xf, 0x0, + 0x0, 0x2e, 0x3, 0xfe, 0xef, 0xb0, 0xf, 0x0, + 0x0, 0x2e, 0x3, 0xc0, 0x0, 0x0, 0xf, 0x0, + 0x0, 0x2e, 0x1, 0x40, 0x0, 0x0, 0xf, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x11, 0x2f, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x2, 0xff, 0xe8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4F59 "余" */ + 0x0, 0x0, 0x0, 0x1, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1d, 0xe6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xd6, 0x1d, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x5e, 0x40, 0x0, 0xbb, 0x10, 0x0, + 0x0, 0x1a, 0xe3, 0x0, 0x0, 0x9, 0xf8, 0x10, + 0x18, 0xf9, 0xcb, 0xbb, 0xbb, 0xbb, 0x7b, 0xf6, + 0xa, 0x30, 0x44, 0x47, 0xe4, 0x44, 0x10, 0x43, + 0x0, 0x0, 0x0, 0x4, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x22, 0x22, 0x26, 0xe2, 0x22, 0x22, 0x20, + 0x3, 0xdd, 0xdd, 0xde, 0xfd, 0xdd, 0xdd, 0xb0, + 0x0, 0x0, 0x10, 0x4, 0xd0, 0x1, 0x0, 0x0, + 0x0, 0x2, 0xe4, 0x4, 0xd0, 0x1d, 0x70, 0x0, + 0x0, 0x3e, 0x50, 0x4, 0xd0, 0x1, 0xca, 0x0, + 0x7, 0xe4, 0x0, 0x5, 0xd0, 0x0, 0xb, 0xa0, + 0x1, 0x10, 0x9, 0xff, 0x80, 0x0, 0x0, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4F5C "作" */ + 0x0, 0x0, 0x43, 0x0, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe4, 0x1, 0xf1, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xc0, 0x7, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x50, 0xd, 0xfe, 0xee, 0xee, 0xe3, + 0x0, 0x5f, 0x0, 0x5b, 0x1e, 0x31, 0x11, 0x10, + 0x1, 0xef, 0x0, 0xd2, 0xe, 0x20, 0x0, 0x0, + 0xc, 0xbf, 0x9, 0x90, 0xe, 0x30, 0x0, 0x0, + 0x3d, 0x1f, 0xa, 0x0, 0xe, 0xff, 0xff, 0xc0, + 0x1, 0xf, 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0xe, 0xff, 0xff, 0xf0, + 0x0, 0xf, 0x0, 0x0, 0xe, 0x30, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, + + /* U+4F60 "你" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc5, 0x7, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xd0, 0xc, 0x50, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x60, 0x2f, 0x20, 0x0, 0x0, 0x10, + 0x0, 0x5e, 0x0, 0x7f, 0xee, 0xff, 0xee, 0xf6, + 0x1, 0xed, 0x0, 0xe3, 0x0, 0xe1, 0x0, 0xc3, + 0x1d, 0xbd, 0x9, 0x90, 0x0, 0xe1, 0x0, 0xe0, + 0x4b, 0x2d, 0x4, 0x14, 0x20, 0xe1, 0x34, 0x30, + 0x0, 0x2d, 0x0, 0xe, 0x30, 0xe1, 0x3e, 0x0, + 0x0, 0x2d, 0x0, 0x3d, 0x0, 0xe1, 0xc, 0x60, + 0x0, 0x2d, 0x0, 0xa8, 0x0, 0xe1, 0x5, 0xc0, + 0x0, 0x2d, 0x4, 0xe0, 0x0, 0xe1, 0x0, 0xf1, + 0x0, 0x2d, 0x6, 0x50, 0x0, 0xe1, 0x0, 0x83, + 0x0, 0x2d, 0x0, 0x0, 0x1, 0xf1, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0x0, 0xaf, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4F7F "使" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd4, 0x0, 0x6, 0xa0, 0x0, 0x0, + 0x0, 0x5, 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xc4, + 0x0, 0xe, 0x42, 0x22, 0x28, 0xb2, 0x22, 0x20, + 0x0, 0x8e, 0x0, 0x0, 0x6, 0xa0, 0x0, 0x0, + 0x4, 0xfe, 0x6, 0xee, 0xef, 0xfe, 0xee, 0xc0, + 0x3f, 0x6e, 0x6, 0x80, 0x6, 0xa0, 0x3, 0xc0, + 0x25, 0x1e, 0x6, 0x80, 0x6, 0xa0, 0x3, 0xc0, + 0x0, 0x1e, 0x6, 0xeb, 0xbd, 0xeb, 0xbc, 0xc0, + 0x0, 0x1e, 0x2, 0x73, 0x3a, 0x93, 0x33, 0x20, + 0x0, 0x1e, 0x1, 0xd3, 0xc, 0x40, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x2d, 0x9d, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x5, 0xfd, 0x40, 0x0, 0x0, + 0x0, 0x1e, 0x3, 0x9e, 0x44, 0xbe, 0x95, 0x20, + 0x0, 0x1e, 0x2d, 0x71, 0x0, 0x2, 0x6a, 0xd2, + + /* U+4F86 "來" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x1a, 0x81, 0x11, 0x11, 0x10, + 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0x1, 0x80, 0x9, 0x80, 0x4, 0x40, 0x0, + 0x0, 0x7, 0xb0, 0x9, 0x80, 0xc, 0x50, 0x0, + 0x0, 0xd, 0x90, 0x9, 0x80, 0x2f, 0x40, 0x0, + 0x0, 0x6d, 0xc8, 0x9, 0x80, 0xc9, 0xe6, 0x0, + 0x5, 0xf3, 0xa, 0x4f, 0xf9, 0xb0, 0x1d, 0x90, + 0x8, 0x40, 0x1, 0xdd, 0xdd, 0x10, 0x1, 0x50, + 0x0, 0x0, 0x1d, 0x59, 0x87, 0xc1, 0x0, 0x0, + 0x0, 0x4, 0xe5, 0x9, 0x80, 0x7d, 0x30, 0x0, + 0x1, 0x9e, 0x40, 0x9, 0x80, 0x6, 0xf8, 0x10, + 0x1f, 0xa1, 0x0, 0x9, 0x80, 0x0, 0x2b, 0xf2, + 0x1, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x20, + + /* U+4F8B "例" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe8, 0xff, 0xff, 0xf1, 0x0, 0x4b, 0x0, + 0x69, 0x0, 0xd3, 0x0, 0xa, 0x4, 0xb0, 0xd, + 0x30, 0x1f, 0x0, 0x1, 0xd0, 0x4b, 0x5, 0xf2, + 0x5, 0xe5, 0x53, 0x1d, 0x4, 0xb1, 0xef, 0x20, + 0x9c, 0xac, 0x91, 0xd0, 0x4b, 0x89, 0xd2, 0xe, + 0x10, 0x96, 0x1d, 0x4, 0xb2, 0x1d, 0x26, 0xb0, + 0xd, 0x31, 0xd0, 0x4b, 0x0, 0xd2, 0xe5, 0x61, + 0xf0, 0x1d, 0x4, 0xb0, 0xd, 0x23, 0x1d, 0xca, + 0x1, 0xd0, 0x4b, 0x0, 0xd2, 0x0, 0x1e, 0x50, + 0x1d, 0x4, 0xb0, 0xd, 0x20, 0x4, 0xe0, 0x0, + 0x20, 0x4b, 0x0, 0xd2, 0x0, 0xd5, 0x0, 0x0, + 0x4, 0xb0, 0xd, 0x20, 0xca, 0x0, 0x0, 0x0, + 0x5b, 0x0, 0xd2, 0x7a, 0x0, 0x0, 0xa, 0xfe, + 0x60, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4F9B "供" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc5, 0x6, 0xa0, 0x0, 0xf0, 0x0, + 0x0, 0x4, 0xd0, 0x6, 0xa0, 0x0, 0xf0, 0x0, + 0x0, 0xc, 0x50, 0x6, 0xa0, 0x0, 0xf0, 0x0, + 0x0, 0x6f, 0x7, 0xff, 0xff, 0xff, 0xff, 0xf4, + 0x2, 0xfe, 0x0, 0x17, 0xb1, 0x12, 0xf1, 0x10, + 0x1d, 0x9e, 0x0, 0x6, 0xa0, 0x0, 0xf0, 0x0, + 0x29, 0x2e, 0x0, 0x6, 0xa0, 0x0, 0xf0, 0x0, + 0x0, 0x2e, 0x0, 0x6, 0xa0, 0x0, 0xf0, 0x0, + 0x0, 0x2e, 0xe, 0xff, 0xff, 0xff, 0xff, 0xf7, + 0x0, 0x2e, 0x1, 0x11, 0x11, 0x11, 0x11, 0x10, + 0x0, 0x2e, 0x0, 0x6, 0x90, 0x2, 0xb0, 0x0, + 0x0, 0x2e, 0x0, 0x2e, 0x20, 0x0, 0x9b, 0x0, + 0x0, 0x2e, 0x2, 0xe5, 0x0, 0x0, 0xb, 0x90, + 0x0, 0x2e, 0x9, 0x60, 0x0, 0x0, 0x1, 0xd1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4F9D "依" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb6, 0x0, 0xb, 0x50, 0x0, 0x0, + 0x0, 0x3, 0xe0, 0x0, 0x5, 0xd0, 0x0, 0x0, + 0x0, 0xb, 0x72, 0x22, 0x22, 0xb3, 0x22, 0x20, + 0x0, 0x3f, 0x1d, 0xdd, 0xdf, 0xed, 0xdd, 0xd4, + 0x0, 0xdd, 0x0, 0x0, 0x7f, 0x60, 0x0, 0x0, + 0xa, 0xdd, 0x0, 0x5, 0xe7, 0xc0, 0x0, 0x50, + 0x1c, 0x3d, 0x0, 0x4f, 0x30, 0xe2, 0x8, 0xd2, + 0x0, 0x2d, 0x8, 0xfe, 0x0, 0x99, 0xb9, 0x0, + 0x0, 0x2d, 0xbc, 0x4e, 0x0, 0x2f, 0x50, 0x0, + 0x0, 0x2d, 0x10, 0x1e, 0x0, 0xa, 0x90, 0x0, + 0x0, 0x2d, 0x0, 0x1e, 0x0, 0x1, 0xe5, 0x0, + 0x0, 0x2d, 0x0, 0x1e, 0x1, 0x60, 0x4f, 0x40, + 0x0, 0x2d, 0x0, 0x4f, 0xcd, 0x80, 0x5, 0xf6, + 0x0, 0x2d, 0x0, 0xaa, 0x30, 0x0, 0x0, 0x32, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4FA1 "価" */ + 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x7e, 0xff, 0xff, 0xff, 0xff, 0xf4, + 0x0, 0x2f, 0x10, 0x0, 0xe2, 0xd, 0x20, 0x0, + 0x0, 0xac, 0x0, 0x0, 0xd2, 0xd, 0x20, 0x0, + 0x4, 0xfc, 0x0, 0x0, 0xd2, 0xd, 0x20, 0x0, + 0x2e, 0x9c, 0xb, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x28, 0x3c, 0xb, 0x40, 0xc2, 0xd, 0x0, 0xe1, + 0x0, 0x3c, 0xb, 0x40, 0xc2, 0xd, 0x0, 0xe1, + 0x0, 0x3c, 0xb, 0x40, 0xc2, 0xd, 0x0, 0xe1, + 0x0, 0x3c, 0xb, 0x40, 0xc2, 0xd, 0x0, 0xe1, + 0x0, 0x3c, 0xb, 0x40, 0xc2, 0xd, 0x0, 0xe1, + 0x0, 0x3c, 0xb, 0x50, 0xc2, 0xd, 0x10, 0xe1, + 0x0, 0x3c, 0xb, 0xfe, 0xee, 0xee, 0xee, 0xf1, + 0x0, 0x3c, 0xb, 0x40, 0x0, 0x0, 0x0, 0xd1, + + /* U+4FBF "便" */ + 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xdc, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0xb, 0x80, 0x0, 0x4, 0xb0, 0x0, 0x0, + 0x0, 0x1f, 0x30, 0x0, 0x4, 0xb0, 0x0, 0x0, + 0x0, 0x9e, 0x4, 0xfd, 0xde, 0xfd, 0xde, 0x80, + 0x2, 0xfd, 0x4, 0xa0, 0x4, 0xb0, 0x7, 0x80, + 0xd, 0xbd, 0x4, 0xeb, 0xbc, 0xeb, 0xbd, 0x80, + 0xa, 0x2d, 0x4, 0xb1, 0x16, 0xb1, 0x18, 0x80, + 0x0, 0x2d, 0x4, 0xa0, 0x5, 0xb0, 0x7, 0x80, + 0x0, 0x2d, 0x4, 0xed, 0xde, 0xfd, 0xde, 0x80, + 0x0, 0x2d, 0x4, 0x40, 0x9, 0x70, 0x0, 0x0, + 0x0, 0x2d, 0x1, 0xe5, 0x1e, 0x20, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0x1c, 0xe9, 0x0, 0x0, 0x0, + 0x0, 0x2d, 0x1, 0x7e, 0x9c, 0xe9, 0x64, 0x20, + 0x0, 0x2d, 0x5e, 0x81, 0x0, 0x16, 0x9b, 0xd2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4FC2 "係" */ + 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xf1, 0x2, 0x35, 0x79, 0xcf, 0x70, + 0x0, 0x8, 0x97, 0xec, 0xcf, 0x85, 0x30, 0x0, + 0x0, 0xe, 0x30, 0x0, 0xc5, 0x0, 0x62, 0x0, + 0x0, 0x7e, 0x0, 0xb, 0x60, 0x8, 0xd1, 0x0, + 0x2, 0xfe, 0x0, 0xdf, 0xee, 0xfb, 0x10, 0x0, + 0xc, 0xae, 0x0, 0x32, 0x2c, 0x90, 0x56, 0x0, + 0x1b, 0x2e, 0x0, 0x5, 0xd5, 0x0, 0x1e, 0x30, + 0x0, 0x2e, 0x2, 0xbf, 0xbb, 0xde, 0xec, 0xd0, + 0x0, 0x2e, 0x3, 0x96, 0x56, 0xd0, 0x0, 0xa5, + 0x0, 0x2e, 0x0, 0x17, 0x3, 0xd0, 0x55, 0x0, + 0x0, 0x2e, 0x0, 0xa8, 0x3, 0xd0, 0x1e, 0x40, + 0x0, 0x2e, 0x6, 0xd0, 0x3, 0xd0, 0x3, 0xe0, + 0x0, 0x2e, 0x2e, 0x10, 0x4, 0xd0, 0x0, 0x94, + 0x0, 0x2e, 0x0, 0x0, 0xdf, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4FDD "保" */ + 0x0, 0x0, 0x63, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xf1, 0xef, 0xff, 0xff, 0xff, 0x30, + 0x0, 0x8, 0xa0, 0xe1, 0x0, 0x0, 0xd, 0x30, + 0x0, 0x1f, 0x20, 0xe1, 0x0, 0x0, 0xd, 0x30, + 0x0, 0xae, 0x0, 0xe1, 0x0, 0x0, 0xd, 0x30, + 0x6, 0xfe, 0x0, 0xed, 0xdd, 0xdd, 0xdf, 0x30, + 0x4f, 0x5e, 0x0, 0x22, 0x24, 0xe2, 0x22, 0x0, + 0x25, 0x1e, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0x1e, 0x1b, 0xbb, 0xbc, 0xfb, 0xbb, 0xb1, + 0x0, 0x1e, 0x3, 0x33, 0x6f, 0xfd, 0x33, 0x30, + 0x0, 0x1e, 0x0, 0x1, 0xe7, 0xe9, 0x70, 0x0, + 0x0, 0x1e, 0x0, 0xc, 0x72, 0xe0, 0xd3, 0x0, + 0x0, 0x1e, 0x3, 0xd8, 0x2, 0xe0, 0x3e, 0x40, + 0x0, 0x1e, 0x3e, 0x40, 0x2, 0xe0, 0x2, 0xe3, + 0x0, 0x1e, 0x1, 0x0, 0x2, 0xe0, 0x0, 0x10, + + /* U+4FE1 "信" */ + 0x0, 0x0, 0x50, 0x0, 0x6, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xe0, 0x0, 0xd, 0x60, 0x0, 0x0, + 0x0, 0x8, 0x80, 0x0, 0x4, 0x90, 0x0, 0x0, + 0x0, 0xe, 0x2d, 0xee, 0xee, 0xee, 0xee, 0xe3, + 0x0, 0x7e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xee, 0x0, 0x8a, 0xaa, 0xaa, 0xaa, 0x0, + 0xb, 0x8e, 0x0, 0x23, 0x33, 0x33, 0x33, 0x0, + 0x1c, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0xae, 0xee, 0xee, 0xed, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0xee, 0xee, 0xee, 0xee, 0x10, + 0x0, 0x1e, 0x0, 0xf0, 0x0, 0x0, 0xd, 0x10, + 0x0, 0x1e, 0x0, 0xf0, 0x0, 0x0, 0xd, 0x10, + 0x0, 0x1e, 0x0, 0xf1, 0x11, 0x11, 0x1d, 0x10, + 0x0, 0x1e, 0x0, 0xfc, 0xcc, 0xcc, 0xce, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+4FEE "修" */ + 0x0, 0x0, 0x60, 0x0, 0x7, 0x10, 0x0, 0x0, + 0x0, 0x5, 0xb0, 0x0, 0x4d, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x50, 0x0, 0xcf, 0xdd, 0xdd, 0xb0, + 0x0, 0x2e, 0x0, 0x8, 0xf5, 0x0, 0xb, 0x60, + 0x0, 0xac, 0x0, 0x5e, 0x3d, 0x20, 0x7c, 0x0, + 0x3, 0xfb, 0xd, 0x63, 0x4, 0xe9, 0xc0, 0x0, + 0xd, 0xbb, 0xd, 0x0, 0x17, 0xdd, 0xb3, 0x0, + 0x4b, 0x4b, 0xd, 0x7c, 0xd7, 0x10, 0x5c, 0xe6, + 0x1, 0x4b, 0xd, 0x32, 0x0, 0x8b, 0x0, 0x10, + 0x0, 0x4b, 0xd, 0x1, 0x8c, 0x60, 0x34, 0x0, + 0x0, 0x4b, 0xd, 0x1, 0x50, 0x8, 0xc1, 0x0, + 0x0, 0x4b, 0xd, 0x0, 0x4a, 0xc6, 0x2, 0xb1, + 0x0, 0x4b, 0xa, 0x0, 0x83, 0x0, 0x7d, 0x50, + 0x0, 0x4b, 0x0, 0x0, 0x25, 0xad, 0x70, 0x0, + 0x0, 0x4b, 0x0, 0xc, 0xb8, 0x30, 0x0, 0x0, + + /* U+500B "個" */ + 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5c, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x0, + 0xc, 0x61, 0xe0, 0x0, 0x0, 0x0, 0xf0, 0x3, + 0xf1, 0x1e, 0x0, 0x9, 0x0, 0xf, 0x0, 0xac, + 0x1, 0xe0, 0x0, 0xd0, 0x0, 0xf0, 0x4f, 0xc0, + 0x1e, 0x5d, 0xdf, 0xdd, 0x6f, 0x1e, 0xac, 0x1, + 0xe0, 0x0, 0xd0, 0x0, 0xf5, 0xb4, 0xc0, 0x1e, + 0x2, 0x2e, 0x22, 0xf, 0x1, 0x3c, 0x1, 0xe0, + 0xba, 0xab, 0xb0, 0xf0, 0x3, 0xc0, 0x1e, 0xb, + 0x10, 0x1b, 0xf, 0x0, 0x3c, 0x1, 0xe0, 0xb1, + 0x1, 0xb0, 0xf0, 0x3, 0xc0, 0x1e, 0xa, 0xdd, + 0xda, 0xf, 0x0, 0x3c, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0xf0, 0x3, 0xc0, 0x1f, 0xee, 0xee, 0xee, + 0xef, 0x0, 0x3c, 0x1, 0xe0, 0x0, 0x0, 0x1, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5011 "們" */ + 0x0, 0x3, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x8e, 0xee, 0xec, 0x4f, 0xee, 0xf0, + 0x0, 0xf, 0x3e, 0x10, 0xc, 0x49, 0x0, 0xf0, + 0x0, 0x6e, 0xe, 0x10, 0xc, 0x49, 0x0, 0xf0, + 0x0, 0xdb, 0xe, 0xdd, 0xdc, 0x4e, 0xdd, 0xf0, + 0x7, 0xfb, 0xe, 0x10, 0xc, 0x49, 0x0, 0xf0, + 0x2f, 0x8b, 0xe, 0xcc, 0xcc, 0x4e, 0xcc, 0xf0, + 0x38, 0x4b, 0xe, 0x21, 0x10, 0x1, 0x11, 0xf0, + 0x0, 0x4b, 0xe, 0x10, 0x0, 0x0, 0x0, 0xf0, + 0x0, 0x4b, 0xe, 0x10, 0x0, 0x0, 0x0, 0xf0, + 0x0, 0x4b, 0xe, 0x10, 0x0, 0x0, 0x0, 0xf0, + 0x0, 0x4b, 0xe, 0x10, 0x0, 0x0, 0x0, 0xf0, + 0x0, 0x4b, 0xe, 0x10, 0x0, 0x0, 0x0, 0xf0, + 0x0, 0x4b, 0xe, 0x10, 0x0, 0x0, 0x1, 0xf0, + 0x0, 0x4b, 0xe, 0x10, 0x0, 0xa, 0xfe, 0x90, + + /* U+5019 "候" */ + 0x0, 0x4, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x50, 0xb, 0xee, 0xee, 0xf9, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x97, 0x0, + 0x0, 0x89, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x0, + 0x0, 0xe3, 0x3a, 0x7b, 0xbb, 0xbb, 0xfc, 0xb2, + 0x8, 0xf2, 0x3b, 0x23, 0xb4, 0x33, 0x33, 0x30, + 0x3f, 0xf2, 0x3b, 0x3, 0xd1, 0x11, 0x11, 0x0, + 0x77, 0xd2, 0x3b, 0xa, 0xed, 0xfd, 0xdd, 0x80, + 0x0, 0xd2, 0x3b, 0x4d, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0xd2, 0x3b, 0x33, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0xd2, 0x3b, 0x8e, 0xee, 0xfe, 0xee, 0xe2, + 0x0, 0xd2, 0x3b, 0x0, 0x5, 0xf8, 0x0, 0x0, + 0x0, 0xd2, 0x0, 0x0, 0x1e, 0x5e, 0x50, 0x0, + 0x0, 0xd2, 0x0, 0x6, 0xe5, 0x2, 0xda, 0x30, + 0x0, 0xd2, 0x0, 0xa9, 0x20, 0x0, 0x6, 0xc2, + + /* U+501F "借" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc4, 0x6, 0x90, 0x4, 0xc0, 0x0, + 0x0, 0x5, 0xd1, 0x28, 0xa2, 0x26, 0xd2, 0x20, + 0x0, 0xd, 0x67, 0xce, 0xec, 0xcd, 0xfc, 0xc0, + 0x0, 0x6e, 0x0, 0x6, 0x90, 0x4, 0xc0, 0x0, + 0x2, 0xfd, 0x0, 0x7, 0xa0, 0x5, 0xc0, 0x0, + 0x2e, 0xad, 0x4e, 0xee, 0xee, 0xee, 0xee, 0xea, + 0x39, 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0x8e, 0xee, 0xee, 0xee, 0x30, + 0x0, 0x2d, 0x0, 0x87, 0x0, 0x0, 0xd, 0x30, + 0x0, 0x2d, 0x0, 0x87, 0x0, 0x0, 0xd, 0x30, + 0x0, 0x2d, 0x0, 0x8e, 0xdd, 0xdd, 0xdf, 0x30, + 0x0, 0x2d, 0x0, 0x87, 0x0, 0x0, 0xd, 0x30, + 0x0, 0x2d, 0x0, 0x88, 0x22, 0x22, 0x2d, 0x30, + 0x0, 0x2c, 0x0, 0x8e, 0xcc, 0xcc, 0xce, 0x30, + + /* U+5024 "値" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa7, 0x0, 0x0, 0xa7, 0x0, 0x0, + 0x0, 0x2, 0xe1, 0xee, 0xee, 0xff, 0xee, 0xea, + 0x0, 0xa, 0x70, 0x0, 0x0, 0xe4, 0x0, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0x22, 0xf3, 0x22, 0x10, + 0x1, 0xed, 0x1, 0xb0, 0xeb, 0xbb, 0xbc, 0xb0, + 0xc, 0xbd, 0x1, 0xe0, 0xe1, 0x0, 0x4, 0xb0, + 0x4b, 0x2d, 0x1, 0xe0, 0xed, 0xcc, 0xcd, 0xb0, + 0x0, 0x2d, 0x1, 0xe0, 0xe1, 0x0, 0x4, 0xb0, + 0x0, 0x2d, 0x1, 0xe0, 0xed, 0xcc, 0xcd, 0xb0, + 0x0, 0x2d, 0x1, 0xe0, 0xe1, 0x0, 0x4, 0xb0, + 0x0, 0x2d, 0x1, 0xe0, 0xed, 0xdd, 0xde, 0xb0, + 0x0, 0x2d, 0x1, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2d, 0x1, 0xfb, 0xbb, 0xbb, 0xbb, 0xb9, + 0x0, 0x2d, 0x1, 0xe3, 0x33, 0x33, 0x33, 0x32, + + /* U+503C "值" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc4, 0x0, 0x4, 0xd0, 0x0, 0x0, + 0x0, 0x4, 0xd8, 0xee, 0xef, 0xfe, 0xee, 0xe0, + 0x0, 0xb, 0x60, 0x0, 0xa, 0x60, 0x0, 0x0, + 0x0, 0x4e, 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, + 0x1, 0xec, 0x0, 0xae, 0xdd, 0xdd, 0xdf, 0x0, + 0xc, 0xdc, 0x0, 0xa5, 0x0, 0x0, 0xf, 0x0, + 0x1b, 0x3c, 0x0, 0xad, 0xcc, 0xcc, 0xcf, 0x0, + 0x0, 0x2c, 0x0, 0xa5, 0x0, 0x0, 0xf, 0x0, + 0x0, 0x2c, 0x0, 0xad, 0xcc, 0xcc, 0xcf, 0x0, + 0x0, 0x2c, 0x0, 0xa5, 0x0, 0x0, 0xf, 0x0, + 0x0, 0x2c, 0x0, 0xa7, 0x22, 0x22, 0x2f, 0x0, + 0x0, 0x2c, 0x0, 0xac, 0xaa, 0xaa, 0xaf, 0x0, + 0x0, 0x2c, 0x0, 0xa5, 0x0, 0x0, 0xf, 0x0, + 0x0, 0x2c, 0x2e, 0xff, 0xee, 0xee, 0xef, 0xe7, + + /* U+505A "做" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0xb, 0x50, 0xa6, 0x0, 0x3c, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0xa6, 0x0, 0x78, 0x0, 0x0, + 0x0, 0x89, 0x0, 0xa6, 0x0, 0xa6, 0x0, 0x0, + 0x0, 0xe4, 0xde, 0xff, 0xe8, 0xed, 0xdf, 0xe1, + 0x8, 0xf4, 0x0, 0xa6, 0x4, 0xf0, 0xb, 0x30, + 0x4e, 0xd4, 0x0, 0xa6, 0xa, 0xf1, 0xe, 0x0, + 0xc5, 0xb4, 0x0, 0xa6, 0x1d, 0x94, 0xd, 0x0, + 0x10, 0xb4, 0x7f, 0xee, 0xf4, 0x58, 0x4a, 0x0, + 0x0, 0xb4, 0x77, 0x0, 0xb3, 0x1d, 0x95, 0x0, + 0x0, 0xb4, 0x77, 0x0, 0xb3, 0xc, 0xe0, 0x0, + 0x0, 0xb4, 0x77, 0x0, 0xb3, 0x9, 0xb0, 0x0, + 0x0, 0xb4, 0x79, 0x33, 0xc3, 0x3e, 0xe3, 0x0, + 0x0, 0xb4, 0x7d, 0xbb, 0xb5, 0xd3, 0x3d, 0x20, + 0x0, 0xb4, 0x45, 0x0, 0x4b, 0x10, 0x3, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+505C "停" */ + 0x0, 0x0, 0x31, 0x0, 0x3, 0x30, 0x0, 0x0, + 0x0, 0x0, 0xe3, 0x0, 0x4, 0xd0, 0x0, 0x0, + 0x0, 0x6, 0xc9, 0xee, 0xee, 0xfe, 0xee, 0xe6, + 0x0, 0xd, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5e, 0x0, 0x6e, 0xcc, 0xcc, 0xcf, 0x0, + 0x1, 0xec, 0x0, 0x69, 0x0, 0x0, 0xf, 0x0, + 0xb, 0xcc, 0x0, 0x6d, 0xcc, 0xcc, 0xce, 0x0, + 0x1b, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2c, 0xd, 0xee, 0xee, 0xee, 0xee, 0xf6, + 0x0, 0x2c, 0xd, 0x10, 0x0, 0x0, 0x0, 0x96, + 0x0, 0x2c, 0x7, 0x7e, 0xee, 0xee, 0xee, 0x53, + 0x0, 0x2c, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0x2c, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0x2c, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0x2c, 0x0, 0x7, 0xee, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5065 "健" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x52, 0x21, 0x0, 0x76, 0x0, 0x0, + 0x0, 0x3d, 0x5c, 0xea, 0x6c, 0xee, 0xce, 0x0, + 0x0, 0x96, 0x0, 0xd3, 0x0, 0x76, 0xd, 0x0, + 0x2, 0xf2, 0x4, 0xb6, 0xdd, 0xee, 0xdf, 0xd1, + 0xc, 0xf2, 0xb, 0x20, 0x0, 0x76, 0xd, 0x0, + 0x6c, 0xd2, 0x8e, 0xb6, 0x6d, 0xee, 0xde, 0x0, + 0x32, 0xc2, 0x43, 0x87, 0x0, 0x76, 0x0, 0x0, + 0x0, 0xc2, 0x30, 0x85, 0xac, 0xed, 0xcc, 0x20, + 0x0, 0xc2, 0xb2, 0xa3, 0x11, 0x87, 0x11, 0x0, + 0x0, 0xc2, 0x67, 0xd1, 0x11, 0x87, 0x11, 0x10, + 0x0, 0xc2, 0xd, 0xb5, 0xbb, 0xdd, 0xbb, 0x80, + 0x0, 0xc2, 0xb, 0xb1, 0x0, 0x76, 0x0, 0x0, + 0x0, 0xc2, 0x7c, 0x9e, 0x95, 0xb8, 0x11, 0x10, + 0x0, 0xc6, 0xc0, 0x1, 0x69, 0xbc, 0xdd, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5074 "側" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xab, 0xee, 0xef, 0x10, 0x0, 0xe1, + 0x0, 0xd, 0x3b, 0x20, 0xe, 0x1c, 0x20, 0xe1, + 0x0, 0x4d, 0xb, 0x20, 0xe, 0x1c, 0x20, 0xe1, + 0x0, 0xbb, 0xb, 0xee, 0xef, 0x1c, 0x20, 0xe1, + 0x5, 0xfb, 0xb, 0x20, 0xe, 0x1c, 0x20, 0xe1, + 0x2e, 0x7b, 0xb, 0x20, 0xe, 0x1c, 0x20, 0xe1, + 0x37, 0x4b, 0xb, 0xdd, 0xdf, 0x1c, 0x20, 0xe1, + 0x0, 0x4b, 0xb, 0x30, 0xe, 0x1c, 0x20, 0xe1, + 0x0, 0x4b, 0xb, 0x20, 0xe, 0x1c, 0x20, 0xe1, + 0x0, 0x4b, 0xb, 0xcb, 0xbf, 0x1c, 0x20, 0xe1, + 0x0, 0x4b, 0x2, 0x63, 0x54, 0x5, 0x10, 0xe1, + 0x0, 0x4b, 0x4, 0xd0, 0x6a, 0x0, 0x0, 0xe1, + 0x0, 0x4b, 0x1d, 0x40, 0xc, 0x30, 0x0, 0xe1, + 0x0, 0x4b, 0x56, 0x0, 0x3, 0x11, 0xff, 0xb0, + + /* U+5099 "備" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xd0, 0x2, 0xd0, 0x5, 0xb0, 0x0, + 0x0, 0x9, 0x79, 0xef, 0xfe, 0xef, 0xfe, 0xd0, + 0x0, 0x1e, 0x0, 0x3, 0xd0, 0x5, 0xb0, 0x0, + 0x0, 0x7c, 0x0, 0x3, 0xd0, 0x5, 0xb0, 0x0, + 0x2, 0xfb, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf5, + 0xc, 0xcb, 0x0, 0x4d, 0x20, 0x0, 0x0, 0x0, + 0xb, 0x4b, 0x5, 0xff, 0xee, 0xee, 0xee, 0x80, + 0x0, 0x4b, 0xae, 0xe3, 0x0, 0xe0, 0x6, 0x90, + 0x0, 0x4b, 0x41, 0xc6, 0x23, 0xe2, 0x28, 0x90, + 0x0, 0x4b, 0x0, 0xcc, 0xab, 0xfa, 0xad, 0x90, + 0x0, 0x4b, 0x0, 0xc3, 0x0, 0xe0, 0x6, 0x90, + 0x0, 0x4b, 0x0, 0xce, 0xdd, 0xfd, 0xde, 0x90, + 0x0, 0x4b, 0x0, 0xc3, 0x0, 0xe0, 0x7, 0x90, + 0x0, 0x4b, 0x0, 0xc3, 0x0, 0xe0, 0x7e, 0x50, + + /* U+50B3 "傳" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe1, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0x6, 0xbc, 0xdd, 0xde, 0xed, 0xdd, 0xd2, + 0x0, 0xe, 0x41, 0x44, 0x49, 0xb4, 0x44, 0x20, + 0x0, 0x6e, 0x4, 0xd5, 0x5a, 0xb5, 0x5b, 0x80, + 0x2, 0xfd, 0x4, 0xea, 0xad, 0xda, 0xad, 0x80, + 0x1d, 0x8d, 0x4, 0xb0, 0x7, 0x90, 0x8, 0x80, + 0x49, 0x2d, 0x3, 0xdb, 0xbd, 0xeb, 0xcd, 0x70, + 0x0, 0x2d, 0x0, 0x0, 0x7, 0x91, 0x7c, 0x10, + 0x0, 0x2d, 0xd, 0xdd, 0xdc, 0xcb, 0xfa, 0xd2, + 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0xf0, 0x30, + 0x0, 0x2d, 0x4e, 0xee, 0xee, 0xee, 0xfe, 0xe4, + 0x0, 0x2d, 0x0, 0x3c, 0x10, 0x0, 0xf0, 0x0, + 0x0, 0x2d, 0x0, 0x4, 0xd0, 0x0, 0xf0, 0x0, + 0x0, 0x2d, 0x0, 0x0, 0x3, 0xee, 0xc0, 0x0, + + /* U+50C5 "僅" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd1, 0x9, 0x60, 0x0, 0xf0, 0x0, + 0x0, 0x6, 0xbb, 0xdf, 0xed, 0xdd, 0xfd, 0xd4, + 0x0, 0xd, 0x40, 0x9, 0x60, 0x0, 0xf0, 0x0, + 0x0, 0x6e, 0x0, 0x8, 0xdc, 0xdc, 0xe0, 0x0, + 0x2, 0xfd, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x1d, 0xbd, 0x0, 0xfc, 0xcd, 0xec, 0xce, 0x80, + 0x4a, 0x2d, 0x0, 0xe0, 0x5, 0xb0, 0x7, 0x80, + 0x0, 0x2d, 0x0, 0xec, 0xcd, 0xfc, 0xcd, 0x80, + 0x0, 0x2d, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x2d, 0x5, 0xdd, 0xde, 0xfd, 0xdd, 0xa0, + 0x0, 0x2d, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0xdd, 0xde, 0xfd, 0xdd, 0x60, + 0x0, 0x2d, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x2d, 0xd, 0xdd, 0xde, 0xfd, 0xdd, 0xd4, + + /* U+50CD "働" */ + 0x0, 0xd, 0x10, 0x13, 0x57, 0xb, 0x30, 0x0, + 0x4, 0xc9, 0xbb, 0xd6, 0x30, 0xb3, 0x0, 0x0, + 0xb5, 0x66, 0x9d, 0x66, 0x1b, 0x30, 0x0, 0x2f, + 0x24, 0x47, 0xc4, 0x4a, 0xed, 0xcb, 0xc, 0xf2, + 0x8b, 0xde, 0xbb, 0x3b, 0x41, 0xf7, 0xbc, 0x2b, + 0x12, 0x90, 0x93, 0xc3, 0xe, 0x92, 0xc2, 0xbb, + 0xce, 0xbe, 0x3d, 0x20, 0xe0, 0xc, 0x2b, 0x12, + 0x90, 0x93, 0xe1, 0x1d, 0x0, 0xc2, 0xbc, 0xce, + 0xbe, 0x3e, 0x2, 0xd0, 0xc, 0x20, 0x4, 0xa0, + 0x3, 0xd0, 0x2c, 0x0, 0xc2, 0xad, 0xef, 0xdd, + 0x98, 0x3, 0xb0, 0xc, 0x20, 0x4, 0xa0, 0xd, + 0x40, 0x5a, 0x0, 0xc3, 0x68, 0xbe, 0xcd, 0xc0, + 0x9, 0x80, 0xc, 0x37, 0x64, 0x20, 0xb3, 0x9f, + 0xe2, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+50CF "像" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd4, 0x5, 0xd1, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xd0, 0x1e, 0xcc, 0xdf, 0x40, 0x0, + 0x0, 0xc, 0x62, 0xd5, 0x0, 0x89, 0x0, 0x0, + 0x0, 0x5e, 0x4e, 0xfd, 0xdd, 0xfd, 0xde, 0xc0, + 0x2, 0xfd, 0x24, 0xe0, 0x3, 0xc0, 0x3, 0xc0, + 0xd, 0xad, 0x0, 0xfa, 0xad, 0xda, 0xac, 0xc0, + 0x9, 0x2d, 0x0, 0x24, 0xeb, 0x22, 0x22, 0x20, + 0x0, 0x2d, 0x2, 0x9d, 0x5c, 0x50, 0x1a, 0x90, + 0x0, 0x2d, 0x9, 0x50, 0x4c, 0xe8, 0xf7, 0x0, + 0x0, 0x2d, 0x0, 0x4a, 0x90, 0xc9, 0x88, 0x0, + 0x0, 0x2d, 0xc, 0xa2, 0x1a, 0xc9, 0x1e, 0x10, + 0x0, 0x2d, 0x0, 0x17, 0xc3, 0x5a, 0x6, 0xd2, + 0x0, 0x2d, 0x1a, 0xd7, 0x0, 0xa8, 0x0, 0x6a, + 0x0, 0x2d, 0x4, 0x0, 0x7e, 0xc1, 0x0, 0x0, + + /* U+50D5 "僕" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc5, 0x70, 0x67, 0xe, 0x3, 0x60, + 0x0, 0x4, 0xe0, 0xa5, 0x67, 0xe, 0xc, 0x40, + 0x0, 0xc, 0x61, 0x46, 0x78, 0x1e, 0x28, 0x10, + 0x0, 0x5e, 0xd, 0xdf, 0xdd, 0xdd, 0xfe, 0xd6, + 0x1, 0xed, 0x0, 0x9, 0x70, 0x1, 0xe1, 0x0, + 0x1d, 0x8d, 0x5, 0xab, 0xea, 0xac, 0xda, 0xa0, + 0x4a, 0x2d, 0x1, 0x22, 0x26, 0xc2, 0x22, 0x20, + 0x0, 0x2d, 0x0, 0x22, 0x26, 0xc2, 0x22, 0x10, + 0x0, 0x2d, 0x0, 0xbb, 0xbc, 0xeb, 0xbb, 0x50, + 0x0, 0x2d, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x2d, 0x1e, 0xee, 0xef, 0xfe, 0xee, 0xe8, + 0x0, 0x2d, 0x0, 0x0, 0x3e, 0x9a, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0x29, 0xd3, 0x6, 0xd6, 0x20, + 0x0, 0x2d, 0xb, 0xc6, 0x0, 0x0, 0x28, 0xe6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+50F9 "價" */ + 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x9c, 0xdd, 0xfd, 0xdf, 0xdd, 0xd4, + 0x0, 0xe, 0x40, 0x0, 0xb2, 0xe, 0x0, 0x0, + 0x0, 0x4e, 0x6, 0xbb, 0xec, 0xbf, 0xbb, 0xa0, + 0x0, 0xbb, 0x8, 0x60, 0xb2, 0xe, 0x1, 0xd0, + 0x4, 0xfb, 0x8, 0xa6, 0xd7, 0x6f, 0x67, 0xd0, + 0xd, 0xbb, 0x2, 0x55, 0x55, 0x55, 0x55, 0x40, + 0x5b, 0x4b, 0x2, 0xdb, 0xbb, 0xbb, 0xbc, 0x90, + 0x1, 0x4b, 0x2, 0xd0, 0x0, 0x0, 0x5, 0xa0, + 0x0, 0x4b, 0x2, 0xfb, 0xbb, 0xbb, 0xbd, 0xa0, + 0x0, 0x4b, 0x2, 0xe6, 0x66, 0x66, 0x69, 0xa0, + 0x0, 0x4b, 0x2, 0xe4, 0x44, 0x44, 0x48, 0xa0, + 0x0, 0x4b, 0x2, 0xeb, 0xbb, 0xbb, 0xbc, 0x90, + 0x0, 0x4b, 0x0, 0x29, 0xa0, 0x7, 0xb5, 0x0, + 0x0, 0x4b, 0x1c, 0xa4, 0x0, 0x0, 0x17, 0xd3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5104 "億" */ + 0x0, 0x0, 0x21, 0x0, 0x5, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xd4, 0x0, 0x8, 0x80, 0x0, 0x0, + 0x0, 0x5, 0xc5, 0xdd, 0xde, 0xfd, 0xdd, 0xd0, + 0x0, 0xc, 0x50, 0x8, 0x50, 0x1, 0xd0, 0x0, + 0x0, 0x5e, 0x16, 0x69, 0xb6, 0x6a, 0xc6, 0x64, + 0x1, 0xed, 0x6, 0x66, 0x66, 0x66, 0x66, 0x64, + 0xb, 0xbd, 0x0, 0x8b, 0xbb, 0xbb, 0xbb, 0x30, + 0xb, 0x2d, 0x0, 0xb4, 0x0, 0x0, 0xc, 0x40, + 0x0, 0x2d, 0x0, 0xbc, 0xaa, 0xaa, 0xae, 0x40, + 0x0, 0x2d, 0x0, 0xb4, 0x0, 0x0, 0xc, 0x40, + 0x0, 0x2d, 0x0, 0xac, 0xbc, 0xbb, 0xbd, 0x30, + 0x0, 0x2d, 0x0, 0x33, 0x4c, 0x80, 0x6, 0x0, + 0x0, 0x2d, 0x5, 0x98, 0x70, 0x85, 0xa, 0x80, + 0x0, 0x2d, 0xd, 0x28, 0x70, 0x0, 0x85, 0xe3, + 0x0, 0x2d, 0x6, 0x4, 0xee, 0xee, 0xd2, 0x42, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+512A "優" */ + 0x0, 0x2, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x8c, 0xdd, 0xdf, 0xed, 0xdd, 0xd1, + 0x0, 0xe, 0x30, 0x12, 0x2d, 0x62, 0x21, 0x0, + 0x0, 0x5e, 0x0, 0xbb, 0x99, 0x99, 0xac, 0x0, + 0x0, 0xcb, 0x0, 0xbb, 0x99, 0x99, 0xac, 0x0, + 0x5, 0xfb, 0x0, 0xb7, 0x44, 0x44, 0x6c, 0x0, + 0x1e, 0xab, 0x0, 0xb8, 0x55, 0x55, 0x7c, 0x0, + 0x4b, 0x4b, 0x3d, 0xcb, 0xbe, 0xbb, 0xbc, 0xd4, + 0x1, 0x4b, 0x49, 0x56, 0x65, 0xb0, 0x46, 0xa5, + 0x0, 0x4b, 0x8, 0xc4, 0xc5, 0x58, 0x7a, 0x91, + 0x0, 0x4b, 0x4, 0x2, 0xe7, 0x54, 0x0, 0x50, + 0x0, 0x4b, 0x0, 0x7f, 0xcb, 0xbb, 0xe7, 0x0, + 0x0, 0x4b, 0x2d, 0x78, 0xc2, 0x2a, 0x90, 0x0, + 0x0, 0x4b, 0x0, 0x3, 0xbf, 0xfb, 0x42, 0x0, + 0x0, 0x4b, 0x4d, 0xc9, 0x51, 0x16, 0xad, 0xe3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+513F "儿" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0x4, 0xd0, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0x8, 0xa0, 0x0, 0x0, 0xf1, 0x0, 0x30, + 0x0, 0x1e, 0x40, 0x0, 0x0, 0xf1, 0x0, 0xc3, + 0x0, 0x9b, 0x0, 0x0, 0x0, 0xf1, 0x0, 0xd2, + 0x7, 0xe2, 0x0, 0x0, 0x0, 0xe4, 0x1, 0xf0, + 0x4d, 0x20, 0x0, 0x0, 0x0, 0x9f, 0xff, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5143 "元" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xfa, 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, + 0xd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xd0, + 0x2, 0x22, 0x2f, 0x52, 0x2a, 0x92, 0x22, 0x20, + 0x0, 0x0, 0x1f, 0x10, 0x9, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x0, 0x9, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x8a, 0x0, 0x9, 0x70, 0x0, 0x0, + 0x0, 0x0, 0xe5, 0x0, 0x9, 0x70, 0x0, 0xa2, + 0x0, 0x9, 0xc0, 0x0, 0x9, 0x70, 0x0, 0xc3, + 0x1, 0x9e, 0x10, 0x0, 0x9, 0x90, 0x1, 0xe1, + 0xe, 0xb2, 0x0, 0x0, 0x4, 0xef, 0xff, 0x90, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5144 "兄" */ + 0x0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x3e, 0x0, + 0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0x1, 0x1b, 0x91, 0x15, 0xc1, 0x11, 0x0, + 0x0, 0x0, 0xc, 0x60, 0x4, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x1f, 0x30, 0x4, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x7d, 0x0, 0x4, 0xc0, 0x0, 0x36, + 0x0, 0x3, 0xf5, 0x0, 0x4, 0xc0, 0x0, 0x5a, + 0x0, 0x7f, 0x70, 0x0, 0x4, 0xd0, 0x0, 0x98, + 0xd, 0xc4, 0x0, 0x0, 0x1, 0xdf, 0xff, 0xe2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5145 "充" */ + 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xd1, 0x0, 0x0, 0x0, + 0xd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x1, 0x11, 0x1b, 0xc1, 0x11, 0x21, 0x11, 0x10, + 0x0, 0x0, 0x6e, 0x10, 0x2, 0xe3, 0x0, 0x0, + 0x0, 0x3, 0xf4, 0x0, 0x0, 0x5f, 0x50, 0x0, + 0x0, 0x3e, 0x71, 0x22, 0x34, 0x5a, 0xf5, 0x0, + 0x0, 0xdf, 0xff, 0xfd, 0xcf, 0xca, 0x9f, 0x30, + 0x0, 0x21, 0x8, 0x90, 0xc, 0x50, 0x5, 0x20, + 0x0, 0x0, 0xb, 0x60, 0xc, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x1f, 0x20, 0xc, 0x50, 0x0, 0x40, + 0x0, 0x0, 0xab, 0x0, 0xc, 0x50, 0x0, 0xc3, + 0x0, 0x2b, 0xd1, 0x0, 0xc, 0x60, 0x0, 0xf1, + 0xa, 0xfa, 0x10, 0x0, 0x7, 0xff, 0xff, 0xa0, + 0x3, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5148 "先" */ + 0x0, 0x0, 0x90, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xa0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0xb, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x0, + 0x0, 0x3d, 0x11, 0x19, 0x91, 0x11, 0x11, 0x0, + 0x0, 0xd4, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x1, 0x80, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x4, 0x44, 0x44, 0x4a, 0xa4, 0x44, 0x44, 0x40, + 0xc, 0xcc, 0xcf, 0xdc, 0xce, 0xec, 0xcc, 0xc0, + 0x0, 0x0, 0xe, 0x30, 0x7, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x1f, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x7b, 0x0, 0x7, 0x90, 0x0, 0x20, + 0x0, 0x2, 0xe4, 0x0, 0x7, 0x90, 0x0, 0xc3, + 0x0, 0x5e, 0x70, 0x0, 0x7, 0xa0, 0x0, 0xe1, + 0xd, 0xd5, 0x0, 0x0, 0x3, 0xef, 0xff, 0xa0, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5149 "光" */ + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x12, 0x0, + 0x0, 0x8a, 0x0, 0x9, 0x70, 0x0, 0x9a, 0x0, + 0x0, 0xe, 0x40, 0x9, 0x70, 0x1, 0xf2, 0x0, + 0x0, 0x6, 0xc0, 0x9, 0x70, 0xa, 0x80, 0x0, + 0x0, 0x0, 0xc1, 0x9, 0x70, 0x1c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0xd, 0x40, 0x8, 0x80, 0x0, 0x0, + 0x0, 0x0, 0xf, 0x10, 0x8, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x4e, 0x0, 0x8, 0x80, 0x0, 0x0, + 0x0, 0x0, 0xb7, 0x0, 0x8, 0x80, 0x0, 0x41, + 0x0, 0x8, 0xd1, 0x0, 0x8, 0x80, 0x0, 0xb4, + 0x2, 0xae, 0x20, 0x0, 0x8, 0x90, 0x0, 0xe2, + 0x2d, 0x80, 0x0, 0x0, 0x4, 0xef, 0xff, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+514B "克" */ + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0xd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0xee, 0xef, 0xfe, 0xee, 0xe2, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, + 0x0, 0x1e, 0xef, 0xfe, 0xef, 0xfe, 0xe2, 0x0, + 0x0, 0x0, 0xa, 0x70, 0xd, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x1f, 0x30, 0xd, 0x30, 0x0, 0x10, + 0x0, 0x0, 0xab, 0x0, 0xd, 0x30, 0x0, 0xb4, + 0x0, 0x5d, 0xc1, 0x0, 0xd, 0x50, 0x1, 0xe2, + 0x1e, 0xc7, 0x0, 0x0, 0x8, 0xff, 0xff, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+514D "免" */ + 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9f, 0xee, 0xef, 0xd0, 0x0, 0x0, + 0x0, 0x7, 0xd1, 0x0, 0xc, 0x50, 0x0, 0x0, + 0x0, 0x9f, 0x42, 0x22, 0x9c, 0x22, 0x22, 0x0, + 0xa, 0xff, 0xcc, 0xcd, 0xfc, 0xcc, 0xcf, 0x30, + 0x5, 0x5c, 0x0, 0x6, 0xc0, 0x0, 0xe, 0x30, + 0x0, 0x4c, 0x0, 0x8, 0xa0, 0x0, 0xe, 0x30, + 0x0, 0x4d, 0x33, 0x3b, 0xa3, 0x33, 0x3f, 0x30, + 0x0, 0x3b, 0xbb, 0xbf, 0xcf, 0xcb, 0xbb, 0x20, + 0x0, 0x0, 0x0, 0x5d, 0xf, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xe5, 0xf, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x2d, 0x90, 0xf, 0x10, 0x0, 0x95, + 0x0, 0x39, 0xf7, 0x0, 0xf, 0x20, 0x0, 0xc4, + 0xa, 0xe8, 0x20, 0x0, 0xa, 0xff, 0xff, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5152 "兒" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x38, 0xe6, 0x1, 0x11, 0x11, 0x0, + 0x0, 0x2e, 0xa6, 0x10, 0xd, 0xee, 0xee, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x3f, 0xee, 0xe5, 0xd, 0xee, 0xee, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0x0, 0x2, 0xf0, 0xe, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x5, 0xd0, 0xe, 0x20, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x80, 0xe, 0x20, 0x0, 0x21, + 0x0, 0x0, 0x5f, 0x10, 0xe, 0x20, 0x0, 0x87, + 0x0, 0x18, 0xe3, 0x0, 0xe, 0x30, 0x0, 0xa5, + 0xa, 0xe9, 0x10, 0x0, 0x9, 0xed, 0xdd, 0xc1, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+515A "党" */ + 0x0, 0x9, 0x10, 0xe, 0x20, 0x0, 0xb2, 0x0, + 0x0, 0x7, 0xb0, 0xe, 0x20, 0x8, 0xb0, 0x0, + 0x2, 0x22, 0xc4, 0x2e, 0x52, 0x5e, 0x32, 0x20, + 0xe, 0xdc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, 0xd0, + 0xe, 0x10, 0x0, 0x0, 0x0, 0x0, 0x3, 0xd0, + 0xe, 0x13, 0xfe, 0xee, 0xee, 0xef, 0x23, 0xd0, + 0x0, 0x3, 0xd0, 0x0, 0x0, 0xf, 0x20, 0x0, + 0x0, 0x3, 0xd0, 0x0, 0x0, 0xf, 0x20, 0x0, + 0x0, 0x3, 0xfc, 0xcc, 0xcc, 0xcf, 0x20, 0x0, + 0x0, 0x0, 0x28, 0xa2, 0x7d, 0x22, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x40, 0x5c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8c, 0x0, 0x5c, 0x0, 0x0, 0xa3, + 0x1, 0x5c, 0xc1, 0x0, 0x5d, 0x0, 0x0, 0xd3, + 0x2f, 0xb6, 0x0, 0x0, 0x1d, 0xff, 0xff, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5165 "入" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8, 0xe3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7e, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0xf3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3f, 0x8b, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8a, 0xe, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xe5, 0x7, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x8, 0xd0, 0x0, 0xe6, 0x0, 0x0, + 0x0, 0x0, 0x2f, 0x40, 0x0, 0x6e, 0x0, 0x0, + 0x0, 0x1, 0xda, 0x0, 0x0, 0xc, 0xa0, 0x0, + 0x0, 0x1c, 0xc0, 0x0, 0x0, 0x1, 0xe9, 0x0, + 0x4, 0xec, 0x10, 0x0, 0x0, 0x0, 0x3e, 0xc1, + 0x1e, 0x80, 0x0, 0x0, 0x0, 0x0, 0x1, 0xc2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5167 "內" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xe1, 0x0, 0x0, 0x0, 0x2f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf2, 0x2e, 0x11, 0x11, 0xee, 0x21, + 0x11, 0xe2, 0x2e, 0x0, 0x3, 0xca, 0x60, 0x0, + 0xe2, 0x2e, 0x0, 0xb, 0x64, 0xd0, 0x0, 0xe2, + 0x2e, 0x0, 0x5d, 0x0, 0xd7, 0x0, 0xe2, 0x2e, + 0x5, 0xe3, 0x0, 0x3f, 0x70, 0xe2, 0x2e, 0x8e, + 0x30, 0x0, 0x4, 0xd8, 0xe2, 0x2e, 0x10, 0x0, + 0x0, 0x0, 0x0, 0xe2, 0x2e, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x2e, 0x0, 0x0, 0x0, 0x1, + 0x11, 0xf1, 0x2e, 0x0, 0x0, 0x0, 0x6, 0xff, + 0xb0, + + /* U+5168 "全" */ + 0x0, 0x0, 0x0, 0x4, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1e, 0xe3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xd6, 0x4e, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x1d, 0x60, 0x4, 0xe4, 0x0, 0x0, + 0x0, 0x4, 0xe6, 0x0, 0x0, 0x3e, 0x80, 0x0, + 0x1, 0x9d, 0x40, 0x0, 0x0, 0x2, 0xcd, 0x30, + 0x3f, 0x89, 0xbb, 0xbb, 0xbb, 0xbb, 0xb7, 0xf5, + 0x2, 0x3, 0x44, 0x4a, 0xb4, 0x44, 0x40, 0x20, + 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xee, 0xef, 0xfe, 0xee, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, + 0xb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + + /* U+5169 "兩" */ + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0xa7, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9, 0x60, 0x0, 0x0, 0x0, 0x3, + 0x33, 0x33, 0xb8, 0x33, 0x33, 0x30, 0x2, 0xfc, + 0xcc, 0xce, 0xdc, 0xcc, 0xcf, 0x20, 0x2d, 0x0, + 0x0, 0x96, 0x0, 0x0, 0xe2, 0x2, 0xd0, 0xb2, + 0x9, 0x61, 0xc0, 0xe, 0x20, 0x2d, 0x6, 0xa0, + 0x96, 0xb, 0x40, 0xe2, 0x2, 0xd0, 0xae, 0x29, + 0x60, 0xec, 0xe, 0x20, 0x2d, 0xd, 0x68, 0x96, + 0x49, 0xb3, 0xe2, 0x2, 0xd7, 0x71, 0xe9, 0x6c, + 0x36, 0x8e, 0x20, 0x2d, 0x80, 0x6, 0xa7, 0x70, + 0x17, 0xe2, 0x2, 0xd0, 0x0, 0x9, 0x60, 0x0, + 0xe, 0x20, 0x2d, 0x0, 0x0, 0x11, 0x0, 0xee, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+516B "八" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x10, 0x7, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x2f, 0x0, 0x6, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x0, 0x3, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x5c, 0x0, 0x1, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x89, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0x0, 0xc5, 0x0, 0x0, 0xa6, 0x0, 0x0, + 0x0, 0x0, 0xf2, 0x0, 0x0, 0x6b, 0x0, 0x0, + 0x0, 0x5, 0xd0, 0x0, 0x0, 0x1f, 0x10, 0x0, + 0x0, 0xb, 0x70, 0x0, 0x0, 0xa, 0x80, 0x0, + 0x0, 0x2f, 0x0, 0x0, 0x0, 0x3, 0xf2, 0x0, + 0x0, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x9b, 0x0, + 0xa, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x90, + 0x2d, 0x10, 0x0, 0x0, 0x0, 0x0, 0x1, 0xd5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+516C "公" */ + 0x0, 0x0, 0x9, 0x20, 0x3, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x6e, 0x0, 0x0, 0xd5, 0x0, 0x0, + 0x0, 0x0, 0xe5, 0x0, 0x0, 0x4e, 0x10, 0x0, + 0x0, 0x8, 0xc0, 0x0, 0x0, 0xa, 0xb0, 0x0, + 0x0, 0x4f, 0x30, 0x1, 0x0, 0x1, 0xe8, 0x0, + 0x3, 0xe7, 0x0, 0xe, 0x60, 0x0, 0x2f, 0x80, + 0xd, 0x80, 0x0, 0x8d, 0x0, 0x0, 0x4, 0xe2, + 0x0, 0x0, 0x2, 0xf4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0xb0, 0x0, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x5e, 0x10, 0x0, 0xaa, 0x0, 0x0, + 0x0, 0x2, 0xe4, 0x0, 0x0, 0xd, 0x70, 0x0, + 0x0, 0x1d, 0x81, 0x23, 0x34, 0x59, 0xf3, 0x0, + 0x0, 0xaf, 0xff, 0xfe, 0xdc, 0xba, 0xbd, 0x0, + 0x0, 0x23, 0x10, 0x0, 0x0, 0x0, 0xd, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + + /* U+516D "六" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3f, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5, 0xf0, 0x0, 0x0, 0x0, + 0x2, 0x22, 0x22, 0x22, 0x62, 0x22, 0x22, 0x20, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x5d, 0x0, 0x0, 0xe4, 0x0, 0x0, + 0x0, 0x0, 0xd7, 0x0, 0x0, 0x6e, 0x10, 0x0, + 0x0, 0x7, 0xe0, 0x0, 0x0, 0xb, 0xa0, 0x0, + 0x0, 0x1e, 0x50, 0x0, 0x0, 0x1, 0xf5, 0x0, + 0x0, 0xbb, 0x0, 0x0, 0x0, 0x0, 0x6e, 0x10, + 0x7, 0xf1, 0x0, 0x0, 0x0, 0x0, 0xc, 0xa0, + 0x1e, 0x40, 0x0, 0x0, 0x0, 0x0, 0x3, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5171 "共" */ + 0x0, 0x0, 0x4c, 0x0, 0x0, 0x79, 0x0, 0x0, + 0x0, 0x0, 0x4c, 0x0, 0x0, 0x79, 0x0, 0x0, + 0x0, 0x0, 0x4c, 0x0, 0x0, 0x79, 0x0, 0x0, + 0x6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, + 0x0, 0x0, 0x5c, 0x0, 0x0, 0x8a, 0x0, 0x0, + 0x0, 0x0, 0x4c, 0x0, 0x0, 0x79, 0x0, 0x0, + 0x0, 0x0, 0x4c, 0x0, 0x0, 0x79, 0x0, 0x0, + 0x0, 0x0, 0x5c, 0x0, 0x0, 0x79, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1c, 0x30, 0x1, 0xc4, 0x0, 0x0, + 0x0, 0x2, 0xd8, 0x0, 0x0, 0x4e, 0x80, 0x0, + 0x0, 0x6e, 0x70, 0x0, 0x0, 0x2, 0xdb, 0x0, + 0x8, 0xd3, 0x0, 0x0, 0x0, 0x0, 0xb, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5176 "其" */ + 0x0, 0x1, 0xe0, 0x0, 0x0, 0xe, 0x10, 0x0, + 0x2, 0x45, 0xf4, 0x44, 0x44, 0x4f, 0x54, 0x30, + 0x7, 0xbc, 0xfb, 0xbb, 0xbb, 0xbf, 0xcb, 0x80, + 0x0, 0x1, 0xe0, 0x0, 0x0, 0xe, 0x10, 0x0, + 0x0, 0x1, 0xfe, 0xee, 0xee, 0xef, 0x10, 0x0, + 0x0, 0x1, 0xe0, 0x0, 0x0, 0xe, 0x10, 0x0, + 0x0, 0x1, 0xe0, 0x0, 0x0, 0xe, 0x10, 0x0, + 0x0, 0x1, 0xfe, 0xee, 0xee, 0xef, 0x10, 0x0, + 0x0, 0x1, 0xe0, 0x0, 0x0, 0xe, 0x10, 0x0, + 0x0, 0x2, 0xe0, 0x0, 0x0, 0xf, 0x20, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x0, 0x8, 0x40, 0x4, 0x71, 0x0, 0x0, + 0x0, 0x28, 0xe9, 0x10, 0x2, 0x8e, 0xa3, 0x0, + 0xb, 0xe8, 0x20, 0x0, 0x0, 0x0, 0x6e, 0xa0, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+5177 "具" */ + 0x0, 0x9, 0xfe, 0xee, 0xee, 0xee, 0xc0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x3, 0xc0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x4, 0xc0, 0x0, + 0x0, 0x9, 0xec, 0xcc, 0xcc, 0xcd, 0xc0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x3, 0xc0, 0x0, + 0x0, 0x9, 0xed, 0xdd, 0xdd, 0xdd, 0xc0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x3, 0xc0, 0x0, + 0x0, 0x9, 0xed, 0xdd, 0xdd, 0xdd, 0xc0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x3, 0xc0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x4, 0xd0, 0x0, + 0x2e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe2, + 0x0, 0x0, 0x4b, 0x10, 0x0, 0xb6, 0x0, 0x0, + 0x0, 0x2a, 0xe4, 0x0, 0x0, 0x3b, 0xe6, 0x0, + 0x1a, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x4d, 0xc1, + 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, + + /* U+5185 "内" */ + 0x0, 0x0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x2e, 0xee, + 0xee, 0xef, 0xee, 0xee, 0xec, 0x2e, 0x22, 0x22, + 0x7c, 0x22, 0x22, 0x5d, 0x2e, 0x0, 0x0, 0x79, + 0x0, 0x0, 0x3d, 0x2e, 0x0, 0x0, 0xbb, 0x0, + 0x0, 0x3d, 0x2e, 0x0, 0x2, 0xfa, 0xb0, 0x0, + 0x3d, 0x2e, 0x0, 0xc, 0x80, 0x9d, 0x10, 0x3d, + 0x2e, 0x0, 0x9c, 0x0, 0x8, 0xd1, 0x3d, 0x2e, + 0x2c, 0xc1, 0x0, 0x0, 0x8d, 0x4d, 0x2e, 0x27, + 0x0, 0x0, 0x0, 0x5, 0x3d, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3d, 0x2e, 0x0, 0x0, 0x0, + 0x0, 0x21, 0x5d, 0x2e, 0x0, 0x0, 0x0, 0x1, + 0xff, 0xd6, + + /* U+5186 "円" */ + 0x1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x4f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x4c, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x2e, 0x4c, 0x0, 0x0, + 0x2e, 0x0, 0x0, 0x2e, 0x4c, 0x0, 0x0, 0x2e, + 0x0, 0x0, 0x2e, 0x4c, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x2e, 0x4d, 0x33, 0x33, 0x5f, 0x33, 0x33, + 0x5e, 0x4f, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xee, + 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x4c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x4c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2e, 0x4c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2e, 0x4c, 0x0, 0x0, 0x0, + 0x0, 0x11, 0x5e, 0x4c, 0x0, 0x0, 0x0, 0x0, + 0xbf, 0xe8, + + /* U+518A "冊" */ + 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, + 0x0, 0x88, 0x1, 0xf0, 0x8, 0x80, 0xe, 0x20, + 0x0, 0x88, 0x0, 0xf0, 0x7, 0x80, 0xe, 0x20, + 0x0, 0x88, 0x0, 0xf0, 0x7, 0x80, 0xe, 0x20, + 0x0, 0x88, 0x0, 0xf0, 0x7, 0x80, 0xe, 0x20, + 0x0, 0x88, 0x0, 0xf0, 0x7, 0x80, 0xe, 0x20, + 0x1d, 0xee, 0xdd, 0xfd, 0xde, 0xed, 0xdf, 0xd7, + 0x3, 0xaa, 0x33, 0xf3, 0x39, 0x93, 0x3e, 0x52, + 0x0, 0x88, 0x0, 0xf0, 0x7, 0x80, 0xe, 0x20, + 0x0, 0x88, 0x0, 0xf0, 0x7, 0x80, 0xe, 0x20, + 0x0, 0x88, 0x0, 0xf0, 0x7, 0x80, 0xe, 0x20, + 0x0, 0x88, 0x0, 0xf0, 0x7, 0x80, 0xe, 0x20, + 0x0, 0x88, 0x0, 0xf0, 0x7, 0x80, 0x1e, 0x20, + 0x0, 0x88, 0x0, 0xf0, 0x7, 0x87, 0xfc, 0x0, + + /* U+518D "再" */ + 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x0, + 0x0, 0x3d, 0x0, 0x6, 0xb0, 0x0, 0x79, 0x0, + 0x0, 0x3d, 0x0, 0x6, 0xb0, 0x0, 0x69, 0x0, + 0x0, 0x3f, 0xee, 0xef, 0xfe, 0xee, 0xf9, 0x0, + 0x0, 0x3d, 0x0, 0x6, 0xb0, 0x0, 0x69, 0x0, + 0x0, 0x3d, 0x0, 0x6, 0xb0, 0x0, 0x69, 0x0, + 0x1d, 0xef, 0xdd, 0xde, 0xfd, 0xdd, 0xef, 0xd8, + 0x1, 0x4d, 0x11, 0x11, 0x11, 0x11, 0x8a, 0x11, + 0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x69, 0x0, + 0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x89, 0x0, + 0x0, 0x3d, 0x0, 0x0, 0x0, 0xef, 0xe4, 0x0, + + /* U+5199 "写" */ + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xe2, + 0x4, 0x50, 0x0, 0x0, 0x0, 0xc4, 0xe2, 0x9, + 0x80, 0x0, 0x0, 0x0, 0xc4, 0x0, 0xc, 0x60, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xee, 0xee, + 0xee, 0xe5, 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6b, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9e, 0xee, 0xee, 0xee, 0xfc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7a, 0x0, 0x11, + 0x11, 0x11, 0x11, 0x10, 0x99, 0x0, 0xad, 0xdd, + 0xdd, 0xdd, 0xd2, 0xb6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xff, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+519B "军" */ + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xb4, + 0x0, 0x5, 0x0, 0x0, 0x0, 0x4c, 0xb4, 0x0, + 0x4e, 0x0, 0x0, 0x0, 0x4c, 0x31, 0x0, 0x9a, + 0x0, 0x0, 0x0, 0x13, 0x1, 0xee, 0xfe, 0xee, + 0xee, 0xee, 0x10, 0x0, 0x7, 0x90, 0xa, 0x0, + 0x0, 0x0, 0x0, 0x1d, 0x0, 0xf, 0x10, 0x0, + 0x0, 0x0, 0xcd, 0xbb, 0xbf, 0xbb, 0xbb, 0x60, + 0x0, 0x44, 0x33, 0x3f, 0x43, 0x33, 0x20, 0x0, + 0x0, 0x0, 0xf, 0x10, 0x0, 0x0, 0x23, 0x33, + 0x33, 0x3f, 0x43, 0x33, 0x33, 0x9c, 0xcc, 0xcc, + 0xcf, 0xcc, 0xcc, 0xcb, 0x0, 0x0, 0x0, 0xf, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x10, + 0x0, 0x0, + + /* U+51AC "冬" */ + 0x0, 0x0, 0x0, 0x81, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3f, 0xff, 0xff, 0xff, 0x70, 0x0, + 0x0, 0x2, 0xe9, 0x0, 0x0, 0x5d, 0x10, 0x0, + 0x0, 0x4e, 0x6d, 0x50, 0x4, 0xe3, 0x0, 0x0, + 0x5, 0xe3, 0x1, 0xd7, 0x8e, 0x30, 0x0, 0x0, + 0x0, 0x20, 0x0, 0x5f, 0xf5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5d, 0xd5, 0x5d, 0xc5, 0x0, 0x0, + 0x6, 0xbf, 0xc5, 0x0, 0x0, 0x6c, 0xfc, 0x81, + 0xa, 0x61, 0x2, 0xd8, 0x30, 0x0, 0x15, 0x80, + 0x0, 0x0, 0x0, 0x28, 0xdd, 0x81, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x0, 0x3, 0x91, 0x0, 0x0, + 0x0, 0x2, 0xec, 0x84, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0x8d, 0xfa, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x27, 0xdb, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+51B7 "冷" */ + 0x0, 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, + 0x8, 0x0, 0x0, 0x0, 0x1f, 0x60, 0x0, 0x0, + 0xa, 0xa0, 0x0, 0x0, 0xbb, 0xe1, 0x0, 0x0, + 0x0, 0xe4, 0x0, 0x8, 0xc0, 0x5c, 0x0, 0x0, + 0x0, 0x6b, 0x0, 0x9d, 0x10, 0x8, 0xc1, 0x0, + 0x0, 0x0, 0x1c, 0xc1, 0x3a, 0x0, 0x9d, 0x30, + 0x0, 0x0, 0xba, 0x0, 0xa, 0x90, 0x7, 0xe0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x30, 0x0, 0x0, + 0x0, 0x4, 0x4, 0xff, 0xff, 0xff, 0xf9, 0x0, + 0x0, 0x5c, 0x0, 0x11, 0x11, 0x13, 0xe3, 0x0, + 0x0, 0xc6, 0x0, 0x0, 0x0, 0xc, 0x70, 0x0, + 0x3, 0xf0, 0x0, 0x7, 0x20, 0xba, 0x0, 0x0, + 0xa, 0x90, 0x0, 0x6, 0xec, 0xb0, 0x0, 0x0, + 0x2f, 0x20, 0x0, 0x0, 0x2c, 0xa0, 0x0, 0x0, + 0x4, 0x0, 0x0, 0x0, 0x0, 0xaa, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + + /* U+51CD "凍" */ + 0x1, 0x0, 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, + 0xe, 0x60, 0x7e, 0xee, 0xef, 0xfe, 0xee, 0xe1, + 0x3, 0xe6, 0x0, 0x0, 0xc, 0x50, 0x0, 0x0, + 0x0, 0x4b, 0x1, 0x22, 0x2c, 0x62, 0x22, 0x0, + 0x0, 0x0, 0xa, 0xca, 0xae, 0xca, 0xae, 0x40, + 0x0, 0x0, 0xa, 0x50, 0xb, 0x40, 0xb, 0x40, + 0x0, 0x0, 0xa, 0xec, 0xcf, 0xdc, 0xcf, 0x40, + 0x0, 0xd, 0x1a, 0x50, 0xb, 0x40, 0xb, 0x40, + 0x0, 0x8a, 0xa, 0xed, 0xdf, 0xed, 0xdf, 0x40, + 0x2, 0xf2, 0x0, 0x3, 0xee, 0xd7, 0x0, 0x0, + 0xb, 0x80, 0x0, 0x3e, 0x3b, 0x5c, 0x60, 0x0, + 0x3e, 0x0, 0x6, 0xe4, 0xb, 0x41, 0xd8, 0x0, + 0x0, 0x2, 0xdc, 0x20, 0xb, 0x40, 0x1b, 0xd2, + 0x0, 0x0, 0x50, 0x0, 0xb, 0x40, 0x0, 0x50, + + /* U+51DD "凝" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x0, 0x68, 0x6, 0x76, 0xee, 0xee, 0xf2, + 0xd, 0x90, 0x6d, 0xe9, 0x20, 0x0, 0xa, 0x80, + 0x1, 0xd8, 0x7a, 0x0, 0x31, 0xa9, 0x8b, 0x0, + 0x0, 0x29, 0x6a, 0x22, 0xa4, 0x8, 0xf4, 0x0, + 0x0, 0x0, 0x1c, 0xcc, 0x90, 0x0, 0x4c, 0x0, + 0x0, 0x0, 0xe, 0x0, 0x8, 0xcc, 0xcc, 0xc5, + 0x0, 0x0, 0x6f, 0xfe, 0xe0, 0x0, 0xe0, 0xa3, + 0x0, 0x24, 0xd2, 0xb3, 0x1, 0x80, 0xe0, 0x80, + 0x0, 0x98, 0x20, 0xb3, 0x4, 0xb0, 0xe2, 0x20, + 0x0, 0xe1, 0xee, 0xfe, 0xe9, 0xa0, 0xfb, 0xb3, + 0x7, 0xa0, 0x0, 0xe5, 0x7, 0xd0, 0xe0, 0x0, + 0xe, 0x30, 0x5, 0xbd, 0x4a, 0xd4, 0xe0, 0x0, + 0x29, 0x0, 0x2e, 0x22, 0x9d, 0x2d, 0xe0, 0x0, + 0x0, 0x2, 0xd3, 0x0, 0x86, 0x2, 0xbf, 0xf8, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+51E6 "処" */ + 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4c, 0x0, 0x0, 0x57, 0x77, 0x60, 0x0, + 0x0, 0x7a, 0x0, 0x0, 0xb9, 0x78, 0xc0, 0x0, + 0x0, 0xbf, 0xdd, 0xb0, 0xb4, 0x2, 0xc0, 0x0, + 0x0, 0xe3, 0x5, 0xb0, 0xb4, 0x2, 0xc0, 0x0, + 0x2, 0xf0, 0x7, 0x90, 0xc3, 0x2, 0xc0, 0x0, + 0x8, 0xf3, 0xa, 0x60, 0xd1, 0x2, 0xc0, 0x0, + 0x1e, 0x97, 0xe, 0x20, 0xe0, 0x2, 0xc0, 0x0, + 0x8a, 0x2d, 0x3d, 0x1, 0xe0, 0x2, 0xc0, 0x0, + 0x11, 0xb, 0xd7, 0x5, 0xa0, 0x2, 0xc0, 0x0, + 0x0, 0x4, 0xf2, 0xc, 0x50, 0x2, 0xc2, 0xa0, + 0x0, 0xa, 0xea, 0x2d, 0x0, 0x1, 0xdd, 0x50, + 0x0, 0x5d, 0x1b, 0xa2, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xe3, 0x0, 0x9e, 0x94, 0x21, 0x0, 0x0, + 0x3e, 0x40, 0x0, 0x2, 0x8c, 0xef, 0xff, 0xf0, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+51FA "出" */ + 0x0, 0x0, 0x0, 0x5c, 0x0, 0x0, 0x0, 0x6, + 0x60, 0x0, 0x5c, 0x0, 0x2, 0xa0, 0x8, 0x90, + 0x0, 0x5c, 0x0, 0x3, 0xe0, 0x8, 0x90, 0x0, + 0x5c, 0x0, 0x3, 0xe0, 0x8, 0x90, 0x0, 0x5c, + 0x0, 0x3, 0xe0, 0x8, 0xb4, 0x44, 0x8d, 0x44, + 0x47, 0xe0, 0x6, 0xbb, 0xbb, 0xdf, 0xbb, 0xbb, + 0xa0, 0x29, 0x0, 0x0, 0x5c, 0x0, 0x0, 0x65, + 0x3e, 0x0, 0x0, 0x5c, 0x0, 0x0, 0x98, 0x3e, + 0x0, 0x0, 0x5c, 0x0, 0x0, 0x98, 0x3e, 0x0, + 0x0, 0x5c, 0x0, 0x0, 0x98, 0x3e, 0x0, 0x0, + 0x5c, 0x0, 0x0, 0x98, 0x3f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf8, 0x1, 0x11, 0x11, 0x11, 0x11, + 0x11, 0xa8, + + /* U+5206 "分" */ + 0x0, 0x0, 0xb, 0x20, 0x1, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x8c, 0x0, 0x0, 0xa7, 0x0, 0x0, + 0x0, 0x1, 0xf3, 0x0, 0x0, 0x1e, 0x20, 0x0, + 0x0, 0xa, 0xa0, 0x0, 0x0, 0x7, 0xd0, 0x0, + 0x0, 0x6e, 0x10, 0x0, 0x0, 0x0, 0xbb, 0x0, + 0x6, 0xf5, 0x11, 0x11, 0x11, 0x11, 0x2d, 0xb0, + 0xc, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xe1, 0xa0, + 0x0, 0x0, 0x0, 0xf2, 0x0, 0x3, 0xd0, 0x0, + 0x0, 0x0, 0x3, 0xe0, 0x0, 0x4, 0xd0, 0x0, + 0x0, 0x0, 0x8, 0xa0, 0x0, 0x5, 0xb0, 0x0, + 0x0, 0x0, 0x1f, 0x20, 0x0, 0x7, 0xa0, 0x0, + 0x0, 0x1, 0xd9, 0x0, 0x0, 0x9, 0x80, 0x0, + 0x0, 0x4d, 0xa0, 0x0, 0x10, 0x1e, 0x50, 0x0, + 0x9, 0xd6, 0x0, 0x0, 0xef, 0xfb, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5207 "切" */ + 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0xf, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0x2d, 0x0, 0x0, 0x5, 0xc0, 0x0, 0xe2, + 0x0, 0x2d, 0x26, 0x90, 0x5, 0xb0, 0x0, 0xe2, + 0x18, 0xcf, 0xd9, 0x60, 0x5, 0xa0, 0x0, 0xf1, + 0x17, 0x6d, 0x0, 0x0, 0x6, 0xa0, 0x0, 0xf1, + 0x0, 0x2d, 0x0, 0x0, 0x9, 0x70, 0x0, 0xf0, + 0x0, 0x2d, 0x0, 0x0, 0xc, 0x40, 0x1, 0xf0, + 0x0, 0x2d, 0x0, 0x20, 0xf, 0x10, 0x2, 0xf0, + 0x0, 0x3d, 0x4b, 0xd2, 0x5d, 0x0, 0x3, 0xe0, + 0x0, 0x8f, 0xc5, 0x0, 0xd6, 0x0, 0x4, 0xc0, + 0x0, 0x64, 0x0, 0x8, 0xc0, 0x0, 0x7, 0xb0, + 0x0, 0x0, 0x0, 0x9e, 0x20, 0x1, 0x1c, 0x70, + 0x0, 0x0, 0x8, 0xc2, 0x0, 0x4f, 0xfc, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+520A "刊" */ + 0xc, 0xff, 0xff, 0xff, 0x60, 0x0, 0x3, 0xe0, + 0x0, 0xb, 0x60, 0x0, 0xb, 0x10, 0x3e, 0x0, + 0x0, 0xb6, 0x0, 0x0, 0xf1, 0x3, 0xe0, 0x0, + 0xb, 0x60, 0x0, 0xf, 0x10, 0x3e, 0x0, 0x0, + 0xb6, 0x0, 0x0, 0xf1, 0x3, 0xe1, 0x77, 0x7d, + 0xa7, 0x77, 0xf, 0x10, 0x3e, 0x29, 0x99, 0xec, + 0x99, 0x80, 0xf1, 0x3, 0xe0, 0x0, 0xb, 0x60, + 0x0, 0xf, 0x10, 0x3e, 0x0, 0x0, 0xb6, 0x0, + 0x0, 0xf1, 0x3, 0xe0, 0x0, 0xb, 0x60, 0x0, + 0xf, 0x10, 0x3e, 0x0, 0x0, 0xb6, 0x0, 0x0, + 0x10, 0x3, 0xe0, 0x0, 0xb, 0x60, 0x0, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0xb6, 0x0, 0x0, 0x1, + 0x15, 0xd0, 0x0, 0xa, 0x50, 0x0, 0x2, 0xff, + 0xe7, + + /* U+5217 "列" */ + 0xf, 0xff, 0xff, 0xff, 0xf1, 0x0, 0x2, 0xe0, + 0x0, 0x7a, 0x0, 0x0, 0xa, 0x20, 0x2e, 0x0, + 0xc, 0x50, 0x0, 0x0, 0xd2, 0x2, 0xe0, 0x1, + 0xf7, 0x55, 0x52, 0xd, 0x20, 0x2e, 0x0, 0x6d, + 0xaa, 0xad, 0x70, 0xd2, 0x2, 0xe0, 0xd, 0x40, + 0x0, 0xc3, 0xd, 0x20, 0x2e, 0x6, 0xd0, 0x0, + 0xe, 0x0, 0xd2, 0x2, 0xe0, 0xd4, 0xb4, 0x5, + 0xb0, 0xd, 0x20, 0x2e, 0x1, 0x4, 0xe8, 0xc3, + 0x0, 0xd2, 0x2, 0xe0, 0x0, 0x1, 0xdb, 0x0, + 0xd, 0x20, 0x2e, 0x0, 0x0, 0x3e, 0x30, 0x0, + 0x20, 0x2, 0xe0, 0x0, 0x2e, 0x50, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0x7e, 0x70, 0x0, 0x0, 0x0, + 0x4, 0xe0, 0x6c, 0x30, 0x0, 0x0, 0x0, 0xaf, + 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+521D "初" */ + 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xe1, 0x2, 0x33, 0x33, 0x33, 0x31, 0x0, + 0x8, 0x60, 0x9c, 0xcf, 0xdc, 0xce, 0x63, 0xcc, + 0xcc, 0xa0, 0x0, 0xe3, 0x0, 0xb5, 0x13, 0x33, + 0x99, 0x0, 0xf, 0x10, 0xb, 0x50, 0x0, 0x1e, + 0x10, 0x0, 0xf0, 0x0, 0xc4, 0x0, 0xa, 0x93, + 0x40, 0x1f, 0x0, 0xc, 0x40, 0x5, 0xf8, 0xd3, + 0x4, 0xc0, 0x0, 0xd3, 0x3, 0xff, 0xe7, 0x0, + 0x79, 0x0, 0xd, 0x24, 0xf4, 0xe5, 0xe2, 0xb, + 0x50, 0x0, 0xe2, 0x25, 0xe, 0x25, 0x11, 0xf1, + 0x0, 0xf, 0x0, 0x0, 0xe2, 0x0, 0x8a, 0x0, + 0x1, 0xf0, 0x0, 0xe, 0x20, 0x2e, 0x30, 0x0, + 0x3d, 0x0, 0x0, 0xe2, 0x1d, 0x80, 0x0, 0x9, + 0xa0, 0x0, 0xe, 0x27, 0x90, 0x3, 0xff, 0xe2, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5224 "判" */ + 0x3, 0x10, 0x6a, 0x0, 0x70, 0x0, 0x4, 0xc0, + 0x6b, 0x6, 0xa0, 0x7a, 0xa, 0x10, 0x4c, 0x0, + 0xc5, 0x6a, 0x1e, 0x20, 0xe1, 0x4, 0xc0, 0x4, + 0x66, 0xa4, 0x80, 0xe, 0x10, 0x4c, 0x8, 0xcc, + 0xee, 0xcc, 0x90, 0xe1, 0x4, 0xc0, 0x23, 0x38, + 0xb3, 0x32, 0xe, 0x10, 0x4c, 0x0, 0x0, 0x79, + 0x0, 0x0, 0xe1, 0x4, 0xc0, 0x0, 0x8, 0x90, + 0x0, 0xe, 0x10, 0x4c, 0x3e, 0xee, 0xff, 0xee, + 0xe1, 0xe1, 0x4, 0xc0, 0x0, 0x1e, 0x40, 0x0, + 0xe, 0x10, 0x4c, 0x0, 0x5, 0xe0, 0x0, 0x0, + 0x10, 0x4, 0xc0, 0x0, 0xc7, 0x0, 0x0, 0x0, + 0x0, 0x4c, 0x0, 0xbc, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xc0, 0x7b, 0x10, 0x0, 0x0, 0x3, 0xff, + 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5225 "別" */ + 0x3, 0xff, 0xff, 0xff, 0x0, 0x0, 0x2, 0xe0, + 0x3c, 0x0, 0x0, 0xf0, 0x1a, 0x0, 0x2e, 0x3, + 0xc0, 0x0, 0xf, 0x1, 0xe0, 0x2, 0xe0, 0x3c, + 0x0, 0x0, 0xf0, 0x1e, 0x0, 0x2e, 0x3, 0xea, + 0xaa, 0xaf, 0x1, 0xe0, 0x2, 0xe0, 0x14, 0xab, + 0x44, 0x40, 0x1e, 0x0, 0x2e, 0x0, 0x8, 0x70, + 0x0, 0x1, 0xe0, 0x2, 0xe0, 0x0, 0xaf, 0xee, + 0xe1, 0x1e, 0x0, 0x2e, 0x0, 0xd, 0x30, 0xe, + 0x11, 0xe0, 0x2, 0xe0, 0x0, 0xe0, 0x0, 0xf0, + 0x1e, 0x0, 0x2e, 0x0, 0x6a, 0x0, 0xf, 0x0, + 0x10, 0x2, 0xe0, 0xc, 0x50, 0x2, 0xe0, 0x0, + 0x0, 0x2e, 0x8, 0xc0, 0x0, 0x6b, 0x0, 0x1, + 0x4, 0xe0, 0xc2, 0xb, 0xed, 0x40, 0x0, 0xdf, + 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5229 "利" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x57, 0xbd, 0xa1, 0x0, 0x0, 0x2e, 0xc, + 0xa7, 0xc7, 0x0, 0x1, 0xa0, 0x2, 0xe0, 0x0, + 0xa, 0x60, 0x0, 0x1e, 0x0, 0x2e, 0x0, 0x0, + 0xa6, 0x0, 0x1, 0xe0, 0x2, 0xe0, 0xcc, 0xce, + 0xec, 0xc6, 0x1e, 0x0, 0x2e, 0x3, 0x34, 0xf8, + 0x33, 0x11, 0xe0, 0x2, 0xe0, 0x0, 0x9f, 0x90, + 0x0, 0x1e, 0x0, 0x2e, 0x0, 0x1e, 0xbe, 0xa0, + 0x1, 0xe0, 0x2, 0xe0, 0xa, 0x6a, 0x69, 0xc1, + 0x1e, 0x0, 0x2e, 0x5, 0xd0, 0xa6, 0x8, 0x21, + 0xe0, 0x2, 0xe3, 0xe2, 0xa, 0x60, 0x0, 0x1, + 0x0, 0x2e, 0x15, 0x0, 0xa6, 0x0, 0x0, 0x0, + 0x2, 0xe0, 0x0, 0xa, 0x60, 0x0, 0x0, 0x10, + 0x4d, 0x0, 0x0, 0xa5, 0x0, 0x0, 0xd, 0xfe, + 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5230 "到" */ + 0xe, 0xff, 0xff, 0xff, 0xf4, 0x0, 0xc, 0x30, + 0x0, 0x89, 0x2, 0x0, 0xe, 0x10, 0xc3, 0x0, + 0x1e, 0x10, 0xa7, 0x0, 0xe1, 0xc, 0x30, 0xa, + 0x70, 0x1, 0xe3, 0xe, 0x10, 0xc3, 0x5, 0xfc, + 0xde, 0xed, 0xc0, 0xe1, 0xc, 0x30, 0x26, 0x32, + 0x20, 0x9, 0x1e, 0x10, 0xc3, 0x0, 0x0, 0x4b, + 0x0, 0x0, 0xe1, 0xc, 0x30, 0x13, 0x37, 0xc3, + 0x33, 0xe, 0x10, 0xc3, 0x6, 0xcc, 0xdf, 0xcc, + 0xc0, 0xe1, 0xc, 0x30, 0x0, 0x4, 0xb0, 0x0, + 0xe, 0x10, 0xc3, 0x0, 0x0, 0x4b, 0x0, 0x0, + 0x90, 0xc, 0x30, 0x0, 0x6, 0xd8, 0xcf, 0x20, + 0x0, 0xc3, 0x9, 0xcf, 0xda, 0x74, 0x10, 0x0, + 0xd, 0x30, 0x64, 0x10, 0x0, 0x0, 0x0, 0xff, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5236 "制" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x51, 0xe0, 0x0, 0x0, 0x0, 0xf, 0x0, + 0xd4, 0x3e, 0x11, 0x10, 0xe, 0x10, 0xf0, 0x3f, + 0xee, 0xfe, 0xee, 0x30, 0xe1, 0xf, 0xb, 0x60, + 0x1e, 0x0, 0x0, 0xe, 0x10, 0xf0, 0xc6, 0x56, + 0xf5, 0x55, 0x50, 0xe1, 0xf, 0xa, 0xaa, 0xaf, + 0xaa, 0xa8, 0xe, 0x10, 0xf0, 0x0, 0x1, 0xe0, + 0x0, 0x0, 0xe1, 0xf, 0x3, 0xaa, 0xbf, 0xaa, + 0xa2, 0xe, 0x10, 0xf0, 0x4c, 0x56, 0xf5, 0x5c, + 0x40, 0xe1, 0xf, 0x4, 0xa0, 0x1e, 0x0, 0xb4, + 0xc, 0x10, 0xf0, 0x4a, 0x1, 0xe0, 0xb, 0x40, + 0x0, 0xf, 0x4, 0xa0, 0x1e, 0x0, 0xb4, 0x0, + 0x0, 0xf0, 0x4a, 0x1, 0xe3, 0xed, 0x10, 0x11, + 0x3f, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x5, 0xff, + 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5238 "券" */ + 0x0, 0x0, 0x10, 0x3, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xc0, 0x8, 0x90, 0xb, 0x70, 0x0, + 0x0, 0x0, 0xa6, 0xd, 0x50, 0x5b, 0x0, 0x0, + 0x0, 0xcc, 0xdc, 0xcf, 0xcc, 0xfd, 0xcb, 0x0, + 0x0, 0x33, 0x33, 0xc9, 0x33, 0x33, 0x32, 0x0, + 0x0, 0x0, 0x3, 0xf1, 0x0, 0x0, 0x0, 0x0, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x2, 0xd8, 0x0, 0x1, 0xc8, 0x0, 0x0, + 0x0, 0x4e, 0x80, 0x0, 0x0, 0xc, 0xa1, 0x0, + 0x1a, 0xed, 0xfe, 0xee, 0xee, 0xef, 0xbe, 0x92, + 0x18, 0x10, 0x3, 0xe0, 0x0, 0xe, 0x21, 0x82, + 0x0, 0x0, 0x8, 0xa0, 0x0, 0xf, 0x0, 0x0, + 0x0, 0x0, 0x4f, 0x20, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x28, 0xe5, 0x0, 0x0, 0x7c, 0x0, 0x0, + 0x3, 0xe9, 0x20, 0x0, 0xef, 0xd4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+523B "刻" */ + 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xc0, 0x0, 0x0, 0x0, 0x1e, 0x9, + 0x99, 0xaf, 0xa9, 0x96, 0x1b, 0x1, 0xe0, 0x55, + 0x6f, 0x75, 0x55, 0x31, 0xe0, 0x1e, 0x0, 0xa, + 0x80, 0x4, 0x10, 0x1e, 0x1, 0xe0, 0x7, 0xb0, + 0x2, 0xe1, 0x1, 0xe0, 0x1e, 0x6, 0xfc, 0xcc, + 0xe6, 0x0, 0x1e, 0x1, 0xe0, 0x24, 0x32, 0xc9, + 0x2, 0x1, 0xe0, 0x1e, 0x0, 0x1, 0xca, 0x2, + 0xe2, 0x1e, 0x1, 0xe0, 0x5, 0xe8, 0x0, 0xc5, + 0x1, 0xe0, 0x1e, 0x9, 0xe5, 0x0, 0xb9, 0x0, + 0x1e, 0x1, 0xe0, 0x10, 0x1, 0xbe, 0x90, 0x0, + 0x20, 0x1e, 0x0, 0x4, 0xe8, 0xb, 0xb0, 0x0, + 0x1, 0xe0, 0x2a, 0xe5, 0x0, 0xb, 0x80, 0x0, + 0x3e, 0xa, 0x90, 0x0, 0x0, 0x0, 0x9, 0xff, + 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5247 "則" */ + 0x3, 0xff, 0xff, 0xff, 0x0, 0x0, 0x2, 0xe0, + 0x3c, 0x0, 0x1, 0xf0, 0x1a, 0x0, 0x2e, 0x3, + 0xc0, 0x0, 0x1f, 0x1, 0xe0, 0x2, 0xe0, 0x3f, + 0xee, 0xee, 0xf0, 0x1e, 0x0, 0x2e, 0x3, 0xc0, + 0x0, 0x1f, 0x1, 0xe0, 0x2, 0xe0, 0x3c, 0x0, + 0x1, 0xf0, 0x1e, 0x0, 0x2e, 0x3, 0xfe, 0xee, + 0xef, 0x1, 0xe0, 0x2, 0xe0, 0x3c, 0x0, 0x1, + 0xf0, 0x1e, 0x0, 0x2e, 0x3, 0xc0, 0x0, 0x1f, + 0x1, 0xe0, 0x2, 0xe0, 0x3f, 0xee, 0xee, 0xf0, + 0x1e, 0x0, 0x2e, 0x0, 0x25, 0x1, 0x40, 0x0, + 0x10, 0x2, 0xe0, 0xa, 0x90, 0xd, 0x60, 0x0, + 0x0, 0x2e, 0x6, 0xe1, 0x0, 0x3f, 0x10, 0x1, + 0x4, 0xe0, 0xc3, 0x0, 0x0, 0x73, 0x0, 0xdf, + 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+524A "削" */ + 0x7, 0x0, 0xf0, 0x7, 0x50, 0x0, 0xe, 0x20, + 0xd3, 0xf, 0x0, 0xe3, 0x6, 0x0, 0xe2, 0x6, + 0xa0, 0xf0, 0x6b, 0x1, 0xe0, 0xe, 0x20, 0x16, + 0xf, 0x5, 0x20, 0x1e, 0x0, 0xe2, 0xc, 0xff, + 0xff, 0xfe, 0x1, 0xe0, 0xe, 0x20, 0xc4, 0x0, + 0x1, 0xe0, 0x1e, 0x0, 0xe2, 0xc, 0x40, 0x0, + 0x2e, 0x1, 0xe0, 0xe, 0x20, 0xce, 0xee, 0xee, + 0xe0, 0x1e, 0x0, 0xe2, 0xc, 0x30, 0x0, 0x1e, + 0x1, 0xe0, 0xe, 0x20, 0xcd, 0xcc, 0xcd, 0xe0, + 0x1e, 0x0, 0xe2, 0xc, 0x52, 0x22, 0x3e, 0x0, + 0x10, 0xe, 0x20, 0xc3, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0xe2, 0xc, 0x30, 0x1, 0x4e, 0x0, 0x1, + 0x1f, 0x20, 0xb3, 0x2, 0xdd, 0x70, 0x2, 0xff, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+524D "前" */ + 0x0, 0x2, 0x40, 0x0, 0x0, 0x4, 0x40, 0x0, + 0x0, 0x2, 0xe3, 0x0, 0x0, 0x1e, 0x50, 0x0, + 0x0, 0x0, 0x6c, 0x0, 0x0, 0x9a, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x33, 0x33, 0x32, 0x0, 0x0, 0x9, 0x0, + 0x1, 0xfb, 0xbb, 0xda, 0x4, 0xb0, 0xf, 0x0, + 0x1, 0xe0, 0x0, 0x5a, 0x4, 0xb0, 0xf, 0x0, + 0x1, 0xf9, 0x99, 0xba, 0x4, 0xb0, 0xf, 0x0, + 0x1, 0xe4, 0x44, 0x8a, 0x4, 0xb0, 0xf, 0x0, + 0x1, 0xe0, 0x0, 0x5a, 0x4, 0xb0, 0xf, 0x0, + 0x1, 0xfd, 0xdd, 0xea, 0x4, 0xb0, 0xf, 0x0, + 0x1, 0xe0, 0x0, 0x5a, 0x2, 0x60, 0xf, 0x0, + 0x1, 0xe0, 0x0, 0x6a, 0x0, 0x0, 0x1f, 0x0, + 0x1, 0xe0, 0x4e, 0xe6, 0x0, 0x4f, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+525B "剛" */ + 0xcf, 0xff, 0xff, 0xff, 0x70, 0x0, 0xb4, 0xc2, + 0x50, 0x2, 0x56, 0x70, 0xd1, 0xb4, 0xc2, 0x84, + 0x7, 0x76, 0x70, 0xe1, 0xb4, 0xc2, 0x39, 0xc, + 0x26, 0x70, 0xe1, 0xb4, 0xc2, 0x27, 0x3d, 0x17, + 0x70, 0xe1, 0xb4, 0xc4, 0xbb, 0xeb, 0xb7, 0x70, + 0xe1, 0xb4, 0xc2, 0x60, 0xb0, 0x66, 0x70, 0xe1, + 0xb4, 0xc2, 0xa0, 0xb0, 0xa6, 0x70, 0xe1, 0xb4, + 0xc2, 0xa0, 0xb0, 0xa6, 0x70, 0xe1, 0xb4, 0xc2, + 0xa0, 0xb0, 0xa6, 0x70, 0xe1, 0xb4, 0xc2, 0xcc, + 0xfc, 0xa6, 0x70, 0x0, 0xb4, 0xc2, 0x0, 0x0, + 0x6, 0x70, 0x0, 0xb4, 0xc2, 0x0, 0x0, 0x8, + 0x70, 0x0, 0xc4, 0xc2, 0x0, 0xb, 0xfd, 0x20, + 0xcf, 0xc1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5272 "割" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xc0, 0x0, 0x0, 0x0, 0x1e, 0xcd, 0xdd, + 0xfd, 0xdd, 0xb0, 0x20, 0x1e, 0xe0, 0x0, 0xa0, + 0x2, 0xc1, 0xe0, 0x1e, 0x8c, 0xcc, 0xfc, 0xcb, + 0x51, 0xe0, 0x1e, 0x0, 0x1, 0xf0, 0x0, 0x1, + 0xe0, 0x1e, 0x9, 0xdd, 0xfd, 0xd6, 0x1, 0xe0, + 0x1e, 0x0, 0x0, 0xe0, 0x0, 0x1, 0xe0, 0x1e, + 0xbc, 0xcd, 0xfc, 0xcc, 0x91, 0xe0, 0x1e, 0x0, + 0x0, 0xe0, 0x0, 0x1, 0xe0, 0x1e, 0xb, 0xbb, + 0xfb, 0xba, 0x1, 0xe0, 0x1e, 0xf, 0x33, 0x33, + 0x4d, 0x0, 0x20, 0x1e, 0xe, 0x0, 0x0, 0x1d, + 0x0, 0x0, 0x1e, 0xf, 0xbb, 0xbb, 0xbd, 0x0, + 0x0, 0x2e, 0xf, 0x22, 0x22, 0x3c, 0x0, 0x7f, + 0xf9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5275 "創" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, 0xe1, 0x0, + 0x8, 0xbb, 0x91, 0x0, 0x70, 0xe, 0x10, 0x1a, + 0xa9, 0x25, 0xd6, 0xe, 0x10, 0xe1, 0x3e, 0x70, + 0x3a, 0x1, 0x50, 0xe1, 0xe, 0x10, 0x2a, 0xcc, + 0xcc, 0xc1, 0xe, 0x10, 0xe1, 0x0, 0xd0, 0x0, + 0xd, 0x10, 0xe1, 0xe, 0x10, 0xe, 0xcb, 0xbb, + 0xf1, 0xe, 0x10, 0xe1, 0x0, 0xf0, 0x0, 0xd, + 0x10, 0xe1, 0xe, 0x10, 0x1f, 0xcc, 0xcc, 0xf1, + 0xe, 0x10, 0xe1, 0x3, 0xb0, 0x0, 0x0, 0x0, + 0xe1, 0xe, 0x10, 0x87, 0xfd, 0xdd, 0xf3, 0x4, + 0x0, 0xe1, 0xe, 0x2d, 0x0, 0xc, 0x30, 0x0, + 0xe, 0x17, 0x90, 0xfb, 0xbb, 0xf3, 0x0, 0x1, + 0xf1, 0x1, 0xd, 0x22, 0x2b, 0x20, 0x1f, 0xfb, + 0x0, + + /* U+5283 "劃" */ + 0x2, 0xbb, 0xce, 0xbb, 0xe0, 0x0, 0x2, 0xd0, + 0x0, 0x3, 0xb0, 0xe, 0x5, 0xb0, 0x2d, 0x3c, + 0xcc, 0xdf, 0xcc, 0xfb, 0x5b, 0x2, 0xd0, 0x1, + 0x15, 0xc1, 0x2e, 0x5, 0xb0, 0x2d, 0x2, 0x88, + 0xae, 0x88, 0x80, 0x5b, 0x2, 0xd0, 0x5b, 0xbc, + 0xeb, 0xbb, 0x15, 0xb0, 0x2d, 0x3, 0x33, 0x6c, + 0x33, 0x32, 0x5b, 0x2, 0xd1, 0x99, 0x99, 0x99, + 0x99, 0x85, 0xb0, 0x2d, 0x1, 0xaa, 0xaa, 0xaa, + 0x90, 0x5b, 0x2, 0xd0, 0x2b, 0x24, 0xd2, 0x3e, + 0x5, 0xb0, 0x2d, 0x2, 0xd6, 0x7e, 0x66, 0xe0, + 0x23, 0x2, 0xd0, 0x2c, 0xaa, 0xda, 0xac, 0x0, + 0x0, 0x2d, 0x0, 0x0, 0x0, 0x12, 0x23, 0x0, + 0x3, 0xd3, 0xdd, 0xdd, 0xdc, 0xba, 0x90, 0x7f, + 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+529B "力" */ + 0x0, 0x0, 0x0, 0x2f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x9f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1, 0x22, + 0x22, 0x6e, 0x22, 0x22, 0x2b, 0x70, 0x0, 0x0, + 0x6, 0xb0, 0x0, 0x0, 0xb6, 0x0, 0x0, 0x0, + 0x98, 0x0, 0x0, 0xc, 0x50, 0x0, 0x0, 0xf, + 0x30, 0x0, 0x0, 0xd4, 0x0, 0x0, 0x6, 0xd0, + 0x0, 0x0, 0xe, 0x20, 0x0, 0x1, 0xe7, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0xbc, 0x0, 0x0, + 0x0, 0x2f, 0x0, 0x0, 0x9e, 0x10, 0x0, 0x0, + 0x5, 0xc0, 0x1, 0xbd, 0x20, 0x0, 0x1, 0x1, + 0xb8, 0x0, 0xca, 0x10, 0x0, 0x0, 0xcf, 0xfc, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+529F "功" */ + 0x0, 0x0, 0x0, 0x0, 0x3, 0xd0, 0x0, 0x0, + 0x8, 0x88, 0x88, 0x60, 0x3, 0xd0, 0x0, 0x0, + 0x6, 0x6c, 0xa6, 0x40, 0x3, 0xd0, 0x0, 0x0, + 0x0, 0xa, 0x60, 0x1e, 0xef, 0xfe, 0xee, 0xe1, + 0x0, 0xa, 0x60, 0x1, 0x16, 0xc1, 0x11, 0xf1, + 0x0, 0xa, 0x60, 0x0, 0x7, 0x90, 0x0, 0xf0, + 0x0, 0xa, 0x60, 0x0, 0x9, 0x70, 0x1, 0xf0, + 0x0, 0xa, 0x60, 0x0, 0xc, 0x50, 0x2, 0xe0, + 0x0, 0xa, 0x63, 0x80, 0x1f, 0x0, 0x3, 0xd0, + 0x2, 0x7d, 0xfd, 0x80, 0x7b, 0x0, 0x4, 0xc0, + 0x2f, 0xb6, 0x20, 0x1, 0xf4, 0x0, 0x5, 0xb0, + 0x0, 0x0, 0x0, 0xb, 0x90, 0x0, 0x8, 0x90, + 0x0, 0x0, 0x2, 0xcc, 0x10, 0x10, 0x1d, 0x50, + 0x0, 0x0, 0xb, 0x90, 0x0, 0x9f, 0xfc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+52A0 "加" */ + 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc3, 0x0, 0x0, 0x22, 0x22, 0x22, 0x2, + 0x2d, 0x52, 0x22, 0xe, 0xdd, 0xde, 0xc0, 0xee, + 0xfe, 0xee, 0xe0, 0xe1, 0x0, 0x4c, 0x0, 0xe, + 0x20, 0x2d, 0xe, 0x10, 0x4, 0xc0, 0x0, 0xf1, + 0x3, 0xd0, 0xe1, 0x0, 0x4c, 0x0, 0xf, 0x0, + 0x3d, 0xe, 0x10, 0x4, 0xc0, 0x2, 0xe0, 0x4, + 0xc0, 0xe1, 0x0, 0x4c, 0x0, 0x4b, 0x0, 0x4c, + 0xe, 0x10, 0x4, 0xc0, 0x7, 0x90, 0x5, 0xb0, + 0xe1, 0x0, 0x4c, 0x0, 0xc4, 0x0, 0x6a, 0xe, + 0x10, 0x4, 0xc0, 0x2e, 0x0, 0x8, 0x90, 0xe3, + 0x11, 0x5c, 0xb, 0x80, 0x11, 0xc6, 0xe, 0xff, + 0xff, 0xc3, 0xd0, 0xe, 0xfc, 0x10, 0xe1, 0x0, + 0x3b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+52A8 "动" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x96, 0x0, 0x0, + 0x8, 0xee, 0xee, 0xe9, 0x0, 0xa6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x78, 0xdb, 0x88, 0x80, + 0x0, 0x0, 0x0, 0x0, 0x78, 0xda, 0x88, 0xf1, + 0x1e, 0xef, 0xfe, 0xed, 0x0, 0xc4, 0x0, 0xf0, + 0x0, 0xf, 0x10, 0x0, 0x0, 0xe2, 0x0, 0xf0, + 0x0, 0x4c, 0x2, 0x60, 0x0, 0xf0, 0x1, 0xf0, + 0x0, 0x97, 0x1, 0xe0, 0x3, 0xd0, 0x2, 0xe0, + 0x0, 0xe1, 0x0, 0xa6, 0x7, 0xa0, 0x3, 0xd0, + 0x5, 0xc5, 0x8b, 0xeb, 0xc, 0x50, 0x4, 0xc0, + 0xc, 0xea, 0x63, 0xc, 0x4e, 0x0, 0x7, 0xa0, + 0x1, 0x0, 0x0, 0x0, 0xd7, 0x10, 0x1c, 0x70, + 0x0, 0x0, 0x0, 0x5, 0xb0, 0x8f, 0xfc, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+52A9 "助" */ + 0x1, 0xff, 0xff, 0xf1, 0x0, 0x96, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0xe1, 0x0, 0xa6, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0xe1, 0x0, 0xa6, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0xe5, 0xcc, 0xed, 0xcc, 0xc0, + 0x1, 0xfe, 0xee, 0xf3, 0x55, 0xd9, 0x56, 0xf0, + 0x1, 0xe0, 0x0, 0xe1, 0x0, 0xd3, 0x0, 0xf0, + 0x1, 0xe0, 0x0, 0xe1, 0x0, 0xe1, 0x1, 0xf0, + 0x1, 0xfe, 0xee, 0xf1, 0x1, 0xf0, 0x1, 0xe0, + 0x1, 0xe0, 0x0, 0xe1, 0x6, 0xa0, 0x2, 0xd0, + 0x1, 0xe0, 0x0, 0xe1, 0xb, 0x60, 0x3, 0xd0, + 0x1, 0xe2, 0x59, 0xff, 0x4e, 0x10, 0x4, 0xc0, + 0x1b, 0xfe, 0xb7, 0x31, 0xc6, 0x0, 0x6, 0xa0, + 0x6, 0x20, 0x0, 0x1c, 0xb0, 0x0, 0xa, 0x70, + 0x0, 0x0, 0x0, 0x99, 0x0, 0x4f, 0xfd, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+52AA "努" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xb0, 0x0, 0x9f, 0xff, 0xff, 0xa0, + 0x1c, 0xce, 0xec, 0xca, 0xe, 0x0, 0xa, 0x60, + 0x1, 0x6d, 0x21, 0x87, 0xa, 0x50, 0x1f, 0x10, + 0x0, 0xd5, 0x0, 0xd1, 0x3, 0xd0, 0xa8, 0x0, + 0x0, 0x8e, 0x89, 0x80, 0x0, 0x9c, 0xd0, 0x0, + 0x0, 0x2, 0xef, 0x70, 0x0, 0x9f, 0xb0, 0x0, + 0x0, 0x5d, 0x94, 0xd7, 0x7e, 0xa2, 0xae, 0x70, + 0x1e, 0xa4, 0x0, 0x4, 0x83, 0x0, 0x3, 0x90, + 0x0, 0x0, 0x0, 0xc, 0x50, 0x0, 0x0, 0x0, + 0x1, 0xee, 0xee, 0xef, 0xee, 0xee, 0xef, 0x10, + 0x0, 0x0, 0x0, 0x8b, 0x0, 0x0, 0x2f, 0x0, + 0x0, 0x0, 0x6, 0xe2, 0x0, 0x0, 0x5c, 0x0, + 0x0, 0x15, 0xcd, 0x30, 0x0, 0x0, 0xa9, 0x0, + 0xa, 0xeb, 0x50, 0x0, 0x7, 0xff, 0xc2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+52B3 "劳" */ + 0x0, 0x0, 0x5b, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x1, 0x11, 0x6c, 0x11, 0x11, 0xc6, 0x11, 0x10, + 0x0, 0x0, 0x25, 0x0, 0x0, 0x52, 0x0, 0x0, + 0xa, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x90, + 0xb, 0x50, 0x0, 0x1, 0x0, 0x0, 0x7, 0xa0, + 0x9, 0x40, 0x0, 0x3e, 0x0, 0x0, 0x5, 0x70, + 0x0, 0x0, 0x0, 0x5c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, + 0x0, 0x0, 0x0, 0xc5, 0x0, 0x0, 0x97, 0x0, + 0x0, 0x0, 0x4, 0xf0, 0x0, 0x0, 0xb6, 0x0, + 0x0, 0x0, 0x4e, 0x50, 0x0, 0x0, 0xd4, 0x0, + 0x0, 0x4a, 0xe5, 0x0, 0x0, 0x2, 0xf1, 0x0, + 0xe, 0xc7, 0x10, 0x0, 0x5f, 0xff, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+52C9 "勉" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xc0, 0x0, 0x0, 0xf, 0x0, 0x0, + 0x0, 0xd, 0xee, 0xf4, 0x0, 0x1f, 0x0, 0x0, + 0x0, 0x88, 0x1, 0xe0, 0x0, 0x1f, 0x0, 0x0, + 0x6, 0xe1, 0x18, 0x91, 0x3f, 0xff, 0xff, 0xf1, + 0x1e, 0xfd, 0xdf, 0xdd, 0xe2, 0x4d, 0x22, 0xe1, + 0x3, 0xb0, 0xe, 0x1, 0xe0, 0x4b, 0x0, 0xf0, + 0x3, 0xb0, 0x1e, 0x1, 0xe0, 0x69, 0x0, 0xf0, + 0x3, 0xc2, 0x3e, 0x23, 0xe0, 0xa6, 0x1, 0xf0, + 0x2, 0xcc, 0xdf, 0xfc, 0xb0, 0xe2, 0x2, 0xe0, + 0x0, 0x0, 0x89, 0xd0, 0x6, 0xb0, 0x4, 0xc0, + 0x0, 0x0, 0xe4, 0xd0, 0x2e, 0x31, 0x29, 0x90, + 0x0, 0xa, 0x91, 0xd0, 0xc5, 0x3, 0xdc, 0x63, + 0x0, 0x9c, 0x1, 0xf0, 0x0, 0x0, 0x0, 0x97, + 0xd, 0x90, 0x0, 0xae, 0xee, 0xee, 0xee, 0xd1, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+52D5 "動" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0xcc, 0xeb, 0x74, 0x10, 0x3c, 0x0, 0x0, + 0x0, 0x0, 0x86, 0x0, 0x0, 0x3c, 0x0, 0x0, + 0x1d, 0xdd, 0xee, 0xdd, 0xc0, 0x3c, 0x0, 0x0, + 0x0, 0x0, 0x86, 0x0, 0x2c, 0xdf, 0xcc, 0xc2, + 0x7, 0xbb, 0xed, 0xbb, 0x85, 0x8c, 0x55, 0xe2, + 0x9, 0x40, 0x86, 0x5, 0x90, 0x6a, 0x0, 0xe2, + 0x9, 0xdb, 0xed, 0xbd, 0x90, 0x88, 0x0, 0xe1, + 0x9, 0x40, 0x86, 0x5, 0x90, 0xa6, 0x0, 0xf1, + 0x9, 0xdc, 0xed, 0xcd, 0x90, 0xd3, 0x0, 0xf0, + 0x0, 0x0, 0x86, 0x0, 0x1, 0xf0, 0x1, 0xf0, + 0x8, 0xdd, 0xee, 0xdd, 0x88, 0x90, 0x2, 0xe0, + 0x0, 0x0, 0x86, 0x1, 0x3e, 0x20, 0x4, 0xc0, + 0x7, 0x9a, 0xee, 0xdd, 0xf7, 0x0, 0x8, 0xa0, + 0x6, 0x43, 0x10, 0x9, 0x80, 0xc, 0xfe, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+52D9 "務" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x90, 0x0, 0x0, + 0xd, 0xff, 0xff, 0xf4, 0xb, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xc0, 0x5f, 0xfe, 0xee, 0xc0, + 0x0, 0x31, 0x4e, 0x24, 0xfd, 0x10, 0x9, 0x50, + 0x0, 0x6d, 0xe3, 0xb, 0x45, 0xb0, 0x5b, 0x0, + 0x0, 0x6, 0xc0, 0x0, 0x0, 0x6d, 0xd0, 0x0, + 0xe, 0xee, 0xfe, 0xe8, 0x3, 0xcb, 0xe8, 0x10, + 0x0, 0xc, 0xd0, 0x9b, 0xde, 0x50, 0x1b, 0xf9, + 0x0, 0x2f, 0xd0, 0xd4, 0x50, 0x94, 0x0, 0x22, + 0x0, 0x9a, 0xd3, 0xb2, 0x33, 0xd6, 0x33, 0x30, + 0x3, 0xe3, 0xd1, 0x28, 0xbc, 0xfb, 0xbc, 0xf0, + 0xd, 0x42, 0xd0, 0x0, 0x7, 0xa0, 0x3, 0xd0, + 0x5, 0x2, 0xd0, 0x0, 0x3e, 0x20, 0x6, 0xa0, + 0x0, 0x3, 0xd0, 0x7, 0xe4, 0x0, 0xb, 0x60, + 0x0, 0xcf, 0x90, 0x9a, 0x20, 0xe, 0xfc, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+52DD "勝" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x64, 0x3, 0x10, + 0x1, 0xff, 0xfe, 0xb, 0x70, 0xa5, 0x1e, 0x20, + 0x1, 0xc0, 0x1e, 0x1, 0xe1, 0xc3, 0x9a, 0x0, + 0x1, 0xc0, 0x1e, 0x2, 0x52, 0xe4, 0xb4, 0x20, + 0x1, 0xd0, 0x1e, 0x1b, 0xbc, 0xfb, 0xbb, 0x90, + 0x1, 0xfb, 0xce, 0x0, 0x8, 0x80, 0x0, 0x0, + 0x2, 0xc0, 0x1e, 0xae, 0xef, 0xfe, 0xee, 0xe7, + 0x2, 0xc0, 0x1e, 0x0, 0xb7, 0x1, 0xd3, 0x0, + 0x3, 0xe9, 0xae, 0x9, 0xc1, 0xc0, 0x3e, 0x40, + 0x3, 0xd5, 0x6e, 0xcc, 0x13, 0xd0, 0x3, 0xd6, + 0x4, 0xa0, 0x1e, 0x49, 0xde, 0xed, 0xdf, 0x20, + 0x6, 0x90, 0x1e, 0x0, 0xa, 0x60, 0xf, 0x0, + 0x8, 0x60, 0x1e, 0x0, 0x3e, 0x0, 0x1e, 0x0, + 0xc, 0x20, 0x1e, 0x5, 0xe4, 0x0, 0x4c, 0x0, + 0xd, 0x9, 0xf9, 0x7c, 0x30, 0x6e, 0xd5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+52E4 "勤" */ + 0x0, 0x68, 0x0, 0xc3, 0x0, 0x2c, 0x0, 0x0, + 0x1d, 0xee, 0xdd, 0xfd, 0xc0, 0x2d, 0x0, 0x0, + 0x0, 0x6a, 0x22, 0xc3, 0x0, 0x2d, 0x0, 0x0, + 0x0, 0x38, 0xdb, 0x82, 0x3b, 0xcf, 0xbb, 0xb3, + 0x6, 0xcc, 0xed, 0xcc, 0x52, 0x5c, 0x22, 0xc4, + 0x8, 0x60, 0xa6, 0x9, 0x60, 0x5a, 0x0, 0xc3, + 0x8, 0x60, 0xa5, 0x9, 0x60, 0x79, 0x0, 0xc3, + 0x6, 0xcc, 0xed, 0xcc, 0x40, 0x97, 0x0, 0xd2, + 0x4, 0x66, 0xca, 0x66, 0x40, 0xb4, 0x0, 0xe1, + 0x3, 0x44, 0xc9, 0x44, 0x30, 0xf1, 0x0, 0xf1, + 0x6, 0xcc, 0xed, 0xcc, 0x34, 0xc0, 0x0, 0xf0, + 0x0, 0x0, 0xa6, 0x0, 0xc, 0x50, 0x2, 0xe0, + 0x16, 0x89, 0xdd, 0xde, 0xec, 0x0, 0x6, 0xc0, + 0x18, 0x75, 0x42, 0x11, 0xd1, 0x9, 0xff, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+52F5 "勵" */ + 0xc, 0xed, 0xdd, 0xdd, 0xd4, 0xf, 0x0, 0x0, + 0xc1, 0x8, 0x7, 0x50, 0x0, 0xe0, 0x0, 0xc, + 0x7b, 0xeb, 0xed, 0xb1, 0xe, 0x0, 0x0, 0xc1, + 0x8, 0x6, 0x50, 0xbd, 0xfd, 0xda, 0xc, 0x1e, + 0xce, 0xcc, 0xb2, 0x4d, 0x24, 0xc0, 0xc1, 0xc0, + 0xd0, 0xc, 0x3, 0xc0, 0x3c, 0xd, 0x1e, 0xaf, + 0xaa, 0xc0, 0x4b, 0x3, 0xb0, 0xd0, 0xd5, 0xe5, + 0x5c, 0x6, 0x90, 0x4b, 0xe, 0x5, 0x5e, 0x55, + 0x40, 0x87, 0x4, 0xa0, 0xe6, 0xcc, 0xfc, 0xcc, + 0x1a, 0x40, 0x5a, 0x1d, 0x77, 0xc, 0x23, 0xb1, + 0xe1, 0x6, 0x94, 0xa7, 0x75, 0xd9, 0x9b, 0x5b, + 0x0, 0x87, 0x86, 0x78, 0x75, 0x28, 0xbc, 0x50, + 0xb, 0x55, 0x27, 0x70, 0x0, 0xac, 0xc0, 0xcf, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5305 "包" */ + 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xaa, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xf3, 0x11, 0x11, 0x11, 0x11, 0x0, + 0x0, 0xc, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x0, + 0x0, 0xac, 0x0, 0x0, 0x0, 0x0, 0x4d, 0x0, + 0xa, 0xe5, 0x33, 0x33, 0x33, 0x0, 0x4c, 0x0, + 0x3d, 0x2e, 0xbb, 0xbb, 0xcc, 0x0, 0x5b, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x3c, 0x0, 0x6b, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x3c, 0x0, 0x7a, 0x0, + 0x0, 0xe, 0x98, 0x88, 0xac, 0x0, 0x88, 0x0, + 0x0, 0xe, 0x76, 0x66, 0x65, 0x22, 0xd5, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x9d, 0xb0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0x0, 0xb2, + 0x0, 0xd, 0x60, 0x0, 0x0, 0x0, 0x4, 0xf1, + 0x0, 0x4, 0xdf, 0xff, 0xff, 0xff, 0xfe, 0x60, + + /* U+5316 "化" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8a, 0x0, 0xe3, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xf2, 0x0, 0xe3, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xa0, 0x0, 0xe3, 0x0, 0x9, 0x50, + 0x0, 0x3f, 0x40, 0x0, 0xe3, 0x0, 0x7e, 0x20, + 0x1, 0xef, 0x40, 0x0, 0xe3, 0x4, 0xf3, 0x0, + 0x1d, 0xad, 0x40, 0x0, 0xe3, 0x5f, 0x50, 0x0, + 0x3b, 0xd, 0x40, 0x0, 0xea, 0xe3, 0x0, 0x0, + 0x0, 0xd, 0x40, 0x1, 0xfd, 0x20, 0x0, 0x0, + 0x0, 0xd, 0x40, 0x7f, 0xf3, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x4a, 0xd3, 0xe3, 0x0, 0x0, 0x40, + 0x0, 0xd, 0x41, 0x0, 0xe3, 0x0, 0x0, 0xf1, + 0x0, 0xd, 0x40, 0x0, 0xe3, 0x0, 0x1, 0xf0, + 0x0, 0xd, 0x40, 0x0, 0xd7, 0x10, 0x16, 0xc0, + 0x0, 0xd, 0x40, 0x0, 0x6f, 0xff, 0xfe, 0x40, + + /* U+5317 "北" */ + 0x0, 0x0, 0xe, 0x20, 0xf, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x20, 0xf, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x20, 0xf, 0x0, 0x1, 0x10, + 0x1, 0x11, 0x1e, 0x20, 0xf, 0x0, 0x3e, 0x90, + 0x1f, 0xff, 0xff, 0x20, 0xf, 0x7, 0xf7, 0x0, + 0x0, 0x0, 0xe, 0x20, 0xf, 0xcb, 0x20, 0x0, + 0x0, 0x0, 0xe, 0x20, 0xf, 0x50, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x20, 0xf, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x20, 0xf, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3f, 0x20, 0xf, 0x0, 0x0, 0x20, + 0x1, 0x7d, 0xdf, 0x20, 0xf, 0x0, 0x0, 0xc4, + 0x5f, 0xa4, 0xe, 0x20, 0xf, 0x0, 0x0, 0xd3, + 0x1, 0x0, 0xe, 0x20, 0xf, 0x40, 0x2, 0xf0, + 0x0, 0x0, 0xe, 0x20, 0x9, 0xff, 0xff, 0x80, + + /* U+533B "医" */ + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, + 0xd0, 0x0, 0x52, 0x0, 0x0, 0x0, 0x0, 0x3d, + 0x0, 0x2f, 0x20, 0x0, 0x0, 0x0, 0x3, 0xd0, + 0xa, 0xfb, 0xbb, 0xbb, 0xbb, 0x0, 0x3d, 0x8, + 0xd3, 0x34, 0xf3, 0x33, 0x30, 0x3, 0xd0, 0xa2, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x3d, 0x0, 0x0, + 0x2, 0xe0, 0x0, 0x0, 0x3, 0xd2, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xb0, 0x3d, 0x0, 0x0, 0x7, + 0xf5, 0x0, 0x0, 0x3, 0xd0, 0x0, 0x3, 0xf4, + 0xc8, 0x0, 0x0, 0x3d, 0x0, 0x7, 0xe5, 0x0, + 0xba, 0x0, 0x3, 0xd0, 0x8e, 0xb2, 0x0, 0x0, + 0xba, 0x0, 0x3d, 0x37, 0x53, 0x33, 0x33, 0x33, + 0x83, 0x13, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xc5, + + /* U+5340 "區" */ + 0x4f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x4, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4c, + 0x0, 0x2c, 0xcc, 0xcc, 0xc0, 0x0, 0x4, 0xc0, + 0x2, 0xc0, 0x0, 0xe, 0x0, 0x0, 0x4c, 0x0, + 0x2c, 0x0, 0x0, 0xe0, 0x0, 0x4, 0xc0, 0x2, + 0xec, 0xcc, 0xce, 0x0, 0x0, 0x4c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4, 0xc0, 0xdc, 0xce, + 0x23, 0xec, 0xdc, 0x0, 0x4c, 0xe, 0x0, 0xb2, + 0x3b, 0x1, 0xd0, 0x4, 0xc0, 0xe0, 0xb, 0x23, + 0xb0, 0x1d, 0x0, 0x4c, 0xe, 0xcc, 0xf2, 0x3f, + 0xcd, 0xd0, 0x4, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4f, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xbb, 0x30, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x30, + + /* U+5341 "十" */ + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x2, 0x22, 0x22, 0x29, 0xa2, 0x22, 0x22, 0x20, + 0x1e, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe3, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + + /* U+5343 "千" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x46, 0x9d, 0xf3, 0x0, + 0x1, 0x79, 0xbd, 0xff, 0xe9, 0x63, 0x0, 0x0, + 0x0, 0x86, 0x42, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x1a, 0x91, 0x11, 0x11, 0x10, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + + /* U+5348 "午" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xb1, 0x11, 0x11, 0x11, 0x11, 0x0, + 0x0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0xba, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x7, 0xe1, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x9, 0x40, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + + /* U+534A "半" */ + 0x0, 0x24, 0x0, 0x9, 0x80, 0x0, 0x53, 0x0, + 0x0, 0x2e, 0x10, 0x9, 0x80, 0x1, 0xf3, 0x0, + 0x0, 0x8, 0xa0, 0x9, 0x80, 0x9, 0xa0, 0x0, + 0x0, 0x1, 0xf1, 0x9, 0x80, 0x3e, 0x10, 0x0, + 0x0, 0x11, 0x21, 0x1a, 0x81, 0x12, 0x11, 0x0, + 0x1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x3, 0x33, 0x33, 0x3b, 0xa3, 0x33, 0x33, 0x30, + 0x1d, 0xdd, 0xdd, 0xdf, 0xed, 0xdd, 0xdd, 0xd2, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + + /* U+5352 "卒" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, + 0x2, 0x44, 0x44, 0x48, 0xe4, 0x44, 0x44, 0x20, + 0x8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x80, + 0x0, 0x0, 0x78, 0x0, 0x0, 0x3b, 0x0, 0x0, + 0x0, 0x1, 0xf4, 0x0, 0x0, 0xc7, 0x0, 0x0, + 0x0, 0x9, 0xdd, 0x30, 0x7, 0xec, 0x20, 0x0, + 0x0, 0x8d, 0x13, 0xd3, 0x9c, 0x14, 0xe7, 0x0, + 0x9, 0xd2, 0x0, 0x4, 0xb0, 0x0, 0x1c, 0x70, + 0x1, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x1, 0x11, 0x11, 0x1a, 0x81, 0x11, 0x11, 0x10, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + + /* U+5354 "協" */ + 0x0, 0x1e, 0x0, 0x0, 0x3, 0xc0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x6d, 0xde, 0xfd, 0xdd, 0x80, + 0x0, 0x1e, 0x0, 0x0, 0x1d, 0x40, 0x7, 0x80, + 0x3, 0x5f, 0x33, 0x0, 0x6c, 0x0, 0x8, 0x60, + 0x1d, 0xdf, 0xdb, 0x5, 0xd2, 0x0, 0xc, 0x30, + 0x0, 0x1e, 0x0, 0xbb, 0x10, 0xc, 0xea, 0x0, + 0x0, 0x1e, 0x0, 0x38, 0x0, 0x0, 0xa0, 0x0, + 0x0, 0x1e, 0x0, 0x3b, 0x0, 0x0, 0xf0, 0x0, + 0x0, 0x1e, 0xc, 0xef, 0xde, 0x9e, 0xfd, 0xf4, + 0x0, 0x1e, 0x0, 0x77, 0xe, 0x3, 0xb0, 0xa4, + 0x0, 0x1e, 0x0, 0xb3, 0x1d, 0x7, 0x70, 0xb3, + 0x0, 0x1e, 0x0, 0xe0, 0x2c, 0xc, 0x30, 0xc2, + 0x0, 0x1e, 0x9, 0x80, 0x4a, 0x6b, 0x0, 0xe0, + 0x0, 0x1e, 0x2b, 0xa, 0xd5, 0xb1, 0x5e, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5357 "南" */ + 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x1, 0x11, 0x11, 0x1a, 0x91, 0x11, 0x11, 0x10, + 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, + 0x1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, + 0x1, 0xf0, 0x7, 0x10, 0x1, 0x80, 0xe, 0x20, + 0x1, 0xf0, 0x7, 0x90, 0x8, 0x80, 0xe, 0x20, + 0x1, 0xf0, 0x24, 0xb3, 0x3e, 0x42, 0xe, 0x20, + 0x1, 0xf0, 0x8a, 0xad, 0xda, 0xa9, 0xe, 0x20, + 0x1, 0xf0, 0x0, 0x8, 0x70, 0x0, 0xe, 0x20, + 0x1, 0xf1, 0xee, 0xef, 0xfe, 0xee, 0x2e, 0x20, + 0x1, 0xf0, 0x0, 0x8, 0x70, 0x0, 0xe, 0x20, + 0x1, 0xf0, 0x0, 0x8, 0x70, 0x0, 0xf, 0x20, + 0x1, 0xf0, 0x0, 0x8, 0x70, 0x6e, 0xec, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5358 "単" */ + 0x0, 0x13, 0x0, 0x25, 0x0, 0x0, 0x53, 0x0, + 0x0, 0x3e, 0x10, 0x2e, 0x10, 0x2, 0xf2, 0x0, + 0x0, 0x8, 0xa0, 0x9, 0x80, 0xb, 0x70, 0x0, + 0x0, 0x7d, 0xdc, 0xcd, 0xcc, 0xdf, 0xc9, 0x0, + 0x0, 0x98, 0x22, 0x2a, 0x92, 0x22, 0x6b, 0x0, + 0x0, 0x97, 0x0, 0x9, 0x80, 0x0, 0x5b, 0x0, + 0x0, 0x9f, 0xee, 0xef, 0xfe, 0xee, 0xeb, 0x0, + 0x0, 0x97, 0x0, 0x9, 0x80, 0x0, 0x5b, 0x0, + 0x0, 0x97, 0x0, 0x9, 0x80, 0x0, 0x5b, 0x0, + 0x0, 0x9e, 0xee, 0xef, 0xfe, 0xee, 0xeb, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x1d, 0xdd, 0xdd, 0xdf, 0xfd, 0xdd, 0xdd, 0xd2, + 0x2, 0x22, 0x22, 0x2a, 0x92, 0x22, 0x22, 0x20, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + + /* U+5371 "危" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1f, 0x61, 0x11, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xbe, 0xdd, 0xde, 0xd0, 0x0, 0x0, + 0x0, 0x9, 0xb0, 0x0, 0xd, 0x40, 0x0, 0x0, + 0x0, 0x9f, 0xdc, 0xcc, 0xdf, 0xcc, 0xcc, 0xc2, + 0xc, 0xce, 0x22, 0x22, 0x22, 0x22, 0x22, 0x20, + 0x5, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0x2, 0xfe, 0xee, 0xef, 0xf0, 0x0, + 0x0, 0x3d, 0x2, 0xe0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0x4c, 0x2, 0xe0, 0x0, 0x3, 0xc0, 0x0, + 0x0, 0x69, 0x2, 0xe0, 0x2, 0x28, 0xa0, 0x0, + 0x0, 0xb6, 0x2, 0xe0, 0x7, 0xca, 0x20, 0x10, + 0x1, 0xf1, 0x2, 0xe0, 0x0, 0x0, 0x0, 0xa5, + 0xa, 0xa0, 0x1, 0xf2, 0x0, 0x0, 0x1, 0xe3, + 0x1e, 0x10, 0x0, 0x9f, 0xff, 0xff, 0xff, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5373 "即" */ + 0x2f, 0xff, 0xff, 0xe0, 0xbe, 0xee, 0xec, 0x2e, + 0x0, 0x2, 0xe0, 0xc5, 0x11, 0x4d, 0x2e, 0x0, + 0x2, 0xe0, 0xc4, 0x0, 0x2d, 0x2e, 0x22, 0x24, + 0xe0, 0xc4, 0x0, 0x2d, 0x2f, 0xcc, 0xcd, 0xe0, + 0xc4, 0x0, 0x2d, 0x2e, 0x0, 0x2, 0xe0, 0xc4, + 0x0, 0x2d, 0x2e, 0x0, 0x3, 0xe0, 0xc4, 0x0, + 0x2d, 0x2f, 0xee, 0xee, 0xd0, 0xc4, 0x0, 0x2d, + 0x2e, 0x0, 0x0, 0x0, 0xc4, 0x0, 0x2d, 0x2e, + 0x0, 0x97, 0x0, 0xc4, 0x0, 0x3d, 0x2e, 0x0, + 0x2f, 0x20, 0xc4, 0x7e, 0xf9, 0x2e, 0x38, 0xde, + 0xa0, 0xc4, 0x0, 0x0, 0x9f, 0xc6, 0x11, 0xe1, + 0xc4, 0x0, 0x0, 0x32, 0x0, 0x0, 0x10, 0xc4, + 0x0, 0x0, + + /* U+537B "卻" */ + 0x0, 0x3, 0x10, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe2, 0xc, 0x70, 0x2f, 0xff, 0xf3, 0x0, + 0xb7, 0x0, 0x1e, 0x42, 0xd0, 0xd, 0x30, 0xbb, + 0x5, 0x40, 0x5e, 0x3d, 0x0, 0xd3, 0x2b, 0x0, + 0xd9, 0x0, 0x43, 0xd0, 0xd, 0x30, 0x0, 0x6b, + 0xc9, 0x0, 0x2d, 0x0, 0xd3, 0x0, 0x2e, 0x10, + 0xba, 0x2, 0xd0, 0xd, 0x30, 0x1d, 0x60, 0x0, + 0xc9, 0x3d, 0x0, 0xd3, 0x2d, 0x70, 0x0, 0x1, + 0xb3, 0xd0, 0xd, 0x35, 0x6d, 0xff, 0xff, 0xd0, + 0x2d, 0x0, 0xd3, 0x0, 0xd1, 0x0, 0x1e, 0x2, + 0xd0, 0xd, 0x30, 0xd, 0x10, 0x1, 0xe0, 0x2d, + 0x6b, 0xf2, 0x0, 0xd1, 0x0, 0x1e, 0x2, 0xd3, + 0x63, 0x0, 0xd, 0xee, 0xee, 0xe0, 0x2d, 0x0, + 0x0, 0x0, 0xd1, 0x0, 0x1d, 0x2, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+539A "厚" */ + 0x0, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd3, 0x1b, 0xbb, 0xbb, 0xbb, 0xb2, 0x0, + 0x0, 0xd3, 0x1e, 0x0, 0x0, 0x0, 0xc3, 0x0, + 0x0, 0xd3, 0x1f, 0xbb, 0xbb, 0xbb, 0xf3, 0x0, + 0x0, 0xe3, 0x1e, 0x0, 0x0, 0x0, 0xc3, 0x0, + 0x0, 0xf2, 0x1d, 0xcc, 0xcc, 0xcc, 0xd3, 0x0, + 0x0, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0x1c, 0xcc, 0xcc, 0xdf, 0xe2, 0x0, + 0x2, 0xe0, 0x0, 0x0, 0x9, 0xa6, 0x0, 0x0, + 0x5, 0xb7, 0xcc, 0xcc, 0xcf, 0xcc, 0xcc, 0xc3, + 0x9, 0x71, 0x11, 0x11, 0x3e, 0x11, 0x11, 0x10, + 0xf, 0x20, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, + 0x3a, 0x0, 0x0, 0x7d, 0xe9, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+539F "原" */ + 0x0, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0xd3, 0x0, 0x0, 0x48, 0x0, 0x0, 0x0, + 0x0, 0xd3, 0x0, 0x0, 0xb8, 0x0, 0x0, 0x0, + 0x0, 0xd3, 0x1d, 0xdd, 0xfe, 0xdd, 0xdc, 0x0, + 0x0, 0xd3, 0x2e, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0xe3, 0x2e, 0x11, 0x11, 0x11, 0x3e, 0x0, + 0x0, 0xf2, 0x2f, 0xbb, 0xbb, 0xbb, 0xce, 0x0, + 0x0, 0xf1, 0x2e, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x1, 0xf0, 0x2f, 0xdd, 0xdd, 0xdd, 0xee, 0x0, + 0x3, 0xd0, 0x0, 0x10, 0x1e, 0x0, 0x0, 0x0, + 0x6, 0xa0, 0x8, 0xc0, 0x1e, 0x4, 0xc0, 0x0, + 0xb, 0x60, 0x6e, 0x10, 0x1e, 0x0, 0x7c, 0x0, + 0x2f, 0x6, 0xe2, 0x0, 0x2e, 0x0, 0x9, 0xa0, + 0x15, 0x0, 0x10, 0x5f, 0xea, 0x0, 0x0, 0x20, + + /* U+53B3 "厳" */ + 0x0, 0x1, 0x0, 0x3, 0x0, 0x0, 0x13, 0x0, + 0x0, 0xe, 0x30, 0xa, 0x80, 0x0, 0xb8, 0x0, + 0x0, 0x6, 0xb0, 0x2, 0xb0, 0x5, 0xc0, 0x0, + 0x0, 0xfe, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe3, + 0x0, 0xf0, 0x0, 0x0, 0x0, 0x15, 0x0, 0x0, + 0x0, 0xf3, 0xcc, 0xcd, 0xe0, 0x5b, 0x0, 0x0, + 0x0, 0xf0, 0x0, 0x8, 0x70, 0x9d, 0xaa, 0xa4, + 0x0, 0xf8, 0xfd, 0xdd, 0xf7, 0xe4, 0x27, 0x90, + 0x1, 0xe0, 0xe0, 0x1, 0xd6, 0xf7, 0xa, 0x50, + 0x2, 0xd0, 0xec, 0xcd, 0xdc, 0x5c, 0xe, 0x10, + 0x3, 0xc0, 0xe0, 0x1, 0xd0, 0xb, 0x7b, 0x0, + 0x5, 0xa0, 0xec, 0xcc, 0xd0, 0x5, 0xf3, 0x0, + 0x9, 0x60, 0xe0, 0x2, 0xe1, 0x9, 0xf5, 0x0, + 0xe, 0x2b, 0xfc, 0xcb, 0xf5, 0xab, 0x2d, 0x60, + 0x29, 0x1, 0x0, 0x1, 0xda, 0x70, 0x1, 0xb6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+53BB "去" */ + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x11, 0x11, 0x19, 0x91, 0x11, 0x11, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x1d, 0xdd, 0xdd, 0xde, 0xed, 0xdd, 0xdd, 0xd2, + 0x3, 0x33, 0x36, 0xf5, 0x33, 0x33, 0x33, 0x30, + 0x0, 0x0, 0xc, 0x80, 0x0, 0xa1, 0x0, 0x0, + 0x0, 0x0, 0x6d, 0x0, 0x0, 0x9b, 0x0, 0x0, + 0x0, 0x2, 0xe2, 0x0, 0x0, 0xc, 0x90, 0x0, + 0x0, 0x1d, 0x40, 0x12, 0x34, 0x58, 0xf4, 0x0, + 0x0, 0xdf, 0xff, 0xfe, 0xcb, 0xa9, 0x9e, 0x0, + 0x0, 0x43, 0x20, 0x0, 0x0, 0x0, 0x9, 0x20, + + /* U+53C2 "参" */ + 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0xe5, 0x4, 0xa1, 0x0, 0x0, + 0x0, 0x0, 0x8c, 0x20, 0x0, 0x7e, 0x40, 0x0, + 0x0, 0x3e, 0xfb, 0xcc, 0xdd, 0xee, 0xf7, 0x0, + 0x0, 0x15, 0x43, 0xaa, 0x0, 0x0, 0x2c, 0x10, + 0x0, 0x0, 0x1, 0xf3, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0xee, 0xef, 0xfe, 0xef, 0xfe, 0xee, 0xe2, + 0x0, 0x0, 0x8c, 0x0, 0x10, 0xb9, 0x0, 0x0, + 0x0, 0x9, 0xd1, 0x18, 0xd3, 0xb, 0xa0, 0x0, + 0x4, 0xdb, 0x7b, 0xd7, 0x0, 0x30, 0x9e, 0x70, + 0x1c, 0x50, 0x33, 0x0, 0x6d, 0x70, 0x3, 0xb1, + 0x0, 0x0, 0x26, 0xbd, 0x81, 0x2, 0x70, 0x0, + 0x0, 0x0, 0xa8, 0x30, 0x0, 0x7e, 0x60, 0x0, + 0x0, 0x0, 0x0, 0x15, 0x9e, 0x92, 0x0, 0x0, + 0x0, 0x8, 0xbd, 0xea, 0x61, 0x0, 0x0, 0x0, + 0x0, 0x5, 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+53C3 "參" */ + 0x0, 0x0, 0x1, 0x81, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4d, 0x60, 0x5, 0xd3, 0x0, 0x0, + 0x0, 0x1b, 0xfb, 0xaa, 0xbb, 0xef, 0x50, 0x0, + 0x0, 0x9, 0x54, 0x32, 0x21, 0x12, 0xb1, 0x0, + 0x0, 0x1e, 0x40, 0x2, 0x20, 0x89, 0x22, 0x0, + 0x1, 0xc7, 0x3a, 0xd, 0xa2, 0xe2, 0x5d, 0x10, + 0x7, 0xfd, 0xde, 0xca, 0xcf, 0xec, 0xbb, 0xa0, + 0x0, 0x0, 0x2c, 0xa0, 0xa, 0xc3, 0x0, 0x40, + 0x0, 0x18, 0xe6, 0x6, 0xb0, 0x4d, 0xa4, 0x0, + 0x1b, 0xe7, 0x37, 0xc6, 0x1, 0x40, 0x4b, 0xe3, + 0x4, 0x4, 0xb5, 0x0, 0x6d, 0x50, 0x0, 0x20, + 0x0, 0x0, 0x5, 0xad, 0x81, 0x5, 0x90, 0x0, + 0x0, 0x2, 0xe9, 0x40, 0x2, 0xac, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x16, 0xbd, 0x50, 0x0, 0x0, + 0x0, 0x8, 0xad, 0xd8, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x5, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+53C8 "又" */ + 0x0, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x0, + 0x6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0x0, 0xd4, 0x0, + 0x0, 0x8, 0x90, 0x0, 0x0, 0x5, 0xe0, 0x0, + 0x0, 0x1, 0xf1, 0x0, 0x0, 0xc, 0x70, 0x0, + 0x0, 0x0, 0xa7, 0x0, 0x0, 0x3f, 0x10, 0x0, + 0x0, 0x0, 0x3e, 0x20, 0x0, 0xc7, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xd0, 0xa, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb9, 0x7e, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xbd, 0xeb, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x6e, 0x90, 0x1a, 0xe5, 0x0, 0x0, + 0x1, 0x7d, 0xd4, 0x0, 0x0, 0x6e, 0xd7, 0x10, + 0x2f, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x5b, 0xf3, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+53CA "及" */ + 0xa, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x0, 0x0, + 0x0, 0x11, 0xd5, 0x11, 0x14, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0xc7, 0x0, 0x7, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0xdc, 0x0, 0xb, 0x60, 0x0, 0x0, + 0x0, 0x0, 0xef, 0x10, 0xf, 0xed, 0xdd, 0x30, + 0x0, 0x0, 0xfb, 0x80, 0x2, 0x22, 0x4f, 0x10, + 0x0, 0x2, 0xf2, 0xe0, 0x0, 0x0, 0x8b, 0x0, + 0x0, 0x5, 0xd0, 0x99, 0x0, 0x0, 0xf4, 0x0, + 0x0, 0xb, 0x80, 0x1e, 0x40, 0xa, 0xa0, 0x0, + 0x0, 0x2f, 0x30, 0x3, 0xe3, 0x8c, 0x0, 0x0, + 0x0, 0xab, 0x0, 0x0, 0x6f, 0xe1, 0x0, 0x0, + 0x4, 0xf2, 0x0, 0x3, 0xcd, 0xfa, 0x10, 0x0, + 0x3f, 0x60, 0x5, 0xbf, 0x70, 0x1b, 0xfa, 0x50, + 0x17, 0x0, 0x6c, 0x61, 0x0, 0x0, 0x28, 0xb0, + + /* U+53CB "友" */ + 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x60, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xee, 0xd0, + 0x1, 0x11, 0x2f, 0x31, 0x11, 0x11, 0x11, 0x10, + 0x0, 0x0, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5e, 0x33, 0x33, 0x33, 0x30, 0x0, + 0x0, 0x0, 0x9f, 0xdc, 0xcc, 0xcd, 0xe0, 0x0, + 0x0, 0x0, 0xed, 0x80, 0x0, 0x9, 0x80, 0x0, + 0x0, 0x3, 0xe1, 0xe2, 0x0, 0x2f, 0x10, 0x0, + 0x0, 0xb, 0x80, 0x6c, 0x0, 0xc8, 0x0, 0x0, + 0x0, 0x3f, 0x20, 0x9, 0xcb, 0xa0, 0x0, 0x0, + 0x0, 0xd9, 0x0, 0x2, 0xff, 0x50, 0x0, 0x0, + 0xb, 0xd0, 0x1, 0x8f, 0x75, 0xdc, 0x40, 0x0, + 0x2b, 0x12, 0xcf, 0x91, 0x0, 0x7, 0xdf, 0xb1, + 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x50, + + /* U+53CD "反" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x12, 0x35, 0x67, 0xac, 0xfe, 0x50, 0x0, + 0x2f, 0xdb, 0xa9, 0x76, 0x31, 0x0, 0x0, 0x2, + 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xf4, + 0x44, 0x44, 0x44, 0x44, 0x10, 0x0, 0x3f, 0xcf, + 0xcc, 0xcc, 0xcc, 0xf6, 0x0, 0x4, 0xd0, 0x97, + 0x0, 0x0, 0x2e, 0x0, 0x0, 0x5c, 0x2, 0xe0, + 0x0, 0xa, 0x80, 0x0, 0x6, 0xb0, 0xa, 0x80, + 0x4, 0xf1, 0x0, 0x0, 0x79, 0x0, 0x1e, 0x52, + 0xe4, 0x0, 0x0, 0xa, 0x70, 0x0, 0x3f, 0xe7, + 0x0, 0x0, 0x0, 0xe3, 0x0, 0x6, 0xff, 0x80, + 0x0, 0x0, 0x5e, 0x0, 0x5c, 0xd3, 0x1a, 0xe7, + 0x10, 0xd, 0x64, 0xed, 0x60, 0x0, 0x4, 0xaf, + 0xa0, 0x30, 0x3, 0x0, 0x0, 0x0, 0x0, 0x2, + + /* U+53D6 "取" */ + 0x3f, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe0, 0x3, 0xc0, 0xbc, 0xcc, 0xcc, 0x90, + 0x1, 0xe0, 0x3, 0xc0, 0x3f, 0x33, 0x38, 0x90, + 0x1, 0xe1, 0x15, 0xc0, 0xd, 0x20, 0x9, 0x50, + 0x1, 0xfd, 0xde, 0xc0, 0x9, 0x50, 0xd, 0x20, + 0x1, 0xe0, 0x3, 0xc0, 0x6, 0x80, 0x1e, 0x0, + 0x1, 0xe0, 0x3, 0xc0, 0x2, 0xd0, 0x7a, 0x0, + 0x1, 0xff, 0xff, 0xc0, 0x0, 0xc3, 0xd3, 0x0, + 0x1, 0xe0, 0x3, 0xc0, 0x0, 0x6c, 0xc0, 0x0, + 0x1, 0xe0, 0x3, 0xd3, 0x0, 0x1f, 0x60, 0x0, + 0x5, 0xf8, 0xbe, 0xfb, 0x20, 0x8f, 0xb0, 0x0, + 0x3c, 0x96, 0x34, 0xc0, 0x5, 0xe2, 0xc7, 0x0, + 0x0, 0x0, 0x3, 0xc0, 0x6e, 0x30, 0x2e, 0x90, + 0x0, 0x0, 0x3, 0xc1, 0xc2, 0x0, 0x1, 0xa2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+53D7 "受" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x12, 0x45, 0x68, 0xac, 0xf8, 0x0, + 0x9, 0xfe, 0xdc, 0xbb, 0x86, 0x42, 0x10, 0x0, + 0x0, 0xb, 0x0, 0xd, 0x40, 0x0, 0xc6, 0x0, + 0x0, 0xb, 0x60, 0x7, 0x90, 0x3, 0xe0, 0x0, + 0x0, 0x5, 0xa0, 0x3, 0x90, 0xb, 0x60, 0x0, + 0xd, 0xef, 0xfe, 0xee, 0xee, 0xef, 0xfe, 0xd0, + 0xe, 0x10, 0x0, 0x0, 0x0, 0x0, 0x1, 0xe0, + 0xe, 0x10, 0x0, 0x0, 0x0, 0x0, 0x1, 0xe0, + 0x4, 0xc, 0xff, 0xff, 0xff, 0xff, 0xb0, 0x40, + 0x0, 0x1, 0xe5, 0x0, 0x0, 0x2e, 0x30, 0x0, + 0x0, 0x0, 0x3e, 0x30, 0x1, 0xd7, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xe7, 0x4e, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6f, 0xf9, 0x0, 0x0, 0x0, + 0x0, 0x14, 0x8e, 0xc6, 0x5b, 0xf9, 0x52, 0x0, + 0xd, 0xfb, 0x72, 0x0, 0x0, 0x27, 0xbe, 0xe0, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+53E3 "口" */ + 0xde, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe4, 0x22, + 0x22, 0x22, 0x22, 0x5f, 0xe2, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x3f, + 0xe2, 0x0, 0x0, 0x0, 0x0, 0x3f, 0xe2, 0x0, + 0x0, 0x0, 0x0, 0x3f, 0xe2, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x3f, + 0xe2, 0x0, 0x0, 0x0, 0x0, 0x3f, 0xe2, 0x0, + 0x0, 0x0, 0x0, 0x3f, 0xed, 0xdd, 0xdd, 0xdd, + 0xdd, 0xef, 0xe6, 0x33, 0x33, 0x33, 0x33, 0x6f, + 0xe2, 0x0, 0x0, 0x0, 0x0, 0x2d, + + /* U+53E4 "古" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x4, 0x44, 0x44, 0x4b, 0xa4, 0x44, 0x44, 0x40, + 0x1c, 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xcc, 0xc2, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x0, + 0x0, 0x5b, 0x11, 0x11, 0x11, 0x11, 0xb6, 0x0, + 0x0, 0x5b, 0x0, 0x0, 0x0, 0x0, 0xb6, 0x0, + 0x0, 0x5b, 0x0, 0x0, 0x0, 0x0, 0xb6, 0x0, + 0x0, 0x5b, 0x0, 0x0, 0x0, 0x0, 0xb6, 0x0, + 0x0, 0x5f, 0xdd, 0xdd, 0xdd, 0xdd, 0xf6, 0x0, + 0x0, 0x5c, 0x22, 0x22, 0x22, 0x22, 0xb6, 0x0, + + /* U+53E5 "句" */ + 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0xe, + 0x50, 0x0, 0x0, 0x0, 0x4, 0xd0, 0xa, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x4c, 0x6, 0xe3, 0xdd, + 0xdd, 0xdd, 0x10, 0x5, 0xc0, 0xd3, 0x1e, 0x11, + 0x11, 0xf1, 0x0, 0x5b, 0x0, 0x1, 0xe0, 0x0, + 0xf, 0x10, 0x6, 0xa0, 0x0, 0x1e, 0x0, 0x0, + 0xf1, 0x0, 0x79, 0x0, 0x1, 0xe0, 0x0, 0xf, + 0x10, 0x9, 0x80, 0x0, 0x1f, 0xee, 0xee, 0xf1, + 0x0, 0xa6, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, + 0xd, 0x40, 0x0, 0x0, 0x0, 0x0, 0x11, 0x15, + 0xf1, 0x0, 0x0, 0x0, 0x0, 0xb, 0xff, 0xf6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+53E6 "另" */ + 0x0, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x0, + 0x5, 0xb0, 0x0, 0x0, 0x0, 0xa, 0x70, 0x0, + 0x5a, 0x0, 0x0, 0x0, 0x0, 0xa7, 0x0, 0x5, + 0xa0, 0x0, 0x0, 0x0, 0xa, 0x70, 0x0, 0x5a, + 0x0, 0x0, 0x0, 0x0, 0xa7, 0x0, 0x5, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x70, 0x0, 0x0, 0x0, + 0xd, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf2, 0x0, 0x0, 0x0, 0xc, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x9, 0x90, + 0x0, 0x2, 0xf0, 0x0, 0x0, 0x3, 0xf2, 0x0, + 0x0, 0x3d, 0x0, 0x0, 0x5, 0xe5, 0x0, 0x0, + 0x6, 0xb0, 0x1, 0x6c, 0xd4, 0x0, 0x1, 0x0, + 0xa8, 0x0, 0xda, 0x50, 0x0, 0x0, 0xbf, 0xfc, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+53EA "只" */ + 0x0, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x0, + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x3, + 0xd0, 0x0, 0x0, 0x0, 0x3, 0xe0, 0x0, 0x3d, + 0x0, 0x0, 0x0, 0x0, 0x3e, 0x0, 0x3, 0xd0, + 0x0, 0x0, 0x0, 0x3, 0xe0, 0x0, 0x3d, 0x0, + 0x0, 0x0, 0x0, 0x3e, 0x0, 0x3, 0xd0, 0x0, + 0x0, 0x0, 0x4, 0xe0, 0x0, 0x3f, 0xff, 0xff, + 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x20, 0x0, + 0x41, 0x0, 0x0, 0x0, 0x3, 0xe4, 0x0, 0x8, + 0xe3, 0x0, 0x0, 0x3, 0xe5, 0x0, 0x0, 0x5, + 0xe5, 0x0, 0x8, 0xe5, 0x0, 0x0, 0x0, 0x3, + 0xe6, 0xa, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xf3, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, + + /* U+53EB "叫" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x3e, + 0xee, 0xed, 0x2, 0xe0, 0x0, 0xe2, 0x3d, 0x0, + 0x2e, 0x2, 0xe0, 0x0, 0xe2, 0x3c, 0x0, 0x1e, + 0x2, 0xe0, 0x0, 0xe2, 0x3c, 0x0, 0x1e, 0x2, + 0xe0, 0x0, 0xe2, 0x3c, 0x0, 0x1e, 0x2, 0xe0, + 0x0, 0xe2, 0x3c, 0x0, 0x1e, 0x2, 0xe0, 0x0, + 0xe2, 0x3c, 0x0, 0x1e, 0x2, 0xe0, 0x0, 0xe2, + 0x3c, 0x0, 0x1e, 0x2, 0xe0, 0x3, 0xf2, 0x3f, + 0xff, 0xfe, 0x6, 0xfb, 0xfc, 0xf2, 0x3d, 0x0, + 0x0, 0xd, 0xa5, 0x10, 0xe2, 0x28, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe2, + + /* U+53EF "可" */ + 0x1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, + 0x0, 0x6f, 0xff, 0xff, 0xf1, 0x0, 0xf2, 0x0, + 0x0, 0x6a, 0x0, 0x0, 0xf1, 0x0, 0xf2, 0x0, + 0x0, 0x69, 0x0, 0x0, 0xf1, 0x0, 0xf2, 0x0, + 0x0, 0x69, 0x0, 0x0, 0xf1, 0x0, 0xf2, 0x0, + 0x0, 0x69, 0x0, 0x0, 0xf1, 0x0, 0xf2, 0x0, + 0x0, 0x6f, 0xff, 0xff, 0xf1, 0x0, 0xf2, 0x0, + 0x0, 0x6a, 0x11, 0x11, 0x10, 0x0, 0xf2, 0x0, + 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x12, 0xf2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2f, 0xfe, 0xa0, 0x0, + + /* U+53F0 "台" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9c, 0x0, 0x2, 0x0, 0x0, 0x0, 0x5, 0xe1, + 0x0, 0x1e, 0x50, 0x0, 0x0, 0x3e, 0x20, 0x0, + 0x3, 0xe5, 0x0, 0x4, 0xd2, 0x0, 0x12, 0x34, + 0x8f, 0x50, 0x3f, 0xff, 0xff, 0xed, 0xcb, 0xaa, + 0xf2, 0x4, 0x21, 0x0, 0x0, 0x0, 0x0, 0x86, + 0x0, 0x33, 0x33, 0x33, 0x33, 0x33, 0x0, 0x1, + 0xfc, 0xcc, 0xcc, 0xcc, 0xcf, 0x10, 0x1, 0xf0, + 0x0, 0x0, 0x0, 0xf, 0x10, 0x1, 0xf0, 0x0, + 0x0, 0x0, 0xf, 0x10, 0x1, 0xf0, 0x0, 0x0, + 0x0, 0xf, 0x10, 0x1, 0xfe, 0xee, 0xee, 0xee, + 0xef, 0x10, 0x1, 0xf2, 0x22, 0x22, 0x22, 0x3f, + 0x10, + + /* U+53F2 "史" */ + 0x0, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, + 0x0, 0xf2, 0x11, 0x15, 0xd1, 0x11, 0x1a, 0x70, + 0x0, 0xf0, 0x0, 0x4, 0xc0, 0x0, 0x9, 0x70, + 0x0, 0xf0, 0x0, 0x4, 0xc0, 0x0, 0x9, 0x70, + 0x0, 0xfe, 0xee, 0xee, 0xfe, 0xee, 0xef, 0x70, + 0x0, 0x13, 0x11, 0x17, 0xb1, 0x11, 0x11, 0x0, + 0x0, 0xe, 0x40, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xd1, 0xe, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9d, 0xac, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0xf9, 0x10, 0x0, 0x0, 0x0, + 0x1, 0x5a, 0xf8, 0x3a, 0xfc, 0x85, 0x31, 0x0, + 0x1e, 0xc7, 0x10, 0x0, 0x15, 0x9b, 0xef, 0xf7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+53F3 "右" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc6, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x22, 0x23, 0xf4, 0x22, 0x22, 0x22, 0x20, + 0xd, 0xdd, 0xdf, 0xfd, 0xdd, 0xdd, 0xdd, 0xd0, + 0x0, 0x0, 0xd, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xf6, 0x11, 0x11, 0x11, 0x11, 0x0, + 0x0, 0xa, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x0, + 0x0, 0x8d, 0xb6, 0x0, 0x0, 0x0, 0x4d, 0x0, + 0x9, 0xd1, 0xa6, 0x0, 0x0, 0x0, 0x4d, 0x0, + 0x2a, 0x10, 0xa6, 0x0, 0x0, 0x0, 0x4d, 0x0, + 0x0, 0x0, 0xa6, 0x0, 0x0, 0x0, 0x4d, 0x0, + 0x0, 0x0, 0xaf, 0xee, 0xee, 0xee, 0xed, 0x0, + 0x0, 0x0, 0xa7, 0x22, 0x22, 0x22, 0x5c, 0x0, + + /* U+53F7 "号" */ + 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0xf0, 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0xf0, + 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0xfb, 0xbb, + 0xbb, 0xbb, 0xbf, 0x0, 0x0, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7e, 0xee, 0xee, 0xee, 0xfe, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xff, + 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+53F8 "司" */ + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf0, 0x7c, 0xcc, 0xcc, + 0xcc, 0xcc, 0x0, 0xf0, 0x12, 0x22, 0x22, 0x22, + 0x22, 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0x8, 0xff, 0xff, 0xff, 0xd0, 0x0, + 0xf0, 0x8, 0x70, 0x0, 0x1, 0xe0, 0x0, 0xf0, + 0x8, 0x70, 0x0, 0x1, 0xe0, 0x0, 0xf0, 0x8, + 0x70, 0x0, 0x1, 0xe0, 0x0, 0xf0, 0x8, 0xed, + 0xdd, 0xde, 0xe0, 0x0, 0xf0, 0x8, 0x80, 0x0, + 0x0, 0x0, 0x0, 0xf0, 0x2, 0x20, 0x0, 0x0, + 0x2, 0x23, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0xfe, 0x80, + + /* U+5403 "吃" */ + 0x0, 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xf1, 0x0, 0x0, 0x0, 0xef, + 0xff, 0x10, 0x7c, 0x0, 0x0, 0x0, 0xe, 0x21, + 0xe1, 0xe, 0xff, 0xff, 0xff, 0xc0, 0xe1, 0xe, + 0x19, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x10, 0xe5, + 0xf2, 0x0, 0x0, 0x0, 0x0, 0xe1, 0xe, 0x13, + 0xad, 0xdd, 0xdd, 0xb0, 0xe, 0x10, 0xe1, 0x1, + 0x22, 0x2c, 0xd2, 0x0, 0xe1, 0xe, 0x10, 0x0, + 0xb, 0xc1, 0x0, 0xe, 0x10, 0xe1, 0x0, 0x1c, + 0xa0, 0x0, 0x0, 0xef, 0xef, 0x10, 0x1d, 0x90, + 0x0, 0x0, 0xe, 0x21, 0x10, 0xc, 0x90, 0x0, + 0x0, 0x61, 0x80, 0x0, 0x7, 0xb0, 0x0, 0x0, + 0xc, 0x20, 0x0, 0x0, 0xb9, 0x10, 0x0, 0x2, + 0xf0, 0x0, 0x0, 0x4, 0xdf, 0xff, 0xff, 0xf8, + 0x0, + + /* U+5404 "各" */ + 0x0, 0x0, 0x5, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1e, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xdf, 0xee, 0xee, 0xee, 0x50, 0x0, + 0x0, 0x2c, 0xf3, 0x0, 0x0, 0x8d, 0x0, 0x0, + 0x4, 0xe8, 0x4d, 0x20, 0x6, 0xe2, 0x0, 0x0, + 0xd, 0x50, 0x4, 0xe4, 0x9d, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8f, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4c, 0xd6, 0xae, 0x81, 0x0, 0x0, + 0x2, 0x7d, 0xe6, 0x0, 0x2, 0xbf, 0xa5, 0x10, + 0x7f, 0xa7, 0x33, 0x33, 0x33, 0x35, 0x8d, 0xc0, + 0x0, 0xe, 0xdc, 0xcc, 0xcc, 0xcf, 0x40, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0xd, 0x40, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0xd, 0x40, 0x0, + 0x0, 0xe, 0x53, 0x33, 0x33, 0x3e, 0x40, 0x0, + 0x0, 0xe, 0xcc, 0xcc, 0xcc, 0xce, 0x40, 0x0, + + /* U+5408 "合" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5e, 0xe6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0xe3, 0x2d, 0x90, 0x0, 0x0, + 0x0, 0x1, 0xae, 0x30, 0x1, 0xcb, 0x20, 0x0, + 0x0, 0x6e, 0xb1, 0x0, 0x0, 0x19, 0xf9, 0x10, + 0x2e, 0xd6, 0xee, 0xee, 0xee, 0xee, 0x2a, 0xf2, + 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0xfe, 0xee, 0xee, 0xef, 0xe0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0xe, 0xfe, 0xee, 0xee, 0xef, 0xe0, 0x0, + 0x0, 0xe, 0x30, 0x0, 0x0, 0x3, 0xe0, 0x0, + + /* U+540C "同" */ + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xc4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe2, 0xc4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe2, 0xc4, 0x3f, 0xff, + 0xff, 0xff, 0xe0, 0xe2, 0xc4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0xc4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe2, 0xc4, 0x6, 0xfe, 0xee, 0xef, 0x0, + 0xe2, 0xc4, 0x6, 0x90, 0x0, 0xf, 0x0, 0xe2, + 0xc4, 0x6, 0x90, 0x0, 0xf, 0x0, 0xe2, 0xc4, + 0x6, 0x90, 0x0, 0xf, 0x0, 0xe2, 0xc4, 0x6, + 0xfe, 0xee, 0xef, 0x0, 0xe2, 0xc4, 0x6, 0x90, + 0x0, 0x0, 0x0, 0xe2, 0xc4, 0x1, 0x20, 0x0, + 0x0, 0x1, 0xf2, 0xc4, 0x0, 0x0, 0x0, 0x1, + 0xff, 0xb0, + + /* U+540D "名" */ + 0x0, 0x0, 0x0, 0x55, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0xff, 0xff, 0xff, 0xf6, 0x0, 0x5, 0xe5, + 0x0, 0x0, 0x5, 0xe1, 0x1, 0xae, 0x40, 0x0, + 0x0, 0x2f, 0x50, 0x7, 0xa1, 0x6d, 0x20, 0x3, + 0xe7, 0x0, 0x0, 0x0, 0x7, 0xf5, 0x6e, 0x60, + 0x0, 0x0, 0x0, 0x0, 0x7f, 0xc2, 0x0, 0x0, + 0x0, 0x0, 0x4b, 0xfa, 0x22, 0x22, 0x21, 0x4, + 0x9e, 0xfd, 0xdd, 0xdd, 0xdd, 0xec, 0x9, 0x73, + 0xf2, 0x0, 0x0, 0x0, 0x4c, 0x0, 0x0, 0xe2, + 0x0, 0x0, 0x0, 0x4c, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x0, 0x4c, 0x0, 0x0, 0xed, 0xdd, 0xdd, + 0xdd, 0xec, 0x0, 0x0, 0xe4, 0x22, 0x22, 0x22, + 0x6c, + + /* U+5411 "向" */ + 0x0, 0x0, 0x0, 0x82, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x90, 0x0, 0x0, 0x0, 0x2d, 0xdd, 0xdf, + 0xed, 0xdd, 0xdd, 0xdc, 0x2e, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x5e, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0x2e, 0x0, 0x22, 0x22, 0x22, 0x0, + 0x2e, 0x2e, 0x0, 0xed, 0xdd, 0xdf, 0x20, 0x2e, + 0x2e, 0x0, 0xe1, 0x0, 0xd, 0x20, 0x2e, 0x2e, + 0x0, 0xe1, 0x0, 0xd, 0x20, 0x2e, 0x2e, 0x0, + 0xe1, 0x0, 0xd, 0x20, 0x2e, 0x2e, 0x0, 0xef, + 0xee, 0xee, 0x20, 0x2e, 0x2e, 0x0, 0xe1, 0x0, + 0x0, 0x0, 0x2e, 0x2e, 0x0, 0x40, 0x0, 0x1, + 0x11, 0x4e, 0x2e, 0x0, 0x0, 0x0, 0x7, 0xff, + 0xe7, + + /* U+5426 "否" */ + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0x0, 0x0, 0x4, 0xf5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6f, 0x90, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x2b, 0xcb, 0x85, 0xea, 0x20, 0x0, + 0x0, 0x3b, 0xf7, 0x8, 0x80, 0x7, 0xe9, 0x10, + 0x2c, 0xf9, 0x20, 0x8, 0x80, 0x0, 0x1a, 0xe1, + 0x6, 0x10, 0x0, 0x8, 0x80, 0x0, 0x0, 0x20, + 0x0, 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0xee, 0xee, 0xee, 0xee, 0xe3, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe4, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe4, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe4, 0x0, + 0x0, 0x1f, 0xbb, 0xbb, 0xbb, 0xbb, 0xf4, 0x0, + 0x0, 0x1f, 0x33, 0x33, 0x33, 0x33, 0xe4, 0x0, + + /* U+5427 "吧" */ + 0x0, 0x0, 0x2, 0xff, 0xff, 0xff, 0xfd, 0xd, + 0xff, 0xf1, 0x2e, 0x0, 0xe1, 0x3, 0xd0, 0xe2, + 0xe, 0x12, 0xe0, 0xe, 0x10, 0x3d, 0xe, 0x10, + 0xe1, 0x2e, 0x0, 0xe1, 0x3, 0xd0, 0xe1, 0xe, + 0x12, 0xe0, 0xe, 0x10, 0x3d, 0xe, 0x10, 0xe1, + 0x2e, 0x0, 0xe1, 0x3, 0xd0, 0xe1, 0xe, 0x12, + 0xe0, 0xe, 0x10, 0x4d, 0xe, 0x10, 0xe1, 0x2f, + 0xee, 0xee, 0xef, 0xd0, 0xe1, 0xe, 0x12, 0xe0, + 0x0, 0x0, 0x14, 0xe, 0xff, 0xf1, 0x2e, 0x0, + 0x0, 0x0, 0x0, 0xe1, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0x2, 0x6, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0xa6, 0x0, 0x0, 0x1, 0xf2, 0x0, 0x0, + 0x1d, 0x30, 0x0, 0x0, 0x8, 0xff, 0xff, 0xff, + 0xa0, + + /* U+5440 "呀" */ + 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, 0xfd, 0xef, + 0xff, 0x10, 0x0, 0x0, 0xf, 0x0, 0xe2, 0x1e, + 0x10, 0xd0, 0x0, 0xf, 0x0, 0xe1, 0xe, 0x12, + 0xd0, 0x0, 0xf, 0x0, 0xe1, 0xe, 0x14, 0xb0, + 0x0, 0xf, 0x0, 0xe1, 0xe, 0x17, 0x91, 0x11, + 0x1f, 0x11, 0xe1, 0xe, 0x1a, 0xff, 0xff, 0xff, + 0xff, 0xe1, 0xe, 0x10, 0x0, 0x5, 0xdf, 0x0, + 0xe1, 0xe, 0x10, 0x0, 0x5d, 0x2f, 0x0, 0xef, + 0xef, 0x10, 0x7, 0xd1, 0xf, 0x0, 0xe2, 0x11, + 0x1, 0xbd, 0x10, 0xf, 0x0, 0x80, 0x0, 0x6e, + 0x90, 0x0, 0xf, 0x0, 0x0, 0x1, 0xa4, 0x0, + 0x11, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, + 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+544A "告" */ + 0x0, 0x2, 0xb0, 0x3, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x80, 0x3, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x0, + 0x0, 0xc6, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0, + 0x8, 0xb0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0, + 0x3, 0x43, 0x33, 0x35, 0xe3, 0x33, 0x33, 0x30, + 0xc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0xee, 0xee, 0xee, 0xee, 0xe2, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x0, 0x0, 0xf2, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, + 0x0, 0xf, 0xcb, 0xbb, 0xbb, 0xbb, 0xf2, 0x0, + 0x0, 0xf, 0x44, 0x44, 0x44, 0x44, 0xf2, 0x0, + + /* U+5462 "呢" */ + 0x0, 0x0, 0xa, 0xff, 0xff, 0xff, 0xf4, 0xdf, + 0xff, 0x1a, 0x40, 0x0, 0x0, 0xb4, 0xe2, 0x1e, + 0x1a, 0x40, 0x0, 0x0, 0xb4, 0xe1, 0xe, 0x1a, + 0x50, 0x0, 0x0, 0xb4, 0xe1, 0xe, 0x1a, 0xfe, + 0xee, 0xee, 0xe4, 0xe1, 0xe, 0x1b, 0x40, 0xa0, + 0x0, 0x0, 0xe1, 0xe, 0x1c, 0x40, 0xf0, 0x0, + 0x72, 0xe1, 0xe, 0x1d, 0x30, 0xf0, 0x3c, 0xb2, + 0xe1, 0xe, 0x1e, 0x20, 0xfb, 0xc4, 0x0, 0xef, + 0xef, 0x1f, 0x0, 0xf4, 0x0, 0x0, 0xe2, 0x11, + 0x3d, 0x0, 0xf0, 0x0, 0x1, 0x80, 0x0, 0x88, + 0x0, 0xf0, 0x0, 0x1d, 0x0, 0x1, 0xe2, 0x0, + 0xf1, 0x0, 0x4c, 0x0, 0x4, 0x90, 0x0, 0xbf, + 0xff, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5468 "周" */ + 0x0, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0xc4, 0x0, 0x1, 0x0, 0x0, 0x2e, 0x0, 0xc4, + 0x0, 0xb, 0x50, 0x0, 0x2e, 0x0, 0xc4, 0x8d, + 0xdf, 0xed, 0xd6, 0x2e, 0x0, 0xc4, 0x0, 0xb, + 0x50, 0x0, 0x2e, 0x0, 0xc4, 0x11, 0x1b, 0x61, + 0x11, 0x2e, 0x0, 0xe4, 0xcc, 0xcc, 0xcc, 0xca, + 0x2e, 0x0, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x2e, + 0x0, 0xf0, 0x3f, 0xdd, 0xde, 0xf0, 0x2e, 0x2, + 0xe0, 0x3c, 0x0, 0x0, 0xf0, 0x2e, 0x6, 0xb0, + 0x3c, 0x0, 0x0, 0xf0, 0x2e, 0xb, 0x60, 0x3f, + 0xee, 0xee, 0xf0, 0x2e, 0x3f, 0x10, 0x3c, 0x0, + 0x0, 0x0, 0x3e, 0x68, 0x0, 0x0, 0x0, 0x0, + 0xdf, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5473 "味" */ + 0x0, 0x0, 0x0, 0x0, 0x79, 0x0, 0x0, 0xd, + 0xdd, 0xe1, 0x0, 0x7, 0x90, 0x0, 0x0, 0xe1, + 0xe, 0x1b, 0xff, 0xff, 0xff, 0xf2, 0xe, 0x10, + 0xe1, 0x1, 0x17, 0xa1, 0x11, 0x0, 0xe1, 0xe, + 0x10, 0x0, 0x79, 0x0, 0x0, 0xe, 0x10, 0xe1, + 0x0, 0x7, 0x90, 0x0, 0x0, 0xe1, 0xe, 0x6f, + 0xff, 0xff, 0xff, 0xfd, 0xe, 0x10, 0xe1, 0x0, + 0x4f, 0xf6, 0x0, 0x0, 0xe1, 0xe, 0x10, 0xc, + 0xbc, 0xd0, 0x0, 0xe, 0xfe, 0xf1, 0x6, 0xa7, + 0x98, 0x70, 0x0, 0xe2, 0x11, 0x3, 0xe1, 0x79, + 0x1e, 0x30, 0x8, 0x0, 0x3, 0xe4, 0x7, 0x90, + 0x4e, 0x20, 0x0, 0x1, 0xe4, 0x0, 0x79, 0x0, + 0x6b, 0x0, 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, + 0x0, + + /* U+547C "呼" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, + 0x0, 0x0, 0x24, 0x67, 0xac, 0xfd, 0x40, 0xdf, + 0xfd, 0xb, 0xa9, 0x8f, 0x20, 0x0, 0xe, 0x11, + 0xe0, 0x32, 0x2, 0xe0, 0x6, 0x40, 0xe1, 0x1e, + 0x5, 0xa0, 0x2e, 0x0, 0xe3, 0xe, 0x11, 0xe0, + 0xe, 0x12, 0xe0, 0x3d, 0x0, 0xe1, 0x1e, 0x0, + 0xb5, 0x2e, 0x9, 0x70, 0xe, 0x11, 0xe0, 0x6, + 0x52, 0xe0, 0xb0, 0x0, 0xe1, 0x1e, 0x37, 0x77, + 0x8f, 0x77, 0x77, 0x2e, 0x11, 0xe3, 0x99, 0x9a, + 0xf9, 0x99, 0x92, 0xef, 0xfd, 0x0, 0x0, 0x2e, + 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0x2, 0xe0, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8f, 0xf9, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+547D "命" */ + 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xbb, 0xba, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3d, 0x90, 0xa, 0xd3, 0x0, 0x0, + 0x0, 0x2a, 0xe6, 0x0, 0x0, 0x6e, 0xa2, 0x0, + 0x2b, 0xe8, 0x4f, 0xff, 0xff, 0xf2, 0x8f, 0xc2, + 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, + 0x0, 0xef, 0xff, 0xd0, 0x5f, 0xff, 0xfe, 0x0, + 0x0, 0xe1, 0x2, 0xd0, 0x5b, 0x0, 0x1f, 0x0, + 0x0, 0xe1, 0x2, 0xd0, 0x5b, 0x0, 0x1f, 0x0, + 0x0, 0xe1, 0x2, 0xd0, 0x5b, 0x0, 0x1f, 0x0, + 0x0, 0xe6, 0x56, 0xd0, 0x5b, 0x0, 0x1f, 0x0, + 0x0, 0xea, 0xaa, 0x80, 0x5b, 0x2f, 0xfa, 0x0, + 0x0, 0xc1, 0x0, 0x0, 0x5b, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x5b, 0x0, 0x0, 0x0, + + /* U+548C "和" */ + 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x58, 0xce, 0x60, 0x0, 0x0, 0x0, 0xb, + 0xb9, 0xf3, 0x0, 0x7f, 0xff, 0xff, 0x30, 0x0, + 0xf, 0x10, 0x7, 0x81, 0x11, 0xe3, 0x0, 0x0, + 0xf1, 0x0, 0x77, 0x0, 0xe, 0x32, 0xee, 0xef, + 0xee, 0xe7, 0x70, 0x0, 0xe3, 0x1, 0x18, 0xf4, + 0x11, 0x77, 0x0, 0xe, 0x30, 0x0, 0xdf, 0xd1, + 0x7, 0x70, 0x0, 0xe3, 0x0, 0x69, 0xf7, 0xc0, + 0x77, 0x0, 0xe, 0x30, 0xd, 0x2f, 0x1a, 0x87, + 0x70, 0x0, 0xe3, 0x9, 0x90, 0xf1, 0x13, 0x77, + 0x0, 0xe, 0x35, 0xe1, 0xf, 0x10, 0x7, 0x70, + 0x0, 0xe3, 0x23, 0x0, 0xf1, 0x0, 0x7f, 0xff, + 0xff, 0x30, 0x0, 0xf, 0x10, 0x7, 0x81, 0x11, + 0xe3, 0x0, 0x0, 0xf1, 0x0, 0x44, 0x0, 0x5, + 0x10, + + /* U+54B2 "咲" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x40, 0x0, + 0x0, 0x0, 0xd, 0x40, 0x0, 0x3e, 0x10, 0xbc, + 0xcc, 0x90, 0x4d, 0x0, 0xb, 0x70, 0xe, 0x43, + 0x6c, 0x0, 0xb1, 0x1, 0xb0, 0x0, 0xe1, 0x3, + 0xc8, 0xff, 0xff, 0xff, 0xfd, 0xe, 0x10, 0x3c, + 0x1, 0x13, 0xe1, 0x11, 0x10, 0xe1, 0x3, 0xc0, + 0x0, 0x2e, 0x0, 0x0, 0xe, 0x10, 0x3c, 0x0, + 0x2, 0xe0, 0x0, 0x0, 0xe1, 0x3, 0xcb, 0xcc, + 0xdf, 0xcc, 0xcc, 0x3e, 0x10, 0x4c, 0x33, 0x38, + 0xf7, 0x33, 0x31, 0xef, 0xff, 0xc0, 0x0, 0x9e, + 0x90, 0x0, 0xe, 0x10, 0x0, 0x0, 0x2f, 0x2d, + 0x20, 0x0, 0x40, 0x0, 0x0, 0x2e, 0x70, 0x5c, + 0x0, 0x0, 0x0, 0x0, 0x6e, 0x70, 0x0, 0xbc, + 0x20, 0x0, 0x0, 0xdc, 0x30, 0x0, 0x0, 0x9f, + 0x30, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+54C1 "品" */ + 0x0, 0x4f, 0xff, 0xff, 0xff, 0xf2, 0x0, 0x0, + 0x4c, 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x4c, + 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x4c, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0x4d, 0x44, 0x44, + 0x44, 0xf2, 0x0, 0x0, 0x3b, 0xbb, 0xbb, 0xbb, + 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xce, 0xee, 0xed, 0x2, 0xee, 0xee, 0xeb, + 0xd4, 0x11, 0x3e, 0x2, 0xd1, 0x11, 0x5c, 0xd2, + 0x0, 0x2e, 0x2, 0xd0, 0x0, 0x4c, 0xd2, 0x0, + 0x2e, 0x2, 0xd0, 0x0, 0x4c, 0xd2, 0x0, 0x2e, + 0x2, 0xd0, 0x0, 0x4c, 0xde, 0xee, 0xee, 0x2, + 0xfe, 0xee, 0xec, 0xd5, 0x22, 0x4c, 0x2, 0xd2, + 0x22, 0x6b, + + /* U+54E1 "員" */ + 0x0, 0x2f, 0xdd, 0xdd, 0xdd, 0xde, 0xe0, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x3, 0xe0, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x3, 0xe0, 0x0, + 0x0, 0x2e, 0xee, 0xee, 0xee, 0xee, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xdd, 0xcc, 0xcc, 0xcc, 0xcc, 0xe8, 0x0, + 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x88, 0x0, + 0x0, 0xdd, 0xcc, 0xcc, 0xcc, 0xcc, 0xe8, 0x0, + 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x88, 0x0, + 0x0, 0xdd, 0xcc, 0xcc, 0xcc, 0xcc, 0xe8, 0x0, + 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x88, 0x0, + 0x0, 0xad, 0xdd, 0xdd, 0xdd, 0xdd, 0xd7, 0x0, + 0x0, 0x4, 0xcb, 0x0, 0x5, 0xea, 0x40, 0x0, + 0x2a, 0xeb, 0x50, 0x0, 0x0, 0x5, 0xbe, 0x80, + 0x5, 0x10, 0x0, 0x0, 0x0, 0x0, 0x2, 0x40, + + /* U+54EA "哪" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xff, 0xef, 0xf, 0xee, 0xe0, 0xdf, + 0xfa, 0x3, 0xa0, 0xe0, 0xe0, 0x2c, 0xd, 0x3, + 0xa0, 0x3a, 0xe, 0xe, 0x6, 0x80, 0xd0, 0x3a, + 0x3, 0xa0, 0xe0, 0xe0, 0xb3, 0xd, 0x3, 0xaa, + 0xff, 0xee, 0xe, 0xd, 0x0, 0xd0, 0x3a, 0x4, + 0xa0, 0xe0, 0xe3, 0xa0, 0xd, 0x3, 0xa0, 0x49, + 0xe, 0xe, 0xc, 0x20, 0xd0, 0x3a, 0x5, 0x80, + 0xe0, 0xe0, 0x58, 0xd, 0x3, 0xaa, 0xff, 0xfe, + 0xe, 0x1, 0xc0, 0xdf, 0xfa, 0xa, 0x20, 0xd0, + 0xe0, 0xe, 0xd, 0x0, 0x0, 0xd0, 0x1d, 0xe, + 0x2, 0xd0, 0x60, 0x0, 0x69, 0x2, 0xc0, 0xe6, + 0xe6, 0x0, 0x0, 0x1d, 0x10, 0x4b, 0xe, 0x0, + 0x0, 0x0, 0x5, 0x60, 0xee, 0x50, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5546 "商" */ + 0x0, 0x0, 0x0, 0x72, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8, 0xa0, 0x0, 0x0, 0x0, 0xdd, + 0xdd, 0xdd, 0xef, 0xdd, 0xdd, 0xdd, 0x1, 0x11, + 0x58, 0x11, 0x11, 0x77, 0x11, 0x10, 0x0, 0x2, + 0xf1, 0x0, 0xe, 0x40, 0x0, 0x0, 0x11, 0x19, + 0x41, 0x17, 0xc1, 0x11, 0x0, 0xf, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0xf1, 0x0, 0xf0, 0x5, 0xb0, + 0x9, 0x70, 0xd, 0x10, 0xf, 0x9, 0xc1, 0x0, + 0x8, 0xd3, 0xd1, 0x0, 0xf2, 0x7a, 0xaa, 0xaa, + 0x93, 0x5d, 0x10, 0xf, 0x0, 0xe2, 0x22, 0x3e, + 0x0, 0xd1, 0x0, 0xf0, 0xe, 0x0, 0x0, 0xe0, + 0xd, 0x10, 0xf, 0x0, 0xec, 0xcc, 0xde, 0x0, + 0xd1, 0x0, 0xf0, 0xa, 0x0, 0x0, 0x0, 0xe, + 0x10, 0xf, 0x0, 0x0, 0x0, 0x3, 0xdd, 0xb0, + 0x0, + + /* U+554A "啊" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x11, 0x6, 0xff, 0xcb, 0xff, 0xff, 0xf7, 0xdf, + 0xfa, 0x66, 0x4a, 0x0, 0x0, 0x4a, 0xd, 0x3, + 0xa6, 0x67, 0x50, 0x0, 0x3, 0xa0, 0xd0, 0x3a, + 0x66, 0xb1, 0x6e, 0xea, 0x3a, 0xd, 0x3, 0xa6, + 0x7c, 0x6, 0x72, 0xb3, 0xa0, 0xd0, 0x3a, 0x66, + 0xc0, 0x66, 0x1b, 0x3a, 0xd, 0x3, 0xa6, 0x66, + 0x76, 0x61, 0xb3, 0xa0, 0xd0, 0x3a, 0x66, 0x1c, + 0x66, 0x1b, 0x3a, 0xd, 0x25, 0xa6, 0x60, 0xe6, + 0x72, 0xb3, 0xa0, 0xde, 0xe9, 0x66, 0xe, 0x6f, + 0xea, 0x3a, 0xd, 0x0, 0x6, 0x8d, 0x76, 0x60, + 0x3, 0xa0, 0x70, 0x0, 0x66, 0x0, 0x0, 0x0, + 0x3a, 0x0, 0x0, 0x6, 0x60, 0x0, 0x1, 0x26, + 0xa0, 0x0, 0x0, 0x66, 0x0, 0x0, 0x5e, 0xc4, + 0x0, + + /* U+554F "問" */ + 0x4f, 0xdd, 0xdf, 0x60, 0xfd, 0xdd, 0xee, 0x4c, + 0x0, 0xa, 0x60, 0xf0, 0x0, 0x2e, 0x4d, 0x22, + 0x2b, 0x60, 0xf2, 0x22, 0x5e, 0x4e, 0xaa, 0xad, + 0x60, 0xfa, 0xaa, 0xbe, 0x4c, 0x0, 0xa, 0x60, + 0xf0, 0x0, 0x2e, 0x4f, 0xdd, 0xdd, 0x50, 0xdd, + 0xdd, 0xee, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0x4c, 0x0, 0xcd, 0xdd, 0xdd, 0x20, 0x2e, + 0x4c, 0x0, 0xe2, 0x0, 0xe, 0x20, 0x2e, 0x4c, + 0x0, 0xe1, 0x0, 0xd, 0x20, 0x2e, 0x4c, 0x0, + 0xe1, 0x0, 0xd, 0x20, 0x2e, 0x4c, 0x0, 0xee, + 0xee, 0xef, 0x20, 0x2e, 0x4c, 0x0, 0xb1, 0x0, + 0x0, 0x11, 0x4e, 0x4c, 0x0, 0x0, 0x0, 0x0, + 0xdf, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5566 "啦" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3b, 0x0, 0xc, 0x20, 0x0, 0x89, + 0x97, 0x3, 0xb0, 0x0, 0x78, 0x0, 0xd, 0x45, + 0xb0, 0x4b, 0x3, 0x57, 0x95, 0x50, 0xd0, 0x1b, + 0xaf, 0xfd, 0x69, 0x99, 0x99, 0xd, 0x1, 0xb0, + 0x3b, 0x1, 0x40, 0x5, 0x40, 0xd0, 0x1b, 0x3, + 0xb0, 0x2b, 0x0, 0xa5, 0xd, 0x1, 0xb0, 0x3b, + 0x30, 0xe0, 0xc, 0x30, 0xd0, 0x1b, 0x18, 0xfb, + 0xd, 0x0, 0xe1, 0xd, 0x2, 0xbb, 0xbb, 0x0, + 0xb3, 0xe, 0x0, 0xdf, 0xfb, 0x3, 0xb0, 0xa, + 0x42, 0xc0, 0xd, 0x0, 0x0, 0x3b, 0x0, 0x86, + 0x59, 0x0, 0x70, 0x0, 0x3, 0xb0, 0x7, 0x78, + 0x60, 0x0, 0x0, 0x0, 0x3b, 0x0, 0x10, 0xb3, + 0x0, 0x0, 0x0, 0x8f, 0x74, 0xee, 0xee, 0xee, + 0x40, + + /* U+5584 "善" */ + 0x0, 0x0, 0x61, 0x0, 0x0, 0x37, 0x0, 0x0, + 0x0, 0x0, 0x8a, 0x0, 0x0, 0xc6, 0x0, 0x0, + 0x3, 0xdd, 0xee, 0xdd, 0xdd, 0xfd, 0xdd, 0x30, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x3d, 0xdd, 0xde, 0xed, 0xdd, 0xd3, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x8, 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xcc, 0x90, + 0x0, 0x8, 0x70, 0x9, 0x80, 0x8, 0x70, 0x0, + 0x0, 0x3, 0xe0, 0x9, 0x80, 0x1e, 0x20, 0x0, + 0x1d, 0xdd, 0xee, 0xde, 0xed, 0xee, 0xdd, 0xd2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xee, 0xee, 0xee, 0xee, 0xf1, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xf1, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xf1, 0x0, + 0x0, 0xf, 0xed, 0xdd, 0xdd, 0xdd, 0xf1, 0x0, + + /* U+5589 "喉" */ + 0x0, 0x0, 0x0, 0x63, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x2d, 0xee, 0xec, 0x0, 0xde, + 0xed, 0x3, 0xc0, 0x0, 0x4, 0xb0, 0xd, 0x0, + 0xd0, 0x96, 0x0, 0x0, 0x69, 0x0, 0xd0, 0xd, + 0x2f, 0x3e, 0xee, 0xef, 0xfe, 0x3d, 0x0, 0xda, + 0xf1, 0xa, 0x20, 0x0, 0x0, 0xd0, 0xf, 0xdf, + 0x11, 0xe0, 0x0, 0x0, 0xd, 0x0, 0xe3, 0xe1, + 0x8f, 0xef, 0xee, 0xc0, 0xd0, 0xd, 0xe, 0x3e, + 0x11, 0xe0, 0x0, 0xd, 0x0, 0xd0, 0xe3, 0x51, + 0x2e, 0x11, 0x10, 0xdf, 0xfd, 0xe, 0x6c, 0xcd, + 0xfd, 0xcc, 0x3d, 0x0, 0x0, 0xe1, 0x0, 0x7f, + 0x80, 0x0, 0xc0, 0x0, 0xe, 0x10, 0x1e, 0x4e, + 0x10, 0x0, 0x0, 0x0, 0xe1, 0x3d, 0x50, 0x5d, + 0x40, 0x0, 0x0, 0xe, 0x5b, 0x30, 0x0, 0x2c, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+559C "喜" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x9, 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xcc, 0xa0, + 0x0, 0x12, 0x22, 0x2a, 0x92, 0x22, 0x22, 0x0, + 0x0, 0x48, 0x88, 0x88, 0x88, 0x88, 0x85, 0x0, + 0x0, 0x9, 0xcc, 0xcc, 0xcc, 0xcc, 0xa0, 0x0, + 0x0, 0xc, 0x30, 0x0, 0x0, 0x3, 0xd0, 0x0, + 0x0, 0xc, 0xba, 0xaa, 0xaa, 0xab, 0xd0, 0x0, + 0x0, 0x1, 0x8a, 0x11, 0x11, 0xc8, 0x10, 0x0, + 0x29, 0x99, 0xbf, 0xa9, 0x9a, 0xfa, 0x99, 0x92, + 0x3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x30, + 0x0, 0x1c, 0xcc, 0xcc, 0xcc, 0xcc, 0xc2, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x1f, 0xcc, 0xcc, 0xcc, 0xcc, 0xf2, 0x0, + + /* U+559D "喝" */ + 0x11, 0x11, 0x2, 0xfd, 0xdd, 0xdd, 0xf1, 0xee, + 0xef, 0x12, 0xc0, 0x0, 0x0, 0xe1, 0xe1, 0xe, + 0x12, 0xfc, 0xcc, 0xcc, 0xf1, 0xe1, 0xe, 0x12, + 0xd0, 0x0, 0x0, 0xe1, 0xe1, 0xe, 0x12, 0xd1, + 0x11, 0x11, 0xe1, 0xe1, 0xe, 0x12, 0xdd, 0xbb, + 0xbb, 0xb0, 0xe1, 0xe, 0x10, 0xd6, 0x0, 0x0, + 0x0, 0xe1, 0xe, 0x17, 0xfd, 0xdd, 0xdd, 0xde, + 0xe1, 0xe, 0x6e, 0x20, 0x8, 0x30, 0x2d, 0xef, + 0xff, 0x46, 0x90, 0x3e, 0x70, 0x3c, 0xe1, 0x0, + 0x3, 0xa5, 0xb1, 0x7a, 0x4b, 0x70, 0x0, 0x3, + 0xdb, 0xa9, 0x9b, 0x89, 0x0, 0x0, 0x0, 0x22, + 0x22, 0x22, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xd2, + + /* U+55AE "單" */ + 0x0, 0xdc, 0xbb, 0xe5, 0x4e, 0xbb, 0xcf, 0x0, + 0x0, 0xd1, 0x0, 0xa5, 0x4a, 0x0, 0xf, 0x0, + 0x0, 0xd9, 0x88, 0xd5, 0x4d, 0x88, 0x8f, 0x0, + 0x0, 0x33, 0x33, 0x31, 0x13, 0x33, 0x33, 0x0, + 0x0, 0x6d, 0xdd, 0xdd, 0xdd, 0xdd, 0xd8, 0x0, + 0x0, 0x69, 0x0, 0x9, 0x80, 0x0, 0x79, 0x0, + 0x0, 0x6e, 0xbb, 0xbe, 0xdb, 0xbb, 0xd9, 0x0, + 0x0, 0x6a, 0x11, 0x1a, 0x91, 0x11, 0x89, 0x0, + 0x0, 0x69, 0x0, 0x9, 0x80, 0x0, 0x79, 0x0, + 0x0, 0x6d, 0xdd, 0xdf, 0xfd, 0xdd, 0xd8, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + + /* U+55B6 "営" */ + 0x0, 0x10, 0x1, 0x40, 0x0, 0x2, 0x0, 0x6, + 0xd1, 0x1, 0xe2, 0x0, 0x3e, 0x10, 0x0, 0xaa, + 0x0, 0x78, 0x0, 0xd4, 0x0, 0xae, 0xff, 0xee, + 0xff, 0xef, 0xfe, 0xe3, 0xb4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc4, 0xb4, 0x2d, 0xdd, 0xdd, 0xdd, + 0xd1, 0xc4, 0x0, 0x2d, 0x0, 0x0, 0x0, 0xe1, + 0x0, 0x0, 0x2d, 0x0, 0x0, 0x0, 0xe1, 0x0, + 0x0, 0x2f, 0xdd, 0xdd, 0xdd, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0x10, 0x6, 0xc1, 0x11, + 0x11, 0x11, 0x1c, 0x20, 0x6, 0xc0, 0x0, 0x0, + 0x0, 0xb, 0x20, 0x6, 0xc1, 0x11, 0x11, 0x11, + 0x1c, 0x20, 0x6, 0xfd, 0xdd, 0xdd, 0xdd, 0xdf, + 0x20, + + /* U+55CE "嗎" */ + 0x23, 0x33, 0x3, 0xfe, 0xef, 0xfe, 0xea, 0xdf, + 0xff, 0x13, 0xb0, 0xe, 0x10, 0x0, 0xd2, 0xe, + 0x13, 0xb0, 0xe, 0x10, 0x0, 0xd1, 0xd, 0x13, + 0xfe, 0xef, 0xee, 0xe5, 0xd1, 0xd, 0x13, 0xb0, + 0xe, 0x10, 0x0, 0xd1, 0xd, 0x13, 0xfd, 0xdf, + 0xdd, 0xd5, 0xd1, 0xd, 0x13, 0xc0, 0xe, 0x10, + 0x0, 0xd1, 0xd, 0x13, 0xc0, 0xe, 0x10, 0x0, + 0xd3, 0x1e, 0x13, 0xff, 0xff, 0xff, 0xfe, 0xde, + 0xdd, 0x11, 0x0, 0x1, 0x32, 0x2d, 0xd1, 0x0, + 0xd, 0x3b, 0x1b, 0x1b, 0x3c, 0x20, 0x0, 0x3e, + 0xa, 0x1a, 0x25, 0x6a, 0x0, 0x0, 0xc5, 0x7, + 0x12, 0x0, 0x97, 0x0, 0x0, 0x30, 0x0, 0x0, + 0xbe, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+55EF "嗯" */ + 0x11, 0x11, 0xf, 0xee, 0xee, 0xee, 0xf1, 0xe, + 0xff, 0xe0, 0xf0, 0x0, 0x10, 0xe, 0x10, 0xe4, + 0x4e, 0xf, 0x0, 0x48, 0x0, 0xe1, 0xe, 0x0, + 0xe0, 0xf4, 0xce, 0xdc, 0x5e, 0x10, 0xe0, 0xe, + 0xf, 0x0, 0xda, 0x0, 0xe1, 0xe, 0x0, 0xe0, + 0xf0, 0x97, 0x5c, 0x1e, 0x10, 0xe0, 0xe, 0xf, + 0x36, 0x0, 0x32, 0xe1, 0xe, 0x0, 0xe0, 0xfe, + 0xee, 0xee, 0xef, 0x10, 0xe0, 0xe, 0x0, 0x0, + 0x23, 0x0, 0x10, 0xe, 0xff, 0xe4, 0x68, 0x53, + 0xd0, 0x3c, 0x0, 0xe0, 0x0, 0x85, 0x95, 0x9, + 0x60, 0xb5, 0x7, 0x0, 0xd, 0x19, 0x50, 0x11, + 0xc4, 0xc0, 0x0, 0x5, 0xa0, 0x96, 0x0, 0xe, + 0xb, 0x0, 0x0, 0x2, 0x5, 0xee, 0xee, 0x80, + 0x0, + + /* U+561B "嘛" */ + 0x0, 0x0, 0x0, 0x0, 0x51, 0x0, 0x0, 0x4, + 0x55, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0xd9, + 0xe0, 0xce, 0xee, 0xef, 0xee, 0xee, 0x2d, 0xd, + 0xe, 0x0, 0x40, 0x0, 0x30, 0x0, 0xd0, 0xd0, + 0xe0, 0xd, 0x0, 0xc, 0x0, 0xd, 0xd, 0xe, + 0x0, 0xe0, 0x0, 0xd0, 0x0, 0xd0, 0xd0, 0xe8, + 0xdf, 0xd5, 0xdf, 0xdc, 0xd, 0xd, 0xe, 0x5, + 0xf4, 0x3, 0xf5, 0x0, 0xd0, 0xd0, 0xf0, 0xae, + 0xb2, 0x8f, 0xa0, 0xd, 0xd, 0xe, 0xa, 0xd2, + 0x6b, 0xda, 0x0, 0xde, 0xf1, 0xc6, 0x5d, 0x3, + 0x7c, 0x64, 0xd, 0x0, 0x4a, 0xc0, 0xd0, 0xb1, + 0xc1, 0xa0, 0xa0, 0x8, 0x76, 0xd, 0x48, 0xc, + 0x8, 0x20, 0x0, 0xe2, 0x0, 0xd0, 0x0, 0xc0, + 0x0, 0x0, 0x2a, 0x0, 0xd, 0x0, 0xc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+56B4 "嚴" */ + 0x0, 0xac, 0xaa, 0xf1, 0x1f, 0xaa, 0xaf, 0x0, + 0x0, 0xa4, 0x0, 0xe1, 0x1e, 0x0, 0xe, 0x0, + 0x0, 0x9b, 0xaa, 0xd1, 0x1d, 0xaa, 0xad, 0x0, + 0x0, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, + 0x0, 0xf6, 0x66, 0x66, 0x66, 0x78, 0x66, 0x60, + 0x0, 0xe0, 0xab, 0xbd, 0x60, 0x69, 0x0, 0x0, + 0x0, 0xe0, 0x0, 0x3e, 0x10, 0xbc, 0x99, 0x91, + 0x1, 0xe7, 0xfc, 0xce, 0xe9, 0xf5, 0x4b, 0x90, + 0x2, 0xc0, 0xd5, 0x4a, 0x9b, 0xe5, 0xd, 0x20, + 0x3, 0xb0, 0xd6, 0x5a, 0x96, 0x2c, 0x3c, 0x0, + 0x5, 0xa0, 0xdb, 0xad, 0x90, 0xa, 0xe4, 0x0, + 0x9, 0x60, 0xd1, 0x7, 0x90, 0x8, 0xf2, 0x0, + 0xe, 0x2a, 0xfc, 0xce, 0xd6, 0x99, 0x4e, 0x50, + 0x39, 0x1, 0x0, 0x7, 0x9a, 0x60, 0x3, 0xc3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+56DB "四" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xc5, 0x0, + 0xc5, 0x1, 0xe0, 0x0, 0xe2, 0xc4, 0x0, 0xc4, + 0x1, 0xe0, 0x0, 0xe2, 0xc4, 0x0, 0xd3, 0x1, + 0xe0, 0x0, 0xe2, 0xc4, 0x0, 0xf1, 0x1, 0xe0, + 0x0, 0xe2, 0xc4, 0x2, 0xd0, 0x1, 0xe0, 0x0, + 0xe2, 0xc4, 0x9, 0x80, 0x0, 0xf0, 0x0, 0xe2, + 0xc4, 0x5e, 0x10, 0x0, 0xbe, 0xed, 0xe2, 0xc8, + 0xd2, 0x0, 0x0, 0x0, 0x0, 0xe2, 0xc4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe2, 0xcd, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0xf2, 0xc7, 0x44, 0x44, 0x44, + 0x44, 0x44, 0xf2, 0x83, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x81, + + /* U+56DE "回" */ + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xd4, + 0x11, 0x11, 0x11, 0x11, 0x11, 0xe3, 0xd3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe3, 0xd3, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe3, 0xd3, 0x1, 0xfe, 0xee, + 0xee, 0x0, 0xe3, 0xd3, 0x1, 0xe0, 0x0, 0x2e, + 0x0, 0xe3, 0xd3, 0x1, 0xe0, 0x0, 0x2e, 0x0, + 0xe3, 0xd3, 0x1, 0xe0, 0x0, 0x2e, 0x0, 0xe3, + 0xd3, 0x1, 0xe0, 0x0, 0x2e, 0x0, 0xe3, 0xd3, + 0x1, 0xee, 0xee, 0xed, 0x0, 0xe3, 0xd3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe3, 0xd3, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe3, 0xde, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xf3, 0xd5, 0x22, 0x22, 0x22, 0x22, + 0x22, 0xe3, + + /* U+56E0 "因" */ + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xd2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc3, 0xd2, 0x0, + 0x0, 0x85, 0x0, 0x0, 0xc3, 0xd2, 0x0, 0x0, + 0xb5, 0x0, 0x0, 0xc3, 0xd2, 0x22, 0x22, 0xc6, + 0x22, 0x20, 0xc3, 0xd2, 0xcd, 0xdd, 0xfe, 0xdd, + 0xd5, 0xc3, 0xd2, 0x0, 0x1, 0xf1, 0x0, 0x0, + 0xc3, 0xd2, 0x0, 0x6, 0xdc, 0x10, 0x0, 0xc3, + 0xd2, 0x0, 0xd, 0x55, 0xd2, 0x0, 0xc3, 0xd2, + 0x0, 0xab, 0x0, 0x4e, 0x20, 0xc3, 0xd2, 0x3c, + 0xb0, 0x0, 0x5, 0xd1, 0xc3, 0xd2, 0x66, 0x0, + 0x0, 0x0, 0x51, 0xc3, 0xdc, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xf3, 0xd5, 0x33, 0x33, 0x33, 0x33, + 0x33, 0xd3, + + /* U+56F0 "困" */ + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xd3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe3, 0xd3, 0x0, + 0x0, 0xd1, 0x0, 0x0, 0xe3, 0xd3, 0x0, 0x0, + 0xe1, 0x0, 0x0, 0xe3, 0xd3, 0x89, 0x99, 0xfa, + 0x99, 0x92, 0xe3, 0xd3, 0x56, 0x6d, 0xfc, 0x66, + 0x62, 0xe3, 0xd3, 0x0, 0x5c, 0xed, 0x70, 0x0, + 0xe3, 0xd3, 0x2, 0xd1, 0xe2, 0xb8, 0x0, 0xe3, + 0xd3, 0x2d, 0x40, 0xe1, 0xc, 0x80, 0xe3, 0xd6, + 0xe3, 0x0, 0xe1, 0x1, 0xd3, 0xe3, 0xd3, 0x10, + 0x0, 0xe1, 0x0, 0x10, 0xe3, 0xd3, 0x0, 0x0, + 0x81, 0x0, 0x0, 0xe3, 0xd7, 0x44, 0x44, 0x44, + 0x44, 0x44, 0xe3, 0xdc, 0xbb, 0xbb, 0xbb, 0xbb, + 0xbb, 0xf3, + + /* U+56F3 "図" */ + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xc5, + 0x0, 0x2, 0x80, 0x0, 0x0, 0xe2, 0xc4, 0x0, + 0x0, 0xaa, 0x0, 0x0, 0xe2, 0xc4, 0x68, 0x6, + 0xa, 0x55, 0xc0, 0xe2, 0xc4, 0x1e, 0x19, 0x90, + 0xc, 0x50, 0xe2, 0xc4, 0x9, 0x70, 0xb5, 0x3e, + 0x0, 0xe2, 0xc4, 0x2, 0xe3, 0x13, 0xd6, 0x0, + 0xe2, 0xc4, 0x0, 0x4e, 0x2c, 0x90, 0x0, 0xe2, + 0xc4, 0x0, 0x8, 0xfc, 0x0, 0x0, 0xe2, 0xc4, + 0x1, 0x8e, 0x9e, 0xa3, 0x0, 0xe2, 0xc7, 0xbf, + 0x91, 0x1, 0x8e, 0xe6, 0xe2, 0xc5, 0x50, 0x0, + 0x0, 0x0, 0x42, 0xe2, 0xcf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf2, 0xc5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe2, + + /* U+56FD "国" */ + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xd4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe3, 0xd4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe3, 0xd4, 0x8f, 0xff, + 0xff, 0xff, 0xa0, 0xe3, 0xd4, 0x0, 0x0, 0xf0, + 0x0, 0x0, 0xe3, 0xd4, 0x0, 0x0, 0xf0, 0x0, + 0x0, 0xe3, 0xd4, 0x1e, 0xef, 0xfe, 0xee, 0x40, + 0xe3, 0xd4, 0x0, 0x0, 0xf0, 0x61, 0x0, 0xe3, + 0xd4, 0x0, 0x0, 0xf0, 0x4c, 0x0, 0xe3, 0xd4, + 0x0, 0x0, 0xf0, 0x5, 0x20, 0xe3, 0xd4, 0xce, + 0xee, 0xee, 0xee, 0xe1, 0xe3, 0xd4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe3, 0xdd, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xf3, 0xd7, 0x33, 0x33, 0x33, 0x33, + 0x33, 0xf3, + + /* U+570B "國" */ + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xd2, + 0x0, 0x0, 0x3, 0x5, 0x0, 0xd3, 0xd2, 0x0, + 0x0, 0xd, 0x7, 0xb0, 0xd3, 0xd2, 0x78, 0x88, + 0x8f, 0x88, 0x94, 0xd3, 0xd2, 0x34, 0x44, 0x4e, + 0x44, 0x42, 0xd3, 0xd2, 0x3a, 0xaa, 0x2b, 0x23, + 0x90, 0xd3, 0xd2, 0x57, 0x9, 0x39, 0x49, 0x60, + 0xd3, 0xd2, 0x57, 0x9, 0x36, 0x8e, 0x10, 0xd3, + 0xd2, 0x3a, 0xaa, 0x23, 0xf8, 0x0, 0xd3, 0xd2, + 0x0, 0x25, 0x63, 0xf2, 0x13, 0xd3, 0xd2, 0xcd, + 0xa7, 0x8e, 0xaa, 0x47, 0xd3, 0xd2, 0x0, 0x3, + 0xd2, 0x9, 0xe2, 0xd3, 0xd5, 0x33, 0x33, 0x43, + 0x33, 0x33, 0xe3, 0xdc, 0xbb, 0xbb, 0xbb, 0xbb, + 0xbb, 0xf3, + + /* U+570D "圍" */ + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xd2, + 0x0, 0x6, 0x40, 0x0, 0x0, 0xd3, 0xd2, 0x9, + 0xad, 0xca, 0xa9, 0x0, 0xd3, 0xd2, 0x0, 0x1e, + 0x0, 0xd, 0x0, 0xd3, 0xd2, 0xaa, 0xbb, 0xaa, + 0xbb, 0xa4, 0xd3, 0xd2, 0x7, 0x99, 0x99, 0x99, + 0x20, 0xd3, 0xd2, 0xc, 0x20, 0x0, 0xb, 0x30, + 0xd3, 0xd2, 0x7, 0x99, 0x9f, 0x9a, 0x20, 0xd3, + 0xd2, 0x7a, 0xaa, 0xaf, 0xaa, 0xa3, 0xd3, 0xd2, + 0xd, 0x0, 0xf, 0x0, 0x0, 0xd3, 0xd2, 0x2f, + 0xbb, 0xbf, 0xbb, 0xb2, 0xd3, 0xd2, 0x0, 0x0, + 0xf, 0x0, 0x0, 0xd3, 0xd5, 0x33, 0x33, 0x38, + 0x33, 0x33, 0xe3, 0xdc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xcc, 0xf3, + + /* U+5712 "園" */ + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xd2, + 0x0, 0x0, 0x41, 0x0, 0x0, 0xd3, 0xd2, 0xa, + 0xaa, 0xeb, 0xaa, 0x60, 0xd3, 0xd2, 0x0, 0x0, + 0xc4, 0x0, 0x0, 0xd3, 0xd2, 0xbb, 0xbb, 0xfc, + 0xbb, 0xb6, 0xd3, 0xd2, 0x11, 0x11, 0x11, 0x11, + 0x10, 0xd3, 0xd2, 0xf, 0xaa, 0xaa, 0xac, 0x80, + 0xd3, 0xd2, 0xe, 0x0, 0x0, 0x6, 0x80, 0xd3, + 0xd2, 0xa, 0xab, 0xfb, 0xaa, 0xa1, 0xd3, 0xd2, + 0x0, 0x4d, 0xfc, 0x79, 0x80, 0xd3, 0xd2, 0x4b, + 0x91, 0xf0, 0x7d, 0x60, 0xd3, 0xd3, 0x91, 0x0, + 0xf0, 0x0, 0x85, 0xd3, 0xd5, 0x33, 0x33, 0x73, + 0x33, 0x33, 0xe3, 0xdc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xcc, 0xf3, + + /* U+5718 "團" */ + 0x3f, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xed, 0x3c, + 0x0, 0x0, 0x6, 0x0, 0x0, 0x2d, 0x3c, 0x4a, + 0xaa, 0xaf, 0xaa, 0xa8, 0x2d, 0x3c, 0x7, 0x88, + 0x9e, 0x88, 0x80, 0x2d, 0x3c, 0xd, 0x33, 0x4e, + 0x33, 0xe0, 0x2d, 0x3c, 0xd, 0x77, 0x8e, 0x77, + 0xe0, 0x2d, 0x3c, 0xc, 0x99, 0xaf, 0x99, 0xd0, + 0x2d, 0x3c, 0x13, 0x34, 0x5e, 0x4a, 0x80, 0x2d, + 0x3c, 0x37, 0x76, 0x65, 0x69, 0x94, 0x2d, 0x3c, + 0x7b, 0xbb, 0xbb, 0xce, 0xbb, 0x3d, 0x3c, 0x0, + 0x79, 0x0, 0x29, 0x0, 0x2d, 0x3c, 0x0, 0x6, + 0x25, 0xa8, 0x0, 0x2d, 0x3e, 0xaa, 0xaa, 0xab, + 0xba, 0xaa, 0xbd, 0x3d, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x5c, + + /* U+571F "土" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x11, 0x11, 0x1a, 0x91, 0x11, 0x11, 0x0, + 0x1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x4, 0x44, 0x44, 0x4b, 0xa4, 0x44, 0x44, 0x40, + 0x1b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb2, + + /* U+5723 "圣" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x0, + 0x0, 0x9, 0xb0, 0x0, 0x0, 0xa, 0xb0, 0x0, + 0x0, 0x0, 0xca, 0x0, 0x0, 0x9e, 0x10, 0x0, + 0x0, 0x0, 0x1b, 0xd2, 0x2c, 0xc1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xaf, 0xfa, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x7c, 0xfa, 0xbf, 0xb5, 0x10, 0x0, + 0x2c, 0xfe, 0xb6, 0x0, 0x1, 0x7d, 0xfd, 0xa2, + 0x5, 0x20, 0x0, 0x8, 0x80, 0x0, 0x4, 0x60, + 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x4e, 0xee, 0xef, 0xfe, 0xee, 0xe3, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x19, 0x91, 0x11, 0x11, 0x10, + 0xe, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe1, + + /* U+5728 "在" */ + 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xd0, 0x0, 0x0, 0x0, 0x0, 0xef, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1, 0x11, + 0x5e, 0x11, 0x11, 0x11, 0x11, 0x10, 0x0, 0xd, + 0x50, 0x0, 0x59, 0x0, 0x0, 0x0, 0x8, 0xb0, + 0x0, 0x6, 0xa0, 0x0, 0x0, 0x5, 0xf4, 0x0, + 0x0, 0x6a, 0x0, 0x0, 0x6, 0xff, 0x30, 0xff, + 0xff, 0xff, 0xff, 0x52, 0xf4, 0xd3, 0x0, 0x0, + 0x7b, 0x0, 0x0, 0x2, 0xd, 0x30, 0x0, 0x6, + 0xa0, 0x0, 0x0, 0x0, 0xd3, 0x0, 0x0, 0x6a, + 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x6, 0xa0, + 0x0, 0x0, 0x0, 0xd3, 0x0, 0x0, 0x6a, 0x0, + 0x0, 0x0, 0xd, 0x3a, 0xff, 0xff, 0xff, 0xff, + 0xf0, + + /* U+5730 "地" */ + 0x0, 0xc, 0x0, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0x0, 0xf, 0x0, 0xc, 0x0, 0xc3, 0x0, 0x0, + 0x0, 0xf, 0x0, 0xf, 0x0, 0xc3, 0x16, 0x80, + 0x1b, 0xcf, 0xbb, 0xf, 0x0, 0xdc, 0xeb, 0xd0, + 0x4, 0x4f, 0x43, 0xf, 0x6d, 0xf8, 0x3, 0xd0, + 0x0, 0xf, 0x0, 0x7f, 0xc4, 0xd3, 0x3, 0xd0, + 0x0, 0xf, 0x7, 0xbf, 0x0, 0xc3, 0x3, 0xd0, + 0x0, 0xf, 0x0, 0xf, 0x0, 0xc3, 0x3, 0xc0, + 0x0, 0xf, 0x5, 0xf, 0x0, 0xc3, 0x5, 0xb0, + 0x0, 0x2f, 0xec, 0xf, 0x0, 0xc3, 0xde, 0x50, + 0x19, 0xfc, 0x40, 0xf, 0x0, 0xc3, 0x0, 0x0, + 0xb, 0x40, 0x0, 0xf, 0x0, 0x10, 0x0, 0x76, + 0x0, 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, 0xb6, + 0x0, 0x0, 0x0, 0x7, 0xef, 0xff, 0xff, 0xc0, + + /* U+5747 "均" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0x1, 0xe1, 0x0, 0x0, 0x0, + 0x1e, 0x0, 0x0, 0x99, 0x0, 0x0, 0x0, 0x1, + 0xe0, 0x0, 0x2f, 0xed, 0xdd, 0xdd, 0x2b, 0xcf, + 0xbb, 0x1d, 0x40, 0x0, 0x1, 0xe0, 0x45, 0xf4, + 0x4c, 0x81, 0x0, 0x0, 0x1e, 0x0, 0x1e, 0x0, + 0x60, 0xc8, 0x0, 0x2, 0xd0, 0x1, 0xe0, 0x0, + 0x0, 0xba, 0x0, 0x2d, 0x0, 0x1e, 0x0, 0x0, + 0x0, 0xa3, 0x3, 0xc0, 0x1, 0xe0, 0x53, 0x0, + 0x1, 0x9c, 0x4b, 0x0, 0x1f, 0xdb, 0x20, 0x18, + 0xe7, 0x5, 0xa0, 0x7e, 0xc3, 0x1, 0x8e, 0x91, + 0x0, 0x79, 0x1b, 0x40, 0x0, 0x2a, 0x20, 0x0, + 0x9, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x2, 0xff, 0xfa, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+574A "坊" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0xe3, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x55, 0x55, 0x78, 0x55, 0x51, + 0x2, 0x2f, 0x23, 0xaa, 0xbf, 0xaa, 0xaa, 0xa3, + 0x1d, 0xef, 0xdd, 0x0, 0x2e, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x3f, 0xff, 0xff, 0x60, + 0x0, 0xf, 0x0, 0x0, 0x4c, 0x0, 0xb, 0x50, + 0x0, 0xf, 0x1, 0x0, 0x8a, 0x0, 0xc, 0x50, + 0x0, 0x1f, 0xbe, 0x30, 0xd5, 0x0, 0xc, 0x40, + 0x2a, 0xfc, 0x60, 0x6, 0xe0, 0x0, 0xe, 0x20, + 0x28, 0x20, 0x0, 0x1e, 0x40, 0x0, 0xf, 0x10, + 0x0, 0x0, 0x2, 0xd8, 0x0, 0x0, 0x4e, 0x0, + 0x0, 0x0, 0xd, 0x60, 0x0, 0xcf, 0xf7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5750 "坐" */ + 0x0, 0x0, 0x60, 0x9, 0x80, 0x1, 0x40, 0x0, + 0x0, 0x5, 0xc0, 0x9, 0x80, 0x8, 0x90, 0x0, + 0x0, 0xb, 0x80, 0x9, 0x80, 0xe, 0x40, 0x0, + 0x0, 0x1f, 0x90, 0x9, 0x80, 0x4f, 0x30, 0x0, + 0x0, 0x8a, 0xb9, 0x9, 0x80, 0xd9, 0xe3, 0x0, + 0x4, 0xf1, 0xc, 0x89, 0x8a, 0xb0, 0x4e, 0x30, + 0x2f, 0x40, 0x1, 0x49, 0xbb, 0x0, 0x5, 0xd0, + 0x2, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x10, + 0x0, 0xdd, 0xdd, 0xdf, 0xed, 0xdd, 0xdd, 0x10, + 0x0, 0x22, 0x22, 0x2a, 0x92, 0x22, 0x22, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x2, 0x22, 0x22, 0x2a, 0x92, 0x22, 0x22, 0x20, + 0x1d, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xd2, + + /* U+578B "型" */ + 0x5, 0xff, 0xff, 0xff, 0xc0, 0xc3, 0xc, 0x30, + 0x0, 0xc, 0x20, 0xb4, 0x0, 0xc3, 0xc, 0x30, + 0x0, 0xc, 0x20, 0xb4, 0x0, 0xc3, 0xc, 0x30, + 0xa, 0xbf, 0xcb, 0xec, 0xb2, 0xc3, 0xc, 0x30, + 0x3, 0x4f, 0x43, 0xc7, 0x30, 0xc3, 0xc, 0x30, + 0x0, 0x4b, 0x0, 0xb4, 0x0, 0x41, 0xc, 0x30, + 0x0, 0xb6, 0x0, 0xb4, 0x0, 0x0, 0xc, 0x30, + 0x9, 0xb0, 0x0, 0xa5, 0x10, 0xc, 0xde, 0x10, + 0x2, 0x0, 0x0, 0x6, 0xa0, 0x1, 0x10, 0x0, + 0x0, 0x23, 0x33, 0x39, 0xb3, 0x33, 0x32, 0x0, + 0x0, 0x6b, 0xbb, 0xbd, 0xeb, 0xbb, 0xb6, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x17, 0xa1, 0x11, 0x11, 0x10, + 0x3e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe3, + + /* U+57DF "域" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x87, 0x0, 0x0, 0x0, 0x2d, 0x2c, 0x30, + 0x0, 0x87, 0x0, 0x0, 0x0, 0x2e, 0x2, 0xb0, + 0x0, 0x87, 0xb, 0xff, 0xff, 0xff, 0xff, 0xf5, + 0x26, 0xba, 0x60, 0x0, 0x0, 0xf, 0x0, 0x0, + 0x3b, 0xed, 0xb0, 0x33, 0x33, 0xf, 0x0, 0x20, + 0x0, 0x87, 0x3, 0xea, 0xae, 0xe, 0x13, 0xd0, + 0x0, 0x87, 0x3, 0xa0, 0xe, 0xd, 0x2a, 0x70, + 0x0, 0x87, 0x3, 0xa0, 0xe, 0xc, 0x5f, 0x10, + 0x0, 0x87, 0x4, 0xfe, 0xee, 0x9, 0xd9, 0x0, + 0x0, 0x8c, 0xe2, 0x0, 0x0, 0x17, 0xf1, 0x0, + 0x19, 0xf9, 0x20, 0x37, 0xbe, 0x8c, 0xc0, 0x10, + 0x29, 0x20, 0x2f, 0xd8, 0x41, 0xb9, 0xf1, 0x57, + 0x0, 0x0, 0x1, 0x0, 0x2c, 0x80, 0x99, 0x85, + 0x0, 0x0, 0x0, 0x0, 0x57, 0x0, 0x1c, 0xd0, + + /* U+57F7 "執" */ + 0x0, 0x0, 0xf0, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x6, 0xee, 0xff, 0xe6, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x45, 0xf5, 0x54, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0xde, 0xfe, 0xec, 0x0, + 0x1f, 0xff, 0xff, 0xfd, 0x0, 0xf0, 0x3c, 0x0, + 0x0, 0xb2, 0x2, 0xb0, 0x1, 0xe0, 0x3c, 0x0, + 0x0, 0x67, 0x8, 0x60, 0xb5, 0xd0, 0x3c, 0x0, + 0x7, 0xee, 0xef, 0xe8, 0x4f, 0xc0, 0x3c, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0x7, 0xe2, 0x2d, 0x0, + 0x0, 0x0, 0xe0, 0x0, 0xc, 0xae, 0x3d, 0x0, + 0xe, 0xee, 0xfe, 0xee, 0x1f, 0x7, 0x4e, 0x0, + 0x0, 0x0, 0xe0, 0x0, 0x8a, 0x0, 0xe, 0x19, + 0x0, 0x0, 0xe0, 0x4, 0xd1, 0x0, 0xb, 0x79, + 0x0, 0x0, 0xe0, 0xc, 0x30, 0x0, 0x4, 0xf5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+57FA "基" */ + 0x0, 0x0, 0xf0, 0x0, 0x0, 0xf, 0x10, 0x0, + 0x7, 0xef, 0xff, 0xee, 0xee, 0xef, 0xfe, 0x80, + 0x0, 0x0, 0xf0, 0x0, 0x0, 0xf, 0x10, 0x0, + 0x0, 0x0, 0xfd, 0xdd, 0xdd, 0xdf, 0x10, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x0, 0xf, 0x10, 0x0, + 0x0, 0x0, 0xfd, 0xdd, 0xdd, 0xdf, 0x10, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x0, 0xf, 0x10, 0x0, + 0x3e, 0xee, 0xfe, 0xee, 0xee, 0xef, 0xee, 0xe3, + 0x0, 0x3, 0xe2, 0x0, 0x0, 0x1d, 0x50, 0x0, + 0x0, 0x3e, 0x40, 0x9, 0x80, 0x2, 0xe6, 0x0, + 0x19, 0xe5, 0xde, 0xef, 0xfe, 0xed, 0x2d, 0xc2, + 0x1a, 0x10, 0x0, 0x9, 0x80, 0x0, 0x0, 0x60, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0x10, + + /* U+5831 "報" */ + 0x0, 0x0, 0xf0, 0x0, 0x7f, 0xff, 0xff, 0xe0, + 0x8, 0xef, 0xfe, 0xe6, 0x78, 0x0, 0x1, 0xe0, + 0x0, 0x0, 0xf0, 0x0, 0x78, 0x0, 0x1, 0xe0, + 0x0, 0x0, 0xf0, 0x0, 0x78, 0x2, 0x35, 0xd0, + 0x1f, 0xff, 0xff, 0xfd, 0x78, 0x4, 0xba, 0x50, + 0x0, 0xb1, 0x3, 0xb0, 0x7a, 0x33, 0x33, 0x30, + 0x0, 0x67, 0xc, 0x30, 0x7e, 0xe9, 0x99, 0xf1, + 0xb, 0xff, 0xff, 0xf8, 0x79, 0xd1, 0x3, 0xd0, + 0x0, 0x0, 0xf0, 0x0, 0x78, 0x87, 0x9, 0x80, + 0x0, 0x0, 0xf0, 0x0, 0x78, 0x1e, 0x3e, 0x10, + 0x1f, 0xff, 0xff, 0xfd, 0x78, 0x7, 0xf9, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x78, 0x7, 0xf9, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x79, 0x8d, 0x3c, 0xb1, + 0x0, 0x0, 0xe0, 0x0, 0x7d, 0xb0, 0x0, 0x87, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5834 "場" */ + 0x0, 0x2d, 0x0, 0xf, 0xdd, 0xdd, 0xdf, 0x10, + 0x0, 0x2d, 0x0, 0xe, 0x0, 0x0, 0xe, 0x10, + 0x0, 0x2d, 0x0, 0xf, 0xcc, 0xcc, 0xcf, 0x10, + 0x1e, 0xef, 0xe9, 0xe, 0x0, 0x0, 0xe, 0x10, + 0x0, 0x2d, 0x0, 0xf, 0xcc, 0xcc, 0xcf, 0x10, + 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2d, 0x9, 0xef, 0xfe, 0xee, 0xee, 0xe5, + 0x0, 0x2d, 0x1, 0xc, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0xba, 0x9f, 0xee, 0xee, 0xee, 0xc0, + 0x6, 0xdd, 0x6a, 0xb0, 0x69, 0xb, 0x24, 0xc0, + 0x2d, 0x50, 0x49, 0x3, 0xd0, 0x3b, 0x6, 0xb0, + 0x0, 0x0, 0x0, 0x3d, 0x30, 0xb4, 0x8, 0x80, + 0x0, 0x0, 0x4, 0xe4, 0x8, 0xa0, 0xc, 0x50, + 0x0, 0x0, 0x1, 0x20, 0x3c, 0x9, 0xeb, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+584A "塊" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x0, 0x3c, 0x0, 0x0, 0x4, 0xd0, 0x0, 0x0, + 0x0, 0x3c, 0x0, 0x9e, 0xef, 0xfe, 0xee, 0xd0, + 0x0, 0x3c, 0x0, 0xa4, 0x0, 0xe0, 0x1, 0xe0, + 0x8, 0x9e, 0x84, 0xa4, 0x1, 0xd0, 0x1, 0xe0, + 0x8, 0xae, 0x84, 0xae, 0xdd, 0xfd, 0xdd, 0xe0, + 0x0, 0x3c, 0x0, 0xa4, 0x4, 0xb0, 0x1, 0xe0, + 0x0, 0x3c, 0x0, 0xa4, 0x6, 0x80, 0x1, 0xe0, + 0x0, 0x3c, 0x0, 0x9e, 0xef, 0xfe, 0xee, 0xd0, + 0x0, 0x3c, 0x0, 0x0, 0xe, 0xf0, 0x34, 0x0, + 0x0, 0x3d, 0x58, 0x0, 0x4c, 0xe0, 0xa5, 0x60, + 0x4, 0xaf, 0xa4, 0x0, 0xd4, 0xe3, 0xb3, 0xd0, + 0x2d, 0x71, 0x0, 0x9, 0xb0, 0xe7, 0xa8, 0x82, + 0x0, 0x0, 0x0, 0x9c, 0x0, 0xe0, 0x0, 0x49, + 0x0, 0x0, 0x9, 0xa1, 0x0, 0xaf, 0xee, 0xe4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5869 "塩" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4a, 0x0, 0xa, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x4a, 0x0, 0xf, 0xcb, 0xbb, 0xbb, 0xb2, + 0x0, 0x4a, 0x0, 0x79, 0x33, 0x33, 0x33, 0x30, + 0x4, 0x7c, 0x44, 0xf4, 0x11, 0x11, 0x11, 0x0, + 0x1b, 0xde, 0xbe, 0x8f, 0xbb, 0xbb, 0xd8, 0x0, + 0x0, 0x4a, 0x2, 0xf, 0x0, 0x0, 0x68, 0x0, + 0x0, 0x4a, 0x0, 0xf, 0x22, 0x22, 0x88, 0x0, + 0x0, 0x4a, 0x0, 0xa, 0xaa, 0xaa, 0xa6, 0x0, + 0x0, 0x4a, 0x1, 0x12, 0x22, 0x22, 0x22, 0x0, + 0x0, 0x5d, 0xd8, 0xdc, 0xde, 0xcf, 0xcf, 0x40, + 0x29, 0xfb, 0x40, 0xd1, 0x57, 0xc, 0xb, 0x40, + 0x29, 0x20, 0x0, 0xd1, 0x57, 0xc, 0xb, 0x40, + 0x0, 0x0, 0x0, 0xd1, 0x57, 0xc, 0xb, 0x40, + 0x0, 0x0, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xf6, + + /* U+5883 "境" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + 0x5, 0xa0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, + 0x5a, 0x0, 0xce, 0xee, 0xee, 0xee, 0x20, 0x5, + 0xa0, 0x0, 0x56, 0x0, 0x57, 0x0, 0x4, 0x8b, + 0x41, 0x3, 0xc0, 0xc, 0x50, 0x2, 0xbd, 0xeb, + 0x6d, 0xdd, 0xdd, 0xdd, 0xd7, 0x0, 0x5a, 0x0, + 0x35, 0x55, 0x55, 0x54, 0x0, 0x5, 0xa0, 0x8, + 0x94, 0x44, 0x48, 0xb0, 0x0, 0x5a, 0x0, 0x8d, + 0xbb, 0xbb, 0xdb, 0x0, 0x5, 0xa0, 0x8, 0x70, + 0x0, 0x4, 0xb0, 0x0, 0x5b, 0x75, 0x8e, 0xcc, + 0xcc, 0xdb, 0x1, 0x6c, 0xf9, 0x20, 0xe, 0x14, + 0xb0, 0x0, 0x3c, 0x60, 0x0, 0x3, 0xd0, 0x4b, + 0x0, 0x60, 0x0, 0x0, 0x3, 0xd5, 0x4, 0xb0, + 0xd, 0x0, 0x0, 0xc, 0xd5, 0x0, 0x1d, 0xee, + 0x90, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + + /* U+5897 "増" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xd0, 0x0, 0xa6, 0x0, 0xa, 0x70, 0x0, + 0x2d, 0x0, 0x2, 0xe0, 0x2, 0xd0, 0x0, 0x2, + 0xd0, 0xd, 0xed, 0xef, 0xdd, 0xea, 0x6, 0x8e, + 0x63, 0xd3, 0x0, 0xf0, 0x5, 0xa0, 0x89, 0xe8, + 0x5d, 0xdc, 0xcf, 0xcc, 0xda, 0x0, 0x2d, 0x0, + 0xd3, 0x0, 0xf0, 0x5, 0xa0, 0x2, 0xd0, 0xd, + 0xca, 0xbf, 0xaa, 0xca, 0x0, 0x2d, 0x0, 0x12, + 0x22, 0x22, 0x22, 0x10, 0x2, 0xd1, 0x41, 0xee, + 0xee, 0xee, 0xe1, 0x0, 0x6f, 0xfa, 0x1e, 0x0, + 0x0, 0xe, 0x12, 0xed, 0x71, 0x1, 0xfb, 0xbb, + 0xbb, 0xf1, 0x4, 0x0, 0x0, 0x1e, 0x11, 0x11, + 0x1e, 0x10, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0xe1, 0x0, 0x0, 0x0, 0x1f, 0xdd, 0xdd, 0xdf, + 0x10, + + /* U+589E "增" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xa0, 0x0, 0x89, 0x0, 0xc, 0x70, 0x0, + 0x5a, 0x0, 0x0, 0xc1, 0x6, 0xc0, 0x0, 0x5, + 0xa0, 0xf, 0xcc, 0xcf, 0xcc, 0xda, 0x4, 0x8b, + 0x41, 0xe2, 0x30, 0xd0, 0x45, 0xa1, 0xbd, 0xeb, + 0x3e, 0xb, 0xd, 0x1c, 0x4a, 0x0, 0x5a, 0x0, + 0xe0, 0x63, 0xd7, 0x23, 0xa0, 0x5, 0xa0, 0xf, + 0x88, 0x8e, 0x88, 0xaa, 0x0, 0x5a, 0x0, 0x22, + 0x22, 0x22, 0x22, 0x20, 0x5, 0xa0, 0x1, 0xdd, + 0xdd, 0xdd, 0xc0, 0x0, 0x5b, 0x84, 0x1e, 0x0, + 0x0, 0x1e, 0x1, 0x8d, 0xd7, 0x11, 0xfb, 0xbb, + 0xbb, 0xe0, 0x1a, 0x40, 0x0, 0x1e, 0x11, 0x11, + 0x3e, 0x0, 0x0, 0x0, 0x1, 0xfa, 0xaa, 0xab, + 0xe0, 0x0, 0x0, 0x0, 0x1f, 0x33, 0x33, 0x4e, + 0x0, + + /* U+58CA "壊" */ + 0x0, 0x77, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, + 0x0, 0x77, 0xe, 0xee, 0xef, 0xee, 0xee, 0xc0, + 0x0, 0x77, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, + 0x4, 0xa9, 0x34, 0xbb, 0xbf, 0xcb, 0xbb, 0x20, + 0x1b, 0xdd, 0xa6, 0x91, 0xb1, 0x59, 0x1d, 0x30, + 0x0, 0x77, 0x6, 0x80, 0xb0, 0x49, 0xc, 0x30, + 0x0, 0x77, 0x4, 0xbb, 0xbd, 0xbb, 0xbb, 0x20, + 0x0, 0x77, 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, + 0x0, 0x77, 0x2e, 0xee, 0xff, 0xee, 0xee, 0xd0, + 0x0, 0x8d, 0xe1, 0x4, 0xda, 0x90, 0x29, 0x0, + 0x2b, 0xf8, 0x11, 0x9f, 0x30, 0xe7, 0xd4, 0x0, + 0x27, 0x10, 0x8e, 0x7e, 0x10, 0x3f, 0x60, 0x0, + 0x0, 0x0, 0x31, 0xe, 0x14, 0x84, 0xe7, 0x0, + 0x0, 0x0, 0x0, 0x2f, 0xe9, 0x40, 0x2a, 0xd0, + 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, + + /* U+58D3 "壓" */ + 0x0, 0xfd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xc0, + 0x0, 0xe0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0xe1, 0xe8, 0x88, 0xd0, 0xb, 0x3b, 0x0, + 0x0, 0xe1, 0xd7, 0x77, 0xd0, 0xb, 0x14, 0x60, + 0x0, 0xe1, 0xa9, 0x99, 0x99, 0xdf, 0xed, 0xc0, + 0x0, 0xe4, 0xa9, 0x99, 0xb0, 0xe, 0x90, 0x0, + 0x1, 0xe6, 0xc8, 0x88, 0xe0, 0x2b, 0xd1, 0x0, + 0x1, 0xd6, 0xa5, 0x55, 0xd0, 0x95, 0x78, 0x0, + 0x2, 0xc6, 0xa4, 0x44, 0xe6, 0xb0, 0xd, 0x70, + 0x3, 0xb4, 0x60, 0x4a, 0x87, 0x0, 0x1, 0xa0, + 0x5, 0x90, 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, + 0x8, 0x60, 0xcc, 0xcc, 0xdf, 0xcc, 0xcc, 0x0, + 0xd, 0x20, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, + 0x1b, 0x2c, 0xcc, 0xcc, 0xdf, 0xcc, 0xcc, 0xc1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+58EB "士" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x1a, 0x91, 0x11, 0x11, 0x10, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x50, + 0x0, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0, + + /* U+58F0 "声" */ + 0x0, 0x0, 0x0, 0xa, 0x60, 0x0, 0x0, 0x0, + 0xde, 0xee, 0xee, 0xff, 0xee, 0xee, 0xeb, 0x0, + 0x0, 0x0, 0xa, 0x60, 0x0, 0x0, 0x0, 0x3, + 0x33, 0x33, 0xb8, 0x33, 0x33, 0x30, 0x0, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xee, + 0xef, 0xfe, 0xee, 0xfb, 0x0, 0x9, 0x70, 0x0, + 0xa6, 0x0, 0x5, 0xb0, 0x0, 0xa6, 0x0, 0xa, + 0x60, 0x0, 0x5b, 0x0, 0xc, 0xed, 0xdd, 0xfe, + 0xdd, 0xde, 0xb0, 0x0, 0xe2, 0x0, 0x0, 0x0, + 0x0, 0x5b, 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x30, 0xa, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+58F2 "売" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x6e, 0xee, 0xee, 0xee, 0xee, 0xe8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x70, + 0x7, 0x90, 0x0, 0x0, 0x0, 0x0, 0x9, 0x70, + 0x7, 0x80, 0x9, 0x40, 0x9, 0x40, 0x9, 0x70, + 0x0, 0x0, 0xe, 0x30, 0xb, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x2f, 0x0, 0xb, 0x50, 0x0, 0x10, + 0x0, 0x0, 0xb8, 0x0, 0xb, 0x50, 0x0, 0xe0, + 0x0, 0x2c, 0xc1, 0x0, 0xb, 0x60, 0x1, 0xe0, + 0xc, 0xf8, 0x0, 0x0, 0x6, 0xff, 0xff, 0x70, + 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5909 "変" */ + 0x0, 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xa0, 0x0, 0x0, 0x0, + 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0x0, 0x4, 0xc0, 0xa, 0x60, 0x0, 0x0, + 0x0, 0x8, 0x74, 0xc0, 0xa, 0x68, 0x70, 0x0, + 0x0, 0x2e, 0x14, 0xc0, 0xa, 0x60, 0xc8, 0x0, + 0x2, 0xe4, 0x4, 0xc0, 0xa, 0x60, 0x1d, 0x60, + 0x4, 0x50, 0x3, 0xb0, 0x8, 0x40, 0x2, 0x40, + 0x0, 0x0, 0x4, 0xe2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0xee, 0xee, 0xef, 0x60, 0x0, + 0x0, 0x2b, 0xcd, 0x10, 0x0, 0x7d, 0x0, 0x0, + 0x6, 0xd5, 0x5, 0xd2, 0x9, 0xd1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5f, 0xea, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x5a, 0xea, 0x9e, 0xb6, 0x20, 0x0, + 0xb, 0xed, 0xa5, 0x0, 0x0, 0x5a, 0xdf, 0xd1, + 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, 0x1, 0x30, + + /* U+590F "夏" */ + 0xd, 0xee, 0xee, 0xef, 0xee, 0xee, 0xee, 0x80, + 0x0, 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x4c, 0xbb, 0xbe, 0xbb, 0xbb, 0xc0, 0x0, + 0x0, 0x5b, 0x0, 0x0, 0x0, 0x0, 0xf0, 0x0, + 0x0, 0x5e, 0xbb, 0xbb, 0xbb, 0xbb, 0xf0, 0x0, + 0x0, 0x5b, 0x22, 0x22, 0x22, 0x22, 0xf0, 0x0, + 0x0, 0x5e, 0x99, 0x99, 0x99, 0x99, 0xf0, 0x0, + 0x0, 0x5d, 0x77, 0x77, 0x77, 0x77, 0xf0, 0x0, + 0x0, 0x12, 0x4e, 0x82, 0x22, 0x23, 0x20, 0x0, + 0x0, 0x4, 0xee, 0xcc, 0xcc, 0xdf, 0x40, 0x0, + 0x6, 0xda, 0x5d, 0x30, 0x2, 0xd8, 0x0, 0x0, + 0x18, 0x20, 0x2, 0xd9, 0x9d, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x48, 0xdd, 0xec, 0x84, 0x0, 0x0, + 0x4c, 0xed, 0xa6, 0x10, 0x3, 0x8c, 0xee, 0xc1, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, + + /* U+5915 "夕" */ + 0x0, 0x0, 0x0, 0x51, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, + 0xff, 0xff, 0xff, 0xe1, 0x0, 0x4, 0xf4, 0x11, + 0x11, 0x17, 0xd0, 0x0, 0x3f, 0x50, 0x0, 0x0, + 0xc, 0x80, 0x5, 0xf7, 0x21, 0x0, 0x0, 0x3f, + 0x10, 0x5f, 0x40, 0x7e, 0x50, 0x0, 0xc9, 0x0, + 0x2, 0x0, 0x3, 0xda, 0x7, 0xe1, 0x0, 0x0, + 0x0, 0x0, 0x1b, 0xdf, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9f, 0x60, 0x0, 0x0, 0x0, 0x0, 0x3c, 0xd2, + 0x0, 0x0, 0x0, 0x0, 0x6c, 0xf9, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xd7, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5916 "外" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xa0, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0xb, 0x60, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0x1f, 0xff, 0xff, 0x32, 0xe0, 0x0, 0x0, + 0x0, 0x6b, 0x0, 0x1f, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0xd3, 0x0, 0x3d, 0x2, 0xf6, 0x0, 0x0, + 0x7, 0xb1, 0x0, 0x79, 0x2, 0xfc, 0xa0, 0x0, + 0x1e, 0x4e, 0x50, 0xd5, 0x2, 0xe0, 0xad, 0x10, + 0x1, 0x2, 0xcb, 0xd0, 0x2, 0xe0, 0x9, 0xd1, + 0x0, 0x0, 0xe, 0x60, 0x2, 0xe0, 0x0, 0x70, + 0x0, 0x0, 0x7e, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0x3, 0xf4, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0x4e, 0x70, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x8, 0xf7, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x1b, 0x30, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, + + /* U+591A "多" */ + 0x0, 0x0, 0x0, 0x51, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7d, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9f, 0xff, 0xff, 0xf6, 0x0, 0x0, 0x3, + 0xca, 0x0, 0x0, 0x7b, 0x0, 0x0, 0xa, 0xe5, + 0x82, 0x0, 0x7d, 0x10, 0x0, 0x0, 0x30, 0x5, + 0xe6, 0xbb, 0x10, 0x0, 0x0, 0x0, 0x0, 0x1a, + 0xf7, 0x49, 0x0, 0x0, 0x0, 0x15, 0xae, 0x81, + 0x3f, 0x82, 0x22, 0x20, 0x7f, 0xb6, 0x0, 0x5e, + 0xcc, 0xcc, 0xed, 0x0, 0x0, 0x1, 0xbc, 0x20, + 0x0, 0x2f, 0x40, 0x0, 0x2a, 0xe7, 0x64, 0x0, + 0x2d, 0x70, 0x0, 0x4, 0x70, 0x3, 0xe7, 0x5e, + 0x70, 0x0, 0x0, 0x0, 0x0, 0x6, 0xfc, 0x20, + 0x0, 0x0, 0x0, 0x14, 0x9e, 0xc6, 0x0, 0x0, + 0x0, 0x6b, 0xef, 0xc8, 0x20, 0x0, 0x0, 0x0, + 0x3, 0x52, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+591C "夜" */ + 0x0, 0x0, 0x0, 0x8, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xa0, 0x0, 0x0, 0x0, + 0xc, 0xcc, 0xcc, 0xcd, 0xfd, 0xcc, 0xcc, 0xc0, + 0x3, 0x33, 0xa8, 0x33, 0x4d, 0x33, 0x33, 0x30, + 0x0, 0x1, 0xf2, 0x0, 0x8a, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xa0, 0x2, 0xfe, 0xee, 0xee, 0x60, + 0x0, 0x3f, 0x30, 0xb, 0x83, 0x10, 0x1e, 0x20, + 0x1, 0xef, 0x20, 0x8f, 0xa, 0x90, 0x5b, 0x0, + 0x1d, 0x8e, 0x27, 0xda, 0x70, 0xa5, 0xc5, 0x0, + 0x39, 0xe, 0x29, 0x10, 0xd2, 0x7, 0xb0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x4d, 0x5d, 0x10, 0x0, + 0x0, 0xe, 0x20, 0x0, 0xb, 0xf4, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x1, 0xad, 0x9e, 0x40, 0x0, + 0x0, 0xe, 0x22, 0x8e, 0x90, 0x4, 0xeb, 0x40, + 0x0, 0xe, 0x2c, 0x92, 0x0, 0x0, 0x7, 0xd3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5920 "夠" */ + 0x0, 0x0, 0x50, 0x0, 0x0, 0x30, 0x0, 0x0, + 0x0, 0x7, 0xa0, 0x0, 0x6, 0xa0, 0x0, 0x0, + 0x0, 0x2f, 0xed, 0xd4, 0xc, 0x50, 0x0, 0x0, + 0x3, 0xe4, 0x2, 0xe0, 0x2f, 0xee, 0xee, 0xf3, + 0xc, 0x66, 0xb, 0x70, 0xb6, 0x0, 0x0, 0xc3, + 0x0, 0xb, 0xcb, 0x5, 0xd0, 0x0, 0x0, 0xc3, + 0x0, 0x7, 0xd3, 0x8, 0x4f, 0xee, 0xe0, 0xd2, + 0x5, 0xd8, 0xa7, 0x0, 0xd, 0x0, 0xe0, 0xd2, + 0x3, 0x28, 0xfe, 0xee, 0xd, 0x0, 0xe0, 0xe2, + 0x2, 0xcb, 0x0, 0x88, 0xd, 0x0, 0xe0, 0xe1, + 0xc, 0x78, 0x52, 0xf2, 0xf, 0xaa, 0xe0, 0xf0, + 0x0, 0x2, 0xee, 0x70, 0xe, 0x33, 0x20, 0xf0, + 0x0, 0x0, 0xab, 0x0, 0xc, 0x0, 0x2, 0xe0, + 0x0, 0x5d, 0x80, 0x0, 0x0, 0x0, 0x7, 0xb0, + 0xc, 0xb3, 0x0, 0x0, 0x0, 0xb, 0xfe, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5927 "大" */ + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x60, 0x0, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x1, 0x11, 0x11, 0x3f, 0xf3, 0x11, 0x11, 0x10, + 0x0, 0x0, 0x0, 0x6c, 0xb7, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb7, 0x4d, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xf1, 0xd, 0x70, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x80, 0x4, 0xf2, 0x0, 0x0, + 0x0, 0x0, 0xad, 0x0, 0x0, 0x9d, 0x10, 0x0, + 0x0, 0x9, 0xe1, 0x0, 0x0, 0xb, 0xd1, 0x0, + 0x4, 0xdc, 0x20, 0x0, 0x0, 0x0, 0xbf, 0x60, + 0x1d, 0x70, 0x0, 0x0, 0x0, 0x0, 0x6, 0xc1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5929 "天" */ + 0x0, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0, + 0x5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, + 0x0, 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x70, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x1c, 0x71, 0x11, 0x11, 0x10, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0x2f, 0xf1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8b, 0x98, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xf3, 0x1e, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x1d, 0x80, 0x6, 0xd1, 0x0, 0x0, + 0x0, 0x2, 0xda, 0x0, 0x0, 0xad, 0x20, 0x0, + 0x1, 0x8f, 0x80, 0x0, 0x0, 0x8, 0xf7, 0x10, + 0x1e, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x4c, 0xf2, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + + /* U+592A "太" */ + 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x1c, 0x71, 0x11, 0x11, 0x10, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x0, 0x0, 0x1f, 0xf3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5d, 0x89, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa8, 0x2e, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xf2, 0xc, 0x80, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x90, 0x3, 0xf2, 0x0, 0x0, + 0x0, 0x0, 0x7f, 0xb1, 0x0, 0x9c, 0x10, 0x0, + 0x0, 0x6, 0xf4, 0xad, 0x10, 0xc, 0xc0, 0x0, + 0x2, 0xbe, 0x30, 0x9, 0xd1, 0x0, 0xcd, 0x40, + 0x1f, 0x91, 0x0, 0x0, 0xa6, 0x0, 0x8, 0xf3, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+592B "夫" */ + 0x0, 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, 0x0, + 0x0, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x11, 0x11, 0x1a, 0x81, 0x11, 0x11, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x70, 0x0, 0x0, 0x0, + 0x2, 0x33, 0x33, 0x3c, 0x83, 0x33, 0x33, 0x30, + 0xd, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xd0, + 0x0, 0x0, 0x0, 0x3f, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb9, 0xa8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xf2, 0x2f, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x8f, 0x40, 0x4, 0xf5, 0x0, 0x0, + 0x0, 0x4c, 0xd3, 0x0, 0x0, 0x4e, 0xb3, 0x0, + 0x1d, 0xe8, 0x0, 0x0, 0x0, 0x1, 0x9f, 0xe2, + 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, + + /* U+592E "央" */ + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x11, 0x1a, 0x81, 0x11, 0x10, 0x0, + 0x0, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x0, + 0x0, 0x5a, 0x0, 0x9, 0x70, 0x0, 0x97, 0x0, + 0x0, 0x5a, 0x0, 0xa, 0x70, 0x0, 0x97, 0x0, + 0x0, 0x5a, 0x0, 0xb, 0x60, 0x0, 0x97, 0x0, + 0x0, 0x5a, 0x0, 0xc, 0x50, 0x0, 0x97, 0x0, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x1, 0x11, 0x11, 0x6e, 0xd5, 0x11, 0x11, 0x10, + 0x0, 0x0, 0x0, 0xc7, 0x5c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9, 0xd0, 0xb, 0x90, 0x0, 0x0, + 0x0, 0x1, 0xae, 0x20, 0x1, 0xda, 0x10, 0x0, + 0x1, 0x7e, 0xb1, 0x0, 0x0, 0x1a, 0xe7, 0x20, + 0x1e, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x4a, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5931 "失" */ + 0x0, 0x3, 0x90, 0xa, 0x70, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x70, 0xa, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0xdc, 0xce, 0xec, 0xcc, 0xca, 0x0, + 0x0, 0x99, 0x44, 0x4b, 0xa4, 0x44, 0x43, 0x0, + 0x4, 0xe0, 0x0, 0xa, 0x70, 0x0, 0x0, 0x0, + 0xb, 0x60, 0x0, 0xb, 0x60, 0x0, 0x0, 0x0, + 0x2, 0x21, 0x11, 0x1c, 0x71, 0x11, 0x11, 0x10, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x4e, 0xd4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc8, 0x5c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8, 0xd1, 0xc, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x9e, 0x30, 0x1, 0xe9, 0x0, 0x0, + 0x0, 0x5d, 0xc1, 0x0, 0x0, 0x2c, 0xd5, 0x0, + 0x1e, 0xd6, 0x0, 0x0, 0x0, 0x0, 0x7d, 0xf3, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + + /* U+5947 "奇" */ + 0x0, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, + 0x4, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0x60, + 0x0, 0x0, 0x0, 0x4f, 0x61, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0xe8, 0xae, 0x92, 0x0, 0x0, + 0x1, 0x47, 0xcd, 0x40, 0x1, 0x7e, 0xc5, 0x0, + 0x5, 0xb8, 0x40, 0x0, 0x0, 0x0, 0x69, 0x0, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0x6e, 0xee, 0xee, 0xc0, 0x2, 0xe0, 0x0, + 0x0, 0x78, 0x0, 0x2, 0xd0, 0x2, 0xe0, 0x0, + 0x0, 0x78, 0x0, 0x2, 0xd0, 0x2, 0xe0, 0x0, + 0x0, 0x7e, 0xbb, 0xbc, 0xd0, 0x2, 0xe0, 0x0, + 0x0, 0x7a, 0x22, 0x22, 0x20, 0x3, 0xe0, 0x0, + 0x0, 0x22, 0x0, 0x0, 0x1f, 0xfe, 0x90, 0x0, + + /* U+5951 "契" */ + 0x0, 0x2, 0xd0, 0x0, 0xff, 0xff, 0xff, 0xc0, + 0xc, 0xde, 0xfd, 0xd6, 0x0, 0xd2, 0x4, 0xb0, + 0x0, 0x2, 0xd0, 0x0, 0x0, 0xf0, 0x4, 0xb0, + 0x7, 0xde, 0xfd, 0xd3, 0x3, 0xd0, 0x5, 0xa0, + 0x0, 0x2, 0xd0, 0x0, 0xa, 0x70, 0x6, 0x90, + 0x6, 0x67, 0xe6, 0x63, 0x5e, 0x0, 0x7, 0x80, + 0x8, 0x8a, 0xe8, 0x9e, 0xe3, 0x1, 0x1b, 0x60, + 0x0, 0x2, 0xd0, 0xa, 0x40, 0x9, 0xdb, 0x10, + 0x0, 0x1, 0x50, 0xc, 0x50, 0x0, 0x0, 0x0, + 0xe, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe0, + 0x0, 0x0, 0x0, 0x9a, 0xa9, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xe1, 0x1d, 0x70, 0x0, 0x0, + 0x0, 0x27, 0xdb, 0x10, 0x1, 0xbd, 0x83, 0x0, + 0x2e, 0xc8, 0x20, 0x0, 0x0, 0x3, 0x9d, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5957 "套" */ + 0x0, 0x0, 0x0, 0x8, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x0, 0x0, + 0xd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0x0, 0x2e, 0x60, 0x3, 0xe3, 0x0, 0x0, + 0x0, 0x2, 0xe8, 0x0, 0x0, 0x4f, 0x50, 0x0, + 0x0, 0x7f, 0xfe, 0xee, 0xee, 0xed, 0xea, 0x10, + 0x1d, 0xc3, 0xd3, 0x0, 0x0, 0x0, 0x1a, 0xf2, + 0x4, 0x0, 0xdd, 0xcc, 0xcc, 0xcb, 0x0, 0x20, + 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xdd, 0xcc, 0xcc, 0xcb, 0x0, 0x0, + 0x1, 0x11, 0xd4, 0x11, 0x11, 0x11, 0x11, 0x10, + 0xd, 0xdd, 0xdf, 0xed, 0xdd, 0xdd, 0xdd, 0xd0, + 0x0, 0x1, 0xa8, 0x0, 0x0, 0x6b, 0x0, 0x0, + 0x0, 0x5e, 0xc8, 0x9a, 0xbc, 0xcf, 0xd1, 0x0, + 0x0, 0x47, 0x65, 0x43, 0x21, 0x0, 0x5a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5973 "女" */ + 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8b, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0x44, 0x4a, 0xd4, 0x44, 0x44, 0x44, 0x40, + 0xc, 0xcc, 0xdf, 0xdc, 0xcc, 0xdf, 0xcc, 0xc1, + 0x0, 0x0, 0x6d, 0x0, 0x0, 0x7c, 0x0, 0x0, + 0x0, 0x0, 0xd6, 0x0, 0x0, 0xc7, 0x0, 0x0, + 0x0, 0x5, 0xe0, 0x0, 0x2, 0xf1, 0x0, 0x0, + 0x0, 0xd, 0xc3, 0x0, 0xb, 0xa0, 0x0, 0x0, + 0x0, 0x2, 0x8e, 0xc5, 0x6e, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6e, 0xfa, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xbf, 0x8d, 0xe6, 0x0, 0x0, + 0x0, 0x15, 0xaf, 0xb2, 0x0, 0x6e, 0xd3, 0x0, + 0xd, 0xfd, 0x82, 0x0, 0x0, 0x0, 0x9f, 0x60, + 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, + + /* U+5979 "她" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3c, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x0, 0x6a, 0x0, 0x1, 0xd0, 0x1e, 0x0, 0x0, + 0x0, 0x97, 0x0, 0x1, 0xe0, 0x1e, 0x0, 0x20, + 0x2f, 0xff, 0xff, 0x11, 0xe0, 0x1e, 0x8e, 0xc0, + 0x0, 0xe1, 0xf, 0x1, 0xe6, 0xcf, 0x74, 0xc0, + 0x2, 0xd0, 0x2d, 0x5b, 0xf9, 0x5e, 0x3, 0xc0, + 0x6, 0x90, 0x5b, 0x66, 0xe0, 0x1e, 0x3, 0xb0, + 0xa, 0x50, 0x87, 0x1, 0xe0, 0x1e, 0x4, 0xb0, + 0xd, 0xa0, 0xd3, 0x1, 0xe0, 0x1e, 0x5, 0xa0, + 0x1, 0xcd, 0xe0, 0x1, 0xe0, 0x1e, 0x7f, 0x50, + 0x0, 0xc, 0xf3, 0x1, 0xe0, 0x1d, 0x0, 0x0, + 0x0, 0x4f, 0x9f, 0x31, 0xe0, 0x0, 0x0, 0x93, + 0x3, 0xe6, 0x6, 0x20, 0xf2, 0x0, 0x1, 0xd2, + 0x1e, 0x60, 0x0, 0x0, 0x9f, 0xff, 0xff, 0xa0, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+597D "好" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4b, 0x0, 0x6, 0xee, 0xee, 0xef, 0x80, + 0x0, 0x79, 0x0, 0x0, 0x0, 0x0, 0x6d, 0x10, + 0x4f, 0xff, 0xff, 0xa0, 0x0, 0x4, 0xd2, 0x0, + 0x0, 0xe2, 0x7, 0x80, 0x0, 0x3d, 0x10, 0x0, + 0x2, 0xe0, 0xa, 0x50, 0x0, 0x5b, 0x0, 0x0, + 0x6, 0x90, 0xd, 0x4c, 0xcc, 0xdf, 0xcc, 0xc4, + 0xb, 0x60, 0x3e, 0x3, 0x33, 0x8c, 0x33, 0x31, + 0x7, 0xf6, 0x98, 0x0, 0x0, 0x5b, 0x0, 0x0, + 0x0, 0x3d, 0xf2, 0x0, 0x0, 0x5b, 0x0, 0x0, + 0x0, 0xa, 0xfc, 0x10, 0x0, 0x5b, 0x0, 0x0, + 0x0, 0x7d, 0x1c, 0xb0, 0x0, 0x5b, 0x0, 0x0, + 0x9, 0xe2, 0x0, 0x30, 0x0, 0x6b, 0x0, 0x0, + 0x4b, 0x10, 0x0, 0x0, 0x9f, 0xe6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5982 "如" */ + 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x80, 0x0, 0x29, 0x99, 0x99, 0x90, 0x0, + 0xb6, 0x0, 0x3, 0xd6, 0x66, 0x7f, 0xf, 0xff, + 0xff, 0xfc, 0x3c, 0x0, 0x1, 0xf0, 0x2, 0xe0, + 0x6, 0xa3, 0xc0, 0x0, 0x1f, 0x0, 0x5a, 0x0, + 0x98, 0x3c, 0x0, 0x1, 0xf0, 0x9, 0x70, 0xc, + 0x53, 0xc0, 0x0, 0x1f, 0x0, 0xe2, 0x0, 0xf1, + 0x3c, 0x0, 0x1, 0xf0, 0x1e, 0x80, 0x6b, 0x3, + 0xc0, 0x0, 0x1f, 0x0, 0x2c, 0xcc, 0x50, 0x3c, + 0x0, 0x1, 0xf0, 0x0, 0xb, 0xf3, 0x3, 0xc0, + 0x0, 0x1f, 0x0, 0x3, 0xfa, 0xf3, 0x3c, 0x22, + 0x23, 0xf0, 0x6, 0xf6, 0x7, 0x83, 0xfd, 0xdd, + 0xdf, 0xb, 0xe4, 0x0, 0x0, 0x3c, 0x0, 0x0, + 0x90, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5987 "妇" */ + 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6a, 0x0, 0xd, 0xdd, 0xdd, 0xdd, 0x20, 0x9, + 0x80, 0x0, 0x22, 0x22, 0x22, 0xe2, 0x5f, 0xff, + 0xff, 0x30, 0x0, 0x0, 0xd, 0x20, 0xf, 0x10, + 0xe1, 0x0, 0x0, 0x0, 0xd2, 0x3, 0xd0, 0xf, + 0x0, 0x0, 0x0, 0xd, 0x20, 0x79, 0x3, 0xc0, + 0x9f, 0xff, 0xff, 0xf2, 0xc, 0x50, 0x88, 0x0, + 0x11, 0x11, 0x1e, 0x20, 0xae, 0x4d, 0x30, 0x0, + 0x0, 0x0, 0xd2, 0x0, 0x5e, 0xe0, 0x0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0xde, 0x80, 0x0, 0x0, + 0x0, 0xd2, 0x0, 0x9a, 0x1d, 0x40, 0x0, 0x0, + 0xe, 0x20, 0xac, 0x0, 0x12, 0xff, 0xff, 0xff, + 0xf2, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x20, + + /* U+59B3 "妳" */ + 0x0, 0x4, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0x5d, 0x0, 0x0, 0x0, + 0x0, 0x5b, 0x0, 0x0, 0xa8, 0x0, 0x0, 0x0, + 0x0, 0x89, 0x0, 0x0, 0xee, 0xcc, 0xcc, 0xd4, + 0x4f, 0xff, 0xff, 0x27, 0xc2, 0x4e, 0x23, 0xe2, + 0x0, 0xd2, 0xe, 0x1e, 0x30, 0x1e, 0x2, 0xd0, + 0x1, 0xe0, 0x1e, 0x28, 0x0, 0x1e, 0x3, 0x50, + 0x5, 0x90, 0x3c, 0x0, 0x69, 0x1e, 0xe, 0x10, + 0xa, 0x50, 0x78, 0x0, 0xb5, 0x1e, 0x8, 0x80, + 0x9, 0xc2, 0xc3, 0x0, 0xe1, 0x1e, 0x2, 0xe0, + 0x0, 0x7e, 0xe0, 0x7, 0xa0, 0x1e, 0x0, 0xd3, + 0x0, 0xb, 0xf3, 0xb, 0x30, 0x1e, 0x0, 0x97, + 0x0, 0x6d, 0x6e, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x6, 0xf3, 0x1, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x1d, 0x30, 0x0, 0x0, 0x2f, 0xf9, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+59B9 "妹" */ + 0x0, 0x3b, 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0x59, 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0x87, 0x0, 0x29, 0x99, 0xfa, 0x99, 0x60, + 0x2f, 0xff, 0xff, 0x15, 0x55, 0xf7, 0x55, 0x40, + 0x0, 0xe0, 0x1e, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x2, 0xd0, 0x3c, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x6, 0x90, 0x6a, 0xae, 0xee, 0xff, 0xee, 0xe2, + 0xa, 0x50, 0xa6, 0x0, 0x8, 0xfd, 0x0, 0x0, + 0x8, 0xe4, 0xe1, 0x0, 0x1e, 0xfc, 0x60, 0x0, + 0x0, 0x5e, 0xd0, 0x0, 0xa6, 0xe4, 0xd1, 0x0, + 0x0, 0xd, 0xf7, 0x5, 0xd0, 0xe2, 0x7b, 0x0, + 0x0, 0x8b, 0x1b, 0x4e, 0x20, 0xe2, 0xb, 0xa0, + 0x9, 0xe1, 0x0, 0xc4, 0x0, 0xe2, 0x0, 0x91, + 0x2b, 0x10, 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, + + /* U+59BB "妻" */ + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0xb, 0xdd, 0xdd, 0xdf, 0xed, 0xdd, 0xdd, 0x90, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x6d, 0xdd, 0xde, 0xed, 0xdd, 0xf5, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0xb5, 0x0, + 0x2d, 0xdd, 0xdd, 0xdf, 0xed, 0xdd, 0xfe, 0xd2, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0xb5, 0x0, + 0x0, 0x7d, 0xdd, 0xef, 0xdd, 0xdd, 0xd4, 0x0, + 0x0, 0x0, 0x0, 0xd5, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0xdd, 0xef, 0xed, 0xdd, 0xef, 0xed, 0xd1, + 0x0, 0x0, 0x9a, 0x0, 0x0, 0x9a, 0x0, 0x0, + 0x0, 0x3, 0xbd, 0xb7, 0x5c, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x25, 0xaf, 0xcd, 0xc8, 0x40, 0x0, + 0xd, 0xee, 0xca, 0x62, 0x0, 0x16, 0xbe, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+59C9 "姉" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6a, 0x0, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0x87, 0x0, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0xb5, 0x0, 0x6d, 0xdd, 0xfd, 0xdd, 0xd5, + 0x5f, 0xff, 0xff, 0x11, 0x11, 0xe2, 0x11, 0x10, + 0x0, 0xf0, 0xe, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x3, 0xc0, 0x3c, 0x2f, 0xff, 0xff, 0xff, 0xe0, + 0x6, 0x80, 0x5a, 0x2d, 0x11, 0xe2, 0x12, 0xe0, + 0xa, 0x50, 0x97, 0x2d, 0x0, 0xe1, 0x1, 0xe0, + 0xa, 0xb0, 0xd2, 0x2d, 0x0, 0xe1, 0x1, 0xe0, + 0x0, 0x9e, 0xd0, 0x2d, 0x0, 0xe1, 0x1, 0xe0, + 0x0, 0xc, 0xe1, 0x2d, 0x0, 0xe1, 0x1, 0xe0, + 0x0, 0x6d, 0x7d, 0x3d, 0x0, 0xe1, 0xbf, 0xb0, + 0x6, 0xe3, 0x5, 0x2, 0x0, 0xe1, 0x0, 0x0, + 0x1c, 0x20, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+59CB "始" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0x0, 0x6, 0xc0, 0x0, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0xe, 0x50, 0x0, 0x0, + 0x0, 0x88, 0x0, 0x0, 0x6c, 0x1, 0xb0, 0x0, + 0x4f, 0xff, 0xff, 0x21, 0xe3, 0x0, 0xa7, 0x0, + 0x0, 0xe1, 0xe, 0xa, 0x70, 0x0, 0x1e, 0x20, + 0x1, 0xd0, 0x1e, 0x7f, 0xcc, 0xde, 0xff, 0xa0, + 0x5, 0xa0, 0x3c, 0x46, 0x53, 0x21, 0x0, 0xc1, + 0x9, 0x60, 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xa0, 0xb4, 0xc, 0xfe, 0xee, 0xef, 0x30, + 0x0, 0x9d, 0xe0, 0xc, 0x30, 0x0, 0xc, 0x30, + 0x0, 0xa, 0xf3, 0xc, 0x30, 0x0, 0xc, 0x30, + 0x0, 0x3e, 0x7e, 0x2c, 0x30, 0x0, 0xc, 0x30, + 0x2, 0xd3, 0x6, 0x2c, 0x63, 0x33, 0x3d, 0x30, + 0x1b, 0x20, 0x0, 0xc, 0xcb, 0xbb, 0xbe, 0x30, + + /* U+59D0 "姐" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3d, 0x0, 0xe, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0x5a, 0x0, 0xe, 0x10, 0x0, 0x2e, 0x0, + 0x17, 0xbb, 0x77, 0xe, 0x10, 0x0, 0x2e, 0x0, + 0x1a, 0xeb, 0xaf, 0xe, 0x10, 0x0, 0x2e, 0x0, + 0x0, 0xe1, 0x1e, 0xe, 0xcc, 0xcc, 0xde, 0x0, + 0x1, 0xe0, 0x3c, 0xe, 0x43, 0x33, 0x5e, 0x0, + 0x4, 0xb0, 0x5a, 0xe, 0x10, 0x0, 0x2e, 0x0, + 0x8, 0x80, 0x87, 0xe, 0x10, 0x0, 0x2e, 0x0, + 0xb, 0x80, 0xc3, 0xe, 0x54, 0x44, 0x6e, 0x0, + 0x1, 0xd9, 0xe0, 0xe, 0xbb, 0xbb, 0xce, 0x0, + 0x0, 0xd, 0xc0, 0xe, 0x10, 0x0, 0x2e, 0x0, + 0x0, 0x2e, 0xd8, 0xe, 0x10, 0x0, 0x2e, 0x0, + 0x1, 0xc7, 0x18, 0x1e, 0x20, 0x0, 0x3e, 0x0, + 0xd, 0x90, 0x8, 0xee, 0xee, 0xee, 0xee, 0xe5, + 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+59D4 "委" */ + 0x0, 0x0, 0x12, 0x34, 0x57, 0x8b, 0xd2, 0x0, + 0x0, 0xbd, 0xcc, 0xbd, 0xc7, 0x53, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, + 0xd, 0xee, 0xee, 0xff, 0xff, 0xfe, 0xee, 0xe3, + 0x0, 0x0, 0x1a, 0xc9, 0x9a, 0xb2, 0x0, 0x0, + 0x0, 0x16, 0xe7, 0x7, 0x90, 0x5e, 0x93, 0x0, + 0xa, 0xd7, 0x10, 0x4a, 0x80, 0x0, 0x5b, 0xe3, + 0x3, 0x0, 0x1, 0xe3, 0x0, 0x0, 0x0, 0x20, + 0x1e, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xee, 0xe6, + 0x0, 0x0, 0x9b, 0x0, 0x0, 0x9b, 0x0, 0x0, + 0x0, 0x6, 0xf7, 0x20, 0x6, 0xe2, 0x0, 0x0, + 0x0, 0x1, 0x58, 0xce, 0xcf, 0x60, 0x0, 0x0, + 0x0, 0x12, 0x48, 0xde, 0x88, 0xce, 0xa5, 0x0, + 0xa, 0xfd, 0xa7, 0x30, 0x0, 0x1, 0x6b, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5A18 "娘" */ + 0x0, 0x18, 0x0, 0x0, 0x2, 0x70, 0x0, 0x0, + 0x0, 0x3c, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0x6a, 0x0, 0xb, 0xcc, 0xfe, 0xcc, 0x10, + 0x4, 0xaa, 0x43, 0xe, 0x32, 0x22, 0x2e, 0x10, + 0xc, 0xfd, 0xdd, 0xe, 0x10, 0x0, 0xe, 0x10, + 0x0, 0xe1, 0x4b, 0xe, 0xee, 0xee, 0xef, 0x10, + 0x1, 0xe0, 0x6a, 0xe, 0x10, 0x0, 0xe, 0x10, + 0x5, 0xa0, 0x87, 0xe, 0x10, 0x0, 0xe, 0x10, + 0xa, 0x60, 0xb4, 0xe, 0xff, 0xff, 0xff, 0x10, + 0xb, 0x90, 0xe0, 0xe, 0x10, 0xe1, 0x1, 0x30, + 0x0, 0xbd, 0xb0, 0xe, 0x10, 0x98, 0x4d, 0x50, + 0x0, 0xe, 0xc0, 0xe, 0x10, 0x1e, 0xc2, 0x0, + 0x0, 0x6d, 0xb9, 0xe, 0x10, 0x6, 0xd1, 0x0, + 0x4, 0xe3, 0x18, 0xf, 0x8c, 0xb0, 0x7e, 0x50, + 0x1e, 0x40, 0x0, 0x5f, 0x93, 0x0, 0x4, 0xb1, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + + /* U+5A5A "婚" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x2e, 0x0, 0xd, 0xcb, 0xcc, 0x52, 0x0, + 0x0, 0x5b, 0x0, 0xe, 0x10, 0x5a, 0x0, 0x0, + 0x0, 0x88, 0x0, 0xe, 0x20, 0x3c, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xe, 0xdd, 0xdf, 0xdd, 0xd1, + 0x0, 0xe2, 0x1e, 0xe, 0x10, 0xa, 0x50, 0x0, + 0x2, 0xe0, 0x3c, 0xf, 0x23, 0x44, 0xd0, 0x53, + 0x6, 0xb0, 0x5a, 0x5f, 0xfb, 0x60, 0xac, 0xc3, + 0xa, 0x70, 0x96, 0x23, 0x0, 0x0, 0x6, 0x70, + 0x8, 0xc1, 0xd2, 0xb, 0xfe, 0xee, 0xef, 0x10, + 0x0, 0x4e, 0xe0, 0xb, 0x30, 0x0, 0xe, 0x10, + 0x0, 0xc, 0xf8, 0xb, 0xdd, 0xdd, 0xdf, 0x10, + 0x0, 0x6c, 0x2f, 0x4b, 0x30, 0x0, 0xe, 0x10, + 0x3, 0xd2, 0x3, 0xb, 0x41, 0x11, 0x1e, 0x10, + 0x1b, 0x10, 0x0, 0xb, 0xdc, 0xcc, 0xcf, 0x10, + + /* U+5A66 "婦" */ + 0x0, 0x25, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x59, 0x0, 0xc, 0xdd, 0xdd, 0xdf, 0x10, + 0x0, 0x77, 0x0, 0x0, 0x0, 0x0, 0xe, 0x10, + 0x1, 0xa6, 0x11, 0x8, 0xcc, 0xcc, 0xcf, 0x10, + 0x1e, 0xfe, 0xfb, 0x0, 0x0, 0x0, 0xe, 0x10, + 0x0, 0xe0, 0x49, 0xd, 0xdd, 0xdd, 0xdd, 0x10, + 0x1, 0xd0, 0x77, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0x90, 0x95, 0xad, 0xdd, 0xfd, 0xdd, 0xf2, + 0xa, 0x50, 0xd2, 0xa3, 0x0, 0xe1, 0x0, 0xd2, + 0xa, 0x82, 0xd0, 0x4d, 0xdd, 0xfd, 0xdd, 0x91, + 0x0, 0x9e, 0x90, 0xe, 0x31, 0xe3, 0x1b, 0x40, + 0x0, 0xe, 0xd1, 0xe, 0x10, 0xe1, 0xa, 0x40, + 0x0, 0x8a, 0x8c, 0xe, 0x10, 0xe1, 0xb, 0x40, + 0x7, 0xe1, 0x8, 0xe, 0x10, 0xe2, 0xde, 0x20, + 0x1b, 0x10, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + + /* U+5A92 "媒" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4b, 0x0, 0x1, 0xe0, 0x0, 0x1e, 0x0, + 0x0, 0x68, 0x0, 0x9d, 0xfd, 0xdd, 0xdf, 0xd5, + 0x2, 0xa7, 0x21, 0x2, 0xe1, 0x11, 0x2e, 0x10, + 0x1f, 0xff, 0xfd, 0x1, 0xe0, 0x0, 0x1e, 0x0, + 0x1, 0xe2, 0x4c, 0x1, 0xfd, 0xdd, 0xee, 0x0, + 0x1, 0xd0, 0x5a, 0x1, 0xe0, 0x0, 0x1e, 0x0, + 0x4, 0xa0, 0x78, 0x1, 0xfe, 0xee, 0xee, 0x0, + 0x8, 0x60, 0xa5, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0xc, 0x60, 0xe1, 0x12, 0x22, 0xe3, 0x22, 0x20, + 0x2, 0xda, 0xc0, 0x8c, 0xce, 0xff, 0xdc, 0xc5, + 0x0, 0x1e, 0xb0, 0x0, 0x2c, 0xfc, 0x90, 0x0, + 0x0, 0x6d, 0xaa, 0x3, 0xd2, 0xe2, 0xba, 0x0, + 0x6, 0xe2, 0x5, 0x9d, 0x30, 0xe1, 0x8, 0xe5, + 0x1b, 0x20, 0x0, 0x60, 0x0, 0xe1, 0x0, 0x32, + + /* U+5ABD "媽" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x69, 0x0, 0x2f, 0xff, 0xff, 0xff, 0xd0, + 0x0, 0x87, 0x0, 0x2e, 0x0, 0x69, 0x0, 0x0, + 0x0, 0xb5, 0x0, 0x2e, 0x33, 0x8a, 0x33, 0x10, + 0x1e, 0xff, 0xff, 0x2f, 0xaa, 0xdd, 0xaa, 0x40, + 0x0, 0xf0, 0x1e, 0x2e, 0x0, 0x69, 0x0, 0x0, + 0x3, 0xc0, 0x3c, 0x2f, 0xee, 0xff, 0xee, 0x50, + 0x6, 0x90, 0x59, 0x2e, 0x0, 0x69, 0x0, 0x0, + 0xa, 0x60, 0x96, 0x2e, 0x0, 0x69, 0x0, 0x0, + 0xa, 0x80, 0xd1, 0x2e, 0xee, 0xee, 0xee, 0xf0, + 0x0, 0xab, 0xd0, 0x2, 0x0, 0x10, 0x40, 0xf0, + 0x0, 0xd, 0xc0, 0x59, 0x65, 0xa2, 0xa3, 0xe0, + 0x0, 0x5d, 0xa9, 0xa5, 0x58, 0x58, 0x14, 0xd0, + 0x6, 0xe2, 0x3, 0xe0, 0x36, 0x1, 0x6, 0xa0, + 0x1c, 0x20, 0x0, 0x0, 0x0, 0x7, 0xee, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5ACC "嫌" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x60, 0x0, 0xc1, 0x0, 0x2c, 0x0, 0x0, + 0xb4, 0x0, 0x5, 0xa0, 0xb, 0x50, 0x0, 0x2e, + 0x32, 0x4e, 0xee, 0xee, 0xfe, 0xe9, 0x3c, 0xfb, + 0xe4, 0x0, 0xf0, 0x1d, 0x0, 0x0, 0x3b, 0xb, + 0x4d, 0xdf, 0xde, 0xfd, 0xd0, 0x6, 0x80, 0xd1, + 0x0, 0xf0, 0x1d, 0xd, 0x0, 0x95, 0xe, 0x6c, + 0xcf, 0xcc, 0xfc, 0xfb, 0xd, 0x12, 0xc1, 0x11, + 0xf1, 0x3e, 0x1e, 0x11, 0xf2, 0x68, 0x0, 0xf, + 0x1, 0xe0, 0xe0, 0x4, 0xdc, 0x42, 0xde, 0xfd, + 0xdf, 0xed, 0x0, 0x4, 0xf5, 0x0, 0xcf, 0x1, + 0xfa, 0x0, 0x0, 0xb8, 0xd4, 0x98, 0xf0, 0x1d, + 0x96, 0x0, 0xaa, 0x2, 0xbb, 0xf, 0x1, 0xd0, + 0xc7, 0x48, 0x0, 0x6, 0x0, 0xf0, 0x1d, 0x0, + 0x40, + + /* U+5B09 "嬉" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x78, 0x2, 0xcc, 0xcd, 0xfd, 0xcc, 0xc2, + 0x1, 0xa7, 0x11, 0x23, 0x33, 0xf4, 0x33, 0x20, + 0x1c, 0xfc, 0xda, 0x58, 0x88, 0x88, 0x88, 0x50, + 0x0, 0xe0, 0x58, 0xc, 0xcc, 0xcc, 0xcc, 0x10, + 0x3, 0xc0, 0x77, 0x1e, 0x0, 0x0, 0xe, 0x10, + 0x6, 0x90, 0xa5, 0x1f, 0xbb, 0xbb, 0xbf, 0x10, + 0xa, 0x50, 0xd1, 0x3, 0xa0, 0x0, 0xc2, 0x0, + 0xa, 0xb3, 0xd3, 0x56, 0xe6, 0x57, 0xd5, 0x52, + 0x0, 0x9f, 0x94, 0x77, 0x77, 0x77, 0x77, 0x73, + 0x0, 0xe, 0xc0, 0x2b, 0xbb, 0xbb, 0xbb, 0x40, + 0x0, 0x7a, 0xaa, 0x2d, 0x0, 0x0, 0xa, 0x60, + 0x3, 0xd1, 0x17, 0x2d, 0x0, 0x0, 0xa, 0x60, + 0xb, 0x20, 0x0, 0x2f, 0xcc, 0xcc, 0xce, 0x50, + + /* U+5B50 "子" */ + 0x0, 0x1, 0x11, 0x11, 0x11, 0x11, 0x10, 0x0, + 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3d, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0xe5, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xe9, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x18, 0xa1, 0x11, 0x11, 0x10, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x11, 0x19, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8f, 0xfd, 0x40, 0x0, 0x0, 0x0, + + /* U+5B57 "字" */ + 0x0, 0x0, 0x0, 0x91, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa9, 0x0, 0x0, 0x0, 0xae, 0xee, + 0xee, 0xff, 0xee, 0xee, 0xe9, 0xb6, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x8a, 0xb5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7a, 0x31, 0x4f, 0xff, 0xff, 0xff, + 0xe2, 0x23, 0x0, 0x0, 0x0, 0x0, 0x5e, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x19, 0xc2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9a, 0x0, 0x0, 0x0, 0xef, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x0, 0x0, + 0x0, 0x99, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x98, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa8, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xff, 0xd3, 0x0, 0x0, + 0x0, + + /* U+5B58 "存" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x16, 0xd1, 0x11, 0x11, 0x11, 0x10, + 0xe, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xee, 0xe0, + 0x0, 0x0, 0x4e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd5, 0x2, 0x22, 0x22, 0x22, 0x0, + 0x0, 0x7, 0xc0, 0x3c, 0xcc, 0xcc, 0xfe, 0x0, + 0x0, 0x4f, 0x30, 0x0, 0x0, 0x9, 0xd1, 0x0, + 0x4, 0xff, 0x20, 0x0, 0x1, 0xd8, 0x0, 0x0, + 0x3f, 0x6e, 0x20, 0x0, 0x3, 0xe0, 0x0, 0x0, + 0x14, 0xe, 0x2a, 0xff, 0xff, 0xff, 0xff, 0xf4, + 0x0, 0xe, 0x20, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0xa, 0xff, 0x90, 0x0, 0x0, + + /* U+5B63 "季" */ + 0x0, 0x0, 0x12, 0x34, 0x57, 0x9c, 0xc1, 0x0, + 0x0, 0xce, 0xdc, 0xbd, 0xc7, 0x52, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0xe, 0xee, 0xee, 0xff, 0xff, 0xee, 0xee, 0xe1, + 0x0, 0x0, 0x8, 0xda, 0x9c, 0x80, 0x0, 0x0, + 0x0, 0x2, 0xca, 0x19, 0x70, 0xac, 0x30, 0x0, + 0x4, 0xbd, 0x50, 0x5, 0x50, 0x5, 0xdc, 0x50, + 0x1b, 0x55, 0xee, 0xee, 0xee, 0xed, 0x4, 0xb1, + 0x0, 0x0, 0x0, 0x0, 0x6c, 0x91, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0xb1, 0x0, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0xee, 0x50, 0x0, 0x0, 0x0, + + /* U+5B66 "学" */ + 0x0, 0x3, 0x0, 0x9, 0x0, 0x0, 0x32, 0x0, + 0x0, 0x1e, 0x30, 0xa, 0x80, 0x1, 0xe4, 0x0, + 0x0, 0x5, 0xc0, 0x2, 0xe0, 0xa, 0x80, 0x0, + 0x9, 0xee, 0xfe, 0xee, 0xfe, 0xef, 0xee, 0xc0, + 0xa, 0x50, 0x0, 0x0, 0x0, 0x0, 0x4, 0xd0, + 0xa, 0x50, 0x0, 0x0, 0x0, 0x0, 0x3, 0xd0, + 0x2, 0x15, 0xee, 0xee, 0xee, 0xff, 0x30, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x19, 0xd2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5, 0xe7, 0x0, 0x0, 0x0, + 0x2, 0x22, 0x22, 0x2a, 0x92, 0x22, 0x22, 0x20, + 0xd, 0xdd, 0xdd, 0xdf, 0xed, 0xdd, 0xdd, 0xd1, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0xfd, 0x30, 0x0, 0x0, 0x0, + + /* U+5B69 "孩" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, + 0x2, 0x22, 0x22, 0x0, 0x2, 0xf1, 0x0, 0x0, + 0xc, 0xcc, 0xde, 0x10, 0x0, 0xb7, 0x0, 0x0, + 0x0, 0x0, 0x96, 0xbf, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x2, 0xc0, 0x0, 0x1e, 0x20, 0x0, 0x0, + 0x0, 0xc, 0x40, 0x0, 0x98, 0x0, 0x81, 0x0, + 0x0, 0xe, 0x10, 0x5, 0xd1, 0x28, 0xb0, 0x0, + 0x0, 0xe, 0x13, 0x4f, 0xec, 0xee, 0x10, 0x0, + 0x0, 0x3f, 0xec, 0x0, 0x6, 0xe2, 0xb, 0x30, + 0x4f, 0xcf, 0x30, 0x1, 0x9c, 0x20, 0x8c, 0x0, + 0x12, 0xe, 0x10, 0x6e, 0x90, 0x6, 0xe1, 0x0, + 0x0, 0xe, 0x10, 0x42, 0x0, 0x8f, 0x40, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x3c, 0xb6, 0xe3, 0x0, + 0x0, 0xf, 0x10, 0x4a, 0xe5, 0x0, 0x4e, 0x50, + 0xe, 0xfc, 0x4, 0xd6, 0x0, 0x0, 0x4, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5B6B "孫" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x1, 0x11, 0x11, 0x0, 0x24, 0x69, 0xce, 0x40, + 0x9, 0xdd, 0xee, 0x3d, 0xbc, 0xd5, 0x20, 0x0, + 0x0, 0x0, 0xa6, 0x0, 0x1d, 0x40, 0x20, 0x0, + 0x0, 0x3, 0xc0, 0x0, 0xc4, 0x3, 0xe2, 0x0, + 0x0, 0xd, 0x20, 0x2d, 0xc9, 0xad, 0x30, 0x0, + 0x0, 0xf, 0x0, 0x17, 0x59, 0xe2, 0x32, 0x0, + 0x0, 0xf, 0x4, 0x0, 0x7b, 0x10, 0x3d, 0x0, + 0x0, 0x4f, 0xe9, 0x3b, 0xe7, 0x8a, 0xbe, 0x90, + 0x2e, 0xbf, 0x0, 0x59, 0x76, 0xf2, 0x10, 0xc0, + 0x1, 0xf, 0x0, 0x6, 0x41, 0xe0, 0x56, 0x0, + 0x0, 0xf, 0x0, 0x1e, 0x11, 0xe0, 0x1e, 0x30, + 0x0, 0xf, 0x0, 0xa8, 0x1, 0xe0, 0x4, 0xc0, + 0x0, 0xf, 0x7, 0xb0, 0x1, 0xe0, 0x0, 0xb3, + 0x6, 0xdb, 0x0, 0x0, 0x7e, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5B78 "學" */ + 0x0, 0x0, 0x33, 0x10, 0x32, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x83, 0x5c, 0xd1, 0x9c, 0xce, 0x0, + 0x0, 0xb4, 0x0, 0x6c, 0xb6, 0x0, 0x2d, 0x0, + 0x0, 0xad, 0xc8, 0x70, 0x35, 0x8c, 0xdc, 0x0, + 0x0, 0x9a, 0x65, 0x4c, 0xd1, 0x56, 0x9b, 0x0, + 0x0, 0x8a, 0x43, 0xa8, 0x78, 0x34, 0x99, 0x0, + 0xa, 0xee, 0xdd, 0xdd, 0xdd, 0xdd, 0xee, 0xb0, + 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x3, 0xd0, + 0xc, 0x32, 0xdd, 0xdd, 0xdd, 0xdd, 0x13, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x29, 0xc3, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xd5, 0x0, 0x0, 0x0, + 0x1e, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe2, + 0x0, 0x0, 0x0, 0x5, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9, 0xde, 0x60, 0x0, 0x0, 0x0, + + /* U+5B83 "它" */ + 0x0, 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xe0, 0x0, 0x0, 0x0, 0x11, 0x11, + 0x11, 0xd7, 0x11, 0x11, 0x10, 0xdf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf2, 0xd3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0xd3, 0x52, 0x0, 0x0, 0x0, + 0x0, 0xe2, 0x20, 0xc5, 0x0, 0x0, 0x0, 0x10, + 0x20, 0x0, 0xc5, 0x0, 0x0, 0x6d, 0xc0, 0x0, + 0x0, 0xc5, 0x5, 0xaf, 0xb5, 0x0, 0x0, 0x0, + 0xcd, 0xea, 0x51, 0x0, 0x0, 0x0, 0x0, 0xc7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x0, + 0x0, 0x0, 0x1, 0x50, 0x0, 0xc5, 0x0, 0x0, + 0x0, 0x4, 0xd0, 0x0, 0xb9, 0x10, 0x0, 0x0, + 0x1a, 0xa0, 0x0, 0x3d, 0xff, 0xff, 0xff, 0xfc, + 0x20, + + /* U+5B85 "宅" */ + 0x0, 0x0, 0x0, 0xa, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x90, 0x0, 0x0, 0x0, + 0xd, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xb0, + 0xe, 0x41, 0x11, 0x11, 0x11, 0x11, 0x17, 0xb0, + 0xe, 0x20, 0x0, 0x0, 0x27, 0xcc, 0x6, 0xb0, + 0x5, 0x24, 0x69, 0xbe, 0xea, 0x61, 0x2, 0x40, + 0x0, 0xbc, 0x97, 0x8d, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4d, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4d, 0x35, 0x68, 0xac, 0xd0, + 0x16, 0x89, 0xbd, 0xff, 0xdb, 0x97, 0x53, 0x20, + 0x3a, 0x86, 0x53, 0x6d, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4d, 0x0, 0x0, 0x1, 0x40, + 0x0, 0x0, 0x0, 0x4d, 0x0, 0x0, 0x4, 0xc0, + 0x0, 0x0, 0x0, 0x4e, 0x10, 0x0, 0x19, 0xa0, + 0x0, 0x0, 0x0, 0xb, 0xff, 0xff, 0xfd, 0x20, + + /* U+5B87 "宇" */ + 0x0, 0x0, 0x0, 0x71, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb8, 0x0, 0x0, 0x0, 0xbe, 0xee, + 0xee, 0xff, 0xee, 0xee, 0xec, 0xc5, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x5d, 0xc4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3d, 0x62, 0x9e, 0xee, 0xee, 0xee, + 0xea, 0x27, 0x0, 0x1, 0x11, 0x7b, 0x11, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x7a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7b, 0x0, 0x0, 0x0, 0xcf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, + 0x0, 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8a, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xff, 0xd5, 0x0, 0x0, + 0x0, + + /* U+5B88 "守" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x50, 0x0, 0x0, 0x0, + 0x2, 0x33, 0x33, 0x38, 0xd3, 0x33, 0x33, 0x20, + 0xa, 0xdc, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x90, + 0xa, 0x60, 0x0, 0x0, 0x0, 0x40, 0x7, 0x90, + 0x9, 0x60, 0x0, 0x0, 0x2, 0xe0, 0x7, 0x80, + 0x1, 0x11, 0x11, 0x11, 0x13, 0xf1, 0x11, 0x10, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0xc, 0x60, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0x1, 0xe5, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x20, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x5, 0x10, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0x14, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xfe, 0x80, 0x0, 0x0, + + /* U+5B89 "安" */ + 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd5, 0x0, 0x0, 0x0, 0x5c, 0xcc, + 0xcc, 0xee, 0xcc, 0xcc, 0xc5, 0x7b, 0x33, 0x34, + 0x33, 0x33, 0x33, 0xb7, 0x79, 0x0, 0x7, 0xb0, + 0x0, 0x0, 0xa7, 0x34, 0x0, 0xd, 0x50, 0x0, + 0x0, 0x43, 0x11, 0x11, 0x5e, 0x11, 0x11, 0x11, + 0x11, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x8, 0xc0, 0x0, 0xb, 0x80, 0x0, 0x0, + 0x3f, 0x20, 0x0, 0x3f, 0x10, 0x0, 0x0, 0x7f, + 0xb6, 0x1, 0xd6, 0x0, 0x0, 0x0, 0x0, 0x5b, + 0xfd, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xea, + 0xfc, 0x50, 0x0, 0x0, 0x38, 0xeb, 0x20, 0x7, + 0xed, 0x50, 0x4f, 0xd8, 0x30, 0x0, 0x0, 0x8, + 0xf3, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5B8C "完" */ + 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x80, 0x0, 0x0, 0x0, + 0x8, 0xcc, 0xcc, 0xcd, 0xfc, 0xcc, 0xcc, 0x70, + 0xa, 0x94, 0x44, 0x44, 0x44, 0x44, 0x49, 0x90, + 0xa, 0x60, 0x0, 0x0, 0x0, 0x0, 0x7, 0x90, + 0x7, 0x45, 0xee, 0xee, 0xee, 0xee, 0x55, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x0, 0xc, 0x50, 0xb, 0x60, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x20, 0xb, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x0, 0xb, 0x50, 0x0, 0x10, + 0x0, 0x0, 0xb8, 0x0, 0xb, 0x50, 0x0, 0xb3, + 0x0, 0x2c, 0xc1, 0x0, 0xa, 0x70, 0x0, 0xd2, + 0x1c, 0xe8, 0x0, 0x0, 0x6, 0xff, 0xff, 0xb0, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5B98 "官" */ + 0x0, 0x0, 0x0, 0x71, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb7, 0x0, 0x0, 0x0, 0xef, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0xe3, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x5d, 0xc2, 0x22, 0x22, 0x22, + 0x22, 0x20, 0x4b, 0x0, 0xed, 0xcc, 0xcc, 0xcc, + 0xf4, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0xc4, + 0x0, 0x0, 0xe3, 0x0, 0x0, 0x0, 0xc4, 0x0, + 0x0, 0xee, 0xdd, 0xdd, 0xdd, 0xd4, 0x0, 0x0, + 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xef, + 0xee, 0xee, 0xee, 0xee, 0x20, 0x0, 0xe3, 0x0, + 0x0, 0x0, 0x3f, 0x20, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0x3f, 0x20, 0x0, 0xe6, 0x44, 0x44, 0x44, + 0x6f, 0x20, 0x0, 0xec, 0xbb, 0xbb, 0xbb, 0xce, + 0x20, + + /* U+5B99 "宙" */ + 0x0, 0x0, 0x3, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xf3, 0x0, 0x0, 0x0, 0xac, 0xcc, + 0xcc, 0xfe, 0xcc, 0xcc, 0xc4, 0xd6, 0x33, 0x33, + 0x54, 0x33, 0x33, 0xc5, 0xd3, 0x0, 0x0, 0xe2, + 0x0, 0x0, 0xb5, 0x61, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x52, 0x1, 0x22, 0x22, 0xe5, 0x22, 0x22, + 0x0, 0x8, 0xec, 0xcc, 0xfd, 0xcc, 0xcf, 0x20, + 0x8, 0x70, 0x0, 0xe2, 0x0, 0xe, 0x20, 0x8, + 0x70, 0x0, 0xe2, 0x0, 0xe, 0x20, 0x8, 0xfe, + 0xee, 0xfe, 0xee, 0xef, 0x20, 0x8, 0x70, 0x0, + 0xe2, 0x0, 0xe, 0x20, 0x8, 0x70, 0x0, 0xe2, + 0x0, 0xe, 0x20, 0x8, 0xec, 0xcc, 0xfd, 0xcc, + 0xcf, 0x20, 0x8, 0x93, 0x33, 0x33, 0x33, 0x3f, + 0x20, + + /* U+5B9A "定" */ + 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe3, 0x0, 0x0, 0x0, 0xb, + 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xcc, 0x20, 0xd6, + 0x33, 0x33, 0x33, 0x33, 0x33, 0xe3, 0xd, 0x30, + 0x0, 0x0, 0x0, 0x0, 0xd, 0x30, 0x81, 0x34, + 0x44, 0x44, 0x44, 0x42, 0x82, 0x0, 0xb, 0xcc, + 0xcf, 0xdc, 0xcc, 0x60, 0x0, 0x0, 0x0, 0x0, + 0xd4, 0x0, 0x0, 0x0, 0x0, 0xb, 0x50, 0xd, + 0x40, 0x0, 0x0, 0x0, 0x0, 0xe3, 0x0, 0xde, + 0xee, 0xee, 0x50, 0x0, 0x2f, 0x30, 0xd, 0x51, + 0x11, 0x10, 0x0, 0x7, 0xcc, 0x0, 0xd4, 0x0, + 0x0, 0x0, 0x0, 0xe2, 0x9a, 0x1d, 0x40, 0x0, + 0x0, 0x0, 0x9a, 0x0, 0xae, 0xf7, 0x21, 0x0, + 0x1, 0x5d, 0x10, 0x0, 0x49, 0xde, 0xff, 0xff, + 0xa0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5B9E "实" */ + 0x0, 0x0, 0x0, 0x81, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9a, 0x0, 0x0, 0x0, 0x6b, 0xbb, + 0xbb, 0xdf, 0xcb, 0xbb, 0xb6, 0x8a, 0x33, 0x33, + 0x33, 0x33, 0x33, 0xa8, 0x88, 0x6, 0x10, 0x9, + 0x20, 0x0, 0x88, 0x33, 0x7, 0xe5, 0xf, 0x20, + 0x0, 0x33, 0x1, 0x0, 0x36, 0xf, 0x10, 0x0, + 0x0, 0x6, 0xe3, 0x0, 0x1f, 0x0, 0x0, 0x0, + 0x0, 0x4e, 0x30, 0x4d, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x0, 0x7a, 0x0, 0x0, 0x0, 0xce, 0xee, + 0xee, 0xfe, 0xee, 0xee, 0xed, 0x0, 0x0, 0x6, + 0xd1, 0x60, 0x0, 0x0, 0x0, 0x0, 0x6e, 0x31, + 0x9e, 0x81, 0x0, 0x0, 0x5c, 0xd3, 0x0, 0x1, + 0x8e, 0x80, 0x6f, 0xc6, 0x0, 0x0, 0x0, 0x1, + 0xb9, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5B9F "実" */ + 0x0, 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x80, 0x0, 0x0, 0x0, + 0xb, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xa0, + 0xc, 0x50, 0x0, 0x4, 0x30, 0x0, 0x6, 0xb0, + 0xc, 0x40, 0x0, 0x9, 0x70, 0x0, 0x6, 0xb0, + 0x1, 0x6e, 0xee, 0xef, 0xfe, 0xee, 0xe7, 0x10, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x33, 0x3a, 0x93, 0x33, 0x30, 0x0, + 0x0, 0x1b, 0xbb, 0xbe, 0xdb, 0xbb, 0xb3, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x40, 0x0, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0xc7, 0xa8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2c, 0x90, 0x1d, 0x80, 0x0, 0x0, + 0x0, 0x29, 0xe6, 0x0, 0x1, 0xbd, 0x60, 0x0, + 0xc, 0xd7, 0x10, 0x0, 0x0, 0x4, 0xbf, 0xc0, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + + /* U+5BA2 "客" */ + 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x80, 0x0, 0x0, 0x0, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, + 0xe, 0x20, 0x2, 0x71, 0x0, 0x0, 0x5, 0xc0, + 0xe, 0x10, 0x1d, 0xb2, 0x22, 0x22, 0x4, 0xc0, + 0x0, 0x2, 0xde, 0xaa, 0xaa, 0xeb, 0x0, 0x0, + 0x0, 0x7e, 0x8d, 0x60, 0x7, 0xc0, 0x0, 0x0, + 0x5, 0x91, 0x0, 0xbb, 0xca, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5, 0xbb, 0xbb, 0x50, 0x0, 0x0, + 0x3, 0x7a, 0xe9, 0x20, 0x2, 0x9e, 0xc9, 0x61, + 0x4d, 0x98, 0xed, 0xdd, 0xdd, 0xde, 0x67, 0x90, + 0x0, 0x3, 0xd0, 0x0, 0x0, 0xe, 0x20, 0x0, + 0x0, 0x3, 0xd0, 0x0, 0x0, 0xe, 0x20, 0x0, + 0x0, 0x3, 0xd0, 0x0, 0x0, 0xe, 0x20, 0x0, + 0x0, 0x3, 0xfe, 0xee, 0xee, 0xef, 0x20, 0x0, + + /* U+5BA4 "室" */ + 0x0, 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x80, 0x0, 0x0, 0x0, + 0xd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xd, 0x30, 0x0, 0x0, 0x0, 0x0, 0x4, 0xc0, + 0xb, 0x4a, 0xaa, 0xaa, 0xaa, 0xaa, 0xa7, 0xa0, + 0x0, 0x3, 0x37, 0xf5, 0x34, 0x73, 0x31, 0x0, + 0x0, 0x0, 0x2e, 0x30, 0x0, 0xd7, 0x0, 0x0, + 0x0, 0x4, 0xe4, 0x23, 0x46, 0x8f, 0x70, 0x0, + 0x0, 0x2f, 0xfe, 0xcb, 0xa8, 0x76, 0xe5, 0x0, + 0x0, 0x1, 0x0, 0x9, 0x70, 0x0, 0x21, 0x0, + 0x0, 0x12, 0x22, 0x2a, 0x92, 0x22, 0x21, 0x0, + 0x0, 0x7b, 0xbb, 0xbe, 0xdb, 0xbb, 0xb7, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + + /* U+5BB3 "害" */ + 0x0, 0x0, 0x0, 0x71, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa8, 0x0, 0x0, 0x0, 0x9e, 0xee, + 0xee, 0xff, 0xee, 0xee, 0xea, 0x97, 0x0, 0x0, + 0x33, 0x0, 0x0, 0x7a, 0x85, 0x22, 0x22, 0xaa, + 0x22, 0x22, 0x58, 0x0, 0x9a, 0xaa, 0xdd, 0xaa, + 0xaa, 0x0, 0x1, 0x22, 0x22, 0x9a, 0x22, 0x22, + 0x10, 0x4, 0xbb, 0xbb, 0xdd, 0xbb, 0xbb, 0x60, + 0x11, 0x11, 0x11, 0x99, 0x11, 0x11, 0x11, 0xbc, + 0xcc, 0xcc, 0xee, 0xcc, 0xcc, 0xcb, 0x0, 0x11, + 0x11, 0x99, 0x11, 0x11, 0x0, 0x0, 0xed, 0xcc, + 0xcc, 0xcc, 0xcf, 0x10, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0xe2, 0x0, 0x0, 0x0, + 0xf, 0x10, 0x0, 0xee, 0xdd, 0xdd, 0xdd, 0xdf, + 0x10, + + /* U+5BB5 "宵" */ + 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd5, 0x0, 0x0, 0x0, 0xdf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0xe3, 0x22, 0x0, + 0xc2, 0x0, 0x41, 0x88, 0xe2, 0x4c, 0x0, 0xe2, + 0x4, 0xd0, 0x88, 0x0, 0xb, 0x40, 0xe2, 0x1d, + 0x30, 0x0, 0x1, 0xab, 0xba, 0xfb, 0xbd, 0xaa, + 0x0, 0x2, 0xe3, 0x33, 0x33, 0x33, 0x6e, 0x0, + 0x2, 0xe0, 0x0, 0x0, 0x0, 0x2e, 0x0, 0x2, + 0xfe, 0xee, 0xee, 0xee, 0xee, 0x0, 0x2, 0xe0, + 0x0, 0x0, 0x0, 0x2e, 0x0, 0x2, 0xfe, 0xee, + 0xee, 0xee, 0xee, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x3e, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x9f, 0xe8, + 0x0, + + /* U+5BB6 "家" */ + 0x0, 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xf3, 0x0, 0x0, 0x0, 0xc, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0xd4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd4, 0xd, 0x31, + 0x11, 0x11, 0x11, 0x11, 0xc, 0x40, 0x41, 0xcd, + 0xde, 0xfd, 0xdd, 0xd5, 0x31, 0x0, 0x0, 0x7, + 0xe7, 0x0, 0x0, 0x40, 0x0, 0x4, 0x9d, 0x86, + 0xc0, 0x2, 0xda, 0x0, 0x9, 0xb6, 0x0, 0x7e, + 0x76, 0xe6, 0x0, 0x0, 0x0, 0x17, 0xd7, 0x2f, + 0xbe, 0x10, 0x0, 0x6, 0xcc, 0x60, 0xa, 0xf3, + 0x78, 0x0, 0x0, 0x32, 0x0, 0x6d, 0x7c, 0x50, + 0xd4, 0x0, 0x0, 0x17, 0xd9, 0x10, 0xc4, 0x3, + 0xe5, 0x0, 0xcd, 0x61, 0x0, 0x5f, 0x10, 0x3, + 0xe9, 0x1, 0x0, 0xb, 0xfe, 0x50, 0x0, 0x0, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5BB9 "容" */ + 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe4, 0x0, 0x0, 0x0, 0xd, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, 0xd3, + 0x0, 0x10, 0x0, 0x10, 0x0, 0xe3, 0xb, 0x20, + 0xa9, 0x0, 0x8, 0xa1, 0xc, 0x30, 0x0, 0xab, + 0x0, 0x73, 0x7, 0xe4, 0x0, 0x3, 0xda, 0x0, + 0x5f, 0x90, 0x4, 0xe6, 0x0, 0x56, 0x0, 0x5e, + 0x2b, 0x90, 0x2, 0x70, 0x0, 0x0, 0x7e, 0x20, + 0xa, 0xc2, 0x0, 0x0, 0x2, 0xcb, 0x10, 0x0, + 0x6, 0xe9, 0x10, 0x2a, 0xef, 0xff, 0xff, 0xff, + 0xff, 0xcf, 0x72, 0x91, 0xe2, 0x0, 0x0, 0x0, + 0xe2, 0x33, 0x0, 0xe, 0x20, 0x0, 0x0, 0xe, + 0x20, 0x0, 0x0, 0xe3, 0x0, 0x0, 0x0, 0xe2, + 0x0, 0x0, 0xe, 0xee, 0xee, 0xee, 0xee, 0x20, + 0x0, + + /* U+5BBF "宿" */ + 0x0, 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xf2, 0x0, 0x0, 0x0, 0xd, + 0xfe, 0xee, 0xef, 0xfe, 0xee, 0xef, 0x40, 0xd3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc4, 0x8, 0x26, + 0xa1, 0x11, 0x11, 0x11, 0x16, 0x20, 0x0, 0xe3, + 0xde, 0xee, 0xfe, 0xee, 0xe7, 0x0, 0x8c, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x6f, 0xa0, 0x3d, + 0xde, 0xfd, 0xdd, 0x90, 0x5f, 0x8a, 0x3, 0xd1, + 0x11, 0x11, 0x7a, 0x3, 0x44, 0xa0, 0x3c, 0x0, + 0x0, 0x6, 0xa0, 0x0, 0x4a, 0x3, 0xfe, 0xee, + 0xee, 0xfa, 0x0, 0x4, 0xa0, 0x3c, 0x0, 0x0, + 0x6, 0xa0, 0x0, 0x4a, 0x3, 0xc0, 0x0, 0x0, + 0x6a, 0x0, 0x4, 0xa0, 0x3f, 0xdd, 0xdd, 0xde, + 0xa0, 0x0, 0x4a, 0x3, 0xd1, 0x11, 0x11, 0x79, + 0x0, + + /* U+5BC4 "寄" */ + 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0xc, 0xfe, 0xee, 0xee, 0xee, 0xee, 0xef, 0xd0, + 0xc, 0x30, 0x0, 0x6, 0x70, 0x0, 0x3, 0xd0, + 0x9, 0x3e, 0xee, 0xef, 0xfe, 0xee, 0xe4, 0x90, + 0x0, 0x0, 0x0, 0x5f, 0x82, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x39, 0xd4, 0x7c, 0xd7, 0x0, 0x0, + 0x0, 0x6e, 0xc7, 0x0, 0x0, 0x29, 0xd0, 0x0, + 0x1e, 0xff, 0xee, 0xee, 0xee, 0xee, 0xfe, 0xe1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xc0, 0x0, + 0x0, 0x1e, 0xdd, 0xdd, 0xe4, 0x4, 0xc0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0xa5, 0x4, 0xc0, 0x0, + 0x0, 0x1e, 0x11, 0x11, 0xb5, 0x4, 0xc0, 0x0, + 0x0, 0x1f, 0xcc, 0xcc, 0xc4, 0x5, 0xc0, 0x0, + 0x0, 0x5, 0x0, 0x0, 0x9, 0xfe, 0x70, 0x0, + + /* U+5BC6 "密" */ + 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0xe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0xe1, + 0x0, 0x18, 0x10, 0x1, 0x0, 0xa6, 0xe, 0x10, + 0x4, 0x7e, 0x32, 0xd3, 0xa, 0x60, 0x14, 0x61, + 0xd0, 0x36, 0xd4, 0x45, 0x10, 0x0, 0xd4, 0x1d, + 0x4, 0xd4, 0x2, 0xe5, 0x0, 0xb9, 0x1, 0xea, + 0xa1, 0x1, 0xc2, 0xe3, 0x29, 0x4, 0xaf, 0x83, + 0x33, 0x8a, 0x5, 0x92, 0xac, 0x96, 0x6a, 0xdb, + 0xa9, 0x20, 0x0, 0x0, 0x33, 0x0, 0xe, 0x20, + 0x0, 0x60, 0x0, 0x8, 0x90, 0x0, 0xe2, 0x0, + 0xe, 0x10, 0x0, 0x89, 0x0, 0xe, 0x20, 0x0, + 0xe1, 0x0, 0x8, 0xeb, 0xbb, 0xfc, 0xbb, 0xbf, + 0x10, 0x0, 0x24, 0x44, 0x44, 0x44, 0x44, 0xf1, + 0x0, + + /* U+5BCC "富" */ + 0x0, 0x0, 0x1, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xf3, 0x0, 0x0, 0x0, 0xef, 0xee, + 0xee, 0xee, 0xee, 0xee, 0xf4, 0xe2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc4, 0xd2, 0xbc, 0xcc, 0xcc, + 0xcc, 0xc4, 0xc4, 0x0, 0x12, 0x22, 0x22, 0x22, + 0x20, 0x0, 0x0, 0xcb, 0xaa, 0xaa, 0xaa, 0xf3, + 0x0, 0x0, 0xc6, 0x33, 0x33, 0x33, 0xe3, 0x0, + 0x0, 0x57, 0x77, 0x77, 0x77, 0x71, 0x0, 0x8, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x20, 0xc, 0x42, + 0x22, 0xe4, 0x22, 0x2a, 0x40, 0xc, 0x31, 0x11, + 0xe4, 0x11, 0x1a, 0x40, 0xc, 0xba, 0xaa, 0xfb, + 0xaa, 0xae, 0x40, 0xc, 0x20, 0x0, 0xd2, 0x0, + 0x9, 0x40, 0xc, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, + 0x30, + + /* U+5BD2 "寒" */ + 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x90, 0x0, 0x0, 0x0, + 0xc, 0xfe, 0xef, 0xee, 0xee, 0xfe, 0xef, 0xc0, + 0xc, 0x40, 0xd, 0x30, 0x2, 0xd0, 0x4, 0xc0, + 0xa, 0xad, 0xdf, 0xdd, 0xdd, 0xfd, 0xd9, 0xa0, + 0x0, 0x0, 0xd, 0x30, 0x2, 0xd0, 0x0, 0x0, + 0x0, 0x2c, 0xcf, 0xdc, 0xcd, 0xfc, 0xc1, 0x0, + 0x0, 0x0, 0xd, 0x30, 0x2, 0xd0, 0x0, 0x0, + 0xb, 0xbb, 0xbf, 0xcb, 0xbc, 0xfb, 0xbb, 0xb1, + 0x2, 0x22, 0x9c, 0x22, 0x22, 0xc9, 0x22, 0x20, + 0x0, 0x8, 0xd1, 0x8d, 0x82, 0xb, 0xa1, 0x0, + 0x5, 0xda, 0x10, 0x0, 0x6c, 0x20, 0x8e, 0x81, + 0x1b, 0x40, 0x68, 0x41, 0x0, 0x0, 0x2, 0x80, + 0x0, 0x0, 0x26, 0xad, 0xd9, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x16, 0xbc, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5BDD "寝" */ + 0x0, 0x0, 0x0, 0x7, 0x60, 0x0, 0x0, 0x0, + 0x6, 0x77, 0x77, 0x7b, 0xe7, 0x77, 0x77, 0x70, + 0xe, 0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0xf0, + 0xe, 0x1a, 0x20, 0x68, 0x88, 0x88, 0x87, 0xf0, + 0x1, 0xc, 0x30, 0x23, 0x33, 0x33, 0x5c, 0x10, + 0xc, 0x1c, 0x30, 0x3b, 0xbb, 0xbb, 0xcc, 0x0, + 0x8, 0x6c, 0x30, 0x0, 0x0, 0x0, 0x3c, 0x0, + 0x2, 0xbc, 0x30, 0xac, 0xcc, 0xcc, 0xc9, 0x0, + 0x0, 0x5c, 0x36, 0x66, 0x66, 0x66, 0x66, 0x60, + 0x0, 0xd, 0x3e, 0x55, 0x55, 0x55, 0x55, 0xe0, + 0x2, 0xbf, 0x3c, 0x3c, 0xcc, 0xcc, 0xc7, 0xc0, + 0x5e, 0x6d, 0x30, 0x5, 0xb0, 0x3, 0xd1, 0x0, + 0x1, 0xc, 0x30, 0x0, 0x5d, 0x8c, 0x20, 0x0, + 0x0, 0xc, 0x30, 0x15, 0x9d, 0xbd, 0x73, 0x0, + 0x0, 0xc, 0x3b, 0xc9, 0x40, 0x1, 0x6a, 0xc1, + + /* U+5BDF "察" */ + 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xa0, 0x0, 0x0, 0x0, + 0xe, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe0, + 0xe, 0x10, 0x92, 0x0, 0x80, 0x0, 0x1, 0xe0, + 0x5, 0x7, 0xfc, 0xc9, 0x9c, 0xcc, 0xcc, 0x60, + 0x0, 0x8b, 0x20, 0x97, 0x2e, 0x21, 0x99, 0x0, + 0x1c, 0x91, 0xba, 0xd0, 0x7, 0xb5, 0xd1, 0x0, + 0x2, 0x78, 0x4e, 0x20, 0x0, 0xaf, 0x30, 0x0, + 0x0, 0x1d, 0xca, 0xee, 0xee, 0xd7, 0xe7, 0x10, + 0x1a, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x18, 0xd2, + 0x4, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, + 0x0, 0x0, 0x43, 0x4, 0xc0, 0x24, 0x0, 0x0, + 0x0, 0x7, 0xd1, 0x4, 0xc0, 0x2c, 0xb2, 0x0, + 0x4, 0xdb, 0x10, 0x4, 0xc0, 0x0, 0x6e, 0x60, + 0x8, 0x50, 0x4, 0xee, 0x80, 0x0, 0x2, 0x50, + + /* U+5BE6 "實" */ + 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc, 0x50, 0x0, 0x0, 0x0, + 0xe, 0xed, 0xdd, 0xde, 0xed, 0xdd, 0xde, 0x70, + 0xe, 0x10, 0x11, 0x11, 0x11, 0x11, 0x8, 0x70, + 0xa, 0x1a, 0xb9, 0x9c, 0xc9, 0x9b, 0x86, 0x50, + 0x4b, 0xbe, 0xa8, 0x8c, 0xb8, 0x8b, 0xdb, 0xb0, + 0x0, 0xf, 0x98, 0x8d, 0xb8, 0x8b, 0x50, 0x0, + 0x0, 0x4, 0x44, 0x44, 0x44, 0x44, 0x20, 0x0, + 0x0, 0x3e, 0x88, 0x88, 0x88, 0x8a, 0xe0, 0x0, + 0x0, 0x3f, 0xaa, 0xaa, 0xaa, 0xab, 0xe0, 0x0, + 0x0, 0x3d, 0x22, 0x22, 0x22, 0x25, 0xe0, 0x0, + 0x0, 0x3e, 0x77, 0x77, 0x77, 0x79, 0xe0, 0x0, + 0x0, 0x3f, 0xaa, 0xaa, 0xaa, 0xab, 0xe0, 0x0, + 0x0, 0x1, 0x6c, 0x50, 0x8, 0xb6, 0x20, 0x0, + 0x8, 0xdc, 0x82, 0x0, 0x0, 0x26, 0xcc, 0x20, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + + /* U+5BEB "寫" */ + 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe6, 0x0, 0x0, 0x0, 0xe, + 0xfe, 0xee, 0xee, 0xee, 0xee, 0xef, 0xd0, 0xe1, + 0x0, 0x26, 0x10, 0x0, 0x0, 0x2d, 0xa, 0x9, + 0xba, 0x61, 0x6c, 0xcc, 0xb2, 0x90, 0x0, 0xf0, + 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0xf, 0xcc, + 0xc2, 0x3c, 0xcd, 0xe0, 0x0, 0x0, 0xf0, 0x0, + 0x0, 0x0, 0x1e, 0x0, 0x0, 0xf, 0xdd, 0xdd, + 0xdd, 0xdd, 0xe0, 0x0, 0x0, 0x9, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1b, 0xfe, 0xee, 0xee, + 0xee, 0xee, 0x41, 0x8e, 0x76, 0x4, 0x5, 0x7, + 0x10, 0xc4, 0x18, 0x14, 0xb0, 0xd0, 0x86, 0x3c, + 0xe, 0x20, 0x0, 0xd3, 0xc, 0x21, 0xb0, 0x31, + 0xf0, 0x0, 0x16, 0x0, 0x30, 0x0, 0x7e, 0xe8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5BFA "寺" */ + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x34, 0x44, 0x4b, 0xa4, 0x44, 0x44, 0x0, + 0x0, 0x9b, 0xbb, 0xbe, 0xdb, 0xbb, 0xbb, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x80, 0x0, 0x0, 0x0, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa6, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x11, 0x11, 0xb7, 0x11, 0x10, + 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0x3, 0x40, 0x0, 0x0, 0xa6, 0x0, 0x0, + 0x0, 0x2, 0xe6, 0x0, 0x0, 0xa6, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0x40, 0x0, 0xa6, 0x0, 0x0, + 0x0, 0x0, 0x4, 0x20, 0x0, 0xb6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5, 0xff, 0xd2, 0x0, 0x0, + + /* U+5BFE "対" */ + 0x0, 0x6, 0x60, 0x0, 0x0, 0x0, 0x3d, 0x0, + 0x0, 0x1, 0xe3, 0x0, 0x0, 0x0, 0x3d, 0x0, + 0x6, 0x66, 0xa9, 0x65, 0x0, 0x0, 0x3d, 0x0, + 0x8, 0x88, 0x88, 0xc8, 0x44, 0x44, 0x7e, 0x43, + 0x0, 0x0, 0x2, 0xf0, 0xbb, 0xbb, 0xcf, 0xb8, + 0x1, 0x90, 0x6, 0xb0, 0x0, 0x0, 0x3d, 0x0, + 0x0, 0xb9, 0xa, 0x70, 0x45, 0x0, 0x3d, 0x0, + 0x0, 0xc, 0x8e, 0x20, 0x2e, 0x10, 0x3d, 0x0, + 0x0, 0x1, 0xdc, 0x0, 0x8, 0x90, 0x3d, 0x0, + 0x0, 0x0, 0xdf, 0x20, 0x1, 0xe0, 0x3d, 0x0, + 0x0, 0x9, 0xb7, 0xd0, 0x0, 0x0, 0x3d, 0x0, + 0x0, 0x6e, 0x10, 0xc5, 0x0, 0x0, 0x3d, 0x0, + 0x9, 0xe3, 0x0, 0x10, 0x0, 0x11, 0x6c, 0x0, + 0x9, 0x10, 0x0, 0x0, 0x0, 0xbf, 0xe7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5C04 "射" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x4b, 0x0, + 0x0, 0xde, 0xed, 0xd1, 0x0, 0x0, 0x4b, 0x0, + 0x0, 0xf0, 0x0, 0xe1, 0x0, 0x0, 0x4b, 0x0, + 0x0, 0xf1, 0x11, 0xe3, 0x88, 0x88, 0xae, 0x84, + 0x0, 0xfa, 0xaa, 0xf3, 0x99, 0x99, 0xbe, 0x94, + 0x0, 0xf0, 0x0, 0xe1, 0x0, 0x0, 0x4b, 0x0, + 0x0, 0xfd, 0xdd, 0xf1, 0x3b, 0x0, 0x4b, 0x0, + 0x0, 0xf0, 0x0, 0xe1, 0xb, 0x70, 0x4b, 0x0, + 0x5f, 0xff, 0xff, 0xf1, 0x2, 0xf1, 0x4b, 0x0, + 0x0, 0x0, 0x99, 0xe1, 0x0, 0x83, 0x4b, 0x0, + 0x0, 0x9, 0xa0, 0xe1, 0x0, 0x0, 0x4b, 0x0, + 0x3, 0xc9, 0x0, 0xe1, 0x0, 0x0, 0x4b, 0x0, + 0x5e, 0x40, 0x0, 0xe1, 0x0, 0x0, 0x5b, 0x0, + 0x1, 0x0, 0xbe, 0xc0, 0x0, 0xcf, 0xe6, 0x0, + + /* U+5C07 "將" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, + 0xd, 0x10, 0xe1, 0x0, 0x8, 0xb0, 0x0, 0x0, + 0xd, 0x10, 0xe1, 0x0, 0x9d, 0xcc, 0xcf, 0x40, + 0xd, 0x10, 0xe1, 0x5c, 0x66, 0x30, 0x6c, 0x0, + 0xd, 0x10, 0xe5, 0x94, 0x21, 0xaa, 0xf3, 0x0, + 0xd, 0xfe, 0xf1, 0x2, 0xc5, 0x8e, 0x30, 0x0, + 0x0, 0x0, 0xe1, 0x0, 0x6f, 0xc3, 0xa0, 0x0, + 0x0, 0x0, 0xe2, 0x8d, 0xe6, 0x1, 0xf0, 0x0, + 0x23, 0x33, 0xf1, 0x94, 0x0, 0x1, 0xf0, 0x0, + 0x7e, 0xdb, 0xf7, 0xee, 0xee, 0xef, 0xfe, 0xe1, + 0xb, 0x40, 0xe1, 0x7, 0x0, 0x1, 0xf0, 0x0, + 0xc, 0x30, 0xe1, 0x7, 0xc0, 0x1, 0xf0, 0x0, + 0xe, 0x10, 0xe1, 0x0, 0x99, 0x1, 0xf0, 0x0, + 0x3d, 0x0, 0xe1, 0x0, 0x1, 0x2, 0xf0, 0x0, + 0x86, 0x0, 0xe1, 0x0, 0x6, 0xff, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5C08 "專" */ + 0x0, 0x0, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x8, 0xdd, 0xdd, 0xde, 0xfd, 0xdd, 0xdd, 0xa0, + 0x0, 0x14, 0x44, 0x49, 0xc4, 0x44, 0x43, 0x0, + 0x0, 0x5c, 0x55, 0x59, 0xc5, 0x55, 0x8c, 0x0, + 0x0, 0x5e, 0xbb, 0xbd, 0xeb, 0xbb, 0xcc, 0x0, + 0x0, 0x5a, 0x0, 0x6, 0xa0, 0x0, 0x3c, 0x0, + 0x0, 0x5e, 0xcc, 0xce, 0xfc, 0xdd, 0xdc, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xb0, 0x3d, 0xa3, 0x0, + 0x5, 0xdd, 0xdd, 0xcc, 0xcb, 0xdd, 0xac, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x79, 0x1, 0x20, + 0x1d, 0xdd, 0xdd, 0xdd, 0xdd, 0xee, 0xdd, 0xd5, + 0x0, 0x2, 0xd6, 0x0, 0x0, 0x78, 0x0, 0x0, + 0x0, 0x0, 0x1a, 0x90, 0x0, 0x78, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xce, 0xe5, 0x0, 0x0, + + /* U+5C0D "對" */ + 0x5, 0xa, 0x37, 0x61, 0x40, 0x0, 0x1e, 0x0, + 0x5, 0xaa, 0x37, 0x7c, 0x50, 0x0, 0x1e, 0x0, + 0x0, 0x8c, 0x37, 0xb6, 0x0, 0x0, 0x1e, 0x0, + 0x2d, 0xde, 0xee, 0xed, 0xc0, 0x0, 0x2e, 0x0, + 0x0, 0x66, 0x0, 0x75, 0x2f, 0xff, 0xff, 0xf8, + 0x0, 0xd, 0x11, 0xe1, 0x0, 0x0, 0x1e, 0x0, + 0x7, 0xbc, 0xbd, 0xeb, 0x45, 0x70, 0x1e, 0x0, + 0x1, 0x22, 0xb7, 0x22, 0x12, 0xe0, 0x1e, 0x0, + 0x0, 0x0, 0x96, 0x0, 0x0, 0xa6, 0x1e, 0x0, + 0x2, 0xee, 0xff, 0xee, 0x10, 0x5b, 0x1e, 0x0, + 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, 0x1e, 0x0, + 0x0, 0x0, 0xa8, 0x57, 0x80, 0x0, 0x1e, 0x0, + 0x1c, 0xef, 0xda, 0x86, 0x30, 0x0, 0x3e, 0x0, + 0x3, 0x10, 0x0, 0x0, 0x0, 0x8f, 0xf8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5C0E "導" */ + 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x40, 0x0, + 0x6, 0xb1, 0x0, 0xa, 0x60, 0x8, 0x90, 0x0, + 0x0, 0x8c, 0x1c, 0xcd, 0xde, 0xdd, 0xdc, 0xb0, + 0x0, 0x5, 0x0, 0x33, 0x4e, 0x43, 0x32, 0x0, + 0x17, 0x77, 0x0, 0xf6, 0x55, 0x55, 0x9a, 0x0, + 0x16, 0x6f, 0x0, 0xf9, 0x99, 0x99, 0xca, 0x0, + 0x0, 0xf, 0x0, 0xf7, 0x77, 0x77, 0xaa, 0x0, + 0x0, 0xf, 0x0, 0xf3, 0x22, 0x22, 0x8a, 0x0, + 0x1, 0xbc, 0xb2, 0x9a, 0xaa, 0xaa, 0xa6, 0x0, + 0xd, 0x50, 0x2a, 0xcb, 0xaa, 0xaa, 0xbb, 0xc2, + 0x1, 0x0, 0x0, 0x1, 0x22, 0x5d, 0x21, 0x0, + 0x1d, 0xdd, 0xdd, 0xdd, 0xdd, 0xef, 0xdd, 0xd0, + 0x0, 0x2, 0xc2, 0x0, 0x0, 0x3c, 0x0, 0x0, + 0x0, 0x0, 0x4e, 0x40, 0x0, 0x4c, 0x0, 0x0, + 0x0, 0x0, 0x2, 0x0, 0x9e, 0xe8, 0x0, 0x0, + + /* U+5C0F "小" */ + 0x0, 0x0, 0x0, 0x4, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x20, 0x4, 0xd0, 0x1, 0x40, 0x0, + 0x0, 0xb, 0x80, 0x4, 0xd0, 0x2, 0xf2, 0x0, + 0x0, 0xf, 0x30, 0x4, 0xd0, 0x0, 0x9a, 0x0, + 0x0, 0x5e, 0x0, 0x4, 0xd0, 0x0, 0x1f, 0x30, + 0x0, 0xb8, 0x0, 0x4, 0xd0, 0x0, 0x8, 0xb0, + 0x3, 0xf1, 0x0, 0x4, 0xd0, 0x0, 0x2, 0xf2, + 0xd, 0x80, 0x0, 0x4, 0xd0, 0x0, 0x0, 0xb8, + 0x6, 0x0, 0x0, 0x4, 0xd0, 0x0, 0x0, 0x66, + 0x0, 0x0, 0x0, 0x4, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0x16, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2f, 0xfe, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5C11 "少" */ + 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x10, 0xe, 0x10, 0x3, 0x10, 0x0, + 0x0, 0xe, 0x30, 0xe, 0x10, 0x8, 0xa0, 0x0, + 0x0, 0x6b, 0x0, 0xe, 0x10, 0x0, 0xd5, 0x0, + 0x0, 0xd3, 0x0, 0xe, 0x10, 0x0, 0x3e, 0x0, + 0x9, 0xa0, 0x0, 0xe, 0x10, 0x0, 0xa, 0x80, + 0x1d, 0x10, 0x0, 0xe, 0x10, 0x0, 0x2, 0xa0, + 0x0, 0x0, 0x0, 0xe, 0x10, 0x2, 0x80, 0x0, + 0x0, 0x0, 0x0, 0xc, 0x10, 0x2e, 0x60, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4, 0xe7, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xae, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x27, 0xce, 0x80, 0x0, 0x0, 0x0, + 0x39, 0xbe, 0xfa, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x28, 0x52, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5C1A "尚" */ + 0x5, 0x10, 0x0, 0xc4, 0x0, 0x2, 0x70, 0x5, + 0xd1, 0x0, 0xc4, 0x0, 0xc, 0x60, 0x0, 0x9a, + 0x0, 0xc4, 0x0, 0x9a, 0x0, 0x0, 0x7, 0x0, + 0xc4, 0x0, 0x70, 0x0, 0xe, 0xee, 0xee, 0xff, + 0xee, 0xee, 0xe1, 0xf, 0x11, 0x11, 0x11, 0x11, + 0x11, 0xf1, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf1, 0xf, 0x0, 0xee, 0xee, 0xee, 0x0, 0xf1, + 0xf, 0x0, 0xe0, 0x0, 0xe, 0x0, 0xf1, 0xf, + 0x0, 0xe0, 0x0, 0xe, 0x0, 0xf1, 0xf, 0x0, + 0xe3, 0x33, 0x4e, 0x0, 0xf1, 0xf, 0x0, 0xeb, + 0xbb, 0xbb, 0x0, 0xf1, 0xf, 0x0, 0x80, 0x0, + 0x0, 0x11, 0xf1, 0xf, 0x0, 0x0, 0x0, 0x4, + 0xfe, 0xa0, + + /* U+5C24 "尤" */ + 0x0, 0x0, 0x0, 0x2e, 0x1, 0xa4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3e, 0x0, 0x3b, 0xc3, 0x0, + 0x0, 0x0, 0x0, 0x3d, 0x0, 0x0, 0x48, 0x0, + 0x1d, 0xdd, 0xdd, 0xef, 0xdd, 0xdd, 0xdd, 0xd1, + 0x2, 0x22, 0x22, 0x7c, 0x22, 0x22, 0x22, 0x20, + 0x0, 0x0, 0x0, 0x88, 0x83, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb6, 0xc4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf2, 0xc4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0xc0, 0xc4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x60, 0xc4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9d, 0x0, 0xc4, 0x0, 0x0, 0xc2, + 0x0, 0x6, 0xf2, 0x0, 0xc4, 0x0, 0x0, 0xe2, + 0x1, 0xaf, 0x40, 0x0, 0xc7, 0x0, 0x2, 0xf0, + 0x1f, 0xb2, 0x0, 0x0, 0x6e, 0xff, 0xff, 0x70, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5C31 "就" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xd0, 0x0, 0x0, 0x3c, 0x1, 0x0, + 0x2, 0x23, 0xd6, 0x22, 0x0, 0x3c, 0x3d, 0x0, + 0x1c, 0xcc, 0xcc, 0xcc, 0x20, 0x3c, 0x6, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x12, 0x6c, 0x22, 0x40, + 0x3, 0xfe, 0xee, 0xf7, 0x8d, 0xee, 0xdd, 0xd4, + 0x3, 0xb0, 0x0, 0x87, 0x0, 0x78, 0x0, 0x0, + 0x3, 0xb0, 0x0, 0x87, 0x0, 0x99, 0x80, 0x0, + 0x3, 0xee, 0xfe, 0xe7, 0x0, 0xc7, 0xb0, 0x0, + 0x0, 0x10, 0xc2, 0x20, 0x0, 0xe3, 0xb0, 0x0, + 0x0, 0xd1, 0xc2, 0xd2, 0x4, 0xb3, 0xb0, 0x0, + 0x3, 0xc0, 0xc2, 0x68, 0xb, 0x43, 0xb0, 0x0, + 0xb, 0x50, 0xc2, 0x18, 0x3c, 0x3, 0xb0, 0x37, + 0x9, 0x0, 0xc2, 0x1, 0xd3, 0x3, 0xb0, 0x58, + 0x0, 0x1e, 0xd1, 0xb, 0x50, 0x1, 0xdd, 0xd3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5C3A "尺" */ + 0x0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0x1f, 0x10, 0x0, 0x0, 0x0, 0x3e, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x1f, 0x43, 0x33, 0x33, 0x33, 0x5e, 0x0, + 0x0, 0x2f, 0xcc, 0xcc, 0xee, 0xcc, 0xcb, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0x5c, 0x0, 0x0, 0x0, + 0x0, 0x5d, 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, + 0x0, 0x8a, 0x0, 0x0, 0x9, 0xa0, 0x0, 0x0, + 0x0, 0xd6, 0x0, 0x0, 0x1, 0xe5, 0x0, 0x0, + 0x2, 0xf1, 0x0, 0x0, 0x0, 0x5f, 0x40, 0x0, + 0xa, 0xb0, 0x0, 0x0, 0x0, 0x5, 0xf7, 0x0, + 0x3f, 0x20, 0x0, 0x0, 0x0, 0x0, 0x4c, 0xe3, + 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, + + /* U+5C40 "局" */ + 0x0, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xf2, 0x0, + 0xb, 0x40, 0x0, 0x0, 0x0, 0xe, 0x20, 0x0, + 0xb4, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, 0xb, + 0x73, 0x33, 0x33, 0x33, 0x3f, 0x20, 0x0, 0xcc, + 0xaa, 0xaa, 0xaa, 0xaa, 0xa1, 0x0, 0xc, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdf, 0xee, + 0xee, 0xee, 0xee, 0xef, 0x30, 0xf, 0x10, 0x0, + 0x0, 0x0, 0x0, 0xe2, 0x1, 0xe0, 0x1e, 0xee, + 0xee, 0xd0, 0xf, 0x20, 0x5c, 0x1, 0xe0, 0x0, + 0x1e, 0x0, 0xf1, 0x9, 0x80, 0x1e, 0x0, 0x1, + 0xe0, 0x1f, 0x0, 0xe2, 0x1, 0xfd, 0xdd, 0xde, + 0x3, 0xe0, 0x7b, 0x0, 0x1e, 0x0, 0x0, 0x0, + 0x7b, 0x3, 0x20, 0x0, 0x10, 0x0, 0xc, 0xfe, + 0x40, + + /* U+5C45 "居" */ + 0x0, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x10, + 0xd, 0x30, 0x0, 0x0, 0x0, 0x0, 0xe1, 0x0, + 0xd3, 0x0, 0x0, 0x0, 0x0, 0xe, 0x10, 0xd, + 0xee, 0xee, 0xee, 0xee, 0xee, 0xf1, 0x0, 0xd4, + 0x0, 0x0, 0x5c, 0x0, 0x0, 0x0, 0xd, 0x30, + 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, 0xef, 0xee, + 0xee, 0xff, 0xee, 0xee, 0xc0, 0xf, 0x20, 0x0, + 0x5, 0xc0, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x4c, 0x0, 0x0, 0x0, 0x2d, 0x3, 0xee, 0xef, + 0xfe, 0xee, 0xc0, 0x5, 0xb0, 0x3c, 0x0, 0x0, + 0x0, 0x4d, 0x0, 0x96, 0x3, 0xc0, 0x0, 0x0, + 0x3, 0xd0, 0xe, 0x10, 0x3d, 0x11, 0x11, 0x11, + 0x4d, 0x6, 0x90, 0x3, 0xfd, 0xdd, 0xdd, 0xde, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5C4A "届" */ + 0x0, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0xd, 0x30, 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, + 0xd3, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x0, 0xd, + 0x63, 0x33, 0x33, 0x33, 0x35, 0xe0, 0x0, 0xdd, + 0xcc, 0xcc, 0xcd, 0xcc, 0xcb, 0x0, 0xd, 0x30, + 0x0, 0x2, 0xd0, 0x0, 0x0, 0x0, 0xe3, 0x22, + 0x22, 0x5e, 0x22, 0x22, 0x0, 0xf, 0x2e, 0xcc, + 0xcd, 0xfc, 0xcc, 0xf1, 0x0, 0xf0, 0xe1, 0x0, + 0x2d, 0x0, 0xe, 0x10, 0x2e, 0xe, 0x42, 0x25, + 0xe2, 0x22, 0xf1, 0x5, 0xb0, 0xeb, 0xbb, 0xcf, + 0xbb, 0xbf, 0x10, 0x97, 0xe, 0x10, 0x2, 0xd0, + 0x0, 0xe1, 0xe, 0x10, 0xe3, 0x11, 0x4e, 0x11, + 0x1f, 0x15, 0x90, 0xe, 0xdd, 0xdd, 0xdd, 0xdd, + 0xf1, + + /* U+5C4B "屋" */ + 0x0, 0xde, 0xee, 0xee, 0xee, 0xee, 0xef, 0x0, + 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0xdf, 0xee, 0xee, 0xee, 0xee, 0xee, 0x0, + 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xdc, 0xee, 0xee, 0xee, 0xee, 0xee, 0x70, + 0x0, 0xe3, 0x1, 0xd6, 0x0, 0x68, 0x0, 0x0, + 0x0, 0xf2, 0x1d, 0x70, 0x1, 0x3e, 0xb0, 0x0, + 0x0, 0xf0, 0xef, 0xee, 0xfd, 0xba, 0xbb, 0x0, + 0x2, 0xf0, 0x21, 0x0, 0xa5, 0x0, 0x5, 0x0, + 0x5, 0xb0, 0xde, 0xee, 0xfe, 0xee, 0xea, 0x0, + 0x9, 0x80, 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, + 0xe, 0x30, 0x0, 0x0, 0xa5, 0x0, 0x0, 0x0, + 0x5c, 0x2e, 0xee, 0xee, 0xfe, 0xee, 0xee, 0xe0, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5C55 "展" */ + 0x0, 0xdf, 0xee, 0xee, 0xee, 0xee, 0xef, 0x0, + 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, + 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, + 0x0, 0xdf, 0xee, 0xff, 0xee, 0xff, 0xef, 0x0, + 0x0, 0xd3, 0x0, 0xd3, 0x0, 0x2d, 0x0, 0x0, + 0x0, 0xd3, 0x0, 0xd4, 0x0, 0x3e, 0x0, 0x0, + 0x0, 0xe6, 0xdd, 0xfe, 0xdd, 0xef, 0xdd, 0x60, + 0x0, 0xf2, 0x0, 0xd3, 0x0, 0x2d, 0x0, 0x0, + 0x0, 0xf9, 0xcc, 0xfd, 0xcc, 0xdf, 0xcc, 0xc0, + 0x3, 0xe1, 0x2e, 0x32, 0x5e, 0x32, 0x4a, 0x20, + 0x6, 0xa0, 0xe, 0x10, 0xa, 0xa5, 0xd5, 0x0, + 0xb, 0x70, 0xe, 0x10, 0x2, 0xcf, 0x20, 0x0, + 0x2f, 0x10, 0x2f, 0x9b, 0xeb, 0xa, 0xe6, 0x10, + 0x59, 0x0, 0x7c, 0x84, 0x0, 0x0, 0x4a, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5C65 "履" */ + 0x0, 0xde, 0xdd, 0xdd, 0xdd, 0xdd, 0xdf, 0x20, + 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0xe, 0x20, + 0x0, 0xdb, 0xaa, 0xaa, 0xaa, 0xaa, 0xaf, 0x20, + 0x0, 0xd6, 0x36, 0x83, 0x78, 0x33, 0x33, 0x0, + 0x0, 0xe3, 0x2d, 0x30, 0xcd, 0xbb, 0xbb, 0x70, + 0x0, 0xe6, 0xe4, 0x19, 0xb2, 0x22, 0x22, 0x0, + 0x0, 0xf2, 0x25, 0xdb, 0xf8, 0x88, 0x8f, 0x0, + 0x0, 0xf1, 0x3f, 0x30, 0xf9, 0x99, 0x9f, 0x0, + 0x1, 0xf6, 0xfd, 0x0, 0xe2, 0x22, 0x2e, 0x0, + 0x3, 0xd7, 0x6c, 0x0, 0x7d, 0xa7, 0x77, 0x0, + 0x6, 0xa0, 0x2c, 0x0, 0x8f, 0xbb, 0xbc, 0x0, + 0xb, 0x60, 0x2c, 0x2c, 0xab, 0x22, 0xc6, 0x0, + 0x1f, 0x10, 0x2c, 0x12, 0x16, 0xff, 0x92, 0x0, + 0x39, 0x0, 0x2c, 0xa, 0xb6, 0x21, 0x59, 0xc1, + + /* U+5C6C "屬" */ + 0x0, 0xdd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0x20, + 0xd, 0x30, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0xdd, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x20, 0xd, + 0x33, 0xa8, 0x25, 0x72, 0x8a, 0x30, 0x0, 0xd3, + 0x1, 0x88, 0x78, 0x47, 0x20, 0x0, 0xd, 0x27, + 0xa6, 0x25, 0x61, 0x59, 0x50, 0x0, 0xe2, 0xe9, + 0x9f, 0x99, 0xf9, 0x9f, 0x0, 0xf, 0x1c, 0x8a, + 0xc7, 0x7c, 0x77, 0xc0, 0x0, 0xf0, 0xa, 0xea, + 0xaa, 0xaa, 0xaa, 0x40, 0x1e, 0x2c, 0xc4, 0x6d, + 0x44, 0x40, 0xa5, 0x4, 0xb7, 0x7d, 0x68, 0xd6, + 0x6c, 0xa, 0x40, 0x88, 0x1, 0xc9, 0xae, 0x9a, + 0xb0, 0xc3, 0xd, 0x30, 0x0, 0x4, 0xd4, 0xd8, + 0xe, 0x12, 0xc0, 0x1c, 0xca, 0x97, 0x53, 0x8d, + 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5C71 "山" */ + 0x0, 0x0, 0x0, 0x4d, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4d, 0x0, 0x0, 0x0, 0x4, 0x0, + 0x0, 0x4d, 0x0, 0x0, 0x23, 0x2e, 0x0, 0x0, + 0x4d, 0x0, 0x0, 0x6a, 0x2e, 0x0, 0x0, 0x4d, + 0x0, 0x0, 0x6a, 0x2e, 0x0, 0x0, 0x4d, 0x0, + 0x0, 0x6a, 0x2e, 0x0, 0x0, 0x4d, 0x0, 0x0, + 0x6a, 0x2e, 0x0, 0x0, 0x4d, 0x0, 0x0, 0x6a, + 0x2e, 0x0, 0x0, 0x4d, 0x0, 0x0, 0x6a, 0x2e, + 0x0, 0x0, 0x4d, 0x0, 0x0, 0x6a, 0x2e, 0x0, + 0x0, 0x4d, 0x0, 0x0, 0x6a, 0x2e, 0x11, 0x11, + 0x5d, 0x11, 0x11, 0x7a, 0x2f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6a, + + /* U+5CF6 "島" */ + 0x0, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x70, 0x0, 0x0, 0x0, 0x0, + 0xdd, 0xcc, 0xcc, 0xcc, 0xde, 0x0, 0x0, 0xd, + 0x40, 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xdd, + 0xcc, 0xcc, 0xcc, 0xce, 0x0, 0x0, 0xd, 0x40, + 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0xdd, 0xcc, + 0xcc, 0xcc, 0xcb, 0x0, 0x0, 0xd, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xde, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0x10, 0xd, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xce, 0xee, 0xee, 0xee, + 0xee, 0xe7, 0x0, 0x20, 0x1, 0xa0, 0x0, 0x20, + 0x8, 0x60, 0x3c, 0x0, 0x1d, 0x0, 0x3b, 0x0, + 0xa4, 0x3, 0xeb, 0xbb, 0xeb, 0xbc, 0xb0, 0xd, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x3a, 0xde, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5D4C "嵌" */ + 0x0, 0xe2, 0x0, 0x5, 0xb0, 0x0, 0xb, 0x50, + 0x0, 0xe2, 0x0, 0x5, 0xb0, 0x0, 0xb, 0x50, + 0x0, 0xdf, 0xee, 0xef, 0xfe, 0xee, 0xef, 0x50, + 0x0, 0x62, 0x0, 0x31, 0x4, 0x70, 0x0, 0x0, + 0x0, 0xb4, 0x0, 0xb4, 0x8, 0x91, 0x11, 0x10, + 0xc, 0xfd, 0xcc, 0xed, 0x7c, 0xdc, 0xcc, 0xf5, + 0x3, 0xc7, 0x33, 0xc7, 0x3e, 0x3, 0x10, 0xe1, + 0x0, 0xb4, 0x0, 0xb4, 0x7a, 0xb, 0x41, 0xc0, + 0x0, 0xb6, 0x22, 0xc4, 0xc3, 0xc, 0x43, 0x70, + 0x0, 0xbd, 0xbb, 0xe4, 0x0, 0xf, 0x90, 0x0, + 0x0, 0xb4, 0x0, 0xb4, 0x0, 0x6e, 0xf1, 0x0, + 0x0, 0xb5, 0x0, 0xb4, 0x1, 0xe4, 0x98, 0x0, + 0x0, 0xbf, 0xee, 0xf4, 0x1c, 0x80, 0x1d, 0x50, + 0x0, 0xb4, 0x0, 0xb5, 0xb5, 0x0, 0x1, 0xb3, + + /* U+5DDD "川" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xd0, 0x0, 0x0, 0x0, 0x0, 0xd3, 0x0, + 0x3d, 0x0, 0x0, 0xc0, 0x0, 0xd, 0x30, 0x3, + 0xd0, 0x0, 0x1f, 0x0, 0x0, 0xd3, 0x0, 0x3d, + 0x0, 0x1, 0xf0, 0x0, 0xd, 0x30, 0x3, 0xd0, + 0x0, 0x1f, 0x0, 0x0, 0xd3, 0x0, 0x3d, 0x0, + 0x1, 0xf0, 0x0, 0xd, 0x30, 0x3, 0xd0, 0x0, + 0x1f, 0x0, 0x0, 0xd3, 0x0, 0x4d, 0x0, 0x1, + 0xf0, 0x0, 0xd, 0x30, 0x6, 0xb0, 0x0, 0x1f, + 0x0, 0x0, 0xd3, 0x0, 0x89, 0x0, 0x1, 0xf0, + 0x0, 0xd, 0x30, 0xc, 0x50, 0x0, 0x1f, 0x0, + 0x0, 0xd3, 0x1, 0xf0, 0x0, 0x1, 0xf0, 0x0, + 0xd, 0x30, 0xa9, 0x0, 0x0, 0x1f, 0x0, 0x0, + 0xd3, 0x1d, 0x10, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5DDE "州" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0xc, 0x40, 0x0, 0xe1, 0x0, + 0x2, 0xe0, 0x0, 0xc4, 0x0, 0xe, 0x10, 0x0, + 0x2e, 0x0, 0xc, 0x40, 0x0, 0xe1, 0x0, 0x82, + 0xe2, 0x20, 0xc5, 0x50, 0xe, 0x10, 0x3c, 0x2e, + 0x69, 0xc, 0x4d, 0x30, 0xe1, 0x8, 0x72, 0xe1, + 0xe0, 0xc4, 0x5b, 0xe, 0x10, 0xe1, 0x3d, 0xc, + 0x3c, 0x40, 0xe2, 0xe1, 0x39, 0x4, 0xc0, 0x73, + 0xc4, 0x6, 0x3e, 0x10, 0x0, 0x79, 0x0, 0xc, + 0x40, 0x0, 0xe1, 0x0, 0xb, 0x70, 0x0, 0xc4, + 0x0, 0xe, 0x10, 0x2, 0xf1, 0x0, 0xc, 0x40, + 0x0, 0xe1, 0x0, 0xab, 0x0, 0x0, 0xc4, 0x0, + 0xe, 0x10, 0x6f, 0x20, 0x0, 0xb, 0x40, 0x0, + 0xe1, 0xc, 0x40, 0x0, 0x0, 0x0, 0x0, 0xe, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5DE5 "工" */ + 0x4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x50, + 0x1, 0x44, 0x44, 0x4b, 0xb4, 0x44, 0x44, 0x10, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x1a, 0x91, 0x11, 0x11, 0x10, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + + /* U+5DE6 "左" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x44, 0x4a, 0xa4, 0x44, 0x44, 0x44, 0x30, + 0xb, 0xcc, 0xcf, 0xdc, 0xcc, 0xcc, 0xcc, 0x90, + 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x50, + 0x0, 0x9, 0x90, 0x0, 0xf, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0x20, 0x0, 0xf, 0x0, 0x0, 0x0, + 0x0, 0xb8, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, + 0x8, 0xd0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, + 0x4e, 0x20, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, + 0x2, 0x5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + + /* U+5DEE "差" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, 0xe4, 0x0, 0x0, 0x3f, 0x10, 0x0, + 0x0, 0x0, 0x6d, 0x10, 0x1, 0xd7, 0x0, 0x0, + 0x4, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0x60, + 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x0, + 0x0, 0x0, 0x0, 0xb7, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x12, 0xf3, 0x11, 0x11, 0x11, 0x10, + 0xe, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xee, 0xe0, + 0x0, 0x0, 0x2e, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xcc, 0xff, 0xff, 0xff, 0xfc, 0x0, + 0x0, 0x9, 0xa0, 0x0, 0x1f, 0x10, 0x0, 0x0, + 0x2, 0xcc, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, + 0x1f, 0x92, 0x44, 0x44, 0x5f, 0x54, 0x44, 0x40, + 0x2, 0x5, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb0, + + /* U+5DF1 "己" */ + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x0, 0x1, + 0x11, 0x11, 0x11, 0x11, 0xe3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe3, 0x0, 0x1, 0x11, 0x11, 0x11, 0x11, + 0xe3, 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x41, 0x0, + 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x4c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe3, 0x4c, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xf1, 0x3e, 0x31, 0x0, 0x0, + 0x0, 0x19, 0xc0, 0x9, 0xef, 0xff, 0xff, 0xff, + 0xfc, 0x30, + + /* U+5DF2 "已" */ + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x1, + 0x11, 0x11, 0x11, 0x11, 0x3f, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2f, 0x0, 0x6, 0x10, 0x0, + 0x0, 0x0, 0x2f, 0x0, 0xd, 0x30, 0x0, 0x0, + 0x0, 0x2f, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, + 0x2f, 0x0, 0xd, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0xd, 0x41, 0x11, 0x11, 0x11, 0x14, 0x0, + 0xd, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x27, 0xd, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x4d, 0xd, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x7b, 0xb, 0x91, 0x0, 0x0, + 0x0, 0x3, 0xd6, 0x2, 0xcf, 0xff, 0xff, 0xff, + 0xfe, 0x80, + + /* U+5E02 "市" */ + 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0xc0, 0x0, 0x0, 0x0, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xfb, 0x0, + 0x0, 0x98, 0x11, 0x1a, 0x81, 0x11, 0x6b, 0x0, + 0x0, 0x97, 0x0, 0x9, 0x70, 0x0, 0x5b, 0x0, + 0x0, 0x97, 0x0, 0x9, 0x70, 0x0, 0x5b, 0x0, + 0x0, 0x97, 0x0, 0x9, 0x70, 0x0, 0x5b, 0x0, + 0x0, 0x97, 0x0, 0x9, 0x70, 0x0, 0x5b, 0x0, + 0x0, 0x97, 0x0, 0x9, 0x70, 0xef, 0xf7, 0x0, + 0x0, 0x11, 0x0, 0x9, 0x70, 0x11, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + + /* U+5E03 "布" */ + 0x0, 0x0, 0x0, 0x32, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x1, 0x11, 0x4e, 0x21, 0x52, 0x11, 0x11, 0x10, + 0x0, 0x0, 0xc7, 0x0, 0xc4, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xd0, 0x0, 0xc4, 0x0, 0x0, 0x0, + 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, + 0x4, 0xfb, 0xa1, 0x11, 0xd5, 0x11, 0x1f, 0x20, + 0x3f, 0x56, 0xa0, 0x0, 0xc4, 0x0, 0xe, 0x20, + 0x4, 0x6, 0xa0, 0x0, 0xc4, 0x0, 0xe, 0x20, + 0x0, 0x6, 0xa0, 0x0, 0xc4, 0x0, 0xe, 0x20, + 0x0, 0x6, 0xa0, 0x0, 0xc4, 0x12, 0x3f, 0x10, + 0x0, 0x6, 0x90, 0x0, 0xc4, 0x4c, 0xb8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc4, 0x0, 0x0, 0x0, + + /* U+5E08 "师" */ + 0x0, 0xd, 0x1d, 0xff, 0xff, 0xff, 0xff, 0x22, + 0x80, 0xd1, 0x0, 0x0, 0xf0, 0x0, 0x0, 0x3c, + 0xd, 0x10, 0x0, 0xf, 0x0, 0x0, 0x3, 0xc0, + 0xd1, 0x3d, 0xdd, 0xfd, 0xdd, 0x60, 0x3c, 0xd, + 0x14, 0xc2, 0x2f, 0x22, 0x97, 0x3, 0xc0, 0xd1, + 0x4b, 0x0, 0xf0, 0x8, 0x70, 0x3c, 0xe, 0x14, + 0xb0, 0xf, 0x0, 0x87, 0x3, 0xc0, 0xe1, 0x4b, + 0x0, 0xf0, 0x8, 0x70, 0x3c, 0xf, 0x4, 0xb0, + 0xf, 0x0, 0x87, 0x0, 0x2, 0xd0, 0x4b, 0x0, + 0xf0, 0x8, 0x70, 0x0, 0x6a, 0x4, 0xb0, 0xf, + 0x1, 0x97, 0x0, 0xd, 0x40, 0x3a, 0x0, 0xf0, + 0xcc, 0x30, 0x7, 0xc0, 0x0, 0x0, 0xf, 0x0, + 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5E0C "希" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x1c, 0xa5, 0x0, 0x0, 0x3c, 0xb0, 0x0, + 0x0, 0x0, 0x49, 0xdb, 0x7c, 0xd5, 0x0, 0x0, + 0x0, 0x0, 0x37, 0xbf, 0xbe, 0xa4, 0x0, 0x0, + 0x1, 0xbf, 0xd9, 0xd6, 0x0, 0x5c, 0xd5, 0x0, + 0x0, 0x41, 0x1, 0xf2, 0x0, 0x0, 0x41, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x5d, 0x10, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xf4, 0x0, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x5f, 0xfe, 0xee, 0xfe, 0xee, 0xfc, 0x0, + 0x9, 0xe9, 0xb0, 0x0, 0xe1, 0x0, 0x4c, 0x0, + 0x18, 0x5, 0xb0, 0x0, 0xe1, 0x0, 0x4c, 0x0, + 0x0, 0x5, 0xb0, 0x0, 0xe1, 0x0, 0x4c, 0x0, + 0x0, 0x5, 0xb0, 0x0, 0xe1, 0x6e, 0xe8, 0x0, + 0x0, 0x0, 0x10, 0x0, 0xe1, 0x0, 0x0, 0x0, + + /* U+5E2B "師" */ + 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0x0, 0x7f, 0xff, 0xff, 0xff, 0xf4, 0x6, + 0x90, 0x0, 0x0, 0xe, 0x10, 0x0, 0xe, 0xff, + 0xfd, 0x0, 0x0, 0xe1, 0x0, 0x0, 0xe1, 0x1, + 0xd0, 0x78, 0x8f, 0x98, 0x86, 0xe, 0x10, 0x1d, + 0xe, 0x65, 0xf6, 0x57, 0xc0, 0xed, 0xcd, 0xd0, + 0xe1, 0xe, 0x10, 0x3c, 0xe, 0x32, 0x22, 0xe, + 0x10, 0xe1, 0x3, 0xc0, 0xe1, 0x0, 0x0, 0xe1, + 0xe, 0x10, 0x3c, 0xe, 0xff, 0xff, 0xe, 0x10, + 0xe1, 0x3, 0xc0, 0xe1, 0x0, 0xf0, 0xe1, 0xe, + 0x10, 0x3c, 0xe, 0x10, 0xf, 0xe, 0x10, 0xe1, + 0x3, 0xc0, 0xe1, 0x0, 0xf0, 0xe1, 0xe, 0x1d, + 0xf8, 0xe, 0xee, 0xee, 0x1, 0x0, 0xe1, 0x0, + 0x0, 0xe1, 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, + 0x0, + + /* U+5E2D "席" */ + 0x0, 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, + 0x0, 0xee, 0xee, 0xee, 0xff, 0xee, 0xee, 0xe0, + 0x0, 0xf0, 0x0, 0x11, 0x0, 0x1, 0x10, 0x0, + 0x0, 0xf0, 0x0, 0xb3, 0x0, 0xd, 0x30, 0x0, + 0x0, 0xf4, 0xee, 0xfe, 0xee, 0xef, 0xee, 0xc0, + 0x0, 0xf0, 0x0, 0xb3, 0x0, 0xd, 0x30, 0x0, + 0x0, 0xf0, 0x0, 0xb3, 0x0, 0xd, 0x30, 0x0, + 0x1, 0xf0, 0x0, 0xae, 0xef, 0xee, 0x30, 0x0, + 0x2, 0xd0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, + 0x3, 0xc0, 0x4f, 0xee, 0xff, 0xee, 0xff, 0x0, + 0x6, 0x90, 0x4b, 0x0, 0x1e, 0x0, 0xf, 0x0, + 0x9, 0x50, 0x4b, 0x0, 0x1e, 0x0, 0xf, 0x0, + 0xd, 0x10, 0x4b, 0x0, 0x1e, 0x2, 0x4f, 0x0, + 0x4a, 0x0, 0x39, 0x0, 0x1e, 0xb, 0xb7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5E2F "帯" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x80, 0x8, 0x70, 0x7, 0x80, 0x0, + 0x2e, 0xef, 0xfe, 0xef, 0xfe, 0xef, 0xfe, 0xe2, + 0x0, 0x8, 0x80, 0x9, 0x70, 0x8, 0x90, 0x0, + 0x0, 0x7, 0x80, 0x8, 0x70, 0x7, 0x80, 0x0, + 0x0, 0x7, 0xee, 0xee, 0xee, 0xee, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xb0, + 0xb, 0x40, 0x0, 0x9, 0x70, 0x0, 0x4, 0xb0, + 0xb, 0x4a, 0xbb, 0xbe, 0xdb, 0xbb, 0xb6, 0xb0, + 0x1, 0xe, 0x42, 0x2a, 0x92, 0x22, 0xf2, 0x10, + 0x0, 0xe, 0x10, 0x9, 0x70, 0x0, 0xe1, 0x0, + 0x0, 0xe, 0x10, 0x9, 0x70, 0x0, 0xf1, 0x0, + 0x0, 0xe, 0x10, 0x9, 0x70, 0xde, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + + /* U+5E30 "帰" */ + 0x0, 0x4, 0xb0, 0xbd, 0xdd, 0xdd, 0xdd, 0x0, + 0x0, 0x4, 0xb0, 0x0, 0x0, 0x0, 0x2d, 0x0, + 0x3, 0x14, 0xb0, 0x1d, 0xdd, 0xdd, 0xdd, 0x0, + 0x9, 0x44, 0xb0, 0x0, 0x0, 0x0, 0x2d, 0x0, + 0xa, 0x34, 0xb0, 0x9d, 0xdd, 0xdd, 0xdb, 0x0, + 0xc, 0x24, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x4, 0xb8, 0xdd, 0xdf, 0xdd, 0xdd, 0xf1, + 0x29, 0x5, 0xa8, 0x30, 0xb, 0x40, 0x0, 0xe1, + 0x0, 0x6, 0x94, 0xee, 0xef, 0xee, 0xed, 0x80, + 0x0, 0x9, 0x60, 0xd2, 0xb, 0x40, 0x1e, 0x0, + 0x0, 0xd, 0x30, 0xd2, 0xb, 0x40, 0x1e, 0x0, + 0x0, 0x5b, 0x0, 0xd2, 0xb, 0x40, 0x1e, 0x0, + 0x2, 0xe3, 0x0, 0xd2, 0xb, 0x48, 0xea, 0x0, + 0xa, 0x40, 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5E33 "帳" */ + 0x0, 0xe0, 0x0, 0x8f, 0xdd, 0xdd, 0xd9, 0x0, + 0xe, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, 0x12, + 0xe2, 0x20, 0x8a, 0x33, 0x33, 0x30, 0xd, 0xdf, + 0xdf, 0x8, 0xda, 0xaa, 0xaa, 0x0, 0xd0, 0xe0, + 0xd0, 0x88, 0x0, 0x0, 0x0, 0xd, 0xe, 0xd, + 0x8, 0xec, 0xcc, 0xcc, 0x20, 0xd0, 0xe0, 0xd0, + 0x88, 0x0, 0x0, 0x0, 0xd, 0xe, 0xd, 0x9f, + 0xff, 0xff, 0xff, 0xf1, 0xd0, 0xe0, 0xd0, 0xe1, + 0x69, 0x0, 0x42, 0xd, 0xe, 0x1d, 0xe, 0x10, + 0xd3, 0x6d, 0x30, 0xd0, 0xe8, 0x80, 0xe1, 0x3, + 0xeb, 0x10, 0x0, 0xe, 0x0, 0xe, 0x10, 0x5, + 0xd2, 0x0, 0x0, 0xe0, 0x0, 0xf8, 0xcb, 0x5, + 0xe7, 0x0, 0xe, 0x0, 0x3e, 0x82, 0x0, 0x2, + 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+5E36 "帶" */ + 0x0, 0x7, 0x80, 0xd0, 0xd, 0x16, 0x80, 0x0, + 0xa, 0xac, 0xda, 0xfa, 0xaf, 0xbc, 0xda, 0xa0, + 0x3, 0x3a, 0x84, 0xe3, 0x3e, 0x48, 0xa3, 0x40, + 0x0, 0x1e, 0x20, 0xe0, 0xe, 0x16, 0x90, 0xb1, + 0x4, 0xd7, 0x0, 0xfd, 0xdf, 0x15, 0xda, 0xe0, + 0x7, 0x40, 0x0, 0x0, 0x0, 0x0, 0x24, 0x20, + 0xb, 0xfe, 0xee, 0xef, 0xfe, 0xee, 0xef, 0xd0, + 0xb, 0x40, 0x0, 0x9, 0x70, 0x0, 0x3, 0xd0, + 0xb, 0x6b, 0xbb, 0xbe, 0xdb, 0xbb, 0xb6, 0xd0, + 0x0, 0x2e, 0x22, 0x2a, 0x92, 0x22, 0xc4, 0x0, + 0x0, 0x2e, 0x0, 0x9, 0x70, 0x0, 0xb4, 0x0, + 0x0, 0x2e, 0x0, 0x9, 0x70, 0x0, 0xc4, 0x0, + 0x0, 0x2e, 0x0, 0x9, 0x70, 0xcd, 0xe2, 0x0, + 0x0, 0x1, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + + /* U+5E38 "常" */ + 0x0, 0xb1, 0x0, 0xd3, 0x0, 0x69, 0x0, 0x0, + 0x5b, 0x0, 0xd3, 0x1, 0xd1, 0x0, 0xcf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf4, 0xc3, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc4, 0xc3, 0x1d, 0xdd, 0xdd, + 0xdd, 0xd0, 0xc4, 0x51, 0x1e, 0x0, 0x0, 0x0, + 0xf0, 0x51, 0x0, 0x1e, 0x0, 0x0, 0x0, 0xf0, + 0x0, 0x0, 0x1d, 0xdd, 0xfe, 0xdd, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0xc4, 0x0, 0x0, 0x0, 0xb, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0xb, 0x70, + 0x0, 0xc4, 0x0, 0xa, 0x40, 0xb, 0x70, 0x0, + 0xc4, 0x0, 0xa, 0x40, 0xb, 0x70, 0x0, 0xc4, + 0x3, 0x2b, 0x30, 0x8, 0x50, 0x0, 0xc4, 0xa, + 0xca, 0x0, + + /* U+5E45 "幅" */ + 0x0, 0xe0, 0x2, 0xee, 0xee, 0xee, 0xee, 0x0, + 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x89, 0xf9, + 0x90, 0xa, 0xaa, 0xaa, 0xa1, 0xd6, 0xf6, 0xd1, + 0x1e, 0x33, 0x33, 0xe1, 0xd0, 0xe0, 0xb1, 0x1d, + 0x0, 0x0, 0xd1, 0xd0, 0xe0, 0xb1, 0x1f, 0xdd, + 0xdd, 0xf1, 0xd0, 0xe0, 0xb1, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0xe0, 0xb1, 0xaa, 0xaa, 0xaa, 0xa8, + 0xd0, 0xe0, 0xb1, 0xf5, 0x3d, 0x43, 0x6c, 0xd0, + 0xe1, 0xc1, 0xf2, 0xc, 0x10, 0x3c, 0xc0, 0xe4, + 0x80, 0xfe, 0xdf, 0xed, 0xec, 0x0, 0xe0, 0x0, + 0xf2, 0xc, 0x10, 0x3c, 0x0, 0xe0, 0x0, 0xf2, + 0xc, 0x10, 0x3c, 0x0, 0xe0, 0x0, 0xfe, 0xdd, + 0xdd, 0xeb, + + /* U+5E73 "平" */ + 0x0, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0, + 0x4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, + 0x0, 0x1, 0x0, 0x9, 0x80, 0x0, 0x20, 0x0, + 0x0, 0xe, 0x20, 0x9, 0x80, 0x3, 0xf1, 0x0, + 0x0, 0x8, 0x90, 0x9, 0x80, 0x9, 0x90, 0x0, + 0x0, 0x2, 0xf0, 0x9, 0x80, 0x1e, 0x10, 0x0, + 0x0, 0x0, 0x92, 0x9, 0x80, 0x57, 0x0, 0x0, + 0x4, 0x44, 0x44, 0x4b, 0xa4, 0x44, 0x44, 0x40, + 0x1c, 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xcc, 0xc2, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + + /* U+5E74 "年" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xf4, 0x33, 0x33, 0x33, 0x33, 0x10, + 0x0, 0xe, 0xdc, 0xcc, 0xfd, 0xcc, 0xcc, 0x60, + 0x0, 0xbb, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, + 0xa, 0xd1, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, + 0x7, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, + 0x0, 0x8, 0x80, 0x0, 0xc6, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x80, 0x0, 0xb5, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x80, 0x0, 0xb5, 0x0, 0x0, 0x0, + 0x2b, 0xbe, 0xdb, 0xbb, 0xed, 0xbb, 0xbb, 0xb2, + 0x4, 0x44, 0x44, 0x44, 0xd8, 0x44, 0x44, 0x41, + 0x0, 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, + + /* U+5E78 "幸" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x7d, 0xdd, 0xdf, 0xfd, 0xdd, 0xd7, 0x0, + 0x0, 0x1, 0x11, 0x1a, 0x81, 0x11, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0x0, 0xd2, 0x0, 0x0, 0x1c, 0x10, 0x0, + 0x0, 0x0, 0xa9, 0x0, 0x0, 0x7b, 0x0, 0x0, + 0x0, 0x23, 0x7c, 0x33, 0x33, 0xe6, 0x33, 0x0, + 0x0, 0xbb, 0xbb, 0xbe, 0xeb, 0xbb, 0xbb, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x8, 0xbb, 0xbb, 0xbe, 0xdb, 0xbb, 0xbb, 0x80, + 0x3, 0x44, 0x44, 0x4b, 0xa4, 0x44, 0x44, 0x30, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + + /* U+5E7E "幾" */ + 0x0, 0x7, 0x30, 0xd, 0x30, 0xa, 0x10, 0x0, + 0x0, 0x1c, 0x0, 0xc, 0x40, 0x4a, 0x4, 0x0, + 0x0, 0xa3, 0x2b, 0xa, 0x51, 0xc1, 0x6a, 0x0, + 0x9, 0xc8, 0xd2, 0x9, 0x6a, 0xdd, 0xc0, 0x0, + 0x5, 0x5d, 0x46, 0x7, 0x80, 0x2c, 0x2c, 0x0, + 0x0, 0xb5, 0x29, 0x84, 0xb4, 0xe9, 0x9d, 0x80, + 0x9, 0xdc, 0xb8, 0xd2, 0xf4, 0x8d, 0x41, 0x90, + 0x1, 0x16, 0xc1, 0x21, 0xe3, 0x17, 0xc1, 0x10, + 0x1d, 0xde, 0xed, 0xdd, 0xef, 0xdd, 0xdd, 0xd2, + 0x0, 0x9, 0x70, 0x0, 0x3d, 0x3, 0xb0, 0x0, + 0x0, 0xd, 0xd7, 0x0, 0xb, 0x8d, 0x30, 0x0, + 0x0, 0x5c, 0x9, 0xb0, 0x8, 0xf6, 0x0, 0x73, + 0x2, 0xe3, 0x0, 0x15, 0xc9, 0x7e, 0x52, 0xd2, + 0xd, 0x40, 0x0, 0xd9, 0x10, 0x4, 0xbf, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5E83 "広" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0x11, 0x11, 0x11, 0xb8, 0x11, 0x11, 0x10, + 0x0, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0xd3, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0xd3, 0x0, 0x0, 0xf3, 0x0, 0x0, 0x0, + 0x0, 0xd3, 0x0, 0x5, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0xd3, 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, + 0x0, 0xe2, 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf2, 0x0, 0xa8, 0x0, 0x5c, 0x0, 0x0, + 0x0, 0xf0, 0x2, 0xe1, 0x0, 0xc, 0x80, 0x0, + 0x3, 0xe0, 0xa, 0x70, 0x0, 0x2, 0xf3, 0x0, + 0x7, 0xa0, 0x3e, 0x0, 0x0, 0x13, 0xad, 0x0, + 0xc, 0x61, 0xdd, 0xbc, 0xef, 0xdc, 0xae, 0x60, + 0x3e, 0x0, 0x97, 0x53, 0x10, 0x0, 0x6, 0xc0, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5E86 "庆" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x22, 0x22, 0x23, 0xc9, 0x22, 0x22, 0x20, + 0x0, 0xfd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xd3, + 0x0, 0xf0, 0x0, 0x0, 0x2b, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0x0, 0x0, 0x4d, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x1, 0xf0, 0x0, 0x0, 0xce, 0x0, 0x0, 0x0, + 0x2, 0xe0, 0x0, 0x1, 0xfc, 0x70, 0x0, 0x0, + 0x3, 0xd0, 0x0, 0x7, 0xb1, 0xd2, 0x0, 0x0, + 0x5, 0xb0, 0x0, 0x1f, 0x30, 0x5c, 0x0, 0x0, + 0x9, 0x70, 0x1, 0xd9, 0x0, 0xa, 0xc1, 0x0, + 0xe, 0x30, 0x3d, 0xa0, 0x0, 0x0, 0xbd, 0x40, + 0x4d, 0x5, 0xe7, 0x0, 0x0, 0x0, 0x7, 0xf2, + 0x1, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+5E95 "底" */ + 0x0, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc7, 0x0, 0x0, 0x0, + 0x0, 0xee, 0xee, 0xee, 0xff, 0xee, 0xee, 0xe3, + 0x0, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0x0, 0x12, 0x34, 0x68, 0xc9, 0x0, + 0x0, 0xf0, 0x1f, 0xed, 0xcc, 0xe7, 0x42, 0x0, + 0x0, 0xf0, 0x1e, 0x0, 0x3, 0xd0, 0x0, 0x0, + 0x0, 0xf0, 0x1e, 0x0, 0x1, 0xf0, 0x0, 0x0, + 0x1, 0xf0, 0x1f, 0xcc, 0xcd, 0xfd, 0xcc, 0xa0, + 0x2, 0xe0, 0x1e, 0x22, 0x22, 0xb7, 0x22, 0x10, + 0x3, 0xc0, 0x1e, 0x0, 0x0, 0x79, 0x0, 0x0, + 0x6, 0xa0, 0x1e, 0x0, 0x57, 0x2e, 0x0, 0x20, + 0xa, 0x60, 0x1e, 0x2, 0x4e, 0x1b, 0x60, 0x84, + 0xf, 0x20, 0x3f, 0xdc, 0x48, 0x83, 0xe3, 0xb1, + 0x4b, 0x0, 0x88, 0x20, 0x1, 0x90, 0x5d, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5E97 "店" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x33, 0x33, 0x33, 0xe6, 0x33, 0x33, 0x30, + 0x0, 0xfd, 0xcc, 0xcc, 0xdd, 0xcc, 0xcc, 0xc1, + 0x0, 0xf2, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, + 0x0, 0xf2, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, + 0x0, 0xf2, 0x0, 0x0, 0xef, 0xff, 0xff, 0x60, + 0x0, 0xf1, 0x0, 0x0, 0xe3, 0x0, 0x0, 0x0, + 0x1, 0xf1, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, + 0x2, 0xf0, 0x1c, 0xcc, 0xfd, 0xcc, 0xcb, 0x0, + 0x3, 0xe0, 0x2e, 0x22, 0x22, 0x22, 0x5e, 0x0, + 0x6, 0xb0, 0x2e, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0xa, 0x80, 0x2e, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x1f, 0x30, 0x2f, 0xcc, 0xcc, 0xcc, 0xde, 0x0, + 0x4c, 0x0, 0x2e, 0x22, 0x22, 0x22, 0x4e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5E9C "府" */ + 0x0, 0x0, 0x0, 0x4, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0xdd, 0xdd, 0xdd, 0xfe, 0xdd, 0xdd, 0xd0, + 0x0, 0xf2, 0x22, 0x73, 0x22, 0x22, 0x73, 0x20, + 0x0, 0xf0, 0x2, 0xe0, 0x0, 0x0, 0xd3, 0x0, + 0x0, 0xf0, 0x8, 0x80, 0x0, 0x0, 0xd3, 0x0, + 0x0, 0xf0, 0x1f, 0x2b, 0xdd, 0xdd, 0xfe, 0xd1, + 0x0, 0xf0, 0xcf, 0x11, 0x11, 0x11, 0xe4, 0x10, + 0x1, 0xf7, 0xce, 0x10, 0x80, 0x0, 0xd3, 0x0, + 0x2, 0xe3, 0x1e, 0x10, 0x98, 0x0, 0xd3, 0x0, + 0x3, 0xd0, 0xe, 0x10, 0x1e, 0x20, 0xd3, 0x0, + 0x4, 0xc0, 0xe, 0x10, 0x7, 0x50, 0xd3, 0x0, + 0x7, 0x90, 0xe, 0x10, 0x0, 0x0, 0xd3, 0x0, + 0xd, 0x50, 0xe, 0x10, 0x0, 0x1, 0xe3, 0x0, + 0x1c, 0x0, 0xe, 0x10, 0x1, 0xff, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5EA6 "度" */ + 0x0, 0x0, 0x0, 0x3, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xf1, 0x0, 0x0, 0x0, + 0x0, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0xe3, 0x11, 0x31, 0x11, 0x13, 0x11, 0x10, + 0x0, 0xe1, 0x0, 0xe1, 0x0, 0xe, 0x10, 0x0, + 0x0, 0xe8, 0xee, 0xfe, 0xee, 0xef, 0xee, 0xa0, + 0x0, 0xf1, 0x0, 0xe1, 0x0, 0xe, 0x10, 0x0, + 0x0, 0xf1, 0x0, 0xe1, 0x0, 0xe, 0x10, 0x0, + 0x0, 0xf1, 0x0, 0xcd, 0xdd, 0xdd, 0x10, 0x0, + 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xe3, 0xee, 0xee, 0xee, 0xee, 0xf4, 0x0, + 0x4, 0xc0, 0x5, 0xd1, 0x0, 0x9, 0xa0, 0x0, + 0x8, 0x80, 0x0, 0x6d, 0x53, 0xc9, 0x0, 0x0, + 0xc, 0x50, 0x0, 0x29, 0xff, 0xb2, 0x0, 0x0, + 0x3e, 0x8, 0xbe, 0xd8, 0x33, 0x8e, 0xdb, 0x80, + 0x3, 0x3, 0x30, 0x0, 0x0, 0x0, 0x14, 0x40, + + /* U+5EA7 "座" */ + 0x0, 0x0, 0x0, 0x0, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa8, 0x0, 0x0, 0x0, + 0x0, 0xee, 0xee, 0xee, 0xff, 0xee, 0xee, 0xe3, + 0x0, 0xf2, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, + 0x0, 0xf0, 0x3, 0x40, 0x58, 0x0, 0x70, 0x0, + 0x0, 0xf0, 0xa, 0x60, 0x69, 0x3, 0xd0, 0x0, + 0x0, 0xf0, 0xf, 0x50, 0x69, 0x9, 0xc0, 0x0, + 0x0, 0xf0, 0x8a, 0xd5, 0x69, 0x4d, 0x8c, 0x10, + 0x1, 0xf6, 0xe1, 0x1c, 0x7b, 0xe2, 0x5, 0xd0, + 0x2, 0xe2, 0x20, 0x0, 0x69, 0x10, 0x0, 0x20, + 0x3, 0xc0, 0xcd, 0xdd, 0xee, 0xdd, 0xdd, 0x30, + 0x5, 0xa0, 0x11, 0x11, 0x7a, 0x11, 0x11, 0x0, + 0x9, 0x70, 0x0, 0x0, 0x69, 0x0, 0x0, 0x0, + 0xe, 0x30, 0x0, 0x0, 0x69, 0x0, 0x0, 0x0, + 0x3d, 0xd, 0xee, 0xee, 0xff, 0xee, 0xee, 0xe3, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5EAB "庫" */ + 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc6, 0x0, 0x0, 0x0, + 0x0, 0xfe, 0xee, 0xee, 0xef, 0xee, 0xee, 0xe3, + 0x0, 0xf0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0xcd, 0xdd, 0xdf, 0xdd, 0xdd, 0xa0, + 0x0, 0xf0, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0x2b, 0xbb, 0xcf, 0xbb, 0xbb, 0x0, + 0x0, 0xf0, 0x3b, 0x0, 0x1e, 0x0, 0xf, 0x0, + 0x1, 0xf0, 0x3e, 0xbb, 0xbf, 0xbb, 0xbf, 0x0, + 0x2, 0xe0, 0x3b, 0x0, 0x1e, 0x0, 0xf, 0x0, + 0x3, 0xc0, 0x3e, 0xbb, 0xbf, 0xbb, 0xbf, 0x0, + 0x6, 0xa0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, + 0x9, 0x69, 0xdd, 0xdd, 0xdf, 0xdd, 0xdd, 0xd4, + 0xe, 0x20, 0x11, 0x11, 0x2e, 0x11, 0x11, 0x10, + 0x3a, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5EAD "庭" */ + 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa6, 0x0, 0x0, 0x0, + 0x0, 0xee, 0xee, 0xee, 0xff, 0xee, 0xee, 0xe4, + 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, + 0x0, 0xf2, 0xdd, 0xd8, 0x25, 0x7a, 0xdc, 0x30, + 0x0, 0xf0, 0x1, 0xe2, 0x59, 0x7f, 0x20, 0x0, + 0x0, 0xf0, 0x8, 0x90, 0x0, 0xe, 0x10, 0x0, + 0x0, 0xf0, 0x3d, 0x0, 0x1, 0x1e, 0x21, 0x10, + 0x1, 0xf0, 0xdd, 0xeb, 0x3d, 0xdf, 0xdd, 0x90, + 0x2, 0xe0, 0x30, 0x78, 0x0, 0xe, 0x10, 0x0, + 0x3, 0xd0, 0xd2, 0xe3, 0x0, 0xe, 0x10, 0x0, + 0x5, 0xb0, 0x6e, 0xb0, 0xbd, 0xdf, 0xdd, 0xd1, + 0x8, 0x80, 0x1f, 0x80, 0x11, 0x11, 0x11, 0x10, + 0xd, 0x40, 0xc8, 0xdb, 0x42, 0x0, 0x0, 0x0, + 0x1e, 0xd, 0x80, 0x6, 0xbc, 0xef, 0xff, 0xf4, + 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5EB7 "康" */ + 0x0, 0x0, 0x0, 0x3, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5, + 0x0, 0xf0, 0x0, 0x0, 0xc4, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0x8c, 0xcc, 0xfd, 0xcc, 0xcb, 0x0, + 0x0, 0xf0, 0x0, 0x0, 0xc4, 0x0, 0x1e, 0x0, + 0x0, 0xf5, 0xcc, 0xcc, 0xfd, 0xcc, 0xdf, 0xd7, + 0x0, 0xf0, 0x0, 0x0, 0xd4, 0x0, 0x1e, 0x10, + 0x1, 0xf0, 0x8a, 0xaa, 0xeb, 0xaa, 0xae, 0x0, + 0x2, 0xd0, 0x84, 0x22, 0xd8, 0x22, 0x27, 0x10, + 0x3, 0xc0, 0x5d, 0x30, 0xcf, 0x41, 0xab, 0x20, + 0x6, 0x90, 0x2, 0x9a, 0xf6, 0xce, 0x40, 0x0, + 0xa, 0x61, 0x6d, 0xb3, 0xc4, 0x1b, 0xc4, 0x0, + 0xf, 0x1a, 0x92, 0x0, 0xd4, 0x0, 0x4a, 0xe4, + 0x39, 0x0, 0x1, 0xee, 0xd1, 0x0, 0x0, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5EE0 "廠" */ + 0x0, 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd4, 0x0, 0x0, 0x0, + 0x0, 0xfe, 0xee, 0xee, 0xfe, 0xee, 0xee, 0xe3, + 0x0, 0xe0, 0x0, 0x60, 0x0, 0x5, 0x0, 0x0, + 0x0, 0xe3, 0x90, 0xd1, 0x94, 0xe, 0x0, 0x0, + 0x0, 0xe0, 0xa3, 0xd3, 0xc0, 0x3c, 0x11, 0x10, + 0x1, 0xe0, 0x21, 0xd3, 0x20, 0x8d, 0xce, 0xe3, + 0x1, 0xe5, 0xed, 0xdd, 0xea, 0xf8, 0x8, 0x60, + 0x2, 0xe5, 0x70, 0x0, 0x2f, 0xab, 0xb, 0x30, + 0x3, 0xd5, 0x7a, 0xce, 0x2b, 0x1a, 0x1e, 0x0, + 0x3, 0xb5, 0x79, 0x9, 0x29, 0x6, 0xaa, 0x0, + 0x6, 0x95, 0x79, 0x9, 0x29, 0x1, 0xf3, 0x0, + 0x9, 0x65, 0x7a, 0xcb, 0x29, 0x6, 0xf6, 0x0, + 0xe, 0x25, 0x72, 0x0, 0x39, 0x5d, 0x2d, 0x50, + 0x1b, 0x5, 0x70, 0xb, 0xda, 0xc1, 0x2, 0xc3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5EFA "建" */ + 0xf, 0xff, 0xe2, 0x0, 0xa, 0x50, 0x0, 0x0, + 0x0, 0x5, 0xe0, 0x9d, 0xdf, 0xed, 0xdf, 0x0, + 0x0, 0xd, 0x70, 0x0, 0xa, 0x50, 0xf, 0x0, + 0x0, 0x5d, 0xa, 0xdd, 0xdf, 0xed, 0xdf, 0xd1, + 0x0, 0xd4, 0x0, 0x0, 0xa, 0x50, 0xf, 0x0, + 0xa, 0xfe, 0xf3, 0xbe, 0xef, 0xee, 0xef, 0x0, + 0x1, 0x0, 0xe1, 0x0, 0xa, 0x50, 0x0, 0x0, + 0x5, 0x21, 0xe0, 0xab, 0xbe, 0xdb, 0xbb, 0x40, + 0x6, 0x84, 0xb0, 0x11, 0x1a, 0x71, 0x11, 0x0, + 0x1, 0xd9, 0x60, 0x11, 0x1a, 0x61, 0x11, 0x10, + 0x0, 0x9f, 0x17, 0xcc, 0xce, 0xdc, 0xcc, 0xc0, + 0x0, 0x6f, 0x70, 0x0, 0xa, 0x50, 0x0, 0x0, + 0x2, 0xf6, 0xcd, 0x74, 0x27, 0x40, 0x0, 0x0, + 0x1e, 0x60, 0x4, 0x9b, 0xde, 0xff, 0xff, 0xf2, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5EFF "廿" */ + 0x0, 0x0, 0xf1, 0x0, 0x0, 0xf, 0x20, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0xf, 0x20, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0xf, 0x20, 0x0, + 0x2, 0x22, 0xf3, 0x22, 0x22, 0x2f, 0x42, 0x20, + 0x2e, 0xef, 0xff, 0xee, 0xee, 0xff, 0xfe, 0xe2, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0xf, 0x20, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0xf, 0x20, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0xf, 0x20, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0xf, 0x20, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0xf, 0x20, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0xf, 0x20, 0x0, + 0x0, 0x0, 0xf3, 0x22, 0x22, 0x2f, 0x20, 0x0, + 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0x20, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0xe, 0x20, 0x0, + + /* U+5F0F "式" */ + 0x0, 0x0, 0x0, 0x0, 0xd, 0x35, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd, 0x40, 0x8d, 0x10, + 0x2, 0x22, 0x22, 0x22, 0x2d, 0x62, 0x27, 0x30, + 0x1e, 0xee, 0xee, 0xee, 0xef, 0xee, 0xee, 0xe2, + 0x0, 0x0, 0x0, 0x0, 0xa, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, + 0x8, 0xff, 0xff, 0xff, 0x86, 0xa0, 0x0, 0x0, + 0x0, 0x11, 0xa8, 0x11, 0x4, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x97, 0x0, 0x1, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0x97, 0x0, 0x0, 0xc5, 0x0, 0x0, + 0x0, 0x0, 0x97, 0x0, 0x10, 0x8a, 0x0, 0x84, + 0x0, 0x1, 0xbc, 0xbe, 0xd0, 0x2f, 0x10, 0xa5, + 0x9, 0xdf, 0xc8, 0x51, 0x0, 0x9, 0xc3, 0xd2, + 0x5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xa0, + + /* U+5F15 "引" */ + 0x1f, 0xff, 0xff, 0xfd, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0x3, 0xd0, 0x0, 0x1e, 0x0, 0x0, 0x0, + 0x3d, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x3, 0xd0, + 0x0, 0x1e, 0x8, 0xff, 0xff, 0xfd, 0x0, 0x1, + 0xe0, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x1e, 0xe, + 0x20, 0x0, 0x0, 0x0, 0x1, 0xe1, 0xf3, 0x33, + 0x33, 0x30, 0x0, 0x1e, 0x3c, 0xcc, 0xcc, 0xdd, + 0x0, 0x1, 0xe0, 0x0, 0x0, 0x5, 0xc0, 0x0, + 0x1e, 0x0, 0x0, 0x0, 0x6a, 0x0, 0x1, 0xe0, + 0x0, 0x0, 0x9, 0x80, 0x0, 0x1e, 0x0, 0x1, + 0x1, 0xe4, 0x0, 0x1, 0xe0, 0x2, 0xff, 0xfb, + 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+5F1F "弟" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x32, 0x0, 0x0, + 0xd, 0x60, 0x0, 0x0, 0xe5, 0x0, 0x0, 0x4, + 0xe0, 0x0, 0x7, 0xb0, 0x0, 0xe, 0xee, 0xfe, + 0xee, 0xef, 0xfe, 0xe2, 0x0, 0x0, 0x0, 0x5c, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x4c, 0x0, + 0x0, 0xe2, 0x1, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf2, 0x4, 0xc0, 0x0, 0x5c, 0x0, 0x0, 0x0, + 0x8, 0x80, 0x0, 0x4c, 0x0, 0x0, 0x0, 0xc, + 0xee, 0xee, 0xef, 0xee, 0xee, 0xec, 0x1, 0x11, + 0x17, 0xfc, 0x11, 0x11, 0x5c, 0x0, 0x0, 0x8d, + 0x6c, 0x0, 0x0, 0x6b, 0x0, 0x5d, 0xa0, 0x4c, + 0x0, 0x0, 0xa8, 0x6e, 0xd5, 0x0, 0x4c, 0x4, + 0xee, 0xe2, 0x35, 0x0, 0x0, 0x4c, 0x0, 0x11, + 0x0, + + /* U+5F31 "弱" */ + 0x9, 0xff, 0xff, 0xf4, 0x2f, 0xff, 0xff, 0xd0, + 0x0, 0x0, 0x0, 0xc4, 0x0, 0x0, 0x3, 0xd0, + 0x0, 0x0, 0x0, 0xc4, 0x0, 0x0, 0x3, 0xd0, + 0x0, 0xee, 0xee, 0xf4, 0xd, 0xee, 0xef, 0xd0, + 0x1, 0xf0, 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, + 0x2, 0xe0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, + 0x3, 0xfc, 0xcc, 0xc4, 0xf, 0xcc, 0xcc, 0xc0, + 0x0, 0x52, 0x22, 0xc5, 0x4, 0x32, 0x23, 0xf0, + 0x1, 0xcc, 0x50, 0xc4, 0xa, 0xd8, 0x12, 0xf0, + 0x0, 0x3, 0xb4, 0xd3, 0x0, 0x18, 0x94, 0xe0, + 0x0, 0x4, 0x9d, 0xf1, 0x0, 0x27, 0xcd, 0xc0, + 0xa, 0xeb, 0x52, 0xf0, 0x3d, 0xd7, 0x16, 0xb0, + 0x5, 0x10, 0x6, 0xc0, 0x13, 0x0, 0xa, 0x80, + 0x0, 0x8, 0xff, 0x50, 0x0, 0x8c, 0xde, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, + + /* U+5F35 "張" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2f, 0xff, 0xf5, 0xb, 0xed, 0xdd, 0xdd, 0xb0, + 0x0, 0x0, 0xa5, 0xb, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa5, 0xb, 0xca, 0xaa, 0xaa, 0x20, + 0x2, 0x22, 0xb5, 0xb, 0x73, 0x33, 0x33, 0x0, + 0xd, 0xff, 0xf5, 0xb, 0x50, 0x0, 0x0, 0x0, + 0xd, 0x31, 0x10, 0xb, 0xdc, 0xcc, 0xcc, 0x30, + 0xe, 0x10, 0x0, 0x1b, 0x61, 0x11, 0x11, 0x10, + 0xf, 0xbb, 0xb5, 0xbf, 0xbe, 0xdb, 0xbb, 0xb1, + 0x3, 0x33, 0xc4, 0x1e, 0x3, 0xc0, 0x6, 0x40, + 0x0, 0x0, 0xc3, 0x1e, 0x0, 0xb7, 0x8c, 0x10, + 0x0, 0x0, 0xd2, 0x1e, 0x0, 0x1e, 0xb0, 0x0, + 0x0, 0x0, 0xf1, 0x1e, 0x0, 0x23, 0xe5, 0x0, + 0x0, 0x3, 0xe0, 0x2f, 0x9e, 0x70, 0x3e, 0xa1, + 0x9, 0xff, 0x60, 0x5c, 0x50, 0x0, 0x1, 0x91, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5F37 "強" */ + 0x0, 0x0, 0x0, 0x0, 0x9, 0x30, 0x0, 0x0, + 0xf, 0xff, 0xfc, 0x0, 0x4d, 0x0, 0x20, 0x0, + 0x0, 0x0, 0x2c, 0x0, 0xd4, 0x1, 0xd1, 0x0, + 0x0, 0x0, 0x2c, 0x9, 0x80, 0x2, 0x9c, 0x0, + 0x0, 0x0, 0x2c, 0x5f, 0xef, 0xed, 0xbd, 0x60, + 0x9, 0xee, 0xfc, 0x13, 0x10, 0xc1, 0x2, 0x80, + 0xc, 0x52, 0x22, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0xe, 0x10, 0x0, 0x3f, 0xee, 0xfe, 0xef, 0x30, + 0xf, 0x54, 0x44, 0x3b, 0x0, 0xf1, 0xb, 0x30, + 0x19, 0x99, 0xae, 0x3b, 0x0, 0xf1, 0xb, 0x30, + 0x0, 0x0, 0x3d, 0x3f, 0xee, 0xfe, 0xef, 0x30, + 0x0, 0x0, 0x4c, 0x0, 0x0, 0xf1, 0x32, 0x0, + 0x0, 0x0, 0x6a, 0x0, 0x0, 0xf1, 0x5d, 0x0, + 0x0, 0x0, 0xa7, 0x0, 0x12, 0xf6, 0x6f, 0x70, + 0x0, 0xef, 0xc1, 0xdf, 0xdb, 0x98, 0x64, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+5F53 "当" */ + 0x3, 0x0, 0x0, 0xc5, 0x0, 0x2, 0x40, 0xa, + 0x80, 0x0, 0xc5, 0x0, 0xa, 0xa0, 0x0, 0xe3, + 0x0, 0xc5, 0x0, 0x3e, 0x10, 0x0, 0x6c, 0x0, + 0xc5, 0x0, 0xd5, 0x0, 0x0, 0x1, 0x0, 0xc5, + 0x0, 0x30, 0x0, 0xc, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xd0, 0x1, 0x11, 0x11, 0x11, 0x11, 0x15, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xd0, + 0x0, 0x11, 0x11, 0x11, 0x11, 0x15, 0xd0, 0x4, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0xd0, 0x4, 0x44, 0x44, 0x44, + 0x44, 0x48, 0xd0, 0x1c, 0xcc, 0xcc, 0xcc, 0xcc, + 0xcd, 0xd0, + + /* U+5F62 "形" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x50, + 0xd, 0xff, 0xff, 0xff, 0xf5, 0x0, 0x6e, 0x20, + 0x0, 0xf, 0x10, 0x3d, 0x0, 0x7, 0xe3, 0x0, + 0x0, 0xf, 0x0, 0x3d, 0x2, 0xcd, 0x20, 0x0, + 0x0, 0xf, 0x0, 0x3d, 0x2, 0x90, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x3d, 0x0, 0x0, 0x2, 0xa0, + 0x0, 0xf, 0x10, 0x4d, 0x0, 0x0, 0x2e, 0x50, + 0x1f, 0xff, 0xff, 0xff, 0xf9, 0x4, 0xe6, 0x0, + 0x0, 0xf, 0x0, 0x3d, 0x0, 0x9d, 0x30, 0x0, + 0x0, 0x1f, 0x0, 0x3d, 0x1, 0x80, 0x0, 0x21, + 0x0, 0x3c, 0x0, 0x3d, 0x0, 0x0, 0x1, 0xe4, + 0x0, 0x79, 0x0, 0x3d, 0x0, 0x0, 0x2d, 0x70, + 0x0, 0xe3, 0x0, 0x3d, 0x0, 0x4, 0xe6, 0x0, + 0x7, 0xc0, 0x0, 0x3d, 0x2, 0xac, 0x30, 0x0, + 0xc, 0x20, 0x0, 0x3d, 0xc, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5F71 "影" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + 0x3, 0xfb, 0xbb, 0xbc, 0xe0, 0x0, 0x3e, 0x30, + 0x3, 0xc0, 0x0, 0x2, 0xe0, 0x2, 0xe6, 0x0, + 0x3, 0xfb, 0xbb, 0xbc, 0xe0, 0x4e, 0x70, 0x0, + 0x3, 0xc0, 0x0, 0x3, 0xe3, 0xf5, 0x0, 0x0, + 0x2, 0xaa, 0xcc, 0xaa, 0x90, 0x10, 0x1, 0x50, + 0x5, 0x55, 0xac, 0x55, 0x52, 0x0, 0x2d, 0x50, + 0x6, 0x66, 0x66, 0x66, 0x63, 0x6, 0xe4, 0x0, + 0x1, 0xcc, 0xcc, 0xcc, 0x92, 0xcb, 0x20, 0x0, + 0x1, 0xe0, 0x0, 0x5, 0xb0, 0x40, 0x0, 0x20, + 0x1, 0xfb, 0xbb, 0xbc, 0xb0, 0x0, 0x3, 0xe1, + 0x0, 0x52, 0x4c, 0x26, 0x0, 0x0, 0x2e, 0x40, + 0x1, 0xe1, 0x3c, 0xc, 0x30, 0x5, 0xe5, 0x0, + 0xc, 0x60, 0x4c, 0x3, 0xc2, 0xbe, 0x30, 0x0, + 0x3, 0xa, 0xe8, 0x0, 0x1a, 0x91, 0x0, 0x0, + + /* U+5F79 "役" */ + 0x0, 0x1, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x70, 0xe, 0xff, 0xff, 0x40, 0x0, + 0x0, 0xba, 0x0, 0xe, 0x10, 0xc, 0x40, 0x0, + 0x1d, 0x90, 0x0, 0xf, 0x0, 0xc, 0x40, 0x0, + 0x5, 0x2, 0xd0, 0x4e, 0x0, 0xc, 0x40, 0x0, + 0x0, 0xb, 0x82, 0xe7, 0x0, 0xa, 0xdb, 0xa0, + 0x0, 0x6f, 0x2f, 0xb0, 0x0, 0x0, 0x33, 0x30, + 0x4, 0xff, 0x6, 0x11, 0x11, 0x11, 0x10, 0x0, + 0x3f, 0x8f, 0x9, 0xfe, 0xee, 0xee, 0xfb, 0x0, + 0x15, 0x1f, 0x0, 0xa8, 0x0, 0x1, 0xe2, 0x0, + 0x0, 0x1f, 0x0, 0x1e, 0x30, 0xb, 0x90, 0x0, + 0x0, 0x1f, 0x0, 0x3, 0xe5, 0xba, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x8f, 0xd1, 0x0, 0x0, + 0x0, 0x1f, 0x2, 0x7d, 0xb4, 0x9e, 0x83, 0x0, + 0x0, 0x1f, 0x7d, 0x83, 0x0, 0x2, 0x8d, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5F7C "彼" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xb0, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0x6e, 0x10, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x9, 0xd2, 0x0, 0xef, 0xff, 0xff, 0xff, 0xe0, + 0x9, 0x11, 0xb0, 0xe2, 0x1, 0xe0, 0x6, 0xa0, + 0x0, 0xa, 0x90, 0xe2, 0x1, 0xe0, 0xb, 0x50, + 0x0, 0x6f, 0x10, 0xe2, 0x2, 0xe0, 0x4, 0x0, + 0x5, 0xfe, 0x0, 0xef, 0xfe, 0xee, 0xef, 0x20, + 0x3f, 0x7e, 0x0, 0xf6, 0xb0, 0x0, 0x4c, 0x0, + 0x3, 0x2e, 0x1, 0xf0, 0xd3, 0x0, 0xc5, 0x0, + 0x0, 0x2e, 0x2, 0xd0, 0x4d, 0x16, 0xc0, 0x0, + 0x0, 0x2e, 0x6, 0xb0, 0x7, 0xce, 0x10, 0x0, + 0x0, 0x2e, 0xa, 0x60, 0x7, 0xfd, 0x30, 0x0, + 0x0, 0x2e, 0x2e, 0x15, 0xcb, 0x15, 0xe9, 0x30, + 0x0, 0x2e, 0x46, 0x6b, 0x40, 0x0, 0x17, 0xc1, + + /* U+5F80 "往" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x8, 0xb0, 0x0, 0x1e, 0x20, 0x0, 0x0, + 0x0, 0x5e, 0x10, 0x0, 0x7, 0xb0, 0x0, 0x0, + 0x7, 0xe2, 0x1, 0x22, 0x23, 0xb2, 0x22, 0x10, + 0x1b, 0x10, 0x67, 0xee, 0xee, 0xfe, 0xee, 0xc0, + 0x0, 0x8, 0xc0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x5f, 0x10, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x7, 0xff, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x4e, 0x4f, 0x0, 0xbc, 0xcd, 0xfc, 0xcc, 0x40, + 0x2, 0x1f, 0x0, 0x33, 0x37, 0xc3, 0x33, 0x10, + 0x0, 0x1f, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x5, 0xc0, 0x0, 0x0, + 0x0, 0x1f, 0xe, 0xff, 0xff, 0xff, 0xff, 0xf4, + + /* U+5F85 "待" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xb0, 0x0, 0x6, 0xa0, 0x0, 0x0, + 0x0, 0x4e, 0x10, 0x11, 0x17, 0xa1, 0x11, 0x0, + 0x7, 0xe3, 0x0, 0xee, 0xef, 0xfe, 0xee, 0x50, + 0x1b, 0x10, 0x80, 0x0, 0x6, 0xa0, 0x0, 0x0, + 0x0, 0x8, 0xb0, 0x0, 0x6, 0xa0, 0x0, 0x0, + 0x0, 0x4f, 0x2d, 0xee, 0xee, 0xee, 0xfe, 0xe3, + 0x3, 0xff, 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x3f, 0x6f, 0x0, 0x11, 0x11, 0x13, 0xe1, 0x10, + 0x16, 0xf, 0xa, 0xee, 0xee, 0xee, 0xfe, 0xe1, + 0x0, 0xf, 0x0, 0x16, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0xf, 0x0, 0xd, 0x60, 0x2, 0xe0, 0x0, + 0x0, 0xf, 0x0, 0x2, 0xe2, 0x2, 0xe0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x20, 0x3, 0xe0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x6, 0xff, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5F88 "很" */ + 0x0, 0x2, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x60, 0xcf, 0xee, 0xee, 0xfe, 0x0, + 0x1, 0xc9, 0x0, 0xc3, 0x0, 0x0, 0x2e, 0x0, + 0x1d, 0x90, 0x0, 0xc3, 0x0, 0x0, 0x2e, 0x0, + 0x5, 0x2, 0xd0, 0xce, 0xee, 0xee, 0xee, 0x0, + 0x0, 0xc, 0x80, 0xc3, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x9f, 0x0, 0xc3, 0x0, 0x0, 0x2e, 0x0, + 0x9, 0xef, 0x0, 0xce, 0xee, 0xee, 0xee, 0x0, + 0x5e, 0x2f, 0x0, 0xc4, 0xe, 0x20, 0x1, 0x10, + 0x1, 0xf, 0x0, 0xc3, 0x8, 0x90, 0x4e, 0x60, + 0x0, 0xf, 0x0, 0xc3, 0x1, 0xe9, 0xd3, 0x0, + 0x0, 0xf, 0x0, 0xc3, 0x0, 0x7e, 0x10, 0x0, + 0x0, 0xf, 0x0, 0xc3, 0x1, 0xb, 0xc1, 0x0, + 0x0, 0xf, 0x0, 0xeb, 0xde, 0x20, 0xae, 0x70, + 0x0, 0xf, 0x1, 0xd8, 0x30, 0x0, 0x4, 0xb1, + + /* U+5F8B "律" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xc0, 0x0, 0x8, 0x80, 0x0, 0x0, + 0x0, 0x6e, 0x20, 0xce, 0xef, 0xfe, 0xee, 0x10, + 0x9, 0xe3, 0x0, 0x0, 0x8, 0x80, 0xe, 0x10, + 0xc, 0x20, 0x82, 0x11, 0x18, 0x91, 0x1e, 0x30, + 0x0, 0x9, 0xb9, 0xdd, 0xde, 0xed, 0xdf, 0xd4, + 0x0, 0x5f, 0x10, 0x0, 0x8, 0x80, 0xe, 0x10, + 0x6, 0xef, 0x0, 0xee, 0xef, 0xfe, 0xef, 0x10, + 0x4e, 0x3f, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, + 0x1, 0xf, 0x2, 0xdd, 0xde, 0xed, 0xdd, 0x40, + 0x0, 0xf, 0x0, 0x11, 0x18, 0x91, 0x11, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, + 0x0, 0xf, 0xd, 0xee, 0xef, 0xfe, 0xee, 0xe2, + 0x0, 0xf, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, + + /* U+5F8C "後" */ + 0x0, 0x0, 0x30, 0x0, 0x3, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x80, 0x0, 0x6d, 0x10, 0x0, 0x0, + 0x0, 0x8b, 0x0, 0x5, 0xd1, 0x1, 0xa2, 0x0, + 0xa, 0xb0, 0x0, 0x7c, 0x10, 0x2d, 0x60, 0x0, + 0x7, 0x1, 0xe5, 0xfe, 0xdf, 0xc2, 0x30, 0x0, + 0x0, 0xc, 0x60, 0x3, 0xb6, 0x0, 0xb6, 0x0, + 0x0, 0x8e, 0x4, 0xbf, 0x98, 0x9a, 0xcf, 0x30, + 0x9, 0xde, 0x5, 0x87, 0xcb, 0x32, 0x13, 0xe0, + 0x3e, 0x3e, 0x0, 0x5, 0xf2, 0x0, 0x0, 0x50, + 0x1, 0x1e, 0x0, 0x4f, 0xed, 0xdd, 0xfa, 0x0, + 0x0, 0x1e, 0x7, 0xfb, 0x90, 0x2, 0xe2, 0x0, + 0x0, 0x1e, 0x1a, 0x20, 0x99, 0x4d, 0x40, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x2e, 0xf8, 0x0, 0x0, + 0x0, 0x1e, 0x1, 0x5b, 0xe7, 0x4b, 0xd7, 0x20, + 0x0, 0x1e, 0x2d, 0x94, 0x0, 0x0, 0x38, 0xd4, + + /* U+5F92 "徒" */ + 0x0, 0x8, 0x70, 0x0, 0x6, 0x90, 0x0, 0x0, + 0x0, 0x6c, 0x0, 0x0, 0x6, 0xa0, 0x0, 0x0, + 0x8, 0xc1, 0x1, 0xee, 0xef, 0xfe, 0xee, 0x60, + 0x29, 0x2, 0xc0, 0x0, 0x6, 0x90, 0x0, 0x0, + 0x0, 0xd, 0x60, 0x0, 0x6, 0x90, 0x0, 0x0, + 0x0, 0xae, 0xe, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x1c, 0xce, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0x69, 0x1e, 0x0, 0x84, 0x4, 0xb0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0xd3, 0x4, 0xeb, 0xbb, 0x60, + 0x0, 0x1e, 0x0, 0xf2, 0x4, 0xc3, 0x33, 0x10, + 0x0, 0x1e, 0x2, 0xf7, 0x4, 0xb0, 0x0, 0x0, + 0x0, 0x1e, 0x7, 0x8d, 0x44, 0xb0, 0x0, 0x0, + 0x0, 0x1e, 0x1d, 0x13, 0xec, 0xc1, 0x0, 0x0, + 0x0, 0x1e, 0x76, 0x0, 0x18, 0xde, 0xff, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5F93 "従" */ + 0x0, 0x2, 0x60, 0x5, 0x0, 0x0, 0x7, 0x0, + 0x0, 0x1d, 0x50, 0xc, 0x50, 0x0, 0x5d, 0x0, + 0x1, 0xc7, 0x0, 0x4, 0xd0, 0x0, 0xc5, 0x0, + 0x2e, 0x60, 0x30, 0x0, 0xc3, 0x2, 0xc0, 0x0, + 0x3, 0x3, 0xe2, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0xd, 0x50, 0x11, 0x12, 0xf1, 0x11, 0x10, + 0x0, 0xae, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x9, 0xee, 0x0, 0x25, 0x0, 0xf0, 0x0, 0x0, + 0x6d, 0x3e, 0x0, 0x6a, 0x0, 0xf3, 0x33, 0x20, + 0x11, 0x1e, 0x0, 0x87, 0x0, 0xfc, 0xcc, 0x80, + 0x0, 0x1e, 0x0, 0xb7, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0xec, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x1e, 0x5, 0xcb, 0x71, 0xf0, 0x0, 0x0, + 0x0, 0x1e, 0xc, 0x51, 0xdb, 0xf0, 0x0, 0x0, + 0x0, 0x1e, 0x59, 0x0, 0x8, 0xdf, 0xff, 0xf4, + + /* U+5F97 "得" */ + 0x0, 0x1, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x80, 0x8e, 0xdd, 0xdd, 0xdf, 0x0, + 0x0, 0xaa, 0x0, 0x87, 0x0, 0x0, 0xf, 0x0, + 0x1c, 0x90, 0x0, 0x8e, 0xcc, 0xcc, 0xcf, 0x0, + 0x6, 0x2, 0xc0, 0x87, 0x0, 0x0, 0xf, 0x0, + 0x0, 0xc, 0x70, 0x8d, 0xaa, 0xaa, 0xaf, 0x0, + 0x0, 0x9f, 0x0, 0x12, 0x22, 0x22, 0x22, 0x0, + 0xa, 0xef, 0x6, 0xbb, 0xbb, 0xbb, 0xbb, 0xa0, + 0x7e, 0x3f, 0x1, 0x33, 0x33, 0x37, 0xc3, 0x20, + 0x12, 0x1f, 0x0, 0x0, 0x0, 0x5, 0xa0, 0x0, + 0x0, 0x1f, 0xd, 0xee, 0xee, 0xef, 0xfe, 0xe2, + 0x0, 0x1f, 0x0, 0x28, 0x0, 0x5, 0xa0, 0x0, + 0x0, 0x1f, 0x0, 0x9, 0xa0, 0x5, 0xa0, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x81, 0x6, 0xa0, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x7, 0xfe, 0x60, 0x0, + + /* U+5F9E "從" */ + 0x0, 0x1, 0x40, 0x1, 0x60, 0x0, 0x61, 0x0, + 0x0, 0xd, 0x60, 0x7, 0xa0, 0x1, 0xf0, 0x0, + 0x0, 0xb8, 0x0, 0xc, 0x60, 0x6, 0xc0, 0x0, + 0x2d, 0x80, 0x20, 0x1f, 0xa0, 0xb, 0xd1, 0x0, + 0x15, 0x3, 0xe1, 0x99, 0x9b, 0x3e, 0x8d, 0x10, + 0x0, 0xd, 0x55, 0xe1, 0x7, 0xe5, 0x7, 0xd1, + 0x0, 0xae, 0xc, 0x40, 0x4, 0xa0, 0x0, 0x82, + 0xa, 0xde, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x6c, 0x2e, 0x0, 0x4b, 0x1, 0xe0, 0x0, 0x0, + 0x11, 0x1e, 0x0, 0x5a, 0x1, 0xe2, 0x22, 0x10, + 0x0, 0x1e, 0x0, 0x89, 0x1, 0xfc, 0xcc, 0x70, + 0x0, 0x1e, 0x0, 0xce, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0x1e, 0x2, 0xe9, 0x81, 0xe0, 0x0, 0x0, + 0x0, 0x1e, 0xc, 0x70, 0xdb, 0xe1, 0x0, 0x0, + 0x0, 0x1e, 0x4a, 0x0, 0x8, 0xdf, 0xff, 0xf3, + + /* U+5FA1 "御" */ + 0x0, 0x26, 0x4, 0x40, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x50, 0xa5, 0x0, 0x0, 0x66, 0x65, 0xa, + 0xa0, 0xf, 0xed, 0xdd, 0x1f, 0x99, 0xe8, 0xc0, + 0x36, 0xa1, 0xf1, 0x10, 0xe0, 0x1e, 0x20, 0x3e, + 0xd2, 0xe, 0x0, 0xe, 0x1, 0xe0, 0xc, 0x71, + 0x0, 0xf0, 0x0, 0xe0, 0x1e, 0x6, 0xf2, 0xbe, + 0xef, 0xfe, 0x2e, 0x1, 0xe3, 0xff, 0x20, 0x0, + 0xe0, 0x0, 0xe0, 0x1e, 0xb6, 0xc2, 0x37, 0xe, + 0x0, 0xe, 0x1, 0xe1, 0xc, 0x24, 0x90, 0xef, + 0xf1, 0xe0, 0x1e, 0x0, 0xc2, 0x49, 0xe, 0x0, + 0xe, 0x1, 0xe0, 0xc, 0x24, 0x90, 0xe0, 0x0, + 0xe1, 0x3d, 0x0, 0xc2, 0x49, 0xf, 0x46, 0x6e, + 0x4c, 0x60, 0xc, 0x3c, 0xfd, 0xb9, 0x73, 0xe0, + 0x0, 0x0, 0xc2, 0x20, 0x0, 0x0, 0xe, 0x0, + 0x0, + + /* U+5FA9 "復" */ + 0x0, 0x1, 0x50, 0x4, 0x40, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x60, 0xd, 0x50, 0x0, 0x0, 0x0, + 0x0, 0xb9, 0x0, 0x5f, 0xee, 0xee, 0xee, 0xe2, + 0x1d, 0x80, 0x11, 0xe5, 0x0, 0x0, 0x0, 0x0, + 0x16, 0x2, 0xed, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, + 0x0, 0xd, 0x63, 0x2e, 0x0, 0x0, 0xe, 0x10, + 0x0, 0xae, 0x0, 0x1f, 0xbb, 0xbb, 0xbf, 0x10, + 0xb, 0xde, 0x0, 0x1e, 0x0, 0x0, 0xe, 0x10, + 0x6b, 0x2e, 0x0, 0x1d, 0xdd, 0xcc, 0xcd, 0x10, + 0x0, 0x1e, 0x0, 0x1, 0xd4, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x1c, 0xec, 0xcc, 0xed, 0x0, + 0x0, 0x1e, 0x4, 0xe8, 0xc3, 0x2, 0xd3, 0x0, + 0x0, 0x1e, 0x5, 0x30, 0x1c, 0xad, 0x30, 0x0, + 0x0, 0x1e, 0x0, 0x25, 0xad, 0xad, 0x94, 0x10, + 0x0, 0x1e, 0xb, 0xb8, 0x40, 0x0, 0x59, 0xd3, + + /* U+5FC3 "心" */ + 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9d, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xf6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3e, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x2d, 0x0, 0x2, 0x30, 0x0, 0x0, + 0x0, 0x72, 0x2e, 0x0, 0x0, 0x0, 0x3c, 0x0, + 0x0, 0xe2, 0x2e, 0x0, 0x0, 0x0, 0xe, 0x30, + 0x1, 0xf0, 0x2e, 0x0, 0x0, 0x0, 0x8, 0xa0, + 0x4, 0xd0, 0x2e, 0x0, 0x0, 0x0, 0x2, 0xf0, + 0x9, 0x90, 0x2e, 0x0, 0x0, 0x1, 0x10, 0xd4, + 0xe, 0x50, 0x2e, 0x0, 0x0, 0x4, 0xc0, 0x99, + 0x9, 0x0, 0x2e, 0x0, 0x0, 0x5, 0xa0, 0x11, + 0x0, 0x0, 0x2f, 0x20, 0x0, 0xa, 0x70, 0x0, + 0x0, 0x0, 0xa, 0xff, 0xff, 0xfc, 0x10, 0x0, + + /* U+5FC5 "必" */ + 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9, 0xd3, 0x0, 0x0, 0x25, 0x0, + 0x0, 0x0, 0x0, 0x5e, 0x80, 0x0, 0xb9, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xd9, 0x5, 0xe0, 0x0, + 0x0, 0x0, 0x9, 0x0, 0x1, 0x1e, 0x50, 0x0, + 0x0, 0x52, 0xf, 0x10, 0x0, 0xb9, 0x0, 0x0, + 0x0, 0xd3, 0xf, 0x10, 0x9, 0xc0, 0xb6, 0x0, + 0x2, 0xe0, 0xf, 0x10, 0x7d, 0x10, 0x3e, 0x10, + 0x7, 0xa0, 0xf, 0x17, 0xe2, 0x0, 0xa, 0x90, + 0xe, 0x30, 0xf, 0xad, 0x20, 0x0, 0x2, 0xf1, + 0x4c, 0x0, 0x1f, 0xc1, 0x0, 0x0, 0x0, 0xc7, + 0x0, 0x7, 0xff, 0x10, 0x0, 0x4, 0xb0, 0x31, + 0x4, 0xdd, 0x4f, 0x10, 0x0, 0x5, 0xb0, 0x0, + 0x2e, 0x60, 0xf, 0x41, 0x0, 0x1a, 0x80, 0x0, + 0x0, 0x0, 0x8, 0xff, 0xff, 0xfc, 0x10, 0x0, + + /* U+5FD8 "忘" */ + 0x0, 0x0, 0x0, 0x8, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, + 0xb, 0xcc, 0xcc, 0xcd, 0xfc, 0xcc, 0xcc, 0xa0, + 0x2, 0x3d, 0x63, 0x33, 0x33, 0x33, 0x33, 0x20, + 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1d, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x62, 0x76, 0x1, 0xe4, 0x0, 0x59, 0x0, + 0x0, 0xe1, 0x87, 0x0, 0x49, 0x0, 0xe, 0x30, + 0x7, 0xa0, 0x87, 0x0, 0x0, 0x6, 0x47, 0xb0, + 0x1e, 0x20, 0x89, 0x0, 0x0, 0xb, 0x61, 0xf1, + 0x2, 0x0, 0x3e, 0xff, 0xff, 0xfc, 0x10, 0x10, + + /* U+5FD9 "忙" */ + 0x0, 0x1e, 0x0, 0x0, 0x6, 0x80, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0xd6, 0x0, 0x0, + 0x2, 0x1e, 0x70, 0x0, 0x0, 0x35, 0x0, 0x0, + 0xb, 0x3e, 0x77, 0xff, 0xff, 0xff, 0xff, 0xf6, + 0xd, 0x1e, 0x1d, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x1c, 0x1e, 0x4, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x48, 0x1e, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x6, 0xfe, 0xee, 0xee, 0xd0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5FEB "快" */ + 0x0, 0x2e, 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, + 0x4, 0x3f, 0xb0, 0xdf, 0xff, 0xff, 0xfd, 0x0, + 0xb, 0x4e, 0x95, 0x0, 0xb, 0x50, 0x3d, 0x0, + 0xd, 0x2e, 0x4c, 0x0, 0xb, 0x50, 0x2d, 0x0, + 0x1c, 0x2e, 0x2, 0x0, 0xb, 0x40, 0x2d, 0x0, + 0x48, 0x2e, 0x0, 0x0, 0xc, 0x40, 0x2e, 0x0, + 0x0, 0x2e, 0xe, 0xff, 0xff, 0xff, 0xff, 0xf4, + 0x0, 0x2e, 0x0, 0x0, 0x1f, 0xe0, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x7a, 0xa7, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0x1, 0xe3, 0x2e, 0x20, 0x0, + 0x0, 0x2e, 0x0, 0xc, 0x80, 0x8, 0xd1, 0x0, + 0x0, 0x2e, 0x3, 0xd9, 0x0, 0x0, 0x9e, 0x50, + 0x0, 0x2e, 0x1d, 0x50, 0x0, 0x0, 0x6, 0xd2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+5FF5 "念" */ + 0x0, 0x0, 0x0, 0xa, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xbc, 0xd2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2d, 0x80, 0x5e, 0x60, 0x0, 0x0, + 0x0, 0x18, 0xe5, 0x46, 0x2, 0xcc, 0x40, 0x0, + 0x18, 0xfa, 0x20, 0x1a, 0xb0, 0x6, 0xec, 0x60, + 0x4a, 0x20, 0x0, 0x0, 0x50, 0x0, 0x6, 0x80, + 0x0, 0x6f, 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x40, 0x3, 0xe2, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xd7, 0x1e, 0x40, 0x0, 0x0, + 0x0, 0x90, 0xc2, 0x1d, 0x51, 0x0, 0xd1, 0x0, + 0x4, 0xc0, 0xd2, 0x3, 0xe0, 0x0, 0x7b, 0x0, + 0xa, 0x60, 0xd2, 0x0, 0x0, 0x9, 0x1d, 0x40, + 0x2e, 0x0, 0xd4, 0x0, 0x0, 0x2f, 0x5, 0xc0, + 0x25, 0x0, 0x7f, 0xff, 0xff, 0xf8, 0x0, 0x30, + + /* U+600E "怎" */ + 0x0, 0x0, 0x72, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xfd, 0xdd, 0xdd, 0xdd, 0xdd, 0xa0, + 0x0, 0x1e, 0x31, 0x6c, 0x11, 0x11, 0x11, 0x10, + 0x0, 0xa8, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xc0, 0x0, 0x4f, 0xee, 0xee, 0xee, 0x0, + 0x9, 0x10, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4f, 0xee, 0xee, 0xee, 0x50, + 0x0, 0x0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x50, 0x61, 0x2d, 0xa0, 0x0, 0x84, 0x0, + 0x1, 0xe0, 0xd3, 0x0, 0xbb, 0x0, 0x6c, 0x0, + 0x6, 0xa0, 0xd3, 0x0, 0x4, 0x5, 0x3d, 0x50, + 0xe, 0x30, 0xc4, 0x0, 0x0, 0xb, 0x56, 0xd0, + 0x6, 0x0, 0x7e, 0xff, 0xff, 0xfc, 0x0, 0x60, + + /* U+6012 "怒" */ + 0x0, 0x1, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xa0, 0x0, 0xff, 0xff, 0xff, 0x60, + 0xb, 0xbe, 0xdb, 0xc7, 0x3b, 0x0, 0xd, 0x20, + 0x3, 0x8d, 0x33, 0xb5, 0xe, 0x20, 0x4d, 0x0, + 0x0, 0xd5, 0x0, 0xe0, 0x8, 0x90, 0xc6, 0x0, + 0x3, 0xf6, 0x9, 0x80, 0x0, 0xea, 0xb0, 0x0, + 0x0, 0x2a, 0xef, 0x10, 0x0, 0x9f, 0x40, 0x0, + 0x0, 0x7, 0xed, 0xb1, 0x1a, 0xc8, 0xe5, 0x0, + 0x6, 0xdb, 0x10, 0x82, 0xe7, 0x0, 0x4e, 0xc2, + 0x6, 0x30, 0x0, 0x78, 0x10, 0x0, 0x0, 0x50, + 0x0, 0x23, 0x19, 0x9, 0xe4, 0x0, 0x81, 0x0, + 0x0, 0x98, 0x2e, 0x0, 0x49, 0x0, 0x8b, 0x0, + 0x2, 0xf1, 0x2e, 0x0, 0x0, 0x39, 0xc, 0x70, + 0xc, 0x70, 0x2f, 0x0, 0x0, 0x6a, 0x3, 0xf1, + 0x7, 0x0, 0xb, 0xff, 0xff, 0xe4, 0x0, 0x61, + + /* U+6015 "怕" */ + 0x0, 0xf, 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0x0, 0xf0, 0x0, 0x0, 0x1f, 0x10, 0x0, 0x0, + 0xf, 0x52, 0x4, 0x48, 0xd4, 0x44, 0x40, 0x93, + 0xf6, 0xa1, 0xfb, 0xbb, 0xbb, 0xce, 0xc, 0x1f, + 0x1d, 0x3f, 0x0, 0x0, 0x2, 0xe0, 0xd0, 0xf0, + 0x32, 0xf0, 0x0, 0x0, 0x2e, 0x28, 0xf, 0x0, + 0x1f, 0x0, 0x0, 0x2, 0xe0, 0x0, 0xf0, 0x1, + 0xfe, 0xee, 0xee, 0xee, 0x0, 0xf, 0x0, 0x1f, + 0x11, 0x11, 0x13, 0xe0, 0x0, 0xf0, 0x1, 0xf0, + 0x0, 0x0, 0x2e, 0x0, 0xf, 0x0, 0x1f, 0x0, + 0x0, 0x2, 0xe0, 0x0, 0xf0, 0x1, 0xf0, 0x0, + 0x0, 0x2e, 0x0, 0xf, 0x0, 0x1f, 0xdd, 0xdd, + 0xde, 0xe0, 0x0, 0xf0, 0x1, 0xf2, 0x22, 0x22, + 0x4d, + + /* U+601D "思" */ + 0x0, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xf5, 0x0, + 0xd, 0x20, 0x0, 0xe2, 0x0, 0xb, 0x50, 0x0, + 0xd2, 0x0, 0xe, 0x20, 0x0, 0xb5, 0x0, 0xd, + 0xdc, 0xcc, 0xfd, 0xcc, 0xcf, 0x50, 0x0, 0xd3, + 0x11, 0x1e, 0x31, 0x11, 0xb5, 0x0, 0xd, 0x20, + 0x0, 0xe2, 0x0, 0xb, 0x50, 0x0, 0xdc, 0xbb, + 0xbf, 0xcb, 0xbb, 0xe5, 0x0, 0x3, 0x33, 0x36, + 0x33, 0x33, 0x33, 0x10, 0x0, 0x0, 0x1, 0xda, + 0x10, 0x0, 0x0, 0x0, 0x9, 0x1a, 0x30, 0x9e, + 0x30, 0x1d, 0x10, 0x2, 0xe0, 0xc4, 0x0, 0x69, + 0x0, 0x8b, 0x0, 0x89, 0xc, 0x40, 0x0, 0x3, + 0xa0, 0xe4, 0x2f, 0x20, 0xc5, 0x0, 0x0, 0x7a, + 0x7, 0xb0, 0x40, 0x7, 0xef, 0xff, 0xfe, 0x30, + 0x2, + + /* U+6025 "急" */ + 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7d, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xfe, 0xee, 0xef, 0xc0, 0x0, 0x0, + 0x0, 0x8e, 0x30, 0x0, 0x2d, 0x20, 0x0, 0x0, + 0x1c, 0xfe, 0xdd, 0xdd, 0xef, 0xdd, 0xc0, 0x0, + 0x8, 0x0, 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0x1, 0x11, 0x11, 0x11, 0x13, 0xe0, 0x0, + 0x0, 0x1b, 0xbb, 0xbb, 0xbb, 0xbc, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0x9e, 0xee, 0xee, 0xee, 0xee, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x3a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa0, 0xd2, 0xa, 0xa0, 0x0, 0x99, 0x0, + 0x6, 0xb0, 0xe2, 0x0, 0xc6, 0x8, 0x1e, 0x30, + 0x1e, 0x30, 0xe3, 0x0, 0x10, 0x2f, 0x6, 0xb0, + 0x16, 0x0, 0x8f, 0xff, 0xff, 0xf8, 0x0, 0x40, + + /* U+6027 "性" */ + 0x0, 0x2e, 0x0, 0x3, 0x10, 0xe0, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0xd, 0x30, 0xf0, 0x0, 0x0, + 0x3, 0x3e, 0x80, 0x1f, 0x0, 0xf0, 0x0, 0x0, + 0xc, 0x3e, 0x86, 0x5f, 0xff, 0xff, 0xff, 0xc0, + 0xd, 0x2e, 0x1d, 0xc5, 0x1, 0xf1, 0x0, 0x0, + 0x1c, 0x2e, 0x6, 0xd0, 0x0, 0xf0, 0x0, 0x0, + 0x58, 0x2e, 0x3, 0x50, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0x24, 0x44, 0xf5, 0x44, 0x10, + 0x0, 0x2e, 0x0, 0x5b, 0xbb, 0xfb, 0xbb, 0x50, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x2e, 0x1, 0x22, 0x22, 0xf2, 0x22, 0x20, + 0x0, 0x2e, 0xa, 0xee, 0xee, 0xee, 0xee, 0xe1, + + /* U+606F "息" */ + 0x0, 0x0, 0x0, 0x4, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x50, 0x0, 0x0, 0x0, + 0x0, 0xd, 0xed, 0xef, 0xed, 0xde, 0xd0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0xe, 0xdd, 0xdd, 0xdd, 0xdd, 0xe0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0xe, 0xba, 0xaa, 0xaa, 0xab, 0xe0, 0x0, + 0x0, 0xe, 0x32, 0x22, 0x22, 0x24, 0xe0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0xc, 0xdd, 0xde, 0xdd, 0xdd, 0xc0, 0x0, + 0x0, 0x0, 0x20, 0xd, 0x40, 0x0, 0x12, 0x0, + 0x0, 0xe1, 0xd3, 0x2, 0xe4, 0x0, 0x5d, 0x0, + 0x6, 0xb0, 0xd3, 0x0, 0x45, 0x7, 0x2b, 0x80, + 0xe, 0x30, 0xd5, 0x0, 0x0, 0x1d, 0x33, 0xe0, + 0x5, 0x0, 0x7e, 0xff, 0xff, 0xfb, 0x0, 0x0, + + /* U+60A8 "您" */ + 0x0, 0x0, 0x51, 0x3, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xe1, 0xe, 0x30, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x60, 0x6f, 0xff, 0xff, 0xff, 0xd0, + 0x0, 0x8f, 0x1, 0xe2, 0x0, 0x10, 0x8, 0x80, + 0x7, 0xff, 0xc, 0x60, 0x1, 0xf0, 0xe, 0x10, + 0x2e, 0x4f, 0x3, 0x8, 0x31, 0xf0, 0x92, 0x0, + 0x1, 0x1f, 0x0, 0x2e, 0x1, 0xf0, 0x7b, 0x0, + 0x0, 0x1f, 0x0, 0xd6, 0x1, 0xf0, 0xc, 0x50, + 0x0, 0x1f, 0x3, 0x80, 0x13, 0xf0, 0x4, 0x70, + 0x0, 0x1e, 0x0, 0x3, 0xac, 0x80, 0x0, 0x0, + 0x0, 0x10, 0x41, 0x1d, 0x60, 0x0, 0x23, 0x0, + 0x0, 0xd3, 0xc4, 0x1, 0xe4, 0x0, 0x4d, 0x0, + 0x4, 0xd0, 0xc4, 0x0, 0x36, 0x5, 0x5b, 0x60, + 0xd, 0x60, 0xc6, 0x0, 0x0, 0xa, 0x64, 0xd0, + 0x7, 0x0, 0x6e, 0xff, 0xff, 0xfd, 0x10, 0x40, + + /* U+60AA "悪" */ + 0xc, 0xee, 0xef, 0xfe, 0xef, 0xfe, 0xee, 0xd0, + 0x0, 0x0, 0x5, 0xa0, 0xd, 0x30, 0x0, 0x0, + 0x0, 0x11, 0x16, 0xb1, 0x1d, 0x41, 0x11, 0x0, + 0x0, 0xbd, 0xcd, 0xec, 0xcf, 0xdc, 0xdb, 0x0, + 0x0, 0xb4, 0x5, 0xa0, 0xd, 0x30, 0x4b, 0x0, + 0x0, 0xb5, 0x17, 0xb1, 0x1d, 0x41, 0x6b, 0x0, + 0x0, 0x8b, 0xbd, 0xeb, 0xbf, 0xcb, 0xb8, 0x0, + 0x0, 0x0, 0x5, 0xa0, 0xd, 0x30, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x0, 0x0, 0xab, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x57, 0x1c, 0x5, 0xe4, 0x3, 0xc1, 0x0, + 0x0, 0xc5, 0x1e, 0x0, 0x20, 0x23, 0x7e, 0x20, + 0xa, 0xc0, 0x1f, 0x0, 0x0, 0x79, 0x7, 0xd0, + 0x8, 0x0, 0xc, 0xff, 0xff, 0xe3, 0x0, 0x60, + + /* U+60B2 "悲" */ + 0x0, 0x0, 0x1, 0xd0, 0xe, 0x20, 0x0, 0x0, + 0xb, 0xee, 0xef, 0xe0, 0xe, 0xff, 0xff, 0xc0, + 0x0, 0x0, 0x1, 0xe0, 0xe, 0x20, 0x0, 0x0, + 0x3, 0xbb, 0xbb, 0xe0, 0xe, 0xcb, 0xbb, 0x30, + 0x0, 0x33, 0x34, 0xe0, 0xe, 0x53, 0x33, 0x0, + 0x0, 0x0, 0x1, 0xe0, 0xe, 0x20, 0x0, 0x0, + 0xe, 0xff, 0xff, 0xe0, 0xe, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x1, 0xe0, 0xe, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xc0, 0xb, 0x20, 0x0, 0x0, + 0x0, 0x24, 0x2d, 0xa, 0x80, 0x2, 0xb0, 0x0, + 0x0, 0xa7, 0x2e, 0x0, 0xc7, 0x0, 0xa9, 0x0, + 0x3, 0xe0, 0x2e, 0x0, 0x17, 0xb, 0x1e, 0x40, + 0xd, 0x60, 0x2f, 0x0, 0x0, 0x3e, 0x5, 0xe0, + 0x5, 0x0, 0xb, 0xff, 0xff, 0xf7, 0x0, 0x30, + + /* U+60C5 "情" */ + 0x0, 0xc3, 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, + 0x0, 0xc3, 0xb, 0xdd, 0xdf, 0xed, 0xdd, 0x80, + 0x1, 0xc9, 0x40, 0x0, 0xb, 0x50, 0x0, 0x0, + 0x1b, 0xc6, 0xb6, 0xcc, 0xcf, 0xdc, 0xcc, 0x20, + 0x3a, 0xc3, 0x80, 0x0, 0xb, 0x50, 0x0, 0x0, + 0x67, 0xc3, 0x5d, 0xdd, 0xdd, 0xdd, 0xdd, 0xd1, + 0xa4, 0xc3, 0x0, 0x22, 0x22, 0x22, 0x21, 0x0, + 0x10, 0xc3, 0x3, 0xfb, 0xbb, 0xbb, 0xcc, 0x0, + 0x0, 0xc3, 0x3, 0xc0, 0x0, 0x0, 0x4c, 0x0, + 0x0, 0xc3, 0x3, 0xfc, 0xcc, 0xcc, 0xdc, 0x0, + 0x0, 0xc3, 0x3, 0xc0, 0x0, 0x0, 0x3c, 0x0, + 0x0, 0xc3, 0x3, 0xfd, 0xdd, 0xdd, 0xdc, 0x0, + 0x0, 0xc3, 0x3, 0xc0, 0x0, 0x0, 0x4c, 0x0, + 0x0, 0xc3, 0x3, 0xc0, 0x0, 0x2e, 0xe8, 0x0, + + /* U+60F3 "想" */ + 0x0, 0x1, 0xe0, 0x0, 0xce, 0xee, 0xef, 0x30, + 0x33, 0x4f, 0x33, 0x1c, 0x20, 0x0, 0xc3, 0x1f, + 0xff, 0xff, 0xf8, 0xc2, 0x0, 0xc, 0x30, 0x0, + 0x9e, 0x0, 0xc, 0xed, 0xdd, 0xf3, 0x0, 0x2d, + 0xfa, 0x10, 0xc2, 0x0, 0xc, 0x30, 0xc, 0x5e, + 0x4e, 0x4c, 0xdd, 0xdd, 0xf3, 0xa, 0xa1, 0xe0, + 0x32, 0xc2, 0x0, 0xc, 0x32, 0xb0, 0x1e, 0x0, + 0xc, 0x20, 0x0, 0xc3, 0x0, 0x1, 0xe0, 0x0, + 0xbe, 0xee, 0xee, 0x30, 0x1, 0x4, 0x1, 0xd3, + 0x0, 0x2, 0x10, 0x0, 0xe1, 0x6a, 0x3, 0xe2, + 0x0, 0x8a, 0x0, 0x5c, 0x6, 0xa0, 0x5, 0x21, + 0x80, 0xd5, 0xd, 0x40, 0x6b, 0x0, 0x0, 0x5b, + 0x5, 0xc0, 0x40, 0x2, 0xdf, 0xff, 0xfe, 0x50, + 0x0, + + /* U+6108 "愈" */ + 0x0, 0x0, 0x0, 0x3, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xeb, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x5d, 0x80, 0x4d, 0x91, 0x0, 0x0, 0x39, + 0xeb, 0xc9, 0x99, 0x9a, 0xdb, 0x61, 0x5d, 0x71, + 0x3, 0x33, 0x33, 0x10, 0x39, 0x90, 0xb, 0xcb, + 0xbc, 0x60, 0x71, 0xc, 0x30, 0x0, 0xd4, 0x33, + 0x87, 0xd, 0x20, 0xc3, 0x0, 0xd, 0x76, 0x6a, + 0x70, 0xd2, 0xc, 0x30, 0x0, 0xdb, 0xaa, 0xc7, + 0xd, 0x20, 0xc3, 0x0, 0xd, 0x10, 0x6, 0x70, + 0x40, 0xd, 0x30, 0x0, 0xc1, 0x6, 0xb4, 0x0, + 0x3d, 0xb0, 0x0, 0x3, 0x21, 0x83, 0xd7, 0x0, + 0x26, 0x0, 0x0, 0xd3, 0x1e, 0x0, 0x94, 0x42, + 0xc6, 0x0, 0x9a, 0x1, 0xf0, 0x0, 0xb, 0x41, + 0xe2, 0x8, 0x0, 0xc, 0xff, 0xff, 0xd0, 0x5, + 0x30, + + /* U+610F "意" */ + 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8a, 0x0, 0x0, 0x0, 0x1d, 0xde, + 0xed, 0xdd, 0xde, 0xed, 0xd1, 0x0, 0x7, 0xa0, + 0x0, 0x9, 0x80, 0x0, 0x68, 0x89, 0xf8, 0x88, + 0x8f, 0x98, 0x87, 0x34, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x0, 0xcc, 0xcc, 0xcc, 0xcc, 0xcd, + 0x0, 0x0, 0xe1, 0x0, 0x0, 0x0, 0xf, 0x0, + 0x0, 0xec, 0xbb, 0xbb, 0xbb, 0xcf, 0x0, 0x0, + 0xe1, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0xbc, + 0xcc, 0xec, 0xcc, 0xcc, 0x0, 0x2, 0x51, 0x71, + 0xc9, 0x0, 0x8, 0x10, 0xa, 0x72, 0xd0, 0x7, + 0x73, 0x36, 0xc0, 0x6d, 0x2, 0xe0, 0x0, 0x8, + 0x80, 0x99, 0x62, 0x0, 0xcf, 0xee, 0xee, 0x20, + 0x12, + + /* U+611A "愚" */ + 0x0, 0xf, 0xcc, 0xcd, 0xfc, 0xcc, 0xf0, 0x0, + 0x0, 0xd, 0x0, 0x3, 0xd0, 0x0, 0xf0, 0x0, + 0x0, 0xf, 0xcc, 0xcd, 0xfc, 0xcc, 0xf0, 0x0, + 0x0, 0xe, 0x44, 0x47, 0xe4, 0x44, 0xf0, 0x0, + 0x0, 0x6, 0x66, 0x68, 0xe6, 0x66, 0x60, 0x0, + 0x1, 0xcc, 0xcc, 0xcd, 0xfc, 0xcc, 0xcc, 0x20, + 0x1, 0xe0, 0x0, 0x3, 0xd0, 0x81, 0xd, 0x20, + 0x1, 0xe2, 0x77, 0x8a, 0xe9, 0xcc, 0xd, 0x20, + 0x1, 0xe2, 0x76, 0x65, 0x54, 0x47, 0x4e, 0x20, + 0x1, 0xd0, 0x0, 0x4d, 0x40, 0x2, 0xdb, 0x0, + 0x0, 0x63, 0xa4, 0x3, 0xca, 0x10, 0x66, 0x0, + 0x0, 0xe2, 0xb4, 0x0, 0x7, 0x26, 0x2e, 0x30, + 0xa, 0x90, 0xb5, 0x0, 0x0, 0x2e, 0x6, 0xd0, + 0x7, 0x0, 0x6e, 0xff, 0xff, 0xf7, 0x0, 0x70, + + /* U+611B "愛" */ + 0x0, 0x0, 0x0, 0x1, 0x34, 0x68, 0xa1, 0x0, + 0x3d, 0xee, 0xee, 0xda, 0x97, 0x74, 0x0, 0x0, + 0xb, 0x50, 0x3c, 0x0, 0xc, 0x60, 0x0, 0x0, + 0x4e, 0x0, 0xc2, 0x6, 0xb0, 0x0, 0xd, 0xee, + 0xfe, 0xee, 0xee, 0xfe, 0xee, 0x40, 0xe1, 0x0, + 0x7, 0xa1, 0x0, 0x0, 0xc4, 0xd, 0x1a, 0x1c, + 0x4, 0xa0, 0x1c, 0x2c, 0x40, 0x5, 0xc0, 0xf0, + 0x0, 0x48, 0x4d, 0x20, 0x3, 0xd2, 0xa, 0xec, + 0xcd, 0x40, 0x5a, 0x0, 0x1, 0x1, 0xb8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0xde, 0xcc, 0xcc, + 0xe9, 0x0, 0x0, 0x19, 0xd9, 0xb1, 0x0, 0x7d, + 0x10, 0x0, 0xb, 0x70, 0x4, 0xd7, 0xcb, 0x10, + 0x0, 0x0, 0x0, 0x4, 0x8d, 0xce, 0xa6, 0x20, + 0x0, 0x1b, 0xdd, 0xb6, 0x10, 0x4, 0xad, 0xfd, + 0x60, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, + + /* U+611F "感" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0x64, 0x95, 0x0, + 0x0, 0xde, 0xee, 0xee, 0xef, 0xfe, 0xef, 0xe2, + 0x0, 0xe1, 0x0, 0x0, 0x5, 0xa0, 0x0, 0x0, + 0x0, 0xe5, 0xcc, 0xcc, 0xc2, 0xd0, 0x1e, 0x0, + 0x0, 0xf0, 0x0, 0x0, 0x0, 0xe1, 0x99, 0x0, + 0x1, 0xe1, 0xec, 0xcd, 0xa0, 0xa7, 0xf2, 0x0, + 0x2, 0xc1, 0xb0, 0x2, 0xb0, 0x5f, 0x70, 0x10, + 0x6, 0x91, 0xc3, 0x35, 0xb0, 0xaf, 0x40, 0xa3, + 0xc, 0x31, 0xaa, 0xaa, 0x8b, 0xb5, 0xd4, 0xd1, + 0x19, 0x0, 0x10, 0x5, 0x7, 0x0, 0x4b, 0x80, + 0x0, 0x61, 0xe2, 0x8, 0xb0, 0x0, 0x69, 0x0, + 0x2, 0xe0, 0xe2, 0x0, 0x88, 0x6, 0x4e, 0x30, + 0xc, 0x60, 0xe3, 0x0, 0x0, 0xc, 0x46, 0xb0, + 0x7, 0x0, 0x8e, 0xee, 0xee, 0xeb, 0x0, 0x20, + + /* U+614B "態" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x81, 0x30, 0xe, 0x10, 0x38, 0x10, + 0x1, 0xb7, 0x3, 0xd4, 0xe, 0x9c, 0xa5, 0x0, + 0xc, 0xfd, 0xdc, 0xbd, 0x3e, 0x40, 0x0, 0x90, + 0x1, 0x0, 0x0, 0x3, 0x3e, 0x52, 0x25, 0xc0, + 0x1, 0xfb, 0xbb, 0xcd, 0x7, 0xbb, 0xbb, 0x40, + 0x1, 0xf8, 0x88, 0x9d, 0xe, 0x10, 0x6, 0x10, + 0x1, 0xe2, 0x22, 0x4d, 0xe, 0x6a, 0xd8, 0x20, + 0x1, 0xfb, 0xbb, 0xcd, 0xe, 0x83, 0x0, 0x40, + 0x1, 0xe0, 0x0, 0x2d, 0xe, 0x10, 0x1, 0xe0, + 0x1, 0xd0, 0x1c, 0xc8, 0x9, 0xee, 0xee, 0x80, + 0x0, 0x80, 0x62, 0x5, 0xb0, 0x0, 0xa, 0x0, + 0x4, 0xc0, 0xb4, 0x0, 0x93, 0x15, 0xb, 0x60, + 0xd, 0x40, 0xb5, 0x0, 0x0, 0x5b, 0x4, 0xd0, + 0x5, 0x0, 0x6e, 0xee, 0xee, 0xe4, 0x0, 0x50, + + /* U+6163 "慣" */ + 0x0, 0x69, 0x0, 0x6e, 0xcd, 0xec, 0xcf, 0x10, + 0x0, 0x69, 0x1, 0x87, 0x4, 0xa0, 0xf, 0x10, + 0x3, 0x69, 0x7b, 0xfd, 0xcd, 0xec, 0xcf, 0xd6, + 0xc, 0x69, 0xc0, 0xb7, 0x49, 0xa4, 0x5e, 0x0, + 0xc, 0x69, 0x92, 0x57, 0x77, 0x77, 0x76, 0x0, + 0x2a, 0x69, 0x21, 0xbc, 0xcc, 0xcc, 0xcc, 0x20, + 0x55, 0x69, 0x0, 0xe1, 0x0, 0x0, 0xd, 0x30, + 0x0, 0x69, 0x0, 0xec, 0xbb, 0xbb, 0xbf, 0x30, + 0x0, 0x69, 0x0, 0xe1, 0x0, 0x0, 0xd, 0x30, + 0x0, 0x69, 0x0, 0xec, 0xbb, 0xbb, 0xbf, 0x30, + 0x0, 0x69, 0x0, 0xe1, 0x0, 0x0, 0xd, 0x30, + 0x0, 0x69, 0x0, 0xbc, 0xdc, 0xcd, 0xcc, 0x20, + 0x0, 0x69, 0x0, 0x4c, 0x80, 0x5, 0xc7, 0x10, + 0x0, 0x69, 0x1d, 0x92, 0x0, 0x0, 0x7, 0xd2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6167 "慧" */ + 0x8b, 0xcf, 0xbb, 0x1b, 0xbd, 0xeb, 0xb4, 0x0, + 0x2d, 0x0, 0x0, 0x5, 0xa0, 0x0, 0x4b, 0xcf, + 0xbb, 0x7, 0xbd, 0xeb, 0xb0, 0x44, 0x6e, 0x44, + 0x13, 0x38, 0xb3, 0x32, 0x88, 0x9f, 0x88, 0x49, + 0x9b, 0xd9, 0x95, 0x7, 0xdf, 0xcc, 0xcc, 0xcf, + 0xfc, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x20, 0x1, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x20, 0x9, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x20, 0x2, 0x4, + 0x40, 0xc5, 0x0, 0x4, 0x20, 0xd, 0x37, 0x90, + 0x1c, 0x30, 0x45, 0xd0, 0x5c, 0x7, 0x90, 0x0, + 0x3, 0xc0, 0xb7, 0x63, 0x3, 0xee, 0xee, 0xef, + 0x60, 0x37, + + /* U+616E "慮" */ + 0x0, 0x0, 0x0, 0xe, 0xdc, 0xcc, 0xc8, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, 0x0, + 0x0, 0xdd, 0xdd, 0xdf, 0xdd, 0xdd, 0xdd, 0x70, + 0x0, 0xf0, 0x0, 0xe, 0x33, 0x45, 0x1e, 0x30, + 0x0, 0xf2, 0xba, 0xaf, 0x87, 0x65, 0x17, 0x50, + 0x0, 0xf0, 0x0, 0x9, 0xba, 0xaa, 0xac, 0x60, + 0x0, 0xf0, 0x45, 0x55, 0x55, 0x55, 0x50, 0x0, + 0x1, 0xf0, 0xe5, 0x44, 0xf5, 0x44, 0xe2, 0x0, + 0x1, 0xe0, 0xea, 0xaa, 0xfa, 0xaa, 0xf2, 0x0, + 0x2, 0xd0, 0xe2, 0x11, 0xe2, 0x11, 0xd2, 0x0, + 0x4, 0xb0, 0x78, 0x8e, 0xb8, 0x88, 0x81, 0x0, + 0x8, 0x82, 0x85, 0x83, 0xc6, 0x0, 0xc4, 0x0, + 0xd, 0x4a, 0x55, 0x90, 0x0, 0x38, 0x2d, 0x50, + 0x2d, 0x58, 0x2, 0xed, 0xdd, 0xd5, 0x2, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+61C9 "應" */ + 0x0, 0x0, 0x0, 0x0, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa7, 0x0, 0x0, 0x0, + 0x0, 0xfe, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe6, + 0x0, 0xf0, 0x4, 0xa0, 0x84, 0x49, 0x0, 0x0, + 0x0, 0xf0, 0xd, 0x33, 0xf9, 0x8e, 0x98, 0x70, + 0x0, 0xf0, 0xbd, 0x1d, 0xc2, 0x2e, 0x32, 0x20, + 0x0, 0xfb, 0xbd, 0xca, 0xea, 0xaf, 0xaa, 0x70, + 0x0, 0xf5, 0x1d, 0x12, 0xd5, 0x5e, 0x65, 0x40, + 0x1, 0xe0, 0x1d, 0x2, 0xd4, 0x4e, 0x54, 0x30, + 0x2, 0xc0, 0x1d, 0x2, 0xeb, 0xbf, 0xcb, 0xb4, + 0x3, 0xb0, 0x9, 0x1, 0xa4, 0x0, 0x0, 0x0, + 0x6, 0x90, 0x26, 0xa, 0x19, 0xc2, 0x46, 0x0, + 0x9, 0x60, 0xa6, 0xf, 0x0, 0x32, 0x2c, 0x40, + 0xe, 0x26, 0xd0, 0xf, 0x0, 0x4, 0xb1, 0xd1, + 0x1b, 0x7, 0x10, 0xc, 0xfe, 0xee, 0x50, 0x42, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+61F8 "懸" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0xdb, 0xbb, 0xe4, 0x48, 0xac, 0xca, 0x30, + 0x0, 0xd5, 0x55, 0xb4, 0x34, 0xa8, 0x0, 0x0, + 0x0, 0xd5, 0x55, 0xb4, 0x5, 0xa0, 0x6b, 0x0, + 0x0, 0xd9, 0x99, 0xd4, 0x2f, 0xce, 0xb0, 0x0, + 0x0, 0xd5, 0x55, 0xb4, 0x1, 0x98, 0x9, 0x10, + 0x0, 0xd5, 0x44, 0xb4, 0x4e, 0xc8, 0xad, 0xb0, + 0xa, 0xdb, 0xcb, 0xcc, 0x46, 0x4b, 0x41, 0x71, + 0x0, 0x73, 0x95, 0x91, 0xc, 0x3a, 0x3c, 0x30, + 0x5, 0xc0, 0x94, 0x5a, 0x99, 0xb, 0x31, 0xd0, + 0x7, 0x1c, 0xd2, 0x4, 0x31, 0xdc, 0x10, 0x10, + 0x0, 0x22, 0x26, 0xa, 0xc1, 0x0, 0x71, 0x0, + 0x0, 0xc4, 0x3c, 0x0, 0x68, 0x1, 0x6d, 0x10, + 0x7, 0xb0, 0x3c, 0x0, 0x0, 0x4a, 0x7, 0xc0, + 0x8, 0x10, 0x1d, 0xed, 0xde, 0xe5, 0x0, 0x71, + + /* U+6210 "成" */ + 0x0, 0x0, 0x0, 0x0, 0x3e, 0xb, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, 0x6c, 0x10, + 0x0, 0xcd, 0xdd, 0xdd, 0xef, 0xdd, 0xdd, 0xd2, + 0x0, 0xe5, 0x22, 0x22, 0x3f, 0x32, 0x22, 0x20, + 0x0, 0xe3, 0x0, 0x0, 0xe, 0x20, 0x1, 0x0, + 0x0, 0xe6, 0x33, 0x31, 0xc, 0x40, 0x2f, 0x0, + 0x0, 0xed, 0xcc, 0xf5, 0xa, 0x60, 0x89, 0x0, + 0x0, 0xf2, 0x0, 0xc4, 0x8, 0x91, 0xe2, 0x0, + 0x0, 0xf1, 0x0, 0xc4, 0x4, 0xc9, 0xa0, 0x0, + 0x1, 0xf0, 0x0, 0xd3, 0x1, 0xfe, 0x10, 0x0, + 0x3, 0xe0, 0x11, 0xf1, 0x3, 0xf7, 0x0, 0x72, + 0x7, 0xa2, 0xee, 0x90, 0x4e, 0xad, 0x0, 0xb3, + 0xe, 0x50, 0x0, 0x9, 0xe3, 0xc, 0xa2, 0xe0, + 0x3d, 0x0, 0x0, 0x5b, 0x10, 0x1, 0xbf, 0x80, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6211 "我" */ + 0x0, 0x0, 0x36, 0xab, 0xf, 0x25, 0x60, 0x0, + 0x9, 0xdd, 0xeb, 0x40, 0xe, 0x31, 0xc8, 0x0, + 0x1, 0x0, 0x97, 0x0, 0xd, 0x30, 0xc, 0x60, + 0x0, 0x0, 0x97, 0x0, 0xc, 0x40, 0x0, 0x0, + 0x1d, 0xdd, 0xfe, 0xdd, 0xdf, 0xed, 0xdd, 0xd1, + 0x2, 0x22, 0xa8, 0x22, 0x2a, 0x92, 0x22, 0x20, + 0x0, 0x0, 0x97, 0x0, 0x7, 0xa0, 0x1d, 0x10, + 0x0, 0x0, 0x99, 0x59, 0x54, 0xc0, 0xc8, 0x0, + 0x5, 0x8b, 0xfe, 0xa6, 0x11, 0xf8, 0xd0, 0x0, + 0x1c, 0x95, 0xa7, 0x0, 0x0, 0xde, 0x10, 0x0, + 0x0, 0x0, 0x97, 0x0, 0x8, 0xfa, 0x0, 0x63, + 0x0, 0x0, 0x97, 0x2, 0xbb, 0x3f, 0x10, 0xa4, + 0x0, 0x11, 0xb7, 0x4e, 0x60, 0x9, 0xc2, 0xd2, + 0x1, 0xff, 0xd2, 0x2, 0x0, 0x0, 0x9f, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6216 "或" */ + 0x0, 0x0, 0x0, 0x1, 0xf0, 0x89, 0x20, 0x0, + 0x0, 0x0, 0x0, 0xf, 0x10, 0x3c, 0x20, 0xdf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x1, 0x11, + 0x11, 0x11, 0x1e, 0x41, 0x11, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xd4, 0x0, 0x30, 0x0, 0xee, 0xee, + 0xf8, 0xb, 0x60, 0x2f, 0x10, 0xe, 0x10, 0x7, + 0x80, 0x97, 0x8, 0x90, 0x0, 0xe1, 0x0, 0x78, + 0x7, 0xa0, 0xe3, 0x0, 0xe, 0x32, 0x29, 0x80, + 0x3d, 0x8a, 0x0, 0x0, 0xbc, 0xcc, 0xc6, 0x0, + 0xfe, 0x10, 0x0, 0x0, 0x0, 0x0, 0x30, 0x2f, + 0x80, 0x5, 0x12, 0x58, 0xbd, 0xda, 0x5e, 0x9e, + 0x0, 0xb4, 0xa9, 0x63, 0x1, 0x9d, 0x20, 0xbb, + 0x3e, 0x10, 0x0, 0x0, 0x69, 0x0, 0x1, 0xaf, + 0x90, + + /* U+6226 "戦" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x19, 0x2, 0xd0, 0x5, 0xb0, 0xc3, 0x56, 0x0, + 0xb, 0x50, 0xd2, 0xd, 0x40, 0xb4, 0xc, 0x50, + 0x4, 0x70, 0x51, 0x48, 0x0, 0xa5, 0x2, 0xa0, + 0xa, 0xdd, 0xdd, 0xdd, 0x60, 0x97, 0x35, 0x72, + 0xc, 0x20, 0xa4, 0x7, 0xbd, 0xff, 0xfc, 0xa2, + 0xc, 0x30, 0xa5, 0x8, 0x97, 0x99, 0x0, 0x0, + 0xc, 0xcc, 0xed, 0xce, 0x70, 0x5b, 0x6, 0x90, + 0xc, 0x20, 0xa4, 0x7, 0x70, 0x3d, 0xd, 0x20, + 0xc, 0xdd, 0xfe, 0xde, 0x70, 0xf, 0x7a, 0x0, + 0x0, 0x0, 0xb5, 0x0, 0x0, 0xc, 0xe1, 0x0, + 0x4c, 0xcc, 0xed, 0xcc, 0xc0, 0x2e, 0x90, 0x23, + 0x12, 0x22, 0xc7, 0x22, 0x22, 0xe9, 0xe0, 0x58, + 0x0, 0x0, 0xb5, 0x0, 0x6e, 0x50, 0xca, 0xb4, + 0x0, 0x0, 0xb5, 0x2, 0xb2, 0x0, 0x2c, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6230 "戰" */ + 0xc, 0xcd, 0x7b, 0xcd, 0x80, 0xc3, 0x78, 0x0, + 0xc, 0x6, 0x7b, 0x14, 0x80, 0xb4, 0xc, 0x50, + 0xc, 0x9b, 0x7b, 0x9b, 0x80, 0xb5, 0x2, 0xb0, + 0x2, 0x33, 0x12, 0x33, 0x10, 0xa6, 0x13, 0x51, + 0x9, 0xdd, 0xdd, 0xdd, 0x9b, 0xef, 0xec, 0xa3, + 0xa, 0x30, 0xa4, 0x8, 0x84, 0x89, 0x2, 0x40, + 0xa, 0xdc, 0xed, 0xce, 0x60, 0x5a, 0x8, 0x70, + 0xa, 0x40, 0xa5, 0x8, 0x60, 0x3c, 0xd, 0x10, + 0xa, 0x41, 0xa5, 0x19, 0x60, 0x1f, 0x6a, 0x0, + 0x8, 0xcc, 0xed, 0xcc, 0x50, 0xe, 0xe2, 0x0, + 0x0, 0x0, 0xb5, 0x0, 0x0, 0xd, 0x90, 0x0, + 0x5e, 0xee, 0xff, 0xee, 0xe1, 0xbe, 0xc0, 0x57, + 0x0, 0x0, 0xb5, 0x0, 0x6e, 0x90, 0xd8, 0xb4, + 0x0, 0x0, 0xb5, 0x1, 0xa3, 0x0, 0x3d, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+623B "戻" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0xde, 0xdd, 0xdd, 0xdd, 0xdd, 0xee, 0x0, + 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0xde, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0x0, + 0x0, 0xe2, 0x0, 0x0, 0x97, 0x0, 0x0, 0x0, + 0x0, 0xf1, 0x0, 0x0, 0xc5, 0x0, 0x0, 0x0, + 0x0, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0x50, + 0x2, 0xe0, 0x0, 0x5, 0xfc, 0x0, 0x0, 0x0, + 0x6, 0xa0, 0x0, 0x1d, 0x4b, 0x90, 0x0, 0x0, + 0xc, 0x50, 0x2, 0xc9, 0x1, 0xcb, 0x10, 0x0, + 0x4e, 0x4, 0x9e, 0x70, 0x0, 0x9, 0xf9, 0x40, + 0x24, 0x2c, 0x71, 0x0, 0x0, 0x0, 0x28, 0xb0, + + /* U+623F "房" */ + 0x0, 0x0, 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa8, 0x0, 0x0, 0x0, 0x0, + 0xce, 0xee, 0xef, 0xfe, 0xee, 0xee, 0x0, 0xd, + 0x30, 0x0, 0x0, 0x0, 0x0, 0xf0, 0x0, 0xd3, + 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0xd, 0xfe, + 0xee, 0xee, 0xee, 0xee, 0xe0, 0x0, 0xd3, 0x0, + 0x0, 0xb3, 0x0, 0x0, 0x0, 0xe, 0x30, 0x0, + 0x4, 0xb0, 0x0, 0x0, 0x0, 0xf5, 0xee, 0xee, + 0xee, 0xee, 0xee, 0x80, 0xf, 0x0, 0x2, 0xe0, + 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x5f, 0xbb, + 0xbb, 0xb6, 0x0, 0x6b, 0x0, 0xb, 0x72, 0x22, + 0x2a, 0x60, 0xa, 0x70, 0x4, 0xe0, 0x0, 0x0, + 0xb5, 0x1, 0xf2, 0x6, 0xe3, 0x0, 0x0, 0xe, + 0x20, 0x5a, 0xa, 0xb2, 0x0, 0xa, 0xde, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6240 "所" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x0, 0x1, 0x47, 0xca, 0x0, 0x14, 0x8c, 0xe1, + 0x2, 0xee, 0xb8, 0x40, 0x1e, 0xeb, 0x83, 0x0, + 0x2, 0xe0, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, + 0x2, 0xe6, 0x66, 0x60, 0x2e, 0x0, 0x0, 0x0, + 0x2, 0xf9, 0x99, 0xf1, 0x2e, 0x0, 0x0, 0x0, + 0x2, 0xd0, 0x0, 0xe1, 0x2f, 0xff, 0xff, 0xf9, + 0x3, 0xd0, 0x0, 0xe1, 0x2e, 0x0, 0x5c, 0x0, + 0x3, 0xfe, 0xee, 0xf1, 0x3e, 0x0, 0x4c, 0x0, + 0x4, 0xc0, 0x0, 0x0, 0x4d, 0x0, 0x4c, 0x0, + 0x5, 0xb0, 0x0, 0x0, 0x6a, 0x0, 0x4c, 0x0, + 0x7, 0x90, 0x0, 0x0, 0xa7, 0x0, 0x4c, 0x0, + 0xa, 0x60, 0x0, 0x1, 0xf1, 0x0, 0x4c, 0x0, + 0xe, 0x10, 0x0, 0xb, 0xa0, 0x0, 0x4c, 0x0, + 0x1a, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x4c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+624B "手" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x40, 0x0, + 0x0, 0x1, 0x34, 0x57, 0x8b, 0xdf, 0xb3, 0x0, + 0x0, 0xed, 0xcb, 0xac, 0xb4, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x19, 0x91, 0x11, 0x11, 0x10, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x11, 0x19, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xbf, 0xfd, 0x30, 0x0, 0x0, 0x0, + + /* U+624D "才" */ + 0x0, 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0, 0x2, + 0x22, 0x22, 0x22, 0x2a, 0xa2, 0x22, 0x20, 0xdf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0x0, 0x1, 0xed, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb9, 0x99, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8d, 0x9, 0x90, 0x0, 0x0, 0x0, 0x0, 0x7e, + 0x10, 0x99, 0x0, 0x0, 0x0, 0x0, 0x7e, 0x20, + 0x9, 0x90, 0x0, 0x0, 0x0, 0xae, 0x20, 0x0, + 0x99, 0x0, 0x0, 0x4, 0xdc, 0x10, 0x0, 0x9, + 0x90, 0x0, 0x2, 0xf8, 0x0, 0x0, 0x0, 0x99, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x11, 0x1a, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x6, 0xff, 0xd3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+6253 "打" */ + 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x70, 0x2c, 0xcc, 0xcc, 0xcc, 0xc8, + 0x0, 0xa, 0x70, 0x12, 0x22, 0x27, 0xd2, 0x22, + 0x1f, 0xff, 0xff, 0xb0, 0x0, 0x5, 0xc0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x5, 0xc0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x5, 0xc0, 0x0, + 0x0, 0x9, 0x72, 0x50, 0x0, 0x5, 0xc0, 0x0, + 0x1, 0x5c, 0xfd, 0x80, 0x0, 0x5, 0xc0, 0x0, + 0x1f, 0xcd, 0x80, 0x0, 0x0, 0x5, 0xc0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x5, 0xc0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x5, 0xc0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0x5, 0xc0, 0x0, + 0x0, 0xa, 0x70, 0x0, 0x0, 0x6, 0xc0, 0x0, + 0x7, 0xfe, 0x30, 0x0, 0x6f, 0xff, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+6255 "払" */ + 0x0, 0x9, 0x70, 0x0, 0x2, 0x50, 0x0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x7, 0xa0, 0x0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0xa, 0x60, 0x0, 0x0, + 0xe, 0xff, 0xff, 0x60, 0xe, 0x30, 0x0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x2f, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x6b, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x72, 0x30, 0xa7, 0x3, 0x30, 0x0, + 0x1, 0x5c, 0xfd, 0x50, 0xf3, 0x6, 0xb0, 0x0, + 0xe, 0xbc, 0x80, 0x4, 0xe0, 0x0, 0xf3, 0x0, + 0x0, 0x9, 0x70, 0x9, 0x90, 0x0, 0x8a, 0x0, + 0x0, 0x9, 0x70, 0xf, 0x30, 0x0, 0x2f, 0x10, + 0x0, 0x9, 0x70, 0x6d, 0x13, 0x68, 0xaf, 0x80, + 0x0, 0xa, 0x70, 0xdf, 0xeb, 0x96, 0x46, 0xd0, + 0x6, 0xfe, 0x30, 0x21, 0x0, 0x0, 0x0, 0x80, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+627E "找" */ + 0x0, 0xe, 0x20, 0x0, 0x5a, 0x7, 0x10, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x4c, 0x6, 0xd1, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x3d, 0x0, 0x69, 0x0, + 0x3f, 0xff, 0xff, 0x20, 0x1f, 0x24, 0x68, 0x90, + 0x0, 0xe, 0x20, 0x7d, 0xff, 0xdb, 0x97, 0x60, + 0x0, 0xe, 0x20, 0x12, 0xd, 0x30, 0x2, 0x0, + 0x0, 0xe, 0x23, 0x10, 0xb, 0x60, 0x2e, 0x0, + 0x2, 0x6f, 0xfc, 0x20, 0x8, 0x90, 0xb7, 0x0, + 0x4e, 0xaf, 0x20, 0x0, 0x4, 0xd7, 0xc0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0xfe, 0x10, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x7, 0xf8, 0x0, 0x43, + 0x0, 0xe, 0x20, 0x1, 0xbd, 0x6e, 0x10, 0x86, + 0x0, 0xe, 0x20, 0x8f, 0x90, 0xa, 0xc3, 0xd3, + 0xb, 0xfc, 0x0, 0x42, 0x0, 0x0, 0x9f, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6280 "技" */ + 0x0, 0xf, 0x10, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0xf, 0x20, 0x9a, 0xab, 0xfb, 0xaa, 0xa0, + 0x1f, 0xff, 0xfd, 0x33, 0x34, 0xf3, 0x33, 0x30, + 0x0, 0xf, 0x10, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0xf, 0x10, 0x12, 0x22, 0xf2, 0x22, 0x0, + 0x0, 0xf, 0x10, 0x7f, 0xdd, 0xdd, 0xdf, 0x50, + 0x0, 0x3f, 0xce, 0xb, 0x60, 0x0, 0x3d, 0x0, + 0x2f, 0xcf, 0x40, 0x3, 0xe0, 0x0, 0xc6, 0x0, + 0x1, 0xf, 0x10, 0x0, 0x9a, 0x9, 0xa0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0xc, 0xdc, 0x0, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x4d, 0xeb, 0x20, 0x0, + 0x0, 0xf, 0x10, 0x5b, 0xe5, 0x7, 0xf9, 0x30, + 0xc, 0xfc, 0x8, 0xc6, 0x0, 0x0, 0x28, 0xe3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+628A "把" */ + 0x0, 0x1e, 0x0, 0x6f, 0xff, 0xff, 0xff, 0xd0, + 0x0, 0x1e, 0x0, 0x6a, 0x0, 0xe1, 0x4, 0xd0, + 0x0, 0x2f, 0x0, 0x6a, 0x0, 0xe1, 0x3, 0xd0, + 0x1f, 0xff, 0xf9, 0x6a, 0x0, 0xe1, 0x3, 0xd0, + 0x0, 0x1e, 0x0, 0x6a, 0x0, 0xe1, 0x3, 0xd0, + 0x0, 0x1e, 0x0, 0x6a, 0x0, 0xe1, 0x3, 0xd0, + 0x0, 0x1e, 0x0, 0x6a, 0x0, 0xe2, 0x4, 0xd0, + 0x0, 0x4f, 0xcc, 0x6f, 0xff, 0xff, 0xff, 0xd0, + 0x1a, 0x7f, 0x10, 0x6a, 0x0, 0x0, 0x1, 0x50, + 0x0, 0x1e, 0x0, 0x6a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x6a, 0x0, 0x0, 0x0, 0x35, + 0x0, 0x1e, 0x0, 0x6a, 0x0, 0x0, 0x0, 0x6a, + 0x0, 0x2e, 0x0, 0x5d, 0x0, 0x0, 0x0, 0xa7, + 0x9, 0xfa, 0x0, 0xb, 0xff, 0xff, 0xff, 0xc1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6295 "投" */ + 0x0, 0xf, 0x0, 0x2, 0xff, 0xff, 0xc0, 0x0, + 0x0, 0xf, 0x0, 0x3, 0xd0, 0x3, 0xc0, 0x0, + 0x15, 0x5f, 0x55, 0x4, 0xc0, 0x3, 0xc0, 0x0, + 0x2a, 0xaf, 0xaa, 0xa, 0x90, 0x3, 0xc0, 0x0, + 0x0, 0xf, 0x0, 0x7f, 0x20, 0x1, 0xfb, 0xb2, + 0x0, 0xf, 0x3, 0xf5, 0x0, 0x0, 0x23, 0x30, + 0x0, 0xf, 0x0, 0x21, 0x11, 0x11, 0x11, 0x0, + 0x0, 0x3f, 0xca, 0xef, 0xee, 0xee, 0xef, 0x20, + 0x4e, 0xdf, 0x40, 0x2e, 0x20, 0x0, 0x7a, 0x0, + 0x1, 0xf, 0x0, 0x7, 0xc0, 0x3, 0xe2, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x9c, 0x5e, 0x30, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x1d, 0xf8, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x4a, 0xe8, 0x4d, 0xd6, 0x20, + 0xd, 0xfb, 0x1f, 0xc7, 0x10, 0x0, 0x5b, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+62BC "押" */ + 0x0, 0x1f, 0x0, 0x6f, 0xff, 0xff, 0xff, 0xe0, + 0x1, 0xf0, 0x6, 0x90, 0xe, 0x10, 0x2e, 0x6, + 0x7f, 0x65, 0x68, 0x0, 0xe1, 0x2, 0xe0, 0xcc, + 0xfc, 0x96, 0x80, 0xe, 0x10, 0x2e, 0x0, 0x1f, + 0x0, 0x6f, 0xee, 0xff, 0xef, 0xe0, 0x1, 0xf0, + 0x6, 0x90, 0xe, 0x20, 0x2e, 0x0, 0x1f, 0x0, + 0x68, 0x0, 0xe1, 0x2, 0xe0, 0x3, 0xfc, 0xc6, + 0x91, 0x1e, 0x31, 0x3e, 0x1c, 0xdf, 0x50, 0x6f, + 0xee, 0xfe, 0xee, 0xe0, 0x1, 0xf0, 0x0, 0x0, + 0xe, 0x10, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, + 0xe1, 0x0, 0x0, 0x1, 0xf0, 0x0, 0x0, 0xe, + 0x10, 0x0, 0x0, 0x2f, 0x0, 0x0, 0x0, 0xe1, + 0x0, 0x0, 0xae, 0x90, 0x0, 0x0, 0xe, 0x10, + 0x0, + + /* U+62C5 "担" */ + 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x3f, 0xff, 0xff, 0xff, 0x0, + 0x0, 0xe, 0x20, 0x3d, 0x0, 0x0, 0xf, 0x0, + 0x3f, 0xff, 0xff, 0x5d, 0x0, 0x0, 0xf, 0x0, + 0x0, 0xe, 0x10, 0x3d, 0x0, 0x0, 0xf, 0x0, + 0x0, 0xe, 0x10, 0x3f, 0xff, 0xff, 0xff, 0x0, + 0x0, 0xe, 0x35, 0x3d, 0x0, 0x0, 0x1f, 0x0, + 0x4, 0x8f, 0xea, 0x4d, 0x0, 0x0, 0xf, 0x0, + 0x4c, 0x7f, 0x20, 0x3d, 0x0, 0x0, 0xf, 0x0, + 0x0, 0xe, 0x10, 0x3f, 0xcc, 0xcc, 0xcf, 0x0, + 0x0, 0xe, 0x10, 0x3, 0x33, 0x33, 0x33, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x11, 0x33, 0x33, 0x33, 0x33, 0x30, + 0xb, 0xfc, 0x5, 0xcc, 0xcc, 0xcc, 0xcc, 0xc2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+62C9 "拉" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x6, 0xa0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x2, 0xf0, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0x35, 0x55, 0xa6, 0x55, 0x50, + 0x1f, 0xff, 0xfa, 0x5a, 0xaa, 0xaa, 0xaa, 0xa0, + 0x0, 0xf, 0x0, 0x0, 0x10, 0x0, 0x23, 0x0, + 0x0, 0xf, 0x0, 0x5, 0xa0, 0x0, 0x7a, 0x0, + 0x0, 0xf, 0x0, 0x2, 0xd0, 0x0, 0x97, 0x0, + 0x0, 0x4f, 0xcc, 0x0, 0xf0, 0x0, 0xc4, 0x0, + 0x1e, 0xef, 0x40, 0x0, 0xc3, 0x0, 0xf1, 0x0, + 0x2, 0x1f, 0x0, 0x0, 0xa6, 0x2, 0xe0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x88, 0x5, 0xa0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x57, 0x9, 0x60, 0x0, + 0x0, 0x1f, 0x1, 0x33, 0x33, 0x3d, 0x63, 0x31, + 0x9, 0xfa, 0x4, 0xcc, 0xcc, 0xcc, 0xcc, 0xc5, + + /* U+62DB "招" */ + 0x0, 0x1f, 0x0, 0x5f, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x1f, 0x0, 0x0, 0xa, 0x70, 0x0, 0xf0, + 0x0, 0x2f, 0x0, 0x0, 0xd, 0x40, 0x1, 0xf0, + 0x2f, 0xff, 0xfe, 0x0, 0x3e, 0x0, 0x2, 0xe0, + 0x0, 0x1f, 0x0, 0x0, 0xc8, 0x0, 0x4, 0xc0, + 0x0, 0x1f, 0x0, 0xa, 0xd0, 0x2, 0x29, 0x90, + 0x0, 0x1f, 0x1, 0xbb, 0x10, 0x7, 0xdb, 0x20, + 0x0, 0x4f, 0xdc, 0x11, 0x11, 0x11, 0x11, 0x10, + 0x3e, 0xef, 0x30, 0xd, 0xee, 0xee, 0xee, 0xd0, + 0x3, 0x1f, 0x0, 0xd, 0x20, 0x0, 0x3, 0xd0, + 0x0, 0x1f, 0x0, 0xd, 0x20, 0x0, 0x3, 0xd0, + 0x0, 0x1f, 0x0, 0xd, 0x20, 0x0, 0x3, 0xd0, + 0x0, 0x2f, 0x0, 0xd, 0xcc, 0xcc, 0xcd, 0xd0, + 0xb, 0xf9, 0x0, 0xd, 0x53, 0x33, 0x36, 0xc0, + + /* U+62E1 "拡" */ + 0x0, 0xf, 0x0, 0x0, 0x4, 0x60, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x1, 0xe1, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0x7c, 0xcc, 0xed, 0xcc, 0xc1, + 0x1f, 0xff, 0xfb, 0x88, 0x22, 0x22, 0x22, 0x20, + 0x0, 0xf, 0x0, 0x87, 0x0, 0x74, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x97, 0x0, 0xd3, 0x0, 0x0, + 0x0, 0xf, 0x2, 0x96, 0x1, 0xf0, 0x0, 0x0, + 0x1, 0x6f, 0xe8, 0xb6, 0x6, 0xb0, 0x40, 0x0, + 0x2f, 0xaf, 0x0, 0xc4, 0xa, 0x60, 0xb4, 0x0, + 0x0, 0xf, 0x0, 0xd2, 0xf, 0x10, 0x4c, 0x0, + 0x0, 0xf, 0x1, 0xe0, 0x6b, 0x0, 0xd, 0x30, + 0x0, 0xf, 0x6, 0xa0, 0xd5, 0x2, 0x4a, 0xa0, + 0x0, 0x1f, 0xe, 0x35, 0xfe, 0xfd, 0xa8, 0xe0, + 0xa, 0xfa, 0x29, 0x1, 0x42, 0x0, 0x0, 0x82, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+62EC "括" */ + 0x0, 0xf, 0x0, 0x0, 0x0, 0x25, 0x7b, 0x80, + 0x0, 0xf, 0x0, 0x3c, 0xdc, 0xf8, 0x52, 0x0, + 0x2, 0x2f, 0x22, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0xb, 0xbf, 0xba, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x8c, 0xcc, 0xfc, 0xcc, 0xc9, + 0x0, 0xf, 0x0, 0x23, 0x33, 0xf5, 0x33, 0x32, + 0x0, 0xf, 0x27, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x4, 0x9f, 0xe9, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x1c, 0x8f, 0x0, 0x2e, 0xee, 0xfe, 0xee, 0xc0, + 0x0, 0xf, 0x0, 0x2d, 0x11, 0x11, 0x14, 0xd0, + 0x0, 0xf, 0x0, 0x2d, 0x0, 0x0, 0x3, 0xd0, + 0x0, 0xf, 0x0, 0x2d, 0x0, 0x0, 0x3, 0xd0, + 0x0, 0x1f, 0x0, 0x2d, 0x22, 0x22, 0x26, 0xd0, + 0xc, 0xea, 0x0, 0x2f, 0xcc, 0xcc, 0xcd, 0xc0, + + /* U+62ED "拭" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0xe, 0x3a, 0x10, + 0x0, 0xf, 0x0, 0x0, 0x0, 0xd, 0x35, 0xc0, + 0x2, 0x2f, 0x21, 0x0, 0x0, 0xd, 0x30, 0x61, + 0x1d, 0xdf, 0xda, 0xdf, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0xf, 0x0, 0x0, 0x0, 0xb, 0x40, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0xa, 0x50, 0x0, + 0x0, 0xf, 0x24, 0x8c, 0xcc, 0xa9, 0x60, 0x0, + 0x4, 0x9f, 0xe8, 0x23, 0xf4, 0x28, 0x80, 0x0, + 0x1c, 0x8f, 0x0, 0x0, 0xe1, 0x7, 0xa0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0xe1, 0x5, 0xc0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0xe1, 0x3, 0xe0, 0x52, + 0x0, 0xf, 0x0, 0x47, 0xfd, 0xf4, 0xe3, 0x94, + 0x1, 0x2f, 0x1, 0xc9, 0x62, 0x0, 0x9b, 0xd1, + 0xc, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+62FF "拿" */ + 0x0, 0x0, 0x0, 0x4, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7d, 0xd7, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x7d, 0x70, 0x9, 0xd7, 0x10, 0x0, + 0x6, 0xbe, 0xdb, 0x99, 0x99, 0xbe, 0xec, 0x71, + 0x19, 0x40, 0x12, 0x22, 0x22, 0x21, 0x3, 0x80, + 0x0, 0xd, 0xcc, 0xcc, 0xcc, 0xcd, 0xd0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x0, 0x3, 0xd0, 0x0, + 0x0, 0xa, 0xbb, 0xbb, 0xbb, 0xbb, 0xa0, 0x0, + 0x0, 0x34, 0x55, 0x66, 0x79, 0xab, 0xb1, 0x0, + 0x0, 0x46, 0x55, 0x4a, 0xa2, 0x10, 0x0, 0x0, + 0x1, 0xdd, 0xdd, 0xde, 0xed, 0xdd, 0xdd, 0x20, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0xc, 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xcc, 0xc0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xdd, 0x40, 0x0, 0x0, 0x0, + + /* U+6301 "持" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x1, 0x11, 0xe3, 0x11, 0x0, + 0x0, 0xf, 0x0, 0x2c, 0xcc, 0xfd, 0xcc, 0x70, + 0x1f, 0xff, 0xfb, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0xf, 0x0, 0xee, 0xee, 0xee, 0xff, 0xe4, + 0x0, 0xf, 0x1, 0x0, 0x0, 0x0, 0xc3, 0x0, + 0x0, 0x2f, 0xdb, 0x11, 0x11, 0x11, 0xd4, 0x10, + 0x2d, 0xef, 0x40, 0xbe, 0xee, 0xee, 0xff, 0xe3, + 0x3, 0xf, 0x0, 0x3, 0x30, 0x0, 0xc3, 0x0, + 0x0, 0xf, 0x0, 0x2, 0xd1, 0x0, 0xc3, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x6a, 0x0, 0xc3, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x2, 0x0, 0xd3, 0x0, + 0x9, 0xfa, 0x0, 0x0, 0x0, 0xef, 0xd1, 0x0, + + /* U+6307 "指" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0xe, 0x10, 0x0, 0x1, 0x0, + 0x0, 0xf, 0x0, 0xe, 0x10, 0x48, 0xdd, 0x20, + 0x0, 0xf, 0x10, 0xe, 0xdc, 0x96, 0x20, 0x0, + 0x4f, 0xff, 0xff, 0xe, 0x20, 0x0, 0x0, 0x85, + 0x0, 0xf, 0x0, 0xe, 0x40, 0x0, 0x2, 0xd4, + 0x0, 0xf, 0x0, 0x7, 0xde, 0xee, 0xee, 0xa0, + 0x0, 0xf, 0x36, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xaf, 0xd8, 0x1d, 0xee, 0xee, 0xee, 0xb0, + 0x5e, 0x8f, 0x0, 0xe, 0x10, 0x0, 0x4, 0xc0, + 0x0, 0xf, 0x0, 0xe, 0x10, 0x0, 0x4, 0xc0, + 0x0, 0xf, 0x0, 0xe, 0xee, 0xee, 0xee, 0xc0, + 0x0, 0xf, 0x0, 0xe, 0x10, 0x0, 0x4, 0xc0, + 0x0, 0xf, 0x0, 0xe, 0x43, 0x33, 0x36, 0xc0, + 0xb, 0xfb, 0x0, 0xe, 0xbb, 0xbb, 0xbc, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6319 "挙" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2b, 0x0, 0x6b, 0x0, 0x1, 0xe1, 0x0, + 0x0, 0xa, 0x90, 0xd, 0x50, 0xb, 0x80, 0x0, + 0x3, 0x34, 0xe4, 0x37, 0x83, 0x7d, 0x33, 0x30, + 0x1c, 0xcc, 0xdf, 0xcc, 0xcc, 0xfd, 0xcc, 0xc1, + 0x0, 0x0, 0xc7, 0x0, 0x0, 0x5c, 0x10, 0x0, + 0x0, 0x1c, 0xe6, 0x89, 0xcd, 0x96, 0xd2, 0x0, + 0x7, 0xe9, 0x46, 0x5b, 0x80, 0x0, 0x4d, 0x81, + 0x2a, 0x38, 0xaa, 0xad, 0xda, 0xaa, 0x70, 0x71, + 0x0, 0x2, 0x33, 0x3a, 0x93, 0x33, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0xa, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xa0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5e, 0xee, 0x30, 0x0, 0x0, 0x0, + + /* U+6355 "捕" */ + 0x0, 0xf, 0x10, 0x0, 0x0, 0xe1, 0xa4, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x0, 0xe0, 0x2a, 0xa0, + 0x0, 0xf, 0x10, 0xcc, 0xcc, 0xfd, 0xcc, 0xd3, + 0x3f, 0xff, 0xfe, 0x11, 0x11, 0xf2, 0x11, 0x10, + 0x0, 0xf, 0x10, 0x12, 0x22, 0xf3, 0x22, 0x20, + 0x0, 0xf, 0x10, 0x7e, 0xdd, 0xfd, 0xdd, 0xe0, + 0x0, 0xf, 0x35, 0x87, 0x0, 0xe0, 0x1, 0xe0, + 0x5, 0x9f, 0xd8, 0x8f, 0xee, 0xfe, 0xee, 0xe0, + 0x5e, 0x8f, 0x10, 0x77, 0x0, 0xe0, 0x1, 0xe0, + 0x0, 0xf, 0x10, 0x77, 0x0, 0xe0, 0x1, 0xe0, + 0x0, 0xf, 0x10, 0x7f, 0xee, 0xff, 0xef, 0xe0, + 0x0, 0xf, 0x10, 0x77, 0x0, 0xe0, 0x1, 0xe0, + 0x0, 0xf, 0x10, 0x77, 0x0, 0xe0, 0x1, 0xe0, + 0xa, 0xfb, 0x0, 0x77, 0x0, 0xd0, 0xbe, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6368 "捨" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0x0, 0x7, 0xc0, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0x0, 0x4d, 0xa9, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0x5, 0xd1, 0x7, 0xc2, 0x0, + 0xe, 0xff, 0xe7, 0xbc, 0x10, 0x0, 0x5e, 0x91, + 0x0, 0x2d, 0xb, 0x7c, 0xff, 0xff, 0xf2, 0x97, + 0x0, 0x2d, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, + 0x0, 0x2d, 0x36, 0xbb, 0xbc, 0xeb, 0xbb, 0xb0, + 0x3, 0x9f, 0xd3, 0x33, 0x36, 0xc3, 0x33, 0x30, + 0x2f, 0xbd, 0x0, 0x0, 0x3, 0xb0, 0x0, 0x0, + 0x1, 0x2d, 0x0, 0xbf, 0xee, 0xee, 0xee, 0x0, + 0x0, 0x2d, 0x0, 0xb3, 0x0, 0x0, 0x1e, 0x0, + 0x0, 0x2d, 0x0, 0xb3, 0x0, 0x0, 0x1e, 0x0, + 0x0, 0x2d, 0x0, 0xb6, 0x33, 0x33, 0x4e, 0x0, + 0xc, 0xf8, 0x0, 0xbc, 0xbb, 0xbb, 0xbe, 0x0, + + /* U+6388 "授" */ + 0x0, 0x0, 0x0, 0x0, 0x12, 0x35, 0x7a, 0x30, + 0x0, 0x1e, 0x0, 0xbd, 0xcb, 0x97, 0x54, 0x0, + 0x0, 0x1e, 0x0, 0x25, 0x3, 0x90, 0x9, 0x70, + 0x19, 0xaf, 0x96, 0x1e, 0x0, 0xe0, 0x1e, 0x10, + 0x18, 0x9f, 0x85, 0xb, 0x30, 0x91, 0x87, 0x0, + 0x0, 0x1e, 0x0, 0xbb, 0xbb, 0xbb, 0xfb, 0xb1, + 0x0, 0x1e, 0x0, 0xe3, 0x33, 0x33, 0x33, 0xe1, + 0x0, 0x1e, 0x67, 0xc0, 0x0, 0x0, 0x0, 0xc1, + 0x16, 0xbf, 0xa4, 0x3c, 0xcc, 0xcc, 0xcb, 0x0, + 0x2a, 0x6e, 0x0, 0x7, 0x91, 0x11, 0x98, 0x0, + 0x0, 0x1e, 0x0, 0x1, 0xe2, 0x2, 0xe1, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x4d, 0x5d, 0x30, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x1b, 0xf9, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0x49, 0xe9, 0x4c, 0xd6, 0x20, + 0xc, 0xf9, 0x7, 0xc7, 0x10, 0x0, 0x4a, 0xe2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6392 "排" */ + 0x0, 0xf, 0x0, 0x0, 0x1d, 0x4, 0xb0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x1e, 0x4, 0xb0, 0x0, + 0x0, 0xf, 0x10, 0x47, 0x8e, 0x4, 0xd7, 0x73, + 0x1f, 0xff, 0xfc, 0x36, 0x7e, 0x4, 0xd6, 0x62, + 0x0, 0xf, 0x0, 0x0, 0x1e, 0x4, 0xb0, 0x0, + 0x0, 0xf, 0x0, 0x1, 0x3e, 0x4, 0xc1, 0x10, + 0x0, 0xf, 0x0, 0x6d, 0xde, 0x4, 0xfd, 0xd3, + 0x0, 0x3f, 0xcd, 0x0, 0x1e, 0x4, 0xb0, 0x0, + 0x2f, 0xbf, 0x30, 0x0, 0x1e, 0x4, 0xb0, 0x0, + 0x0, 0xf, 0x0, 0xdf, 0xfe, 0x4, 0xff, 0xf9, + 0x0, 0xf, 0x0, 0x0, 0x1e, 0x4, 0xc0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x1e, 0x4, 0xb0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x1e, 0x4, 0xb0, 0x0, + 0x9, 0xfb, 0x0, 0x0, 0x1e, 0x4, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+639B "掛" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x68, 0x0, 0xb, 0x30, 0xc, 0x30, 0x0, + 0x0, 0x68, 0x0, 0xb, 0x30, 0xc, 0x30, 0x0, + 0x0, 0x79, 0x7, 0xcf, 0xdc, 0x4c, 0x30, 0x0, + 0x6f, 0xff, 0xf1, 0xb, 0x30, 0xc, 0x30, 0x0, + 0x0, 0x68, 0x0, 0xb, 0x30, 0xc, 0x30, 0x0, + 0x0, 0x68, 0xe, 0xee, 0xee, 0xac, 0xd2, 0x0, + 0x0, 0x69, 0x51, 0x6, 0x20, 0xc, 0x7e, 0x30, + 0x4, 0xcf, 0xc2, 0xb, 0x30, 0xc, 0x33, 0xe1, + 0x8d, 0xc9, 0x1, 0x2c, 0x52, 0x1c, 0x30, 0x10, + 0x0, 0x68, 0x9, 0xcf, 0xdc, 0x6c, 0x30, 0x0, + 0x0, 0x68, 0x0, 0xb, 0x30, 0xc, 0x30, 0x0, + 0x0, 0x68, 0x0, 0xc, 0x76, 0x7c, 0x30, 0x0, + 0x0, 0x78, 0x4d, 0xdb, 0x86, 0x3c, 0x30, 0x0, + 0x1f, 0xe5, 0x0, 0x0, 0x0, 0xc, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+63A1 "採" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x2, 0x35, 0x69, 0xbf, 0x60, + 0x0, 0xf, 0x0, 0xbc, 0xa9, 0x85, 0x30, 0x0, + 0x0, 0x1f, 0x0, 0x30, 0x6, 0x50, 0x1, 0xd1, + 0x1f, 0xff, 0xfb, 0x78, 0x3, 0xc0, 0x7, 0x90, + 0x0, 0xf, 0x0, 0xe, 0x0, 0xf0, 0x1e, 0x10, + 0x0, 0xf, 0x0, 0x6, 0x10, 0x90, 0x96, 0x0, + 0x0, 0xf, 0x77, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x18, 0xdf, 0x93, 0xbb, 0xbb, 0xfc, 0xbb, 0xb2, + 0x19, 0x4f, 0x0, 0x33, 0x4e, 0xff, 0x43, 0x30, + 0x0, 0xf, 0x0, 0x0, 0xb8, 0xe7, 0xc0, 0x0, + 0x0, 0xf, 0x0, 0x9, 0xb0, 0xe1, 0x9a, 0x0, + 0x0, 0xf, 0x2, 0xcb, 0x10, 0xe1, 0xa, 0xc1, + 0x0, 0x1f, 0x8, 0x70, 0x0, 0xe1, 0x0, 0x76, + 0xb, 0xfa, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+63A2 "探" */ + 0x0, 0x2d, 0x0, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0x2d, 0x0, 0xe0, 0x0, 0x0, 0x0, 0xe0, + 0x0, 0x2e, 0x0, 0xb0, 0x12, 0x5, 0x10, 0xb0, + 0x1f, 0xff, 0xf7, 0x0, 0xd5, 0x6, 0xd1, 0x0, + 0x0, 0x2d, 0x0, 0x1c, 0x80, 0x0, 0x6d, 0x10, + 0x0, 0x2d, 0x0, 0xd7, 0x0, 0x70, 0x8, 0x80, + 0x0, 0x2e, 0x64, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x5, 0xbf, 0xa5, 0xcc, 0xcd, 0xfc, 0xcc, 0xc1, + 0x1c, 0x8d, 0x0, 0x22, 0x4f, 0xfe, 0x32, 0x20, + 0x0, 0x2d, 0x0, 0x0, 0xc7, 0xe8, 0x90, 0x0, + 0x0, 0x2d, 0x0, 0x9, 0xa1, 0xe0, 0xc6, 0x0, + 0x0, 0x2d, 0x1, 0xab, 0x1, 0xe0, 0x2d, 0x90, + 0x0, 0x2d, 0xb, 0x70, 0x1, 0xe0, 0x1, 0xc4, + 0xa, 0xe9, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, + + /* U+63A5 "接" */ + 0x0, 0x96, 0x0, 0x0, 0xb, 0x20, 0x0, 0x0, + 0x0, 0x96, 0x0, 0x66, 0x6b, 0xc6, 0x66, 0x30, + 0x0, 0x96, 0x0, 0x69, 0x76, 0x66, 0xa7, 0x30, + 0x8f, 0xff, 0xf1, 0x8, 0x80, 0x5, 0xc0, 0x0, + 0x0, 0x96, 0x0, 0x0, 0xb0, 0xd, 0x20, 0x0, + 0x0, 0x96, 0x9, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x96, 0x10, 0x0, 0x2b, 0x0, 0x0, 0x0, + 0x1, 0xbe, 0xf0, 0x0, 0x98, 0x0, 0x0, 0x0, + 0x8f, 0xf9, 0x1c, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x21, 0x96, 0x0, 0xc, 0x50, 0x2, 0xe0, 0x0, + 0x0, 0x96, 0x0, 0x7f, 0x51, 0xb, 0x70, 0x0, + 0x0, 0x96, 0x0, 0x3, 0x8d, 0xdd, 0x0, 0x0, + 0x0, 0x96, 0x0, 0x25, 0xbd, 0x7b, 0xd6, 0x0, + 0x1f, 0xe3, 0xd, 0xc9, 0x40, 0x0, 0x3c, 0x60, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+63A7 "控" */ + 0x0, 0x1e, 0x0, 0x0, 0x1, 0xd0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x22, 0x22, 0xc8, 0x22, 0x21, + 0x0, 0x2e, 0x0, 0xdc, 0xbb, 0xbb, 0xbb, 0xd8, + 0x1f, 0xff, 0xf9, 0xd2, 0x2, 0x0, 0x10, 0x78, + 0x0, 0x1e, 0x0, 0x40, 0x7c, 0x4, 0xd2, 0x11, + 0x0, 0x1e, 0x0, 0x7, 0xe1, 0x0, 0x4e, 0x30, + 0x0, 0x1e, 0x0, 0x8d, 0x20, 0x0, 0x4, 0xd0, + 0x0, 0x1f, 0xb9, 0x23, 0x22, 0x22, 0x22, 0x20, + 0x1a, 0xff, 0x61, 0x1c, 0xcc, 0xfd, 0xcc, 0x70, + 0x7, 0x3e, 0x0, 0x0, 0x0, 0xd3, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0xd3, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0xd3, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0xd4, 0x0, 0x0, + 0xb, 0xf9, 0x6, 0xee, 0xee, 0xee, 0xee, 0xe9, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+63A8 "推" */ + 0x0, 0xf, 0x0, 0x0, 0xc1, 0x38, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x6, 0xb0, 0xd, 0x20, 0x0, + 0x0, 0xf, 0x0, 0xc, 0x95, 0x5a, 0x95, 0x50, + 0x1f, 0xff, 0xfd, 0x4f, 0xa9, 0x9f, 0x99, 0x80, + 0x0, 0xf, 0x0, 0xdf, 0x10, 0xf, 0x0, 0x0, + 0x0, 0xf, 0x9, 0xae, 0x31, 0x2f, 0x11, 0x10, + 0x0, 0xf, 0x9, 0x1e, 0xdd, 0xdf, 0xdd, 0xb0, + 0x0, 0x2f, 0xcc, 0xe, 0x10, 0xf, 0x0, 0x0, + 0x1d, 0xef, 0x40, 0xe, 0x10, 0xf, 0x0, 0x0, + 0x3, 0xf, 0x0, 0xe, 0xff, 0xff, 0xff, 0xc0, + 0x0, 0xf, 0x0, 0xe, 0x10, 0xf, 0x0, 0x0, + 0x0, 0xf, 0x0, 0xe, 0x10, 0xf, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0xe, 0xfe, 0xff, 0xee, 0xe6, + 0xa, 0xfb, 0x0, 0xe, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+63CF "描" */ + 0x0, 0x1d, 0x0, 0x0, 0xe1, 0x0, 0xe1, 0x0, + 0x0, 0x1d, 0x0, 0x0, 0xe1, 0x0, 0xe1, 0x0, + 0x0, 0x2e, 0x1, 0xdd, 0xfe, 0xdd, 0xfe, 0xd3, + 0x1f, 0xff, 0xfa, 0x0, 0xe2, 0x0, 0xe2, 0x0, + 0x0, 0x1d, 0x0, 0x0, 0xe1, 0x0, 0xe1, 0x0, + 0x0, 0x1d, 0x0, 0x0, 0x71, 0x0, 0x71, 0x0, + 0x0, 0x1d, 0x1, 0x5f, 0xee, 0xfe, 0xef, 0xa0, + 0x0, 0x5f, 0xe8, 0x58, 0x0, 0xe0, 0x5, 0xa0, + 0x2f, 0xce, 0x10, 0x58, 0x0, 0xe0, 0x5, 0xa0, + 0x0, 0x1d, 0x0, 0x5f, 0xee, 0xfe, 0xef, 0xa0, + 0x0, 0x1d, 0x0, 0x58, 0x0, 0xf1, 0x6, 0xa0, + 0x0, 0x1d, 0x0, 0x58, 0x0, 0xe0, 0x5, 0xa0, + 0x0, 0x3d, 0x0, 0x5e, 0xcc, 0xfc, 0xcd, 0xa0, + 0xb, 0xe8, 0x0, 0x59, 0x22, 0x22, 0x27, 0x90, + + /* U+63D0 "提" */ + 0x0, 0x1e, 0x0, 0x3f, 0xdd, 0xdd, 0xdf, 0x10, + 0x0, 0x1e, 0x0, 0x3b, 0x0, 0x0, 0xe, 0x10, + 0x3, 0x5e, 0x32, 0x3f, 0xcc, 0xcc, 0xcf, 0x10, + 0x1a, 0xbf, 0xa7, 0x3b, 0x0, 0x0, 0xe, 0x10, + 0x0, 0x1e, 0x0, 0x3f, 0xcc, 0xcc, 0xcf, 0x10, + 0x0, 0x1e, 0x0, 0x1, 0x11, 0x11, 0x11, 0x0, + 0x0, 0x1e, 0x34, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, + 0x4, 0x9f, 0xd5, 0x33, 0x33, 0xf3, 0x33, 0x30, + 0x2d, 0x8e, 0x0, 0xe, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x3e, 0x0, 0xfd, 0xcc, 0x20, + 0x0, 0x1e, 0x0, 0x7f, 0x10, 0xf1, 0x11, 0x0, + 0x0, 0x1e, 0x0, 0xc8, 0xa0, 0xf0, 0x0, 0x0, + 0x0, 0x1e, 0x5, 0xc0, 0xab, 0xf1, 0x0, 0x0, + 0xa, 0xeb, 0x1e, 0x20, 0x6, 0xce, 0xff, 0xf5, + 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+63DB "換" */ + 0x0, 0x77, 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, + 0x0, 0x77, 0x0, 0x3, 0xfe, 0xef, 0x10, 0x0, + 0x13, 0x99, 0x30, 0x2d, 0x40, 0x59, 0x0, 0x0, + 0x3a, 0xdc, 0xa2, 0xef, 0xdd, 0xfd, 0xdd, 0x0, + 0x0, 0x77, 0x1, 0x7c, 0x2, 0x12, 0xd, 0x0, + 0x0, 0x77, 0x0, 0x1c, 0xc, 0x1b, 0xd, 0x0, + 0x0, 0x79, 0x60, 0x1c, 0x66, 0x7, 0x5d, 0x0, + 0x16, 0xdf, 0x90, 0x1c, 0xb0, 0x51, 0x9d, 0x0, + 0x6b, 0xb7, 0x0, 0x1c, 0x2, 0xc0, 0xd, 0x0, + 0x0, 0x77, 0x9, 0xcf, 0xbc, 0xeb, 0xbf, 0xc1, + 0x0, 0x77, 0x1, 0x22, 0x2c, 0xe6, 0x22, 0x20, + 0x0, 0x77, 0x0, 0x0, 0x6c, 0x2d, 0x10, 0x0, + 0x0, 0x87, 0x0, 0x3a, 0xc1, 0x4, 0xd7, 0x10, + 0xf, 0xe3, 0xd, 0xb5, 0x0, 0x0, 0x18, 0xd1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+63EE "揮" */ + 0x0, 0xf, 0x0, 0xde, 0xee, 0xee, 0xee, 0xf5, + 0x0, 0xf, 0x0, 0xd1, 0x0, 0x80, 0x0, 0x95, + 0x2, 0x2f, 0x21, 0x50, 0x0, 0xe1, 0x0, 0x32, + 0x1d, 0xdf, 0xda, 0x6d, 0xdd, 0xfe, 0xdd, 0xd0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x3e, 0xcc, 0xfd, 0xcd, 0xb0, + 0x0, 0xf, 0x45, 0x3b, 0x0, 0xe1, 0x3, 0xb0, + 0x5, 0xaf, 0xc5, 0x3e, 0xcc, 0xfc, 0xcd, 0xb0, + 0x2c, 0x7f, 0x0, 0x3b, 0x0, 0xe1, 0x3, 0xb0, + 0x0, 0xf, 0x0, 0x3e, 0xcc, 0xfc, 0xcd, 0xb0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0xf, 0x6, 0xee, 0xee, 0xfe, 0xee, 0xea, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0xa, 0xfa, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + + /* U+63FA "揺" */ + 0x0, 0xf, 0x10, 0x1, 0x24, 0x57, 0xad, 0x90, + 0x0, 0xf, 0x11, 0xdc, 0xba, 0x87, 0x42, 0x10, + 0x0, 0xf, 0x10, 0x27, 0x6, 0x70, 0x6, 0xc0, + 0x3f, 0xff, 0xfe, 0xd, 0x12, 0xd0, 0xe, 0x20, + 0x0, 0xf, 0x10, 0x6, 0x30, 0x60, 0x98, 0x0, + 0x0, 0xf, 0x10, 0xde, 0xee, 0xee, 0xff, 0xe2, + 0x0, 0xf, 0x13, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x3f, 0xee, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x3e, 0xdf, 0x44, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0x1, 0xf, 0x10, 0x43, 0x0, 0xf0, 0x1, 0x60, + 0x0, 0xf, 0x10, 0x87, 0x0, 0xf0, 0x2, 0xd0, + 0x0, 0xf, 0x10, 0x87, 0x0, 0xf0, 0x2, 0xd0, + 0x0, 0xf, 0x10, 0x8e, 0xcc, 0xfc, 0xcd, 0xd0, + 0xa, 0xfc, 0x0, 0x88, 0x22, 0x22, 0x24, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+643A "携" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x69, 0x0, 0xa, 0x33, 0xc1, 0x0, 0x0, + 0x0, 0x69, 0x0, 0x2f, 0xdd, 0xfe, 0xdd, 0x90, + 0x3, 0x9b, 0x31, 0xdb, 0x0, 0xe1, 0x0, 0x0, + 0x3d, 0xee, 0xdc, 0xce, 0xbb, 0xfc, 0xbb, 0x50, + 0x0, 0x69, 0x5, 0x3b, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0x69, 0x0, 0x2e, 0xbb, 0xfb, 0xbb, 0x50, + 0x0, 0x69, 0x30, 0x2b, 0x0, 0xe1, 0x0, 0x0, + 0x1, 0x9f, 0xd1, 0x2f, 0xdd, 0xdd, 0xdd, 0xd1, + 0x3f, 0xda, 0x1, 0x47, 0x44, 0x44, 0x10, 0x0, + 0x0, 0x69, 0x2, 0x99, 0xf9, 0xaf, 0x10, 0x0, + 0x0, 0x69, 0x0, 0x2, 0xc0, 0x4e, 0xdd, 0xe2, + 0x0, 0x69, 0x0, 0xa, 0x60, 0x0, 0x0, 0xf0, + 0x0, 0x79, 0x0, 0x9c, 0x0, 0x0, 0x4, 0xd0, + 0xe, 0xf5, 0xc, 0xa0, 0x0, 0x1e, 0xdd, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+64C1 "擁" */ + 0x0, 0x58, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, + 0x0, 0x58, 0xb, 0xcc, 0xce, 0xec, 0xcc, 0xc1, + 0x4, 0x8a, 0x41, 0x62, 0x22, 0x62, 0x42, 0x20, + 0x1e, 0xff, 0xd0, 0xd1, 0x2, 0xe0, 0xd0, 0x0, + 0x0, 0x58, 0x3, 0xa0, 0x8, 0xa3, 0xb6, 0x30, + 0x0, 0x58, 0xb, 0x48, 0x7e, 0xba, 0xfa, 0xa0, + 0x0, 0x59, 0x3e, 0xce, 0xaf, 0x30, 0xd0, 0x0, + 0x2, 0xaf, 0xc0, 0x76, 0x4b, 0xdc, 0xfc, 0x80, + 0x1f, 0xd9, 0x1, 0xc0, 0xba, 0x30, 0xd0, 0x0, + 0x1, 0x58, 0xa, 0xef, 0x8a, 0x52, 0xe2, 0x10, + 0x0, 0x58, 0x8, 0x4b, 0x2a, 0xb9, 0xf9, 0x60, + 0x0, 0x58, 0x0, 0x5a, 0xa, 0x30, 0xd0, 0x0, + 0x0, 0x68, 0x6, 0xd0, 0xa, 0xed, 0xfd, 0xd2, + 0xd, 0xe5, 0x2c, 0x10, 0xa, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+64C7 "擇" */ + 0x0, 0x1e, 0x0, 0xad, 0xcf, 0xcf, 0xdc, 0xf0, + 0x0, 0x1e, 0x0, 0xa4, 0xd, 0xc, 0x10, 0xe0, + 0x5, 0x6e, 0x53, 0xa9, 0x6e, 0x6d, 0x76, 0xe0, + 0x9, 0xaf, 0x95, 0x35, 0x55, 0xe5, 0x55, 0x50, + 0x0, 0x1e, 0x0, 0x4a, 0xaa, 0xfa, 0xaa, 0x60, + 0x0, 0x1e, 0x0, 0x13, 0x33, 0xd3, 0x33, 0x20, + 0x0, 0x1e, 0x23, 0x22, 0x22, 0xd2, 0x22, 0x20, + 0x2, 0x7f, 0xe7, 0xbb, 0xeb, 0xbb, 0xec, 0xb1, + 0x1d, 0x9e, 0x0, 0x0, 0xd2, 0x2, 0xe1, 0x0, + 0x0, 0x1e, 0x0, 0xbd, 0xed, 0xee, 0xed, 0xb0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, + 0x0, 0x1e, 0x5, 0xdd, 0xdd, 0xfd, 0xdd, 0xd5, + 0x1, 0x3e, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, + 0xb, 0xe8, 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, + + /* U+64D4 "擔" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x68, 0x0, 0x4, 0xdc, 0xce, 0xa0, 0x0, + 0x0, 0x68, 0x0, 0x1b, 0x0, 0xe, 0x40, 0x0, + 0x0, 0x69, 0x1, 0xce, 0xbb, 0xcf, 0xcb, 0xb5, + 0x3f, 0xff, 0xf7, 0xf6, 0x47, 0x84, 0x95, 0x41, + 0x0, 0x68, 0x0, 0xc2, 0x5b, 0x10, 0x4c, 0x50, + 0x0, 0x68, 0x0, 0xc4, 0x70, 0x3a, 0x0, 0x80, + 0x0, 0x69, 0x40, 0xca, 0xbb, 0xbe, 0xbb, 0xb5, + 0x2, 0xaf, 0xc1, 0xd1, 0x33, 0x33, 0x33, 0x20, + 0x3e, 0xc9, 0x0, 0xe0, 0x67, 0x77, 0x77, 0x40, + 0x0, 0x68, 0x0, 0xe0, 0x9b, 0xbb, 0xbb, 0x50, + 0x0, 0x68, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x68, 0x3, 0xb0, 0xeb, 0xbb, 0xbc, 0xb0, + 0x0, 0x78, 0x7, 0x70, 0xe1, 0x0, 0x4, 0xb0, + 0xd, 0xd4, 0xb, 0x10, 0xeb, 0xbb, 0xbc, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+64DA "據" */ + 0x0, 0x68, 0x0, 0x0, 0x6, 0xed, 0xdd, 0x30, + 0x0, 0x68, 0x0, 0x0, 0x6, 0x90, 0x0, 0x0, + 0x0, 0x68, 0x0, 0xcc, 0xcd, 0xec, 0xcc, 0xb1, + 0x3f, 0xff, 0xe1, 0xf4, 0x4a, 0x84, 0x47, 0xd0, + 0x0, 0x68, 0x1, 0xe3, 0x7c, 0xca, 0xa4, 0x50, + 0x0, 0x68, 0x1, 0xe2, 0x38, 0x83, 0x36, 0x80, + 0x0, 0x68, 0x41, 0xe0, 0x1, 0x67, 0x77, 0x20, + 0x2, 0xaf, 0xc2, 0xd7, 0xcc, 0xfd, 0xcc, 0xb0, + 0x3e, 0xc8, 0x3, 0xc0, 0x3a, 0xd0, 0x2, 0x70, + 0x0, 0x68, 0x5, 0xa6, 0x73, 0xc8, 0x8a, 0x20, + 0x0, 0x68, 0x7, 0x82, 0x89, 0x3f, 0x79, 0x0, + 0x0, 0x68, 0xc, 0x48, 0x25, 0xab, 0x2a, 0x40, + 0x0, 0x68, 0x3d, 0x6, 0xb6, 0xb, 0x21, 0xb5, + 0xd, 0xe4, 0x84, 0x27, 0x4, 0xca, 0x0, 0x1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+652F "支" */ + 0x0, 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, + 0x1, 0x11, 0x11, 0x1c, 0x61, 0x11, 0x11, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x11, 0x11, 0x1c, 0x61, 0x11, 0x10, 0x0, + 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x0, + 0x0, 0x8, 0xa0, 0x0, 0x0, 0xc, 0x70, 0x0, + 0x0, 0x0, 0xd6, 0x0, 0x0, 0x8d, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x50, 0x7, 0xe2, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xe8, 0xad, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x1, 0x9f, 0xf6, 0x0, 0x0, 0x0, + 0x0, 0x14, 0xaf, 0xa3, 0x6d, 0xe8, 0x30, 0x0, + 0x4d, 0xfc, 0x81, 0x0, 0x0, 0x49, 0xdf, 0xc0, + 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x30, + + /* U+6539 "改" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x11, 0x11, 0x10, 0x6, 0xb0, 0x0, 0x0, 0x8f, + 0xff, 0xff, 0x10, 0xb6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf1, 0xf, 0x63, 0x33, 0x31, 0x0, 0x0, + 0xf, 0x15, 0xfc, 0xcc, 0xfd, 0x50, 0x0, 0x0, + 0xf1, 0xdd, 0x0, 0xf, 0x20, 0x4e, 0xee, 0xef, + 0x7c, 0xc2, 0x3, 0xd0, 0x4, 0xc2, 0x22, 0x2b, + 0x37, 0x70, 0x79, 0x0, 0x4c, 0x0, 0x0, 0x0, + 0x2d, 0xe, 0x40, 0x4, 0xc0, 0x0, 0x0, 0x0, + 0xca, 0xc0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x4, + 0xf5, 0x0, 0x4, 0xc0, 0x39, 0xe2, 0x0, 0xaf, + 0x90, 0x0, 0x6e, 0xde, 0x82, 0x0, 0xac, 0x2e, + 0x70, 0xa, 0xb4, 0x0, 0x4, 0xdc, 0x10, 0x2e, + 0xb1, 0x0, 0x0, 0x0, 0xd7, 0x0, 0x0, 0x1a, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+653E "放" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x6, 0xa0, 0x0, 0x4, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0x8, 0x90, 0x0, 0x0, + 0x19, 0x99, 0xb9, 0x98, 0xd, 0x83, 0x33, 0x31, + 0x16, 0x9e, 0x66, 0x66, 0x2f, 0xcc, 0xcf, 0xd4, + 0x0, 0x3c, 0x0, 0x0, 0x9f, 0x10, 0xf, 0x0, + 0x0, 0x3f, 0xcc, 0xc4, 0xeb, 0x50, 0x4c, 0x0, + 0x0, 0x4d, 0x33, 0xea, 0x85, 0x90, 0x88, 0x0, + 0x0, 0x4b, 0x0, 0xe2, 0x1, 0xe0, 0xe3, 0x0, + 0x0, 0x5a, 0x0, 0xf1, 0x0, 0xbb, 0xc0, 0x0, + 0x0, 0x88, 0x0, 0xf0, 0x0, 0x4f, 0x40, 0x0, + 0x0, 0xc4, 0x0, 0xf0, 0x0, 0xaf, 0x80, 0x0, + 0x2, 0xe0, 0x2, 0xe0, 0x8, 0xd3, 0xe5, 0x0, + 0xc, 0x70, 0x5, 0xc2, 0xbd, 0x10, 0x4f, 0x70, + 0x3b, 0x4, 0xfe, 0x5c, 0x90, 0x0, 0x3, 0xd3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+653F "政" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x11, 0x5, 0xc0, 0x0, 0x0, + 0x2f, 0xff, 0xff, 0xff, 0x2a, 0x80, 0x0, 0x0, + 0x0, 0x0, 0xb4, 0x0, 0xe, 0x73, 0x33, 0x31, + 0x0, 0x0, 0xb4, 0x0, 0x4f, 0xcc, 0xcf, 0xd3, + 0x4, 0x50, 0xb4, 0x0, 0xce, 0x0, 0xf, 0x0, + 0x7, 0x80, 0xbd, 0xcb, 0xed, 0x20, 0x4c, 0x0, + 0x7, 0x80, 0xb7, 0x3b, 0x58, 0x60, 0x88, 0x0, + 0x7, 0x80, 0xb4, 0x0, 0x3, 0xc0, 0xe3, 0x0, + 0x7, 0x80, 0xb4, 0x0, 0x0, 0xd9, 0xc0, 0x0, + 0x7, 0x80, 0xb4, 0x0, 0x0, 0x6f, 0x40, 0x0, + 0x7, 0x82, 0xdc, 0xdf, 0x20, 0xaf, 0x70, 0x0, + 0x3d, 0xfe, 0xa7, 0x30, 0x9, 0xd4, 0xf4, 0x0, + 0x26, 0x20, 0x0, 0x2, 0xcd, 0x10, 0x5f, 0x80, + 0x0, 0x0, 0x0, 0xa, 0x80, 0x0, 0x3, 0xc2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6545 "故" */ + 0x0, 0x1, 0xf0, 0x0, 0x7, 0x80, 0x0, 0x0, + 0x0, 0x1, 0xf0, 0x0, 0xc, 0x50, 0x0, 0x0, + 0x0, 0x2, 0xf0, 0x0, 0x1f, 0x43, 0x33, 0x31, + 0x1f, 0xff, 0xff, 0xfd, 0x5e, 0xcc, 0xcf, 0xd4, + 0x0, 0x1, 0xf0, 0x0, 0xcc, 0x0, 0x1f, 0x0, + 0x0, 0x1, 0xf0, 0x4, 0xee, 0x0, 0x4b, 0x0, + 0x0, 0x2, 0xf0, 0xd, 0x5a, 0x40, 0x87, 0x0, + 0x6, 0xfe, 0xee, 0xf6, 0x5, 0xa0, 0xe2, 0x0, + 0x6, 0x90, 0x0, 0xc3, 0x0, 0xe7, 0xb0, 0x0, + 0x6, 0x90, 0x0, 0xc3, 0x0, 0x8f, 0x30, 0x0, + 0x6, 0x90, 0x0, 0xc3, 0x0, 0xaf, 0x40, 0x0, + 0x6, 0xec, 0xcc, 0xf3, 0x9, 0xb4, 0xe1, 0x0, + 0x6, 0xb2, 0x22, 0x23, 0xcc, 0x0, 0x8d, 0x30, + 0x4, 0x70, 0x0, 0x4f, 0x80, 0x0, 0x7, 0xf3, + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x30, + + /* U+6548 "效" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x8, 0xa0, 0x0, 0x0, 0xd3, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x1, 0xf0, 0x0, 0x0, + 0xd, 0xdd, 0xed, 0xdd, 0x24, 0xd4, 0x44, 0x41, + 0x2, 0x44, 0x23, 0x42, 0x8, 0xdb, 0xbf, 0xd2, + 0x0, 0xb5, 0x4, 0xd0, 0xe, 0x30, 0xe, 0x20, + 0x4, 0xd0, 0x0, 0x98, 0x4f, 0x30, 0x1e, 0x0, + 0x1e, 0x40, 0x6, 0x68, 0xdc, 0x80, 0x5b, 0x0, + 0x16, 0x7a, 0xd, 0x30, 0x92, 0xc0, 0xa7, 0x0, + 0x0, 0xb, 0xcc, 0x0, 0x0, 0xb4, 0xe1, 0x0, + 0x0, 0x0, 0xfa, 0x0, 0x0, 0x5e, 0x90, 0x0, + 0x0, 0x7, 0xce, 0x50, 0x0, 0x3f, 0x50, 0x0, + 0x0, 0x4e, 0x14, 0xe1, 0x1, 0xea, 0xe1, 0x0, + 0x6, 0xe4, 0x0, 0x72, 0x3d, 0x70, 0x8d, 0x20, + 0x1d, 0x20, 0x0, 0x8, 0xe6, 0x0, 0x8, 0xf2, + 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, 0x30, + + /* U+6557 "敗" */ + 0x0, 0x0, 0x0, 0x0, 0x5, 0x30, 0x0, 0x0, + 0xc, 0xee, 0xee, 0xe0, 0xd, 0x40, 0x0, 0x0, + 0xc, 0x30, 0x2, 0xe0, 0x1f, 0x10, 0x0, 0x0, + 0xc, 0x30, 0x2, 0xe0, 0x6f, 0x88, 0x88, 0x82, + 0xc, 0xed, 0xde, 0xe0, 0xbc, 0x77, 0x9f, 0x71, + 0xc, 0x30, 0x2, 0xe2, 0xfb, 0x0, 0x5b, 0x0, + 0xc, 0x30, 0x2, 0xeb, 0xaf, 0x0, 0x98, 0x0, + 0xc, 0xed, 0xde, 0xfd, 0xc, 0x30, 0xd4, 0x0, + 0xc, 0x30, 0x2, 0xe0, 0x7, 0xa3, 0xe0, 0x0, + 0xc, 0x30, 0x2, 0xe0, 0x1, 0xfb, 0x80, 0x0, + 0xc, 0xfe, 0xee, 0xe0, 0x0, 0xaf, 0x10, 0x0, + 0x0, 0x72, 0x17, 0x0, 0x0, 0xcf, 0x40, 0x0, + 0x3, 0xe0, 0xb, 0x70, 0xb, 0xb6, 0xf2, 0x0, + 0xc, 0x70, 0x2, 0xe4, 0xdc, 0x0, 0x8f, 0x60, + 0x6b, 0x0, 0x0, 0x1d, 0x80, 0x0, 0x5, 0xe2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6559 "教" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xb0, 0x3, 0x80, 0xd3, 0x0, 0x0, + 0x6, 0xef, 0xfe, 0xcc, 0x51, 0xf0, 0x0, 0x0, + 0x0, 0x4, 0xc0, 0x5c, 0x5, 0xe9, 0x99, 0x93, + 0x0, 0x5, 0xc1, 0xe5, 0xa, 0xc8, 0x8e, 0xb3, + 0x1e, 0xee, 0xef, 0xfe, 0xaf, 0x90, 0xe, 0x20, + 0x0, 0x0, 0x8c, 0x0, 0x8d, 0xc0, 0x1e, 0x0, + 0x0, 0xbe, 0xfe, 0xda, 0xf2, 0xe1, 0x5b, 0x0, + 0x3, 0xca, 0x17, 0xb1, 0x10, 0xb6, 0xb6, 0x0, + 0xc, 0x50, 0x89, 0x0, 0x0, 0x5c, 0xe0, 0x0, + 0x1, 0x34, 0xca, 0x9b, 0x90, 0xe, 0x90, 0x0, + 0xd, 0xba, 0xd9, 0x43, 0x10, 0x5f, 0xc0, 0x0, + 0x0, 0x0, 0xa5, 0x0, 0x4, 0xf4, 0xc8, 0x0, + 0x0, 0x0, 0xb5, 0x1, 0x9f, 0x40, 0x2e, 0xa0, + 0x0, 0x7e, 0xd2, 0x4, 0xb2, 0x0, 0x1, 0xc2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6562 "敢" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb3, 0x0, 0x0, + 0x3, 0xee, 0xee, 0xf2, 0x1, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf0, 0x4, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xc0, 0x8, 0xc5, 0x55, 0x51, + 0x1e, 0xee, 0xef, 0xfe, 0x9c, 0xdc, 0xdf, 0xd4, + 0x0, 0xd3, 0x0, 0xb5, 0x2f, 0x40, 0x1e, 0x0, + 0x0, 0xc2, 0x0, 0xb4, 0x9f, 0x70, 0x4b, 0x0, + 0x0, 0xce, 0xdd, 0xf5, 0xf7, 0xb0, 0x78, 0x0, + 0x0, 0xc2, 0x0, 0xb4, 0x40, 0xf0, 0xc4, 0x0, + 0x0, 0xce, 0xdd, 0xf4, 0x0, 0xb8, 0xe0, 0x0, + 0x0, 0xc2, 0x0, 0xb4, 0x0, 0x3f, 0x80, 0x0, + 0x0, 0xc4, 0x36, 0xdc, 0x70, 0x3f, 0x80, 0x0, + 0x3d, 0xfe, 0xb9, 0xd7, 0x11, 0xe7, 0xe5, 0x0, + 0x13, 0x0, 0x0, 0xb4, 0x3e, 0x80, 0x3f, 0x80, + 0x0, 0x0, 0x0, 0xb4, 0xc5, 0x0, 0x2, 0xc3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6570 "数" */ + 0x2, 0x40, 0xb4, 0x8, 0x0, 0xb1, 0x0, 0x0, + 0x0, 0xd1, 0xb4, 0x78, 0x1, 0xf0, 0x0, 0x0, + 0x2, 0x85, 0xc6, 0x93, 0x14, 0xc0, 0x0, 0x0, + 0xb, 0xbc, 0xfe, 0xbb, 0x78, 0xfe, 0xef, 0xf3, + 0x0, 0xb, 0xfd, 0x90, 0xc, 0x80, 0xf, 0x0, + 0x1, 0xb8, 0xb4, 0x7d, 0x3f, 0xc0, 0x2d, 0x0, + 0xd, 0x70, 0xa4, 0x2, 0xb5, 0xd0, 0x69, 0x0, + 0x1, 0x4, 0x80, 0x0, 0x80, 0x85, 0xb5, 0x0, + 0xb, 0xff, 0xfe, 0xfc, 0x0, 0x3c, 0xe0, 0x0, + 0x0, 0x5b, 0x0, 0xa6, 0x0, 0xd, 0x80, 0x0, + 0x0, 0xcb, 0x25, 0xd0, 0x0, 0x3f, 0xb0, 0x0, + 0x0, 0x5, 0xef, 0x40, 0x1, 0xd5, 0xc7, 0x0, + 0x0, 0x2a, 0xc7, 0xe2, 0x3d, 0x70, 0x2e, 0x70, + 0xc, 0xd6, 0x0, 0x5, 0xe5, 0x0, 0x2, 0xd5, + 0x1, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x10, + + /* U+6574 "整" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0xc, 0xdd, 0xfe, 0xdd, 0x30, 0xe4, 0x33, 0x31, + 0x0, 0x0, 0xb3, 0x0, 0x6, 0xff, 0xff, 0xf5, + 0x5, 0xbb, 0xec, 0xb9, 0x2e, 0x93, 0x3f, 0x41, + 0x7, 0x60, 0xb3, 0x1d, 0xc8, 0xc0, 0x5b, 0x0, + 0x7, 0xdb, 0xec, 0xcd, 0x10, 0x79, 0xe3, 0x0, + 0x0, 0x8, 0xfb, 0x50, 0x0, 0x1f, 0xa0, 0x0, + 0x0, 0x8a, 0xc4, 0xb7, 0x2, 0xd9, 0xd8, 0x0, + 0xc, 0x90, 0xb3, 0x3, 0x9d, 0x40, 0x9, 0xd3, + 0x1, 0xdd, 0xfe, 0xdd, 0xfd, 0xdd, 0xdd, 0x50, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x4, 0x60, 0x7, 0xa2, 0x22, 0x20, 0x0, + 0x0, 0x6, 0x90, 0x7, 0xdb, 0xbb, 0xb2, 0x0, + 0x0, 0x6, 0x90, 0x7, 0x90, 0x0, 0x0, 0x0, + 0x1e, 0xef, 0xfe, 0xef, 0xfe, 0xee, 0xee, 0xe6, + + /* U+6587 "文" */ + 0x0, 0x0, 0x0, 0x9, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0, + 0x2c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc3, + 0x4, 0x4a, 0xb4, 0x44, 0x44, 0x4c, 0xa4, 0x41, + 0x0, 0x1, 0xe1, 0x0, 0x0, 0x2f, 0x20, 0x0, + 0x0, 0x0, 0x98, 0x0, 0x0, 0x9a, 0x0, 0x0, + 0x0, 0x0, 0x1e, 0x30, 0x2, 0xf2, 0x0, 0x0, + 0x0, 0x0, 0x6, 0xe1, 0xd, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9c, 0xbb, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0xeb, 0xae, 0x50, 0x0, 0x0, + 0x0, 0x2, 0x9f, 0x60, 0x6, 0xfa, 0x20, 0x0, + 0x5, 0xcf, 0xa2, 0x0, 0x0, 0x2a, 0xfc, 0x60, + 0x1d, 0x71, 0x0, 0x0, 0x0, 0x0, 0x17, 0xc1, + + /* U+6599 "料" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x60, 0x0, 0x0, 0x0, 0xe1, 0x0, + 0xd, 0x9, 0x61, 0xd0, 0x77, 0x0, 0xe1, 0x0, + 0xa, 0x49, 0x66, 0x80, 0xa, 0xb0, 0xe1, 0x0, + 0x5, 0x89, 0x6b, 0x10, 0x0, 0x60, 0xe1, 0x0, + 0x1, 0x39, 0x64, 0x0, 0x0, 0x0, 0xe1, 0x0, + 0x3f, 0xff, 0xff, 0xf6, 0xd3, 0x0, 0xe1, 0x0, + 0x0, 0x1f, 0xa0, 0x0, 0x3d, 0x40, 0xe1, 0x0, + 0x0, 0x8e, 0xe6, 0x0, 0x1, 0x0, 0xe1, 0x0, + 0x0, 0xda, 0x6d, 0x30, 0x0, 0x1, 0xf8, 0xa1, + 0x7, 0x89, 0x64, 0x95, 0x9c, 0xed, 0xf9, 0x50, + 0x2e, 0x19, 0x60, 0x8, 0x63, 0x10, 0xe1, 0x0, + 0x35, 0x9, 0x60, 0x0, 0x0, 0x0, 0xe1, 0x0, + 0x0, 0x9, 0x60, 0x0, 0x0, 0x0, 0xe1, 0x0, + 0x0, 0x9, 0x60, 0x0, 0x0, 0x0, 0xe1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+65AD "断" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0x23, 0xe, 0x5, 0x0, 0x36, 0xaa, 0x50, 0xd2, + 0xc0, 0xe0, 0xd1, 0xf9, 0x51, 0x0, 0xd, 0x2a, + 0x2e, 0x56, 0x1e, 0x0, 0x0, 0x0, 0xd2, 0x42, + 0xe6, 0x1, 0xe0, 0x0, 0x0, 0xd, 0x69, 0x9f, + 0x99, 0x3e, 0x0, 0x0, 0x0, 0xd4, 0x58, 0xf6, + 0x52, 0xff, 0xff, 0xff, 0x2d, 0x20, 0xbf, 0xa0, + 0x1e, 0x0, 0xd2, 0x0, 0xd2, 0x3b, 0xe8, 0x72, + 0xd0, 0xd, 0x20, 0xd, 0x3d, 0x2e, 0xc, 0x4c, + 0x0, 0xd2, 0x0, 0xda, 0x80, 0xe0, 0x4, 0xb0, + 0xd, 0x20, 0xd, 0x40, 0xe, 0x0, 0x69, 0x0, + 0xd2, 0x0, 0xd4, 0x22, 0x92, 0x2a, 0x60, 0xd, + 0x20, 0xa, 0xcc, 0xcc, 0xcb, 0xe1, 0x0, 0xd2, + 0x0, 0x0, 0x0, 0x0, 0x3a, 0x0, 0xd, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+65B0 "新" */ + 0x0, 0x3, 0x60, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x1, 0xe1, 0x0, 0x3, 0x69, 0xed, 0x40, + 0xe, 0xee, 0xff, 0xee, 0x3e, 0x85, 0x10, 0x0, + 0x0, 0xa1, 0x0, 0xb0, 0x2c, 0x0, 0x0, 0x0, + 0x0, 0xa6, 0x5, 0xb0, 0x2c, 0x0, 0x0, 0x0, + 0x0, 0x67, 0xa, 0x60, 0x2c, 0x0, 0x0, 0x0, + 0x3d, 0xdd, 0xfe, 0xdd, 0x6f, 0xff, 0xff, 0xf4, + 0x0, 0x0, 0xe0, 0x0, 0x2c, 0x0, 0xc4, 0x0, + 0x2, 0x22, 0xe3, 0x22, 0x4b, 0x0, 0xb4, 0x0, + 0x2c, 0xcc, 0xfc, 0xcc, 0x69, 0x0, 0xb4, 0x0, + 0x0, 0x70, 0xe1, 0x60, 0x58, 0x0, 0xb4, 0x0, + 0x4, 0xb0, 0xe0, 0xc3, 0x87, 0x0, 0xb4, 0x0, + 0xd, 0x30, 0xe0, 0x4a, 0xc3, 0x0, 0xb4, 0x0, + 0x5, 0x0, 0xe0, 0x3, 0xd0, 0x0, 0xb4, 0x0, + 0x0, 0x2e, 0xc0, 0x6, 0x60, 0x0, 0xb4, 0x0, + + /* U+65B7 "斷" */ + 0x0, 0x2, 0x0, 0x40, 0x0, 0x0, 0x53, 0xd, + 0x17, 0x50, 0x38, 0x0, 0x38, 0xdb, 0x40, 0xd3, + 0xb8, 0x5c, 0x69, 0xe, 0x51, 0x0, 0xd, 0x6b, + 0x92, 0x9c, 0x10, 0xe0, 0x0, 0x0, 0xd2, 0xb8, + 0x3a, 0x6a, 0xe, 0x0, 0x0, 0xd, 0x68, 0x78, + 0x86, 0x90, 0xe6, 0x66, 0x61, 0xdd, 0xdd, 0xdd, + 0xdd, 0x1e, 0x78, 0xe7, 0x1d, 0x12, 0x30, 0x6, + 0x0, 0xe0, 0x1d, 0x0, 0xd1, 0x93, 0x16, 0x54, + 0xe, 0x1, 0xd0, 0xd, 0x5c, 0xa6, 0xd8, 0x71, + 0xd0, 0x1d, 0x0, 0xd6, 0x99, 0x27, 0xc1, 0x2c, + 0x1, 0xd0, 0xd, 0x3b, 0x92, 0xb7, 0x85, 0x90, + 0x1d, 0x0, 0xd7, 0x87, 0x88, 0x68, 0x86, 0x1, + 0xd0, 0xd, 0xed, 0xed, 0xdd, 0x8e, 0x10, 0x1d, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x80, 0x1, 0xd0, + 0x0, + + /* U+65B9 "方" */ + 0x0, 0x0, 0x0, 0x6, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7b, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xe1, 0x0, 0x0, 0x0, 0xbd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0x3, 0x33, + 0x39, 0xc3, 0x33, 0x33, 0x33, 0x30, 0x0, 0x0, + 0x89, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, + 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, + 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0xf, 0x41, + 0x11, 0x11, 0xe3, 0x0, 0x0, 0x4, 0xf0, 0x0, + 0x0, 0xf, 0x20, 0x0, 0x0, 0xaa, 0x0, 0x0, + 0x0, 0xf0, 0x0, 0x0, 0x3f, 0x20, 0x0, 0x0, + 0x3e, 0x0, 0x0, 0xd, 0x90, 0x0, 0x0, 0x5, + 0xc0, 0x0, 0x2c, 0xb0, 0x0, 0x1, 0x1, 0xb8, + 0x0, 0xd, 0x80, 0x0, 0x2, 0xff, 0xfc, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+65BC "於" */ + 0x0, 0x18, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, + 0x0, 0xb, 0x70, 0x0, 0x0, 0x89, 0x0, 0x0, + 0x0, 0x2, 0xc0, 0x0, 0x0, 0xdd, 0x10, 0x0, + 0x3f, 0xff, 0xff, 0xf4, 0x7, 0x85, 0xa0, 0x0, + 0x0, 0x98, 0x0, 0x0, 0x3e, 0x0, 0xb6, 0x0, + 0x0, 0x97, 0x0, 0x3, 0xe4, 0x0, 0x1e, 0x70, + 0x0, 0x99, 0x33, 0x3e, 0x50, 0x0, 0x2, 0xe3, + 0x0, 0xad, 0xcd, 0xa1, 0x4, 0xb1, 0x0, 0x0, + 0x0, 0xb5, 0x7, 0x90, 0x0, 0x7e, 0x40, 0x0, + 0x0, 0xd2, 0x7, 0x80, 0x0, 0x4, 0x70, 0x0, + 0x0, 0xf0, 0x8, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xe0, 0xa, 0x60, 0x17, 0x0, 0x0, 0x0, + 0x7, 0xb0, 0xb, 0x40, 0x2b, 0xe5, 0x0, 0x0, + 0xe, 0x50, 0xe, 0x20, 0x0, 0x4e, 0xb1, 0x0, + 0x4c, 0xa, 0xfb, 0x0, 0x0, 0x0, 0xa2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+65BD "施" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x40, 0x0, 0x5c, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xb0, 0x0, 0xa6, 0x0, 0x0, 0x0, + 0x28, 0x89, 0xd8, 0x82, 0xff, 0xee, 0xee, 0xe5, + 0x27, 0xbb, 0x77, 0x7b, 0x81, 0x15, 0x11, 0x10, + 0x0, 0x97, 0x0, 0x3d, 0x60, 0x1d, 0x3, 0x50, + 0x0, 0xac, 0x99, 0x41, 0xe1, 0x1f, 0xce, 0xb0, + 0x0, 0xba, 0x6b, 0x70, 0xe7, 0xdf, 0x53, 0xb0, + 0x0, 0xc4, 0x9, 0x65, 0xfb, 0x5d, 0x3, 0xb0, + 0x0, 0xd1, 0x9, 0x6a, 0xf1, 0x1d, 0x4, 0xb0, + 0x0, 0xe0, 0xa, 0x50, 0xe1, 0x1d, 0x4, 0xa0, + 0x3, 0xd0, 0xb, 0x50, 0xe1, 0x1d, 0x6d, 0x40, + 0x8, 0x80, 0xc, 0x40, 0xe1, 0xb, 0x0, 0x21, + 0x1e, 0x30, 0xe, 0x20, 0xe2, 0x0, 0x0, 0x96, + 0x3a, 0xe, 0xfa, 0x0, 0x8f, 0xff, 0xff, 0xd1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+65C1 "旁" */ + 0x0, 0x0, 0x0, 0x5, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0xa0, 0x0, 0x0, 0x0, + 0x9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa0, + 0x0, 0x0, 0x97, 0x0, 0x0, 0x79, 0x0, 0x0, + 0x0, 0x0, 0x2f, 0x10, 0x0, 0xe3, 0x0, 0x0, + 0xa, 0xee, 0xef, 0xee, 0xef, 0xfe, 0xee, 0x90, + 0xa, 0x50, 0x0, 0x5, 0x20, 0x0, 0x6, 0xa0, + 0x7, 0x30, 0x0, 0x8, 0xb0, 0x0, 0x4, 0x60, + 0x2e, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe2, + 0x0, 0x0, 0xc, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0x51, 0x11, 0x11, 0x10, 0x0, + 0x0, 0x0, 0x7f, 0xcc, 0xcc, 0xcd, 0xf1, 0x0, + 0x0, 0x4, 0xf6, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x2, 0x8f, 0x80, 0x0, 0x0, 0x7, 0xb0, 0x0, + 0x3f, 0xa3, 0x0, 0x0, 0x8e, 0xed, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+65C5 "旅" */ + 0x0, 0x6, 0x10, 0x0, 0x18, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x6a, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x90, 0x0, 0xca, 0x77, 0x77, 0x70, + 0x2e, 0xee, 0xee, 0xe4, 0xe8, 0x88, 0x88, 0x80, + 0x0, 0x69, 0x0, 0x1d, 0x40, 0x1, 0x6d, 0x60, + 0x0, 0x69, 0x0, 0x29, 0x49, 0xde, 0x94, 0x0, + 0x0, 0x6e, 0xcc, 0x60, 0xe6, 0x6a, 0x0, 0x0, + 0x0, 0x6a, 0x39, 0x80, 0xe1, 0x1e, 0x6, 0xc0, + 0x0, 0x78, 0x7, 0x70, 0xe1, 0xe, 0xac, 0x10, + 0x0, 0x96, 0x8, 0x70, 0xe1, 0x9, 0xb0, 0x0, + 0x0, 0xb3, 0x9, 0x60, 0xe1, 0x4, 0xd0, 0x0, + 0x0, 0xf0, 0xa, 0x50, 0xe1, 0x0, 0xe4, 0x0, + 0x5, 0xa0, 0xb, 0x40, 0xe1, 0x46, 0x6c, 0x0, + 0xd, 0x40, 0xe, 0x20, 0xfd, 0xc4, 0xc, 0xc0, + 0x4b, 0x9, 0xfa, 0x3, 0xc4, 0x0, 0x0, 0xa1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+65CF "族" */ + 0x0, 0x16, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x50, 0x0, 0x5c, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xc0, 0x0, 0xbb, 0x77, 0x77, 0x71, + 0x3f, 0xff, 0xff, 0xe3, 0xe7, 0x77, 0x77, 0x71, + 0x0, 0x6a, 0x0, 0x1d, 0x58, 0x50, 0x0, 0x0, + 0x0, 0x69, 0x0, 0x3a, 0x1f, 0x20, 0x0, 0x0, + 0x0, 0x7a, 0x22, 0x10, 0x8f, 0xff, 0xff, 0x70, + 0x0, 0x7e, 0xce, 0x74, 0xe3, 0x3f, 0x11, 0x0, + 0x0, 0x97, 0x8, 0x73, 0x30, 0x1e, 0x0, 0x0, + 0x0, 0xa6, 0x8, 0x6a, 0xdd, 0xdf, 0xdd, 0xd2, + 0x0, 0xc4, 0x9, 0x61, 0x22, 0x7f, 0x72, 0x20, + 0x0, 0xf1, 0xa, 0x50, 0x0, 0xc9, 0xd0, 0x0, + 0x4, 0xd0, 0xb, 0x40, 0x7, 0xc0, 0xb5, 0x0, + 0xb, 0x70, 0xe, 0x20, 0x8d, 0x10, 0x2e, 0x30, + 0x2e, 0xa, 0xfb, 0xd, 0xa1, 0x0, 0x3, 0xe2, + 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + + /* U+65E2 "既" */ + 0x3, 0x33, 0x33, 0x0, 0x0, 0x0, 0x0, 0x2, + 0xfb, 0xbb, 0xf0, 0xbe, 0xef, 0xfe, 0xe0, 0x2d, + 0x0, 0xf, 0x0, 0x30, 0x95, 0x0, 0x2, 0xfb, + 0xbc, 0xf0, 0x3b, 0xa, 0x40, 0x0, 0x2e, 0x11, + 0x2f, 0x7, 0x80, 0xb3, 0x0, 0x2, 0xd0, 0x0, + 0xf0, 0xc5, 0x1e, 0x31, 0x10, 0x2f, 0xdd, 0xdf, + 0x1e, 0xdd, 0xfd, 0xdd, 0x42, 0xe1, 0x11, 0x10, + 0x0, 0x5c, 0x10, 0x0, 0x2d, 0x0, 0x70, 0x0, + 0xa, 0xd6, 0x0, 0x2, 0xd0, 0x9, 0x70, 0x1, + 0xe8, 0x60, 0x0, 0x2d, 0x0, 0x8e, 0x0, 0x88, + 0x76, 0x1, 0x2, 0xe8, 0xe9, 0xc4, 0x2f, 0x17, + 0x60, 0x47, 0x7f, 0x91, 0x2, 0x2d, 0x70, 0x77, + 0x6, 0x62, 0x20, 0x0, 0xb, 0xa0, 0x4, 0xef, + 0xd2, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, + + /* U+65E5 "日" */ + 0x1, 0x11, 0x11, 0x11, 0x11, 0x10, 0x1f, 0xff, + 0xff, 0xff, 0xff, 0xf3, 0x1f, 0x0, 0x0, 0x0, + 0x0, 0xe3, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe3, + 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe3, 0x1f, 0x0, + 0x0, 0x0, 0x0, 0xe3, 0x1f, 0xff, 0xff, 0xff, + 0xff, 0xf3, 0x1f, 0x11, 0x11, 0x11, 0x11, 0xe3, + 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe3, 0x1f, 0x0, + 0x0, 0x0, 0x0, 0xe3, 0x1f, 0x0, 0x0, 0x0, + 0x0, 0xe3, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe3, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x1f, 0x0, + 0x0, 0x0, 0x0, 0xd2, + + /* U+65E6 "旦" */ + 0x0, 0x9f, 0xff, 0xff, 0xff, 0xfc, 0x0, 0x0, + 0x97, 0x0, 0x0, 0x0, 0x5c, 0x0, 0x0, 0x96, + 0x0, 0x0, 0x0, 0x5c, 0x0, 0x0, 0x96, 0x0, + 0x0, 0x0, 0x5c, 0x0, 0x0, 0x97, 0x0, 0x0, + 0x0, 0x5c, 0x0, 0x0, 0x9f, 0xff, 0xff, 0xff, + 0xfc, 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, 0x5c, + 0x0, 0x0, 0x96, 0x0, 0x0, 0x0, 0x5c, 0x0, + 0x0, 0x96, 0x0, 0x0, 0x0, 0x5c, 0x0, 0x0, + 0x9f, 0xff, 0xff, 0xff, 0xfc, 0x0, 0x0, 0x1, + 0x11, 0x11, 0x11, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, + + /* U+65E9 "早" */ + 0x0, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x79, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x79, 0x0, + 0x0, 0x5f, 0xee, 0xee, 0xee, 0xee, 0xf9, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x79, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x79, 0x0, + 0x0, 0x5e, 0xee, 0xef, 0xfe, 0xee, 0xe9, 0x0, + 0x0, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, + 0x1d, 0xdd, 0xdd, 0xde, 0xfd, 0xdd, 0xdd, 0xd6, + 0x2, 0x22, 0x22, 0x28, 0xb2, 0x22, 0x22, 0x21, + 0x0, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, + + /* U+65F6 "时" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x20, 0xb, + 0xdd, 0xdd, 0x0, 0x0, 0x0, 0xe2, 0x0, 0xd3, + 0x0, 0xf0, 0x11, 0x11, 0x1f, 0x31, 0xd, 0x20, + 0xf, 0x3f, 0xff, 0xff, 0xff, 0xf2, 0xd2, 0x0, + 0xf0, 0x0, 0x0, 0xe, 0x20, 0xd, 0x53, 0x3f, + 0x2, 0x40, 0x0, 0xe2, 0x0, 0xdc, 0xbb, 0xf0, + 0x2e, 0x20, 0xe, 0x20, 0xd, 0x20, 0xf, 0x0, + 0x6c, 0x0, 0xe2, 0x0, 0xd2, 0x0, 0xf0, 0x0, + 0xc7, 0xe, 0x20, 0xd, 0x20, 0xf, 0x0, 0x2, + 0x20, 0xe2, 0x0, 0xde, 0xee, 0xf0, 0x0, 0x0, + 0xe, 0x20, 0xd, 0x30, 0x0, 0x0, 0x0, 0x0, + 0xe2, 0x0, 0x71, 0x0, 0x0, 0x0, 0x11, 0x1f, + 0x10, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfe, 0xa0, + 0x0, + + /* U+6607 "昇" */ + 0x0, 0x5f, 0xdd, 0xdd, 0xdd, 0xdd, 0xea, 0x0, + 0x0, 0x5b, 0x0, 0x0, 0x0, 0x0, 0x6a, 0x0, + 0x0, 0x5c, 0x33, 0x33, 0x33, 0x33, 0x8a, 0x0, + 0x0, 0x5e, 0xaa, 0xaa, 0xaa, 0xaa, 0xca, 0x0, + 0x0, 0x5b, 0x0, 0x0, 0x0, 0x0, 0x6a, 0x0, + 0x0, 0x4e, 0xee, 0xee, 0xee, 0xee, 0xe9, 0x0, + 0x0, 0x2, 0x57, 0xbe, 0x80, 0x2e, 0x0, 0x0, + 0x2, 0xdb, 0x9f, 0x50, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x20, 0x0, 0x2e, 0x0, 0x0, + 0x1e, 0xee, 0xef, 0xee, 0xee, 0xef, 0xee, 0xe6, + 0x0, 0x0, 0x2f, 0x10, 0x0, 0x3e, 0x0, 0x0, + 0x0, 0x0, 0xb9, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x3c, 0xc1, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x3, 0xd6, 0x0, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+660E "明" */ + 0xef, 0xff, 0xf1, 0x2f, 0xff, 0xff, 0xfc, 0xe1, + 0x0, 0xe1, 0x2e, 0x0, 0x0, 0x3c, 0xe1, 0x0, + 0xe1, 0x2e, 0x0, 0x0, 0x3c, 0xe1, 0x0, 0xe1, + 0x2e, 0x0, 0x0, 0x3c, 0xe2, 0x0, 0xe1, 0x2f, + 0xcc, 0xcc, 0xdc, 0xee, 0xee, 0xf1, 0x2f, 0x55, + 0x55, 0x8c, 0xe1, 0x0, 0xe1, 0x2e, 0x0, 0x0, + 0x3c, 0xe1, 0x0, 0xe1, 0x3d, 0x0, 0x0, 0x3c, + 0xe1, 0x0, 0xe1, 0x6f, 0xdd, 0xdd, 0xdc, 0xef, + 0xff, 0xf1, 0x99, 0x11, 0x11, 0x4c, 0xe2, 0x0, + 0x1, 0xf3, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x8, + 0xc0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x7f, 0x20, + 0x0, 0x0, 0x5c, 0x0, 0x1, 0xe3, 0x0, 0x0, + 0xef, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+6613 "易" */ + 0x0, 0xf, 0xee, 0xee, 0xee, 0xee, 0xf2, 0x0, + 0x0, 0xf0, 0x0, 0x0, 0x0, 0xe, 0x20, 0x0, + 0xf, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0xfe, 0xdd, 0xdd, 0xdd, 0xdf, 0x20, 0x0, 0xf, + 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, 0xfb, + 0xbb, 0xbb, 0xbb, 0xbf, 0x20, 0x0, 0x2, 0x9d, + 0x32, 0x22, 0x22, 0x20, 0x0, 0x0, 0x4f, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e, 0xfe, 0xff, + 0xef, 0xff, 0xef, 0x20, 0x7f, 0x60, 0x1d, 0x30, + 0x6b, 0x0, 0xf0, 0x1b, 0x20, 0xd, 0x60, 0x1e, + 0x20, 0x1f, 0x0, 0x0, 0x2c, 0x80, 0xa, 0x90, + 0x4, 0xc0, 0x0, 0x6e, 0x60, 0x9, 0xc0, 0x0, + 0x99, 0x0, 0x5, 0x30, 0x3, 0xc0, 0x1e, 0xec, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+6614 "昔" */ + 0x0, 0x0, 0x3d, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x0, 0x22, 0x5e, 0x22, 0x22, 0xd6, 0x22, 0x0, + 0x2, 0xcc, 0xdf, 0xcc, 0xcc, 0xfd, 0xcc, 0x40, + 0x0, 0x0, 0x3d, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x0, 0x0, 0x4d, 0x0, 0x0, 0xc5, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xee, 0xee, 0xee, 0xee, 0xb0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x5, 0xc0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x5, 0xc0, 0x0, + 0x0, 0xb, 0xee, 0xee, 0xee, 0xee, 0xc0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x5, 0xc0, 0x0, + 0x0, 0xb, 0x61, 0x11, 0x11, 0x16, 0xc0, 0x0, + 0x0, 0xb, 0xed, 0xdd, 0xdd, 0xde, 0xc0, 0x0, + + /* U+661F "星" */ + 0x0, 0x4f, 0xdd, 0xdd, 0xdd, 0xdd, 0xf5, 0x0, + 0x4, 0xc0, 0x0, 0x0, 0x0, 0xb, 0x50, 0x0, + 0x4c, 0x22, 0x22, 0x22, 0x22, 0xc5, 0x0, 0x4, + 0xeb, 0xbb, 0xbb, 0xbb, 0xbe, 0x50, 0x0, 0x4c, + 0x0, 0x0, 0x0, 0x0, 0xb5, 0x0, 0x3, 0xed, + 0xdd, 0xdd, 0xdd, 0xde, 0x40, 0x0, 0x7, 0x80, + 0x5, 0x50, 0x0, 0x0, 0x0, 0x2, 0xf6, 0x22, + 0xaa, 0x22, 0x22, 0x20, 0x1, 0xdd, 0xbb, 0xbe, + 0xeb, 0xbb, 0xbb, 0x0, 0xd9, 0x0, 0x0, 0x88, + 0x0, 0x0, 0x0, 0x2, 0x1e, 0xee, 0xef, 0xfe, + 0xee, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x88, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, + 0x0, 0x0, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfe, + + /* U+6620 "映" */ + 0x11, 0x11, 0x0, 0x0, 0xf, 0x0, 0x0, 0xe, + 0xbb, 0xf1, 0x0, 0x0, 0xf0, 0x0, 0x0, 0xe1, + 0xe, 0x11, 0xee, 0xff, 0xee, 0xe1, 0xe, 0x10, + 0xe1, 0x1e, 0x1, 0xf0, 0xe, 0x10, 0xe1, 0xe, + 0x11, 0xe0, 0xf, 0x0, 0xe1, 0xe, 0xbb, 0xf1, + 0x1e, 0x0, 0xf0, 0xe, 0x10, 0xe4, 0x3e, 0x11, + 0xe0, 0x1e, 0x0, 0xe1, 0xe, 0x10, 0xe5, 0xbf, + 0xbc, 0xfb, 0xbf, 0xb0, 0xe1, 0xe, 0x24, 0x44, + 0x9f, 0x84, 0x44, 0xe, 0x10, 0xe1, 0x0, 0xb, + 0xba, 0x0, 0x0, 0xee, 0xef, 0x10, 0x4, 0xe1, + 0xe2, 0x0, 0xe, 0x10, 0x0, 0x3, 0xe5, 0x6, + 0xc0, 0x0, 0x70, 0x0, 0x6, 0xe6, 0x0, 0xb, + 0xa0, 0x0, 0x0, 0xb, 0xc3, 0x0, 0x0, 0xb, + 0xc0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x1, + 0x0, + + /* U+6625 "春" */ + 0x0, 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc, 0x50, 0x0, 0x0, 0x0, + 0x3, 0xee, 0xee, 0xef, 0xee, 0xee, 0xee, 0x30, + 0x0, 0x0, 0x0, 0x5d, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xae, 0xee, 0xff, 0xee, 0xee, 0xeb, 0x0, + 0x0, 0x0, 0x3, 0xe1, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0xdd, 0xdf, 0xfd, 0xdd, 0xdd, 0xdd, 0xd1, + 0x1, 0x11, 0xbc, 0x11, 0x11, 0xab, 0x11, 0x10, + 0x0, 0x8, 0xf5, 0x22, 0x22, 0x3f, 0x90, 0x0, + 0x0, 0x9f, 0xfc, 0xcc, 0xcc, 0xcf, 0xfa, 0x10, + 0x2d, 0xc4, 0xf0, 0x0, 0x0, 0xe, 0x5a, 0xe2, + 0x4, 0x1, 0xfd, 0xdd, 0xdd, 0xdf, 0x30, 0x20, + 0x0, 0x1, 0xf0, 0x0, 0x0, 0xe, 0x30, 0x0, + 0x0, 0x1, 0xf1, 0x11, 0x11, 0x1e, 0x30, 0x0, + 0x0, 0x1, 0xfc, 0xcc, 0xcc, 0xce, 0x30, 0x0, + + /* U+6628 "昨" */ + 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x4, + 0x44, 0x44, 0x0, 0xe0, 0x0, 0x0, 0x0, 0xeb, + 0xab, 0xe0, 0x4b, 0x0, 0x0, 0x0, 0xe, 0x10, + 0x1e, 0x9, 0xff, 0xff, 0xff, 0xf6, 0xe1, 0x1, + 0xe0, 0xe1, 0xd3, 0x0, 0x0, 0xe, 0x10, 0x1e, + 0x7a, 0xd, 0x30, 0x0, 0x0, 0xe6, 0x56, 0xec, + 0x20, 0xd6, 0x44, 0x42, 0xe, 0xaa, 0xae, 0x10, + 0xd, 0xcb, 0xbb, 0x70, 0xe1, 0x1, 0xe0, 0x0, + 0xd3, 0x0, 0x0, 0xe, 0x10, 0x1e, 0x0, 0xd, + 0x30, 0x0, 0x0, 0xe1, 0x1, 0xe0, 0x0, 0xde, + 0xee, 0xeb, 0xe, 0xee, 0xee, 0x0, 0xd, 0x30, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0xd3, 0x0, + 0x0, 0x6, 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd3, 0x0, 0x0, + 0x0, + + /* U+662F "是" */ + 0x0, 0x5f, 0xdd, 0xdd, 0xdd, 0xdd, 0xf4, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0x0, 0x0, 0xc4, 0x0, + 0x0, 0x5e, 0xbb, 0xbb, 0xbb, 0xbb, 0xf4, 0x0, + 0x0, 0x5b, 0x0, 0x0, 0x0, 0x0, 0xc4, 0x0, + 0x0, 0x5b, 0x11, 0x11, 0x11, 0x11, 0xd4, 0x0, + 0x0, 0x4b, 0xbb, 0xbb, 0xbb, 0xbb, 0xb3, 0x0, + 0x1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, + 0xd, 0xdd, 0xdd, 0xde, 0xfd, 0xdd, 0xdd, 0xd1, + 0x0, 0x3, 0x60, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x90, 0x6, 0xc3, 0x33, 0x33, 0x0, + 0x0, 0xf, 0xa0, 0x6, 0xeb, 0xbb, 0xbb, 0x0, + 0x0, 0x6c, 0xd5, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x3, 0xf3, 0x2e, 0xca, 0xb1, 0x0, 0x0, 0x0, + 0x2e, 0x50, 0x0, 0x6b, 0xef, 0xff, 0xff, 0xf2, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+663C "昼" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6f, 0xee, 0xee, 0xee, 0xee, 0xf8, 0x0, + 0x0, 0x6a, 0x0, 0x0, 0x0, 0x0, 0x88, 0x0, + 0x0, 0x6a, 0x0, 0x0, 0x0, 0x0, 0x88, 0x0, + 0x0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, + 0x0, 0xa7, 0x0, 0x0, 0x0, 0xe5, 0x0, 0x0, + 0x0, 0xe2, 0x0, 0x0, 0x0, 0x5f, 0x40, 0x0, + 0x6, 0xd8, 0xed, 0xdd, 0xdd, 0xdf, 0xf8, 0x10, + 0x2f, 0x58, 0x60, 0x0, 0x0, 0xc, 0x7b, 0xe1, + 0x26, 0x8, 0xec, 0xcc, 0xcc, 0xcf, 0x40, 0x10, + 0x0, 0x8, 0x60, 0x0, 0x0, 0xc, 0x40, 0x0, + 0x0, 0x8, 0x82, 0x22, 0x22, 0x2c, 0x40, 0x0, + 0x0, 0x5, 0xaa, 0xaa, 0xaa, 0xaa, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, + + /* U+6642 "時" */ + 0xef, 0xff, 0xc0, 0x0, 0xf, 0x0, 0x0, 0xe, + 0x10, 0x3c, 0x13, 0x34, 0xf4, 0x33, 0x20, 0xe1, + 0x3, 0xc3, 0xbb, 0xbf, 0xbb, 0xb5, 0xe, 0x10, + 0x3c, 0x0, 0x0, 0xf0, 0x0, 0x0, 0xe1, 0x3, + 0xc7, 0x77, 0x7f, 0x77, 0x77, 0x1e, 0xee, 0xec, + 0x56, 0x66, 0x66, 0xf7, 0x61, 0xe2, 0x14, 0xc0, + 0x0, 0x0, 0xe, 0x20, 0xe, 0x10, 0x3c, 0x9b, + 0xbb, 0xbb, 0xfb, 0xb0, 0xe1, 0x3, 0xc3, 0x43, + 0x33, 0x3f, 0x53, 0xe, 0x10, 0x3c, 0x9, 0x70, + 0x0, 0xe2, 0x0, 0xee, 0xef, 0xc0, 0xd, 0x40, + 0xe, 0x20, 0xa, 0x10, 0x0, 0x0, 0x28, 0x0, + 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x3, 0xff, 0xb0, + 0x0, + + /* U+6669 "晩" */ + 0x0, 0x0, 0x0, 0x3, 0x20, 0x0, 0x0, 0x2, + 0x22, 0x20, 0x1, 0xf3, 0x0, 0x0, 0x0, 0xec, + 0xcf, 0x20, 0x9f, 0xee, 0xfb, 0x0, 0xe, 0x10, + 0xc2, 0x5e, 0x10, 0x1d, 0x30, 0x0, 0xe1, 0xc, + 0x7f, 0xa7, 0x7c, 0xc7, 0x76, 0xe, 0x10, 0xca, + 0xe8, 0x66, 0xf6, 0x68, 0xc0, 0xed, 0xdf, 0x2b, + 0x30, 0xe, 0x0, 0x2c, 0xe, 0x31, 0xc2, 0xb3, + 0x0, 0xe0, 0x2, 0xc0, 0xe1, 0xc, 0x2b, 0x63, + 0x4f, 0x33, 0x6c, 0xe, 0x10, 0xc2, 0x8b, 0xfc, + 0xbf, 0xbb, 0x90, 0xe1, 0xc, 0x20, 0xf, 0x20, + 0xf1, 0x0, 0xe, 0xee, 0xf2, 0x4, 0xe0, 0xf, + 0x10, 0x0, 0xe1, 0x0, 0x0, 0xc7, 0x0, 0xf1, + 0x6, 0x55, 0x0, 0x3, 0xca, 0x0, 0xf, 0x20, + 0x86, 0x0, 0x7, 0xd6, 0x0, 0x0, 0xbf, 0xfe, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+666E "普" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, 0xe4, 0x0, 0x0, 0x4e, 0x0, 0x0, + 0x0, 0x33, 0x8b, 0x33, 0x33, 0xd8, 0x33, 0x10, + 0x2, 0xab, 0xab, 0xfa, 0xaf, 0xba, 0xba, 0x40, + 0x0, 0x3c, 0x1, 0xd0, 0xe, 0x10, 0xd3, 0x0, + 0x0, 0xc, 0x51, 0xd0, 0xe, 0x16, 0xb0, 0x0, + 0x1, 0x15, 0x63, 0xe1, 0x1f, 0x28, 0x31, 0x10, + 0x2d, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xd2, + 0x0, 0x1, 0x11, 0x11, 0x11, 0x11, 0x10, 0x0, + 0x0, 0xe, 0xcb, 0xbb, 0xbb, 0xbc, 0xf0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0xf0, 0x0, + 0x0, 0xe, 0xed, 0xdd, 0xdd, 0xdd, 0xf0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0xf0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0xf0, 0x0, + 0x0, 0xe, 0xed, 0xdd, 0xdd, 0xde, 0xe0, 0x0, + + /* U+666F "景" */ + 0x0, 0x3f, 0xbb, 0xbb, 0xbb, 0xbb, 0xf3, 0x0, + 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0xc3, 0x0, + 0x0, 0x3f, 0xbb, 0xbb, 0xbb, 0xbb, 0xf3, 0x0, + 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0xc3, 0x0, + 0x0, 0x3c, 0xcc, 0xce, 0xcc, 0xcc, 0xc3, 0x0, + 0x4, 0x44, 0x44, 0x4d, 0x84, 0x44, 0x44, 0x40, + 0x7, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, + 0x0, 0xa, 0xbb, 0xbb, 0xbb, 0xbb, 0xb0, 0x0, + 0x0, 0xe, 0x30, 0x0, 0x0, 0x2, 0xf0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0x1, 0xf0, 0x0, + 0x0, 0xb, 0xdd, 0xde, 0xed, 0xdd, 0xc0, 0x0, + 0x0, 0x2, 0xa3, 0x8, 0x80, 0x76, 0x10, 0x0, + 0x4, 0xad, 0x40, 0x8, 0x80, 0x16, 0xda, 0x20, + 0x8, 0x40, 0x6, 0xde, 0x50, 0x0, 0x5, 0x80, + + /* U+6674 "晴" */ + 0x22, 0x22, 0x0, 0x0, 0xe, 0x10, 0x0, 0xe, + 0xbb, 0xf0, 0x9d, 0xdd, 0xfd, 0xdd, 0xc0, 0xe0, + 0xe, 0x0, 0x0, 0xe, 0x10, 0x0, 0xe, 0x0, + 0xe0, 0x3c, 0xcc, 0xfd, 0xcc, 0x70, 0xe0, 0xe, + 0x0, 0x0, 0xf, 0x10, 0x0, 0xe, 0x66, 0xf2, + 0xdd, 0xdd, 0xdd, 0xdd, 0xd2, 0xe8, 0x8f, 0x0, + 0x22, 0x22, 0x22, 0x20, 0xe, 0x0, 0xe0, 0xf, + 0xba, 0xaa, 0xaf, 0x20, 0xe0, 0xe, 0x0, 0xf0, + 0x0, 0x0, 0xd2, 0xe, 0x0, 0xe0, 0xf, 0xcc, + 0xcc, 0xcf, 0x20, 0xea, 0xaf, 0x0, 0xf0, 0x0, + 0x0, 0xd2, 0xe, 0x33, 0x30, 0xf, 0xcc, 0xcc, + 0xcf, 0x20, 0x50, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0xd2, 0x0, 0x0, 0x0, 0xf, 0x0, 0x7, 0xdd, + 0x0, + + /* U+667A "智" */ + 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xfe, 0xfe, 0xd8, 0x4f, 0xff, 0xff, 0x40, 0xd4, + 0xd, 0x30, 0x4, 0xb0, 0x0, 0xb4, 0x1b, 0x99, + 0xfb, 0x99, 0x4b, 0x0, 0xb, 0x40, 0x22, 0x5f, + 0x52, 0x24, 0xb0, 0x0, 0xb4, 0x0, 0xb, 0x7d, + 0x90, 0x4f, 0xcc, 0xcf, 0x40, 0x1b, 0x90, 0xb, + 0xa0, 0x22, 0x22, 0x20, 0x1e, 0x71, 0x11, 0x12, + 0x11, 0x11, 0x10, 0x0, 0x0, 0xcd, 0xcc, 0xcc, + 0xcc, 0xde, 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, + 0x2, 0xe0, 0x0, 0x0, 0xce, 0xdd, 0xdd, 0xdd, + 0xde, 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, 0x2, + 0xe0, 0x0, 0x0, 0xc3, 0x0, 0x0, 0x0, 0x2e, + 0x0, 0x0, 0xc, 0xed, 0xdd, 0xdd, 0xde, 0xe0, + 0x0, + + /* U+6687 "暇" */ + 0x11, 0x11, 0xf, 0xee, 0xf3, 0xee, 0xfd, 0xe, + 0xdd, 0xe0, 0xf0, 0xe, 0x0, 0x1, 0xd0, 0xe0, + 0xe, 0xf, 0x0, 0xe0, 0x0, 0x1d, 0xe, 0x0, + 0xe0, 0xf0, 0xe, 0x0, 0x1, 0xd0, 0xe0, 0xe, + 0xf, 0xee, 0xf3, 0xee, 0xed, 0xe, 0xcc, 0xe0, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0xe4, 0x4e, 0xf, + 0x0, 0x6, 0x88, 0x87, 0xe, 0x0, 0xe0, 0xfe, + 0xea, 0x6c, 0x68, 0xd0, 0xe0, 0xe, 0xf, 0x0, + 0x0, 0xd0, 0x88, 0xe, 0x0, 0xe0, 0xf1, 0x11, + 0x9, 0x5e, 0x30, 0xee, 0xee, 0xf, 0xdd, 0xd0, + 0x3e, 0xa0, 0xe, 0x0, 0x0, 0xf0, 0x0, 0x4, + 0xf6, 0x0, 0x90, 0x0, 0xf, 0x0, 0x6, 0xe8, + 0xe4, 0x0, 0x0, 0x0, 0xf0, 0x8, 0xa2, 0x2, + 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+6691 "暑" */ + 0x0, 0x6e, 0xcc, 0xcc, 0xcc, 0xcc, 0xf2, 0x0, + 0x6, 0x90, 0x0, 0x0, 0x0, 0xe, 0x20, 0x0, + 0x6e, 0xbb, 0xbb, 0xbb, 0xbb, 0xf2, 0x0, 0x6, + 0xa2, 0x22, 0x22, 0x22, 0x2e, 0x20, 0x0, 0x49, + 0x99, 0xbb, 0x99, 0x99, 0x98, 0x10, 0x9, 0xaa, + 0xad, 0xda, 0xaa, 0x7c, 0x90, 0x0, 0x22, 0x22, + 0x99, 0x24, 0xcd, 0x30, 0x0, 0xaa, 0xaa, 0xad, + 0xda, 0xff, 0xba, 0xaa, 0x3, 0x33, 0x49, 0xee, + 0x73, 0x33, 0x33, 0x30, 0x37, 0xbf, 0xff, 0xcb, + 0xbb, 0xbb, 0x50, 0x1d, 0x97, 0xc0, 0x0, 0x0, + 0x0, 0xa6, 0x0, 0x0, 0x3f, 0xbb, 0xbb, 0xbb, + 0xbe, 0x60, 0x0, 0x3, 0xc0, 0x0, 0x0, 0x0, + 0xa6, 0x0, 0x0, 0x3f, 0xbb, 0xbb, 0xbb, 0xbe, + 0x60, + + /* U+6696 "暖" */ + 0x0, 0x0, 0x0, 0x12, 0x34, 0x68, 0xa1, 0x0, + 0x0, 0x2, 0xdc, 0xcb, 0xa8, 0x64, 0x10, 0xde, + 0xef, 0x12, 0x30, 0x95, 0x1, 0xd1, 0xd, 0x10, + 0xe1, 0x4a, 0x6, 0x80, 0x89, 0x0, 0xd1, 0xe, + 0x10, 0xc0, 0x37, 0x1e, 0x10, 0xd, 0x10, 0xe1, + 0xee, 0xfe, 0xee, 0xee, 0xa0, 0xd9, 0x8f, 0x10, + 0x1f, 0x0, 0x0, 0x0, 0xd, 0x54, 0xe9, 0xee, + 0xfe, 0xee, 0xee, 0xe1, 0xd1, 0xe, 0x10, 0x6a, + 0x0, 0x0, 0x0, 0xd, 0x10, 0xe1, 0x9, 0xed, + 0xdd, 0xda, 0x0, 0xd1, 0xe, 0x10, 0xee, 0x10, + 0x9, 0x70, 0xd, 0xee, 0xf1, 0x5b, 0x6b, 0x3, + 0xe1, 0x0, 0xd1, 0x0, 0xe, 0x30, 0x9c, 0xe4, + 0x0, 0x7, 0x0, 0xa, 0x90, 0x7, 0xfe, 0x60, + 0x0, 0x0, 0xb, 0xa1, 0x9e, 0xa1, 0x3b, 0xfb, + 0x10, 0x0, 0x20, 0x5, 0x10, 0x0, 0x1, 0x50, + + /* U+6697 "暗" */ + 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x6, + 0x77, 0x70, 0x0, 0x0, 0xd3, 0x0, 0x0, 0xd9, + 0x8e, 0x14, 0xbb, 0xbe, 0xdb, 0xba, 0xd, 0x10, + 0xd1, 0x15, 0xa3, 0x33, 0x6a, 0x30, 0xd1, 0xd, + 0x10, 0xf, 0x10, 0x9, 0x80, 0xd, 0x10, 0xd1, + 0x0, 0xa5, 0x0, 0xe1, 0x0, 0xda, 0xaf, 0x1e, + 0xef, 0xee, 0xff, 0xee, 0x6d, 0x54, 0xe1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd1, 0xd, 0x10, 0x9c, + 0xcc, 0xcc, 0xc5, 0xd, 0x10, 0xd1, 0xc, 0x41, + 0x11, 0x1a, 0x60, 0xd1, 0xd, 0x10, 0xc5, 0x22, + 0x22, 0xb6, 0xd, 0xee, 0xf1, 0xc, 0xcb, 0xbb, + 0xbe, 0x60, 0xd1, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0x96, 0x6, 0x0, 0x0, 0xc, 0x52, 0x22, 0x2b, + 0x60, 0x0, 0x0, 0x0, 0xcd, 0xcc, 0xcc, 0xe6, + 0x0, + + /* U+66C7 "曇" */ + 0x0, 0x6d, 0x99, 0x99, 0x99, 0x99, 0xe4, 0x0, + 0x0, 0x6c, 0x88, 0x88, 0x88, 0x88, 0xe4, 0x0, + 0x0, 0x6a, 0x22, 0x22, 0x22, 0x22, 0xc4, 0x0, + 0x0, 0x49, 0x99, 0x99, 0x99, 0x99, 0x93, 0x0, + 0x0, 0x99, 0x99, 0x9b, 0xb9, 0x99, 0x99, 0x10, + 0x8, 0x99, 0x99, 0x9d, 0xc9, 0x99, 0x99, 0x80, + 0xc, 0x35, 0x55, 0x39, 0x74, 0x55, 0x54, 0xc0, + 0x7, 0x14, 0x55, 0x29, 0x63, 0x55, 0x41, 0x70, + 0x0, 0x19, 0x99, 0x59, 0x66, 0x99, 0x92, 0x0, + 0x0, 0x37, 0x77, 0x77, 0x77, 0x77, 0x74, 0x0, + 0x0, 0x13, 0x33, 0x33, 0x33, 0x33, 0x32, 0x0, + 0x2c, 0xcc, 0xcf, 0xdc, 0xcc, 0xec, 0xcc, 0xc1, + 0x0, 0x1, 0xc9, 0x0, 0x0, 0x9d, 0x50, 0x0, + 0x0, 0x4f, 0xeb, 0xbc, 0xcc, 0xcd, 0xe9, 0x0, + 0x0, 0x13, 0x21, 0x0, 0x0, 0x0, 0x6, 0x0, + + /* U+66DC "曜" */ + 0x11, 0x11, 0x2c, 0xcc, 0xe5, 0xcc, 0xdc, 0xe, + 0xdd, 0xe0, 0x41, 0xe, 0x5, 0x2, 0xc0, 0xe0, + 0xe, 0x2, 0xc1, 0xe0, 0x5b, 0x2c, 0xe, 0x0, + 0xe0, 0x6, 0xbe, 0x0, 0x7b, 0xc0, 0xe0, 0xe, + 0x2c, 0x71, 0xe4, 0xc6, 0x3c, 0xe, 0xcc, 0xe0, + 0x5, 0x80, 0x91, 0x0, 0x0, 0xe6, 0x6e, 0x0, + 0xd6, 0x9, 0x80, 0x0, 0xe, 0x0, 0xe0, 0x7f, + 0xdd, 0xee, 0xdd, 0xc0, 0xe0, 0xe, 0x3f, 0xe0, + 0x6, 0x90, 0x0, 0xe, 0x0, 0xeb, 0x7f, 0xcc, + 0xde, 0xcc, 0x50, 0xea, 0xae, 0x1, 0xe0, 0x6, + 0x90, 0x0, 0xe, 0x44, 0x40, 0x1f, 0xbb, 0xde, + 0xbb, 0x50, 0x80, 0x0, 0x1, 0xe0, 0x6, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x1f, 0xcc, 0xcc, 0xcc, + 0xc3, + + /* U+66F2 "曲" */ + 0x0, 0x0, 0x1e, 0x0, 0x3d, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x3d, 0x0, 0x0, 0x1, 0x11, + 0x3e, 0x11, 0x4d, 0x11, 0x11, 0x2f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x2d, 0x0, 0x1e, 0x0, + 0x3d, 0x0, 0x2e, 0x2d, 0x0, 0x1e, 0x0, 0x3d, + 0x0, 0x2e, 0x2d, 0x0, 0x1e, 0x0, 0x3d, 0x0, + 0x2e, 0x2f, 0xbb, 0xcf, 0xbb, 0xcf, 0xbb, 0xce, + 0x2e, 0x33, 0x5f, 0x33, 0x6e, 0x33, 0x5e, 0x2d, + 0x0, 0x1e, 0x0, 0x3d, 0x0, 0x2e, 0x2d, 0x0, + 0x1e, 0x0, 0x3d, 0x0, 0x2e, 0x2d, 0x0, 0x1e, + 0x0, 0x3d, 0x0, 0x2e, 0x2f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe, 0x2d, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x3d, + + /* U+66F4 "更" */ + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x7f, 0xee, 0xef, 0xfe, 0xee, 0xef, 0x0, + 0x0, 0x78, 0x0, 0x7, 0xa0, 0x0, 0x1f, 0x0, + 0x0, 0x7e, 0xbb, 0xbd, 0xeb, 0xbb, 0xcf, 0x0, + 0x0, 0x79, 0x22, 0x28, 0xb2, 0x22, 0x3f, 0x0, + 0x0, 0x78, 0x0, 0x7, 0x90, 0x0, 0x1f, 0x0, + 0x0, 0x7f, 0xee, 0xef, 0xfe, 0xee, 0xef, 0x0, + 0x0, 0x8, 0x40, 0xd, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xe3, 0x6d, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4f, 0xf4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x48, 0xea, 0x8e, 0xc8, 0x53, 0x21, 0x0, + 0xe, 0xc8, 0x20, 0x0, 0x37, 0xac, 0xef, 0xf4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+66F8 "書" */ + 0x0, 0x1, 0x11, 0x1a, 0x81, 0x11, 0x10, 0x0, + 0x0, 0x27, 0x77, 0x7c, 0xb7, 0x77, 0xf1, 0x0, + 0xc, 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xfc, 0xc1, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0xf2, 0x0, + 0x0, 0x6c, 0xcc, 0xce, 0xec, 0xcc, 0xf1, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0xbb, 0xbb, 0xbe, 0xdb, 0xbb, 0xbb, 0x0, + 0x4, 0x44, 0x44, 0x4b, 0xa4, 0x44, 0x44, 0x40, + 0x7, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, + 0x0, 0xc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc2, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xe3, 0x0, + 0x0, 0xf, 0xbb, 0xbb, 0xbb, 0xbb, 0xf3, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xe3, 0x0, + 0x0, 0xf, 0xcc, 0xcc, 0xcc, 0xcc, 0xf3, 0x0, + + /* U+66FE "曾" */ + 0x0, 0x10, 0x0, 0x0, 0x11, 0x0, 0x0, 0xb6, + 0x0, 0x0, 0xd7, 0x0, 0x11, 0x3c, 0x21, 0x1a, + 0xb2, 0x11, 0xec, 0xbb, 0xbf, 0xcb, 0xbb, 0xcf, + 0xe3, 0xb1, 0xd, 0x20, 0x58, 0x2f, 0xe2, 0x3b, + 0xd, 0x22, 0xd1, 0x2f, 0xe2, 0x5, 0xd, 0x26, + 0x20, 0x2f, 0xcd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xdc, + 0xcc, 0xcc, 0xcd, 0xf0, 0xe, 0x20, 0x0, 0x0, + 0x2, 0xf0, 0xe, 0xdc, 0xcc, 0xcc, 0xcd, 0xf0, + 0xe, 0x20, 0x0, 0x0, 0x2, 0xf0, 0xe, 0xba, + 0xaa, 0xaa, 0xab, 0xf0, 0xe, 0x53, 0x33, 0x33, + 0x35, 0xe0, + + /* U+66FF "替" */ + 0x0, 0x0, 0xf0, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x7, 0xdd, 0xfd, 0xd2, 0x7d, 0xef, 0xdd, 0x70, + 0x0, 0x1, 0xf0, 0x0, 0x0, 0x3d, 0x0, 0x0, + 0xc, 0xcd, 0xfc, 0xc5, 0xbc, 0xdf, 0xcc, 0xc0, + 0x1, 0x1a, 0xe4, 0x10, 0x11, 0xdb, 0xa1, 0x10, + 0x0, 0x4e, 0x4d, 0x70, 0xb, 0x90, 0xc6, 0x0, + 0x6, 0xe3, 0x1, 0x92, 0xe8, 0x0, 0x1c, 0xb1, + 0x9, 0x1a, 0xbb, 0xbb, 0xcb, 0xbb, 0xa0, 0x60, + 0x0, 0xe, 0x43, 0x33, 0x33, 0x35, 0xe0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0xe, 0xdd, 0xdd, 0xdd, 0xdd, 0xe0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0xe, 0x21, 0x11, 0x11, 0x13, 0xe0, 0x0, + 0x0, 0xe, 0xdd, 0xdd, 0xdd, 0xdd, 0xe0, 0x0, + + /* U+6700 "最" */ + 0x0, 0x2f, 0xcc, 0xcc, 0xcc, 0xcc, 0xf3, 0x0, + 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0xd3, 0x0, + 0x0, 0x2f, 0xbb, 0xbb, 0xbb, 0xbb, 0xf3, 0x0, + 0x0, 0x2d, 0x0, 0x0, 0x0, 0x0, 0xd3, 0x0, + 0x0, 0x2d, 0xcc, 0xcc, 0xcc, 0xcc, 0xd3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0xff, 0xee, 0xff, 0xee, 0xee, 0xee, 0xe2, + 0x0, 0xa5, 0x0, 0x96, 0x11, 0x11, 0x11, 0x0, + 0x0, 0xae, 0xdd, 0xe6, 0xcf, 0xcc, 0xce, 0x70, + 0x0, 0xa5, 0x0, 0x96, 0xd, 0x10, 0x1e, 0x0, + 0x0, 0xae, 0xdd, 0xe6, 0x5, 0xb0, 0xb6, 0x0, + 0x0, 0xa5, 0x2, 0xba, 0x20, 0x8e, 0x90, 0x0, + 0x2b, 0xed, 0xca, 0xda, 0x38, 0xd9, 0xe9, 0x20, + 0x1, 0x0, 0x0, 0x97, 0xb6, 0x0, 0x18, 0xd1, + + /* U+6703 "會" */ + 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0xf6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xc6, 0x1b, 0xa1, 0x0, 0x0, + 0x0, 0x4, 0xbf, 0xb7, 0x77, 0xee, 0x94, 0x0, + 0x8, 0xeb, 0x42, 0x44, 0x44, 0x41, 0x7e, 0xe7, + 0x5, 0x4c, 0xbb, 0xbc, 0xcb, 0xbb, 0xca, 0x32, + 0x0, 0x2c, 0x9, 0x4, 0xa0, 0x75, 0x2c, 0x0, + 0x0, 0x2c, 0x8, 0x54, 0xa0, 0xd1, 0x2c, 0x0, + 0x0, 0x2e, 0x9a, 0xab, 0xd9, 0xb9, 0xac, 0x0, + 0x0, 0x2, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, + 0x0, 0x2, 0xfc, 0xcc, 0xcc, 0xcd, 0xf0, 0x0, + 0x0, 0x2, 0xd0, 0x0, 0x0, 0x3, 0xf0, 0x0, + 0x0, 0x2, 0xfc, 0xcc, 0xcc, 0xcd, 0xf0, 0x0, + 0x0, 0x2, 0xd0, 0x0, 0x0, 0x3, 0xf0, 0x0, + 0x0, 0x2, 0xfc, 0xcc, 0xcc, 0xcd, 0xf0, 0x0, + + /* U+6708 "月" */ + 0x0, 0xd, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x0, + 0xd4, 0x0, 0x0, 0x0, 0x3e, 0x0, 0xd, 0x30, + 0x0, 0x0, 0x3, 0xe0, 0x0, 0xd3, 0x0, 0x0, + 0x0, 0x3e, 0x0, 0xd, 0xee, 0xee, 0xee, 0xee, + 0xe0, 0x0, 0xd4, 0x11, 0x11, 0x11, 0x4e, 0x0, + 0xe, 0x20, 0x0, 0x0, 0x3, 0xe0, 0x0, 0xf1, + 0x0, 0x0, 0x0, 0x3e, 0x0, 0x2f, 0xff, 0xff, + 0xff, 0xff, 0xe0, 0x6, 0xb1, 0x11, 0x11, 0x11, + 0x4e, 0x0, 0xd5, 0x0, 0x0, 0x0, 0x3, 0xe0, + 0x4f, 0x0, 0x0, 0x0, 0x0, 0x3e, 0x2e, 0x60, + 0x0, 0x0, 0x11, 0x15, 0xe6, 0x90, 0x0, 0x0, + 0x7, 0xff, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+6709 "有" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe4, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x14, 0xe1, 0x11, 0x11, 0x11, 0x10, + 0xe, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xee, 0xe0, + 0x0, 0x0, 0x3e, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd9, 0x11, 0x11, 0x11, 0x10, 0x0, + 0x0, 0x9, 0xfe, 0xdd, 0xdd, 0xdd, 0xf1, 0x0, + 0x0, 0x9d, 0xe2, 0x0, 0x0, 0x0, 0xe1, 0x0, + 0xb, 0xc1, 0xdd, 0xcc, 0xcc, 0xcc, 0xf1, 0x0, + 0x9, 0x0, 0xd4, 0x11, 0x11, 0x11, 0xe1, 0x0, + 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0xe1, 0x0, + 0x0, 0x0, 0xdf, 0xee, 0xee, 0xee, 0xf1, 0x0, + 0x0, 0x0, 0xd2, 0x0, 0x0, 0x0, 0xe1, 0x0, + 0x0, 0x0, 0xd2, 0x0, 0x0, 0x11, 0xf1, 0x0, + 0x0, 0x0, 0xd2, 0x0, 0x7, 0xfe, 0xb0, 0x0, + + /* U+670B "朋" */ + 0x0, 0xff, 0xff, 0xf1, 0xf, 0xff, 0xff, 0x30, + 0xf, 0x10, 0xe, 0x10, 0xf0, 0x0, 0xd3, 0x0, + 0xf0, 0x0, 0xe1, 0xf, 0x0, 0xd, 0x30, 0xf, + 0x0, 0xe, 0x10, 0xf0, 0x0, 0xd3, 0x0, 0xff, + 0xff, 0xf1, 0xf, 0xff, 0xff, 0x30, 0xf, 0x0, + 0xe, 0x11, 0xf0, 0x0, 0xd3, 0x0, 0xf0, 0x0, + 0xe1, 0x1f, 0x0, 0xd, 0x30, 0xf, 0x10, 0xe, + 0x13, 0xe0, 0x0, 0xd3, 0x1, 0xff, 0xff, 0xf1, + 0x4f, 0xff, 0xff, 0x30, 0x2d, 0x0, 0xe, 0x15, + 0xb0, 0x0, 0xd3, 0x5, 0xb0, 0x0, 0xe1, 0x88, + 0x0, 0xd, 0x30, 0x98, 0x0, 0xe, 0x1d, 0x50, + 0x0, 0xd3, 0xe, 0x20, 0x23, 0xf5, 0xd0, 0x0, + 0x1e, 0x34, 0xa0, 0x8, 0xc8, 0xa5, 0x0, 0xef, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+670D "服" */ + 0x0, 0xff, 0xff, 0xc0, 0xef, 0xff, 0xff, 0xe0, + 0x0, 0xf0, 0x3, 0xc0, 0xe1, 0x0, 0x2, 0xe0, + 0x0, 0xf0, 0x3, 0xc0, 0xe1, 0x0, 0x1, 0xe0, + 0x0, 0xf0, 0x3, 0xc0, 0xe1, 0x1, 0x25, 0xe0, + 0x0, 0xfd, 0xde, 0xc0, 0xe1, 0x4, 0xba, 0x50, + 0x0, 0xf2, 0x25, 0xc0, 0xe3, 0x11, 0x11, 0x20, + 0x0, 0xf0, 0x3, 0xc0, 0xee, 0xfd, 0xdd, 0xf3, + 0x1, 0xf0, 0x4, 0xc0, 0xe3, 0xd0, 0x1, 0xd0, + 0x2, 0xff, 0xff, 0xc0, 0xe1, 0xb4, 0x7, 0x90, + 0x3, 0xc0, 0x3, 0xc0, 0xe1, 0x3d, 0x1e, 0x10, + 0x5, 0xa0, 0x3, 0xc0, 0xe1, 0x9, 0xe7, 0x0, + 0x8, 0x70, 0x3, 0xc0, 0xe1, 0x9, 0xf7, 0x0, + 0xd, 0x30, 0x4, 0xc0, 0xe3, 0xbb, 0x2d, 0x91, + 0x1b, 0x2, 0xff, 0x70, 0xe8, 0x70, 0x0, 0x98, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+671B "望" */ + 0x0, 0x2, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xe0, 0x0, 0x2f, 0xcc, 0xcd, 0xc0, + 0x3d, 0xdd, 0xfd, 0xdd, 0x3e, 0x0, 0x4, 0xc0, + 0x3, 0xa9, 0x33, 0x33, 0x3f, 0xcc, 0xcd, 0xc0, + 0x0, 0x87, 0x0, 0x0, 0x4c, 0x0, 0x4, 0xc0, + 0x0, 0x87, 0x1, 0x43, 0x6f, 0xcc, 0xcd, 0xc0, + 0x0, 0xbd, 0xdd, 0x92, 0xc5, 0x0, 0x4, 0xc0, + 0x0, 0xb6, 0x20, 0x9, 0xd0, 0x2, 0x69, 0xb0, + 0x0, 0x0, 0x0, 0x6, 0x10, 0x2, 0x87, 0x20, + 0x0, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x40, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x3b, 0xbb, 0xbd, 0xdb, 0xbb, 0xb5, 0x0, + 0x0, 0x3, 0x33, 0x3a, 0xa3, 0x33, 0x31, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x1e, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe4, + + /* U+671D "朝" */ + 0x0, 0x1, 0xe0, 0x0, 0xf, 0xff, 0xff, 0xd1, + 0xcc, 0xdf, 0xcc, 0xc1, 0xf1, 0x0, 0x2d, 0x2, + 0x23, 0xe2, 0x22, 0xf, 0x10, 0x2, 0xd0, 0x0, + 0x2e, 0x0, 0x0, 0xf1, 0x0, 0x2d, 0xa, 0xdc, + 0xcc, 0xe9, 0xf, 0xa9, 0x9a, 0xd0, 0xa4, 0x0, + 0x6, 0x90, 0xf5, 0x44, 0x6d, 0xa, 0xed, 0xdd, + 0xe9, 0xf, 0x10, 0x2, 0xd0, 0xa4, 0x0, 0x6, + 0x90, 0xf1, 0x0, 0x3d, 0xa, 0xed, 0xdd, 0xe9, + 0x2f, 0xee, 0xee, 0xd0, 0x0, 0x1e, 0x0, 0x4, + 0xc0, 0x0, 0x2d, 0x4c, 0xcc, 0xfc, 0xcc, 0xa8, + 0x0, 0x2, 0xd1, 0x33, 0x4f, 0x33, 0x3f, 0x30, + 0x0, 0x2d, 0x0, 0x1, 0xe0, 0x9, 0xb0, 0x0, + 0x4, 0xd0, 0x0, 0x1e, 0x1, 0xc1, 0x0, 0x3f, + 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+671F "期" */ + 0x0, 0x86, 0x0, 0x77, 0x7, 0xff, 0xff, 0xf0, + 0x0, 0x97, 0x0, 0x88, 0x7, 0x80, 0x0, 0xf0, + 0xd, 0xff, 0xee, 0xff, 0xa7, 0x80, 0x0, 0xf0, + 0x0, 0x86, 0x0, 0x77, 0x7, 0x80, 0x0, 0xf0, + 0x0, 0x8d, 0xcc, 0xe7, 0x7, 0xfe, 0xee, 0xf0, + 0x0, 0x87, 0x11, 0x87, 0x7, 0x90, 0x0, 0xf0, + 0x0, 0x86, 0x0, 0x77, 0x8, 0x80, 0x0, 0xf0, + 0x0, 0x8e, 0xdd, 0xe7, 0x9, 0x80, 0x0, 0xf0, + 0x0, 0x86, 0x0, 0x77, 0xa, 0xdb, 0xbb, 0xf0, + 0x1d, 0xee, 0xdd, 0xee, 0x9b, 0x50, 0x0, 0xf0, + 0x1, 0x27, 0x23, 0x41, 0x1d, 0x20, 0x0, 0xf0, + 0x0, 0x7b, 0x3, 0xe1, 0x1f, 0x0, 0x0, 0xf0, + 0x3, 0xe2, 0x0, 0x7a, 0x79, 0x0, 0x1, 0xf0, + 0xc, 0x40, 0x0, 0x2, 0xb2, 0x1, 0xff, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6728 "木" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x3, 0x33, 0x33, 0x3a, 0xa3, 0x33, 0x33, 0x30, + 0xc, 0xdd, 0xdd, 0xdf, 0xfd, 0xdd, 0xdd, 0xc0, + 0x0, 0x0, 0x0, 0x8f, 0xf7, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xea, 0xad, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x1d, 0x49, 0x83, 0xd1, 0x0, 0x0, + 0x0, 0x0, 0xb7, 0x9, 0x80, 0x7c, 0x0, 0x0, + 0x0, 0xb, 0xb0, 0x9, 0x80, 0xa, 0xc1, 0x0, + 0x2, 0xda, 0x0, 0x9, 0x80, 0x0, 0xad, 0x30, + 0x3f, 0x80, 0x0, 0x9, 0x80, 0x0, 0x7, 0xf3, + 0x2, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x10, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + + /* U+672A "未" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0x11, 0x11, 0x19, 0x91, 0x11, 0x11, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x1, 0x11, 0x11, 0xaf, 0xf9, 0x11, 0x11, 0x10, + 0x0, 0x0, 0x6, 0xca, 0x9c, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x6d, 0x19, 0x81, 0xd6, 0x0, 0x0, + 0x0, 0x9, 0xd1, 0x9, 0x80, 0x1d, 0x90, 0x0, + 0x4, 0xdb, 0x10, 0x9, 0x80, 0x1, 0xbd, 0x40, + 0x2e, 0x60, 0x0, 0x9, 0x80, 0x0, 0x6, 0xe2, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + + /* U+672B "末" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0xe, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe1, + 0x2, 0x22, 0x22, 0x2a, 0x92, 0x22, 0x22, 0x20, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x2, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0x30, + 0x0, 0x22, 0x22, 0xaf, 0xfa, 0x22, 0x22, 0x0, + 0x0, 0x0, 0x6, 0xca, 0x9b, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x6c, 0x19, 0x80, 0xc7, 0x0, 0x0, + 0x0, 0x9, 0xd1, 0x9, 0x80, 0x1d, 0xa0, 0x0, + 0x4, 0xdb, 0x10, 0x9, 0x80, 0x1, 0xbe, 0x50, + 0x2d, 0x60, 0x0, 0x9, 0x80, 0x0, 0x6, 0xd2, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + + /* U+672C "本" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x1, 0x11, 0x14, 0xea, 0xae, 0x31, 0x11, 0x10, + 0x0, 0x0, 0xa, 0x79, 0x88, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x4e, 0x9, 0x81, 0xe3, 0x0, 0x0, + 0x0, 0x1, 0xe4, 0x9, 0x80, 0x5d, 0x0, 0x0, + 0x0, 0xc, 0x90, 0x9, 0x80, 0xa, 0xb0, 0x0, + 0x0, 0xbb, 0x0, 0x9, 0x80, 0x0, 0xcb, 0x10, + 0x1d, 0xb6, 0xff, 0xff, 0xff, 0xff, 0x6b, 0xe2, + 0x5, 0x0, 0x11, 0x1a, 0x91, 0x11, 0x0, 0x40, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + + /* U+672D "札" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x4b, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x4b, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x4b, 0x0, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xfd, 0x4b, 0x0, 0x0, 0x0, + 0x1, 0x17, 0xf2, 0x11, 0x4b, 0x0, 0x0, 0x0, + 0x0, 0xd, 0xfb, 0x0, 0x4b, 0x0, 0x0, 0x0, + 0x0, 0x3d, 0xf9, 0xa0, 0x4b, 0x0, 0x0, 0x0, + 0x0, 0xa5, 0xf0, 0xd7, 0x4b, 0x0, 0x0, 0x0, + 0x3, 0xd1, 0xf0, 0x22, 0x4b, 0x0, 0x0, 0x0, + 0xd, 0x50, 0xf0, 0x0, 0x4b, 0x0, 0x0, 0x0, + 0x6b, 0x0, 0xf0, 0x0, 0x4b, 0x0, 0x0, 0x92, + 0x1, 0x0, 0xf0, 0x0, 0x4b, 0x0, 0x0, 0xc3, + 0x0, 0x0, 0xf0, 0x0, 0x4d, 0x0, 0x1, 0xe1, + 0x0, 0x0, 0xf0, 0x0, 0xc, 0xff, 0xff, 0x80, + + /* U+673A "机" */ + 0x0, 0x6, 0x90, 0x0, 0xff, 0xff, 0xf2, 0x0, + 0x0, 0x6, 0x90, 0x0, 0xf0, 0x0, 0xe2, 0x0, + 0x0, 0x6, 0x90, 0x0, 0xf0, 0x0, 0xe2, 0x0, + 0x2f, 0xff, 0xff, 0xf0, 0xf0, 0x0, 0xe2, 0x0, + 0x1, 0x1c, 0xa1, 0x10, 0xf0, 0x0, 0xe2, 0x0, + 0x0, 0x1f, 0xa0, 0x0, 0xf0, 0x0, 0xe2, 0x0, + 0x0, 0x7d, 0xf7, 0x0, 0xe0, 0x0, 0xe2, 0x0, + 0x0, 0xd7, 0x9c, 0x61, 0xd0, 0x0, 0xe2, 0x0, + 0x6, 0x96, 0x91, 0xc4, 0xb0, 0x0, 0xe2, 0x0, + 0x1e, 0x16, 0x90, 0x6, 0x90, 0x0, 0xe2, 0x0, + 0x57, 0x6, 0x90, 0xb, 0x40, 0x0, 0xe2, 0x37, + 0x0, 0x6, 0x90, 0x2e, 0x0, 0x0, 0xe2, 0x39, + 0x0, 0x6, 0x90, 0xb6, 0x0, 0x0, 0xe3, 0x58, + 0x0, 0x6, 0x92, 0xb0, 0x0, 0x0, 0x8f, 0xe3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6750 "材" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, 0x3d, 0x0, + 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, 0x3d, 0x0, + 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, 0x3d, 0x0, + 0xf, 0xff, 0xff, 0xf5, 0xff, 0xff, 0xff, 0xf8, + 0x1, 0x1a, 0xe1, 0x10, 0x11, 0x11, 0xed, 0x10, + 0x0, 0xf, 0xfa, 0x0, 0x0, 0x7, 0xed, 0x0, + 0x0, 0x6d, 0xca, 0x90, 0x0, 0x3e, 0x5d, 0x0, + 0x0, 0xd6, 0xc0, 0xd3, 0x0, 0xd5, 0x3d, 0x0, + 0x6, 0xa4, 0xc0, 0x10, 0xc, 0x90, 0x3d, 0x0, + 0x2e, 0x24, 0xc0, 0x1, 0xbb, 0x0, 0x3d, 0x0, + 0x47, 0x4, 0xc0, 0xd, 0xb0, 0x0, 0x3d, 0x0, + 0x0, 0x4, 0xc0, 0x3, 0x0, 0x0, 0x3d, 0x0, + 0x0, 0x4, 0xc0, 0x0, 0x0, 0x11, 0x5d, 0x0, + 0x0, 0x4, 0xc0, 0x0, 0x0, 0xef, 0xe7, 0x0, + + /* U+6751 "村" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xc0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x3, 0xc0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x3, 0xc0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x2f, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf9, + 0x1, 0x19, 0xd1, 0x10, 0x0, 0x0, 0x3e, 0x0, + 0x0, 0xe, 0xd0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x5d, 0xfb, 0x0, 0x99, 0x0, 0x2e, 0x0, + 0x0, 0xc6, 0xc9, 0xa0, 0x1e, 0x40, 0x2e, 0x0, + 0x5, 0xa3, 0xc0, 0xb1, 0x6, 0xc0, 0x2e, 0x0, + 0x2e, 0x23, 0xc0, 0x0, 0x0, 0xc1, 0x2e, 0x0, + 0x47, 0x3, 0xc0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x3, 0xc0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x3, 0xc0, 0x0, 0x0, 0x11, 0x4e, 0x0, + 0x0, 0x3, 0xc0, 0x0, 0x0, 0xef, 0xe7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+675F "束" */ + 0x0, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, + 0x9, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xd0, + 0x1, 0x11, 0x11, 0x18, 0xa1, 0x11, 0x11, 0x10, + 0x0, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x8e, 0xee, 0xef, 0xfe, 0xee, 0xeb, 0x0, + 0x0, 0x88, 0x0, 0x7, 0xa0, 0x0, 0x5c, 0x0, + 0x0, 0x87, 0x0, 0x7, 0xa0, 0x0, 0x4c, 0x0, + 0x0, 0x88, 0x0, 0x8, 0xa0, 0x0, 0x5c, 0x0, + 0x0, 0x8e, 0xee, 0xef, 0xff, 0xee, 0xeb, 0x0, + 0x0, 0x0, 0x0, 0xae, 0xec, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x2c, 0x77, 0xa4, 0xd4, 0x0, 0x0, + 0x0, 0x29, 0xe4, 0x7, 0xa0, 0x2d, 0xb3, 0x0, + 0xa, 0xe7, 0x0, 0x7, 0xa0, 0x0, 0x6d, 0xc3, + 0x4, 0x0, 0x0, 0x7, 0xa0, 0x0, 0x0, 0x50, + + /* U+6761 "条" */ + 0x0, 0x0, 0x2, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xbf, 0xff, 0xff, 0xfd, 0x0, 0x0, + 0x0, 0x2c, 0xea, 0x0, 0x1, 0xd5, 0x0, 0x0, + 0x7, 0xe6, 0x9, 0xb1, 0x4d, 0x60, 0x0, 0x0, + 0x4, 0x10, 0x0, 0x9f, 0xf4, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x7d, 0xd6, 0x9e, 0xa5, 0x10, 0x0, + 0x4b, 0xed, 0x93, 0x6, 0x20, 0x6a, 0xee, 0xa0, + 0x14, 0x10, 0x0, 0xc, 0x40, 0x0, 0x1, 0x30, + 0x0, 0xac, 0xcc, 0xcf, 0xdc, 0xcc, 0xc4, 0x0, + 0x0, 0x22, 0x32, 0x2d, 0x72, 0x32, 0x21, 0x0, + 0x0, 0x1, 0xd3, 0xc, 0x40, 0xc6, 0x0, 0x0, + 0x0, 0x2d, 0x60, 0xc, 0x40, 0x1d, 0x70, 0x0, + 0x4, 0xe5, 0x0, 0xc, 0x40, 0x1, 0xe5, 0x0, + 0x0, 0x20, 0x3, 0xee, 0x20, 0x0, 0x22, 0x0, + + /* U+6765 "来" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x1, 0x33, 0x33, 0x3a, 0xa3, 0x33, 0x33, 0x10, + 0x4, 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xcc, 0x50, + 0x0, 0x8, 0x20, 0x9, 0x80, 0x0, 0xb1, 0x0, + 0x0, 0x7, 0xb0, 0x9, 0x80, 0x7, 0xb0, 0x0, + 0x0, 0x0, 0xf3, 0x9, 0x80, 0x1e, 0x30, 0x0, + 0x0, 0x0, 0x73, 0x9, 0x90, 0x48, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x0, 0x0, 0xcd, 0xdc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1b, 0x69, 0x86, 0xb0, 0x0, 0x0, + 0x0, 0x2, 0xd6, 0x9, 0x80, 0x6d, 0x20, 0x0, + 0x0, 0x7e, 0x50, 0x9, 0x80, 0x5, 0xe7, 0x0, + 0x2e, 0xb1, 0x0, 0x9, 0x80, 0x0, 0x2b, 0xe2, + 0x2, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x30, + + /* U+676F "杯" */ + 0x0, 0x8, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x70, 0x9f, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0x8, 0x70, 0x0, 0x0, 0x4e, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xa0, 0x0, 0xc6, 0x0, 0x0, + 0x1, 0x1d, 0x91, 0x0, 0x7, 0xf5, 0x20, 0x0, + 0x0, 0x3f, 0xf5, 0x0, 0x3e, 0xf7, 0xe3, 0x0, + 0x0, 0x8e, 0x9d, 0x33, 0xe4, 0xe2, 0x4e, 0x30, + 0x0, 0xd9, 0x73, 0x8f, 0x50, 0xe2, 0x4, 0xe2, + 0x6, 0x88, 0x71, 0xc3, 0x0, 0xe2, 0x0, 0x61, + 0x1e, 0x18, 0x70, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x37, 0x8, 0x70, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0x8, 0x70, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0x8, 0x70, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0x8, 0x70, 0x0, 0x0, 0xe2, 0x0, 0x0, + + /* U+6771 "東" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x12, 0x22, 0x2a, 0x92, 0x22, 0x22, 0x0, + 0x0, 0x8d, 0xaa, 0xad, 0xda, 0xaa, 0xcb, 0x0, + 0x0, 0x88, 0x0, 0x9, 0x80, 0x0, 0x5b, 0x0, + 0x0, 0x8e, 0xdd, 0xde, 0xed, 0xdd, 0xeb, 0x0, + 0x0, 0x88, 0x0, 0x9, 0x80, 0x0, 0x5b, 0x0, + 0x0, 0x8d, 0xaa, 0xad, 0xda, 0xaa, 0xcb, 0x0, + 0x0, 0x13, 0x34, 0xee, 0xed, 0x43, 0x32, 0x0, + 0x0, 0x0, 0x3e, 0x69, 0x88, 0xc2, 0x0, 0x0, + 0x0, 0x18, 0xe4, 0x9, 0x80, 0x5e, 0x81, 0x0, + 0x8, 0xfa, 0x20, 0x9, 0x80, 0x2, 0xaf, 0x81, + 0x8, 0x30, 0x0, 0x9, 0x80, 0x0, 0x3, 0x90, + + /* U+6790 "析" */ + 0x0, 0x9, 0x70, 0x0, 0x0, 0x3, 0x8a, 0x10, + 0x0, 0x9, 0x70, 0x1, 0x8b, 0xec, 0x73, 0x0, + 0x0, 0x9, 0x70, 0x3, 0xd2, 0x0, 0x0, 0x0, + 0xc, 0xce, 0xec, 0xb3, 0xc0, 0x0, 0x0, 0x0, + 0x1, 0x2d, 0x81, 0x13, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0xd0, 0x3, 0xff, 0xff, 0xff, 0xf4, + 0x0, 0x8e, 0xda, 0x4, 0xc1, 0x13, 0xe1, 0x10, + 0x0, 0xd9, 0x7b, 0x65, 0xa0, 0x1, 0xe0, 0x0, + 0x6, 0x89, 0x72, 0x36, 0x90, 0x1, 0xe0, 0x0, + 0x1e, 0x19, 0x70, 0x7, 0x80, 0x1, 0xe0, 0x0, + 0x37, 0x9, 0x70, 0xa, 0x50, 0x1, 0xe0, 0x0, + 0x0, 0x9, 0x70, 0xe, 0x10, 0x1, 0xe0, 0x0, + 0x0, 0x9, 0x70, 0x6c, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0x9, 0x70, 0x93, 0x0, 0x1, 0xe0, 0x0, + + /* U+6797 "林" */ + 0x0, 0x2, 0xd0, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x2, 0xd0, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x2, 0xd0, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xf4, 0xff, 0xff, 0xff, 0xf0, + 0x1, 0x19, 0xf2, 0x10, 0x11, 0x9f, 0x61, 0x10, + 0x0, 0xe, 0xfc, 0x0, 0x0, 0xff, 0xb0, 0x0, + 0x0, 0x5c, 0xd7, 0xb0, 0x6, 0xce, 0xd2, 0x0, + 0x0, 0xc5, 0xd0, 0xb4, 0xd, 0x5e, 0x78, 0x0, + 0x5, 0xb2, 0xd0, 0x0, 0x6a, 0x2e, 0x1e, 0x10, + 0x1e, 0x32, 0xd0, 0x2, 0xe2, 0x2e, 0x9, 0xa0, + 0x48, 0x2, 0xd0, 0xe, 0x70, 0x2e, 0x1, 0xe4, + 0x0, 0x2, 0xd0, 0x5, 0x0, 0x2e, 0x0, 0x20, + 0x0, 0x2, 0xd0, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x2, 0xd0, 0x0, 0x0, 0x2e, 0x0, 0x0, + + /* U+679C "果" */ + 0x0, 0x6f, 0xee, 0xef, 0xfe, 0xee, 0xf8, 0x0, + 0x0, 0x6a, 0x0, 0x8, 0x80, 0x0, 0x98, 0x0, + 0x0, 0x6a, 0x0, 0x8, 0x80, 0x0, 0x98, 0x0, + 0x0, 0x6f, 0xee, 0xef, 0xfe, 0xee, 0xf8, 0x0, + 0x0, 0x6a, 0x0, 0x8, 0x80, 0x0, 0x98, 0x0, + 0x0, 0x6b, 0x0, 0x9, 0x90, 0x0, 0x98, 0x0, + 0x0, 0x6d, 0xdd, 0xdf, 0xfd, 0xdd, 0xd7, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0xe, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe0, + 0x0, 0x0, 0x2, 0xdd, 0xcd, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x4e, 0x58, 0x83, 0xd5, 0x0, 0x0, + 0x0, 0x3a, 0xd3, 0x8, 0x80, 0x1b, 0xc5, 0x0, + 0x1c, 0xe6, 0x0, 0x8, 0x80, 0x0, 0x4c, 0xd2, + 0x4, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x30, + + /* U+67D0 "某" */ + 0x0, 0x1, 0xf0, 0x0, 0x0, 0xf, 0x0, 0x0, + 0xe, 0xee, 0xfe, 0xee, 0xee, 0xef, 0xee, 0xe1, + 0x0, 0x2, 0xf0, 0x0, 0x0, 0x1f, 0x10, 0x0, + 0x0, 0x1, 0xf2, 0x22, 0x22, 0x2f, 0x0, 0x0, + 0x0, 0x1, 0xfb, 0xbb, 0xbb, 0xcf, 0x0, 0x0, + 0x0, 0x1, 0xf0, 0x0, 0x0, 0xf, 0x0, 0x0, + 0x0, 0x1, 0xfe, 0xee, 0xee, 0xef, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x1b, 0xbb, 0xbb, 0xbe, 0xeb, 0xbb, 0xbb, 0xb1, + 0x3, 0x33, 0x35, 0xed, 0xde, 0x43, 0x33, 0x30, + 0x0, 0x0, 0x4e, 0x69, 0x87, 0xd3, 0x0, 0x0, + 0x0, 0x19, 0xe4, 0x9, 0x80, 0x4e, 0x92, 0x0, + 0x1a, 0xf8, 0x10, 0x9, 0x80, 0x1, 0x9f, 0xa1, + 0x7, 0x10, 0x0, 0x9, 0x80, 0x0, 0x1, 0x70, + + /* U+67E5 "查" */ + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x19, 0x81, 0x11, 0x11, 0x10, + 0x1d, 0xdd, 0xdd, 0xff, 0xff, 0xdd, 0xdd, 0xd1, + 0x0, 0x0, 0x9, 0xb9, 0x8b, 0x60, 0x0, 0x0, + 0x0, 0x1, 0xb9, 0x9, 0x70, 0x99, 0x0, 0x0, + 0x1, 0x8c, 0x40, 0x9, 0x70, 0x4, 0xb7, 0x0, + 0x1b, 0x54, 0xaa, 0xaf, 0xea, 0xaa, 0x45, 0x91, + 0x0, 0x6, 0xb2, 0x22, 0x22, 0x2b, 0x60, 0x0, + 0x0, 0x6, 0xa0, 0x0, 0x0, 0xb, 0x60, 0x0, + 0x0, 0x6, 0xeb, 0xbb, 0xbb, 0xbe, 0x60, 0x0, + 0x0, 0x6, 0xa0, 0x0, 0x0, 0xa, 0x60, 0x0, + 0x0, 0x5, 0xcc, 0xcc, 0xcc, 0xcc, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xc0, + + /* U+67F1 "柱" */ + 0x0, 0xb, 0x50, 0x0, 0x3, 0xb0, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0xd5, 0x0, 0x0, + 0x0, 0xb, 0x60, 0x12, 0x22, 0x77, 0x22, 0x20, + 0x1e, 0xef, 0xfe, 0x9d, 0xdd, 0xfe, 0xdd, 0xc0, + 0x0, 0xe, 0x50, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x0, 0x4f, 0xe1, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x0, 0x9e, 0x9c, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x0, 0xcb, 0x59, 0x4b, 0xcc, 0xfd, 0xcc, 0x50, + 0x7, 0x7b, 0x50, 0x2, 0x22, 0xd7, 0x22, 0x10, + 0x1e, 0x1b, 0x50, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x16, 0xb, 0x50, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x0, 0xb, 0x50, 0xcf, 0xff, 0xff, 0xff, 0xf3, + + /* U+67FB "査" */ + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x19, 0x81, 0x11, 0x11, 0x10, + 0x1d, 0xdd, 0xdd, 0xff, 0xff, 0xdd, 0xdd, 0xd1, + 0x0, 0x0, 0x8, 0xc9, 0x9c, 0x70, 0x0, 0x0, + 0x0, 0x0, 0xab, 0x19, 0x71, 0xc9, 0x0, 0x0, + 0x0, 0x5d, 0x90, 0x9, 0x70, 0x8, 0xd5, 0x0, + 0x1d, 0xc4, 0x22, 0x27, 0x62, 0x22, 0x4b, 0xd1, + 0x3, 0x6, 0xeb, 0xbb, 0xbb, 0xbe, 0x70, 0x10, + 0x0, 0x6, 0xa0, 0x0, 0x0, 0xa, 0x70, 0x0, + 0x0, 0x6, 0xec, 0xcc, 0xcc, 0xce, 0x70, 0x0, + 0x0, 0x6, 0xa0, 0x0, 0x0, 0xa, 0x70, 0x0, + 0x0, 0x6, 0xec, 0xcc, 0xcc, 0xce, 0x70, 0x0, + 0x0, 0x6, 0xa0, 0x0, 0x0, 0xa, 0x70, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + + /* U+67FF "柿" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x1, 0xe4, 0x0, 0x0, + 0x0, 0xf, 0x10, 0xad, 0xdd, 0xfe, 0xdd, 0xd7, + 0x3e, 0xef, 0xee, 0x1, 0x11, 0xe2, 0x11, 0x10, + 0x0, 0x4f, 0x10, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0x8f, 0xb0, 0x1f, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0xcf, 0xa5, 0x1e, 0x0, 0xe1, 0x1, 0xe0, + 0x2, 0xaf, 0x2d, 0x1e, 0x0, 0xe1, 0x1, 0xe0, + 0x8, 0x5f, 0x2, 0x1e, 0x0, 0xe1, 0x1, 0xe0, + 0x1e, 0xf, 0x0, 0x1e, 0x0, 0xe1, 0x1, 0xe0, + 0x28, 0xf, 0x0, 0x1e, 0x0, 0xe1, 0x23, 0xe0, + 0x0, 0xf, 0x0, 0x1c, 0x0, 0xe1, 0xcd, 0x70, + 0x0, 0xf, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + + /* U+6811 "树" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4a, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, + 0x0, 0x4a, 0x1, 0x55, 0x52, 0x0, 0xf, 0x0, + 0x0, 0x5b, 0x1, 0x77, 0xb7, 0x0, 0xf, 0x0, + 0x1e, 0xff, 0xe2, 0x0, 0x98, 0xee, 0xef, 0xf4, + 0x0, 0x8b, 0x3, 0x80, 0xc3, 0x0, 0xf, 0x0, + 0x0, 0xcf, 0x30, 0xd3, 0xf0, 0x20, 0xf, 0x0, + 0x0, 0xfc, 0xc0, 0x4d, 0xd0, 0x78, 0xf, 0x0, + 0x4, 0xda, 0x95, 0xb, 0x90, 0xd, 0x1f, 0x0, + 0xa, 0x8a, 0x21, 0xc, 0xe0, 0x7, 0x8f, 0x0, + 0x2d, 0x5a, 0x0, 0x2e, 0xa7, 0x1, 0x1f, 0x0, + 0x35, 0x4a, 0x0, 0x98, 0x2c, 0x0, 0xf, 0x0, + 0x0, 0x4a, 0x3, 0xe1, 0x0, 0x0, 0xf, 0x0, + 0x0, 0x4a, 0xb, 0x50, 0x0, 0x0, 0xf, 0x0, + 0x0, 0x4a, 0x1, 0x0, 0x0, 0x2f, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6821 "校" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0x0, 0xd, 0x20, 0x8d, 0xdd, 0xdd, 0xdd, 0xd2, + 0xf, 0xff, 0xff, 0x0, 0x41, 0x1, 0x50, 0x0, + 0x0, 0x3f, 0x30, 0x2, 0xe2, 0x1, 0xd5, 0x0, + 0x0, 0x7f, 0xa0, 0xc, 0x60, 0x0, 0x1e, 0x30, + 0x0, 0xce, 0xc4, 0xba, 0x80, 0x0, 0xa5, 0xd0, + 0x2, 0xbd, 0x4d, 0x20, 0xd3, 0x4, 0xd0, 0x10, + 0x9, 0x5d, 0x23, 0x0, 0x6b, 0xb, 0x70, 0x0, + 0x2d, 0xd, 0x20, 0x0, 0xc, 0xbd, 0x0, 0x0, + 0x36, 0xd, 0x20, 0x0, 0x5, 0xf8, 0x0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x5e, 0x7e, 0x80, 0x0, + 0x0, 0xd, 0x20, 0x2a, 0xe3, 0x1, 0xcd, 0x60, + 0x0, 0xd, 0x20, 0xc7, 0x0, 0x0, 0x5, 0xb1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+682A "株" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x30, 0xc3, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x3, 0xc0, 0xc3, 0x0, 0x0, + 0x1, 0x1b, 0x61, 0x7, 0xa2, 0xd5, 0x22, 0x10, + 0x1e, 0xef, 0xfe, 0x6a, 0xed, 0xfe, 0xdd, 0x80, + 0x0, 0xf, 0x70, 0x1e, 0x0, 0xc3, 0x0, 0x0, + 0x0, 0x5f, 0xe1, 0x78, 0x0, 0xc3, 0x0, 0x0, + 0x0, 0xbe, 0x9a, 0x14, 0x33, 0xd6, 0x33, 0x30, + 0x1, 0xcb, 0x5b, 0x8c, 0xce, 0xff, 0xcc, 0xc2, + 0x9, 0x7b, 0x51, 0x0, 0xd, 0xed, 0x60, 0x0, + 0x2e, 0xb, 0x50, 0x0, 0x88, 0xc5, 0xe1, 0x0, + 0x15, 0xb, 0x50, 0x3, 0xd0, 0xc3, 0x7b, 0x0, + 0x0, 0xb, 0x50, 0x3d, 0x30, 0xc3, 0xb, 0x90, + 0x0, 0xb, 0x51, 0xe3, 0x0, 0xc3, 0x1, 0xc5, + 0x0, 0xb, 0x50, 0x10, 0x0, 0xc3, 0x0, 0x0, + + /* U+6839 "根" */ + 0x0, 0xa, 0x40, 0x1f, 0xee, 0xee, 0xff, 0x0, + 0x0, 0xa, 0x40, 0x1e, 0x0, 0x0, 0xf, 0x0, + 0x18, 0x8d, 0xb8, 0x4e, 0x0, 0x0, 0xf, 0x0, + 0x17, 0x7e, 0xa7, 0x3f, 0xee, 0xee, 0xef, 0x0, + 0x0, 0x2f, 0x70, 0x1e, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0x7f, 0xe2, 0x1e, 0x0, 0x0, 0xf, 0x0, + 0x0, 0xcc, 0x8c, 0x2f, 0xee, 0xee, 0xef, 0x0, + 0x3, 0xba, 0x48, 0x2e, 0x4, 0xc0, 0x1, 0x10, + 0xb, 0x5a, 0x40, 0x1e, 0x0, 0xe2, 0x1c, 0x90, + 0x3d, 0xa, 0x40, 0x1e, 0x0, 0x7c, 0xe5, 0x0, + 0x3, 0xa, 0x40, 0x1e, 0x0, 0xe, 0x60, 0x0, + 0x0, 0xa, 0x40, 0x1e, 0x0, 0x14, 0xf3, 0x0, + 0x0, 0xa, 0x40, 0x3f, 0x9d, 0xe0, 0x6f, 0x80, + 0x0, 0xa, 0x40, 0x5c, 0x72, 0x0, 0x3, 0xb1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+683C "格" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x60, 0x0, 0xd, 0x20, 0x0, 0x0, + 0x0, 0x9, 0x60, 0x0, 0x7e, 0x77, 0x77, 0x0, + 0x0, 0x9, 0x60, 0x3, 0xf6, 0x55, 0xac, 0x0, + 0x1f, 0xff, 0xff, 0xae, 0xb8, 0x1, 0xe4, 0x0, + 0x0, 0x1e, 0x71, 0xc6, 0xc, 0x5b, 0x90, 0x0, + 0x0, 0x3f, 0xe2, 0x0, 0x2, 0xfd, 0x0, 0x0, + 0x0, 0x9e, 0xad, 0x10, 0x3d, 0x9c, 0xa1, 0x0, + 0x0, 0xc9, 0x67, 0x6a, 0xd4, 0x0, 0x6e, 0x92, + 0x6, 0x89, 0x63, 0xec, 0xdc, 0xcc, 0xce, 0x92, + 0xd, 0x19, 0x60, 0x8, 0x81, 0x11, 0x1e, 0x10, + 0x48, 0x9, 0x60, 0x8, 0x70, 0x0, 0xe, 0x10, + 0x0, 0x9, 0x60, 0x8, 0x70, 0x0, 0xe, 0x10, + 0x0, 0x9, 0x60, 0x8, 0x93, 0x33, 0x3f, 0x10, + 0x0, 0x9, 0x60, 0x8, 0xdb, 0xbb, 0xbf, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6843 "桃" */ + 0x0, 0xf, 0x0, 0x0, 0xe, 0xc, 0x20, 0x0, + 0x0, 0xf, 0x0, 0x0, 0xe, 0xc, 0x20, 0x0, + 0x1, 0x1f, 0x20, 0x52, 0xe, 0xc, 0x20, 0xa2, + 0x1e, 0xef, 0xe9, 0x4b, 0x1e, 0xc, 0x25, 0xd0, + 0x0, 0x3f, 0x20, 0xc, 0x4e, 0xc, 0x3e, 0x30, + 0x0, 0x8f, 0xc0, 0x5, 0x6e, 0xc, 0x67, 0x0, + 0x0, 0xcf, 0x89, 0x0, 0x1e, 0xc, 0x30, 0x0, + 0x2, 0xbf, 0x19, 0x0, 0x6d, 0xc, 0xd5, 0x0, + 0x8, 0x6f, 0x0, 0x1b, 0xdc, 0xc, 0x4c, 0x70, + 0x1e, 0xf, 0x1, 0xe7, 0x58, 0xc, 0x20, 0xc6, + 0x16, 0xf, 0x0, 0x20, 0xb4, 0xc, 0x20, 0x0, + 0x0, 0xf, 0x0, 0x4, 0xb0, 0xc, 0x20, 0x37, + 0x0, 0xf, 0x0, 0x3d, 0x20, 0xc, 0x30, 0x69, + 0x0, 0xf, 0x4, 0xc2, 0x0, 0x8, 0xff, 0xf4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6848 "案" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x60, 0x0, 0x0, 0x0, + 0xa, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xc0, + 0xa, 0x40, 0x0, 0x84, 0x0, 0x0, 0x3, 0xc0, + 0xe, 0xcb, 0xbc, 0xfb, 0xbb, 0xbb, 0xbc, 0xe0, + 0x2, 0x22, 0xaa, 0x22, 0x22, 0xba, 0x22, 0x20, + 0x0, 0x7, 0xf8, 0x52, 0x2a, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x28, 0xdf, 0xff, 0x84, 0x10, 0x0, + 0x9, 0xcd, 0xdb, 0x75, 0x22, 0x6a, 0xec, 0x30, + 0x2, 0x10, 0x0, 0x9, 0x70, 0x0, 0x3, 0x0, + 0x2e, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe2, + 0x0, 0x0, 0x3, 0xdc, 0xbd, 0x40, 0x0, 0x0, + 0x0, 0x1, 0x9d, 0x29, 0x72, 0xd9, 0x20, 0x0, + 0x16, 0xcd, 0x70, 0x9, 0x70, 0x7, 0xdc, 0x61, + 0x1a, 0x40, 0x0, 0x9, 0x70, 0x0, 0x4, 0xa2, + + /* U+689D "條" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x4, 0xc0, 0x0, 0x5, 0xd0, 0x0, 0x0, + 0x0, 0xa, 0x60, 0x0, 0x2f, 0xdb, 0xbb, 0x60, + 0x0, 0x1f, 0x1e, 0x13, 0xed, 0x11, 0x2e, 0x20, + 0x0, 0x8c, 0xe, 0x2d, 0x48, 0x91, 0xc6, 0x0, + 0x3, 0xfb, 0xe, 0x10, 0x0, 0xbf, 0x70, 0x0, + 0xc, 0xbb, 0xe, 0x10, 0x5c, 0xb6, 0xe9, 0x30, + 0xb, 0x4b, 0xe, 0x5e, 0xa4, 0x39, 0x7, 0xd8, + 0x0, 0x4b, 0xe, 0x11, 0x0, 0x4b, 0x0, 0x0, + 0x0, 0x4b, 0xe, 0x1d, 0xdd, 0xef, 0xdd, 0xd4, + 0x0, 0x4b, 0xe, 0x13, 0x33, 0x6c, 0x33, 0x31, + 0x0, 0x4b, 0xe, 0x11, 0xd1, 0x4b, 0x1c, 0x20, + 0x0, 0x4b, 0xa, 0x1b, 0x70, 0x4b, 0x3, 0xd0, + 0x0, 0x4b, 0x0, 0xa8, 0x2, 0x6b, 0x0, 0x75, + 0x0, 0x4b, 0x0, 0x0, 0xd, 0xd6, 0x0, 0x0, + + /* U+68B0 "械" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x3c, 0x43, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x2c, 0x1c, 0x20, + 0x0, 0x1e, 0x0, 0x22, 0x22, 0x4d, 0x24, 0x30, + 0xb, 0xcf, 0xc5, 0xdd, 0xdd, 0xdf, 0xdd, 0xc0, + 0x3, 0x6f, 0x31, 0x3, 0x4, 0xe, 0x0, 0x0, + 0x0, 0x7f, 0x60, 0x2b, 0xe, 0xe, 0x2, 0x90, + 0x0, 0xbe, 0xd1, 0x2b, 0xe, 0xd, 0x17, 0x80, + 0x0, 0xde, 0x64, 0x9e, 0x8f, 0x6b, 0x3c, 0x30, + 0x6, 0x8e, 0x0, 0x8d, 0x6f, 0x59, 0x7e, 0x0, + 0xd, 0x3e, 0x0, 0x58, 0xe, 0x6, 0xe6, 0x0, + 0x49, 0x1e, 0x0, 0x76, 0xe, 0x4, 0xe0, 0x0, + 0x1, 0x1e, 0x0, 0xd1, 0xe, 0xc, 0xf0, 0x81, + 0x0, 0x1e, 0x7, 0x90, 0xc, 0xb7, 0xa7, 0xc0, + 0x0, 0x1e, 0x2, 0x0, 0x8, 0x50, 0x1d, 0xa0, + + /* U+68EE "森" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x3, 0xdd, 0xdd, 0xde, 0xed, 0xdd, 0xdd, 0x60, + 0x0, 0x22, 0x25, 0xed, 0xce, 0x52, 0x22, 0x10, + 0x0, 0x0, 0x5f, 0x59, 0x84, 0xe6, 0x0, 0x0, + 0x0, 0x4b, 0xf4, 0x9, 0x80, 0x3e, 0xd7, 0x10, + 0xa, 0xfb, 0x40, 0x9, 0x80, 0x3, 0x7e, 0xe0, + 0x3, 0x42, 0xc0, 0x9, 0x80, 0x1e, 0x1, 0x30, + 0x0, 0x2, 0xc0, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x2e, 0xef, 0xfe, 0xe3, 0xee, 0xff, 0xfe, 0xe5, + 0x0, 0x1e, 0xe3, 0x0, 0x3, 0xef, 0xc0, 0x0, + 0x0, 0xb8, 0xec, 0x80, 0xd, 0x5e, 0x6a, 0x0, + 0xb, 0xa3, 0xc0, 0x82, 0xc7, 0x1e, 0xb, 0x90, + 0x5a, 0x2, 0xc0, 0x1e, 0x60, 0x1e, 0x0, 0xb8, + 0x0, 0x2, 0xc0, 0x1, 0x0, 0x1e, 0x0, 0x0, + + /* U+690D "植" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0xf, 0x0, 0xbc, 0xce, 0xec, 0xcc, 0xb0, + 0x6, 0x6f, 0x64, 0x11, 0x1c, 0x51, 0x11, 0x10, + 0x1e, 0xef, 0xea, 0x0, 0xe, 0x20, 0x0, 0x0, + 0x0, 0x4f, 0x10, 0x2f, 0xcc, 0xcc, 0xcf, 0x0, + 0x0, 0x9f, 0xa0, 0x2c, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0xdf, 0xa5, 0x2f, 0xcc, 0xcc, 0xdf, 0x0, + 0x3, 0x9f, 0x28, 0x2c, 0x0, 0x0, 0x1f, 0x0, + 0xb, 0x4f, 0x0, 0x2f, 0xcc, 0xcc, 0xdf, 0x0, + 0x4c, 0xf, 0x0, 0x2c, 0x0, 0x0, 0x1f, 0x0, + 0x13, 0xf, 0x0, 0x2f, 0xaa, 0xaa, 0xbf, 0x0, + 0x0, 0xf, 0x0, 0x2d, 0x22, 0x22, 0x3f, 0x0, + 0x0, 0xf, 0x0, 0x2c, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0xf, 0x9, 0xef, 0xee, 0xee, 0xef, 0xe6, + + /* U+691C "検" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x4, 0xaa, 0x0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x5b, 0x4, 0xc1, 0x0, + 0x1, 0x1d, 0x31, 0x2b, 0xa0, 0x0, 0x3d, 0x70, + 0x2d, 0xdf, 0xdd, 0xea, 0xdd, 0xdd, 0xdc, 0xa9, + 0x0, 0x2f, 0x20, 0x0, 0x11, 0xc4, 0x11, 0x0, + 0x0, 0x7f, 0x40, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0x0, 0xcf, 0xe1, 0x6f, 0xee, 0xfe, 0xee, 0xd0, + 0x1, 0xdd, 0x8b, 0x7a, 0x0, 0xc3, 0x2, 0xd0, + 0x8, 0x7d, 0x29, 0x7a, 0x0, 0xc3, 0x2, 0xd0, + 0x2e, 0x1d, 0x20, 0x6e, 0xde, 0xfe, 0xde, 0xc0, + 0x46, 0xd, 0x20, 0x0, 0x4, 0xee, 0x0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x2e, 0x48, 0xb0, 0x0, + 0x0, 0xd, 0x20, 0x18, 0xe4, 0x0, 0xad, 0x50, + 0x0, 0xd, 0x25, 0xd8, 0x10, 0x0, 0x3, 0xc7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+695A "楚" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xe0, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0xe, 0xef, 0xfe, 0xe3, 0xee, 0xff, 0xee, 0xb0, + 0x0, 0xd, 0xf8, 0x0, 0x1, 0xef, 0x80, 0x0, + 0x0, 0xa9, 0xe9, 0xa0, 0xc, 0x7e, 0x99, 0x0, + 0xb, 0xa2, 0xe0, 0x72, 0xd8, 0x2e, 0xa, 0x90, + 0x29, 0x2, 0xe0, 0x5, 0x70, 0x2e, 0x0, 0x80, + 0x2, 0x23, 0x82, 0x22, 0x22, 0x38, 0x22, 0x10, + 0xb, 0xcc, 0xcc, 0xcf, 0xec, 0xcc, 0xce, 0xa0, + 0x0, 0x3, 0x40, 0xc, 0x50, 0x0, 0xe, 0x30, + 0x0, 0x9, 0x70, 0xc, 0x72, 0x22, 0x35, 0x0, + 0x0, 0xe, 0x90, 0xc, 0xed, 0xdd, 0xd1, 0x0, + 0x0, 0x6d, 0xe4, 0xc, 0x50, 0x0, 0x0, 0x0, + 0x4, 0xf3, 0x4f, 0xad, 0x60, 0x0, 0x0, 0x0, + 0x3e, 0x40, 0x1, 0x8c, 0xef, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+696D "業" */ + 0x0, 0x39, 0x0, 0xf0, 0xf, 0x0, 0x76, 0x0, + 0x0, 0xb, 0x60, 0xf0, 0xf, 0x2, 0xd1, 0x0, + 0xa, 0xbd, 0xdb, 0xfb, 0xbf, 0xbd, 0xdb, 0xb0, + 0x2, 0x22, 0x6c, 0x22, 0x22, 0xc9, 0x22, 0x20, + 0x0, 0x0, 0xe, 0x30, 0x2, 0xe0, 0x0, 0x0, + 0x3, 0xee, 0xef, 0xee, 0xee, 0xfe, 0xee, 0x50, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x5d, 0xdd, 0xde, 0xed, 0xdd, 0xd8, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0xb, 0xbb, 0xbb, 0xbe, 0xdb, 0xbb, 0xbb, 0xb0, + 0x2, 0x22, 0x27, 0xed, 0xde, 0x62, 0x22, 0x20, + 0x0, 0x2, 0xbd, 0x48, 0x83, 0xda, 0x20, 0x0, + 0x17, 0xdd, 0x70, 0x8, 0x80, 0x7, 0xec, 0x71, + 0x8, 0x40, 0x0, 0x8, 0x80, 0x0, 0x4, 0x90, + + /* U+6975 "極" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x59, 0x7, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0x59, 0x0, 0x0, 0x0, 0x6, 0xe3, 0x0, + 0x16, 0x9c, 0x60, 0x0, 0x1, 0xac, 0x20, 0x0, + 0x2d, 0xef, 0xd1, 0x0, 0xd, 0x80, 0x0, 0x0, + 0x0, 0x8a, 0x8, 0xdd, 0x1d, 0x3d, 0xde, 0x70, + 0x0, 0xdf, 0x29, 0x1a, 0x1d, 0x10, 0x9, 0x40, + 0x1, 0xfc, 0xb9, 0x1a, 0x1d, 0x1d, 0x1e, 0x10, + 0x6, 0xc9, 0x9a, 0x1a, 0x1d, 0x14, 0xdb, 0x0, + 0xc, 0x79, 0x9, 0x1a, 0x1d, 0x10, 0xc8, 0x0, + 0x4b, 0x59, 0x9, 0xdc, 0x1d, 0x15, 0xbd, 0x10, + 0x44, 0x59, 0x8, 0x10, 0xe, 0x5d, 0x15, 0x90, + 0x0, 0x59, 0x0, 0x8, 0xaa, 0x11, 0x0, 0x10, + 0x0, 0x59, 0x3b, 0xbb, 0xbb, 0xbb, 0xbb, 0xb1, + 0x0, 0x59, 0x13, 0x33, 0x33, 0x33, 0x33, 0x30, + + /* U+697D "楽" */ + 0x0, 0x0, 0x0, 0x4, 0x40, 0x0, 0x0, 0x0, + 0x3, 0x10, 0x0, 0xb, 0x60, 0x0, 0x4, 0x50, + 0x6, 0xe3, 0xd, 0xef, 0xee, 0xe0, 0x3e, 0x40, + 0x0, 0x5e, 0x2e, 0x10, 0x0, 0xf3, 0xe5, 0x0, + 0x0, 0x7, 0x2e, 0x10, 0x0, 0xf5, 0x40, 0x0, + 0x0, 0x0, 0x1e, 0xdd, 0xdd, 0xf3, 0x10, 0x0, + 0x0, 0x5c, 0x6e, 0x10, 0x0, 0xf5, 0xd9, 0x10, + 0x2d, 0xa2, 0xe, 0xdd, 0xdd, 0xf0, 0x8, 0xe1, + 0x2, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x20, + 0x1, 0x11, 0x11, 0x19, 0x81, 0x11, 0x11, 0x10, + 0x1d, 0xdd, 0xdd, 0xff, 0xff, 0xdd, 0xdd, 0xd1, + 0x0, 0x0, 0x8, 0xdb, 0xbd, 0x50, 0x0, 0x0, + 0x0, 0x3, 0xda, 0x19, 0x81, 0xbb, 0x30, 0x0, + 0x6, 0xcc, 0x40, 0x9, 0x80, 0x5, 0xcd, 0x71, + 0x19, 0x30, 0x0, 0x9, 0x80, 0x0, 0x2, 0x80, + + /* U+6982 "概" */ + 0x0, 0x69, 0x9, 0xee, 0xf3, 0xff, 0xff, 0xb0, + 0x0, 0x69, 0x9, 0x30, 0xc0, 0x0, 0x85, 0x0, + 0x1, 0x7a, 0x19, 0x30, 0xc0, 0x53, 0x94, 0x0, + 0x1c, 0xee, 0xc9, 0xdc, 0xf0, 0xa3, 0x94, 0x0, + 0x0, 0x9a, 0x9, 0x30, 0xc0, 0xd0, 0xb2, 0x0, + 0x0, 0xdf, 0x29, 0x30, 0xc1, 0xd0, 0xd1, 0x0, + 0x1, 0xfd, 0xb9, 0xcb, 0xf6, 0xfe, 0xfe, 0xe0, + 0x5, 0xe9, 0xa9, 0x52, 0x20, 0x4, 0xc0, 0x0, + 0xb, 0x99, 0x9, 0x35, 0x50, 0x9, 0xf2, 0x0, + 0x2d, 0x69, 0x9, 0x31, 0xd0, 0xe, 0xc2, 0x0, + 0x45, 0x69, 0x9, 0x6c, 0xd4, 0x78, 0xb2, 0x0, + 0x0, 0x69, 0xd, 0xc2, 0x35, 0xd1, 0xb2, 0x90, + 0x0, 0x69, 0x7, 0x0, 0xc, 0x30, 0xb2, 0xa0, + 0x0, 0x69, 0x0, 0x0, 0x86, 0x0, 0x8e, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+69CB "構" */ + 0x0, 0xd, 0x20, 0x0, 0xe1, 0x0, 0xf0, 0x0, + 0x0, 0xd, 0x20, 0x8c, 0xfd, 0xcd, 0xfc, 0xc0, + 0x0, 0xd, 0x20, 0x0, 0xe1, 0x0, 0xf0, 0x0, + 0x1c, 0xcf, 0xdc, 0x5c, 0xfd, 0xcc, 0xfc, 0x90, + 0x3, 0x4f, 0x53, 0x0, 0xe1, 0x0, 0xf0, 0x0, + 0x0, 0x5f, 0x40, 0xdd, 0xdd, 0xfd, 0xdd, 0xd4, + 0x0, 0xaf, 0xd0, 0x1, 0x11, 0xf1, 0x11, 0x0, + 0x0, 0xcd, 0x98, 0x4e, 0xbb, 0xfb, 0xbe, 0x70, + 0x6, 0x7d, 0x2b, 0x4a, 0x1, 0xf0, 0x9, 0x70, + 0xd, 0x1d, 0x20, 0x4e, 0xbb, 0xfb, 0xbe, 0x70, + 0x58, 0xd, 0x20, 0x4a, 0x1, 0xf0, 0x8, 0x70, + 0x1, 0xd, 0x24, 0xdf, 0xdd, 0xdd, 0xde, 0xe6, + 0x0, 0xd, 0x20, 0x4a, 0x0, 0x0, 0x8, 0x70, + 0x0, 0xd, 0x20, 0x4a, 0x0, 0x5, 0xde, 0x40, + + /* U+69D8 "様" */ + 0x0, 0xd, 0x20, 0x3, 0x90, 0x0, 0x78, 0x0, + 0x0, 0xd, 0x20, 0x12, 0xd4, 0x12, 0xe3, 0x10, + 0x0, 0xd, 0x20, 0x8c, 0xcc, 0xfc, 0xcc, 0xc0, + 0x1b, 0xbf, 0xbb, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x4, 0x5f, 0x64, 0x2d, 0xdd, 0xfd, 0xdd, 0x80, + 0x0, 0x5f, 0x50, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0xbf, 0xd1, 0xee, 0xee, 0xfe, 0xee, 0xe3, + 0x1, 0xbd, 0x6b, 0x2, 0x0, 0xe2, 0x0, 0x40, + 0x8, 0x6d, 0x26, 0x2d, 0x20, 0xe9, 0xa, 0x90, + 0x1d, 0xd, 0x20, 0x4, 0xb0, 0xee, 0xb8, 0x0, + 0x35, 0xd, 0x20, 0x0, 0x66, 0xe5, 0xd1, 0x0, + 0x0, 0xd, 0x20, 0x5d, 0xa2, 0xe1, 0x7c, 0x20, + 0x0, 0xd, 0x26, 0xb3, 0x0, 0xf1, 0x5, 0xe4, + 0x0, 0xd, 0x20, 0x0, 0xaf, 0xc0, 0x0, 0x10, + + /* U+6A02 "樂" */ + 0x0, 0x3, 0x0, 0x3, 0x30, 0x0, 0x30, 0x0, + 0x0, 0x3c, 0x0, 0x9, 0x50, 0x0, 0xe1, 0x0, + 0x0, 0x95, 0x32, 0xdf, 0xdd, 0x14, 0xa0, 0x20, + 0x1, 0xc0, 0xc2, 0xe0, 0xe, 0x1c, 0x25, 0xa0, + 0xb, 0xdd, 0x60, 0xe0, 0xe, 0x7d, 0x9d, 0x10, + 0x3, 0x4b, 0x1, 0xfc, 0xcf, 0x56, 0xb5, 0x0, + 0x0, 0xb1, 0x93, 0xe0, 0xe, 0x14, 0x83, 0x60, + 0xb, 0xdb, 0xc7, 0xfd, 0xdf, 0x4f, 0xbc, 0xc0, + 0x0, 0x0, 0x12, 0x5, 0x50, 0x12, 0x0, 0x50, + 0x2, 0x22, 0x22, 0x2a, 0x92, 0x22, 0x22, 0x20, + 0x1b, 0xbb, 0xbb, 0xdf, 0xfd, 0xbb, 0xbb, 0xb1, + 0x0, 0x0, 0x6, 0xdb, 0xac, 0x70, 0x0, 0x0, + 0x0, 0x5, 0xd9, 0x8, 0x80, 0x7d, 0x71, 0x0, + 0x1a, 0xe9, 0x20, 0x8, 0x80, 0x1, 0x7e, 0xb2, + 0x4, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x40, + + /* U+6A19 "標" */ + 0x0, 0xd, 0x20, 0xde, 0xef, 0xef, 0xfe, 0xe4, + 0x0, 0xd, 0x20, 0x0, 0xe, 0x8, 0x50, 0x0, + 0x0, 0xd, 0x20, 0x4b, 0xbf, 0xbd, 0xdb, 0xa0, + 0x2f, 0xff, 0xff, 0x6a, 0x3d, 0x39, 0x63, 0xe0, + 0x1, 0x3f, 0x31, 0x68, 0xc, 0x8, 0x40, 0xe0, + 0x0, 0x6f, 0x50, 0x6d, 0xbe, 0xbd, 0xcb, 0xe0, + 0x0, 0xbf, 0xd1, 0x1, 0x11, 0x11, 0x11, 0x10, + 0x1, 0xbd, 0x6b, 0xd, 0xdd, 0xdd, 0xdd, 0x70, + 0x8, 0x5d, 0x25, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0xd, 0x20, 0xee, 0xee, 0xee, 0xee, 0xe5, + 0x35, 0xd, 0x20, 0x3, 0x40, 0xd2, 0x24, 0x0, + 0x0, 0xd, 0x20, 0x2e, 0x30, 0xd2, 0x2d, 0x40, + 0x0, 0xd, 0x23, 0xe4, 0x0, 0xd2, 0x2, 0xe2, + 0x0, 0xd, 0x20, 0x20, 0x8d, 0xd0, 0x0, 0x20, + + /* U+6A21 "模" */ + 0x0, 0xf, 0x0, 0x0, 0xe1, 0x1, 0xe0, 0x0, + 0x0, 0xf, 0x1, 0xaa, 0xfa, 0xaa, 0xfa, 0xa2, + 0x0, 0xf, 0x0, 0x44, 0xf5, 0x45, 0xf4, 0x41, + 0x5, 0x7f, 0x54, 0x6c, 0xfd, 0xcd, 0xfc, 0x40, + 0x0, 0x5f, 0x30, 0x86, 0x0, 0x0, 0xa, 0x60, + 0x0, 0x9f, 0xc0, 0x8d, 0xbb, 0xbb, 0xbe, 0x60, + 0x0, 0xdf, 0x86, 0x87, 0x0, 0x0, 0xa, 0x60, + 0x3, 0xaf, 0x19, 0x8d, 0xaa, 0xaa, 0xae, 0x60, + 0x9, 0x5f, 0x0, 0x11, 0x17, 0xc1, 0x11, 0x0, + 0x2e, 0x1f, 0x0, 0x0, 0x8, 0xa0, 0x0, 0x0, + 0x27, 0xf, 0x7, 0xdd, 0xef, 0xff, 0xdd, 0xd3, + 0x0, 0xf, 0x0, 0x0, 0x6e, 0x4e, 0x30, 0x0, + 0x0, 0xf, 0x0, 0x29, 0xe2, 0x5, 0xe7, 0x10, + 0x0, 0xf, 0x9, 0xc7, 0x0, 0x0, 0x17, 0xd3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6A23 "樣" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x20, 0x3, 0xa0, 0x0, 0xa4, 0x0, + 0x0, 0xd, 0x20, 0x46, 0xd8, 0x67, 0xe6, 0x60, + 0x0, 0xd, 0x20, 0x35, 0x55, 0xf6, 0x55, 0x50, + 0x2f, 0xff, 0xff, 0xb, 0xbb, 0xfb, 0xbb, 0x50, + 0x1, 0x2f, 0x31, 0x1, 0x11, 0xf3, 0x11, 0x0, + 0x0, 0x6f, 0x70, 0xdd, 0xdd, 0xfe, 0xdd, 0xd2, + 0x0, 0xbe, 0xd2, 0x0, 0x1d, 0x93, 0x0, 0x0, + 0x0, 0xbd, 0x6b, 0x0, 0x0, 0x5d, 0x80, 0x0, + 0x7, 0x6d, 0x28, 0xc, 0xdd, 0xf1, 0x10, 0x30, + 0xd, 0x1d, 0x20, 0x11, 0x10, 0xe5, 0x1c, 0x70, + 0x47, 0xd, 0x21, 0xab, 0xf3, 0xed, 0xc4, 0x0, + 0x0, 0xd, 0x20, 0x7, 0xa0, 0xe4, 0xc3, 0x0, + 0x0, 0xd, 0x22, 0xa9, 0x0, 0xf1, 0x3c, 0xa2, + 0x0, 0xd, 0x22, 0x40, 0x9e, 0xc0, 0x0, 0x50, + + /* U+6A2A "横" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0xe1, 0x0, 0xf0, 0x0, + 0x0, 0xe, 0x10, 0x9e, 0xfe, 0xee, 0xfe, 0xe0, + 0x0, 0xe, 0x10, 0x0, 0xe1, 0x0, 0xf0, 0x0, + 0x2c, 0xcf, 0xdc, 0x21, 0xe3, 0x11, 0xf1, 0x10, + 0x4, 0x5f, 0x55, 0xdd, 0xdd, 0xfd, 0xdd, 0xd4, + 0x0, 0x6f, 0x30, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0xcf, 0xd0, 0x6e, 0xdd, 0xfd, 0xdd, 0xb0, + 0x2, 0xbe, 0x8a, 0x76, 0x0, 0xf0, 0x4, 0xb0, + 0x9, 0x5e, 0x28, 0x7e, 0xcc, 0xfc, 0xcd, 0xb0, + 0x3d, 0xe, 0x10, 0x66, 0x0, 0xf0, 0x4, 0xb0, + 0x44, 0xe, 0x10, 0x6e, 0xcd, 0xfd, 0xcd, 0xb0, + 0x0, 0xe, 0x10, 0x0, 0x61, 0x0, 0x60, 0x0, + 0x0, 0xe, 0x10, 0x3c, 0xb1, 0x1, 0x9d, 0x50, + 0x0, 0xe, 0x13, 0xd5, 0x0, 0x0, 0x3, 0xd3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6A39 "樹" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3b, 0x0, 0x3, 0xb0, 0x0, 0xa, 0x50, + 0x0, 0x3b, 0xb, 0xee, 0xfe, 0xc0, 0xa, 0x50, + 0x1, 0x4c, 0x10, 0x3, 0xb0, 0x0, 0xa, 0x50, + 0x2e, 0xef, 0xe7, 0x8a, 0xd8, 0x6e, 0xef, 0xe4, + 0x0, 0x7c, 0x2, 0x55, 0x55, 0x20, 0xa, 0x50, + 0x0, 0xbf, 0x13, 0xcc, 0xcc, 0x55, 0xa, 0x50, + 0x0, 0xee, 0x94, 0xb0, 0x7, 0x6d, 0x1a, 0x50, + 0x4, 0xbb, 0xb6, 0xb0, 0x6, 0x69, 0x5a, 0x50, + 0xa, 0x6b, 0x35, 0xfc, 0xce, 0x65, 0x9a, 0x50, + 0x2c, 0x3b, 0x0, 0x70, 0x7, 0x12, 0x8a, 0x50, + 0x34, 0x3b, 0x0, 0xa5, 0xd, 0x0, 0xa, 0x50, + 0x0, 0x3b, 0x0, 0x69, 0x49, 0x10, 0xa, 0x50, + 0x0, 0x3b, 0x5, 0x8a, 0xde, 0xc1, 0xb, 0x50, + 0x0, 0x3b, 0x9, 0x64, 0x10, 0x6, 0xfd, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6A4B "橋" */ + 0x0, 0x0, 0x0, 0x0, 0x12, 0x35, 0x79, 0x0, + 0x0, 0xd, 0x10, 0x6b, 0xbd, 0xd9, 0x73, 0x0, + 0x0, 0xd, 0x10, 0x0, 0xc, 0x50, 0x0, 0x0, + 0x1, 0x1e, 0x21, 0xdd, 0xdf, 0xed, 0xdd, 0xd3, + 0x1f, 0xff, 0xfe, 0x0, 0xd6, 0x1, 0xe2, 0x0, + 0x1, 0x3f, 0x31, 0xb, 0xfb, 0xbb, 0xee, 0x20, + 0x0, 0x6f, 0x31, 0xd9, 0xe0, 0x0, 0xa9, 0xe4, + 0x0, 0xbf, 0xc0, 0x40, 0xe8, 0x88, 0xd3, 0x20, + 0x0, 0xce, 0x88, 0x0, 0x33, 0x33, 0x30, 0x0, + 0x6, 0x7d, 0x2a, 0xbe, 0xdd, 0xdd, 0xde, 0xe0, + 0xd, 0x1d, 0x10, 0xb4, 0x1, 0x11, 0x10, 0xe0, + 0x49, 0xd, 0x10, 0xb4, 0x7c, 0xaa, 0xd0, 0xe0, + 0x0, 0xd, 0x10, 0xb4, 0x76, 0x0, 0xd0, 0xe0, + 0x0, 0xd, 0x10, 0xb4, 0x7d, 0xbb, 0x90, 0xe0, + 0x0, 0xd, 0x10, 0xb4, 0x43, 0x0, 0x9e, 0xb0, + + /* U+6A5F "機" */ + 0x0, 0x49, 0x0, 0x15, 0x9, 0x30, 0x52, 0x0, + 0x0, 0x49, 0x0, 0x83, 0xa, 0x40, 0xb0, 0x0, + 0x1, 0x59, 0x11, 0x91, 0x99, 0x58, 0x59, 0x50, + 0x1e, 0xff, 0xdb, 0xce, 0x48, 0x7d, 0xcc, 0x0, + 0x0, 0x99, 0x2, 0x6a, 0x47, 0x70, 0xb5, 0x50, + 0x0, 0xed, 0x2, 0xb3, 0xd5, 0x99, 0xa8, 0xc0, + 0x2, 0xee, 0x79, 0xb9, 0xb7, 0xb7, 0xc4, 0x80, + 0x7, 0xa9, 0xb0, 0xb3, 0x1, 0xd0, 0x6b, 0x0, + 0xc, 0x59, 0xb, 0xfe, 0xee, 0xfe, 0xee, 0xe0, + 0x49, 0x49, 0x0, 0xe5, 0x0, 0xb4, 0x1b, 0x0, + 0x12, 0x49, 0x1, 0xeb, 0x90, 0x6a, 0xb8, 0x0, + 0x0, 0x49, 0x7, 0x80, 0x85, 0x2f, 0x90, 0x21, + 0x0, 0x49, 0x3d, 0x10, 0x18, 0xd9, 0xc1, 0x85, + 0x0, 0x49, 0x93, 0x0, 0xa7, 0x0, 0x6d, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6B21 "次" */ + 0x0, 0x0, 0x0, 0x7, 0x20, 0x0, 0x0, 0x0, + 0x4, 0x10, 0x0, 0xf, 0x30, 0x0, 0x0, 0x0, + 0x9, 0xe5, 0x0, 0x4e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4e, 0x60, 0x9f, 0xdd, 0xdd, 0xde, 0x90, + 0x0, 0x1, 0x10, 0xe6, 0x33, 0x33, 0x3b, 0x80, + 0x0, 0x0, 0x6, 0xd0, 0xd, 0x40, 0xe, 0x20, + 0x0, 0x0, 0x1e, 0x50, 0xd, 0x40, 0x5c, 0x0, + 0x0, 0x0, 0x5, 0x0, 0xe, 0x50, 0x54, 0x0, + 0x0, 0x6, 0xa0, 0x0, 0x2f, 0xa0, 0x0, 0x0, + 0x0, 0x1f, 0x30, 0x0, 0x7d, 0xe0, 0x0, 0x0, + 0x0, 0xb9, 0x0, 0x0, 0xd6, 0x98, 0x0, 0x0, + 0x7, 0xe1, 0x0, 0x8, 0xc0, 0x2e, 0x20, 0x0, + 0x1f, 0x40, 0x0, 0x8e, 0x20, 0x7, 0xe2, 0x0, + 0x2, 0x0, 0x2b, 0xd2, 0x0, 0x0, 0x8f, 0x70, + 0x0, 0x0, 0xc8, 0x0, 0x0, 0x0, 0x4, 0xb1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6B32 "欲" */ + 0x0, 0x1, 0x1, 0x0, 0x5, 0x40, 0x0, 0x0, + 0x0, 0x6c, 0xb, 0x70, 0xb, 0x60, 0x0, 0x0, + 0x1, 0xe3, 0x1, 0xd6, 0xf, 0x20, 0x0, 0x0, + 0xc, 0x80, 0x40, 0x2d, 0x3f, 0xed, 0xdd, 0xd3, + 0x18, 0x4, 0xf1, 0x0, 0x8a, 0x29, 0x22, 0xe1, + 0x0, 0xc, 0xbc, 0x0, 0xe3, 0xf, 0x1, 0xe0, + 0x0, 0x4e, 0x9, 0xa7, 0xb0, 0x1f, 0x4, 0xa0, + 0x1, 0xe5, 0x0, 0xc7, 0x20, 0x2f, 0x3, 0x40, + 0xc, 0xa0, 0x0, 0x3e, 0x10, 0x5f, 0x20, 0x0, + 0x4a, 0xff, 0xee, 0xf3, 0x0, 0x9f, 0x60, 0x0, + 0x0, 0xf0, 0x0, 0xe1, 0x0, 0xda, 0xc0, 0x0, + 0x0, 0xf0, 0x0, 0xe1, 0x4, 0xe0, 0xe2, 0x0, + 0x0, 0xf0, 0x0, 0xe1, 0xc, 0x70, 0x8b, 0x0, + 0x0, 0xfe, 0xee, 0xf1, 0xad, 0x0, 0xc, 0x80, + 0x0, 0xf1, 0x0, 0x4, 0xd2, 0x0, 0x1, 0xd1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6B4C "歌" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb1, 0x0, 0x0, + 0x2f, 0xff, 0xff, 0xff, 0xb2, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x78, 0x5, 0xc0, 0x0, 0x0, + 0x3, 0xcc, 0xc5, 0x78, 0x8, 0xfe, 0xee, 0xe2, + 0x4, 0x80, 0x66, 0x78, 0xd, 0x30, 0x0, 0xf0, + 0x4, 0x80, 0x66, 0x78, 0x3e, 0x9, 0x22, 0xd0, + 0x3, 0xcc, 0xc5, 0x78, 0xb7, 0xc, 0x36, 0x90, + 0x0, 0x0, 0x0, 0x78, 0x40, 0xd, 0x34, 0x30, + 0x4e, 0xee, 0xee, 0xff, 0xe1, 0xf, 0x60, 0x0, + 0x0, 0x0, 0x0, 0x59, 0x0, 0x2f, 0xa0, 0x0, + 0x7, 0xec, 0xe7, 0x59, 0x0, 0x6d, 0xe0, 0x0, + 0x7, 0x70, 0x67, 0x59, 0x0, 0xe4, 0xa6, 0x0, + 0x7, 0xec, 0xe7, 0x59, 0x7, 0xd0, 0x3e, 0x10, + 0x7, 0x70, 0x0, 0x59, 0x5f, 0x30, 0x8, 0xc1, + 0x0, 0x0, 0x1c, 0xd7, 0xd5, 0x0, 0x0, 0x96, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6B50 "歐" */ + 0x0, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0xd, + 0xfe, 0xee, 0xee, 0x66, 0xc0, 0x0, 0x0, 0xd1, + 0x0, 0x0, 0x0, 0x9a, 0x0, 0x0, 0xd, 0x19, + 0xbb, 0xb3, 0xc, 0xfe, 0xee, 0xd0, 0xd1, 0xd0, + 0x4, 0x41, 0xf2, 0x0, 0x5b, 0xd, 0x1d, 0x0, + 0x44, 0x7c, 0x6, 0x8, 0x60, 0xd1, 0xdb, 0xbd, + 0x4d, 0x50, 0xf0, 0xb1, 0xd, 0x10, 0x0, 0x0, + 0x10, 0x1f, 0x0, 0x0, 0xd5, 0xbc, 0x2b, 0xb0, + 0x2, 0xf3, 0x0, 0xd, 0x73, 0xa2, 0x8a, 0x0, + 0x5f, 0x80, 0x0, 0xd7, 0x3a, 0x28, 0xa0, 0x9, + 0xbd, 0x0, 0xd, 0x7a, 0xd2, 0xdd, 0x0, 0xe1, + 0xd3, 0x0, 0xd1, 0x11, 0x1, 0x10, 0x6c, 0x5, + 0xc0, 0xd, 0xcc, 0xcc, 0xcc, 0xaf, 0x30, 0xa, + 0x90, 0x22, 0x22, 0x22, 0x3c, 0x50, 0x0, 0xa, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6B61 "歡" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3a, 0x0, 0xd1, 0x0, 0xc1, 0x0, 0x0, + 0x2d, 0xdf, 0xdd, 0xfd, 0xd1, 0xe0, 0x0, 0x0, + 0x0, 0x38, 0x0, 0xb1, 0x3, 0xd6, 0x66, 0x60, + 0xa, 0xbc, 0x6a, 0xbc, 0x67, 0xa6, 0x66, 0xf0, + 0xa, 0x15, 0x6a, 0x15, 0x7d, 0x18, 0x12, 0xb0, + 0x7, 0xbb, 0x47, 0xaa, 0x9b, 0xc, 0x17, 0x60, + 0x0, 0x86, 0x1c, 0x0, 0x1, 0xd, 0x14, 0x10, + 0x1, 0xfc, 0xcf, 0xdc, 0x70, 0xe, 0x30, 0x0, + 0xc, 0xe0, 0xd, 0x10, 0x0, 0x1f, 0x70, 0x0, + 0x39, 0xfc, 0xcf, 0xcc, 0x30, 0x4d, 0xc0, 0x0, + 0x0, 0xe5, 0x5e, 0x55, 0x20, 0xa5, 0xc2, 0x0, + 0x0, 0xe5, 0x5e, 0x55, 0x22, 0xe0, 0x5b, 0x0, + 0x0, 0xfa, 0xaf, 0xaa, 0x6c, 0x70, 0xb, 0x70, + 0x0, 0xe2, 0x22, 0x22, 0x5b, 0x0, 0x0, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6B62 "止" */ + 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x20, 0x0, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x20, 0x0, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x20, 0x0, 0xff, 0xff, 0xff, 0x70, + 0x0, 0xf, 0x20, 0x0, 0xf3, 0x11, 0x11, 0x0, + 0x0, 0xf, 0x20, 0x0, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x20, 0x0, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x20, 0x0, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x20, 0x0, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x20, 0x0, 0xf2, 0x0, 0x0, 0x0, + 0x2d, 0xdf, 0xdd, 0xdd, 0xfd, 0xdd, 0xdd, 0xd2, + 0x3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x30, + + /* U+6B63 "正" */ + 0x0, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0, + 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, + 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x2, 0xff, 0xff, 0xff, 0x0, + 0x0, 0xe, 0x20, 0x2, 0xf1, 0x11, 0x11, 0x0, + 0x0, 0xe, 0x20, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x1b, 0xbf, 0xcb, 0xbc, 0xfb, 0xbb, 0xbb, 0xb2, + 0x4, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x40, + + /* U+6B64 "此" */ + 0x0, 0x0, 0xf, 0x10, 0xe, 0x30, 0x0, 0x0, + 0x0, 0x0, 0xf, 0x10, 0xe, 0x30, 0x0, 0x0, + 0x0, 0x0, 0xf, 0x10, 0xe, 0x30, 0x0, 0x0, + 0x0, 0xd1, 0xf, 0x10, 0xe, 0x30, 0x5, 0x20, + 0x0, 0xe1, 0xf, 0x53, 0x1e, 0x31, 0xae, 0x40, + 0x0, 0xe1, 0xf, 0xdc, 0x6e, 0x9e, 0x91, 0x0, + 0x0, 0xe1, 0xf, 0x10, 0xe, 0xb2, 0x0, 0x0, + 0x0, 0xe1, 0xf, 0x10, 0xe, 0x30, 0x0, 0x0, + 0x0, 0xe1, 0xf, 0x10, 0xe, 0x30, 0x0, 0x0, + 0x0, 0xe1, 0xf, 0x10, 0xe, 0x30, 0x0, 0x0, + 0x0, 0xe1, 0xf, 0x10, 0xe, 0x30, 0x0, 0xa2, + 0x0, 0xe1, 0xf, 0x11, 0x1e, 0x30, 0x0, 0xd3, + 0x0, 0xf7, 0x9f, 0xff, 0x7d, 0x72, 0x23, 0xf0, + 0x2f, 0xeb, 0x85, 0x20, 0x6, 0xde, 0xee, 0x70, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6B65 "步" */ + 0x0, 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x87, 0x0, 0x6f, 0xdd, 0xdd, 0x50, 0x0, + 0x9, 0x70, 0x6, 0xb2, 0x22, 0x21, 0x0, 0x0, + 0x97, 0x0, 0x6b, 0x0, 0x0, 0x0, 0x4, 0x4b, + 0xa4, 0x49, 0xc4, 0x44, 0x44, 0x40, 0xcc, 0xcc, + 0xcc, 0xee, 0xcc, 0xcc, 0xcb, 0x0, 0x0, 0x33, + 0x7, 0x90, 0x0, 0x20, 0x0, 0x0, 0x1e, 0x40, + 0x79, 0x0, 0x1e, 0x50, 0x0, 0xc, 0x80, 0x7, + 0x90, 0xa, 0xa0, 0x0, 0x1c, 0xa0, 0x0, 0x79, + 0x9, 0xe1, 0x0, 0x2, 0x90, 0x0, 0x7, 0xbc, + 0xc1, 0x0, 0x0, 0x0, 0x0, 0x2, 0x8f, 0x90, + 0x0, 0x0, 0x0, 0x3, 0x6b, 0xf9, 0x20, 0x0, + 0x0, 0x0, 0xcf, 0xea, 0x61, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+6B69 "歩" */ + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x50, 0x8, 0xa3, 0x33, 0x32, 0x0, + 0x0, 0xa, 0x50, 0x8, 0xdb, 0xbb, 0xb6, 0x0, + 0x0, 0xa, 0x50, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x1, 0x1b, 0x61, 0x19, 0x91, 0x11, 0x11, 0x10, + 0x1e, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe1, + 0x0, 0x0, 0x61, 0x8, 0x80, 0x4, 0x10, 0x0, + 0x0, 0x8, 0xc0, 0x8, 0x80, 0x8, 0xd1, 0x0, + 0x0, 0x7e, 0x20, 0x8, 0x80, 0x2, 0x7e, 0x10, + 0x8, 0xe2, 0x0, 0x9, 0x80, 0x2f, 0x39, 0xc0, + 0x2, 0x10, 0xa, 0xed, 0x30, 0xc9, 0x0, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x2d, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4a, 0xf8, 0x0, 0x0, 0x0, + 0x0, 0x5a, 0xdf, 0xd7, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x36, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6B6F "歯" */ + 0x0, 0x9, 0x50, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x50, 0x8, 0xfe, 0xee, 0xea, 0x0, + 0x0, 0x9, 0x50, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x2e, 0xef, 0xfe, 0xef, 0xfe, 0xee, 0xee, 0xe2, + 0x1, 0x50, 0x0, 0x4, 0x30, 0x0, 0x5, 0x20, + 0x1, 0xe0, 0x76, 0x8, 0x60, 0x76, 0xd, 0x30, + 0x1, 0xe0, 0x1d, 0x8, 0x60, 0xd1, 0xd, 0x30, + 0x1, 0xe0, 0x27, 0x39, 0x84, 0x72, 0x1d, 0x30, + 0x1, 0xe4, 0xaa, 0xbf, 0xdb, 0xaa, 0x6d, 0x30, + 0x1, 0xe0, 0x0, 0xbc, 0x8c, 0x30, 0xd, 0x30, + 0x1, 0xe0, 0x3c, 0x58, 0x62, 0xc5, 0xd, 0x30, + 0x1, 0xe3, 0xc3, 0x8, 0x60, 0x16, 0xd, 0x30, + 0x1, 0xe3, 0x33, 0x36, 0x63, 0x33, 0x3d, 0x30, + 0x1, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0x30, + + /* U+6B72 "歲" */ + 0x0, 0x6, 0x90, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0x90, 0x6, 0xfd, 0xdd, 0xd7, 0x0, + 0x0, 0x6, 0x90, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0xe, 0xef, 0xfe, 0xef, 0xfe, 0xee, 0xee, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x9, 0x56, 0xb3, 0x0, + 0x0, 0x88, 0x88, 0x88, 0x8c, 0xb8, 0xab, 0x70, + 0x1, 0xf5, 0x55, 0x55, 0x59, 0xb5, 0x55, 0x40, + 0x1, 0xe3, 0xaa, 0xaa, 0x94, 0xb0, 0x58, 0x0, + 0x2, 0xd0, 0x34, 0xc2, 0x11, 0xe0, 0xd4, 0x0, + 0x3, 0xc0, 0xd2, 0xb1, 0xc0, 0xd8, 0xc0, 0x0, + 0x4, 0xb7, 0x82, 0xb9, 0x60, 0x8f, 0x20, 0x0, + 0x7, 0x85, 0x1, 0xca, 0x2, 0xde, 0x10, 0xa1, + 0xd, 0x40, 0x2b, 0x90, 0x4d, 0x47, 0xb1, 0xd0, + 0x2c, 0x6, 0xa3, 0x2, 0xd2, 0x0, 0x9f, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6B73 "歳" */ + 0x0, 0x5, 0xa0, 0x5, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xa0, 0x5, 0xfc, 0xcc, 0xc5, 0x0, + 0x0, 0x5, 0xa0, 0x5, 0xb0, 0x0, 0x0, 0x0, + 0xe, 0xee, 0xee, 0xee, 0xef, 0xff, 0xee, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0xa, 0x55, 0xb3, 0x0, + 0x0, 0xcc, 0xcc, 0xcc, 0xce, 0xdc, 0xdf, 0xc0, + 0x1, 0xe1, 0x11, 0x11, 0x16, 0xa1, 0x13, 0x10, + 0x1, 0xe3, 0xaa, 0xaa, 0xa2, 0xc0, 0x2e, 0x0, + 0x2, 0xd1, 0x34, 0xd3, 0x30, 0xe1, 0x98, 0x0, + 0x3, 0xc0, 0xc2, 0xc4, 0x70, 0x98, 0xf1, 0x0, + 0x4, 0xa4, 0xa1, 0xc0, 0xd0, 0x4f, 0x70, 0x0, + 0x8, 0x7c, 0x21, 0xc0, 0x73, 0x9f, 0x50, 0x74, + 0xe, 0x23, 0x1, 0xc0, 0x1b, 0xa3, 0xe2, 0xa3, + 0x39, 0x0, 0x4e, 0x90, 0xa6, 0x0, 0x4e, 0xc0, + + /* U+6B77 "歷" */ + 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, + 0x0, 0xf0, 0x0, 0x15, 0x0, 0x0, 0x36, 0x0, + 0x0, 0xf3, 0xbd, 0xd6, 0x16, 0xcf, 0x84, 0x0, + 0x0, 0xf0, 0x4, 0xa0, 0x0, 0xe, 0x0, 0x0, + 0x0, 0xf6, 0xcd, 0xec, 0x99, 0xcf, 0xcc, 0xc1, + 0x0, 0xf0, 0x1e, 0xe4, 0x0, 0xaf, 0xd3, 0x0, + 0x0, 0xf0, 0xb8, 0xbc, 0x57, 0x7e, 0x3e, 0x30, + 0x0, 0xfa, 0x84, 0x91, 0x6c, 0xd, 0x4, 0xe4, + 0x2, 0xd2, 0x0, 0x0, 0x28, 0x0, 0x0, 0x10, + 0x3, 0xc0, 0x5, 0x0, 0x3d, 0x0, 0x0, 0x0, + 0x6, 0x90, 0xf, 0x0, 0x3f, 0xee, 0xeb, 0x0, + 0x9, 0x60, 0xf, 0x0, 0x3d, 0x0, 0x0, 0x0, + 0xe, 0x20, 0xf, 0x0, 0x3d, 0x0, 0x0, 0x0, + 0x4c, 0x1e, 0xef, 0xee, 0xff, 0xee, 0xee, 0xe5, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6B7B "死" */ + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x2, 0xf2, 0x0, 0xb, 0x60, 0x0, 0x0, + 0x0, 0x7, 0xc0, 0x0, 0xa, 0x60, 0x0, 0x0, + 0x0, 0xd, 0x60, 0x0, 0xa, 0x60, 0x1, 0x0, + 0x0, 0x3f, 0xdc, 0xcc, 0x2a, 0x60, 0x1d, 0x60, + 0x0, 0xc8, 0x33, 0x3f, 0xa, 0x63, 0xe8, 0x0, + 0x7, 0xd0, 0x0, 0x4b, 0xa, 0xce, 0x50, 0x0, + 0x2e, 0x3d, 0x20, 0xa6, 0xa, 0xb1, 0x0, 0x0, + 0x1, 0x7, 0xe4, 0xe1, 0xa, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x7f, 0x70, 0xa, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x7d, 0x0, 0xa, 0x60, 0x0, 0x51, + 0x0, 0x7, 0xe2, 0x0, 0xa, 0x60, 0x0, 0xb4, + 0x2, 0xbe, 0x20, 0x0, 0xa, 0x91, 0x1, 0xe2, + 0x1f, 0x90, 0x0, 0x0, 0x4, 0xde, 0xee, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6B8A "殊" */ + 0x1f, 0xff, 0xff, 0xf1, 0xc0, 0xc3, 0x0, 0x0, + 0x0, 0x3c, 0x0, 0x3, 0xc0, 0xc3, 0x0, 0x0, + 0x0, 0x79, 0x0, 0x7, 0xc6, 0xe8, 0x66, 0x20, + 0x0, 0xc8, 0x22, 0xc, 0xdc, 0xfd, 0xcc, 0x50, + 0x0, 0xfd, 0xce, 0xbd, 0x0, 0xc3, 0x0, 0x0, + 0x6, 0xc0, 0xb, 0xa4, 0x0, 0xc3, 0x0, 0x0, + 0xd, 0x71, 0xf, 0x6b, 0xbb, 0xfc, 0xbb, 0xb0, + 0x5b, 0x7e, 0x8d, 0x14, 0x4b, 0xff, 0x54, 0x40, + 0x1, 0x4, 0xe8, 0x0, 0x3d, 0xda, 0x90, 0x0, + 0x0, 0x1, 0xe1, 0x0, 0xd3, 0xc3, 0xc3, 0x0, + 0x0, 0xa, 0xa0, 0xc, 0x80, 0xc3, 0x3e, 0x20, + 0x0, 0x5e, 0x12, 0xd7, 0x0, 0xc3, 0x6, 0xe2, + 0x6, 0xf4, 0x1, 0x50, 0x0, 0xc3, 0x0, 0x40, + 0xa, 0x30, 0x0, 0x0, 0x0, 0xc3, 0x0, 0x0, + + /* U+6B8B "残" */ + 0x2f, 0xff, 0xff, 0xf0, 0x6, 0xa2, 0xc7, 0x10, + 0x0, 0x3d, 0x0, 0x0, 0x5, 0xb0, 0x8, 0x20, + 0x0, 0x7a, 0x0, 0x0, 0x5, 0xb2, 0x58, 0x90, + 0x0, 0xa9, 0x22, 0x17, 0xad, 0xff, 0xda, 0x70, + 0x0, 0xed, 0xcf, 0x59, 0x77, 0xd0, 0x0, 0x0, + 0x4, 0xd0, 0xd, 0x10, 0x1, 0xe0, 0x3, 0x51, + 0xa, 0x70, 0x1e, 0x2, 0x47, 0xfd, 0xec, 0x92, + 0x3e, 0x77, 0x5b, 0x5c, 0xa7, 0xe4, 0x0, 0x41, + 0x4, 0x1a, 0xf5, 0x0, 0x0, 0xa6, 0x5, 0xd0, + 0x0, 0x2, 0xe0, 0x0, 0x0, 0x6a, 0x6d, 0x10, + 0x0, 0xb, 0x80, 0x0, 0x0, 0x3f, 0xc1, 0x0, + 0x0, 0x6d, 0x0, 0x0, 0x18, 0xee, 0x60, 0x23, + 0x7, 0xe3, 0x0, 0x5b, 0xf9, 0x14, 0xe4, 0x77, + 0x1c, 0x20, 0x0, 0x86, 0x0, 0x0, 0x6e, 0xe1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6BB5 "段" */ + 0x0, 0x0, 0x5, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5a, 0xec, 0x60, 0x1f, 0xee, 0xf0, 0x0, + 0x0, 0xf5, 0x10, 0x0, 0x1d, 0x0, 0xf0, 0x0, + 0x0, 0xf0, 0x0, 0x0, 0x3d, 0x0, 0xf0, 0x0, + 0x0, 0xf6, 0x66, 0x50, 0x6b, 0x0, 0xf0, 0x0, + 0x0, 0xf9, 0x99, 0x70, 0xb6, 0x0, 0xf0, 0x0, + 0x0, 0xf0, 0x0, 0x8, 0xc0, 0x0, 0x9d, 0xd2, + 0x0, 0xf0, 0x0, 0x5, 0x10, 0x0, 0x0, 0x0, + 0x0, 0xfe, 0xee, 0xb5, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0xf0, 0x0, 0x0, 0x86, 0x0, 0x69, 0x0, + 0x0, 0xf0, 0x1, 0x30, 0x1d, 0x0, 0xd3, 0x0, + 0x28, 0xfc, 0xed, 0xb0, 0x7, 0xb9, 0x80, 0x0, + 0x28, 0xf2, 0x0, 0x0, 0x0, 0xdf, 0x10, 0x0, + 0x0, 0xf0, 0x0, 0x0, 0x5d, 0x98, 0xe6, 0x0, + 0x0, 0xf0, 0x0, 0x4e, 0xb4, 0x0, 0x3b, 0xe1, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + + /* U+6BCD "母" */ + 0x0, 0x6, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, + 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, 0x97, 0x0, + 0x0, 0xa, 0x70, 0x5e, 0x60, 0x0, 0xa7, 0x0, + 0x0, 0xc, 0x40, 0x2, 0xca, 0x0, 0xa6, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x6, 0x0, 0xb5, 0x0, + 0xc, 0xcf, 0xdc, 0xcc, 0xcc, 0xcc, 0xfd, 0xc0, + 0x3, 0x6e, 0x33, 0x33, 0x33, 0x33, 0xe6, 0x30, + 0x0, 0x5c, 0x1, 0xd4, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x89, 0x0, 0x3d, 0x90, 0x0, 0xf1, 0x0, + 0x0, 0xa7, 0x0, 0x0, 0xb9, 0x1, 0xf0, 0x0, + 0x0, 0xd6, 0x22, 0x22, 0x34, 0x24, 0xf2, 0x10, + 0x0, 0xcd, 0xdd, 0xdd, 0xdd, 0xde, 0xfd, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xbf, 0xfc, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6BCE "毎" */ + 0x0, 0x0, 0x36, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xff, 0xee, 0xee, 0xee, 0xee, 0xb0, + 0x0, 0x1d, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xb0, 0xfe, 0xee, 0xfe, 0xee, 0xf7, 0x0, + 0x0, 0x3, 0xe0, 0x0, 0xf0, 0x0, 0xa6, 0x0, + 0x0, 0x5, 0xb0, 0x1, 0xe0, 0x0, 0xb5, 0x0, + 0x1e, 0xef, 0xfe, 0xee, 0xfe, 0xee, 0xfe, 0xe7, + 0x1, 0x1b, 0x61, 0x16, 0xa1, 0x11, 0xe3, 0x10, + 0x0, 0xd, 0x30, 0x7, 0x80, 0x0, 0xf1, 0x0, + 0x0, 0xf, 0x0, 0x9, 0x60, 0x1, 0xf0, 0x0, + 0x0, 0x3f, 0xee, 0xef, 0xfe, 0xee, 0xfe, 0xe1, + 0x0, 0x59, 0x0, 0x0, 0x0, 0x8, 0xa0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x5d, 0xdd, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6BCF "每" */ + 0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0xfe, 0xee, 0xee, 0xee, 0xee, 0xe0, + 0x0, 0x2e, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xb4, 0xfe, 0xee, 0xee, 0xee, 0xf6, 0x0, + 0x6, 0x15, 0xb0, 0x3b, 0x20, 0x0, 0xa5, 0x0, + 0x0, 0x7, 0x90, 0x4, 0xd7, 0x0, 0xb5, 0x0, + 0x4, 0x4b, 0x93, 0x33, 0x5a, 0x43, 0xd7, 0x42, + 0xb, 0xbf, 0xba, 0xca, 0xaa, 0xaa, 0xfc, 0xb6, + 0x0, 0xe, 0x10, 0x7c, 0x40, 0x0, 0xd2, 0x0, + 0x0, 0x1f, 0x0, 0x1, 0xb7, 0x0, 0xf1, 0x0, + 0x0, 0x4f, 0xee, 0xee, 0xef, 0xee, 0xfe, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb, 0xde, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6BD4 "比" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0xe, + 0x30, 0x0, 0x3, 0xd0, 0x0, 0x0, 0xe, 0x30, + 0x0, 0x3, 0xd0, 0x0, 0x0, 0xe, 0x30, 0x0, + 0x3, 0xd0, 0x0, 0x0, 0xe, 0x30, 0x0, 0x3, + 0xd0, 0x1, 0xc6, 0xe, 0x63, 0x33, 0x3, 0xd0, + 0x3d, 0xb1, 0xe, 0xed, 0xdd, 0x33, 0xe7, 0xe7, + 0x0, 0xe, 0x30, 0x0, 0x3, 0xfb, 0x20, 0x0, + 0xe, 0x30, 0x0, 0x3, 0xe0, 0x0, 0x0, 0xe, + 0x30, 0x0, 0x3, 0xd0, 0x0, 0x0, 0xe, 0x30, + 0x0, 0x3, 0xd0, 0x0, 0x7, 0xe, 0x30, 0x0, + 0x3, 0xd0, 0x0, 0x1f, 0xe, 0x30, 0x27, 0x23, + 0xe0, 0x0, 0x3d, 0xf, 0xad, 0xea, 0x12, 0xf1, + 0x0, 0x7a, 0x5f, 0xa4, 0x0, 0x0, 0xbf, 0xff, + 0xe3, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6BDB "毛" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x15, 0x9e, 0xd1, 0x0, 0x0, + 0x25, 0x8b, 0xdf, 0xb7, 0x20, 0x0, 0x6, 0xfd, + 0xa8, 0x9c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xc0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x5d, 0x58, 0xac, 0xef, 0x0, 0x28, 0xad, 0xff, + 0xfa, 0x86, 0x31, 0x0, 0x1, 0x85, 0x31, 0x5c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xc0, + 0x0, 0x13, 0x57, 0x0, 0x1, 0x35, 0x9e, 0xbd, + 0xfe, 0xca, 0x81, 0x9e, 0xfd, 0xbb, 0xd5, 0x30, + 0x0, 0x0, 0x2, 0x10, 0x0, 0x4c, 0x0, 0x0, + 0x0, 0x20, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0x9, 0x80, 0x0, 0x0, 0x3e, 0x10, 0x0, 0x1, + 0xd5, 0x0, 0x0, 0x0, 0xbf, 0xff, 0xff, 0xfb, + 0x0, + + /* U+6C0F "氏" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x25, 0x7a, 0xe9, 0x0, 0x1a, 0xcd, + 0xff, 0xee, 0x86, 0x30, 0x0, 0x2f, 0x42, 0x0, + 0x5c, 0x0, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x3d, + 0x0, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x0, 0x2e, 0x11, 0x11, 0x3f, 0x11, 0x11, + 0x10, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x2e, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0x2e, + 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x5, 0xc0, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0xe2, 0x0, 0x20, 0x2e, 0x3, 0x7b, 0x90, + 0x8b, 0x0, 0x95, 0x6f, 0xed, 0x94, 0x0, 0xd, + 0x92, 0xd3, 0x57, 0x20, 0x0, 0x0, 0x1, 0xbf, + 0xb0, + + /* U+6C11 "民" */ + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x1f, + 0x0, 0x0, 0x0, 0x0, 0xe, 0x20, 0x1f, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x20, 0x1f, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x20, 0x1f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x20, 0x1f, 0x0, 0x0, 0xb6, 0x0, + 0x0, 0x0, 0x1f, 0x0, 0x0, 0x88, 0x0, 0x0, + 0x0, 0x1f, 0x33, 0x33, 0x8b, 0x33, 0x33, 0x31, + 0x1f, 0xcc, 0xcc, 0xcf, 0xcc, 0xcc, 0xc5, 0x1f, + 0x0, 0x0, 0xd, 0x40, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0x6, 0xc0, 0x0, 0x10, 0x1f, 0x0, 0x4, + 0x30, 0xc7, 0x0, 0x59, 0x4f, 0x8c, 0xea, 0x30, + 0x2e, 0x92, 0xa7, 0xae, 0x94, 0x0, 0x0, 0x1, + 0x9e, 0xd1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+6C14 "气" */ + 0x0, 0x0, 0x81, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xec, 0xcc, 0xcc, 0xcc, 0xcc, 0xa0, + 0x0, 0x3e, 0x22, 0x22, 0x22, 0x22, 0x22, 0x10, + 0x0, 0xc6, 0x22, 0x22, 0x22, 0x22, 0x21, 0x0, + 0x7, 0xc0, 0xbb, 0xbb, 0xbb, 0xbb, 0xb7, 0x0, + 0x3e, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x7e, 0xee, 0xee, 0xee, 0xef, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xf1, 0x63, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb8, 0x94, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0xd0, + + /* U+6C17 "気" */ + 0x0, 0x0, 0x81, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xfe, 0xee, 0xee, 0xee, 0xee, 0x80, + 0x0, 0x3e, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc6, 0x22, 0x22, 0x22, 0x22, 0x20, 0x0, + 0x8, 0xc0, 0xbb, 0xbb, 0xbb, 0xbb, 0xb3, 0x0, + 0x1c, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcf, 0xff, 0xff, 0xff, 0xff, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x92, 0x7, 0x90, 0x0, + 0x0, 0x1d, 0x70, 0x8, 0xb0, 0x6, 0xa0, 0x0, + 0x0, 0x1, 0xad, 0x8e, 0x10, 0x6, 0xb0, 0x0, + 0x0, 0x0, 0x9, 0xfb, 0x0, 0x4, 0xc0, 0x0, + 0x0, 0x1, 0xac, 0x2a, 0xd2, 0x1, 0xf0, 0xa0, + 0x0, 0x7e, 0x90, 0x0, 0x7e, 0x10, 0xc6, 0xc0, + 0x9, 0xb2, 0x0, 0x0, 0x2, 0x0, 0x3e, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6C34 "水" */ + 0x0, 0x0, 0x0, 0x5, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5, 0xc0, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x12, 0x5, 0xd0, 0x0, 0x3e, 0x10, + 0x9, 0xff, 0xff, 0x95, 0xf4, 0x2, 0xe5, 0x0, + 0x0, 0x0, 0xc, 0x55, 0xfc, 0x2e, 0x60, 0x0, + 0x0, 0x0, 0x1f, 0x5, 0xda, 0xe5, 0x0, 0x0, + 0x0, 0x0, 0x8a, 0x5, 0xc1, 0xd3, 0x0, 0x0, + 0x0, 0x2, 0xf2, 0x5, 0xc0, 0x4e, 0x20, 0x0, + 0x0, 0xc, 0x90, 0x5, 0xc0, 0x8, 0xd2, 0x0, + 0x0, 0xac, 0x0, 0x5, 0xc0, 0x0, 0x8e, 0x50, + 0xc, 0xc1, 0x0, 0x5, 0xc0, 0x0, 0x5, 0xe7, + 0x2, 0x0, 0x1, 0x27, 0xc0, 0x0, 0x0, 0x10, + 0x0, 0x0, 0x7, 0xfe, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6C37 "氷" */ + 0x0, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x4c, 0x30, 0x4, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xe8, 0x4, 0xd0, 0x0, 0x5, 0x80, + 0x0, 0x0, 0x1b, 0x44, 0xf3, 0x0, 0x4f, 0x50, + 0x0, 0x0, 0x0, 0x4, 0xfa, 0x5, 0xe4, 0x0, + 0xb, 0xee, 0xef, 0x74, 0xde, 0x7e, 0x30, 0x0, + 0x1, 0x11, 0x2d, 0x44, 0xc7, 0xe1, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x4, 0xc1, 0xe3, 0x0, 0x0, + 0x0, 0x0, 0xb7, 0x4, 0xc0, 0x6e, 0x10, 0x0, + 0x0, 0x6, 0xe0, 0x4, 0xc0, 0xb, 0xb0, 0x0, + 0x0, 0x5f, 0x30, 0x4, 0xc0, 0x0, 0xcb, 0x0, + 0x8, 0xf4, 0x0, 0x4, 0xc0, 0x0, 0x1b, 0xe4, + 0x7, 0x20, 0x2, 0x27, 0xc0, 0x0, 0x0, 0x62, + 0x0, 0x0, 0xe, 0xfe, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6C38 "永" */ + 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1c, 0xfa, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x16, 0xcf, 0x90, 0x0, 0x0, + 0x0, 0x1, 0x11, 0x11, 0x13, 0x80, 0x0, 0x0, + 0x0, 0xc, 0xff, 0xff, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xf0, 0x0, 0x6, 0xa0, + 0x0, 0x0, 0x0, 0x4, 0xf6, 0x0, 0x7e, 0x30, + 0xd, 0xff, 0xff, 0x44, 0xfd, 0x9, 0xd2, 0x0, + 0x0, 0x0, 0x2e, 0x4, 0xdc, 0xda, 0x0, 0x0, + 0x0, 0x0, 0x99, 0x4, 0xd3, 0xf1, 0x0, 0x0, + 0x0, 0x4, 0xe1, 0x4, 0xd0, 0x8d, 0x10, 0x0, + 0x0, 0x2e, 0x50, 0x4, 0xd0, 0xa, 0xc2, 0x0, + 0x4, 0xe7, 0x0, 0x4, 0xd0, 0x0, 0x9f, 0x81, + 0xc, 0x50, 0x0, 0x6, 0xd0, 0x0, 0x3, 0xc4, + 0x0, 0x0, 0xa, 0xfe, 0x70, 0x0, 0x0, 0x0, + + /* U+6C42 "求" */ + 0x0, 0x0, 0x0, 0x8, 0x80, 0x79, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x4, 0xc5, 0x0, + 0xd, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe0, + 0x2, 0x22, 0x22, 0x29, 0xb2, 0x22, 0x22, 0x20, + 0x0, 0x93, 0x0, 0x8, 0xf1, 0x0, 0x3d, 0x10, + 0x0, 0x4e, 0x30, 0x8, 0xf8, 0x1, 0xe6, 0x0, + 0x0, 0x5, 0xe1, 0x8, 0xae, 0x3d, 0x70, 0x0, + 0x0, 0x0, 0x72, 0xa, 0x88, 0xf5, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xcf, 0x80, 0xd6, 0x0, 0x0, + 0x0, 0x1, 0xae, 0x59, 0x80, 0x3f, 0x50, 0x0, + 0x1, 0x8f, 0x80, 0x8, 0x80, 0x4, 0xf7, 0x0, + 0xe, 0xb2, 0x0, 0x8, 0x80, 0x0, 0x3e, 0xd2, + 0x2, 0x0, 0x1, 0x1b, 0x80, 0x0, 0x0, 0x70, + 0x0, 0x0, 0x3f, 0xfd, 0x30, 0x0, 0x0, 0x0, + + /* U+6C5A "汚" */ + 0x3, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xae, 0x43, 0xff, 0xff, 0xff, 0xff, 0x90, + 0x0, 0x5, 0x80, 0x0, 0x8a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd3, 0x0, 0x0, 0x0, + 0x3f, 0x80, 0xd, 0xee, 0xff, 0xee, 0xee, 0xe3, + 0x2, 0xcd, 0x0, 0x5, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x40, 0xe, 0xff, 0xff, 0xff, 0x20, + 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, 0xf, 0x0, + 0x0, 0x5d, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x5b, 0x0, + 0x8, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xb8, 0x0, + 0x7, 0x20, 0x0, 0x0, 0xe, 0xff, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6C60 "池" */ + 0x5, 0xa4, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0x4c, 0x90, 0xd3, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd3, 0x1, 0xe0, 0x18, 0x20, + 0x0, 0x0, 0x0, 0xd3, 0x1, 0xfa, 0xee, 0x40, + 0x4b, 0x30, 0x0, 0xd5, 0x7d, 0xf7, 0x1b, 0x40, + 0x6, 0xe8, 0x5, 0xef, 0xa6, 0xe0, 0xc, 0x40, + 0x0, 0x13, 0xac, 0xe3, 0x1, 0xe0, 0xc, 0x40, + 0x0, 0x0, 0x0, 0xd3, 0x1, 0xe0, 0xc, 0x30, + 0x0, 0x5, 0x60, 0xd3, 0x1, 0xe0, 0xe, 0x20, + 0x0, 0xd, 0x40, 0xd3, 0x1, 0xe6, 0xfb, 0x0, + 0x0, 0x6c, 0x0, 0xd3, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0xe4, 0x0, 0xd3, 0x0, 0x10, 0x0, 0xb0, + 0x9, 0xb0, 0x0, 0xc6, 0x0, 0x0, 0x5, 0xd0, + 0x9, 0x20, 0x0, 0x5e, 0xff, 0xff, 0xfe, 0x50, + + /* U+6C7A "決" */ + 0x3, 0xb4, 0x0, 0x0, 0xf, 0x10, 0x0, 0x0, + 0x0, 0x3b, 0x90, 0x0, 0xf, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0x20, 0x1f, 0x0, + 0x2d, 0x60, 0x0, 0x0, 0xf, 0x10, 0xf, 0x0, + 0x3, 0xcc, 0x0, 0x0, 0xf, 0x10, 0xf, 0x0, + 0x0, 0x4, 0x0, 0x0, 0x1f, 0x10, 0x1f, 0x0, + 0x0, 0x0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf5, + 0x0, 0x5, 0x40, 0x0, 0x5d, 0xe0, 0x0, 0x0, + 0x0, 0xd, 0x50, 0x0, 0xb7, 0xb6, 0x0, 0x0, + 0x0, 0x5d, 0x0, 0x3, 0xe1, 0x3e, 0x10, 0x0, + 0x0, 0xd5, 0x0, 0x2e, 0x60, 0x9, 0xb0, 0x0, + 0x6, 0xc0, 0x4, 0xe7, 0x0, 0x0, 0xbc, 0x20, + 0x9, 0x40, 0x7e, 0x50, 0x0, 0x0, 0x9, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+6C88 "沈" */ + 0x6, 0x81, 0x0, 0x0, 0xf, 0x10, 0x0, 0x0, + 0x1, 0x8e, 0x40, 0x0, 0xf, 0x10, 0x0, 0x0, + 0x0, 0x2, 0x11, 0x11, 0x1f, 0x21, 0x11, 0x10, + 0x0, 0x0, 0xc, 0xee, 0xef, 0xee, 0xee, 0xe0, + 0x27, 0x0, 0xc, 0x30, 0x1f, 0x0, 0x2, 0xe0, + 0x2b, 0xe6, 0xc, 0x30, 0x3e, 0x40, 0x2, 0xe0, + 0x0, 0x57, 0x2, 0x0, 0x5f, 0xd0, 0x0, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x9b, 0xd0, 0x0, 0x0, + 0x0, 0x3, 0x30, 0x0, 0xe8, 0xd0, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x3, 0xe4, 0xd0, 0x0, 0x0, + 0x0, 0x4d, 0x0, 0xd, 0x73, 0xd0, 0x0, 0x30, + 0x0, 0xd4, 0x0, 0x8d, 0x3, 0xd0, 0x0, 0xa4, + 0x8, 0xb0, 0x9, 0xe2, 0x3, 0xe0, 0x0, 0xd2, + 0xb, 0x20, 0x8c, 0x20, 0x0, 0xdf, 0xff, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6C92 "沒" */ + 0x0, 0x10, 0x0, 0x1, 0x50, 0x0, 0x0, 0x0, + 0x3, 0xe8, 0x0, 0x5, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x1a, 0xb0, 0x8, 0xff, 0xff, 0xff, 0x40, + 0x0, 0x0, 0x10, 0xd, 0x50, 0x0, 0xe, 0x20, + 0x0, 0x0, 0x0, 0x3e, 0x0, 0x0, 0xf, 0x10, + 0x1c, 0x60, 0x0, 0xc7, 0x0, 0x0, 0x2f, 0x0, + 0x3, 0xcc, 0xa, 0xb0, 0x0, 0x8a, 0xda, 0x0, + 0x0, 0x4, 0x5, 0x10, 0x0, 0x24, 0x30, 0x0, + 0x0, 0x0, 0x3, 0xff, 0xff, 0xff, 0xff, 0x20, + 0x0, 0x3, 0x70, 0xd, 0x30, 0x0, 0x7b, 0x0, + 0x0, 0xb, 0x70, 0x5, 0xd0, 0x2, 0xe2, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0x8c, 0x4e, 0x40, 0x0, + 0x0, 0xc7, 0x0, 0x0, 0x1d, 0xf8, 0x0, 0x0, + 0x5, 0xd0, 0x0, 0x39, 0xe9, 0x6e, 0xb4, 0x0, + 0x7, 0x50, 0x1f, 0xd8, 0x10, 0x0, 0x7c, 0xf2, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+6CB9 "油" */ + 0x3, 0xa3, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x5, 0xcb, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, + 0x0, 0x30, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0xff, 0xff, 0xff, 0xfe, 0x1a, 0x30, + 0x1, 0xe0, 0x1, 0xe0, 0x1, 0xe0, 0x7e, 0x90, + 0x1e, 0x0, 0x1e, 0x0, 0x1e, 0x0, 0x1a, 0x1, + 0xe0, 0x1, 0xe0, 0x1, 0xe0, 0x0, 0x0, 0x1f, + 0x44, 0x5f, 0x44, 0x5e, 0x0, 0x0, 0x1, 0xfc, + 0xcc, 0xfc, 0xcc, 0xe0, 0x0, 0x76, 0x1e, 0x0, + 0x1e, 0x0, 0x1e, 0x0, 0x1e, 0x21, 0xe0, 0x1, + 0xe0, 0x1, 0xe0, 0xa, 0x90, 0x1e, 0x0, 0x1e, + 0x0, 0x1e, 0x5, 0xe0, 0x1, 0xff, 0xff, 0xff, + 0xff, 0xe0, 0x54, 0x0, 0x1e, 0x11, 0x11, 0x11, + 0x2d, + + /* U+6CBB "治" */ + 0x0, 0x10, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, + 0x1, 0xe9, 0x10, 0x0, 0x8b, 0x0, 0x0, 0x0, + 0x0, 0x19, 0xe1, 0x2, 0xf2, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x20, 0xa, 0x80, 0xd, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x4d, 0x0, 0x2, 0xe3, 0x0, + 0x1a, 0x30, 0x1, 0xe3, 0x0, 0x1, 0x7e, 0x0, + 0x6, 0xea, 0xd, 0xfd, 0xef, 0xfe, 0xde, 0x90, + 0x0, 0x17, 0x5, 0x43, 0x21, 0x0, 0x1, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x61, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x9, 0x91, 0xf0, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0x2f, 0x11, 0xf0, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0xc7, 0x1, 0xf0, 0x0, 0x0, 0x1f, 0x0, + 0x6, 0xd0, 0x1, 0xf3, 0x33, 0x33, 0x4f, 0x0, + 0x7, 0x40, 0x1, 0xfc, 0xcc, 0xcc, 0xce, 0x0, + + /* U+6CC1 "況" */ + 0x0, 0x71, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xaf, 0x80, 0xef, 0xff, 0xff, 0xff, 0x20, + 0x0, 0x2, 0xa0, 0xe2, 0x0, 0x0, 0xe, 0x20, + 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, 0xe, 0x20, + 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, 0xe, 0x20, + 0x1b, 0x50, 0x0, 0xe2, 0x0, 0x0, 0xe, 0x20, + 0x6, 0xdc, 0x20, 0xe3, 0x0, 0x0, 0xe, 0x20, + 0x0, 0x6, 0x0, 0xef, 0xff, 0xff, 0xff, 0x20, + 0x0, 0x0, 0x0, 0x3, 0xd0, 0x1f, 0x0, 0x0, + 0x0, 0x0, 0x91, 0x4, 0xb0, 0x1f, 0x0, 0x0, + 0x0, 0x5, 0xd0, 0x7, 0x90, 0x1f, 0x0, 0x0, + 0x0, 0xe, 0x40, 0xc, 0x40, 0x1f, 0x0, 0x10, + 0x0, 0x8a, 0x0, 0x5e, 0x0, 0x1f, 0x0, 0xd1, + 0x3, 0xe1, 0x7, 0xf3, 0x0, 0x1f, 0x0, 0xe0, + 0x6, 0x60, 0x8c, 0x30, 0x0, 0xd, 0xff, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6CCA "泊" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0x60, 0x0, 0x0, 0xf3, 0x0, 0x0, 0x0, + 0x3c, 0xc0, 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, + 0x4, 0x4, 0x49, 0xb4, 0x44, 0x41, 0x0, 0x0, + 0x1, 0xfb, 0xbb, 0xbb, 0xbf, 0x40, 0x83, 0x0, + 0x1e, 0x0, 0x0, 0x0, 0xd4, 0x5, 0xda, 0x1, + 0xe0, 0x0, 0x0, 0xd, 0x40, 0x0, 0x40, 0x1e, + 0x0, 0x0, 0x0, 0xd4, 0x0, 0x0, 0x1, 0xfe, + 0xee, 0xee, 0xef, 0x40, 0x0, 0x49, 0x1e, 0x11, + 0x11, 0x11, 0xd4, 0x0, 0xc, 0x61, 0xe0, 0x0, + 0x0, 0xd, 0x40, 0x3, 0xe0, 0x1e, 0x0, 0x0, + 0x0, 0xd4, 0x0, 0xc6, 0x1, 0xe0, 0x0, 0x0, + 0xd, 0x40, 0x5d, 0x0, 0x1f, 0xdd, 0xdd, 0xdd, + 0xf4, 0x3, 0x40, 0x1, 0xe2, 0x22, 0x22, 0x2c, + 0x30, + + /* U+6CD5 "法" */ + 0x2, 0xb5, 0x0, 0x0, 0x6, 0xa0, 0x0, 0x0, + 0x2, 0x9c, 0x0, 0x0, 0x6a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xbc, 0xce, 0xfc, 0xcc, 0x40, 0x0, + 0x0, 0x3, 0x33, 0x8c, 0x33, 0x31, 0x1e, 0x80, + 0x0, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x1a, 0xe0, + 0x0, 0x0, 0x6a, 0x0, 0x0, 0x0, 0x2, 0x7, + 0xcc, 0xce, 0xec, 0xcc, 0xc0, 0x0, 0x0, 0x23, + 0x35, 0xf5, 0x33, 0x33, 0x0, 0x1, 0xc0, 0x0, + 0x8b, 0x0, 0x0, 0x0, 0x0, 0x99, 0x0, 0x1f, + 0x20, 0x68, 0x0, 0x0, 0x2f, 0x10, 0xa, 0x80, + 0x0, 0xd3, 0x0, 0xb, 0x80, 0x5, 0xd0, 0x13, + 0x5a, 0xd0, 0x6, 0xd0, 0x1, 0xff, 0xfe, 0xb9, + 0x7b, 0x70, 0x44, 0x0, 0x5, 0x20, 0x0, 0x0, + 0x2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+6CE2 "波" */ + 0x1, 0xb5, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0x0, 0x3b, 0xb0, 0x0, 0x2, 0xe0, 0x0, 0x10, + 0x0, 0x0, 0x21, 0xff, 0xff, 0xff, 0xff, 0xf6, + 0x0, 0x0, 0x1, 0xe0, 0x1, 0xe0, 0x1, 0xf0, + 0xb, 0x60, 0x1, 0xe0, 0x1, 0xe0, 0x8, 0x90, + 0x3, 0xcc, 0x11, 0xe0, 0x2, 0xe0, 0x3, 0x10, + 0x0, 0x6, 0x2, 0xff, 0xfe, 0xee, 0xef, 0x30, + 0x0, 0x0, 0x3, 0xd4, 0xc0, 0x0, 0x3d, 0x0, + 0x0, 0x3, 0x34, 0xb0, 0xc4, 0x0, 0xa7, 0x0, + 0x0, 0xb, 0x76, 0x90, 0x4d, 0x14, 0xd0, 0x0, + 0x0, 0x2e, 0x9, 0x70, 0x8, 0xce, 0x30, 0x0, + 0x0, 0xa8, 0xe, 0x30, 0x5, 0xfd, 0x20, 0x0, + 0x3, 0xf1, 0x5d, 0x2, 0xae, 0x47, 0xf7, 0x10, + 0x7, 0x80, 0xd4, 0x9f, 0x91, 0x0, 0x3b, 0xf6, + 0x0, 0x0, 0x10, 0x21, 0x0, 0x0, 0x0, 0x10, + + /* U+6CE3 "泣" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x6, 0xb4, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, + 0x0, 0x5e, 0x90, 0x0, 0xc, 0x40, 0x0, 0x0, + 0x0, 0x1, 0x43, 0x33, 0x38, 0x63, 0x33, 0x20, + 0x0, 0x0, 0xc, 0xcc, 0xcc, 0xcc, 0xcc, 0x80, + 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, + 0x2b, 0xe5, 0x0, 0xb5, 0x0, 0x0, 0xf2, 0x0, + 0x0, 0x49, 0x0, 0x88, 0x0, 0x3, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x5b, 0x0, 0x6, 0xb0, 0x0, + 0x0, 0x1, 0x40, 0x2e, 0x0, 0x9, 0x70, 0x0, + 0x0, 0x9, 0x90, 0xf, 0x10, 0xc, 0x40, 0x0, + 0x0, 0x2f, 0x10, 0xd, 0x30, 0xf, 0x0, 0x0, + 0x0, 0xb8, 0x0, 0xb, 0x50, 0x4b, 0x0, 0x0, + 0x5, 0xe0, 0x34, 0x45, 0x44, 0xaa, 0x44, 0x40, + 0xc, 0x50, 0x9b, 0xbb, 0xbb, 0xbb, 0xbb, 0xb1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6CE8 "注" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x1, 0xd6, 0x0, 0x0, 0xd, 0x50, 0x0, 0x0, + 0x0, 0x3c, 0xd1, 0x0, 0x4, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x51, 0x22, 0x22, 0xb3, 0x22, 0x20, + 0x0, 0x0, 0x8, 0xee, 0xee, 0xfe, 0xee, 0xe1, + 0x7, 0x30, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0x5, 0xdb, 0x10, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0x0, 0x5, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xcc, 0xcd, 0xfc, 0xcc, 0x60, + 0x0, 0x0, 0xb0, 0x33, 0x37, 0xd3, 0x33, 0x10, + 0x0, 0x7, 0xb0, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0x0, 0xe, 0x30, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0x0, 0x7b, 0x0, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0x1, 0xf3, 0x0, 0x0, 0x4, 0xd0, 0x0, 0x0, + 0x7, 0xa0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf7, + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6CF3 "泳" */ + 0x0, 0x10, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, + 0x1, 0xe9, 0x10, 0x5, 0xdc, 0x72, 0x0, 0x0, + 0x0, 0x19, 0xe0, 0x0, 0x3, 0x9e, 0x70, 0x0, + 0x0, 0x0, 0x30, 0x0, 0x0, 0x1, 0x10, 0x0, + 0x0, 0x0, 0x0, 0xaf, 0xff, 0xc0, 0x0, 0x0, + 0xb, 0x60, 0x0, 0x0, 0x4, 0xd0, 0x0, 0x50, + 0x4, 0xdc, 0x10, 0x0, 0x4, 0xf1, 0x8, 0xd1, + 0x0, 0x7, 0x3f, 0xff, 0xb4, 0xf6, 0x7c, 0x10, + 0x0, 0x0, 0x0, 0x9, 0x74, 0xee, 0xb0, 0x0, + 0x0, 0x1, 0x70, 0xf, 0x24, 0xc9, 0x50, 0x0, + 0x0, 0x9, 0x90, 0x7b, 0x4, 0xc1, 0xe1, 0x0, + 0x0, 0x2f, 0x11, 0xe3, 0x4, 0xc0, 0x8c, 0x10, + 0x0, 0xa8, 0x1c, 0x70, 0x4, 0xc0, 0xb, 0xd2, + 0x4, 0xe1, 0x77, 0x0, 0x5, 0xc0, 0x0, 0x84, + 0x3, 0x50, 0x0, 0x6, 0xfe, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6D0B "洋" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x10, 0x0, + 0x3, 0x91, 0x0, 0x1e, 0x20, 0x0, 0x99, 0x0, + 0x0, 0x8e, 0x40, 0x7, 0xb0, 0x1, 0xe1, 0x0, + 0x0, 0x4, 0x91, 0x33, 0xd3, 0x3a, 0xa3, 0x20, + 0x0, 0x0, 0x5, 0xcc, 0xce, 0xfc, 0xcc, 0xb0, + 0x7, 0x10, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x7, 0xe8, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x19, 0x0, 0xff, 0xff, 0xff, 0xff, 0x60, + 0x0, 0x0, 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, + 0x0, 0x8, 0x50, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x1f, 0x2a, 0xbb, 0xbd, 0xeb, 0xbb, 0xb3, + 0x0, 0x8a, 0x4, 0x44, 0x48, 0xc4, 0x44, 0x41, + 0x2, 0xf2, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0xb, 0x90, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x4, 0x10, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + + /* U+6D17 "洗" */ + 0x3, 0xa3, 0x0, 0x1b, 0x5, 0xa0, 0x0, 0x0, + 0x0, 0x4d, 0x60, 0x6b, 0x5, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xbf, 0xff, 0xff, 0xff, 0xa0, + 0x0, 0x0, 0x3, 0xe1, 0x6, 0xb0, 0x0, 0x0, + 0x1e, 0x70, 0xc, 0x60, 0x5, 0xa0, 0x0, 0x0, + 0x2, 0xbc, 0x3, 0x0, 0x5, 0xa0, 0x0, 0x0, + 0x0, 0x3, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xf5, + 0x0, 0x0, 0x0, 0x5, 0xc0, 0xf, 0x10, 0x0, + 0x0, 0x8, 0x30, 0x6, 0xa0, 0xf, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x9, 0x80, 0xf, 0x0, 0x0, + 0x0, 0x7a, 0x0, 0xe, 0x30, 0xf, 0x0, 0x21, + 0x0, 0xe3, 0x0, 0x6d, 0x0, 0xf, 0x0, 0x77, + 0x7, 0xc0, 0x6, 0xf3, 0x0, 0xf, 0x10, 0x96, + 0x8, 0x40, 0x9c, 0x30, 0x0, 0xb, 0xff, 0xe1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6D32 "洲" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0x70, 0x2, 0xd0, 0xe, 0x10, 0x1e, 0x0, + 0x1b, 0x80, 0x2d, 0x0, 0xe1, 0x1, 0xe0, 0x0, + 0x0, 0x2, 0xd0, 0xe, 0x10, 0x1e, 0x0, 0x0, + 0x0, 0x2d, 0x0, 0xe1, 0x1, 0xe0, 0xc7, 0x0, + 0x76, 0xe8, 0xe, 0xa4, 0x1e, 0x2, 0xbd, 0xb, + 0x4d, 0xb2, 0xe4, 0xd2, 0xe0, 0x0, 0x31, 0xd2, + 0xd6, 0x7e, 0x1b, 0x7e, 0x0, 0x0, 0x87, 0x3c, + 0x2a, 0xe1, 0x4d, 0xe0, 0x0, 0x52, 0x14, 0xb0, + 0xe, 0x10, 0x2e, 0x0, 0x1f, 0x10, 0x78, 0x0, + 0xe1, 0x1, 0xe0, 0x7, 0xa0, 0xb, 0x40, 0xe, + 0x10, 0x1e, 0x0, 0xd4, 0x1, 0xe0, 0x0, 0xe1, + 0x1, 0xe0, 0x5d, 0x0, 0x97, 0x0, 0xe, 0x10, + 0x1e, 0x7, 0x50, 0x2c, 0x0, 0x0, 0xe1, 0x1, + 0xe0, + + /* U+6D3B "活" */ + 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x37, 0x0, + 0x3, 0xea, 0x20, 0x35, 0x7a, 0xcf, 0xd9, 0x20, + 0x0, 0x8, 0xc0, 0xa9, 0x78, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0xc0, 0x0, 0x0, + 0x1d, 0x60, 0xd, 0xee, 0xef, 0xfe, 0xee, 0xe3, + 0x3, 0xdc, 0x1, 0x11, 0x14, 0xc1, 0x11, 0x10, + 0x0, 0x5, 0x0, 0x0, 0x3, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3, 0xc0, 0x0, 0x0, + 0x0, 0x1, 0x70, 0xbe, 0xef, 0xfe, 0xee, 0x20, + 0x0, 0xa, 0x80, 0xb4, 0x0, 0x0, 0xd, 0x20, + 0x0, 0x3e, 0x0, 0xb4, 0x0, 0x0, 0xd, 0x20, + 0x0, 0xc6, 0x0, 0xb4, 0x0, 0x0, 0xd, 0x20, + 0x7, 0xd0, 0x0, 0xb7, 0x33, 0x33, 0x3e, 0x20, + 0x8, 0x30, 0x0, 0xbd, 0xbb, 0xbb, 0xbe, 0x20, + + /* U+6D3E "派" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, + 0x2, 0xe7, 0x0, 0x0, 0x25, 0x7b, 0xfd, 0x50, + 0x0, 0x2b, 0xa0, 0xdf, 0xca, 0x74, 0x10, 0x0, + 0x0, 0x0, 0x20, 0xf0, 0x0, 0x0, 0x4, 0x0, + 0x0, 0x0, 0x0, 0xf0, 0x4, 0x8b, 0xeb, 0x20, + 0xa, 0x40, 0x0, 0xf0, 0x2e, 0x7e, 0x10, 0x0, + 0x5, 0xda, 0x0, 0xf0, 0x2d, 0xc, 0x30, 0x0, + 0x0, 0x4, 0x1, 0xf0, 0x2d, 0x9, 0x60, 0xb4, + 0x0, 0x0, 0x2, 0xe0, 0x2d, 0x6, 0xbc, 0x80, + 0x0, 0x6, 0x33, 0xc0, 0x2d, 0x1, 0xf5, 0x0, + 0x0, 0xe, 0x24, 0xa0, 0x2d, 0x0, 0xc4, 0x0, + 0x0, 0x6b, 0x8, 0x70, 0x2d, 0x0, 0x6c, 0x0, + 0x0, 0xe3, 0xc, 0x30, 0x2d, 0x4, 0x4e, 0x50, + 0x7, 0xb0, 0x3d, 0x0, 0x4e, 0xdb, 0x35, 0xf4, + 0x7, 0x30, 0xb6, 0x0, 0x99, 0x20, 0x0, 0x77, + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6D41 "流" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x5, 0xa1, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, + 0x0, 0x8e, 0x31, 0x11, 0x18, 0xa1, 0x11, 0x10, + 0x0, 0x5, 0x5d, 0xee, 0xff, 0xee, 0xee, 0xe1, + 0x0, 0x0, 0x0, 0x4, 0xe1, 0x3, 0x70, 0x0, + 0x19, 0x20, 0x0, 0x3e, 0x30, 0x0, 0xb8, 0x0, + 0x6, 0xd9, 0x6, 0xfd, 0xbc, 0xdd, 0xde, 0x60, + 0x0, 0x5, 0x3, 0x53, 0x21, 0x0, 0x2, 0xa0, + 0x0, 0x0, 0x0, 0x96, 0xb, 0x30, 0xd2, 0x0, + 0x0, 0x2, 0x90, 0x96, 0xb, 0x30, 0xd2, 0x0, + 0x0, 0xa, 0x70, 0xa5, 0xb, 0x30, 0xd2, 0x0, + 0x0, 0x3e, 0x0, 0xd3, 0xb, 0x30, 0xd2, 0x0, + 0x0, 0xc7, 0x3, 0xf0, 0xb, 0x30, 0xd2, 0x54, + 0x6, 0xd0, 0x1c, 0x80, 0xb, 0x30, 0xd2, 0x75, + 0x9, 0x50, 0x8b, 0x0, 0x4, 0x10, 0x9e, 0xd1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6D45 "浅" */ + 0x3, 0xa2, 0x0, 0x0, 0xe3, 0x55, 0x0, 0x0, + 0x0, 0x6e, 0x50, 0x0, 0xd3, 0x1b, 0xa0, 0x0, + 0x0, 0x2, 0x40, 0x0, 0xc4, 0x0, 0x62, 0x10, + 0x0, 0x0, 0x4, 0x68, 0xec, 0xde, 0xec, 0x50, + 0x19, 0x20, 0x8, 0x97, 0xc9, 0x10, 0x0, 0x0, + 0x6, 0xe7, 0x0, 0x0, 0x79, 0x0, 0x0, 0x20, + 0x0, 0x16, 0x1, 0x35, 0xae, 0xac, 0xee, 0xc1, + 0x0, 0x0, 0x2e, 0xca, 0x8f, 0x42, 0x2, 0x70, + 0x0, 0x7, 0x30, 0x0, 0xd, 0x40, 0x2e, 0x50, + 0x0, 0x1e, 0x10, 0x0, 0x8, 0x94, 0xe6, 0x0, + 0x0, 0x8a, 0x0, 0x0, 0x4, 0xfd, 0x30, 0x71, + 0x1, 0xe2, 0x0, 0x2, 0x9e, 0xd9, 0x0, 0xc2, + 0x9, 0xa0, 0x8, 0xde, 0x81, 0x2f, 0x83, 0xe0, + 0x6, 0x20, 0x7, 0x40, 0x0, 0x3, 0xcf, 0x70, + + /* U+6D74 "浴" */ + 0x0, 0x20, 0x0, 0x0, 0x40, 0x2, 0x0, 0x0, + 0x3, 0xe9, 0x0, 0x8, 0xb0, 0xa, 0xb0, 0x0, + 0x0, 0x1a, 0xc0, 0x4e, 0x10, 0x0, 0xab, 0x0, + 0x0, 0x0, 0x24, 0xe4, 0x6, 0x40, 0xc, 0xa0, + 0x0, 0x0, 0xd, 0x40, 0x1f, 0xa0, 0x1, 0xa1, + 0x1c, 0x50, 0x0, 0x0, 0xc8, 0xc5, 0x0, 0x0, + 0x3, 0xdb, 0x0, 0x9, 0xb0, 0x1e, 0x40, 0x0, + 0x0, 0x3, 0x0, 0xac, 0x10, 0x3, 0xe7, 0x0, + 0x0, 0x0, 0x3d, 0xa0, 0x0, 0x0, 0x1c, 0xd3, + 0x0, 0x2, 0x76, 0xee, 0xee, 0xee, 0xec, 0x85, + 0x0, 0xd, 0x30, 0xf1, 0x0, 0x0, 0x4d, 0x0, + 0x0, 0x5c, 0x0, 0xf1, 0x0, 0x0, 0x3d, 0x0, + 0x0, 0xd5, 0x0, 0xf1, 0x0, 0x0, 0x3d, 0x0, + 0x6, 0xd0, 0x0, 0xf4, 0x22, 0x22, 0x5d, 0x0, + 0x6, 0x50, 0x0, 0xfd, 0xcc, 0xcc, 0xdc, 0x0, + + /* U+6D77 "海" */ + 0x1, 0x20, 0x0, 0x26, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xe9, 0x0, 0x99, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x60, 0xed, 0xcc, 0xcc, 0xcc, 0x90, + 0x0, 0x0, 0x7, 0xb3, 0x33, 0x33, 0x33, 0x20, + 0x0, 0x0, 0x2f, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x14, 0x0, 0x98, 0xaf, 0xee, 0xee, 0xff, 0x0, + 0x2b, 0xc3, 0x0, 0xd3, 0x1a, 0x10, 0xf, 0x0, + 0x0, 0x44, 0x0, 0xf0, 0x2, 0xb0, 0x1e, 0x0, + 0x0, 0x0, 0x9d, 0xfd, 0xdd, 0xdd, 0xdf, 0xd2, + 0x0, 0x1b, 0x15, 0xd2, 0x75, 0x22, 0x5d, 0x20, + 0x0, 0x6a, 0x5, 0xa0, 0x1c, 0x20, 0x4b, 0x0, + 0x0, 0xd4, 0x8, 0x80, 0x2, 0x80, 0x5a, 0x0, + 0x3, 0xe0, 0xa, 0xee, 0xee, 0xee, 0xff, 0xa0, + 0xa, 0x70, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x0, + 0x9, 0x10, 0x0, 0x0, 0x4, 0xee, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6D88 "消" */ + 0x4, 0x91, 0x1, 0x50, 0x1, 0xe0, 0x3, 0x40, + 0x6, 0xe5, 0xd, 0x50, 0x1e, 0x0, 0xd4, 0x0, + 0x2, 0x30, 0x3e, 0x1, 0xe0, 0x79, 0x0, 0x0, + 0x0, 0x0, 0x50, 0x1e, 0x4, 0x0, 0x1d, 0x50, + 0x0, 0xef, 0xff, 0xff, 0xff, 0x10, 0x3d, 0xa0, + 0xe, 0x20, 0x0, 0x0, 0xe1, 0x0, 0x6, 0x0, + 0xe2, 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0xe, + 0xfe, 0xee, 0xee, 0xf1, 0x0, 0x4, 0x30, 0xe2, + 0x0, 0x0, 0xe, 0x10, 0x0, 0xc6, 0xe, 0x20, + 0x0, 0x0, 0xe1, 0x0, 0x4d, 0x0, 0xee, 0xee, + 0xee, 0xef, 0x10, 0xd, 0x50, 0xe, 0x20, 0x0, + 0x0, 0xe1, 0x7, 0xc0, 0x0, 0xe2, 0x0, 0x1, + 0x1f, 0x10, 0x63, 0x0, 0xe, 0x20, 0x0, 0xce, + 0xa0, + + /* U+6DBC "涼" */ + 0x2, 0x20, 0x0, 0x0, 0x8, 0x10, 0x0, 0x0, + 0x5, 0xea, 0x10, 0x0, 0xc, 0x70, 0x0, 0x0, + 0x0, 0x9, 0x99, 0xbb, 0xbd, 0xfb, 0xbb, 0xb0, + 0x0, 0x0, 0x2, 0x33, 0x33, 0x33, 0x33, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x28, 0x10, 0x0, 0xfe, 0xee, 0xee, 0xef, 0x0, + 0x7, 0xe6, 0x0, 0xf1, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0x14, 0x0, 0xf1, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0x0, 0x0, 0xfe, 0xee, 0xee, 0xef, 0x0, + 0x0, 0x6, 0x60, 0x0, 0x9, 0x90, 0x0, 0x0, + 0x0, 0xd, 0x30, 0x79, 0x8, 0x80, 0xa3, 0x0, + 0x0, 0x6b, 0x1, 0xe2, 0x8, 0x80, 0x5d, 0x0, + 0x0, 0xe3, 0xc, 0x70, 0x8, 0x80, 0xb, 0x70, + 0x9, 0xa0, 0x5b, 0x0, 0x9, 0x80, 0x2, 0xc0, + 0x9, 0x20, 0x0, 0xa, 0xee, 0x40, 0x0, 0x0, + + /* U+6DF1 "深" */ + 0x4, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xcc, 0x2d, 0xff, 0xff, 0xff, 0xff, 0x80, + 0x0, 0x7, 0x2d, 0x20, 0x0, 0x0, 0x7, 0x80, + 0x0, 0x0, 0xa, 0x23, 0xa0, 0x3c, 0x5, 0x60, + 0x1, 0x0, 0x0, 0x1e, 0x40, 0x8, 0xb0, 0x0, + 0x3e, 0x70, 0x1, 0xc8, 0x0, 0x0, 0xa9, 0x0, + 0x2, 0xcb, 0xb, 0x80, 0x7, 0x30, 0xd, 0x20, + 0x0, 0x2, 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, + 0x0, 0x0, 0xd, 0xee, 0xef, 0xee, 0xee, 0x80, + 0x0, 0xb, 0x11, 0x11, 0xcf, 0xf6, 0x11, 0x0, + 0x0, 0x3d, 0x0, 0x8, 0xac, 0x7e, 0x20, 0x0, + 0x0, 0xb5, 0x0, 0x4d, 0xb, 0x56, 0xc0, 0x0, + 0x3, 0xd0, 0x7, 0xd2, 0xb, 0x50, 0x9c, 0x20, + 0xc, 0x60, 0x7b, 0x10, 0xb, 0x50, 0x8, 0xc0, + 0x7, 0x0, 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, + + /* U+6DF7 "混" */ + 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xeb, 0x22, 0xfe, 0xee, 0xee, 0xef, 0x20, + 0x0, 0xa, 0xf3, 0xd0, 0x0, 0x0, 0xe, 0x20, + 0x0, 0x0, 0x32, 0xe0, 0x0, 0x0, 0xe, 0x20, + 0x0, 0x0, 0x2, 0xfd, 0xdd, 0xdd, 0xdf, 0x20, + 0x7, 0x30, 0x2, 0xd0, 0x0, 0x0, 0xe, 0x20, + 0x5, 0xeb, 0x12, 0xfe, 0xee, 0xee, 0xef, 0x20, + 0x0, 0x7, 0x0, 0x20, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf0, 0x0, 0x3c, 0x0, 0x0, + 0x0, 0x0, 0x60, 0xf0, 0x0, 0x3c, 0x4, 0xc1, + 0x0, 0x5, 0xd0, 0xff, 0xfd, 0x3d, 0xae, 0x50, + 0x0, 0xd, 0x50, 0xf0, 0x0, 0x3e, 0x50, 0x0, + 0x0, 0x7c, 0x0, 0xf0, 0x0, 0x3c, 0x0, 0x45, + 0x2, 0xf3, 0x1, 0xf4, 0x7a, 0x3d, 0x0, 0x78, + 0x5, 0x90, 0x7, 0xfc, 0x73, 0x1d, 0xff, 0xe3, + 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, + + /* U+6E05 "清" */ + 0x6, 0x70, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, + 0x1, 0x9e, 0x2d, 0xdd, 0xdf, 0xdd, 0xdd, 0x60, + 0x0, 0x3, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x8, 0xcc, 0xcf, 0xdc, 0xcc, 0x10, + 0x27, 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, + 0x1a, 0xd3, 0x8d, 0xdd, 0xdd, 0xdd, 0xdd, 0xd1, + 0x0, 0x66, 0x0, 0x22, 0x22, 0x22, 0x21, 0x0, + 0x0, 0x0, 0x4, 0xeb, 0xbb, 0xbb, 0xca, 0x0, + 0x0, 0x4, 0x4, 0xb0, 0x0, 0x0, 0x5a, 0x0, + 0x0, 0x1f, 0x24, 0xec, 0xcc, 0xcc, 0xda, 0x0, + 0x0, 0x8a, 0x4, 0xa0, 0x0, 0x0, 0x5a, 0x0, + 0x1, 0xf2, 0x4, 0xfd, 0xdd, 0xdd, 0xea, 0x0, + 0x9, 0xa0, 0x4, 0xa0, 0x0, 0x0, 0x5a, 0x0, + 0x8, 0x20, 0x4, 0xa0, 0x0, 0x4e, 0xe6, 0x0, + + /* U+6E07 "渇" */ + 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5e, 0x80, 0xe, 0xed, 0xdd, 0xde, 0xe0, 0x0, + 0x1b, 0x60, 0xe1, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0xe, 0xcc, 0xcc, 0xcc, 0xe0, 0x0, 0x0, + 0x0, 0xe2, 0x0, 0x0, 0x3e, 0x4, 0xb2, 0x0, + 0xe, 0x20, 0x0, 0x3, 0xe0, 0x7, 0xe6, 0x0, + 0xbe, 0xfc, 0xcc, 0xcb, 0x0, 0x2, 0x40, 0x1, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, + 0xee, 0xee, 0xef, 0xb0, 0x0, 0x72, 0xce, 0x10, + 0x2, 0x0, 0x5a, 0x0, 0x2e, 0x89, 0xd5, 0x8d, + 0xb2, 0x7, 0x90, 0xa, 0x80, 0xd, 0xa5, 0x10, + 0x10, 0x87, 0x2, 0xf1, 0x0, 0xd3, 0x0, 0x1c, + 0xb, 0x50, 0xb8, 0x0, 0x7, 0xee, 0xed, 0x60, + 0xe2, 0x8, 0x0, 0x0, 0x0, 0x0, 0x3f, 0xfb, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6E08 "済" */ + 0x0, 0x10, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, + 0x4, 0xe4, 0x0, 0x0, 0xd, 0x20, 0x0, 0x0, + 0x0, 0x3e, 0x3e, 0xee, 0xef, 0xfe, 0xee, 0xe3, + 0x0, 0x2, 0x0, 0x5c, 0x0, 0x2, 0xe2, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xc2, 0x3d, 0x50, 0x0, + 0x2b, 0x20, 0x0, 0x0, 0x8f, 0xf7, 0x0, 0x0, + 0x6, 0xe3, 0x6, 0xbe, 0xb5, 0x6b, 0xfc, 0x92, + 0x0, 0x41, 0x7, 0x73, 0x0, 0x0, 0x34, 0x50, + 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, 0xb4, 0x0, + 0x0, 0x5, 0x0, 0x9e, 0xdd, 0xdd, 0xf4, 0x0, + 0x0, 0x1e, 0x0, 0xa5, 0x0, 0x0, 0xb4, 0x0, + 0x0, 0x88, 0x0, 0xdd, 0xcc, 0xcc, 0xf4, 0x0, + 0x1, 0xe1, 0x3, 0xd1, 0x11, 0x11, 0xb4, 0x0, + 0x9, 0x80, 0xc, 0x60, 0x0, 0x0, 0xb4, 0x0, + 0x7, 0x0, 0x5a, 0x0, 0x0, 0x0, 0xb4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6E09 "渉" */ + 0x1, 0xc7, 0x10, 0x13, 0x2, 0xd0, 0x0, 0x0, + 0x0, 0x18, 0xd0, 0x4b, 0x2, 0xfb, 0xbb, 0x60, + 0x0, 0x0, 0x0, 0x4b, 0x2, 0xe3, 0x33, 0x20, + 0x0, 0x0, 0x0, 0x4b, 0x2, 0xd0, 0x0, 0x0, + 0xd, 0xa2, 0x1c, 0xdf, 0xcd, 0xfc, 0xcc, 0xc6, + 0x1, 0x8f, 0x23, 0x33, 0x35, 0xe3, 0x33, 0x31, + 0x0, 0x3, 0x0, 0xb, 0x12, 0xd0, 0x78, 0x0, + 0x0, 0x0, 0x0, 0x6b, 0x2, 0xd0, 0x1e, 0x50, + 0x0, 0x2, 0x52, 0xe2, 0x2, 0xd0, 0x4, 0xf2, + 0x0, 0x9, 0x9a, 0x50, 0x25, 0xd0, 0x69, 0x83, + 0x0, 0x1f, 0x10, 0x0, 0xcc, 0x62, 0xe2, 0x0, + 0x0, 0x99, 0x0, 0x0, 0x0, 0x3e, 0x60, 0x0, + 0x2, 0xf1, 0x0, 0x0, 0x3a, 0xe4, 0x0, 0x0, + 0x8, 0x80, 0x3, 0xae, 0xd6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0x51, 0x0, 0x0, 0x0, 0x0, + + /* U+6E1B "減" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xc4, 0x0, 0x0, 0x0, 0xe, 0x4b, 0x20, + 0x0, 0x3c, 0x50, 0x0, 0x0, 0xf, 0x2, 0xa0, + 0x0, 0x0, 0xe, 0xee, 0xee, 0xef, 0xee, 0xe2, + 0x0, 0x0, 0xe, 0x0, 0x0, 0xe, 0x10, 0x0, + 0x2e, 0x70, 0xe, 0x3b, 0xbb, 0x8c, 0x21, 0x60, + 0x4, 0xeb, 0xe, 0x2, 0x22, 0x1b, 0x34, 0x90, + 0x0, 0x13, 0x1e, 0x1, 0x11, 0xa, 0x48, 0x50, + 0x0, 0x0, 0x2d, 0x3e, 0xbc, 0xa8, 0x6d, 0x10, + 0x0, 0x8, 0x3b, 0x3a, 0x2, 0xa6, 0xca, 0x0, + 0x0, 0x5b, 0x4a, 0x3a, 0x2, 0xa4, 0xf3, 0x0, + 0x0, 0xc5, 0x78, 0x3f, 0xde, 0x97, 0xe0, 0x11, + 0x4, 0xe0, 0xb4, 0x3a, 0x0, 0x6e, 0xe4, 0x57, + 0xc, 0x62, 0xe0, 0x1, 0x9, 0xc1, 0x7c, 0xa4, + 0x7, 0x6, 0x60, 0x0, 0x39, 0x0, 0xb, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6E21 "渡" */ + 0x1, 0x10, 0x0, 0x0, 0x5, 0x40, 0x0, 0x0, + 0x5, 0xf7, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x2d, 0x5c, 0xee, 0xef, 0xfe, 0xee, 0xd0, + 0x0, 0x0, 0xc, 0x30, 0x50, 0x0, 0x50, 0x0, + 0x0, 0x0, 0xc, 0x30, 0xe0, 0x0, 0xe1, 0x0, + 0x3b, 0x30, 0xc, 0xce, 0xfe, 0xee, 0xfe, 0xa0, + 0x5, 0xd8, 0xd, 0x30, 0xe0, 0x0, 0xe1, 0x0, + 0x0, 0x2, 0xe, 0x20, 0xe9, 0x88, 0xf1, 0x0, + 0x0, 0x0, 0xf, 0x20, 0x33, 0x33, 0x30, 0x0, + 0x0, 0xb, 0xf, 0x5d, 0xdd, 0xdd, 0xdc, 0x0, + 0x0, 0x7b, 0x2e, 0x2, 0xe1, 0x0, 0xa7, 0x0, + 0x0, 0xe4, 0x5a, 0x0, 0x6c, 0x7, 0xc0, 0x0, + 0x6, 0xc0, 0xa6, 0x0, 0x9, 0xec, 0x0, 0x0, + 0xe, 0x42, 0xf1, 0x4, 0xad, 0x8d, 0xb5, 0x10, + 0x19, 0x5, 0x80, 0xca, 0x50, 0x0, 0x5a, 0xb0, + + /* U+6E29 "温" */ + 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xdd, 0x40, 0xfe, 0xee, 0xee, 0xeb, 0x0, + 0x0, 0x7, 0xd0, 0xf0, 0x0, 0x0, 0x5b, 0x0, + 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, 0x5b, 0x0, + 0x0, 0x0, 0x0, 0xfd, 0xdd, 0xdd, 0xeb, 0x0, + 0x1a, 0x50, 0x0, 0xf0, 0x0, 0x0, 0x5b, 0x0, + 0x5, 0xdc, 0x0, 0xfc, 0xcc, 0xcc, 0xdb, 0x0, + 0x0, 0x4, 0x0, 0x22, 0x22, 0x22, 0x21, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x48, 0xff, 0xff, 0xff, 0xff, 0x30, + 0x0, 0xa, 0x88, 0x60, 0xd0, 0x58, 0xc, 0x30, + 0x0, 0x2e, 0x8, 0x60, 0xd0, 0x58, 0xc, 0x30, + 0x0, 0xb7, 0x8, 0x60, 0xd0, 0x58, 0xc, 0x30, + 0x4, 0xe0, 0x8, 0x60, 0xd0, 0x58, 0xc, 0x30, + 0xa, 0x50, 0xef, 0xff, 0xff, 0xff, 0xff, 0xf5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6E2F "港" */ + 0x7, 0x81, 0x0, 0xf, 0x0, 0xb, 0x50, 0x0, + 0x1, 0x8e, 0x43, 0x4f, 0x33, 0x3c, 0x73, 0x20, + 0x0, 0x4, 0x4b, 0xbf, 0xbb, 0xbe, 0xdb, 0x90, + 0x0, 0x0, 0x0, 0xf, 0x0, 0xb, 0x50, 0x0, + 0x38, 0x10, 0x44, 0x5f, 0x44, 0x4c, 0x84, 0x40, + 0x18, 0xe4, 0xab, 0xbf, 0xbb, 0xbe, 0xdb, 0xb2, + 0x0, 0x23, 0x0, 0x88, 0x0, 0x3, 0xd0, 0x0, + 0x0, 0x0, 0x5, 0xfe, 0xdd, 0xdd, 0xea, 0x0, + 0x0, 0x7, 0x7e, 0x88, 0x0, 0x7, 0x8b, 0xc2, + 0x0, 0x3f, 0xb3, 0x68, 0x0, 0x7, 0x80, 0x81, + 0x0, 0xa8, 0x0, 0x6f, 0xdd, 0xdd, 0x70, 0x0, + 0x3, 0xf1, 0x0, 0x68, 0x0, 0x0, 0x5, 0x10, + 0xb, 0x80, 0x0, 0x6a, 0x0, 0x0, 0x1d, 0x20, + 0xa, 0x10, 0x0, 0x2d, 0xff, 0xff, 0xfa, 0x0, + + /* U+6E56 "湖" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5e, 0x70, 0x6, 0x80, 0x8, 0xff, 0xfe, 0x0, + 0x2c, 0x40, 0x68, 0x0, 0x86, 0x1, 0xe0, 0x0, + 0x1, 0x17, 0x91, 0x18, 0x60, 0x1e, 0x0, 0x0, + 0xef, 0xff, 0xfb, 0x86, 0x1, 0xe1, 0xb4, 0x0, + 0x6, 0x80, 0x8, 0xff, 0xfe, 0x4, 0xd9, 0x0, + 0x68, 0x0, 0x86, 0x1, 0xe0, 0x0, 0x20, 0x7, + 0x80, 0x8, 0x60, 0x1e, 0x0, 0x0, 0x5f, 0xee, + 0xf4, 0xa6, 0x1, 0xe0, 0x0, 0x55, 0x90, 0xa, + 0x4b, 0xfe, 0xee, 0x0, 0x3d, 0x59, 0x0, 0xa4, + 0xc3, 0x1, 0xe0, 0xa, 0x75, 0x90, 0xa, 0x4e, + 0x0, 0x1e, 0x1, 0xf1, 0x5f, 0xff, 0xf9, 0xc0, + 0x1, 0xe0, 0x99, 0x5, 0x90, 0x0, 0xc6, 0x0, + 0x1e, 0xa, 0x20, 0x24, 0x0, 0x4c, 0x0, 0xde, + 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6E90 "源" */ + 0x3, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xe8, 0xc, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x2c, 0x4c, 0x40, 0x0, 0x91, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x40, 0x3, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x4c, 0xde, 0xfd, 0xdd, 0x10, + 0x4c, 0x40, 0xc, 0x4e, 0x10, 0x0, 0xe, 0x10, + 0x5, 0xe7, 0xd, 0x3e, 0xa9, 0x99, 0x9f, 0x10, + 0x0, 0x1, 0xd, 0x3e, 0x42, 0x22, 0x2e, 0x10, + 0x0, 0x0, 0xf, 0x1e, 0x10, 0x0, 0xe, 0x10, + 0x0, 0x6, 0x1f, 0xc, 0xdd, 0xfd, 0xdd, 0x10, + 0x0, 0x5d, 0x4c, 0x1, 0x10, 0xe1, 0x21, 0x0, + 0x0, 0xc5, 0x88, 0xa, 0x60, 0xe1, 0x7c, 0x0, + 0x4, 0xe0, 0xd4, 0x4c, 0x0, 0xe1, 0xc, 0x80, + 0xd, 0x65, 0xd0, 0xb2, 0x0, 0xe1, 0x3, 0xb0, + 0x8, 0x7, 0x40, 0x0, 0xbe, 0xc0, 0x0, 0x0, + + /* U+6E96 "準" */ + 0x0, 0x51, 0x0, 0x28, 0x3, 0x30, 0x0, 0x0, + 0x0, 0x8e, 0x80, 0xb8, 0x5, 0xd0, 0x0, 0x0, + 0x0, 0x1, 0x45, 0xfe, 0xde, 0xfe, 0xdd, 0x60, + 0x1a, 0x40, 0x3f, 0xc0, 0x2, 0xd0, 0x0, 0x0, + 0x5, 0xc8, 0xd9, 0xfb, 0xbc, 0xfb, 0xbb, 0x0, + 0x0, 0x0, 0x3, 0xc0, 0x2, 0xd0, 0x0, 0x0, + 0x0, 0x5, 0x93, 0xfb, 0xbc, 0xfb, 0xbb, 0x0, + 0x0, 0x4d, 0x13, 0xc0, 0x2, 0xd0, 0x0, 0x0, + 0x4, 0xe2, 0x3, 0xea, 0xab, 0xfa, 0xaa, 0x80, + 0x8, 0x40, 0x3, 0xc6, 0x63, 0x33, 0x33, 0x20, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x2e, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe3, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + + /* U+6E9D "溝" */ + 0x6, 0x91, 0x0, 0xb, 0x40, 0xe, 0x20, 0x0, + 0x0, 0x8e, 0x5d, 0xdf, 0xed, 0xdf, 0xdd, 0x70, + 0x0, 0x3, 0x10, 0xb, 0x40, 0xe, 0x20, 0x0, + 0x0, 0x0, 0x7, 0xcf, 0xdc, 0xcf, 0xdc, 0x30, + 0x39, 0x10, 0x0, 0xb, 0x40, 0xe, 0x20, 0x0, + 0x18, 0xf5, 0x8e, 0xee, 0xef, 0xee, 0xee, 0xe0, + 0x0, 0x34, 0x0, 0x11, 0x1d, 0x41, 0x11, 0x0, + 0x0, 0x0, 0x4, 0xeb, 0xbf, 0xcb, 0xcd, 0x0, + 0x0, 0x4, 0x4, 0xc1, 0x1d, 0x31, 0x4d, 0x0, + 0x0, 0x1f, 0x14, 0xeb, 0xbf, 0xcb, 0xcd, 0x0, + 0x0, 0x99, 0x4, 0xb0, 0xd, 0x20, 0x3d, 0x0, + 0x2, 0xf2, 0xbe, 0xfd, 0xdd, 0xdd, 0xef, 0xd2, + 0xb, 0x80, 0x4, 0xb0, 0x0, 0x0, 0x3d, 0x0, + 0x9, 0x10, 0x4, 0xb0, 0x0, 0x3d, 0xd9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6EFF "滿" */ + 0x9, 0x70, 0x0, 0x3c, 0x0, 0x9, 0x60, 0x0, + 0x1, 0x9c, 0xae, 0xff, 0xee, 0xef, 0xfe, 0xe1, + 0x0, 0x0, 0x0, 0x4c, 0x0, 0xa, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x3d, 0x33, 0x3b, 0x60, 0x0, + 0x44, 0x0, 0x0, 0x2b, 0xbf, 0xbb, 0x50, 0x0, + 0x3d, 0xb1, 0x0, 0x0, 0xf, 0x10, 0x0, 0x0, + 0x0, 0x71, 0x4f, 0xdd, 0xdf, 0xdd, 0xde, 0x80, + 0x0, 0x0, 0x4a, 0x32, 0xf, 0x6, 0x6, 0x80, + 0x0, 0x7, 0x4a, 0x2a, 0xf, 0x9, 0x26, 0x80, + 0x0, 0x5a, 0x4a, 0x2f, 0x2f, 0xc, 0xa6, 0x80, + 0x0, 0xd2, 0x4a, 0xa6, 0x8f, 0x57, 0xb8, 0x80, + 0x6, 0xa0, 0x4b, 0x70, 0x8f, 0x80, 0x4a, 0x80, + 0x1e, 0x20, 0x4a, 0x0, 0xf, 0x0, 0x6, 0x80, + 0x6, 0x0, 0x4a, 0x0, 0xc, 0x1, 0xcd, 0x50, + + /* U+6F22 "漢" */ + 0x3, 0xa2, 0x0, 0xc, 0x20, 0x8, 0x70, 0x0, + 0x0, 0x6e, 0x8d, 0xdf, 0xed, 0xdf, 0xed, 0xd2, + 0x0, 0x1, 0x20, 0xc, 0x41, 0x19, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x6, 0x8d, 0xb8, 0x40, 0x0, + 0x2e, 0x70, 0x4, 0xcc, 0xce, 0xdc, 0xcc, 0x20, + 0x4, 0xeb, 0x5, 0xa0, 0xa, 0x50, 0xc, 0x30, + 0x0, 0x15, 0x5, 0xa1, 0x1b, 0x61, 0x1d, 0x30, + 0x0, 0x0, 0x3, 0xbb, 0xbe, 0xdb, 0xbb, 0x20, + 0x0, 0x4, 0x24, 0x77, 0x7d, 0xa7, 0x77, 0x30, + 0x0, 0xe, 0x32, 0x33, 0x3e, 0x63, 0x33, 0x10, + 0x0, 0x6b, 0x3c, 0xcc, 0xcf, 0xdc, 0xcc, 0xc2, + 0x0, 0xe4, 0x0, 0x3, 0xe6, 0xba, 0x10, 0x0, + 0x8, 0xb0, 0x1, 0x7e, 0x60, 0xb, 0xc5, 0x10, + 0x7, 0x30, 0x3e, 0x91, 0x0, 0x0, 0x39, 0xe3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6F38 "漸" */ + 0x6, 0x80, 0x0, 0x68, 0x0, 0x0, 0x26, 0x90, + 0x0, 0x7b, 0x9d, 0xef, 0xdc, 0x4d, 0x85, 0x0, + 0x0, 0x0, 0x0, 0x68, 0x0, 0x49, 0x0, 0x0, + 0x0, 0x0, 0x49, 0xcd, 0x95, 0x49, 0x0, 0x0, + 0x1b, 0x10, 0x76, 0x57, 0x59, 0x4b, 0x66, 0x62, + 0x7, 0xd1, 0x75, 0x36, 0x29, 0x4d, 0x9f, 0x93, + 0x0, 0x50, 0x7d, 0xcd, 0xc9, 0x49, 0xd, 0x0, + 0x0, 0x0, 0x75, 0x36, 0x29, 0x58, 0xd, 0x0, + 0x0, 0x7, 0x7d, 0xdd, 0xc9, 0x66, 0xd, 0x0, + 0x0, 0x59, 0x0, 0x68, 0x0, 0x75, 0xd, 0x0, + 0x0, 0xb3, 0x22, 0x8a, 0x22, 0xa4, 0xd, 0x0, + 0x2, 0xc0, 0x9b, 0xdd, 0xba, 0xd0, 0xd, 0x0, + 0x9, 0x50, 0x0, 0x68, 0x4, 0xb0, 0xd, 0x0, + 0x7, 0x0, 0x0, 0x68, 0x4, 0x40, 0xd, 0x0, + + /* U+6FC3 "濃" */ + 0x6, 0xc7, 0x19, 0xdc, 0xfb, 0xbf, 0xbc, 0xb0, + 0x0, 0x3c, 0x29, 0x41, 0xd0, 0xe, 0x3, 0xb0, + 0x0, 0x0, 0x9, 0xcb, 0xfa, 0xbf, 0xac, 0xb0, + 0x0, 0x0, 0x9, 0x52, 0xe0, 0xe, 0x4, 0xb0, + 0x5b, 0x20, 0x9, 0xca, 0xfa, 0xaf, 0xab, 0xb0, + 0x7, 0xe4, 0x1, 0x22, 0x22, 0x22, 0x22, 0x10, + 0x0, 0x31, 0xc, 0xdd, 0xdd, 0xdd, 0xdd, 0xd0, + 0x0, 0x0, 0xd, 0x24, 0x44, 0x44, 0x44, 0x10, + 0x0, 0x9, 0x1e, 0x36, 0x66, 0x66, 0x66, 0x10, + 0x0, 0x3d, 0xf, 0xcc, 0xcc, 0xcc, 0xcc, 0xc2, + 0x0, 0xb5, 0x1d, 0xd, 0x11, 0xd6, 0x5, 0x80, + 0x3, 0xd0, 0x69, 0xd, 0x10, 0x3e, 0xb7, 0x0, + 0xc, 0x40, 0xc3, 0xf, 0x68, 0xa3, 0xea, 0x30, + 0x6, 0x3, 0x90, 0x2e, 0xa5, 0x10, 0x8, 0xd2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+6FDF "濟" */ + 0x1, 0x0, 0x0, 0x0, 0x17, 0x0, 0x0, 0x0, + 0xa, 0x90, 0x0, 0x0, 0xf, 0x10, 0x0, 0x0, + 0x0, 0x8a, 0x7e, 0xee, 0xef, 0xee, 0xee, 0xe2, + 0x0, 0x2, 0x0, 0x0, 0x90, 0x93, 0x2, 0x0, + 0x0, 0x0, 0x4c, 0xcc, 0x69, 0x66, 0xbc, 0x20, + 0x2b, 0x20, 0x9, 0x3a, 0x2c, 0x1c, 0xb, 0x0, + 0x4, 0xd5, 0xc, 0xb, 0x1c, 0x1c, 0x8, 0x50, + 0x0, 0x11, 0xa3, 0x9c, 0xc, 0x1e, 0xa3, 0xa0, + 0x0, 0x0, 0x2, 0xb0, 0x1, 0x0, 0x57, 0x0, + 0x0, 0x35, 0x2, 0xfb, 0xbb, 0xbb, 0xd8, 0x0, + 0x0, 0xa5, 0x3, 0xd2, 0x22, 0x22, 0x88, 0x0, + 0x1, 0xe0, 0x5, 0xc0, 0x0, 0x0, 0x68, 0x0, + 0x7, 0x80, 0x9, 0xfe, 0xee, 0xee, 0xf8, 0x0, + 0xe, 0x20, 0x2f, 0x30, 0x0, 0x0, 0x68, 0x0, + 0x17, 0x0, 0xb5, 0x0, 0x0, 0x0, 0x68, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7063 "灣" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x70, 0x19, 0x0, 0x76, 0x0, 0xa3, 0x0, + 0x0, 0xa9, 0xa4, 0x88, 0xbd, 0xa7, 0xa5, 0x50, + 0x0, 0x1, 0x6d, 0x33, 0xaa, 0x65, 0x7b, 0x0, + 0x0, 0x0, 0x78, 0xa2, 0x66, 0x42, 0xc5, 0xa0, + 0x2b, 0x22, 0xb8, 0x85, 0x55, 0x39, 0x96, 0x91, + 0x6, 0xe3, 0x55, 0x75, 0xca, 0xa5, 0x33, 0x70, + 0x0, 0x32, 0xaa, 0x69, 0x84, 0xac, 0x19, 0x90, + 0x0, 0x2, 0x44, 0x2, 0x66, 0x56, 0x6, 0x20, + 0x0, 0x12, 0xb, 0xbb, 0xbb, 0xbb, 0xcd, 0x0, + 0x0, 0x79, 0x4, 0x66, 0x66, 0x66, 0x8d, 0x0, + 0x0, 0xd3, 0xd, 0x44, 0x44, 0x44, 0x43, 0x0, + 0x4, 0xd0, 0xd, 0xbb, 0xbb, 0xbb, 0xbd, 0x60, + 0xb, 0x70, 0x0, 0x0, 0x0, 0x0, 0xe, 0x20, + 0x9, 0x10, 0x0, 0x0, 0x8, 0xcc, 0xd7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+706B "火" */ + 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7b, 0x0, 0x0, 0x0, 0x0, 0x7, + 0x60, 0x7, 0xa0, 0x0, 0x8, 0x60, 0x0, 0xd4, + 0x0, 0x89, 0x0, 0x1, 0xf3, 0x0, 0x3f, 0x0, + 0xa, 0x70, 0x0, 0x7b, 0x0, 0xc, 0x70, 0x0, + 0xda, 0x0, 0x1e, 0x30, 0x3, 0xd0, 0x0, 0x1f, + 0xf0, 0x5, 0x90, 0x0, 0x0, 0x0, 0x6, 0xda, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd6, 0x3e, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x8d, 0x0, 0xab, + 0x0, 0x0, 0x0, 0x0, 0x6f, 0x30, 0x0, 0xcb, + 0x0, 0x0, 0x1, 0x9e, 0x30, 0x0, 0x1, 0xbd, + 0x50, 0x8, 0xfa, 0x10, 0x0, 0x0, 0x0, 0x6d, + 0xe3, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0x0, + + /* U+707D "災" */ + 0x0, 0x2, 0x30, 0x0, 0x41, 0x0, 0x4, 0x0, + 0x0, 0xd, 0x60, 0x5, 0xd1, 0x0, 0xaa, 0x0, + 0x0, 0xb8, 0x0, 0x4e, 0x20, 0x8, 0xb0, 0x0, + 0x5, 0xe0, 0x0, 0xc8, 0x0, 0x4f, 0x10, 0x0, + 0x0, 0xaa, 0x0, 0x1d, 0x60, 0x8, 0xc1, 0x0, + 0x0, 0xc, 0x80, 0x2, 0xe4, 0x0, 0x8c, 0x0, + 0x0, 0x1, 0x60, 0x3, 0x51, 0x0, 0x7, 0x20, + 0x0, 0x2, 0x20, 0xc, 0x70, 0x0, 0x5, 0x0, + 0x0, 0xb, 0x60, 0xe, 0xb0, 0x0, 0x6d, 0x0, + 0x0, 0x5e, 0x0, 0x1f, 0xf0, 0x1, 0xe3, 0x0, + 0x4, 0xe2, 0x0, 0x8c, 0xc5, 0xb, 0x70, 0x0, + 0x0, 0x20, 0x1, 0xe5, 0x5e, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x2c, 0x90, 0xa, 0xb1, 0x0, 0x0, + 0x0, 0x28, 0xe8, 0x0, 0x0, 0xbe, 0x61, 0x0, + 0x1d, 0xe9, 0x20, 0x0, 0x0, 0x4, 0xbf, 0xd2, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, + + /* U+70B9 "点" */ + 0x0, 0x0, 0x0, 0x7, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0xfd, 0xdd, 0xdd, 0x70, + 0x0, 0x0, 0x0, 0x7, 0x92, 0x22, 0x22, 0x10, + 0x0, 0x0, 0x0, 0x7, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x1b, 0xbb, 0xbd, 0xeb, 0xbb, 0xb3, 0x0, + 0x0, 0x1f, 0x44, 0x44, 0x44, 0x44, 0xd5, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x0, + 0x0, 0x1f, 0x44, 0x44, 0x44, 0x44, 0xd5, 0x0, + 0x0, 0x1b, 0xbb, 0xbb, 0xbb, 0xbb, 0xb3, 0x0, + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + 0x0, 0x4d, 0x3, 0xb0, 0xd, 0x10, 0x99, 0x0, + 0x0, 0xd5, 0x1, 0xf0, 0x8, 0x80, 0xd, 0x50, + 0xa, 0xa0, 0x0, 0xf1, 0x3, 0xd0, 0x4, 0xe0, + 0x4, 0x0, 0x0, 0x30, 0x0, 0x20, 0x0, 0x20, + + /* U+70BA "為" */ + 0x0, 0x2, 0x40, 0x0, 0x81, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0x30, 0x3e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5a, 0x9, 0x90, 0x0, 0x0, 0x0, 0x8d, + 0xde, 0xed, 0xfe, 0xdd, 0xd6, 0x0, 0x1, 0x11, + 0x11, 0xaa, 0x11, 0x1c, 0x40, 0x0, 0x0, 0x0, + 0x3f, 0x20, 0x0, 0xe1, 0x0, 0x0, 0x0, 0xd, + 0xfe, 0xee, 0xef, 0xea, 0x0, 0x0, 0x8, 0xd1, + 0x0, 0x0, 0x8, 0x70, 0x0, 0x6, 0xf2, 0x0, + 0x0, 0x0, 0xb4, 0x0, 0x7, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfd, 0x1b, 0xd3, 0x0, 0x0, 0x0, + 0x31, 0x4, 0xc2, 0x90, 0xb3, 0x46, 0xd, 0x5, + 0xa0, 0x6a, 0x0, 0x2e, 0x3, 0xb0, 0x95, 0xa, + 0x19, 0x70, 0xb, 0x70, 0x1d, 0x3, 0x60, 0x0, + 0xe4, 0x1, 0x90, 0x0, 0x30, 0x0, 0x7e, 0xfa, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7121 "無" */ + 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0xdc, 0xcc, 0xcc, 0xcc, 0xcc, 0x70, + 0x3, 0xef, 0x43, 0xf3, 0x4e, 0x35, 0xe3, 0x10, + 0x1e, 0x6e, 0x10, 0xe0, 0x1d, 0x2, 0xd0, 0x0, + 0x2, 0xe, 0x10, 0xe0, 0x1d, 0x2, 0xd0, 0x0, + 0x9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, + 0x0, 0xe, 0x20, 0xe0, 0x2d, 0x2, 0xd0, 0x0, + 0x0, 0xe, 0x10, 0xe0, 0x1d, 0x2, 0xd0, 0x0, + 0x0, 0xe, 0x10, 0xe0, 0x1d, 0x2, 0xd0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, 0x21, 0x0, + 0x0, 0x98, 0x5, 0x90, 0xe, 0x10, 0x8b, 0x0, + 0x3, 0xe1, 0x3, 0xc0, 0xa, 0x70, 0xc, 0x70, + 0xd, 0x50, 0x2, 0xe0, 0x5, 0xb0, 0x3, 0xf1, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+7136 "然" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xe0, 0x0, 0x0, 0x5b, 0x66, 0x0, + 0x0, 0xb, 0xee, 0xef, 0x0, 0x5b, 0x1d, 0x50, + 0x0, 0x3d, 0x0, 0x3c, 0x0, 0x5b, 0x2, 0x40, + 0x1, 0xe5, 0xc5, 0x87, 0xff, 0xff, 0xff, 0xf1, + 0xc, 0x80, 0x1a, 0xf2, 0x0, 0x8e, 0x10, 0x0, + 0x28, 0x69, 0x9, 0x80, 0x0, 0xcf, 0x40, 0x0, + 0x0, 0x7, 0xde, 0x0, 0x3, 0xe6, 0xb0, 0x0, + 0x0, 0x5, 0xe3, 0x0, 0x1d, 0x60, 0xd3, 0x0, + 0x1, 0x8e, 0x30, 0x2, 0xca, 0x0, 0x4e, 0x20, + 0xc, 0xa1, 0x0, 0x4f, 0x80, 0x0, 0x4, 0xe1, + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x11, 0x10, + 0x0, 0x98, 0x5, 0x90, 0xe, 0x10, 0x7c, 0x0, + 0x4, 0xe0, 0x3, 0xc0, 0x9, 0x70, 0xb, 0x80, + 0x1e, 0x40, 0x2, 0xe0, 0x4, 0xc0, 0x2, 0xf1, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+7159 "煙" */ + 0x0, 0xe, 0x7, 0xff, 0xff, 0xff, 0xff, 0xf5, + 0x0, 0xe, 0x0, 0x0, 0x78, 0x9, 0x60, 0x0, + 0x0, 0xe, 0x13, 0x0, 0x78, 0x9, 0x60, 0x0, + 0x6, 0x5e, 0x57, 0xfe, 0xff, 0xef, 0xee, 0xf0, + 0x9, 0x3e, 0xa2, 0xe0, 0x68, 0x9, 0x40, 0xf0, + 0xc, 0xe, 0x80, 0xe0, 0x68, 0x9, 0x40, 0xf0, + 0x8, 0xd, 0x0, 0xfb, 0xdd, 0xbe, 0xcb, 0xf0, + 0x0, 0x1c, 0x0, 0x33, 0x33, 0x43, 0x33, 0x30, + 0x0, 0x2b, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x4e, 0x10, 0xab, 0xbc, 0xfc, 0xbb, 0x90, + 0x0, 0x88, 0x90, 0x22, 0x23, 0xf2, 0x22, 0x20, + 0x0, 0xd0, 0xb3, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x5, 0xa0, 0x42, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0xd, 0x10, 0xd, 0xee, 0xef, 0xff, 0xee, 0xe7, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+71B1 "熱" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x0, 0xd2, 0x0, 0x0, + 0x4, 0xcc, 0xfc, 0xc5, 0x0, 0xd1, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0xad, 0xfd, 0xd9, 0x0, + 0xd, 0xdd, 0xdd, 0xdc, 0x0, 0xf0, 0x4a, 0x0, + 0x0, 0x56, 0x5, 0x60, 0x42, 0xe0, 0x4a, 0x0, + 0xa, 0x91, 0x40, 0x8c, 0x6e, 0xc0, 0x3b, 0x0, + 0x2, 0x0, 0xf0, 0x2, 0x7, 0xf8, 0x3b, 0x0, + 0x7, 0xcc, 0xfc, 0xc6, 0xc, 0x5b, 0x5d, 0x3, + 0x0, 0x0, 0xf1, 0x23, 0x6d, 0x0, 0xe, 0x28, + 0x1c, 0xdd, 0xcb, 0x9b, 0xe2, 0x0, 0x8, 0xe5, + 0x2, 0x10, 0x0, 0x0, 0x20, 0x0, 0x1, 0x20, + 0x0, 0x99, 0x5, 0x80, 0xe, 0x0, 0x8b, 0x0, + 0x3, 0xe1, 0x4, 0xc0, 0xb, 0x60, 0xc, 0x90, + 0xc, 0x40, 0x2, 0xb0, 0x5, 0x70, 0x2, 0xe2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+71DF "營" */ + 0x0, 0x24, 0xb0, 0x20, 0x11, 0x4a, 0x2, 0x0, + 0x87, 0x67, 0x3d, 0x2c, 0x37, 0x72, 0xc1, 0x7, + 0xd, 0xa5, 0x13, 0x52, 0xea, 0x61, 0x1, 0x6d, + 0x66, 0xd6, 0x39, 0xe4, 0x5d, 0x70, 0x1b, 0x64, + 0x46, 0x88, 0x95, 0x44, 0x5d, 0x30, 0xd9, 0x77, + 0x77, 0x77, 0x77, 0x77, 0xe3, 0xd, 0x27, 0xaa, + 0xaa, 0xaa, 0xaa, 0xd, 0x30, 0x81, 0xb5, 0x11, + 0x11, 0x11, 0xe1, 0x82, 0x0, 0xb, 0x84, 0x44, + 0x44, 0x4e, 0x10, 0x0, 0x0, 0x45, 0x55, 0x55, + 0x55, 0x50, 0x0, 0x0, 0x6a, 0xaa, 0xaa, 0xaa, + 0xaa, 0xa2, 0x0, 0x9, 0x62, 0x22, 0x22, 0x22, + 0x2b, 0x30, 0x0, 0x94, 0x0, 0x0, 0x0, 0x0, + 0xa3, 0x0, 0x9, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, + 0x30, + + /* U+722D "爭" */ + 0x0, 0x0, 0x12, 0x34, 0x56, 0x8a, 0xcb, 0x0, + 0x2, 0xed, 0xcb, 0xba, 0x97, 0x64, 0x42, 0x0, + 0x0, 0x8, 0x40, 0xd, 0x30, 0x0, 0xd7, 0x0, + 0x0, 0x6, 0xc0, 0x9, 0x90, 0x7, 0xc0, 0x0, + 0x0, 0x0, 0x80, 0x3, 0x60, 0x1d, 0x10, 0x0, + 0x0, 0x7e, 0xee, 0xee, 0xee, 0xee, 0xe7, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x88, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x88, 0x0, + 0x1e, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xff, 0xe8, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x88, 0x0, + 0x0, 0x11, 0x11, 0x18, 0xa1, 0x11, 0x98, 0x0, + 0x0, 0x9c, 0xcc, 0xce, 0xec, 0xcc, 0xc6, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0xfe, 0x40, 0x0, 0x0, 0x0, + + /* U+7236 "父" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x5e, 0x10, 0x2, 0xe5, 0x0, 0x0, + 0x0, 0x2, 0xf5, 0x0, 0x0, 0x3f, 0x50, 0x0, + 0x0, 0x1c, 0x90, 0x0, 0x0, 0x3, 0xf5, 0x0, + 0x1, 0xdb, 0x0, 0x0, 0x0, 0x0, 0x4f, 0x30, + 0xc, 0xb0, 0x74, 0x0, 0x0, 0x4b, 0x7, 0xd0, + 0x2, 0x0, 0x6c, 0x0, 0x0, 0xb8, 0x0, 0x10, + 0x0, 0x0, 0xe, 0x40, 0x2, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0x6, 0xd1, 0xc, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xba, 0x8c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1e, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xae, 0xec, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x4e, 0xb1, 0x1b, 0xf6, 0x0, 0x0, + 0x1, 0x7d, 0xf6, 0x0, 0x0, 0x6e, 0xe9, 0x30, + 0x2f, 0xc6, 0x0, 0x0, 0x0, 0x0, 0x5b, 0xf2, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7238 "爸" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6e, 0x20, 0x0, 0xd9, 0x10, 0x0, + 0x0, 0x9, 0xf4, 0x0, 0x0, 0xd, 0xf6, 0x0, + 0x6, 0xe9, 0x5d, 0x50, 0x1, 0xca, 0x3d, 0xa0, + 0x5, 0x30, 0x1, 0xbc, 0x8e, 0x50, 0x0, 0x60, + 0x0, 0x0, 0x3, 0x9f, 0xdd, 0x60, 0x0, 0x0, + 0x0, 0x37, 0xdd, 0x71, 0x3, 0xae, 0xa6, 0x20, + 0x3f, 0xdb, 0x62, 0x22, 0x22, 0x23, 0x8b, 0xe6, + 0x1, 0xf, 0xcc, 0xcd, 0xfc, 0xcc, 0xd9, 0x0, + 0x0, 0xf, 0x0, 0x3, 0xd0, 0x0, 0x69, 0x0, + 0x0, 0xf, 0x22, 0x25, 0xd2, 0x22, 0x89, 0x0, + 0x0, 0xf, 0xcc, 0xcc, 0xcc, 0xcc, 0xc7, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32, + 0x0, 0xe, 0x30, 0x0, 0x0, 0x0, 0x1, 0xc5, + 0x0, 0x6, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xb0, + + /* U+7247 "片" */ + 0x0, 0x1f, 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, + 0x1, 0xf0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0, + 0x1f, 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, 0x1, + 0xf2, 0x22, 0x25, 0xe2, 0x22, 0x21, 0x0, 0x1f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x1, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xf4, 0x44, + 0x44, 0x44, 0x40, 0x0, 0x0, 0x4f, 0xcc, 0xcc, + 0xcc, 0xde, 0x0, 0x0, 0x7, 0xb0, 0x0, 0x0, + 0x2, 0xe0, 0x0, 0x0, 0xc6, 0x0, 0x0, 0x0, + 0x2e, 0x0, 0x0, 0x3f, 0x20, 0x0, 0x0, 0x2, + 0xe0, 0x0, 0xd, 0x90, 0x0, 0x0, 0x0, 0x2e, + 0x0, 0x1, 0xb0, 0x0, 0x0, 0x0, 0x2, 0xe0, + 0x0, + + /* U+725B "牛" */ + 0x0, 0x2, 0x50, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x80, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x63, 0x38, 0xc3, 0x33, 0x33, 0x10, + 0x0, 0x7e, 0xcc, 0xce, 0xfc, 0xcc, 0xcc, 0x30, + 0x2, 0xf2, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0xc, 0x80, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x4, 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x3, 0x33, 0x33, 0x38, 0xc3, 0x33, 0x33, 0x30, + 0x1c, 0xcc, 0xcc, 0xce, 0xfc, 0xcc, 0xcc, 0xc2, + 0x0, 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, + + /* U+7260 "牠" */ + 0x4, 0x1c, 0x30, 0x0, 0x0, 0xd1, 0x0, 0x0, + 0xc, 0x2c, 0x30, 0xd, 0x10, 0xd1, 0x0, 0x0, + 0xe, 0x1c, 0x40, 0xe, 0x10, 0xd1, 0x4, 0x50, + 0xf, 0xff, 0xfd, 0xe, 0x10, 0xd9, 0xee, 0xc0, + 0x59, 0xc, 0x30, 0xe, 0x7d, 0xf8, 0x23, 0xc0, + 0x95, 0xc, 0x33, 0xaf, 0xa3, 0xd1, 0x3, 0xc0, + 0x0, 0xc, 0x37, 0x6e, 0x10, 0xd1, 0x3, 0xb0, + 0x0, 0x4e, 0xed, 0xe, 0x10, 0xd1, 0x4, 0xb0, + 0x6f, 0xce, 0x50, 0xe, 0x10, 0xd1, 0x6, 0x90, + 0x11, 0xc, 0x30, 0xe, 0x10, 0xd1, 0xdd, 0x30, + 0x0, 0xc, 0x30, 0xe, 0x10, 0xd1, 0x0, 0x0, + 0x0, 0xc, 0x30, 0xe, 0x10, 0x10, 0x0, 0x52, + 0x0, 0xc, 0x30, 0xd, 0x30, 0x0, 0x0, 0xc4, + 0x0, 0xc, 0x30, 0x6, 0xee, 0xee, 0xef, 0xb0, + + /* U+7269 "物" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x12, 0xd0, 0x0, 0x5a, 0x0, 0x0, 0x0, + 0x4, 0xb2, 0xd0, 0x0, 0xb5, 0x0, 0x0, 0x0, + 0x6, 0x93, 0xd0, 0x1, 0xfa, 0x99, 0x99, 0x93, + 0x8, 0xff, 0xff, 0x87, 0xa5, 0xf5, 0xb9, 0xc5, + 0xd, 0x12, 0xd0, 0x1e, 0x15, 0xb0, 0xc2, 0xb4, + 0x2c, 0x2, 0xd0, 0xc6, 0xc, 0x51, 0xe0, 0xc3, + 0x2, 0x2, 0xd0, 0x40, 0x3e, 0x5, 0x90, 0xd2, + 0x0, 0x6, 0xfe, 0xb0, 0xb6, 0xc, 0x30, 0xf1, + 0x1b, 0xfc, 0xe1, 0x6, 0xc0, 0x2d, 0x0, 0xf0, + 0x5, 0x12, 0xd0, 0x5e, 0x20, 0xa6, 0x2, 0xe0, + 0x0, 0x2, 0xd0, 0x33, 0x4, 0xd0, 0x4, 0xc0, + 0x0, 0x2, 0xd0, 0x0, 0x1e, 0x40, 0x7, 0xa0, + 0x0, 0x2, 0xd0, 0x1, 0xd7, 0x1, 0x1d, 0x60, + 0x0, 0x2, 0xd0, 0x5, 0x80, 0x1f, 0xfb, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7279 "特" */ + 0x2, 0xc, 0x30, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0xb, 0x3c, 0x30, 0x1d, 0xdd, 0xfd, 0xdd, 0x40, + 0xc, 0x5d, 0x62, 0x2, 0x22, 0xe3, 0x22, 0x0, + 0xe, 0xff, 0xfc, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x1d, 0xc, 0x40, 0x44, 0x44, 0xf5, 0x44, 0x40, + 0x5a, 0xc, 0x30, 0xbb, 0xbb, 0xbb, 0xfc, 0xb0, + 0x55, 0xc, 0x30, 0x0, 0x0, 0x0, 0xf1, 0x0, + 0x0, 0xc, 0x67, 0x33, 0x33, 0x33, 0xf5, 0x30, + 0x5, 0xaf, 0xd7, 0x9b, 0xbb, 0xbb, 0xfc, 0xb0, + 0x4b, 0x6d, 0x30, 0x7, 0x30, 0x0, 0xf1, 0x0, + 0x0, 0xc, 0x30, 0x2, 0xe2, 0x0, 0xf1, 0x0, + 0x0, 0xc, 0x30, 0x0, 0x4a, 0x0, 0xf1, 0x0, + 0x0, 0xc, 0x30, 0x0, 0x0, 0x1, 0xf1, 0x0, + 0x0, 0xc, 0x30, 0x0, 0x3, 0xff, 0xb0, 0x0, + + /* U+72AC "犬" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x62, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x70, 0x4d, 0x80, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x70, 0x0, 0xaa, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x60, 0x0, 0x1, 0x0, + 0x1e, 0xee, 0xee, 0xef, 0xee, 0xee, 0xee, 0xe2, + 0x2, 0x22, 0x22, 0x3f, 0xf3, 0x22, 0x22, 0x20, + 0x0, 0x0, 0x0, 0x5e, 0xc5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa8, 0x5c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xf3, 0xe, 0x50, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xa0, 0x5, 0xe1, 0x0, 0x0, + 0x0, 0x0, 0x9e, 0x10, 0x0, 0xbc, 0x0, 0x0, + 0x0, 0x9, 0xe2, 0x0, 0x0, 0x1c, 0xc1, 0x0, + 0x5, 0xed, 0x30, 0x0, 0x0, 0x1, 0xcf, 0x70, + 0x1c, 0x60, 0x0, 0x0, 0x0, 0x0, 0x6, 0xd2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+72AF "犯" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xa0, 0x1d, 0x50, 0x11, 0x11, 0x11, 0x0, + 0x0, 0xaa, 0xc9, 0x3, 0xff, 0xff, 0xff, 0x30, + 0x0, 0x1f, 0xc0, 0x3, 0xd0, 0x0, 0xd, 0x30, + 0x2, 0xdb, 0xe0, 0x3, 0xd0, 0x0, 0xd, 0x30, + 0x1e, 0x60, 0xd4, 0x3, 0xd0, 0x0, 0xd, 0x30, + 0x1, 0x0, 0x98, 0x3, 0xd0, 0x0, 0xd, 0x30, + 0x0, 0x3, 0xfa, 0x3, 0xd0, 0x1, 0x1e, 0x30, + 0x0, 0x1e, 0xab, 0x3, 0xd0, 0x5f, 0xec, 0x0, + 0x3, 0xe7, 0x5b, 0x3, 0xd0, 0x0, 0x0, 0x0, + 0x2f, 0x60, 0x5a, 0x3, 0xd0, 0x0, 0x0, 0x0, + 0x2, 0x0, 0x69, 0x3, 0xd0, 0x0, 0x0, 0x71, + 0x0, 0x0, 0x88, 0x3, 0xd0, 0x0, 0x0, 0xd3, + 0x1, 0x2, 0xe3, 0x2, 0xf4, 0x22, 0x24, 0xf0, + 0x8, 0xfe, 0x80, 0x0, 0x9d, 0xee, 0xed, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+72B6 "状" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0xb, 0x41, 0x40, 0x0, + 0x0, 0x0, 0xf1, 0x0, 0xb, 0x40, 0xc5, 0x0, + 0xd, 0x40, 0xf1, 0x0, 0xb, 0x40, 0x1e, 0x20, + 0x2, 0xe2, 0xf1, 0x0, 0xb, 0x40, 0x2, 0x0, + 0x0, 0x67, 0xf6, 0xdd, 0xdf, 0xed, 0xdd, 0xd0, + 0x0, 0x0, 0xf2, 0x33, 0x3e, 0xa3, 0x33, 0x30, + 0x0, 0x0, 0xf1, 0x0, 0xf, 0xd0, 0x0, 0x0, + 0x0, 0x1c, 0xf1, 0x0, 0x3d, 0xd1, 0x0, 0x0, + 0x2, 0xd7, 0xf1, 0x0, 0x89, 0x88, 0x0, 0x0, + 0x2e, 0x60, 0xf1, 0x0, 0xe3, 0x2e, 0x0, 0x0, + 0x15, 0x0, 0xf1, 0x7, 0xc0, 0xa, 0x90, 0x0, + 0x0, 0x0, 0xf1, 0x2e, 0x30, 0x1, 0xe5, 0x0, + 0x0, 0x0, 0xf3, 0xe7, 0x0, 0x0, 0x4f, 0x70, + 0x0, 0x0, 0xf8, 0x80, 0x0, 0x0, 0x3, 0xc1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+72C0 "狀" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x20, 0x3c, 0x0, 0x1, 0xe0, 0xc3, 0x0, + 0xc, 0x20, 0x3c, 0x0, 0x1, 0xe0, 0x3e, 0x10, + 0xc, 0x20, 0x3c, 0x0, 0x1, 0xe0, 0x7, 0xa0, + 0xc, 0x20, 0x3c, 0x0, 0x1, 0xe0, 0x0, 0x0, + 0xc, 0xff, 0xfc, 0x9d, 0xdd, 0xfd, 0xdd, 0xd3, + 0x0, 0x0, 0x4c, 0x23, 0x35, 0xf6, 0x33, 0x30, + 0x0, 0x0, 0x3c, 0x0, 0x4, 0xf6, 0x0, 0x0, + 0x2, 0x22, 0x6c, 0x0, 0x7, 0xf9, 0x0, 0x0, + 0x3d, 0xfc, 0xdc, 0x0, 0xc, 0xbe, 0x0, 0x0, + 0x3, 0xd0, 0x3c, 0x0, 0x2f, 0x2e, 0x50, 0x0, + 0x4, 0xb0, 0x3c, 0x0, 0xbb, 0x7, 0xd0, 0x0, + 0x7, 0x80, 0x3c, 0x5, 0xf2, 0x0, 0xd9, 0x0, + 0xd, 0x20, 0x3c, 0x6f, 0x40, 0x0, 0x2f, 0xb0, + 0x15, 0x0, 0x3d, 0xc3, 0x0, 0x0, 0x2, 0xb2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+72EC "独" */ + 0x8, 0x10, 0x64, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x5, 0xc3, 0xe2, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x0, 0x8f, 0x50, 0x0, 0x2, 0xe0, 0x0, 0x0, + 0x1, 0xdf, 0x20, 0xef, 0xff, 0xff, 0xff, 0x30, + 0x1e, 0x79, 0x70, 0xe2, 0x2, 0xe0, 0xd, 0x30, + 0x2, 0x5, 0xc0, 0xe2, 0x2, 0xe0, 0xd, 0x30, + 0x0, 0x6, 0xd0, 0xe2, 0x2, 0xe0, 0xd, 0x30, + 0x0, 0x2f, 0xe0, 0xe3, 0x13, 0xe1, 0x1e, 0x30, + 0x2, 0xd6, 0xf0, 0xcd, 0xdd, 0xfd, 0xdd, 0x20, + 0x2e, 0x61, 0xe0, 0x0, 0x2, 0xe0, 0x42, 0x0, + 0x3, 0x2, 0xd0, 0x0, 0x2, 0xe0, 0x5b, 0x0, + 0x0, 0x3, 0xc0, 0x0, 0x2, 0xe1, 0x3f, 0x30, + 0x0, 0x8, 0x95, 0xab, 0xde, 0xfd, 0xcc, 0xb0, + 0xb, 0xfc, 0x24, 0x64, 0x31, 0x0, 0x1, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+72ED "狭" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x30, 0x88, 0x0, 0x1, 0xf0, 0x0, 0x0, + 0x2, 0xe8, 0xd1, 0x0, 0x2, 0xf0, 0x0, 0x0, + 0x0, 0x7f, 0x30, 0xaf, 0xff, 0xff, 0xff, 0xe0, + 0x7, 0xec, 0x60, 0x4, 0x1, 0xf0, 0x5, 0x10, + 0x2b, 0x15, 0xb0, 0xe, 0x11, 0xf0, 0xe, 0x10, + 0x0, 0x2, 0xf0, 0x8, 0x72, 0xf0, 0x79, 0x0, + 0x0, 0xb, 0xf0, 0x3, 0x63, 0xe0, 0x91, 0x0, + 0x0, 0x7b, 0xe4, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x8, 0xd0, 0xe2, 0x11, 0x19, 0xf5, 0x11, 0x10, + 0x3c, 0x10, 0xf1, 0x0, 0xe, 0x8b, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x8b, 0xc, 0x50, 0x0, + 0x0, 0x1, 0xe0, 0x7, 0xe1, 0x2, 0xe4, 0x0, + 0x0, 0x8, 0xb2, 0xbd, 0x20, 0x0, 0x4f, 0x81, + 0xb, 0xfc, 0x3b, 0x80, 0x0, 0x0, 0x2, 0xb2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+732B "猫" */ + 0x6, 0x20, 0x72, 0x3, 0xe0, 0x2, 0xb0, 0x0, + 0x3e, 0x8d, 0x10, 0x4e, 0x0, 0x3b, 0x0, 0x0, + 0x7f, 0x38, 0xef, 0xfe, 0xef, 0xfe, 0xd0, 0x3f, + 0xe4, 0x0, 0x3e, 0x0, 0x2b, 0x0, 0x2e, 0x57, + 0xa0, 0x3, 0xe0, 0x2, 0xb0, 0x0, 0x30, 0x3e, + 0x0, 0x27, 0x0, 0x26, 0x0, 0x0, 0x9, 0xf0, + 0xee, 0xee, 0xfe, 0xef, 0x40, 0x4, 0xdf, 0xe, + 0x10, 0x1e, 0x0, 0xb4, 0x5, 0xe2, 0xe1, 0xe1, + 0x1, 0xe0, 0xb, 0x42, 0xe3, 0xf, 0xe, 0xee, + 0xef, 0xee, 0xf4, 0x1, 0x0, 0xf0, 0xe2, 0x1, + 0xe0, 0xb, 0x40, 0x0, 0x2d, 0xe, 0x10, 0x1e, + 0x0, 0xb4, 0x2, 0x39, 0xa0, 0xec, 0xcc, 0xfc, + 0xcf, 0x40, 0x6c, 0xa1, 0xe, 0x42, 0x22, 0x22, + 0xb4, + + /* U+733F "猿" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x20, 0xb4, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x3, 0xd9, 0xb0, 0xbe, 0xef, 0xfe, 0xee, 0x20, + 0x0, 0x9f, 0x10, 0x0, 0x7, 0x90, 0x0, 0x0, + 0x8, 0xdd, 0x28, 0xee, 0xef, 0xfe, 0xee, 0xd0, + 0x2b, 0x18, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xc0, 0x9d, 0xcc, 0xcc, 0xde, 0x0, + 0x0, 0xc, 0xd0, 0xa5, 0x0, 0x0, 0xf, 0x0, + 0x0, 0x7e, 0xe0, 0xa6, 0x11, 0x11, 0x1f, 0x0, + 0x6, 0xe3, 0xe0, 0x7b, 0xcf, 0xfb, 0xbb, 0x0, + 0x3e, 0x32, 0xd0, 0x4, 0xd7, 0xd2, 0x7, 0x80, + 0x1, 0x2, 0xd6, 0xde, 0x60, 0x5c, 0xc7, 0x0, + 0x0, 0x4, 0xb3, 0x19, 0x50, 0xb, 0xa0, 0x0, + 0x0, 0x9, 0x80, 0xb, 0x9a, 0x90, 0xbc, 0x30, + 0xc, 0xfc, 0x10, 0x1e, 0x94, 0x0, 0x6, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7372 "獲" */ + 0x5, 0x10, 0x52, 0x0, 0xb1, 0x9, 0x80, 0x0, + 0x7, 0xc3, 0xe4, 0xcc, 0xfc, 0xce, 0xec, 0xc3, + 0x0, 0x9f, 0x40, 0x2, 0xc3, 0x49, 0x90, 0x0, + 0x3, 0xde, 0x10, 0xd, 0x63, 0xe6, 0x32, 0x20, + 0x3e, 0x47, 0x61, 0xce, 0x77, 0xe8, 0x77, 0x60, + 0x1, 0x4, 0xb7, 0x9f, 0xaa, 0xeb, 0xaa, 0x40, + 0x0, 0xc, 0xd0, 0x1e, 0x55, 0xd6, 0x55, 0x20, + 0x0, 0x6b, 0xe0, 0x1e, 0x55, 0xd7, 0x55, 0x20, + 0x3, 0xe1, 0xf0, 0x1f, 0xbb, 0xec, 0xbb, 0xb0, + 0x2f, 0x40, 0xf0, 0x7, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x1, 0xe0, 0xbf, 0xdd, 0xdd, 0xdf, 0x80, + 0x0, 0x2, 0xd0, 0x8, 0xb2, 0x4, 0xc7, 0x0, + 0x0, 0x18, 0x90, 0x0, 0x7f, 0xee, 0x51, 0x0, + 0x9, 0xfc, 0x26, 0xdc, 0x84, 0x27, 0xbe, 0xe5, + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, + + /* U+73A9 "玩" */ + 0x0, 0x0, 0x0, 0x1, 0x11, 0x11, 0x11, 0x0, + 0x3f, 0xff, 0xff, 0x3e, 0xee, 0xee, 0xee, 0xa0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0x5f, 0x43, 0x56, 0x66, 0x66, 0x66, 0x63, + 0xb, 0xcf, 0xba, 0x79, 0xeb, 0x9e, 0xb9, 0x95, + 0x0, 0x1f, 0x0, 0x0, 0xc4, 0xc, 0x30, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0xd2, 0xc, 0x30, 0x0, + 0x0, 0x1f, 0x0, 0x1, 0xf0, 0xc, 0x30, 0x0, + 0x0, 0x4f, 0xbe, 0x45, 0xb0, 0xc, 0x30, 0x0, + 0x4f, 0xc7, 0x30, 0x1e, 0x50, 0xc, 0x30, 0x39, + 0x0, 0x0, 0x3, 0xc9, 0x0, 0xc, 0x50, 0x69, + 0x0, 0x0, 0x3e, 0x60, 0x0, 0x8, 0xff, 0xf4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+73FE "現" */ + 0x0, 0x0, 0x0, 0x1, 0x11, 0x11, 0x11, 0x10, + 0x2f, 0xff, 0xff, 0x4f, 0xcc, 0xcc, 0xcd, 0xb0, + 0x0, 0xe, 0x10, 0xf, 0x0, 0x0, 0x4, 0xb0, + 0x0, 0xe, 0x10, 0xf, 0x0, 0x0, 0x4, 0xb0, + 0x0, 0xe, 0x10, 0xf, 0xdd, 0xdd, 0xde, 0xb0, + 0x2, 0x2e, 0x42, 0xf, 0x0, 0x0, 0x4, 0xb0, + 0xb, 0xbf, 0xbb, 0x1f, 0xaa, 0xaa, 0xac, 0xb0, + 0x0, 0xe, 0x10, 0xf, 0x33, 0x33, 0x37, 0xb0, + 0x0, 0xe, 0x10, 0xf, 0x0, 0x0, 0x4, 0xb0, + 0x0, 0xe, 0x10, 0xf, 0xee, 0xee, 0xef, 0xb0, + 0x0, 0xe, 0x9c, 0x60, 0xa5, 0xe, 0x10, 0x0, + 0x3b, 0xfc, 0x73, 0x0, 0xe2, 0xe, 0x10, 0x0, + 0x25, 0x10, 0x0, 0x7, 0xb0, 0xe, 0x10, 0x27, + 0x0, 0x0, 0x0, 0x8e, 0x20, 0xe, 0x10, 0x4a, + 0x0, 0x0, 0x1e, 0xa2, 0x0, 0x9, 0xfe, 0xf5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7403 "球" */ + 0x2, 0x22, 0x21, 0x0, 0x0, 0xe2, 0x94, 0x0, + 0xa, 0xaf, 0xa8, 0x0, 0x0, 0xe1, 0xa, 0x30, + 0x0, 0x1e, 0x0, 0xac, 0xcc, 0xfd, 0xcc, 0xc4, + 0x0, 0x1e, 0x0, 0x22, 0x22, 0xe4, 0x22, 0x21, + 0x0, 0x1e, 0x0, 0x35, 0x0, 0xe4, 0x1, 0xa0, + 0xd, 0xef, 0xd7, 0x1e, 0x20, 0xe7, 0xb, 0x70, + 0x1, 0x3e, 0x11, 0x6, 0xa0, 0xeb, 0x7b, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x72, 0xff, 0xd0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x2d, 0xf9, 0x80, 0x0, + 0x0, 0x1e, 0x2, 0x3, 0xe3, 0xe2, 0xe2, 0x0, + 0x0, 0x5f, 0xed, 0x5e, 0x40, 0xe1, 0x6d, 0x10, + 0x2f, 0xc7, 0x23, 0xe3, 0x0, 0xe1, 0x9, 0xd2, + 0x2, 0x0, 0x0, 0x20, 0x0, 0xf1, 0x0, 0x74, + 0x0, 0x0, 0x0, 0x1, 0xff, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7406 "理" */ + 0x1, 0x11, 0x11, 0x5f, 0xee, 0xff, 0xef, 0xe0, + 0x1e, 0xef, 0xec, 0x59, 0x0, 0xd1, 0x1, 0xe0, + 0x0, 0xf, 0x0, 0x59, 0x0, 0xd1, 0x1, 0xe0, + 0x0, 0xf, 0x0, 0x5e, 0xcc, 0xfc, 0xcc, 0xe0, + 0x0, 0xf, 0x0, 0x5a, 0x11, 0xe2, 0x13, 0xe0, + 0xd, 0xef, 0xe9, 0x59, 0x0, 0xd1, 0x1, 0xe0, + 0x1, 0x2f, 0x11, 0x5e, 0xbb, 0xfb, 0xbb, 0xe0, + 0x0, 0xf, 0x0, 0x13, 0x33, 0xf5, 0x33, 0x30, + 0x0, 0xf, 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0xf, 0x3, 0x6c, 0xcc, 0xfd, 0xcc, 0xc1, + 0x0, 0x3f, 0xed, 0x12, 0x22, 0xf5, 0x22, 0x20, + 0x1d, 0xfb, 0x50, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x8, 0x20, 0x0, 0x0, 0x0, 0xf3, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xee, 0xee, 0xee, 0xee, 0xea, + + /* U+74B0 "環" */ + 0x0, 0x0, 0x0, 0xdd, 0xde, 0xcf, 0xcd, 0x90, + 0x4e, 0xff, 0xe0, 0xd1, 0x1a, 0xc, 0x5, 0x90, + 0x0, 0x95, 0x0, 0xd2, 0x2b, 0xc, 0x6, 0x90, + 0x0, 0x95, 0x0, 0xab, 0xbb, 0xbb, 0xbb, 0x60, + 0x0, 0x95, 0x4, 0x77, 0x77, 0x77, 0x77, 0x70, + 0x19, 0xdb, 0x72, 0x55, 0x55, 0x55, 0x55, 0x50, + 0x4, 0xb8, 0x30, 0x5d, 0xdd, 0xdd, 0xdd, 0x10, + 0x0, 0x95, 0x0, 0x69, 0x0, 0x0, 0xe, 0x10, + 0x0, 0x95, 0x0, 0x6a, 0x22, 0x22, 0x2e, 0x10, + 0x0, 0x95, 0x0, 0x4a, 0xbf, 0xec, 0xaa, 0x0, + 0x0, 0x98, 0x70, 0x5, 0xc5, 0x59, 0x9, 0x90, + 0x29, 0xed, 0x88, 0xde, 0x50, 0xb, 0xd6, 0x0, + 0x47, 0x20, 0x4, 0xb, 0x52, 0x51, 0xd7, 0x0, + 0x0, 0x0, 0x0, 0x1f, 0xea, 0x60, 0x1b, 0xe2, + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x20, + + /* U+7518 "甘" */ + 0x0, 0x3, 0xe0, 0x0, 0x0, 0xe, 0x30, 0x0, + 0x0, 0x3, 0xe0, 0x0, 0x0, 0xe, 0x30, 0x0, + 0x1, 0x14, 0xe1, 0x11, 0x11, 0x1e, 0x51, 0x10, + 0x3e, 0xef, 0xfe, 0xee, 0xee, 0xef, 0xfe, 0xe3, + 0x0, 0x3, 0xe0, 0x0, 0x0, 0xe, 0x30, 0x0, + 0x0, 0x3, 0xe0, 0x0, 0x0, 0xe, 0x30, 0x0, + 0x0, 0x3, 0xe0, 0x0, 0x0, 0xe, 0x30, 0x0, + 0x0, 0x3, 0xfd, 0xdd, 0xdd, 0xdf, 0x30, 0x0, + 0x0, 0x3, 0xe2, 0x22, 0x22, 0x2e, 0x30, 0x0, + 0x0, 0x3, 0xe0, 0x0, 0x0, 0xe, 0x30, 0x0, + 0x0, 0x3, 0xe0, 0x0, 0x0, 0xe, 0x30, 0x0, + 0x0, 0x3, 0xe0, 0x0, 0x0, 0xe, 0x30, 0x0, + 0x0, 0x3, 0xff, 0xff, 0xff, 0xff, 0x30, 0x0, + 0x0, 0x3, 0xe1, 0x11, 0x11, 0x1d, 0x30, 0x0, + + /* U+751A "甚" */ + 0x0, 0x0, 0xf0, 0x0, 0x0, 0xe, 0x20, 0x0, + 0xc, 0xef, 0xff, 0xee, 0xee, 0xef, 0xfe, 0xb0, + 0x0, 0x0, 0xf0, 0x0, 0x0, 0xe, 0x20, 0x0, + 0x0, 0x0, 0xfb, 0xbb, 0xbb, 0xbf, 0x20, 0x0, + 0x0, 0x0, 0xf1, 0x11, 0x11, 0x1e, 0x20, 0x0, + 0x0, 0x0, 0xf1, 0x11, 0x11, 0x1e, 0x20, 0x0, + 0x0, 0x0, 0xfb, 0xbb, 0xbb, 0xbf, 0x20, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x0, 0xe, 0x20, 0x0, + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0x3d, 0x0, 0x18, 0x3, 0x90, 0x0, 0x0, + 0x0, 0x3d, 0x0, 0xc6, 0x0, 0x9b, 0x0, 0x0, + 0x0, 0x3d, 0xa, 0x90, 0x0, 0xa, 0xb0, 0x0, + 0x0, 0x3d, 0x28, 0x11, 0x11, 0x12, 0x51, 0x0, + 0x0, 0x3c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, + + /* U+751F "生" */ + 0x0, 0x3, 0x90, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x90, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0xf, 0x51, 0x19, 0xa1, 0x11, 0x11, 0x0, + 0x0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, + 0x3, 0xf3, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0xd, 0x70, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x2, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x4c, 0xcc, 0xce, 0xec, 0xcc, 0xca, 0x0, + 0x0, 0x13, 0x33, 0x3a, 0xb3, 0x33, 0x33, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + + /* U+7522 "產" */ + 0x0, 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0xde, 0xee, 0xee, 0xfe, 0xee, 0xee, 0x80, + 0x0, 0x0, 0x8c, 0x94, 0x1, 0x6c, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x6e, 0xff, 0xc2, 0x0, 0x0, + 0x0, 0x2, 0xbc, 0x84, 0x1, 0x6b, 0xc1, 0x0, + 0x0, 0xee, 0xfe, 0xee, 0xee, 0xee, 0xfe, 0xe1, + 0x0, 0xf0, 0x5, 0x0, 0x26, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0x3e, 0x10, 0x4c, 0x0, 0x0, 0x0, + 0x0, 0xf1, 0xcd, 0xdd, 0xdf, 0xdd, 0xdd, 0x20, + 0x1, 0xf9, 0xa0, 0x0, 0x3c, 0x0, 0x0, 0x0, + 0x2, 0xd3, 0x1d, 0xdd, 0xef, 0xdd, 0xdc, 0x0, + 0x4, 0xc0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, + 0xa, 0x70, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, + 0x3e, 0x18, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe4, + 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7523 "産" */ + 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x89, 0x0, 0x0, 0x0, 0x1, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x0, + 0x2, 0xb0, 0x0, 0x3, 0xa0, 0x0, 0x0, 0x0, + 0xb, 0x70, 0x0, 0xb7, 0x0, 0x0, 0x9, 0xbb, + 0xcc, 0xbb, 0xbf, 0xbb, 0xba, 0x0, 0xd6, 0x34, + 0x33, 0x44, 0x33, 0x33, 0x30, 0xd, 0x20, 0xc3, + 0x7, 0x90, 0x0, 0x0, 0x0, 0xe2, 0x4f, 0xdc, + 0xee, 0xcc, 0xcb, 0x0, 0xf, 0x3e, 0x30, 0x7, + 0x90, 0x0, 0x0, 0x0, 0xf3, 0x60, 0x0, 0x79, + 0x0, 0x0, 0x0, 0x2e, 0x1, 0xdd, 0xde, 0xfd, + 0xdd, 0x60, 0x6, 0xa0, 0x0, 0x0, 0x79, 0x0, + 0x0, 0x0, 0xb6, 0x0, 0x0, 0x7, 0x90, 0x0, + 0x0, 0x2e, 0x7, 0xee, 0xee, 0xff, 0xee, 0xee, + 0xe0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7528 "用" */ + 0x0, 0x1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0, + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0xb4, + 0x0, 0xe, 0x20, 0x0, 0x1e, 0x0, 0xb4, 0x0, + 0xe, 0x20, 0x0, 0x1e, 0x0, 0xbd, 0xcc, 0xcf, + 0xcc, 0xcc, 0xce, 0x0, 0xb7, 0x44, 0x4e, 0x64, + 0x44, 0x5e, 0x0, 0xb4, 0x0, 0xe, 0x20, 0x0, + 0x1e, 0x0, 0xd4, 0x0, 0xe, 0x20, 0x0, 0x1e, + 0x0, 0xef, 0xee, 0xef, 0xee, 0xee, 0xee, 0x0, + 0xf2, 0x11, 0x1e, 0x31, 0x11, 0x3e, 0x2, 0xd0, + 0x0, 0xe, 0x20, 0x0, 0x1e, 0x7, 0x90, 0x0, + 0xe, 0x20, 0x0, 0x1e, 0x1e, 0x20, 0x0, 0xe, + 0x20, 0x0, 0x2e, 0x78, 0x0, 0x0, 0xe, 0x21, + 0xff, 0xf9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+7530 "田" */ + 0x1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x3f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3d, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x2e, 0x3d, 0x0, 0x0, + 0x2e, 0x0, 0x0, 0x2e, 0x3d, 0x0, 0x0, 0x2e, + 0x0, 0x0, 0x2e, 0x3d, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x2e, 0x3f, 0xee, 0xee, 0xef, 0xee, 0xee, + 0xee, 0x3e, 0x22, 0x22, 0x5e, 0x22, 0x22, 0x5e, + 0x3d, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x2e, 0x3d, + 0x0, 0x0, 0x2e, 0x0, 0x0, 0x2e, 0x3d, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x2e, 0x3d, 0x0, 0x0, + 0x2e, 0x0, 0x0, 0x2e, 0x3f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe, 0x3e, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x4e, + + /* U+7531 "由" */ + 0x0, 0x0, 0x0, 0xc4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc4, 0x0, 0x0, 0x0, 0x1, 0x11, + 0x11, 0xd5, 0x11, 0x11, 0x10, 0x1f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf2, 0x1e, 0x0, 0x0, 0xc4, + 0x0, 0x0, 0xe2, 0x1e, 0x0, 0x0, 0xc4, 0x0, + 0x0, 0xe2, 0x1e, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0xe2, 0x1f, 0xcc, 0xcc, 0xfd, 0xcc, 0xcc, 0xf2, + 0x1f, 0x33, 0x33, 0xd7, 0x33, 0x33, 0xf2, 0x1e, + 0x0, 0x0, 0xc4, 0x0, 0x0, 0xe2, 0x1e, 0x0, + 0x0, 0xc4, 0x0, 0x0, 0xe2, 0x1e, 0x0, 0x0, + 0xc4, 0x0, 0x0, 0xe2, 0x1f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf2, 0x1e, 0x11, 0x11, 0x11, 0x11, + 0x11, 0xe2, + + /* U+7533 "申" */ + 0x0, 0x0, 0x0, 0xc5, 0x0, 0x0, 0x0, 0x1, + 0x11, 0x11, 0xc6, 0x11, 0x11, 0x10, 0x1f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf2, 0x1e, 0x0, 0x0, + 0xc5, 0x0, 0x0, 0xe2, 0x1e, 0x0, 0x0, 0xc5, + 0x0, 0x0, 0xe2, 0x1f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf2, 0x1e, 0x0, 0x0, 0xc5, 0x0, 0x0, + 0xe2, 0x1e, 0x0, 0x0, 0xc5, 0x0, 0x0, 0xe2, + 0x1e, 0x0, 0x0, 0xc6, 0x0, 0x0, 0xe2, 0x1f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0x1e, 0x0, + 0x0, 0xc5, 0x0, 0x0, 0xc2, 0x0, 0x0, 0x0, + 0xc5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x0, + 0x0, 0x0, + + /* U+7535 "电" */ + 0x0, 0x0, 0xe, 0x30, 0x0, 0x0, 0x0, 0x11, + 0x11, 0x1e, 0x41, 0x11, 0x11, 0x0, 0xef, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x0, 0xe2, 0x0, 0xe, + 0x30, 0x0, 0x2e, 0x0, 0xe2, 0x0, 0xe, 0x30, + 0x0, 0x2e, 0x0, 0xed, 0xdd, 0xdf, 0xdd, 0xdd, + 0xde, 0x0, 0xe5, 0x22, 0x2e, 0x52, 0x22, 0x5e, + 0x0, 0xe2, 0x0, 0xe, 0x30, 0x0, 0x2e, 0x0, + 0xe3, 0x11, 0x1e, 0x41, 0x11, 0x3e, 0x0, 0xef, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0xd2, 0x0, + 0xe, 0x30, 0x0, 0x0, 0x62, 0x0, 0x0, 0xe, + 0x30, 0x0, 0x0, 0xb5, 0x0, 0x0, 0xd, 0x71, + 0x11, 0x12, 0xf2, 0x0, 0x0, 0x6, 0xef, 0xff, + 0xff, 0x90, + + /* U+7537 "男" */ + 0x0, 0x8f, 0xee, 0xef, 0xfe, 0xee, 0xf8, 0x0, + 0x8, 0x80, 0x0, 0x97, 0x0, 0x8, 0x80, 0x0, + 0x88, 0x0, 0x9, 0x70, 0x0, 0x88, 0x0, 0x8, + 0xfd, 0xdd, 0xfe, 0xdd, 0xdf, 0x80, 0x0, 0x88, + 0x0, 0x9, 0x70, 0x0, 0x88, 0x0, 0x8, 0x80, + 0x0, 0x97, 0x0, 0x8, 0x80, 0x0, 0x7f, 0xff, + 0xff, 0xff, 0xff, 0xf7, 0x0, 0x0, 0x0, 0x0, + 0xf2, 0x0, 0x0, 0x0, 0xa, 0xbb, 0xbb, 0xcf, + 0xcb, 0xbb, 0xbb, 0x0, 0x33, 0x33, 0x3c, 0x93, + 0x33, 0x36, 0xf0, 0x0, 0x0, 0x4, 0xf1, 0x0, + 0x0, 0x4d, 0x0, 0x0, 0x5, 0xf4, 0x0, 0x0, + 0x7, 0xa0, 0x1, 0x6c, 0xd4, 0x0, 0x0, 0x0, + 0xc6, 0x1, 0xea, 0x50, 0x0, 0x0, 0xef, 0xfc, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+753A "町" */ + 0x22, 0x22, 0x22, 0x0, 0x0, 0x0, 0x0, 0xe, + 0xcd, 0xfc, 0xf2, 0xff, 0xff, 0xff, 0xf4, 0xe0, + 0x1c, 0xe, 0x11, 0x11, 0x2f, 0x11, 0xe, 0x1, + 0xc0, 0xe1, 0x0, 0x1, 0xf0, 0x0, 0xe0, 0x1c, + 0xe, 0x10, 0x0, 0x1f, 0x0, 0xe, 0x1, 0xc0, + 0xe1, 0x0, 0x1, 0xf0, 0x0, 0xef, 0xff, 0xff, + 0x10, 0x0, 0x1f, 0x0, 0xe, 0x1, 0xc0, 0xe1, + 0x0, 0x1, 0xf0, 0x0, 0xe0, 0x1c, 0xe, 0x10, + 0x0, 0x1f, 0x0, 0xe, 0x1, 0xc0, 0xe1, 0x0, + 0x1, 0xf0, 0x0, 0xe0, 0x1c, 0xe, 0x10, 0x0, + 0x1f, 0x0, 0xe, 0xff, 0xff, 0xf1, 0x0, 0x1, + 0xf0, 0x0, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x3f, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xfe, 0x80, + 0x0, + + /* U+753B "画" */ + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xaa, + 0xaa, 0xaa, 0xa0, 0x0, 0x27, 0xd, 0x43, 0x5e, + 0x33, 0xe0, 0x1a, 0x4c, 0xd, 0x10, 0x1d, 0x0, + 0xe0, 0x2e, 0x4c, 0xd, 0x21, 0x3d, 0x11, 0xe0, + 0x2e, 0x4c, 0xd, 0xcc, 0xcf, 0xcc, 0xf0, 0x2e, + 0x4c, 0xd, 0x10, 0x1d, 0x0, 0xe0, 0x2e, 0x4c, + 0xd, 0x10, 0x1d, 0x0, 0xe0, 0x2e, 0x4c, 0xc, + 0xee, 0xee, 0xee, 0xe0, 0x2e, 0x4c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2e, 0x4f, 0xcc, 0xcc, 0xcc, + 0xcc, 0xcc, 0xde, 0x13, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x5e, + + /* U+754C "界" */ + 0x0, 0x3f, 0xee, 0xee, 0xfe, 0xee, 0xee, 0x0, + 0x0, 0x3c, 0x0, 0x2, 0xe0, 0x0, 0x2e, 0x0, + 0x0, 0x3c, 0x0, 0x2, 0xe0, 0x0, 0x2e, 0x0, + 0x0, 0x3f, 0xdd, 0xde, 0xfd, 0xdd, 0xee, 0x0, + 0x0, 0x3c, 0x0, 0x2, 0xe0, 0x0, 0x2e, 0x0, + 0x0, 0x3f, 0xaa, 0xab, 0xfa, 0xaa, 0xbe, 0x0, + 0x0, 0x3, 0x39, 0xf6, 0x38, 0xc4, 0x33, 0x0, + 0x0, 0x0, 0x9f, 0x40, 0x0, 0x7d, 0x30, 0x0, + 0x1, 0x7e, 0xb9, 0x20, 0x0, 0x76, 0xdb, 0x50, + 0xb, 0xb3, 0xc, 0x40, 0x0, 0xd3, 0x4, 0xc7, + 0x0, 0x0, 0xe, 0x20, 0x0, 0xd3, 0x0, 0x0, + 0x0, 0x0, 0x6d, 0x0, 0x0, 0xd3, 0x0, 0x0, + 0x0, 0x7, 0xf3, 0x0, 0x0, 0xd3, 0x0, 0x0, + 0x0, 0x8c, 0x30, 0x0, 0x0, 0xd3, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7559 "留" */ + 0x0, 0x2, 0x7b, 0x10, 0x0, 0x0, 0x0, 0xa, + 0xec, 0x83, 0xf, 0xff, 0xff, 0xf7, 0x1e, 0x0, + 0x0, 0x0, 0xd, 0x0, 0xa6, 0x1e, 0x0, 0x93, + 0x0, 0x3b, 0x0, 0xb5, 0x1e, 0x0, 0x5c, 0x0, + 0x77, 0x0, 0xb4, 0x2e, 0x3, 0x7f, 0x40, 0xd2, + 0x0, 0xd3, 0x6f, 0xee, 0x99, 0xb9, 0x90, 0x23, + 0xf0, 0x48, 0x30, 0x0, 0xba, 0x0, 0xbc, 0x60, + 0x0, 0x22, 0x22, 0x33, 0x22, 0x22, 0x0, 0x3, + 0xfb, 0xbb, 0xce, 0xbb, 0xbf, 0x30, 0x3, 0xd0, + 0x0, 0x3c, 0x0, 0xd, 0x30, 0x3, 0xfd, 0xdd, + 0xef, 0xdd, 0xdf, 0x30, 0x3, 0xd0, 0x0, 0x3c, + 0x0, 0xd, 0x30, 0x3, 0xe0, 0x0, 0x4c, 0x0, + 0xe, 0x30, 0x3, 0xfd, 0xdd, 0xdd, 0xdd, 0xde, + 0x30, + + /* U+756A "番" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x12, 0x34, 0x68, 0xac, 0xe2, 0x0, + 0x0, 0xdd, 0xcb, 0xad, 0xb6, 0x45, 0x30, 0x0, + 0x0, 0x6, 0xb0, 0x9, 0x70, 0xd, 0x60, 0x0, + 0x0, 0x0, 0xc5, 0x9, 0x70, 0x7b, 0x0, 0x0, + 0xe, 0xee, 0xfe, 0xef, 0xfe, 0xff, 0xee, 0xe0, + 0x0, 0x0, 0x7, 0xdb, 0xad, 0x70, 0x0, 0x0, + 0x0, 0x1, 0xbc, 0x19, 0x71, 0xcc, 0x20, 0x0, + 0x2, 0x9e, 0x60, 0x7, 0x60, 0x6, 0xeb, 0x50, + 0x2e, 0x8e, 0xdd, 0xde, 0xdd, 0xdd, 0xe9, 0xc2, + 0x0, 0xf, 0x10, 0x8, 0x70, 0x0, 0xd3, 0x0, + 0x0, 0xf, 0xcc, 0xce, 0xec, 0xcc, 0xf3, 0x0, + 0x0, 0xf, 0x10, 0x8, 0x80, 0x0, 0xe3, 0x0, + 0x0, 0xf, 0x10, 0x8, 0x70, 0x0, 0xd3, 0x0, + 0x0, 0xf, 0xdd, 0xdd, 0xdd, 0xdd, 0xe3, 0x0, + + /* U+756B "畫" */ + 0x0, 0x4b, 0xbb, 0xbe, 0xdb, 0xbb, 0xe5, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0xb5, 0x0, + 0x1b, 0xbb, 0xbb, 0xbe, 0xdb, 0xbb, 0xed, 0xb1, + 0x0, 0x13, 0x33, 0x3a, 0x93, 0x33, 0xc5, 0x0, + 0x0, 0x36, 0x66, 0x6c, 0xb6, 0x66, 0x62, 0x0, + 0x0, 0xab, 0xbb, 0xbe, 0xdb, 0xbb, 0xbb, 0x0, + 0x1, 0x11, 0x11, 0x1a, 0x81, 0x11, 0x11, 0x10, + 0x19, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x91, + 0x0, 0x3a, 0xaa, 0xaa, 0xaa, 0xaa, 0xa4, 0x0, + 0x0, 0x5b, 0x22, 0x2a, 0x82, 0x22, 0xb6, 0x0, + 0x0, 0x5d, 0x77, 0x7c, 0xb7, 0x77, 0xd6, 0x0, + 0x0, 0x5e, 0xaa, 0xad, 0xca, 0xaa, 0xe6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc2, + + /* U+7570 "異" */ + 0x0, 0x8e, 0xdd, 0xdf, 0xed, 0xdd, 0xe9, 0x0, + 0x0, 0x87, 0x0, 0x9, 0x70, 0x0, 0x79, 0x0, + 0x0, 0x88, 0x22, 0x2a, 0x92, 0x22, 0x89, 0x0, + 0x0, 0x8d, 0xaa, 0xad, 0xda, 0xaa, 0xc9, 0x0, + 0x0, 0x87, 0x0, 0x9, 0x70, 0x0, 0x79, 0x0, + 0x0, 0x7d, 0xef, 0xdd, 0xdd, 0xfe, 0xd8, 0x0, + 0x0, 0x0, 0x3d, 0x0, 0x0, 0xd4, 0x0, 0x0, + 0x1, 0xcc, 0xdf, 0xcc, 0xcc, 0xfd, 0xcc, 0x20, + 0x0, 0x22, 0x6d, 0x22, 0x22, 0xd6, 0x22, 0x0, + 0x0, 0x0, 0x3d, 0x0, 0x0, 0xd4, 0x0, 0x0, + 0x1d, 0xdd, 0xef, 0xdd, 0xdd, 0xfe, 0xdd, 0xd2, + 0x1, 0x11, 0x18, 0x41, 0x13, 0x93, 0x11, 0x10, + 0x0, 0x39, 0xe9, 0x20, 0x1, 0x7d, 0xc6, 0x0, + 0xa, 0xc7, 0x10, 0x0, 0x0, 0x0, 0x4b, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7576 "當" */ + 0x2, 0xb1, 0x0, 0xf1, 0x0, 0x3c, 0x10, 0x0, + 0x7b, 0x0, 0xf1, 0x1, 0xe4, 0x0, 0xcf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0xd2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4c, 0xd2, 0x1d, 0xdd, 0xdd, + 0xdd, 0xd0, 0x4c, 0x40, 0x1e, 0x0, 0x0, 0x0, + 0xf0, 0x13, 0x0, 0x1f, 0x66, 0x66, 0x66, 0xf0, + 0x0, 0x0, 0x6, 0x66, 0x66, 0x66, 0x60, 0x0, + 0x8, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x90, 0xb, + 0x82, 0x22, 0xe4, 0x22, 0x27, 0xd0, 0xb, 0x60, + 0x0, 0xe2, 0x0, 0x6, 0xd0, 0xb, 0xdc, 0xcc, + 0xfc, 0xcc, 0xcd, 0xd0, 0xb, 0x60, 0x0, 0xe1, + 0x0, 0x6, 0xd0, 0xb, 0xed, 0xdd, 0xfd, 0xdd, + 0xde, 0xc0, + + /* U+75B2 "疲" */ + 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x5, 0xf, 0x0, 0x0, 0x7, 0x20, 0x0, 0x0, + 0xe, 0x1f, 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, + 0x9, 0x6f, 0x3, 0xff, 0xff, 0xff, 0xff, 0xa0, + 0x5, 0x7f, 0x3, 0xb0, 0xb, 0x40, 0xc, 0x40, + 0x0, 0xf, 0x4, 0xb0, 0xb, 0x40, 0x8, 0x0, + 0x0, 0x5e, 0x4, 0xfe, 0xef, 0xee, 0xe7, 0x0, + 0x2c, 0xcd, 0x5, 0xa8, 0x60, 0x0, 0xd2, 0x0, + 0x24, 0x5b, 0x7, 0x71, 0xd0, 0x8, 0xa0, 0x0, + 0x0, 0x98, 0xb, 0x40, 0x7a, 0x6d, 0x10, 0x0, + 0x0, 0xd2, 0x1f, 0x0, 0xe, 0xf3, 0x0, 0x0, + 0x6, 0xc0, 0xa9, 0x5, 0xda, 0x7e, 0x93, 0x0, + 0xc, 0x22, 0xd0, 0xcb, 0x40, 0x1, 0x7c, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+75C5 "病" */ + 0x0, 0x0, 0x0, 0x0, 0x73, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0, 0x0, + 0x0, 0xb, 0xcc, 0xcc, 0xef, 0xcc, 0xcc, 0xc4, + 0x2, 0xe, 0x42, 0x22, 0x22, 0x22, 0x22, 0x21, + 0x1d, 0xe, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x5e, 0x5e, 0xee, 0xef, 0xee, 0xee, 0xe3, + 0x5, 0xae, 0x10, 0x0, 0xd, 0x10, 0x0, 0x0, + 0x0, 0xe, 0x13, 0x33, 0x3e, 0x53, 0x33, 0x20, + 0x0, 0xe, 0xe, 0xcb, 0xbf, 0xcb, 0xbc, 0xb0, + 0x6, 0xdf, 0xe, 0x10, 0x1f, 0x10, 0x4, 0xb0, + 0x69, 0x5c, 0xe, 0x10, 0x8b, 0xd3, 0x4, 0xb0, + 0x0, 0x78, 0xe, 0x17, 0xd0, 0x2d, 0x54, 0xb0, + 0x0, 0xd2, 0xe, 0x69, 0x0, 0x1, 0x94, 0xb0, + 0x7, 0xa0, 0xe, 0x10, 0x0, 0x0, 0x5, 0xb0, + 0xb, 0x10, 0xe, 0x10, 0x0, 0x7, 0xee, 0x60, + + /* U+75DB "痛" */ + 0x0, 0x0, 0x0, 0x1, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe4, 0x0, 0x0, 0x0, + 0x0, 0xd, 0xdd, 0xdd, 0xef, 0xdd, 0xdd, 0xd2, + 0x3, 0xf, 0x21, 0x11, 0x11, 0x11, 0x11, 0x10, + 0x1e, 0xf, 0x7, 0xcc, 0xcc, 0xcd, 0xf7, 0x0, + 0xa, 0x6f, 0x0, 0x18, 0x30, 0x6d, 0x70, 0x0, + 0x4, 0x6f, 0x0, 0x4, 0xae, 0xe2, 0x0, 0x0, + 0x0, 0xf, 0xc, 0xdd, 0xde, 0xff, 0xdd, 0x30, + 0x0, 0x6f, 0xe, 0x10, 0xe, 0x10, 0xc, 0x30, + 0x4e, 0xad, 0xe, 0xcb, 0xbf, 0xcb, 0xbf, 0x30, + 0x33, 0x5b, 0xe, 0x21, 0x1e, 0x21, 0x1c, 0x30, + 0x0, 0x97, 0xe, 0x10, 0xe, 0x10, 0xc, 0x30, + 0x0, 0xe1, 0xe, 0xcc, 0xcf, 0xcc, 0xcf, 0x30, + 0x8, 0xa0, 0xe, 0x10, 0xe, 0x10, 0xc, 0x30, + 0xa, 0x10, 0xe, 0x10, 0xc, 0x16, 0xcd, 0x10, + + /* U+767A "発" */ + 0x0, 0x0, 0x0, 0x0, 0x71, 0x1, 0x40, 0x0, + 0x3, 0xff, 0xff, 0xf2, 0x88, 0x1d, 0x60, 0x0, + 0x0, 0x30, 0x7, 0xb0, 0x1e, 0xd4, 0x4, 0x40, + 0x1, 0xd7, 0x2f, 0x20, 0x7, 0xc0, 0x5d, 0x20, + 0x0, 0x1c, 0xf6, 0x0, 0x0, 0xac, 0xc1, 0x0, + 0x0, 0x3e, 0x70, 0x0, 0x0, 0xc, 0xb1, 0x0, + 0x18, 0xed, 0xee, 0xee, 0xee, 0xee, 0xce, 0x60, + 0x7a, 0x11, 0x1e, 0x51, 0x1d, 0x51, 0x5, 0xc1, + 0x0, 0x0, 0xd, 0x30, 0xd, 0x40, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x40, 0xd, 0x40, 0x0, 0x0, + 0x9, 0xee, 0xef, 0xfe, 0xef, 0xfe, 0xee, 0x20, + 0x0, 0x0, 0x2f, 0x0, 0xd, 0x40, 0x0, 0x0, + 0x0, 0x0, 0xc8, 0x0, 0xd, 0x40, 0x6, 0x40, + 0x0, 0x3d, 0xb0, 0x0, 0xd, 0x50, 0xa, 0x60, + 0x9, 0xd6, 0x0, 0x0, 0x8, 0xff, 0xfd, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+767C "發" */ + 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x51, 0x0, + 0x0, 0x7e, 0xee, 0xf5, 0x6a, 0x9, 0xb1, 0x0, + 0x0, 0x73, 0x4, 0xc0, 0xb, 0xe7, 0x1, 0xc1, + 0x0, 0x3e, 0x8e, 0x30, 0x1, 0xba, 0x4d, 0x40, + 0x0, 0x8, 0xe2, 0x0, 0x0, 0x8, 0xf7, 0x0, + 0x6, 0xdf, 0xdc, 0xa0, 0xad, 0xdd, 0xdc, 0xe6, + 0x8, 0x21, 0x13, 0xd0, 0xd2, 0x2, 0xc0, 0x32, + 0x0, 0x1, 0x13, 0xd0, 0xe0, 0x1, 0xd0, 0x0, + 0x0, 0x7d, 0xcc, 0xab, 0x90, 0x0, 0xcc, 0xc1, + 0x0, 0x94, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc3, 0x0, 0x7, 0xee, 0xee, 0xee, 0x0, + 0x0, 0xbc, 0xcd, 0xc3, 0x81, 0x0, 0xa7, 0x0, + 0x0, 0x0, 0x4, 0xa0, 0x4c, 0x8a, 0xa0, 0x0, + 0x0, 0x0, 0x8, 0x80, 0x39, 0xed, 0x91, 0x0, + 0x0, 0x4e, 0xed, 0x2c, 0xc7, 0x0, 0x6d, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+767D "白" */ + 0x0, 0x0, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd5, 0x0, + 0x0, 0x0, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0xd4, 0x11, 0x11, 0x11, 0x11, 0xe3, 0xd3, 0x0, + 0x0, 0x0, 0x0, 0xd3, 0xd3, 0x0, 0x0, 0x0, + 0x0, 0xd3, 0xd3, 0x0, 0x0, 0x0, 0x0, 0xd3, + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xd4, 0x11, + 0x11, 0x11, 0x11, 0xe3, 0xd3, 0x0, 0x0, 0x0, + 0x0, 0xd3, 0xd3, 0x0, 0x0, 0x0, 0x0, 0xd3, + 0xd3, 0x0, 0x0, 0x0, 0x0, 0xe3, 0xdf, 0xff, + 0xff, 0xff, 0xff, 0xf3, 0xd4, 0x0, 0x0, 0x0, + 0x0, 0xd3, + + /* U+767E "百" */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x0, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0xf0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x50, 0x1, 0xf0, 0x0, 0x0, 0x0, + 0xc, 0x50, 0x1, 0xf0, 0x0, 0x0, 0x0, 0xc, + 0x50, 0x1, 0xf0, 0x0, 0x0, 0x0, 0xc, 0x50, + 0x1, 0xfe, 0xee, 0xee, 0xee, 0xef, 0x50, 0x1, + 0xf0, 0x0, 0x0, 0x0, 0xc, 0x50, 0x1, 0xf0, + 0x0, 0x0, 0x0, 0xc, 0x50, 0x1, 0xf0, 0x0, + 0x0, 0x0, 0xc, 0x50, 0x1, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x50, 0x1, 0xf0, 0x0, 0x0, 0x0, + 0xc, 0x50, + + /* U+7684 "的" */ + 0x0, 0x26, 0x0, 0x0, 0x52, 0x0, 0x0, 0x0, + 0x8a, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0xc4, + 0x0, 0x2, 0xe0, 0x0, 0x0, 0xcf, 0xff, 0xfd, + 0x7, 0xff, 0xff, 0xf5, 0xc3, 0x0, 0x1e, 0xe, + 0x30, 0x0, 0xa5, 0xc3, 0x0, 0x1e, 0x6c, 0x0, + 0x0, 0xb4, 0xc3, 0x0, 0x1e, 0xa4, 0x0, 0x0, + 0xb4, 0xc5, 0x22, 0x3e, 0x1, 0xe1, 0x0, 0xc3, + 0xcd, 0xcc, 0xde, 0x0, 0x8b, 0x0, 0xd2, 0xc3, + 0x0, 0x1e, 0x0, 0xd, 0x40, 0xe1, 0xc3, 0x0, + 0x1e, 0x0, 0x4, 0xb0, 0xf0, 0xc3, 0x0, 0x1e, + 0x0, 0x0, 0x0, 0xf0, 0xc5, 0x22, 0x4e, 0x0, + 0x0, 0x2, 0xd0, 0xcd, 0xcc, 0xcb, 0x0, 0x0, + 0x7, 0xa0, 0xc3, 0x0, 0x0, 0x0, 0x4e, 0xef, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, + + /* U+7686 "皆" */ + 0x3e, 0x0, 0x0, 0x1e, 0x0, 0x2, 0x0, 0x3f, + 0xbb, 0xb8, 0x1e, 0x27, 0xcb, 0x10, 0x3f, 0x33, + 0x32, 0x1f, 0xb7, 0x10, 0x0, 0x3e, 0x0, 0x0, + 0x1e, 0x0, 0x0, 0x40, 0x4e, 0x36, 0xac, 0x1f, + 0x0, 0x0, 0xe1, 0xbf, 0xc8, 0x54, 0x1d, 0xed, + 0xde, 0xb0, 0x20, 0x0, 0xf, 0x30, 0x1, 0x11, + 0x0, 0x9, 0xbb, 0xcf, 0xbb, 0xbb, 0xb2, 0x0, + 0xd, 0x53, 0x33, 0x33, 0x33, 0xf3, 0x0, 0xd, + 0x20, 0x0, 0x0, 0x0, 0xe3, 0x0, 0xd, 0xed, + 0xdd, 0xdd, 0xdd, 0xf3, 0x0, 0xd, 0x20, 0x0, + 0x0, 0x0, 0xe3, 0x0, 0xd, 0x30, 0x0, 0x0, + 0x0, 0xe3, 0x0, 0xd, 0xee, 0xee, 0xee, 0xee, + 0xf3, 0x0, + + /* U+76BF "皿" */ + 0x0, 0x7e, 0xee, 0xee, 0xee, 0xee, 0xee, 0x10, + 0x0, 0x7a, 0x22, 0xf2, 0x29, 0x92, 0x2f, 0x10, + 0x0, 0x78, 0x0, 0xf0, 0x8, 0x70, 0xf, 0x10, + 0x0, 0x78, 0x0, 0xf0, 0x8, 0x70, 0xf, 0x10, + 0x0, 0x78, 0x0, 0xf0, 0x8, 0x70, 0xf, 0x10, + 0x0, 0x78, 0x0, 0xf0, 0x8, 0x70, 0xf, 0x10, + 0x0, 0x78, 0x0, 0xf0, 0x8, 0x70, 0xf, 0x10, + 0x0, 0x78, 0x0, 0xf0, 0x8, 0x70, 0xf, 0x10, + 0x0, 0x78, 0x0, 0xf0, 0x8, 0x70, 0xf, 0x10, + 0x0, 0x78, 0x0, 0xf0, 0x8, 0x70, 0xf, 0x10, + 0x0, 0x78, 0x0, 0xf0, 0x8, 0x70, 0xf, 0x10, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, + 0x1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + + /* U+76D7 "盗" */ + 0x0, 0x0, 0x0, 0x4, 0x40, 0x0, 0x0, 0x0, + 0x5, 0xd6, 0x0, 0xd, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x3c, 0xb0, 0x5f, 0xee, 0xee, 0xee, 0xd0, + 0x0, 0x0, 0x11, 0xe4, 0x6, 0xb0, 0x6, 0xb0, + 0x0, 0x0, 0x9, 0x80, 0xa, 0xd0, 0xc, 0x50, + 0x0, 0x0, 0x42, 0x0, 0x1f, 0xd4, 0x6, 0x0, + 0x0, 0x9, 0xe2, 0x0, 0xaa, 0x3d, 0x0, 0x0, + 0x4, 0xea, 0x10, 0x1b, 0xd1, 0x8, 0xd3, 0x0, + 0xd, 0x50, 0x1b, 0xf9, 0x0, 0x0, 0x6e, 0xd2, + 0x0, 0x3, 0x3a, 0x53, 0x33, 0x33, 0x32, 0x40, + 0x0, 0x2f, 0xaa, 0xfb, 0xae, 0xca, 0xca, 0x0, + 0x0, 0x2c, 0x0, 0xe0, 0xa, 0x40, 0x6a, 0x0, + 0x0, 0x2c, 0x0, 0xe0, 0xa, 0x40, 0x6a, 0x0, + 0x0, 0x2c, 0x0, 0xe0, 0xa, 0x40, 0x6a, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, + + /* U+76EE "目" */ + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf5, 0x3d, 0x0, + 0x0, 0x0, 0x0, 0xc5, 0x3d, 0x0, 0x0, 0x0, + 0x0, 0xc5, 0x3d, 0x0, 0x0, 0x0, 0x0, 0xc5, + 0x3f, 0xdd, 0xdd, 0xdd, 0xdd, 0xf5, 0x3e, 0x33, + 0x33, 0x33, 0x33, 0xd5, 0x3d, 0x0, 0x0, 0x0, + 0x0, 0xc5, 0x3d, 0x0, 0x0, 0x0, 0x0, 0xc5, + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf5, 0x3d, 0x0, + 0x0, 0x0, 0x0, 0xc5, 0x3d, 0x0, 0x0, 0x0, + 0x0, 0xc5, 0x3d, 0x0, 0x0, 0x0, 0x0, 0xc5, + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf5, 0x3d, 0x0, + 0x0, 0x0, 0x0, 0xc5, + + /* U+76F4 "直" */ + 0x0, 0x0, 0x0, 0x3, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xdd, 0xdf, 0xdd, 0xdd, 0xd3, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0xd3, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x0, 0xd3, 0x0, + 0x0, 0xb, 0xdc, 0xcc, 0xcc, 0xcc, 0xf3, 0x0, + 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, 0xd3, 0x0, + 0x0, 0xb, 0xed, 0xdd, 0xdd, 0xdd, 0xf3, 0x0, + 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, 0xd3, 0x0, + 0x0, 0xb, 0xed, 0xdd, 0xdd, 0xdd, 0xf3, 0x0, + 0x0, 0xb, 0x40, 0x0, 0x0, 0x0, 0xd3, 0x0, + 0x2, 0x2c, 0x62, 0x22, 0x22, 0x22, 0xe5, 0x21, + 0x1d, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xd6, + + /* U+76F8 "相" */ + 0x0, 0x7, 0x80, 0x5, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0x78, 0x0, 0x5b, 0x0, 0x0, 0x2e, 0x4, + 0x49, 0xb4, 0x45, 0xb0, 0x0, 0x2, 0xe1, 0xcc, + 0xee, 0xcb, 0x5b, 0x0, 0x0, 0x2e, 0x0, 0xd, + 0x80, 0x5, 0xfd, 0xdd, 0xdd, 0xe0, 0x3, 0xfb, + 0x0, 0x5b, 0x22, 0x22, 0x4e, 0x0, 0x8d, 0xf9, + 0x5, 0xb0, 0x0, 0x2, 0xe0, 0xd, 0x79, 0xb7, + 0x5b, 0x0, 0x0, 0x2e, 0x7, 0x97, 0x81, 0x95, + 0xfe, 0xee, 0xee, 0xe1, 0xe1, 0x78, 0x0, 0x5b, + 0x0, 0x0, 0x2e, 0x38, 0x7, 0x80, 0x5, 0xb0, + 0x0, 0x2, 0xe0, 0x0, 0x78, 0x0, 0x5b, 0x0, + 0x0, 0x2e, 0x0, 0x7, 0x80, 0x5, 0xfe, 0xee, + 0xef, 0xe0, 0x0, 0x78, 0x0, 0x5b, 0x0, 0x0, + 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+770B "看" */ + 0x0, 0x0, 0x0, 0x1, 0x13, 0x46, 0x96, 0x0, + 0x0, 0xdd, 0xee, 0xef, 0xba, 0x97, 0x52, 0x0, + 0x0, 0x0, 0x0, 0x99, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0xcc, 0xfd, 0xcc, 0xcc, 0xcc, 0x10, + 0x0, 0x11, 0x15, 0xe1, 0x11, 0x11, 0x11, 0x0, + 0x2, 0x22, 0x29, 0xb2, 0x22, 0x22, 0x22, 0x20, + 0xb, 0xbb, 0xcf, 0xbb, 0xbb, 0xbb, 0xbb, 0xb0, + 0x0, 0x0, 0xc9, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0xfd, 0xcc, 0xcc, 0xcc, 0xe7, 0x0, + 0x0, 0x7d, 0xe3, 0x0, 0x0, 0x0, 0x97, 0x0, + 0x1b, 0xc1, 0xdc, 0xbb, 0xbb, 0xbb, 0xe7, 0x0, + 0x19, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x97, 0x0, + 0x0, 0x0, 0xdc, 0xbb, 0xbb, 0xbb, 0xe7, 0x0, + 0x0, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x97, 0x0, + 0x0, 0x0, 0xde, 0xdd, 0xdd, 0xdd, 0xf7, 0x0, + + /* U+771F "真" */ + 0x0, 0x0, 0x0, 0x3, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x9, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xa0, + 0x0, 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xdc, 0xcc, 0xcc, 0xcd, 0xc0, 0x0, + 0x0, 0xc, 0x40, 0x0, 0x0, 0x3, 0xc0, 0x0, + 0x0, 0xc, 0xcb, 0xbb, 0xbb, 0xbc, 0xc0, 0x0, + 0x0, 0xc, 0x85, 0x55, 0x55, 0x58, 0xc0, 0x0, + 0x0, 0xc, 0x85, 0x55, 0x55, 0x57, 0xc0, 0x0, + 0x0, 0xc, 0xcb, 0xbb, 0xbb, 0xbc, 0xc0, 0x0, + 0x0, 0xc, 0x40, 0x0, 0x0, 0x3, 0xc0, 0x0, + 0x1e, 0xef, 0xee, 0xee, 0xee, 0xee, 0xfe, 0xe1, + 0x0, 0x0, 0x17, 0x10, 0x1, 0x82, 0x0, 0x0, + 0x0, 0x39, 0xe8, 0x10, 0x0, 0x6c, 0xd6, 0x0, + 0xb, 0xc6, 0x10, 0x0, 0x0, 0x0, 0x3b, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7720 "眠" */ + 0xef, 0xff, 0x21, 0xff, 0xff, 0xff, 0xf2, 0xe, + 0x10, 0xd2, 0x1e, 0x0, 0x0, 0xe, 0x20, 0xe1, + 0xd, 0x21, 0xe0, 0x0, 0x0, 0xe2, 0xe, 0x10, + 0xd2, 0x1e, 0x44, 0x44, 0x4e, 0x20, 0xef, 0xff, + 0x21, 0xfc, 0xcf, 0xdc, 0xc2, 0xe, 0x10, 0xd2, + 0x1e, 0x0, 0xb4, 0x0, 0x0, 0xe1, 0xd, 0x21, + 0xe0, 0x9, 0x50, 0x0, 0xe, 0xff, 0xf2, 0x1f, + 0xff, 0xff, 0xff, 0xf5, 0xe1, 0xd, 0x21, 0xe0, + 0x3, 0x90, 0x0, 0xe, 0x10, 0xd2, 0x1e, 0x0, + 0xb, 0x0, 0x0, 0xe3, 0x2e, 0x21, 0xe0, 0x0, + 0xc0, 0x0, 0xe, 0xdc, 0xc1, 0x1e, 0x0, 0x7, + 0x50, 0xa5, 0x50, 0x0, 0x5, 0xfc, 0xd9, 0x1c, + 0x3e, 0x60, 0x0, 0x0, 0xeb, 0x50, 0x0, 0x3d, + 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+773E "眾" */ + 0x1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, + 0x1, 0xe0, 0x1, 0xe0, 0x3, 0xb0, 0xc, 0x40, + 0x1, 0xe0, 0x1, 0xe0, 0x3, 0xb0, 0xc, 0x40, + 0x1, 0xfc, 0xcc, 0xfc, 0xcd, 0xfc, 0xcf, 0x40, + 0x0, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x12, 0x35, 0x78, 0x10, + 0x2, 0xef, 0xff, 0xfe, 0xfb, 0xa9, 0x74, 0x10, + 0x0, 0x0, 0x42, 0x1, 0xf0, 0x0, 0x80, 0x0, + 0x0, 0x0, 0xf2, 0x1, 0xf0, 0x4, 0xa0, 0x0, + 0x0, 0x7, 0xf2, 0x1, 0xf0, 0xa, 0xa0, 0x0, + 0x0, 0x2e, 0x6d, 0x51, 0xf0, 0x3d, 0xb5, 0x0, + 0x3, 0xd6, 0x1, 0xc3, 0xf2, 0xd4, 0x1d, 0x70, + 0x1d, 0x40, 0x0, 0x1, 0xfa, 0x50, 0x1, 0xa0, + 0x0, 0x0, 0x0, 0x1, 0xf0, 0x0, 0x0, 0x0, + + /* U+7740 "着" */ + 0x0, 0x0, 0x72, 0x0, 0x0, 0x28, 0x0, 0x0, + 0x0, 0x6, 0xd0, 0x0, 0xb, 0x80, 0x0, 0x2, + 0xcc, 0xcf, 0xcc, 0xcc, 0xfc, 0xcc, 0x20, 0x1, + 0x11, 0x16, 0xd1, 0x11, 0x11, 0x10, 0x0, 0x5a, + 0xaa, 0xdd, 0xaa, 0xaa, 0xa5, 0x0, 0x1, 0x22, + 0x5e, 0x22, 0x22, 0x22, 0x10, 0x9, 0xaa, 0xad, + 0xea, 0xaa, 0xaa, 0xaa, 0x90, 0x33, 0x39, 0xd3, + 0x33, 0x33, 0x33, 0x33, 0x0, 0x2, 0xfd, 0xaa, + 0xaa, 0xaa, 0xa4, 0x0, 0x0, 0xdf, 0x72, 0x22, + 0x22, 0x2c, 0x60, 0x2, 0xd9, 0xad, 0xbb, 0xbb, + 0xbb, 0xe6, 0x2, 0xe8, 0xa, 0x50, 0x0, 0x0, + 0xb, 0x60, 0x5, 0x0, 0xad, 0xbb, 0xbb, 0xbb, + 0xe6, 0x0, 0x0, 0xa, 0x50, 0x0, 0x0, 0xb, + 0x60, 0x0, 0x0, 0xae, 0xdd, 0xdd, 0xdd, 0xe6, + 0x0, + + /* U+77E5 "知" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xf2, 0x0, 0x0, 0x5d, 0xdd, 0xdd, 0x20, 0x6f, + 0xff, 0xff, 0x96, 0xa2, 0x22, 0xe2, 0xd, 0x40, + 0xf0, 0x0, 0x69, 0x0, 0xe, 0x26, 0xc0, 0xf, + 0x0, 0x6, 0x90, 0x0, 0xe2, 0x1, 0x1, 0xf0, + 0x0, 0x69, 0x0, 0xe, 0x26, 0xff, 0xff, 0xff, + 0xf7, 0x90, 0x0, 0xe2, 0x0, 0x4, 0xd0, 0x0, + 0x69, 0x0, 0xe, 0x20, 0x0, 0x5e, 0x20, 0x6, + 0x90, 0x0, 0xe2, 0x0, 0xa, 0xae, 0x20, 0x69, + 0x0, 0xe, 0x20, 0x1, 0xe0, 0x6e, 0x16, 0x90, + 0x0, 0xe2, 0x0, 0xa8, 0x0, 0x8c, 0x6e, 0xbb, + 0xbf, 0x20, 0x8e, 0x10, 0x0, 0x36, 0xb4, 0x44, + 0xf2, 0x5e, 0x30, 0x0, 0x0, 0x69, 0x0, 0xc, + 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+77ED "短" */ + 0x0, 0x72, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd2, 0x0, 0xb, 0xff, 0xff, 0xff, 0xf8, + 0x1, 0xf7, 0x77, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xec, 0xea, 0x70, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x65, 0xa0, 0x2, 0xee, 0xee, 0xee, 0xd0, + 0xe, 0x5, 0xa0, 0x2, 0xe0, 0x0, 0x2, 0xe0, + 0x2, 0x6, 0xb0, 0x2, 0xd0, 0x0, 0x2, 0xe0, + 0x1e, 0xef, 0xfe, 0xd2, 0xd0, 0x0, 0x2, 0xe0, + 0x0, 0x7, 0x80, 0x2, 0xfe, 0xee, 0xef, 0xe0, + 0x0, 0x9, 0xa0, 0x0, 0x11, 0x0, 0x3, 0x10, + 0x0, 0xd, 0xd5, 0x0, 0x78, 0x0, 0xe, 0x40, + 0x0, 0x3d, 0x2e, 0x10, 0x1e, 0x0, 0x3e, 0x0, + 0x0, 0xb6, 0x8, 0x90, 0xd, 0x30, 0x97, 0x0, + 0x6, 0xd0, 0x0, 0x20, 0x5, 0x30, 0xe1, 0x0, + 0xd, 0x20, 0x0, 0x6f, 0xff, 0xff, 0xff, 0xfb, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+77F3 "石" */ + 0x1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0x7, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x0, 0x5, 0xef, 0x11, + 0x11, 0x11, 0x13, 0xf0, 0x4, 0xe3, 0xf0, 0x0, + 0x0, 0x0, 0x2f, 0x4, 0xe3, 0xf, 0x0, 0x0, + 0x0, 0x2, 0xf0, 0x3, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x2f, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, + 0x2, 0xf0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0, 0x0, 0xf, 0x11, 0x11, 0x11, 0x13, + 0xf0, + + /* U+7802 "砂" */ + 0x1f, 0xff, 0xff, 0xb0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0xe1, 0x11, 0x0, + 0x0, 0x5a, 0x0, 0x2, 0xc0, 0xe1, 0x79, 0x0, + 0x0, 0x96, 0x0, 0x5, 0x90, 0xe1, 0x1e, 0x10, + 0x0, 0xd2, 0x0, 0x7, 0x70, 0xe1, 0x9, 0x70, + 0x3, 0xfd, 0xdd, 0x3c, 0x30, 0xe1, 0x4, 0xd0, + 0xa, 0xf3, 0x2b, 0x5e, 0x0, 0xe1, 0x0, 0x70, + 0x3e, 0xe1, 0xb, 0x45, 0x0, 0xe1, 0x5, 0x10, + 0x55, 0xd1, 0xb, 0x40, 0x0, 0xe1, 0x3e, 0x0, + 0x0, 0xd1, 0xb, 0x40, 0x0, 0xd1, 0xc6, 0x0, + 0x0, 0xd1, 0xb, 0x40, 0x0, 0xb, 0xa0, 0x0, + 0x0, 0xde, 0xef, 0x40, 0x3, 0xcb, 0x0, 0x0, + 0x0, 0xd2, 0x0, 0x16, 0xbe, 0x50, 0x0, 0x0, + 0x0, 0x40, 0x0, 0xab, 0x50, 0x0, 0x0, 0x0, + + /* U+7814 "研" */ + 0x1f, 0xff, 0xff, 0x89, 0xff, 0xff, 0xff, 0xf5, + 0x0, 0x2d, 0x0, 0x0, 0x3d, 0x0, 0x3d, 0x0, + 0x0, 0x69, 0x0, 0x0, 0x3c, 0x0, 0x3c, 0x0, + 0x0, 0xa5, 0x0, 0x0, 0x3c, 0x0, 0x3c, 0x0, + 0x0, 0xe1, 0x0, 0x0, 0x3c, 0x0, 0x3c, 0x0, + 0x4, 0xfd, 0xdd, 0x30, 0x3c, 0x0, 0x3c, 0x0, + 0xb, 0xf2, 0x2c, 0x4f, 0xff, 0xff, 0xff, 0xfa, + 0x3e, 0xe0, 0xb, 0x40, 0x5c, 0x0, 0x4d, 0x0, + 0x4, 0xe0, 0xb, 0x30, 0x6b, 0x0, 0x3c, 0x0, + 0x0, 0xe0, 0xb, 0x30, 0x88, 0x0, 0x3c, 0x0, + 0x0, 0xe0, 0xb, 0x30, 0xb5, 0x0, 0x3c, 0x0, + 0x0, 0xfe, 0xef, 0x31, 0xf1, 0x0, 0x3c, 0x0, + 0x0, 0xe0, 0x0, 0x9, 0x90, 0x0, 0x3c, 0x0, + 0x0, 0x40, 0x0, 0x1c, 0x0, 0x0, 0x3c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7834 "破" */ + 0x2f, 0xff, 0xff, 0x20, 0x0, 0xd1, 0x0, 0x0, + 0x0, 0x4c, 0x0, 0x0, 0x0, 0xd1, 0x0, 0x0, + 0x0, 0x88, 0x0, 0xe, 0xee, 0xfe, 0xee, 0xb0, + 0x0, 0xc4, 0x0, 0xe, 0x0, 0xd2, 0x7, 0x80, + 0x0, 0xf1, 0x0, 0xe, 0x0, 0xd1, 0xb, 0x30, + 0x6, 0xf7, 0x76, 0xe, 0x0, 0xd1, 0x5, 0x0, + 0xd, 0xe8, 0x9c, 0xf, 0xff, 0xff, 0xff, 0x10, + 0x5f, 0xd0, 0x2c, 0x1d, 0xd1, 0x0, 0x3c, 0x0, + 0x36, 0xd0, 0x2c, 0x2b, 0x68, 0x0, 0xa5, 0x0, + 0x1, 0xd0, 0x2c, 0x4a, 0xd, 0x35, 0xc0, 0x0, + 0x1, 0xd0, 0x2c, 0x77, 0x2, 0xee, 0x10, 0x0, + 0x1, 0xfe, 0xec, 0xc3, 0x5, 0xee, 0x50, 0x0, + 0x1, 0xd0, 0x3, 0xd3, 0xad, 0x23, 0xdb, 0x50, + 0x0, 0x0, 0x3, 0x46, 0x60, 0x0, 0x5, 0x80, + + /* U+78BA "確" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x52, 0x0, 0x0, + 0x17, 0x77, 0x77, 0x0, 0x0, 0xd1, 0x0, 0x0, + 0x18, 0xae, 0x88, 0x7e, 0xef, 0xfe, 0xee, 0xd0, + 0x0, 0x6a, 0x0, 0x79, 0xb, 0x62, 0x1, 0xe0, + 0x0, 0xa6, 0x0, 0x57, 0x6e, 0x3d, 0x0, 0xa0, + 0x0, 0xd3, 0x0, 0x2, 0xe9, 0x2e, 0x52, 0x10, + 0x1, 0xf7, 0x65, 0x2e, 0xfc, 0xcf, 0xdc, 0xa0, + 0x7, 0xf5, 0x7d, 0xec, 0xe0, 0xe, 0x10, 0x0, + 0xe, 0xf0, 0x2c, 0x12, 0xfd, 0xdf, 0xdd, 0xa0, + 0x6a, 0xe0, 0x2c, 0x2, 0xe0, 0xe, 0x10, 0x0, + 0x1, 0xe0, 0x2c, 0x2, 0xe0, 0xe, 0x10, 0x0, + 0x0, 0xe0, 0x2c, 0x2, 0xfd, 0xdf, 0xed, 0xb0, + 0x0, 0xfc, 0xcc, 0x2, 0xe0, 0xe, 0x10, 0x0, + 0x0, 0xf4, 0x43, 0x2, 0xe2, 0x2e, 0x42, 0x21, + 0x0, 0x90, 0x0, 0x2, 0xfb, 0xbb, 0xbb, 0xb5, + + /* U+793A "示" */ + 0x0, 0x1, 0x11, 0x11, 0x11, 0x11, 0x10, 0x0, + 0x0, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x40, 0x8, 0x90, 0x4, 0x0, 0x0, + 0x0, 0xb, 0x80, 0x8, 0x90, 0x9, 0xa0, 0x0, + 0x0, 0x4e, 0x0, 0x8, 0x90, 0x0, 0xd6, 0x0, + 0x2, 0xe5, 0x0, 0x8, 0x90, 0x0, 0x3f, 0x10, + 0x1d, 0x80, 0x0, 0x8, 0x90, 0x0, 0xb, 0x80, + 0x6, 0x0, 0x1, 0x1a, 0x90, 0x0, 0x2, 0x40, + 0x0, 0x0, 0x3f, 0xfe, 0x40, 0x0, 0x0, 0x0, + + /* U+793C "礼" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x90, 0x0, 0xe, 0x20, 0x0, 0x0, + 0x0, 0x0, 0xb5, 0x0, 0xe, 0x20, 0x0, 0x0, + 0x9, 0xdd, 0xed, 0xd0, 0xe, 0x20, 0x0, 0x0, + 0x1, 0x11, 0x18, 0xa0, 0xe, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x1e, 0x20, 0xe, 0x20, 0x0, 0x0, + 0x0, 0x0, 0xc7, 0x0, 0xe, 0x20, 0x0, 0x0, + 0x0, 0xa, 0xf8, 0x0, 0xe, 0x20, 0x0, 0x0, + 0x0, 0xbc, 0xfc, 0x70, 0xe, 0x20, 0x0, 0x0, + 0x1d, 0x91, 0xe1, 0xe6, 0xe, 0x20, 0x0, 0x0, + 0x6, 0x1, 0xe0, 0x33, 0xe, 0x20, 0x0, 0x0, + 0x0, 0x1, 0xe0, 0x0, 0xe, 0x20, 0x0, 0xa2, + 0x0, 0x1, 0xe0, 0x0, 0xe, 0x20, 0x0, 0xc3, + 0x0, 0x1, 0xe0, 0x0, 0xe, 0x40, 0x0, 0xe1, + 0x0, 0x1, 0xe0, 0x0, 0x8, 0xff, 0xff, 0x90, + + /* U+793E "社" */ + 0x0, 0x3a, 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0x0, 0x7, 0x70, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0x1d, 0xde, 0xdd, 0x20, 0x0, 0xb5, 0x0, 0x0, + 0x1, 0x11, 0x4e, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0x0, 0x0, 0xb7, 0x2, 0x22, 0xc6, 0x22, 0x10, + 0x0, 0x6, 0xd0, 0x4e, 0xee, 0xfe, 0xee, 0xb0, + 0x0, 0x3f, 0x80, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0x3, 0xff, 0xd7, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0x4f, 0x5e, 0x3d, 0x50, 0x0, 0xb5, 0x0, 0x0, + 0x24, 0xe, 0x12, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x33, 0x33, 0xc7, 0x33, 0x30, + 0x0, 0xe, 0x11, 0xdd, 0xdd, 0xdd, 0xdd, 0xd2, + + /* U+7956 "祖" */ + 0x0, 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x50, 0xd, 0xff, 0xff, 0xfb, 0x0, + 0x1, 0x15, 0x71, 0xd, 0x20, 0x0, 0x5b, 0x0, + 0x4f, 0xff, 0xff, 0x1d, 0x20, 0x0, 0x5b, 0x0, + 0x0, 0x0, 0x5b, 0xd, 0x20, 0x0, 0x5b, 0x0, + 0x0, 0x0, 0xd3, 0xd, 0xdc, 0xcc, 0xdb, 0x0, + 0x0, 0x9, 0x90, 0xd, 0x53, 0x33, 0x7b, 0x0, + 0x0, 0x6f, 0xa0, 0xd, 0x20, 0x0, 0x5b, 0x0, + 0x6, 0xff, 0xc8, 0xd, 0x20, 0x0, 0x5b, 0x0, + 0x7e, 0x3e, 0x3e, 0x3d, 0x64, 0x44, 0x8b, 0x0, + 0x32, 0xe, 0x13, 0xd, 0xcb, 0xbb, 0xdb, 0x0, + 0x0, 0xe, 0x10, 0xd, 0x20, 0x0, 0x5b, 0x0, + 0x0, 0xe, 0x10, 0xd, 0x20, 0x0, 0x5b, 0x0, + 0x0, 0xe, 0x10, 0xe, 0x30, 0x0, 0x6b, 0x0, + 0x0, 0xe, 0x1c, 0xee, 0xee, 0xee, 0xee, 0xe1, + + /* U+795D "祝" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x59, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x60, 0x1f, 0xff, 0xff, 0xff, 0x20, + 0x0, 0x5, 0x40, 0x1e, 0x0, 0x0, 0xe, 0x20, + 0x1d, 0xdd, 0xdd, 0x3e, 0x0, 0x0, 0xe, 0x20, + 0x1, 0x11, 0x8c, 0x2e, 0x0, 0x0, 0xe, 0x20, + 0x0, 0x1, 0xe4, 0x1e, 0x0, 0x0, 0xe, 0x20, + 0x0, 0xa, 0xa0, 0x1e, 0x0, 0x0, 0xe, 0x20, + 0x0, 0x5f, 0x90, 0x1e, 0xff, 0xef, 0xfe, 0x20, + 0x5, 0xef, 0xca, 0x0, 0x87, 0xe, 0x10, 0x0, + 0x3e, 0x3e, 0x1b, 0x70, 0x95, 0xe, 0x10, 0x0, + 0x2, 0xe, 0x10, 0x0, 0xc3, 0xe, 0x10, 0x0, + 0x0, 0xe, 0x10, 0x1, 0xe0, 0xe, 0x10, 0x0, + 0x0, 0xe, 0x10, 0xa, 0x80, 0xe, 0x10, 0xc0, + 0x0, 0xe, 0x11, 0xad, 0x0, 0xe, 0x20, 0xe0, + 0x0, 0xe, 0x1b, 0xa1, 0x0, 0xa, 0xee, 0xa0, + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+795E "神" */ + 0x0, 0x2c, 0x10, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0x69, 0x0, 0x0, 0xe, 0x20, 0x0, 0x2d, + 0xde, 0xed, 0x3f, 0xee, 0xfe, 0xee, 0xe0, 0x11, + 0x15, 0xd1, 0xe0, 0xe, 0x10, 0x1e, 0x0, 0x0, + 0xd5, 0x1e, 0x0, 0xe1, 0x1, 0xe0, 0x0, 0x8a, + 0x1, 0xfb, 0xbf, 0xcb, 0xce, 0x0, 0x4f, 0xb0, + 0x1f, 0x33, 0xf5, 0x34, 0xe0, 0x4e, 0xfa, 0xa1, + 0xe0, 0xe, 0x10, 0x1e, 0x4e, 0x3e, 0x1c, 0x6e, + 0x0, 0xe2, 0x2, 0xe1, 0x30, 0xe1, 0x11, 0xfe, + 0xef, 0xee, 0xee, 0x0, 0xe, 0x10, 0x8, 0x0, + 0xe1, 0x0, 0x60, 0x0, 0xe1, 0x0, 0x0, 0xe, + 0x10, 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, 0xe1, + 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, 0xe, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+796D "祭" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xd1, 0x0, 0xc3, 0x11, 0x12, 0x0, + 0x0, 0x1e, 0xdd, 0xde, 0x7e, 0xcc, 0xdf, 0x30, + 0x0, 0xc8, 0x0, 0x97, 0x1e, 0x0, 0xa9, 0x0, + 0xc, 0x92, 0xd8, 0xe1, 0xa, 0x86, 0xd0, 0x0, + 0x3, 0x60, 0x1f, 0x50, 0x1, 0xdd, 0x10, 0x0, + 0x0, 0x5d, 0xc8, 0x0, 0x0, 0x4e, 0x40, 0x0, + 0x0, 0x6d, 0x7f, 0xff, 0xff, 0xf6, 0xe8, 0x10, + 0x2d, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x18, 0xe2, + 0x2, 0xad, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0x0, + 0x0, 0x12, 0x22, 0x29, 0xa2, 0x22, 0x22, 0x0, + 0x0, 0x2, 0xd5, 0x7, 0x90, 0x7b, 0x10, 0x0, + 0x0, 0x4e, 0x50, 0x7, 0x90, 0x8, 0xd2, 0x0, + 0x7, 0xe3, 0x0, 0x8, 0x90, 0x0, 0x6e, 0x30, + 0x1, 0x10, 0x6, 0xfe, 0x50, 0x0, 0x3, 0x0, + + /* U+7981 "禁" */ + 0x0, 0x0, 0xf0, 0x0, 0x0, 0x2d, 0x0, 0x0, + 0xb, 0xee, 0xfe, 0xe3, 0xee, 0xef, 0xee, 0xb0, + 0x0, 0xb, 0xf5, 0x0, 0x0, 0xdf, 0x80, 0x0, + 0x0, 0x5c, 0xfb, 0x90, 0x9, 0xae, 0xc4, 0x0, + 0x3, 0xe2, 0xf0, 0xb3, 0x8c, 0x2d, 0x2e, 0x30, + 0x2e, 0x40, 0xf0, 0x7, 0xc1, 0x2d, 0x4, 0xe1, + 0x3, 0x0, 0xa0, 0x1, 0x0, 0x19, 0x0, 0x20, + 0x0, 0x1e, 0xee, 0xee, 0xee, 0xee, 0xe4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe0, + 0x0, 0x0, 0x40, 0x7, 0x90, 0x3, 0x0, 0x0, + 0x0, 0x1c, 0x80, 0x7, 0x90, 0x1b, 0xa1, 0x0, + 0x4, 0xd7, 0x0, 0x8, 0x90, 0x0, 0x7d, 0x20, + 0x8, 0x40, 0xc, 0xee, 0x50, 0x0, 0x5, 0x50, + + /* U+79C0 "秀" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x12, 0x35, 0x67, 0x9b, 0xdf, 0xc1, 0x0, + 0x0, 0xcb, 0xa9, 0x8c, 0xa4, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0x0, 0x8, 0xca, 0x9d, 0x80, 0x0, 0x0, + 0x0, 0x1, 0xcb, 0x19, 0x71, 0xbc, 0x20, 0x0, + 0x2, 0x9e, 0x70, 0x9, 0x70, 0x5, 0xdb, 0x40, + 0x3e, 0x8a, 0x99, 0x99, 0x99, 0x70, 0x5, 0xb1, + 0x0, 0x4, 0x4b, 0xa4, 0x4a, 0x80, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x40, 0xd, 0xdc, 0xc9, 0x0, + 0x0, 0x0, 0x4e, 0x0, 0x2, 0x22, 0x8a, 0x0, + 0x0, 0x1, 0xd6, 0x0, 0x0, 0x0, 0x98, 0x0, + 0x0, 0x4e, 0x80, 0x0, 0x0, 0x0, 0xd4, 0x0, + 0x9, 0xd5, 0x0, 0x0, 0xc, 0xff, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+79C1 "私" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x25, 0x8d, 0xe1, 0x0, 0xc4, 0x0, 0x0, + 0xd, 0xcb, 0xe2, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0x2, 0xd0, 0x0, 0x3, 0xe0, 0x0, 0x0, + 0x0, 0x2, 0xd0, 0x0, 0x7, 0xa0, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xf8, 0xb, 0x60, 0x0, 0x0, + 0x0, 0x9, 0xf4, 0x0, 0xf, 0x30, 0x0, 0x0, + 0x0, 0x1e, 0xed, 0x20, 0x3e, 0x4, 0x80, 0x0, + 0x0, 0x98, 0xd3, 0xd1, 0x8a, 0x1, 0xf1, 0x0, + 0x3, 0xc2, 0xd0, 0x72, 0xd5, 0x0, 0xa8, 0x0, + 0x1d, 0x32, 0xd0, 0x2, 0xf0, 0x0, 0x3e, 0x0, + 0x57, 0x2, 0xd0, 0x8, 0xa0, 0x0, 0xd, 0x60, + 0x0, 0x2, 0xd0, 0x1e, 0xa8, 0xac, 0xfe, 0xc0, + 0x0, 0x2, 0xd0, 0x3e, 0xa8, 0x53, 0x1, 0xf1, + 0x0, 0x2, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x50, + + /* U+79CB "秋" */ + 0x0, 0x3, 0x7c, 0x70, 0x0, 0xc3, 0x0, 0x0, + 0xb, 0xcc, 0xc3, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0x0, 0x5, 0xa0, 0x0, 0x0, 0xc2, 0x0, 0x0, + 0x0, 0x5, 0xa0, 0x0, 0xb0, 0xc2, 0x6, 0x70, + 0x3f, 0xff, 0xff, 0xf5, 0xb0, 0xd1, 0xd, 0x40, + 0x0, 0xc, 0xd1, 0x7, 0x80, 0xf1, 0x3d, 0x0, + 0x0, 0x3f, 0xf9, 0xd, 0x21, 0xf4, 0xb5, 0x0, + 0x0, 0xba, 0xab, 0x54, 0x3, 0xf7, 0x40, 0x0, + 0x4, 0xc6, 0xa2, 0x30, 0x6, 0xbc, 0x0, 0x0, + 0x1d, 0x35, 0xa0, 0x0, 0xb, 0x3d, 0x20, 0x0, + 0x58, 0x5, 0xa0, 0x0, 0x3d, 0x6, 0xa0, 0x0, + 0x0, 0x5, 0xa0, 0x0, 0xd5, 0x0, 0xd5, 0x0, + 0x0, 0x5, 0xa0, 0x1c, 0x90, 0x0, 0x2e, 0x60, + 0x0, 0x5, 0xa0, 0x97, 0x0, 0x0, 0x2, 0xb1, + + /* U+79CD "种" */ + 0x0, 0x2, 0x6b, 0x50, 0x0, 0x2e, 0x0, 0x0, + 0xb, 0xde, 0xc4, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x7, 0x90, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x7, 0x90, 0xb, 0xff, 0xff, 0xff, 0xf1, + 0x1f, 0xff, 0xff, 0xab, 0x50, 0x2e, 0x0, 0xe1, + 0x0, 0xd, 0xb0, 0xb, 0x50, 0x2e, 0x0, 0xe1, + 0x0, 0x4f, 0xf7, 0xb, 0x50, 0x2e, 0x0, 0xe1, + 0x0, 0xba, 0x9c, 0x3b, 0x50, 0x2e, 0x0, 0xe1, + 0x3, 0xb7, 0x93, 0x8b, 0xff, 0xff, 0xff, 0xf1, + 0xd, 0x37, 0x90, 0xb, 0x50, 0x2e, 0x0, 0xd1, + 0x48, 0x7, 0x90, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x7, 0x90, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x7, 0x90, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x7, 0x90, 0x0, 0x0, 0x2e, 0x0, 0x0, + + /* U+79D1 "科" */ + 0x0, 0x2, 0x6b, 0x40, 0x0, 0x0, 0xe2, 0x0, + 0xb, 0xde, 0xc4, 0x0, 0x97, 0x0, 0xe2, 0x0, + 0x0, 0x8, 0x80, 0x0, 0xa, 0xb0, 0xe2, 0x0, + 0x0, 0x8, 0x80, 0x0, 0x0, 0x60, 0xe2, 0x0, + 0x4f, 0xff, 0xff, 0xe0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0xe, 0xb0, 0x4, 0xd3, 0x0, 0xe2, 0x0, + 0x0, 0x5f, 0xe7, 0x0, 0x3e, 0x50, 0xe2, 0x0, + 0x0, 0xca, 0x8c, 0x40, 0x2, 0x60, 0xe2, 0x0, + 0x5, 0xa8, 0x83, 0x70, 0x0, 0x0, 0xe5, 0x50, + 0x1e, 0x28, 0x80, 0x3, 0x69, 0xbe, 0xfd, 0xa1, + 0x47, 0x8, 0x80, 0x2c, 0x97, 0x41, 0xe2, 0x0, + 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, 0xe2, 0x0, + + /* U+79D8 "秘" */ + 0x0, 0x0, 0x13, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x3, 0x7b, 0xf9, 0x0, 0x2d, 0x90, 0x5, 0x10, + 0x7, 0x7e, 0x30, 0x0, 0x0, 0xac, 0xe, 0x10, + 0x0, 0xd, 0x20, 0x0, 0x1, 0x5, 0x4b, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x1e, 0x0, 0x96, 0x0, + 0x1f, 0xff, 0xff, 0x13, 0x1e, 0x0, 0xe1, 0x0, + 0x0, 0x2f, 0x50, 0x2b, 0x1e, 0x5, 0xbd, 0x0, + 0x0, 0x8f, 0xd0, 0x58, 0x1e, 0xd, 0x4a, 0x60, + 0x0, 0xde, 0x99, 0x95, 0x1e, 0x6b, 0x4, 0xc0, + 0x5, 0x9d, 0x39, 0xe1, 0x1f, 0xd2, 0x0, 0xf0, + 0xe, 0x2d, 0x22, 0x90, 0x1f, 0x90, 0x0, 0xb3, + 0x49, 0xd, 0x20, 0x0, 0x6f, 0x10, 0x2, 0x0, + 0x0, 0xd, 0x20, 0x8, 0xfe, 0x0, 0xe, 0x0, + 0x0, 0xd, 0x20, 0xae, 0x5f, 0x0, 0x1e, 0x0, + 0x0, 0xd, 0x21, 0xa2, 0xc, 0xff, 0xf8, 0x0, + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+79FB "移" */ + 0x0, 0x0, 0x2, 0x0, 0x0, 0x61, 0x0, 0x0, + 0x2, 0x6a, 0xea, 0x0, 0x8, 0xb0, 0x0, 0x0, + 0xa, 0x8d, 0x40, 0x0, 0x8f, 0xfe, 0xee, 0x20, + 0x0, 0xb, 0x30, 0x3d, 0xa1, 0x0, 0x8a, 0x0, + 0x0, 0xb, 0x30, 0x64, 0x7b, 0x28, 0xd1, 0x0, + 0x3f, 0xff, 0xff, 0x30, 0x9, 0xfc, 0x10, 0x0, + 0x0, 0x2f, 0x60, 0x4, 0xbe, 0x79, 0x10, 0x0, + 0x0, 0x7f, 0xe1, 0xac, 0x71, 0x9c, 0x0, 0x0, + 0x0, 0xdd, 0x9b, 0x0, 0x8, 0xfe, 0xee, 0xf1, + 0x5, 0xab, 0x49, 0x1, 0xbc, 0x10, 0x7, 0x90, + 0xd, 0x3b, 0x30, 0x4e, 0x77, 0x20, 0x3e, 0x10, + 0x49, 0xb, 0x30, 0x1, 0x4, 0xe8, 0xd3, 0x0, + 0x0, 0xb, 0x30, 0x0, 0x1, 0xae, 0x30, 0x0, + 0x0, 0xb, 0x30, 0x4, 0x9e, 0x70, 0x0, 0x0, + 0x0, 0xb, 0x30, 0xdb, 0x61, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7A0B "程" */ + 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x4, 0x7a, 0xec, 0x46, 0xfe, 0xee, 0xef, 0xc0, + 0x9, 0x79, 0xa0, 0x6, 0xa0, 0x0, 0x3, 0xc0, + 0x0, 0x6, 0xa0, 0x6, 0xa0, 0x0, 0x3, 0xc0, + 0x1, 0x17, 0xb1, 0x16, 0xa0, 0x0, 0x3, 0xc0, + 0x1e, 0xef, 0xfe, 0xa6, 0xfe, 0xee, 0xef, 0xc0, + 0x0, 0xc, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0xec, 0x1d, 0xdd, 0xef, 0xdd, 0xd5, + 0x2, 0xe7, 0xa8, 0xa0, 0x0, 0x4b, 0x0, 0x0, + 0xb, 0x76, 0xa0, 0x20, 0x11, 0x5c, 0x11, 0x10, + 0x4c, 0x6, 0xa0, 0x9, 0xdd, 0xef, 0xdd, 0xd0, + 0x2, 0x6, 0xa0, 0x0, 0x0, 0x4b, 0x0, 0x0, + 0x0, 0x6, 0xa0, 0x0, 0x0, 0x4b, 0x0, 0x0, + 0x0, 0x6, 0xa0, 0xcf, 0xff, 0xff, 0xff, 0xfb, + + /* U+7A2E "種" */ + 0x0, 0x0, 0x38, 0x30, 0x12, 0x34, 0x68, 0x90, + 0x8, 0xcf, 0xe7, 0x4d, 0xcb, 0xea, 0x75, 0x20, + 0x5, 0x37, 0xa0, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x0, 0x6, 0xa0, 0x9f, 0xff, 0xff, 0xff, 0xf3, + 0x2, 0x27, 0xb2, 0x10, 0x0, 0xc3, 0x0, 0x0, + 0x1e, 0xef, 0xfe, 0xab, 0xcc, 0xfd, 0xcc, 0xb0, + 0x0, 0xc, 0xa0, 0xe, 0x0, 0xc4, 0x1, 0xe0, + 0x0, 0x3f, 0xf3, 0xf, 0x99, 0xeb, 0x9a, 0xe0, + 0x0, 0xaa, 0xcd, 0x1e, 0x22, 0xd5, 0x23, 0xe0, + 0x2, 0xc6, 0xa6, 0xae, 0x0, 0xc4, 0x1, 0xe0, + 0xb, 0x56, 0xa0, 0x2b, 0xcc, 0xfd, 0xcc, 0xb0, + 0x4c, 0x6, 0xa0, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0x2, 0x6, 0xa0, 0x1d, 0xdd, 0xfe, 0xdd, 0xd0, + 0x0, 0x6, 0xa0, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0x0, 0x6, 0xa0, 0xee, 0xee, 0xfe, 0xee, 0xe7, + + /* U+7A4D "積" */ + 0x18, 0x9b, 0x96, 0x5b, 0xbb, 0xfc, 0xbb, 0x80, + 0x9, 0x5b, 0x50, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0xa, 0x50, 0xb, 0xbb, 0xfc, 0xbb, 0x30, + 0x0, 0xa, 0x60, 0x44, 0x44, 0xf6, 0x44, 0x40, + 0x2e, 0xef, 0xfe, 0x86, 0x66, 0x66, 0x66, 0x60, + 0x0, 0xf, 0x60, 0xa, 0xcc, 0xcc, 0xcc, 0x20, + 0x0, 0x6f, 0xd0, 0xe, 0x10, 0x0, 0xd, 0x20, + 0x0, 0xdb, 0xbc, 0xe, 0xcb, 0xbb, 0xbf, 0x20, + 0x5, 0x9a, 0x59, 0x4e, 0x10, 0x0, 0xd, 0x20, + 0x1e, 0x2a, 0x50, 0xe, 0xbb, 0xbb, 0xbf, 0x20, + 0x67, 0xa, 0x50, 0xe, 0x10, 0x0, 0xd, 0x20, + 0x0, 0xa, 0x50, 0xa, 0xcc, 0xcc, 0xcc, 0x20, + 0x0, 0xa, 0x50, 0x4, 0xd7, 0x2, 0xc6, 0x0, + 0x0, 0xa, 0x52, 0xd9, 0x20, 0x0, 0x8, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7A76 "究" */ + 0x0, 0x0, 0x0, 0x29, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x60, 0x0, 0x0, 0x0, + 0xc, 0xdd, 0xdd, 0xdf, 0xfd, 0xdd, 0xdd, 0xa0, + 0xe, 0x31, 0x12, 0x21, 0x12, 0x11, 0x16, 0xc0, + 0xa, 0x10, 0x4d, 0x60, 0x6, 0xd6, 0x3, 0x80, + 0x0, 0x3b, 0xc2, 0x0, 0x0, 0x18, 0xd5, 0x0, + 0x2, 0xc4, 0x0, 0x60, 0x0, 0x0, 0x2b, 0x30, + 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xee, 0xee, 0xfe, 0xee, 0xeb, 0x0, 0x0, + 0x0, 0x11, 0x12, 0xf2, 0x11, 0x5c, 0x0, 0x0, + 0x0, 0x0, 0x4, 0xe0, 0x0, 0x4c, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x70, 0x0, 0x4c, 0x0, 0x41, + 0x0, 0x0, 0xbd, 0x0, 0x0, 0x4c, 0x0, 0xa5, + 0x0, 0x5d, 0xc1, 0x0, 0x0, 0x4d, 0x0, 0xc3, + 0xd, 0xe7, 0x0, 0x0, 0x0, 0x1e, 0xff, 0xd0, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7A7A "空" */ + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xf1, 0x0, 0x0, 0x0, 0x33, 0x33, + 0x33, 0xe9, 0x33, 0x33, 0x32, 0xec, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0xdd, 0xe2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4d, 0xe2, 0x3, 0xd4, 0x0, 0xca, + 0x20, 0x3c, 0x41, 0x7e, 0x40, 0x0, 0x6, 0xea, + 0x10, 0x5e, 0xa2, 0x0, 0x0, 0x0, 0x8, 0xf5, + 0x35, 0x33, 0x33, 0x33, 0x33, 0x33, 0x31, 0x3, + 0xbb, 0xbb, 0xfc, 0xbb, 0xbb, 0x20, 0x0, 0x0, + 0x0, 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe4, 0x0, + 0x0, 0x0, 0xde, 0xee, 0xee, 0xee, 0xee, 0xee, + 0xec, + + /* U+7A93 "窓" */ + 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x80, 0x0, 0x0, 0x0, + 0xe, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xd0, + 0xe, 0x20, 0x5, 0x40, 0x4, 0x10, 0x4, 0xd0, + 0x8, 0x11, 0xab, 0x10, 0x5, 0xc9, 0x12, 0x60, + 0x1, 0x9d, 0x60, 0x88, 0x0, 0x5, 0xd7, 0x0, + 0x0, 0x60, 0x8, 0xb0, 0x6, 0x60, 0x2, 0x0, + 0x0, 0x0, 0x99, 0x0, 0x0, 0xab, 0x10, 0x0, + 0x0, 0x2e, 0xfb, 0xcd, 0xee, 0xdc, 0xd2, 0x0, + 0x0, 0x6, 0x42, 0x12, 0x0, 0x0, 0x64, 0x0, + 0x0, 0x10, 0x50, 0x1e, 0x40, 0x0, 0x80, 0x0, + 0x1, 0xe0, 0xf0, 0x3, 0xe2, 0x0, 0xaa, 0x0, + 0x8, 0x90, 0xf0, 0x0, 0x68, 0x7, 0x3d, 0x50, + 0x1e, 0x20, 0xf1, 0x0, 0x0, 0x1e, 0x34, 0xd0, + 0x15, 0x0, 0xae, 0xee, 0xee, 0xfa, 0x0, 0x10, + + /* U+7ACB "立" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x1, 0x22, 0x22, 0x26, 0x72, 0x22, 0x22, 0x10, + 0x6, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x0, 0xf, 0x30, 0x0, + 0x0, 0x0, 0xc5, 0x0, 0x0, 0x5e, 0x0, 0x0, + 0x0, 0x0, 0x89, 0x0, 0x0, 0x99, 0x0, 0x0, + 0x0, 0x0, 0x4d, 0x0, 0x0, 0xd4, 0x0, 0x0, + 0x0, 0x0, 0x1f, 0x10, 0x2, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0xd, 0x40, 0x8, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x9, 0x50, 0xd, 0x40, 0x0, 0x0, + 0x4, 0x44, 0x44, 0x44, 0x7f, 0x54, 0x44, 0x40, + 0x1c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc1, + + /* U+7AD9 "站" */ + 0x0, 0xc, 0x10, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0x7, 0x90, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x5, 0x56, 0x95, 0x50, 0x0, 0xe2, 0x0, 0x0, + 0xa, 0xaa, 0xaa, 0xa1, 0x0, 0xef, 0xff, 0xf4, + 0x2, 0x50, 0x8, 0x30, 0x0, 0xe2, 0x0, 0x0, + 0x3, 0xa0, 0xd, 0x20, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0xd0, 0xe, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0xe0, 0x2c, 0x7, 0xff, 0xff, 0xff, 0xd0, + 0x0, 0xc2, 0x49, 0x8, 0x80, 0x0, 0x4, 0xd0, + 0x0, 0xa4, 0x75, 0x8, 0x80, 0x0, 0x3, 0xd0, + 0x0, 0x14, 0xcd, 0xf8, 0x80, 0x0, 0x3, 0xd0, + 0x1c, 0xfc, 0x84, 0x8, 0x80, 0x0, 0x3, 0xd0, + 0x4, 0x0, 0x0, 0x8, 0xec, 0xcc, 0xcd, 0xd0, + 0x0, 0x0, 0x0, 0x8, 0xa3, 0x33, 0x36, 0xc0, + + /* U+7AE5 "童" */ + 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xa0, 0x0, 0x0, 0x0, + 0x2, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x20, + 0x0, 0x0, 0x98, 0x0, 0x0, 0xa8, 0x0, 0x0, + 0x17, 0x77, 0x8f, 0x77, 0x78, 0xf8, 0x77, 0x71, + 0x16, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x61, + 0x0, 0x5b, 0xbb, 0xbb, 0xbb, 0xbb, 0xb5, 0x0, + 0x0, 0x69, 0x0, 0x8, 0x80, 0x0, 0x96, 0x0, + 0x0, 0x6e, 0xbb, 0xbd, 0xdb, 0xbb, 0xe6, 0x0, + 0x0, 0x69, 0x0, 0x8, 0x80, 0x0, 0x96, 0x0, + 0x0, 0x6d, 0xbb, 0xbe, 0xeb, 0xbb, 0xd6, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x1, 0xdd, 0xdd, 0xde, 0xed, 0xdd, 0xdd, 0x10, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x3d, 0xdd, 0xdd, 0xdf, 0xfd, 0xdd, 0xdd, 0xd3, + + /* U+7AEF "端" */ + 0x0, 0x4a, 0x0, 0x4b, 0x0, 0xd0, 0x1, 0xe0, + 0x0, 0xd, 0x30, 0x4b, 0x0, 0xd0, 0x1, 0xe0, + 0x18, 0x8a, 0x98, 0x6b, 0x0, 0xd0, 0x1, 0xe0, + 0x17, 0x77, 0x77, 0x5f, 0xff, 0xff, 0xff, 0xe0, + 0x6, 0x20, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x60, 0x77, 0xcd, 0xdd, 0xdd, 0xdd, 0xd6, + 0x5, 0x80, 0x95, 0x22, 0x23, 0xe2, 0x22, 0x21, + 0x2, 0xb0, 0xb2, 0x0, 0x3, 0xb0, 0x0, 0x0, + 0x1, 0xc0, 0xd0, 0x6f, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0xd0, 0xc0, 0x68, 0xd, 0xb, 0x20, 0xd1, + 0x0, 0x56, 0xc9, 0x98, 0xd, 0xb, 0x20, 0xd1, + 0x2c, 0xfd, 0x95, 0x88, 0xd, 0xb, 0x20, 0xd1, + 0x5, 0x10, 0x0, 0x68, 0xd, 0xb, 0x20, 0xd1, + 0x0, 0x0, 0x0, 0x68, 0xb, 0x9, 0x3d, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7B11 "笑" */ + 0x0, 0x9, 0x0, 0x0, 0x7, 0x10, 0x0, 0x0, + 0x0, 0x5c, 0x0, 0x0, 0x2f, 0x0, 0x0, 0x0, + 0x0, 0xcf, 0xee, 0xee, 0x9f, 0xee, 0xee, 0xe1, + 0x6, 0xc0, 0xd3, 0x4, 0xe1, 0x3e, 0x10, 0x0, + 0x1f, 0x20, 0x79, 0xe, 0x50, 0xa, 0x60, 0x0, + 0x2, 0x0, 0x11, 0x3, 0x35, 0x7a, 0xd9, 0x0, + 0x0, 0xac, 0xef, 0xff, 0xea, 0x86, 0x20, 0x0, + 0x0, 0x22, 0x10, 0x8, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0x70, 0x0, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x7c, 0xb7, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xf3, 0x1e, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x5f, 0x50, 0x3, 0xe7, 0x0, 0x0, + 0x1, 0x6c, 0xd3, 0x0, 0x0, 0x2c, 0xd6, 0x10, + 0xc, 0xa5, 0x0, 0x0, 0x0, 0x0, 0x5b, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7B26 "符" */ + 0x0, 0x16, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, + 0x0, 0x7a, 0x0, 0x0, 0x4e, 0x0, 0x0, 0x0, + 0x0, 0xef, 0xee, 0xe8, 0xbf, 0xee, 0xee, 0xd0, + 0x8, 0xb0, 0xc3, 0x5, 0xd0, 0x3d, 0x0, 0x0, + 0x2e, 0x10, 0x5a, 0xe, 0x30, 0x9, 0x40, 0x0, + 0x1, 0x1, 0xb1, 0x0, 0x0, 0x2, 0x90, 0x0, + 0x0, 0xa, 0x90, 0x0, 0x0, 0x3, 0xd0, 0x0, + 0x0, 0x4f, 0x2a, 0xee, 0xee, 0xef, 0xfe, 0xe1, + 0x3, 0xff, 0x10, 0x0, 0x0, 0x4, 0xd0, 0x0, + 0x1e, 0x7e, 0x10, 0x69, 0x0, 0x3, 0xd0, 0x0, + 0x5, 0xe, 0x10, 0xd, 0x40, 0x3, 0xd0, 0x0, + 0x0, 0xe, 0x10, 0x4, 0xe0, 0x3, 0xd0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x50, 0x3, 0xd0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x4, 0xd0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0xe, 0xfe, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7B2C "第" */ + 0x0, 0x5, 0x10, 0x0, 0x4, 0x20, 0x0, 0x0, + 0x0, 0x2f, 0x0, 0x0, 0xf, 0x30, 0x0, 0x0, + 0x0, 0xae, 0xfe, 0xdb, 0x7e, 0xdf, 0xdd, 0xd1, + 0x6, 0xc0, 0x78, 0x3, 0xe2, 0xa, 0x80, 0x0, + 0xc, 0x20, 0x18, 0x6, 0x60, 0x1, 0x90, 0x0, + 0x0, 0xce, 0xee, 0xee, 0xee, 0xee, 0xed, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x30, 0x0, 0x2e, 0x0, + 0x0, 0x2, 0x22, 0x2d, 0x52, 0x22, 0x4e, 0x0, + 0x0, 0x6e, 0xcc, 0xcf, 0xdc, 0xcc, 0xcb, 0x0, + 0x0, 0x96, 0x0, 0xd, 0x30, 0x0, 0x0, 0x0, + 0x0, 0xcf, 0xee, 0xef, 0xfe, 0xee, 0xee, 0x50, + 0x0, 0x0, 0x4, 0xde, 0x30, 0x0, 0xd, 0x30, + 0x0, 0x0, 0x5c, 0x1d, 0x30, 0x0, 0xf, 0x10, + 0x0, 0x19, 0xa0, 0xd, 0x30, 0x32, 0x6e, 0x0, + 0x5, 0xa3, 0x0, 0xd, 0x30, 0x9c, 0xb4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7B46 "筆" */ + 0x0, 0x4, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x0, 0x4e, 0x0, 0x0, 0x5e, 0x0, 0x0, 0x0, + 0x1, 0xdd, 0xfd, 0xdd, 0xed, 0xfe, 0xdd, 0xd1, + 0xc, 0xa0, 0xb6, 0x3e, 0x50, 0x5d, 0x0, 0x0, + 0x7, 0x0, 0x12, 0xb, 0x70, 0x3, 0x0, 0x0, + 0x0, 0x3d, 0xdd, 0xde, 0xed, 0xdd, 0xe7, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x97, 0x0, + 0x2d, 0xdd, 0xdd, 0xdf, 0xed, 0xdd, 0xfe, 0xd3, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x97, 0x0, + 0x0, 0x5d, 0xdd, 0xde, 0xed, 0xdd, 0xd6, 0x0, + 0x0, 0x11, 0x11, 0x1a, 0x81, 0x11, 0x11, 0x0, + 0x0, 0xab, 0xbb, 0xbe, 0xdb, 0xbb, 0xbb, 0x0, + 0x2, 0x22, 0x22, 0x2a, 0x92, 0x22, 0x22, 0x20, + 0xa, 0xbb, 0xbb, 0xbe, 0xdb, 0xbb, 0xbb, 0xb0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + + /* U+7B49 "等" */ + 0x0, 0x5, 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, + 0x0, 0x5d, 0x0, 0x0, 0x1f, 0x20, 0x0, 0x0, + 0x0, 0xcf, 0xfe, 0xee, 0x9f, 0xff, 0xee, 0xe3, + 0x8, 0xa0, 0xe2, 0x6, 0xe1, 0x1e, 0x10, 0x0, + 0xa, 0x0, 0x64, 0x9, 0x90, 0x6, 0x50, 0x0, + 0x0, 0x6d, 0xdd, 0xde, 0xfd, 0xdd, 0xdc, 0x0, + 0x0, 0x0, 0x0, 0x7, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xa0, 0x0, 0x0, 0x0, + 0x1e, 0xee, 0xee, 0xee, 0xee, 0xff, 0xee, 0xe6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, + 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0xb3, 0x0, 0x0, 0x1f, 0x0, 0x0, + 0x0, 0x0, 0x4e, 0x60, 0x0, 0x1f, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xe1, 0x0, 0x2f, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xaf, 0xf9, 0x0, 0x0, + + /* U+7B54 "答" */ + 0x0, 0x6, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, + 0x0, 0x7b, 0x0, 0x0, 0x4d, 0x0, 0x0, 0x0, + 0x0, 0xef, 0xee, 0xe8, 0xbf, 0xee, 0xee, 0x80, + 0xb, 0x90, 0xe2, 0x6, 0xc0, 0x6c, 0x0, 0x0, + 0x5c, 0x0, 0x78, 0x8, 0x40, 0xc, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x8f, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0xc1, 0x9d, 0x40, 0x0, 0x0, + 0x0, 0x5, 0xea, 0x0, 0x4, 0xeb, 0x50, 0x0, + 0x6, 0xdc, 0xae, 0xee, 0xee, 0xe6, 0xde, 0x70, + 0x29, 0x20, 0x0, 0x0, 0x0, 0x0, 0x3, 0x40, + 0x0, 0xc, 0xff, 0xff, 0xff, 0xff, 0x30, 0x0, + 0x0, 0xc, 0x30, 0x0, 0x0, 0xd, 0x30, 0x0, + 0x0, 0xc, 0x30, 0x0, 0x0, 0xd, 0x30, 0x0, + 0x0, 0xc, 0x52, 0x22, 0x22, 0x2d, 0x30, 0x0, + 0x0, 0xc, 0xdc, 0xcc, 0xcc, 0xce, 0x30, 0x0, + + /* U+7B56 "策" */ + 0x0, 0x5, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, + 0x0, 0x7b, 0x0, 0x0, 0x5e, 0x0, 0x0, 0x0, + 0x2, 0xff, 0xfe, 0xec, 0xdf, 0xff, 0xee, 0xe0, + 0x1e, 0x70, 0xe3, 0x1d, 0xa0, 0x3d, 0x0, 0x0, + 0x16, 0x0, 0x43, 0xb, 0x90, 0x6, 0x10, 0x0, + 0xd, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xb0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x23, 0x33, 0x3a, 0xb3, 0x33, 0x33, 0x0, + 0x0, 0xbc, 0xbb, 0xbd, 0xeb, 0xbb, 0xcd, 0x0, + 0x0, 0xb5, 0x0, 0x8, 0x90, 0x0, 0x3d, 0x0, + 0x0, 0xb5, 0x0, 0x1d, 0xd1, 0x0, 0x3d, 0x0, + 0x0, 0xa4, 0x4, 0xdc, 0xdd, 0x49, 0xc7, 0x0, + 0x0, 0x3, 0xab, 0x28, 0x92, 0xcb, 0x40, 0x0, + 0x17, 0xcb, 0x50, 0x8, 0x90, 0x4, 0xad, 0x91, + 0x6, 0x20, 0x0, 0x8, 0x90, 0x0, 0x1, 0x50, + + /* U+7B97 "算" */ + 0x0, 0x2, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x8b, 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, + 0x2, 0xfe, 0xfe, 0xec, 0xce, 0xef, 0xee, 0xe0, + 0x1e, 0x50, 0xc4, 0xa, 0x90, 0xd, 0x40, 0x0, + 0x3, 0x1c, 0xdc, 0xcd, 0xcc, 0xcd, 0xc5, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0xa6, 0x0, + 0x0, 0x2f, 0xbb, 0xbb, 0xbb, 0xbb, 0xe6, 0x0, + 0x0, 0x2f, 0x55, 0x55, 0x55, 0x55, 0xc6, 0x0, + 0x0, 0x2f, 0x44, 0x44, 0x44, 0x44, 0xc6, 0x0, + 0x0, 0x2f, 0xbb, 0xbb, 0xbb, 0xbb, 0xe6, 0x0, + 0x0, 0x0, 0xf, 0x20, 0x0, 0xa6, 0x0, 0x0, + 0x2, 0x22, 0x2f, 0x42, 0x22, 0xb8, 0x22, 0x20, + 0xb, 0xbb, 0xdf, 0xbb, 0xbb, 0xed, 0xbb, 0xb1, + 0x0, 0x6, 0xd4, 0x0, 0x0, 0xa6, 0x0, 0x0, + 0x6, 0xc8, 0x10, 0x0, 0x0, 0xa6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7BA1 "管" */ + 0x0, 0x13, 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, + 0x0, 0x7a, 0x0, 0x0, 0xa, 0x80, 0x0, 0x0, + 0x0, 0xed, 0xee, 0xcc, 0x1e, 0xce, 0xdc, 0xc3, + 0x9, 0xa0, 0x5b, 0x0, 0xa7, 0x5, 0xb0, 0x0, + 0x8, 0x10, 0x6, 0x6, 0xa0, 0x0, 0x60, 0x0, + 0x1, 0xed, 0xdd, 0xde, 0xfd, 0xdd, 0xdd, 0xc0, + 0x1, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xd0, + 0x1, 0xa6, 0xfd, 0xdd, 0xdd, 0xde, 0xe2, 0xa0, + 0x0, 0x6, 0xb0, 0x0, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0x6, 0xfd, 0xdd, 0xdd, 0xdd, 0xe0, 0x0, + 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xfd, 0xdd, 0xdd, 0xdd, 0xda, 0x0, + 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, 0x4b, 0x0, + 0x0, 0x6, 0xb0, 0x0, 0x0, 0x0, 0x4b, 0x0, + 0x0, 0x6, 0xfd, 0xdd, 0xdd, 0xdd, 0xeb, 0x0, + + /* U+7BC0 "節" */ + 0x0, 0x5, 0x0, 0x0, 0x1, 0x40, 0x0, 0x0, + 0x0, 0x6c, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, + 0x0, 0xdd, 0xfd, 0xdd, 0x2e, 0xdf, 0xed, 0xd6, + 0xa, 0x90, 0x97, 0x1, 0xd4, 0x8, 0xa0, 0x0, + 0x19, 0x0, 0x19, 0x4, 0x60, 0x0, 0xb2, 0x0, + 0x1, 0xdd, 0xdd, 0xdc, 0xc, 0xdd, 0xdd, 0xc0, + 0x1, 0xe0, 0x0, 0x1e, 0xe, 0x31, 0x14, 0xe0, + 0x1, 0xfb, 0xbb, 0xbe, 0xe, 0x10, 0x2, 0xe0, + 0x1, 0xe1, 0x11, 0x3e, 0xe, 0x10, 0x2, 0xe0, + 0x1, 0xe0, 0x0, 0x2e, 0xe, 0x10, 0x2, 0xe0, + 0x1, 0xfd, 0xdd, 0xdc, 0xe, 0x10, 0x2, 0xe0, + 0x1, 0xe0, 0x7, 0x60, 0xe, 0x10, 0x2, 0xe0, + 0x1, 0xe0, 0x26, 0xf3, 0xe, 0x1a, 0xde, 0xa0, + 0x7, 0xfe, 0xd9, 0x6d, 0x1e, 0x11, 0x10, 0x0, + 0x3, 0x51, 0x0, 0x5, 0x1e, 0x10, 0x0, 0x0, + + /* U+7BC4 "範" */ + 0x0, 0x3, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x5d, 0x0, 0x0, 0x2f, 0x30, 0x0, 0x0, + 0x1, 0xee, 0xfe, 0xef, 0xcf, 0xff, 0xee, 0xe8, + 0xd, 0x70, 0xc3, 0xb, 0x80, 0xc, 0x60, 0x0, + 0x1, 0x0, 0xa2, 0x0, 0x0, 0x1, 0x0, 0x0, + 0xa, 0xcc, 0xfd, 0xcc, 0x4f, 0xff, 0xff, 0xe0, + 0x0, 0x0, 0xb3, 0x0, 0xf, 0x10, 0x1, 0xe0, + 0x6, 0xdb, 0xec, 0xbe, 0xf, 0x10, 0x1, 0xe0, + 0x6, 0x82, 0xc5, 0x2e, 0xf, 0x10, 0x1, 0xe0, + 0x6, 0xc9, 0xea, 0x9e, 0xf, 0x10, 0x2, 0xe0, + 0x6, 0x94, 0xc6, 0x4e, 0xf, 0x12, 0xff, 0xa0, + 0x2, 0x66, 0xd8, 0x66, 0xf, 0x10, 0x0, 0x0, + 0xb, 0xbb, 0xec, 0xbb, 0x5f, 0x10, 0x0, 0x4a, + 0x2, 0x22, 0xc5, 0x22, 0x1e, 0x30, 0x0, 0x79, + 0x0, 0x0, 0xb3, 0x0, 0x8, 0xff, 0xff, 0xe2, + + /* U+7C21 "簡" */ + 0x0, 0x3, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, + 0x0, 0x5c, 0x0, 0x0, 0x1f, 0x30, 0x0, 0x0, + 0x1, 0xde, 0xfd, 0xdd, 0xbe, 0xef, 0xdd, 0xd7, + 0xb, 0x80, 0xe1, 0xb, 0xb0, 0xb, 0x60, 0x0, + 0x5, 0x44, 0x86, 0x45, 0x4, 0x46, 0x94, 0x40, + 0x1, 0xe6, 0x66, 0xc6, 0x1f, 0x66, 0x67, 0xd0, + 0x1, 0xfa, 0xaa, 0xe6, 0x1f, 0xaa, 0xab, 0xd0, + 0x1, 0xe1, 0x11, 0xb6, 0x1e, 0x11, 0x13, 0xd0, + 0x1, 0xf9, 0x99, 0x93, 0x9, 0x99, 0x9a, 0xd0, + 0x1, 0xe0, 0x9, 0xaa, 0xaa, 0xa2, 0x2, 0xd0, + 0x1, 0xe0, 0xe, 0x20, 0x0, 0xb4, 0x2, 0xd0, + 0x1, 0xe0, 0xe, 0xbb, 0xbb, 0xe4, 0x2, 0xd0, + 0x1, 0xe0, 0xe, 0x10, 0x0, 0xb4, 0x2, 0xd0, + 0x1, 0xe0, 0xe, 0xbb, 0xbb, 0xe4, 0x2, 0xd0, + 0x1, 0xe0, 0x4, 0x0, 0x0, 0x6, 0xfe, 0x80, + + /* U+7C73 "米" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x1, 0x0, + 0x0, 0xc5, 0x0, 0x9, 0x80, 0x0, 0x4e, 0x0, + 0x0, 0x3e, 0x20, 0x9, 0x80, 0x0, 0xd6, 0x0, + 0x0, 0x9, 0xa0, 0x9, 0x80, 0x8, 0xb0, 0x0, + 0x0, 0x1, 0xb0, 0x9, 0x80, 0x1c, 0x10, 0x0, + 0x1, 0x11, 0x11, 0x1a, 0x91, 0x11, 0x11, 0x10, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0xdd, 0xdd, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0x99, 0x89, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x9c, 0x9, 0x80, 0xba, 0x0, 0x0, + 0x0, 0xa, 0xc0, 0x9, 0x80, 0xb, 0xb1, 0x0, + 0x2, 0xcb, 0x0, 0x9, 0x80, 0x0, 0x9e, 0x40, + 0x2f, 0x80, 0x0, 0x9, 0x80, 0x0, 0x5, 0xe2, + 0x1, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + + /* U+7CBE "精" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe, 0x12, 0x0, 0x0, 0x69, 0x0, 0x0, + 0xc, 0xe, 0x1c, 0x3b, 0xdd, 0xee, 0xdd, 0xd3, + 0x8, 0x4e, 0x2d, 0x0, 0x0, 0x69, 0x0, 0x0, + 0x4, 0x8e, 0x67, 0x5, 0xcc, 0xee, 0xcc, 0xb0, + 0x1, 0x4e, 0x51, 0x0, 0x0, 0x69, 0x0, 0x0, + 0x2c, 0xcf, 0xdb, 0x5d, 0xdd, 0xdd, 0xdd, 0xd9, + 0x2, 0x5f, 0x52, 0x0, 0x22, 0x22, 0x22, 0x10, + 0x0, 0x8f, 0xb0, 0x3, 0xea, 0xaa, 0xad, 0x90, + 0x0, 0xde, 0xa7, 0x3, 0xc0, 0x0, 0x6, 0x90, + 0x5, 0x9e, 0x2e, 0x3, 0xfc, 0xcc, 0xcd, 0x90, + 0xd, 0x3e, 0x12, 0x3, 0xc0, 0x0, 0x6, 0x90, + 0x2a, 0xe, 0x10, 0x3, 0xfc, 0xcc, 0xce, 0x90, + 0x0, 0xe, 0x10, 0x3, 0xc0, 0x0, 0x6, 0x90, + 0x0, 0xe, 0x10, 0x3, 0xc0, 0x1, 0xee, 0x60, + + /* U+7CD6 "糖" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xf, 0x5, 0x0, 0x0, 0x98, 0x0, 0x0, + 0xc, 0xf, 0xe, 0x6e, 0xee, 0xef, 0xee, 0xe2, + 0xa, 0x3f, 0x39, 0x68, 0x0, 0x4, 0x0, 0x0, + 0x7, 0x6f, 0x84, 0x68, 0x22, 0x3e, 0x22, 0x20, + 0x3, 0x3f, 0x40, 0x68, 0x7a, 0xaf, 0xaa, 0xd0, + 0x1a, 0xbf, 0xaa, 0x69, 0x22, 0x3e, 0x23, 0xe2, + 0x5, 0x8f, 0x54, 0x7a, 0xaa, 0xaf, 0xaa, 0xf8, + 0x0, 0x9f, 0x40, 0x85, 0x12, 0x3e, 0x23, 0xd0, + 0x0, 0xdf, 0xd1, 0x94, 0x8a, 0xbf, 0xaa, 0x90, + 0x6, 0x7f, 0x59, 0xa3, 0x0, 0x1e, 0x0, 0x0, + 0xd, 0x1f, 0x1, 0xd0, 0xdd, 0xdd, 0xdd, 0xe0, + 0x38, 0xf, 0x1, 0xc0, 0xd1, 0x0, 0x1, 0xe0, + 0x0, 0xf, 0x8, 0x60, 0xd1, 0x0, 0x1, 0xe0, + 0x0, 0xf, 0xc, 0x0, 0xdd, 0xdd, 0xdd, 0xe0, + + /* U+7CFB "系" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x1, 0x24, 0x56, 0x8a, 0xcf, 0xd6, 0x0, 0xd, + 0xdc, 0xbd, 0xf7, 0x42, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xc2, 0x0, 0x6, 0x0, 0x0, 0x0, 0x7, + 0xb1, 0x0, 0x4e, 0x90, 0x0, 0x0, 0xd, 0xfa, + 0xbc, 0xde, 0x40, 0x0, 0x0, 0x0, 0x65, 0x38, + 0xfa, 0x10, 0x81, 0x0, 0x0, 0x0, 0x2b, 0xc3, + 0x0, 0x5, 0xd1, 0x0, 0x3, 0xaf, 0xa7, 0x89, + 0xab, 0xcf, 0xd0, 0x0, 0xcc, 0xa9, 0x78, 0xf4, + 0x32, 0x9, 0xa0, 0x0, 0x3, 0x60, 0x2e, 0x2, + 0x70, 0x3, 0x0, 0x3, 0xe4, 0x2, 0xe0, 0xb, + 0xb1, 0x0, 0x4, 0xe6, 0x0, 0x2e, 0x0, 0x9, + 0xd1, 0x3, 0xf4, 0x0, 0x3, 0xe0, 0x0, 0x8, + 0xd0, 0x1, 0x0, 0x5f, 0xf9, 0x0, 0x0, 0x1, + 0x0, + + /* U+7D00 "紀" */ + 0x0, 0x3, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x70, 0xa, 0xff, 0xff, 0xff, 0x20, + 0x0, 0x2e, 0x0, 0x1, 0x11, 0x11, 0x1e, 0x20, + 0x0, 0xa6, 0xe, 0x10, 0x0, 0x0, 0xe, 0x20, + 0x4, 0xc0, 0x79, 0x0, 0x0, 0x0, 0xe, 0x20, + 0x1e, 0xdd, 0xd0, 0x0, 0x0, 0x0, 0xe, 0x20, + 0x8, 0x5c, 0x31, 0x0, 0x11, 0x11, 0x1e, 0x20, + 0x0, 0x95, 0xc, 0x22, 0xff, 0xff, 0xff, 0x20, + 0xa, 0xeb, 0xcd, 0x82, 0xf0, 0x0, 0x1, 0x0, + 0x9, 0x63, 0x0, 0x82, 0xf0, 0x0, 0x0, 0x0, + 0x2, 0x23, 0x29, 0x22, 0xf0, 0x0, 0x0, 0x0, + 0x8, 0x67, 0x77, 0x72, 0xf0, 0x0, 0x0, 0x40, + 0xb, 0x35, 0x93, 0xb2, 0xf0, 0x0, 0x0, 0xe1, + 0xe, 0x4, 0xb0, 0x71, 0xf2, 0x0, 0x2, 0xf0, + 0x28, 0x1, 0x40, 0x0, 0xbf, 0xff, 0xff, 0x70, + + /* U+7D04 "約" */ + 0x0, 0x0, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0x10, 0x0, 0xf2, 0x0, 0x0, 0x0, + 0xb, 0x70, 0x0, 0x4d, 0x0, 0x0, 0x0, 0x5, + 0xc0, 0x33, 0xa, 0xa3, 0x33, 0x32, 0x2, 0xe2, + 0xe, 0x52, 0xfc, 0xcc, 0xcd, 0xd1, 0xdc, 0x9c, + 0x90, 0xb9, 0x0, 0x0, 0x3d, 0x8, 0x5a, 0xc2, + 0x3d, 0x0, 0x0, 0x4, 0xc0, 0x5, 0xd1, 0x5a, + 0x2, 0xc0, 0x0, 0x4c, 0x5, 0xe6, 0x69, 0xf0, + 0x7, 0xc0, 0x5, 0xb1, 0xfc, 0x97, 0x4b, 0x30, + 0x9, 0x90, 0x6a, 0x1, 0x0, 0x22, 0x50, 0x0, + 0xa, 0x7, 0x90, 0x79, 0x4a, 0x1d, 0x0, 0x0, + 0x0, 0x98, 0xa, 0x51, 0xd0, 0xb3, 0x0, 0x0, + 0xb, 0x60, 0xe0, 0xf, 0x4, 0x30, 0x1, 0x2, + 0xf3, 0x17, 0x0, 0x30, 0x0, 0x0, 0xef, 0xfa, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7D19 "紙" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xc0, 0x0, 0x1, 0x47, 0xbe, 0xa0, + 0x0, 0xe, 0x30, 0x3, 0xed, 0xaf, 0x50, 0x0, + 0x0, 0x89, 0x8, 0x54, 0xb0, 0xe, 0x10, 0x0, + 0x3, 0xd0, 0x3e, 0x14, 0xb0, 0xd, 0x20, 0x0, + 0x1e, 0xcb, 0xe5, 0x4, 0xb0, 0xd, 0x20, 0x0, + 0x6, 0x4b, 0x94, 0x4, 0xc0, 0xc, 0x30, 0x0, + 0x0, 0x6b, 0xb, 0x44, 0xff, 0xff, 0xff, 0xf8, + 0x5, 0xe5, 0x6b, 0xb4, 0xb0, 0x9, 0x50, 0x0, + 0xe, 0xc9, 0x74, 0xe5, 0xb0, 0x7, 0x70, 0x0, + 0x1, 0x1, 0x15, 0x24, 0xb0, 0x5, 0xa0, 0x0, + 0x9, 0x68, 0x66, 0x84, 0xb0, 0x2, 0xd0, 0x12, + 0xb, 0x35, 0x81, 0xd4, 0xb0, 0x0, 0xe2, 0x39, + 0xe, 0x4, 0xa0, 0x35, 0xd9, 0xe2, 0x7a, 0x67, + 0x18, 0x0, 0x10, 0xb, 0xc5, 0x0, 0xb, 0xe2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7D20 "素" */ + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x3, 0xdd, 0xdd, 0xde, 0xed, 0xdd, 0xdd, 0x50, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x5c, 0xcc, 0xce, 0xec, 0xcc, 0xc5, 0x0, + 0x1, 0x11, 0x11, 0x19, 0x91, 0x11, 0x11, 0x10, + 0x1c, 0xcc, 0xcc, 0xee, 0xcc, 0xcc, 0xcc, 0xc2, + 0x0, 0x0, 0x3a, 0xa3, 0x2, 0x94, 0x0, 0x0, + 0x0, 0xd, 0xfe, 0xcd, 0xec, 0x50, 0x0, 0x0, + 0x0, 0x2, 0x27, 0xc9, 0x30, 0xb, 0x60, 0x0, + 0x2, 0x7c, 0xfd, 0x9a, 0xab, 0xcd, 0xea, 0x0, + 0x2, 0x86, 0x65, 0x36, 0xc1, 0x0, 0x8, 0x50, + 0x0, 0x5, 0xe4, 0x4, 0xb0, 0x6d, 0x60, 0x0, + 0x3, 0xbc, 0x20, 0x5, 0xb0, 0x2, 0xad, 0x30, + 0x9, 0x50, 0x8, 0xfe, 0x70, 0x0, 0x5, 0x70, + + /* U+7D30 "細" */ + 0x0, 0x7, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe1, 0x0, 0xef, 0xff, 0xff, 0xfe, 0x0, + 0x78, 0x1, 0xe, 0x21, 0xc4, 0x12, 0xe0, 0x1d, + 0x7, 0x90, 0xe1, 0xb, 0x30, 0x1e, 0xa, 0x51, + 0xe1, 0xe, 0x10, 0xb3, 0x1, 0xe5, 0xfe, 0xf7, + 0x0, 0xe1, 0xb, 0x30, 0x1e, 0x1, 0x3c, 0x34, + 0xe, 0x10, 0xb3, 0x1, 0xe0, 0xd, 0x21, 0xc0, + 0xef, 0xff, 0xff, 0xfe, 0xb, 0xb7, 0xaf, 0x1e, + 0x10, 0xb4, 0x2, 0xe2, 0xc8, 0x63, 0x62, 0xe1, + 0xb, 0x30, 0x1e, 0x2, 0x3, 0x16, 0xe, 0x10, + 0xb3, 0x1, 0xe0, 0xd1, 0xd0, 0xc0, 0xe1, 0xb, + 0x30, 0x1e, 0xe, 0xb, 0x1a, 0x2e, 0x10, 0xb4, + 0x2, 0xe3, 0xb0, 0xa3, 0x53, 0xef, 0xff, 0xff, + 0xfe, 0x45, 0x2, 0x0, 0xe, 0x10, 0x0, 0x1, + 0xc0, + + /* U+7D39 "紹" */ + 0x0, 0x3, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa7, 0x0, 0xef, 0xff, 0xff, 0xfb, 0x0, + 0x2e, 0x0, 0x0, 0x0, 0xf0, 0x5, 0xa0, 0xa, + 0x70, 0xe1, 0x0, 0x2d, 0x0, 0x6a, 0x3, 0xd0, + 0x79, 0x0, 0x8, 0x90, 0x7, 0x81, 0xed, 0xce, + 0x10, 0x1, 0xe3, 0x0, 0x97, 0x9, 0x6c, 0x60, + 0x1, 0xba, 0x3, 0x3d, 0x40, 0x5, 0xa0, 0xd0, + 0xbb, 0x0, 0x7b, 0x80, 0x3, 0xe3, 0x4c, 0x50, + 0x10, 0x0, 0x0, 0x0, 0xee, 0xb9, 0x9a, 0x1f, + 0xee, 0xee, 0xf4, 0x1, 0x0, 0x5, 0x21, 0xe0, + 0x0, 0xc, 0x40, 0x76, 0x85, 0xc2, 0x1e, 0x0, + 0x0, 0xc4, 0xa, 0x46, 0x77, 0x61, 0xe0, 0x0, + 0xc, 0x40, 0xd1, 0x49, 0x36, 0x1f, 0x33, 0x33, + 0xd4, 0x1a, 0x2, 0x60, 0x1, 0xfb, 0xbb, 0xbe, + 0x40, + + /* U+7D42 "終" */ + 0x0, 0x5, 0x30, 0x0, 0x7, 0x20, 0x0, 0x0, + 0x0, 0xe, 0x30, 0x0, 0x3e, 0x0, 0x0, 0x0, + 0x0, 0x7a, 0x0, 0x0, 0xcf, 0xee, 0xee, 0x10, + 0x1, 0xe2, 0x4c, 0x8, 0xf4, 0x0, 0x7a, 0x0, + 0xa, 0x70, 0xd4, 0x7d, 0x5e, 0x12, 0xe2, 0x0, + 0x4f, 0xef, 0xa0, 0x52, 0x7, 0xbd, 0x50, 0x0, + 0x2, 0x3d, 0x52, 0x0, 0x3, 0xfd, 0x0, 0x0, + 0x0, 0xd3, 0x59, 0x0, 0x7e, 0x59, 0xd3, 0x0, + 0x1c, 0xc8, 0xbe, 0x4e, 0xb3, 0x0, 0x6e, 0xa1, + 0x2b, 0x85, 0x2b, 0x34, 0x9, 0xc4, 0x1, 0x60, + 0x3, 0x4, 0x26, 0x0, 0x0, 0x3c, 0x90, 0x0, + 0xc, 0x1d, 0xd, 0x0, 0x0, 0x0, 0x10, 0x0, + 0xe, 0xb, 0x1b, 0x25, 0xea, 0x50, 0x0, 0x0, + 0x3b, 0xa, 0x32, 0x10, 0x5, 0xae, 0x81, 0x0, + 0x24, 0x1, 0x0, 0x0, 0x0, 0x1, 0x9d, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7D44 "組" */ + 0x0, 0x3, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x60, 0x4, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x3d, 0x1, 0x4, 0xb0, 0x0, 0xf, 0x0, + 0x0, 0xc4, 0x1e, 0x4, 0xb0, 0x0, 0xf, 0x0, + 0x8, 0x90, 0xa7, 0x4, 0xb0, 0x0, 0xf, 0x0, + 0x2f, 0xff, 0xe0, 0x4, 0xeb, 0xbb, 0xbf, 0x0, + 0x2, 0xd, 0x46, 0x4, 0xc4, 0x44, 0x4f, 0x0, + 0x0, 0x99, 0xc, 0x14, 0xb0, 0x0, 0xf, 0x0, + 0x5, 0xe4, 0x6c, 0x54, 0xb0, 0x0, 0xf, 0x0, + 0x1f, 0xfc, 0x99, 0x94, 0xb1, 0x11, 0x1f, 0x0, + 0x2, 0x0, 0x5, 0x34, 0xfd, 0xdd, 0xdf, 0x0, + 0x8, 0x48, 0x5c, 0x14, 0xb0, 0x0, 0xf, 0x0, + 0xc, 0x26, 0x87, 0x64, 0xb0, 0x0, 0xf, 0x0, + 0xe, 0x4, 0x92, 0x34, 0xb0, 0x0, 0xf, 0x0, + 0x2a, 0x1, 0x40, 0xbf, 0xff, 0xff, 0xff, 0xf1, + + /* U+7D4C "経" */ + 0x0, 0x9, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0x10, 0x7f, 0xff, 0xff, 0xff, 0x40, + 0x0, 0x89, 0x2, 0x3, 0xd0, 0x0, 0x4e, 0x0, + 0x1, 0xe1, 0x5d, 0x0, 0xc5, 0x0, 0xd6, 0x0, + 0xa, 0x70, 0xd4, 0x0, 0x3e, 0x2a, 0xb0, 0x0, + 0x5f, 0xdf, 0xb0, 0x0, 0x7, 0xfd, 0x10, 0x0, + 0x25, 0x5e, 0x31, 0x0, 0x3c, 0xde, 0x60, 0x0, + 0x0, 0xc5, 0x59, 0x4b, 0xe6, 0x3, 0xcd, 0x71, + 0xa, 0xb4, 0x7e, 0x56, 0x0, 0xc4, 0x3, 0x80, + 0x4f, 0xc9, 0x7c, 0x30, 0x0, 0xc4, 0x0, 0x0, + 0x1, 0x1, 0x15, 0xd, 0xff, 0xff, 0xff, 0x60, + 0xe, 0x1d, 0xd, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0xe, 0xd, 0xb, 0x20, 0x0, 0xc4, 0x0, 0x0, + 0x3b, 0xb, 0x27, 0x40, 0x0, 0xc4, 0x0, 0x0, + 0x77, 0x7, 0x20, 0x8f, 0xff, 0xff, 0xff, 0xf1, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7D50 "結" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xa0, 0x0, 0x0, 0x89, 0x0, 0x0, + 0x0, 0xd, 0x40, 0x0, 0x0, 0x89, 0x0, 0x0, + 0x0, 0x7a, 0x7, 0x2f, 0xff, 0xff, 0xff, 0xf5, + 0x3, 0xd0, 0x6d, 0x0, 0x0, 0x89, 0x0, 0x0, + 0xe, 0xdc, 0xf3, 0x0, 0x0, 0x89, 0x0, 0x0, + 0x3, 0x1c, 0x76, 0x7, 0xcc, 0xee, 0xcc, 0xb0, + 0x0, 0x8a, 0xc, 0x21, 0x22, 0x22, 0x22, 0x20, + 0x7, 0xe7, 0x9d, 0x80, 0x0, 0x0, 0x0, 0x0, + 0xd, 0xb8, 0x65, 0xb4, 0xee, 0xee, 0xee, 0x70, + 0x1, 0x1, 0x7, 0x4, 0xb0, 0x0, 0x9, 0x70, + 0x8, 0x68, 0x4b, 0x24, 0xb0, 0x0, 0x8, 0x70, + 0xa, 0x36, 0x76, 0x74, 0xb0, 0x0, 0x8, 0x70, + 0xd, 0x4, 0x92, 0x94, 0xc3, 0x33, 0x3a, 0x70, + 0x1b, 0x2, 0x70, 0x4, 0xfc, 0xcc, 0xcd, 0x70, + + /* U+7D61 "絡" */ + 0x0, 0x5, 0x30, 0x0, 0x5, 0x50, 0x0, 0x0, + 0x0, 0xe, 0x30, 0x0, 0xe, 0x40, 0x0, 0x0, + 0x0, 0x7a, 0x0, 0x0, 0x8f, 0xee, 0xee, 0x10, + 0x1, 0xe1, 0x5c, 0x5, 0xf8, 0x0, 0x7b, 0x0, + 0xb, 0x50, 0xd4, 0x4f, 0x6d, 0x22, 0xf3, 0x0, + 0x6f, 0xef, 0xa0, 0x45, 0x4, 0xdc, 0x70, 0x0, + 0x12, 0x4d, 0x52, 0x0, 0x0, 0xde, 0x0, 0x0, + 0x1, 0xd2, 0x68, 0x0, 0x2d, 0x98, 0xd3, 0x0, + 0x1d, 0xb8, 0xbe, 0x19, 0xe5, 0x0, 0x4e, 0xa0, + 0x3b, 0x85, 0x3c, 0x4b, 0xec, 0xcc, 0xce, 0x70, + 0x2, 0x3, 0x26, 0x3, 0xd2, 0x22, 0x2e, 0x10, + 0xe, 0xd, 0x1d, 0x3, 0xc0, 0x0, 0xe, 0x10, + 0xd, 0xc, 0x1c, 0x23, 0xc0, 0x0, 0xe, 0x10, + 0x4a, 0xb, 0x27, 0x33, 0xc2, 0x22, 0x2e, 0x10, + 0x65, 0x6, 0x10, 0x3, 0xfd, 0xdd, 0xdf, 0x10, + + /* U+7D66 "給" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0xe, 0x40, 0x0, 0x1, 0xf4, 0x0, 0x0, + 0x0, 0x6c, 0x0, 0x0, 0x9, 0xdd, 0x0, 0x0, + 0x0, 0xd3, 0x46, 0x0, 0x3d, 0xb, 0x90, 0x0, + 0x8, 0x80, 0xd4, 0x3, 0xe3, 0x1, 0xe6, 0x0, + 0x4f, 0xab, 0xb0, 0x4f, 0x50, 0x0, 0x3e, 0x80, + 0x37, 0x7f, 0x32, 0xe8, 0xee, 0xee, 0xe6, 0xd3, + 0x0, 0xb5, 0x67, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xa2, 0x5d, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5f, 0xec, 0x9d, 0x1e, 0xfe, 0xee, 0xef, 0x10, + 0x2, 0x0, 0x25, 0xe, 0x20, 0x0, 0xf, 0x10, + 0xe, 0x1d, 0x3a, 0xe, 0x20, 0x0, 0xf, 0x10, + 0x1e, 0xd, 0x1c, 0xe, 0x20, 0x0, 0xf, 0x10, + 0x5a, 0xb, 0x33, 0xe, 0xcc, 0xcc, 0xcf, 0x10, + 0x44, 0x2, 0x0, 0xe, 0x53, 0x33, 0x3e, 0x10, + + /* U+7D71 "統" */ + 0x0, 0x1, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0xb, 0x60, 0x0, 0x6, 0xa0, 0x0, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0x1, 0xe2, 0x0, 0x0, + 0x0, 0xb6, 0x7, 0x6e, 0xef, 0xfe, 0xee, 0xe0, + 0x5, 0xc0, 0x8a, 0x0, 0xd, 0x50, 0x50, 0x0, + 0x2e, 0xa9, 0xe1, 0x0, 0x99, 0x0, 0xa7, 0x0, + 0x18, 0x6e, 0x61, 0x7, 0xe4, 0x46, 0x8f, 0x30, + 0x0, 0x89, 0x4b, 0x3f, 0xcb, 0x97, 0x67, 0xc0, + 0x6, 0xc3, 0x5f, 0x10, 0x43, 0x5, 0x20, 0x30, + 0x2f, 0xeb, 0x8c, 0x50, 0xa5, 0xb, 0x40, 0x0, + 0x1, 0x0, 0x24, 0x10, 0xb4, 0xb, 0x40, 0x0, + 0xa, 0x2d, 0x39, 0x0, 0xe1, 0xb, 0x40, 0x0, + 0xd, 0xc, 0xd, 0x4, 0xd0, 0xb, 0x40, 0x93, + 0x1d, 0xb, 0x25, 0x2d, 0x50, 0xb, 0x50, 0xb3, + 0x48, 0x5, 0x13, 0xe8, 0x0, 0x7, 0xff, 0xd0, + 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, + + /* U+7D75 "絵" */ + 0x0, 0x2, 0x10, 0x0, 0x0, 0x31, 0x0, 0x0, + 0x0, 0xc, 0x60, 0x0, 0x1, 0xe5, 0x0, 0x0, + 0x0, 0x3d, 0x0, 0x0, 0x9, 0xcd, 0x10, 0x0, + 0x0, 0xc5, 0x2a, 0x0, 0x3e, 0x17, 0xb0, 0x0, + 0x6, 0xa0, 0xb8, 0x2, 0xe3, 0x0, 0xab, 0x0, + 0x3f, 0xbc, 0xe0, 0x3e, 0x50, 0x0, 0xa, 0xc1, + 0x16, 0x5f, 0x51, 0xa5, 0xff, 0xff, 0xf9, 0x92, + 0x0, 0xa8, 0x4a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xc2, 0x4f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2f, 0xfc, 0xac, 0x7e, 0xef, 0xfe, 0xee, 0xd0, + 0x2, 0x0, 0x14, 0x10, 0xd, 0x40, 0x0, 0x0, + 0xa, 0x2c, 0x3a, 0x0, 0x7b, 0x0, 0x90, 0x0, + 0xd, 0xd, 0xd, 0x1, 0xe2, 0x0, 0x98, 0x0, + 0x1d, 0xb, 0x26, 0x2b, 0x81, 0x24, 0x6f, 0x30, + 0x49, 0x6, 0x20, 0xaf, 0xec, 0xb9, 0x89, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, + + /* U+7D93 "經" */ + 0x0, 0x7, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x6f, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x7a, 0x1, 0x0, 0x40, 0x13, 0x2, 0x20, + 0x0, 0xd2, 0x6b, 0x5, 0xb0, 0x88, 0xc, 0x40, + 0x9, 0x70, 0xe4, 0xd, 0x31, 0xd0, 0x5b, 0x0, + 0x4f, 0xef, 0xa0, 0x6a, 0xa, 0x60, 0xe3, 0x0, + 0x15, 0x4e, 0x42, 0x2d, 0x6, 0xb0, 0xa8, 0x0, + 0x0, 0xb6, 0x59, 0x8, 0x80, 0xb5, 0xe, 0x30, + 0x7, 0xb2, 0x5e, 0x1, 0xe1, 0x3d, 0x6, 0xb0, + 0x2f, 0xfc, 0xad, 0x31, 0x21, 0x12, 0x11, 0x20, + 0x2, 0x0, 0x15, 0x2e, 0xee, 0xfe, 0xee, 0x80, + 0xa, 0x2c, 0x49, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0xe, 0xc, 0x1d, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x1d, 0xb, 0x25, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x49, 0x4, 0x10, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7D9A "続" */ + 0x0, 0xc, 0x0, 0x0, 0x0, 0xa5, 0x0, 0x0, + 0x0, 0x59, 0x0, 0x7e, 0xee, 0xff, 0xee, 0xe1, + 0x0, 0xb1, 0x57, 0x0, 0x0, 0xa5, 0x0, 0x0, + 0x5, 0x60, 0xd3, 0xa, 0xaa, 0xec, 0xaa, 0x50, + 0x2e, 0xef, 0x90, 0x3, 0x33, 0x33, 0x33, 0x10, + 0x28, 0x5e, 0x10, 0x13, 0x33, 0x33, 0x33, 0x30, + 0x0, 0xa4, 0x74, 0x6d, 0xaa, 0xaa, 0xab, 0xf0, + 0x6, 0xb4, 0x9a, 0x68, 0x14, 0x2, 0x30, 0xf0, + 0x2f, 0xea, 0x7d, 0x45, 0x4b, 0x5, 0x90, 0x90, + 0x2, 0x0, 0x14, 0x0, 0x5a, 0x5, 0x90, 0x0, + 0x9, 0x4c, 0x2a, 0x0, 0x97, 0x5, 0x90, 0x0, + 0xc, 0x1b, 0x1c, 0x1, 0xe2, 0x5, 0x90, 0x53, + 0x1d, 0xa, 0x36, 0x3c, 0x80, 0x5, 0x90, 0x95, + 0x37, 0x3, 0x10, 0xd8, 0x0, 0x3, 0xff, 0xe1, + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + + /* U+7DAD "維" */ + 0x0, 0x5, 0x20, 0x0, 0x16, 0x23, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x6b, 0x4d, 0x0, 0x0, + 0x0, 0x6a, 0x0, 0x0, 0xc5, 0xc, 0x40, 0x0, + 0x0, 0xd2, 0x5c, 0x2, 0xfc, 0xbc, 0xbb, 0xb0, + 0x7, 0x70, 0xd4, 0xb, 0xd3, 0x3f, 0x33, 0x30, + 0x3f, 0xbd, 0xb0, 0x4f, 0xc0, 0xf, 0x0, 0x0, + 0x28, 0x6e, 0x21, 0xb9, 0xd2, 0x2f, 0x22, 0x20, + 0x0, 0xa5, 0x3c, 0x23, 0xfc, 0xcf, 0xcc, 0x90, + 0x7, 0xa1, 0x3e, 0x33, 0xc0, 0xf, 0x0, 0x0, + 0x3f, 0xec, 0x9a, 0x83, 0xc0, 0xf, 0x0, 0x0, + 0x2, 0x0, 0x4, 0x3, 0xfe, 0xef, 0xee, 0xb0, + 0xc, 0x1c, 0xd, 0x3, 0xc0, 0xf, 0x0, 0x0, + 0xd, 0xc, 0x9, 0x53, 0xc0, 0xf, 0x0, 0x0, + 0x3a, 0xa, 0x23, 0x53, 0xfe, 0xef, 0xee, 0xe4, + 0x34, 0x2, 0x0, 0x3, 0xc0, 0x0, 0x0, 0x0, + + /* U+7DB2 "網" */ + 0x0, 0x5, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe4, 0x1, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x6b, 0x1, 0x1e, 0x4, 0x0, 0x50, 0xf0, 0xd, + 0x23, 0xe1, 0xe0, 0xc0, 0x1b, 0xf, 0x9, 0x70, + 0xc6, 0x1e, 0x8, 0x46, 0x60, 0xf3, 0xff, 0xfc, + 0x1, 0xe7, 0xba, 0xdb, 0x6f, 0x2, 0x2e, 0x44, + 0x1e, 0x23, 0xc3, 0x32, 0xf0, 0xc, 0x52, 0xd1, + 0xe0, 0x8, 0x50, 0xf, 0x9, 0xc5, 0x7f, 0x3e, + 0x7e, 0xee, 0xe5, 0xf2, 0xeb, 0x86, 0xa7, 0xe0, + 0xe0, 0x0, 0xf, 0x2, 0x3, 0x35, 0x1e, 0xe, + 0x0, 0x0, 0xf0, 0xb2, 0xd2, 0xc1, 0xe0, 0xfd, + 0xdd, 0x4f, 0xd, 0xc, 0xc, 0x2e, 0x0, 0x0, + 0x0, 0xf2, 0xb0, 0xb2, 0x32, 0xe0, 0x0, 0x0, + 0x1f, 0x24, 0x1, 0x0, 0x1e, 0x0, 0x0, 0xae, + 0x90, + + /* U+7DD1 "緑" */ + 0x0, 0x4, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x50, 0xa, 0xee, 0xee, 0xee, 0x0, + 0x0, 0x5d, 0x0, 0x0, 0x0, 0x0, 0xe, 0x0, + 0x0, 0xd4, 0xa, 0x0, 0x0, 0x0, 0xe, 0x0, + 0x8, 0xa0, 0x8a, 0x4, 0xdd, 0xdd, 0xde, 0x0, + 0x4f, 0xbb, 0xd1, 0x0, 0x0, 0x0, 0xe, 0x0, + 0x14, 0x3e, 0x53, 0x8e, 0xee, 0xee, 0xef, 0xe1, + 0x0, 0xb6, 0x1c, 0x1, 0x0, 0x96, 0x0, 0x10, + 0xa, 0xd6, 0x8f, 0x1b, 0x70, 0x96, 0x7, 0xb0, + 0x2d, 0xa7, 0x5a, 0x40, 0xc6, 0x99, 0x8a, 0x0, + 0x2, 0x3, 0x35, 0x0, 0x14, 0xdf, 0xa0, 0x0, + 0xc, 0x1d, 0x2a, 0x0, 0x8d, 0xc7, 0xd4, 0x0, + 0xe, 0xb, 0x1d, 0x4e, 0x90, 0x96, 0x2d, 0x80, + 0x3b, 0xa, 0x33, 0x44, 0x0, 0x96, 0x1, 0x81, + 0x35, 0x2, 0x0, 0x0, 0x2e, 0xe3, 0x0, 0x0, + + /* U+7DD2 "緒" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x40, 0x0, 0x7, 0x80, 0x0, 0x10, + 0x0, 0x3d, 0x0, 0x3, 0x39, 0xa3, 0x28, 0x90, + 0x0, 0xb5, 0x35, 0xb, 0xbd, 0xeb, 0xad, 0x0, + 0x4, 0xb0, 0xb5, 0x0, 0x7, 0x80, 0xc4, 0x0, + 0x2e, 0x9a, 0xb0, 0x22, 0x29, 0xaa, 0xb2, 0x20, + 0x29, 0x7e, 0x20, 0xad, 0xdd, 0xfe, 0xdd, 0xd1, + 0x0, 0xb4, 0x56, 0x0, 0x3c, 0x70, 0x0, 0x0, + 0xa, 0xc8, 0xbb, 0x3a, 0xff, 0xee, 0xee, 0x30, + 0x2c, 0x96, 0x4c, 0xb7, 0xf0, 0x0, 0xc, 0x40, + 0x0, 0x1, 0x35, 0x0, 0xf0, 0x0, 0xc, 0x40, + 0xc, 0x2d, 0x49, 0x0, 0xfe, 0xdd, 0xdf, 0x40, + 0xe, 0xc, 0x1c, 0x0, 0xf0, 0x0, 0xc, 0x40, + 0x1c, 0xb, 0x29, 0x0, 0xf3, 0x22, 0x2d, 0x40, + 0x47, 0x6, 0x20, 0x0, 0xfb, 0xbb, 0xbe, 0x40, + + /* U+7DDA "線" */ + 0x0, 0x4, 0x20, 0x0, 0x0, 0x71, 0x0, 0x0, + 0x0, 0xe, 0x30, 0x0, 0x4, 0xd0, 0x0, 0x0, + 0x0, 0x6b, 0x0, 0xc, 0xde, 0xfd, 0xdd, 0x30, + 0x0, 0xd4, 0x4a, 0xe, 0x10, 0x0, 0xc, 0x40, + 0x7, 0xb0, 0xc4, 0xe, 0x31, 0x11, 0x1c, 0x40, + 0x3f, 0xaa, 0xa0, 0xe, 0xbb, 0xbb, 0xbe, 0x40, + 0x17, 0x6e, 0x30, 0xe, 0x10, 0x0, 0xc, 0x40, + 0x0, 0xb4, 0x76, 0xd, 0xdd, 0xfe, 0xde, 0x40, + 0xa, 0xc6, 0xab, 0x0, 0x0, 0xb5, 0x3, 0x30, + 0x1c, 0x96, 0x3d, 0x6e, 0xea, 0xbc, 0x3d, 0x30, + 0x3, 0x14, 0x63, 0x0, 0x97, 0xbe, 0xd2, 0x0, + 0xc, 0x2d, 0x57, 0x3, 0xe0, 0xb6, 0xd1, 0x0, + 0xe, 0xd, 0x1b, 0x2d, 0x40, 0xb4, 0x6c, 0x10, + 0x2b, 0xc, 0x11, 0xe5, 0x0, 0xc4, 0x6, 0xd0, + 0x24, 0x0, 0x0, 0x0, 0x7f, 0xd1, 0x0, 0x10, + + /* U+7DE0 "締" */ + 0x0, 0x3, 0x10, 0x0, 0x1, 0x30, 0x0, 0x0, + 0x0, 0xd3, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, + 0x5b, 0x0, 0x9e, 0xee, 0xff, 0xee, 0xb0, 0xd, + 0x24, 0x80, 0xc, 0x0, 0xc, 0x10, 0x8, 0x70, + 0xd3, 0x0, 0xb4, 0x2, 0xb0, 0x3, 0xfe, 0xf9, + 0xb, 0xde, 0xdd, 0xee, 0xdc, 0x2, 0x2d, 0x43, + 0xd1, 0x0, 0x70, 0x0, 0xf0, 0xc, 0x33, 0x99, + 0x0, 0xe, 0x10, 0xa, 0xb, 0xc8, 0xbd, 0x1b, + 0xbb, 0xfc, 0xbb, 0x21, 0xb8, 0x53, 0xc2, 0xe2, + 0x2e, 0x42, 0xc3, 0x2, 0x3, 0x43, 0x1d, 0x0, + 0xe1, 0xb, 0x30, 0xb2, 0xd4, 0x81, 0xd0, 0xe, + 0x10, 0xb3, 0xd, 0xc, 0x1b, 0x1d, 0x0, 0xe1, + 0x2c, 0x32, 0xc0, 0xb2, 0x91, 0xa0, 0xe, 0x1c, + 0xa0, 0x47, 0x4, 0x10, 0x0, 0x0, 0xe1, 0x0, + 0x0, + + /* U+7DE9 "緩" */ + 0x0, 0x8, 0x30, 0x0, 0x13, 0x47, 0x9c, 0x20, + 0x0, 0x1e, 0x0, 0x7d, 0xcb, 0xa7, 0x54, 0x0, + 0x0, 0x78, 0x1, 0x9, 0x4, 0xb0, 0x1e, 0x10, + 0x0, 0xe1, 0x78, 0x9, 0x60, 0xe0, 0x88, 0x0, + 0x9, 0x70, 0xd1, 0x3, 0x70, 0x71, 0xe1, 0x0, + 0x4f, 0xbd, 0x70, 0x3e, 0xee, 0xee, 0xfe, 0x90, + 0x15, 0x5c, 0x22, 0x0, 0x3c, 0x0, 0x0, 0x0, + 0x0, 0xb2, 0x2b, 0x7a, 0xce, 0xaa, 0xaa, 0xa0, + 0xa, 0xa7, 0x9f, 0x32, 0xa9, 0x22, 0x22, 0x20, + 0x2b, 0x85, 0x36, 0x20, 0xdd, 0xbb, 0xba, 0x0, + 0x3, 0x4, 0x27, 0x2, 0xfd, 0x32, 0x9b, 0x0, + 0xc, 0x1c, 0xc, 0x7, 0x99, 0xa3, 0xe2, 0x0, + 0xd, 0xb, 0x1a, 0x3e, 0x20, 0xcf, 0x50, 0x0, + 0x3a, 0xa, 0x33, 0xc7, 0x3b, 0xd9, 0xe7, 0x10, + 0x24, 0x0, 0x2, 0x95, 0xd7, 0x0, 0x29, 0xe1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7DF4 "練" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x50, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0x9e, 0xee, 0xfe, 0xee, 0xe1, + 0x0, 0xa6, 0x4b, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x4, 0xb0, 0xc4, 0x1, 0x11, 0xd5, 0x11, 0x10, + 0x2e, 0x99, 0xb0, 0x2e, 0xcc, 0xec, 0xcd, 0x90, + 0x28, 0x7e, 0x20, 0x2b, 0x61, 0xb2, 0x68, 0x90, + 0x0, 0x95, 0x49, 0x2b, 0x47, 0xb2, 0xb5, 0x90, + 0x7, 0xb3, 0x5e, 0x2b, 0x5, 0xb3, 0x45, 0x90, + 0x3f, 0xda, 0x8d, 0x4e, 0xef, 0xff, 0xee, 0x80, + 0x1, 0x1, 0x26, 0x0, 0xd, 0xfd, 0x50, 0x0, + 0xc, 0x2c, 0x3a, 0x0, 0x98, 0xc4, 0xc3, 0x0, + 0xe, 0xb, 0x1c, 0x9, 0xb0, 0xc3, 0x2d, 0x40, + 0x2b, 0xa, 0x25, 0x9a, 0x0, 0xc3, 0x2, 0xd1, + 0x45, 0x3, 0x10, 0x0, 0x0, 0xc3, 0x0, 0x0, + + /* U+7E3D "總" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x3, 0xc0, 0x0, 0x0, + 0x0, 0x69, 0x0, 0xd, 0xee, 0xee, 0xee, 0x80, + 0x0, 0xd2, 0x48, 0xd, 0x2, 0x80, 0x6, 0x80, + 0x6, 0x90, 0xc4, 0xd, 0xb, 0xaa, 0xe6, 0x80, + 0x2f, 0x9a, 0xb0, 0xd, 0x77, 0x65, 0x66, 0x80, + 0x18, 0x6e, 0x20, 0xd, 0x0, 0xaf, 0x16, 0x80, + 0x0, 0x87, 0x66, 0xd, 0x2a, 0x95, 0xb6, 0x80, + 0x4, 0xb1, 0x6c, 0xd, 0x56, 0x33, 0x48, 0x80, + 0x2f, 0xeb, 0x8d, 0x19, 0xaa, 0xba, 0xaa, 0x60, + 0x3, 0x0, 0x23, 0x1, 0x12, 0xb4, 0x5, 0x0, + 0x8, 0x5c, 0x48, 0xd, 0x68, 0x1d, 0x1b, 0x40, + 0xb, 0x2b, 0x1c, 0x4a, 0x68, 0x2, 0x25, 0xd0, + 0xd, 0xa, 0x26, 0xb4, 0x68, 0x0, 0x49, 0x92, + 0x28, 0x4, 0x10, 0x10, 0x3e, 0xee, 0xe4, 0x0, + + /* U+7E3E "績" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x40, 0x7c, 0xcc, 0xfd, 0xcc, 0x80, + 0x0, 0x2c, 0x1, 0x0, 0x0, 0xd3, 0x0, 0x0, + 0x0, 0xb4, 0x4c, 0x2c, 0xcc, 0xfd, 0xcc, 0x30, + 0x5, 0x90, 0xc4, 0x0, 0x0, 0xd3, 0x0, 0x0, + 0x2f, 0xcc, 0xa2, 0xdd, 0xdd, 0xfd, 0xdd, 0xd3, + 0x15, 0x4d, 0x31, 0x4, 0x44, 0x44, 0x44, 0x10, + 0x0, 0xb4, 0x48, 0x1e, 0x66, 0x66, 0x6d, 0x40, + 0x9, 0xc7, 0xad, 0x1f, 0xaa, 0xaa, 0xae, 0x40, + 0x1c, 0x97, 0x4c, 0x3e, 0x0, 0x0, 0xc, 0x40, + 0x1, 0x2, 0x35, 0x2f, 0xaa, 0xaa, 0xae, 0x40, + 0xb, 0x2c, 0x38, 0x1e, 0x0, 0x0, 0xc, 0x40, + 0xd, 0xc, 0xc, 0x1b, 0xbb, 0xbb, 0xbb, 0x30, + 0x1c, 0xb, 0x16, 0x4, 0xd7, 0x3, 0xd5, 0x0, + 0x59, 0x6, 0x13, 0xdb, 0x30, 0x0, 0x2b, 0xb0, + 0x1, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x30, + + /* U+7E54 "織" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x0, 0x8, 0x60, 0xd, 0x12, 0x0, + 0x0, 0x68, 0x6, 0xdd, 0xfd, 0xad, 0x3d, 0x10, + 0x0, 0xc1, 0xa3, 0x82, 0xb, 0x1c, 0x26, 0x90, + 0x7, 0x72, 0xc0, 0x75, 0x1d, 0xc, 0x20, 0x70, + 0x2f, 0xdf, 0x48, 0xcd, 0xce, 0xbe, 0xcb, 0xb0, + 0x3, 0x3b, 0x32, 0x33, 0x33, 0x3b, 0x63, 0x30, + 0x0, 0xb2, 0xa0, 0xbc, 0xcc, 0x59, 0x54, 0x70, + 0x6, 0xa6, 0xd2, 0xd0, 0x7, 0x67, 0x6a, 0x40, + 0x1f, 0xda, 0xa4, 0xd0, 0x8, 0x66, 0x9d, 0x0, + 0x2, 0x0, 0x31, 0xeb, 0xbd, 0x63, 0xf6, 0x0, + 0xa, 0x48, 0xb0, 0xd0, 0x7, 0x63, 0xf0, 0x20, + 0xc, 0xb, 0x74, 0xec, 0xce, 0x9d, 0xd2, 0x92, + 0xc, 0xc, 0x26, 0xc0, 0x6, 0xf3, 0x79, 0xc0, + 0x38, 0x4, 0x0, 0x0, 0xd, 0x40, 0xc, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7E70 "繰" */ + 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x1, 0xfc, 0xcc, 0xe6, 0x0, + 0x0, 0x6a, 0x0, 0x1, 0xe0, 0x0, 0x96, 0x0, + 0x0, 0xd2, 0x59, 0x1, 0xf6, 0x66, 0xc6, 0x0, + 0x7, 0x90, 0xd4, 0x0, 0x66, 0x66, 0x62, 0x0, + 0x2f, 0xcc, 0xa0, 0x8d, 0xcd, 0x2c, 0xcc, 0xd0, + 0x17, 0x5e, 0x30, 0x84, 0xb, 0x2d, 0x0, 0xe0, + 0x0, 0xb4, 0x84, 0x85, 0xc, 0x2d, 0x0, 0xe0, + 0x7, 0xc6, 0xb9, 0x6b, 0xbb, 0xab, 0xbb, 0xb0, + 0x2f, 0xda, 0x7c, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0x0, 0x36, 0xce, 0xef, 0xff, 0xee, 0xe1, + 0xa, 0x3c, 0x74, 0x0, 0x5c, 0xea, 0x80, 0x0, + 0xd, 0xd, 0x29, 0x6, 0xd1, 0xe2, 0xa9, 0x0, + 0x1d, 0xc, 0x6, 0xda, 0x10, 0xe1, 0x8, 0xd2, + 0x48, 0x4, 0x0, 0x30, 0x0, 0xe1, 0x0, 0x20, + + /* U+7E7C "繼" */ + 0x0, 0x6, 0x0, 0x0, 0x4, 0x0, 0x41, 0x0, + 0x0, 0x2d, 0x0, 0xe1, 0x66, 0x0, 0xc0, 0x0, + 0x0, 0x87, 0x0, 0xe1, 0xb4, 0x66, 0x58, 0x20, + 0x0, 0xd1, 0x94, 0xe8, 0xed, 0x1f, 0xda, 0x0, + 0x7, 0x81, 0xe0, 0xe1, 0x75, 0x51, 0xb5, 0x40, + 0x2f, 0x9c, 0x70, 0xe6, 0xfb, 0xbb, 0xdb, 0x90, + 0x19, 0x7d, 0x0, 0xe3, 0x20, 0x64, 0x10, 0x70, + 0x0, 0xa4, 0xc0, 0xed, 0xcc, 0xcc, 0xdc, 0xb0, + 0x5, 0xa0, 0xb2, 0xe1, 0x48, 0x0, 0xb1, 0x0, + 0x1f, 0xed, 0xc6, 0xe1, 0xb2, 0x53, 0x84, 0x20, + 0x2, 0x0, 0x53, 0xe7, 0xed, 0x3d, 0xcc, 0x0, + 0x9, 0x49, 0xa1, 0xe2, 0x58, 0x31, 0x95, 0x40, + 0xd, 0xb, 0x65, 0xe5, 0xea, 0xb8, 0xda, 0x90, + 0xc, 0xc, 0x28, 0xe4, 0x41, 0x74, 0x31, 0x60, + 0x49, 0xa, 0x0, 0xcd, 0xdd, 0xdd, 0xdd, 0xd5, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7E8C "續" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x21, 0xcc, 0xcc, 0xfc, 0xcc, 0xc0, + 0x0, 0x4a, 0x0, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0xb3, 0x78, 0x6e, 0xee, 0xee, 0xee, 0x60, + 0x4, 0xa0, 0xd2, 0x22, 0x22, 0x22, 0x22, 0x20, + 0x1e, 0x9a, 0x80, 0xf9, 0xae, 0x9c, 0xb9, 0xe0, + 0x29, 0x8d, 0x0, 0xe0, 0x2b, 0x8, 0x50, 0xe0, + 0x0, 0xa3, 0x84, 0xbb, 0xbb, 0xbb, 0xbb, 0xb0, + 0x9, 0xb5, 0x9a, 0x59, 0x88, 0x88, 0x89, 0x40, + 0x1c, 0x96, 0x4d, 0x7c, 0x88, 0x88, 0x8d, 0x60, + 0x2, 0x13, 0x72, 0x79, 0x22, 0x22, 0x2a, 0x60, + 0xb, 0x3c, 0x67, 0x7b, 0x77, 0x77, 0x7c, 0x60, + 0xd, 0xd, 0x1b, 0x7d, 0xbb, 0xab, 0xbd, 0x60, + 0x1c, 0xc, 0x6, 0x4, 0xc6, 0x5, 0xc6, 0x0, + 0x59, 0x6, 0x3, 0xda, 0x30, 0x0, 0x29, 0xd1, + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + + /* U+7EDF "统" */ + 0x0, 0x2, 0x10, 0x0, 0x1, 0x30, 0x0, 0x0, + 0x0, 0xa, 0xa0, 0x0, 0x3, 0xe0, 0x0, 0x0, + 0x0, 0x1f, 0x20, 0x0, 0x0, 0xb4, 0x0, 0x0, + 0x0, 0x9a, 0x0, 0x7e, 0xef, 0xfe, 0xee, 0xe1, + 0x2, 0xe1, 0x2c, 0x0, 0x1e, 0x40, 0x10, 0x0, + 0xc, 0x72, 0xb9, 0x0, 0xb8, 0x0, 0xd3, 0x0, + 0x5f, 0xfe, 0xe0, 0x7, 0xc0, 0x1, 0x6d, 0x0, + 0x2, 0x1e, 0x40, 0x9f, 0xee, 0xed, 0xcc, 0x80, + 0x0, 0xb7, 0x0, 0x34, 0x92, 0x7, 0x11, 0x90, + 0x9, 0xe9, 0xcc, 0x0, 0xf1, 0xd, 0x30, 0x0, + 0x3e, 0xa7, 0x30, 0x0, 0xf0, 0xd, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xd0, 0xd, 0x30, 0x0, + 0x0, 0x38, 0xcd, 0xa, 0x80, 0xd, 0x30, 0xa2, + 0x3e, 0xd8, 0x30, 0x7e, 0x10, 0xd, 0x30, 0xd2, + 0x2, 0x0, 0xb, 0xc2, 0x0, 0x9, 0xff, 0xc0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+7F3A "缺" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xc0, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x7, 0xc8, 0x88, 0x60, 0x0, 0xe1, 0x0, 0x0, + 0xc, 0x4b, 0x83, 0x23, 0xee, 0xfe, 0xed, 0x0, + 0x5a, 0xa, 0x50, 0x0, 0x11, 0xe3, 0x3e, 0x0, + 0x33, 0xa, 0x50, 0x0, 0x0, 0xe1, 0x1e, 0x0, + 0x13, 0x3b, 0x73, 0x30, 0x0, 0xe1, 0x1e, 0x0, + 0x5b, 0xbe, 0xdb, 0xb0, 0x0, 0xf0, 0x1e, 0x0, + 0x4, 0xa, 0x51, 0x38, 0xdd, 0xfd, 0xdf, 0xc0, + 0xd, 0xa, 0x53, 0xa0, 0x3, 0xfe, 0x10, 0x0, + 0xd, 0xa, 0x53, 0xa0, 0x6, 0x9d, 0x50, 0x0, + 0xd, 0xa, 0x53, 0xa0, 0xc, 0x45, 0xc0, 0x0, + 0xe, 0x3c, 0xaa, 0xa0, 0x5e, 0x0, 0xe5, 0x0, + 0xc, 0xa8, 0x66, 0xa2, 0xe5, 0x0, 0x4f, 0x50, + 0x0, 0x0, 0x0, 0x1c, 0x80, 0x0, 0x5, 0xe1, + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + + /* U+7F6E "置" */ + 0x1, 0xfc, 0xce, 0xec, 0xce, 0xec, 0xcf, 0x40, + 0x1, 0xe0, 0x6, 0x90, 0x9, 0x60, 0xc, 0x40, + 0x1, 0xfa, 0xac, 0xda, 0xad, 0xca, 0xae, 0x40, + 0x0, 0x22, 0x22, 0x2c, 0x72, 0x22, 0x22, 0x0, + 0xc, 0xdd, 0xdd, 0xdf, 0xed, 0xdd, 0xdd, 0xa0, + 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xcb, 0xce, 0xbb, 0xbc, 0xb0, 0x0, + 0x0, 0xe, 0x43, 0x33, 0x33, 0x35, 0xd0, 0x0, + 0x0, 0xe, 0x76, 0x66, 0x66, 0x68, 0xd0, 0x0, + 0x0, 0xe, 0xba, 0xaa, 0xaa, 0xab, 0xd0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x2, 0xd0, 0x0, + 0x0, 0xe, 0xba, 0xaa, 0xaa, 0xab, 0xd0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x2, 0xd0, 0x0, + 0xc, 0xcf, 0xdc, 0xcc, 0xcc, 0xcd, 0xfc, 0xc1, + + /* U+7F8E "美" */ + 0x0, 0x0, 0x30, 0x0, 0x0, 0x3, 0x0, 0x0, + 0x0, 0x1, 0xe4, 0x0, 0x0, 0x5e, 0x10, 0x0, + 0x0, 0x0, 0x5c, 0x0, 0x1, 0xe5, 0x0, 0x0, + 0x6, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0x60, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x9e, 0xee, 0xef, 0xfe, 0xee, 0xea, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x2, 0x22, 0x22, 0x2a, 0x92, 0x22, 0x22, 0x20, + 0x1c, 0xcc, 0xcc, 0xcf, 0xec, 0xcc, 0xcc, 0xc2, + 0x0, 0x0, 0x0, 0xd, 0x50, 0x0, 0x0, 0x0, + 0xa, 0xee, 0xee, 0xff, 0xfe, 0xee, 0xee, 0xe0, + 0x0, 0x0, 0x0, 0x9a, 0xb7, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xe2, 0x1e, 0x80, 0x0, 0x0, + 0x0, 0x15, 0xcd, 0x20, 0x1, 0xbd, 0x61, 0x0, + 0x1d, 0xfb, 0x50, 0x0, 0x0, 0x4, 0xbf, 0xd1, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + + /* U+7FA9 "義" */ + 0x0, 0x0, 0x61, 0x0, 0x0, 0x26, 0x0, 0x0, + 0x0, 0x0, 0x7c, 0x0, 0x0, 0xb7, 0x0, 0x0, + 0x5, 0xdd, 0xef, 0xed, 0xde, 0xfe, 0xdd, 0x60, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x7d, 0xdd, 0xde, 0xed, 0xdd, 0xd7, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x1c, 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xcc, 0xc1, + 0x3, 0x45, 0x68, 0xaa, 0x59, 0x37, 0x53, 0x30, + 0x9, 0xba, 0xd9, 0x31, 0x2e, 0x5, 0xda, 0x0, + 0x1, 0x11, 0xb6, 0x11, 0x2f, 0x11, 0x27, 0x10, + 0x1c, 0xcc, 0xed, 0xcc, 0xce, 0xdc, 0xcc, 0xc1, + 0x0, 0x1, 0xb8, 0x45, 0x26, 0xa1, 0xb6, 0x0, + 0x1c, 0xba, 0xda, 0x65, 0x10, 0xed, 0x50, 0x20, + 0x0, 0x0, 0xa5, 0x3, 0x9d, 0xae, 0x61, 0xb4, + 0x0, 0xad, 0xd3, 0x2c, 0x60, 0x1, 0xae, 0xb0, + + /* U+7FD2 "習" */ + 0xae, 0xee, 0xef, 0x2b, 0xee, 0xee, 0xf2, 0x3, + 0x10, 0xd, 0x20, 0x30, 0x0, 0xc2, 0x7, 0xd9, + 0xd, 0x21, 0xae, 0x70, 0xc2, 0x0, 0x6, 0x9f, + 0x20, 0x1, 0x8b, 0xf2, 0x5, 0xcc, 0x5d, 0x20, + 0x6d, 0xa2, 0xc2, 0xaa, 0x30, 0xd, 0x37, 0x92, + 0x0, 0xc2, 0x0, 0x0, 0x3, 0xf5, 0x0, 0x0, + 0x41, 0x0, 0x11, 0x16, 0xe2, 0x11, 0x11, 0x0, + 0x0, 0xfc, 0xbb, 0xbb, 0xbb, 0xbf, 0x20, 0x0, + 0xf0, 0x0, 0x0, 0x0, 0xf, 0x20, 0x0, 0xfe, + 0xdd, 0xdd, 0xdd, 0xdf, 0x20, 0x0, 0xf0, 0x0, + 0x0, 0x0, 0xf, 0x20, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0xf, 0x20, 0x0, 0xfd, 0xdd, 0xdd, 0xdd, + 0xdf, 0x20, + + /* U+8001 "老" */ + 0x0, 0x0, 0x0, 0x97, 0x0, 0x0, 0x5, 0x0, + 0x0, 0x0, 0x0, 0xa8, 0x0, 0x0, 0x7d, 0x10, + 0x0, 0xbf, 0xff, 0xff, 0xff, 0xfc, 0xe2, 0x0, + 0x0, 0x0, 0x0, 0x97, 0x0, 0x6e, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x97, 0x9, 0xd1, 0x0, 0x0, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x1, 0x7f, 0x71, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3c, 0xd3, 0x0, 0x0, 0x10, 0x0, + 0x0, 0x3b, 0xef, 0x40, 0x2, 0x8e, 0xa0, 0x0, + 0x2c, 0xe7, 0xc, 0x78, 0xdd, 0x82, 0x0, 0x0, + 0x5, 0x0, 0xc, 0xb6, 0x10, 0x0, 0x1, 0x0, + 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0x7, 0x80, + 0x0, 0x0, 0xc, 0x60, 0x0, 0x0, 0xc, 0x60, + 0x0, 0x0, 0x5, 0xef, 0xff, 0xff, 0xfb, 0x0, + + /* U+8003 "考" */ + 0x0, 0x0, 0x0, 0x4c, 0x0, 0x0, 0x7, 0x0, + 0x0, 0x4b, 0xbb, 0xcf, 0xbb, 0xb3, 0xa9, 0x0, + 0x0, 0x13, 0x33, 0x6d, 0x33, 0x4b, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x4c, 0x2, 0xd7, 0x0, 0x0, + 0xb, 0xdd, 0xdd, 0xef, 0xdf, 0xfd, 0xdd, 0xd0, + 0x1, 0x11, 0x11, 0x2b, 0xd3, 0x11, 0x11, 0x10, + 0x0, 0x0, 0x6, 0xea, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xcf, 0xfe, 0xee, 0xee, 0xe7, 0x0, + 0x5, 0xce, 0x6c, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0x60, 0x3f, 0x43, 0x33, 0x33, 0x20, 0x0, + 0x0, 0x0, 0x6a, 0xaa, 0xaa, 0xad, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x60, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2f, 0x10, 0x0, + 0x0, 0x0, 0x0, 0xd, 0xfe, 0xf8, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8005 "者" */ + 0x0, 0x0, 0x0, 0x88, 0x0, 0x0, 0x5, 0x0, + 0x0, 0x11, 0x11, 0x99, 0x11, 0x11, 0x7d, 0x10, + 0x0, 0x9c, 0xcc, 0xee, 0xcc, 0xcd, 0xe1, 0x0, + 0x0, 0x0, 0x0, 0x88, 0x0, 0x8d, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x88, 0x1b, 0xc1, 0x0, 0x0, + 0x1e, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe1, + 0x0, 0x0, 0x2, 0xab, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xaf, 0xeb, 0xbb, 0xbb, 0xb1, 0x0, + 0x17, 0xdc, 0xd7, 0x33, 0x33, 0x33, 0xf2, 0x0, + 0x1b, 0x40, 0xb5, 0x0, 0x0, 0x0, 0xf2, 0x0, + 0x0, 0x0, 0xbe, 0xdd, 0xdd, 0xdd, 0xf2, 0x0, + 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0xf2, 0x0, + 0x0, 0x0, 0xb5, 0x0, 0x0, 0x0, 0xf2, 0x0, + 0x0, 0x0, 0xbf, 0xee, 0xee, 0xee, 0xe2, 0x0, + + /* U+800C "而" */ + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x1, 0x11, 0x11, 0x1e, 0x61, 0x11, 0x11, 0x10, + 0x0, 0x0, 0x0, 0x1f, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5d, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x50, + 0x4, 0xc0, 0x8, 0x80, 0xa, 0x60, 0xb, 0x50, + 0x4, 0xc0, 0x8, 0x80, 0xa, 0x60, 0xb, 0x50, + 0x4, 0xc0, 0x8, 0x80, 0xa, 0x60, 0xb, 0x50, + 0x4, 0xc0, 0x8, 0x80, 0xa, 0x60, 0xb, 0x50, + 0x4, 0xc0, 0x8, 0x80, 0xa, 0x60, 0xb, 0x50, + 0x4, 0xc0, 0x8, 0x80, 0xa, 0x60, 0xb, 0x50, + 0x4, 0xc0, 0x8, 0x80, 0xa, 0x60, 0xb, 0x50, + 0x4, 0xc0, 0x8, 0x80, 0xa, 0x61, 0x1c, 0x50, + 0x4, 0xc0, 0x8, 0x80, 0xa, 0x6c, 0xeb, 0x10, + + /* U+8033 "耳" */ + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x1, 0x17, 0xb1, 0x11, 0x11, 0x1b, 0x81, 0x10, + 0x0, 0x6, 0xb0, 0x0, 0x0, 0xa, 0x70, 0x0, + 0x0, 0x6, 0xb0, 0x0, 0x0, 0xa, 0x70, 0x0, + 0x0, 0x6, 0xff, 0xff, 0xff, 0xff, 0x70, 0x0, + 0x0, 0x6, 0xb0, 0x0, 0x0, 0xa, 0x70, 0x0, + 0x0, 0x6, 0xb0, 0x0, 0x0, 0xa, 0x70, 0x0, + 0x0, 0x6, 0xb2, 0x22, 0x22, 0x2b, 0x70, 0x0, + 0x0, 0x6, 0xfd, 0xdd, 0xdd, 0xdf, 0x70, 0x0, + 0x0, 0x6, 0xb0, 0x0, 0x0, 0xa, 0x70, 0x0, + 0x0, 0x6, 0xb1, 0x23, 0x45, 0x6c, 0xb8, 0x91, + 0x1d, 0xef, 0xff, 0xfd, 0xcb, 0xad, 0xb7, 0x50, + 0x4, 0x32, 0x10, 0x0, 0x0, 0xa, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x70, 0x0, + + /* U+805E "聞" */ + 0xcd, 0xcc, 0xcf, 0x25, 0xec, 0xcc, 0xf2, 0xc4, + 0x0, 0xd, 0x25, 0xa0, 0x0, 0xd2, 0xcd, 0xcc, + 0xcf, 0x25, 0xec, 0xcc, 0xf2, 0xc4, 0x0, 0xd, + 0x25, 0xa0, 0x0, 0xd2, 0xcc, 0xaa, 0xaf, 0x25, + 0xea, 0xaa, 0xf2, 0xc6, 0x22, 0x22, 0x0, 0x22, + 0x22, 0xe2, 0xc4, 0x1d, 0xdd, 0xdd, 0xdd, 0xc0, + 0xd2, 0xc4, 0x0, 0xe0, 0x0, 0x4a, 0x0, 0xd2, + 0xc4, 0x0, 0xeb, 0xbb, 0xca, 0x0, 0xd2, 0xc4, + 0x0, 0xe0, 0x0, 0x4a, 0x0, 0xd2, 0xc4, 0x0, + 0xeb, 0xbb, 0xca, 0x0, 0xd2, 0xc4, 0x28, 0xfb, + 0xbc, 0xef, 0xd5, 0xd2, 0xc4, 0x15, 0x43, 0x21, + 0x4a, 0x1, 0xe2, 0xc4, 0x0, 0x0, 0x0, 0x37, + 0x5f, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+806F "聯" */ + 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x32, 0x0, + 0x3f, 0xff, 0xff, 0x16, 0x80, 0x0, 0xd3, 0x0, + 0x4, 0x90, 0x95, 0xc, 0x16, 0x5, 0x92, 0x40, + 0x4, 0x90, 0x95, 0x77, 0x68, 0x1c, 0x2a, 0x40, + 0x4, 0xa2, 0xa5, 0xef, 0xe0, 0x6f, 0xfa, 0x0, + 0x4, 0xec, 0xe5, 0x19, 0x42, 0x0, 0xb1, 0x40, + 0x4, 0x90, 0x95, 0x78, 0x2c, 0x1b, 0x53, 0xd1, + 0x4, 0xb3, 0xb6, 0xdb, 0x8a, 0x8b, 0x97, 0x77, + 0x4, 0xff, 0xf5, 0x37, 0xc, 0xa, 0x0, 0x10, + 0x4, 0xa1, 0xa5, 0x39, 0xe, 0xd, 0x12, 0xc0, + 0x4, 0x90, 0x95, 0x39, 0xe, 0xd, 0x12, 0xc0, + 0x4, 0xb5, 0xcc, 0x4e, 0xbe, 0xd, 0xcc, 0xc0, + 0x4f, 0xda, 0xd8, 0x12, 0x5a, 0xd, 0x44, 0xa0, + 0x0, 0x0, 0x95, 0x0, 0xb3, 0xd, 0x10, 0x0, + 0x0, 0x0, 0x95, 0x1c, 0x40, 0xd, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8072 "聲" */ + 0xa, 0xaa, 0xfa, 0xaa, 0xc, 0xcc, 0xe6, 0x0, + 0x3, 0x77, 0xf7, 0x73, 0x2e, 0x0, 0x78, 0x31, + 0x2, 0x55, 0x55, 0x53, 0xd6, 0x11, 0x3b, 0xa2, + 0x4, 0xda, 0xea, 0xc7, 0x5e, 0xb9, 0xaf, 0x20, + 0x5, 0x80, 0xd0, 0x67, 0x2, 0xd4, 0xc7, 0x0, + 0x9, 0xca, 0xaa, 0xa4, 0x15, 0xbe, 0xd6, 0x20, + 0xc, 0x0, 0x0, 0x0, 0xa7, 0x20, 0x16, 0xb2, + 0xd, 0xdf, 0xed, 0xdd, 0xdd, 0xdd, 0xfd, 0xd3, + 0x0, 0xa, 0x95, 0x55, 0x55, 0x57, 0xd0, 0x0, + 0x0, 0xa, 0xa6, 0x66, 0x66, 0x68, 0xd0, 0x0, + 0x0, 0xa, 0xdb, 0xbb, 0xbb, 0xbc, 0xd0, 0x0, + 0x0, 0xa, 0x60, 0x0, 0x0, 0x3, 0xe1, 0x20, + 0xc, 0xdf, 0xee, 0xed, 0xdd, 0xdd, 0xfc, 0xb3, + 0x1, 0x10, 0x0, 0x0, 0x0, 0x2, 0xd0, 0x0, + + /* U+8077 "職" */ + 0x1f, 0xff, 0xfe, 0x1, 0xd1, 0x5, 0xa7, 0x20, + 0x3, 0xa0, 0xa3, 0xcd, 0xfe, 0xd7, 0xa5, 0xa0, + 0x3, 0xa0, 0xa3, 0x27, 0x4, 0x74, 0xb0, 0xd2, + 0x3, 0xd9, 0xd3, 0xc, 0x8, 0x53, 0xb0, 0x20, + 0x3, 0xc5, 0xc4, 0xcf, 0xcf, 0xdd, 0xfc, 0xc5, + 0x3, 0xa0, 0xa3, 0x22, 0x22, 0x24, 0xe2, 0x21, + 0x3, 0xa0, 0xa3, 0x4b, 0xbb, 0x90, 0xe0, 0x52, + 0x3, 0xfe, 0xf3, 0x69, 0x33, 0xd0, 0xf0, 0xe2, + 0x3, 0xa0, 0xa3, 0x68, 0x0, 0xd0, 0xd6, 0xb0, + 0x3, 0xa0, 0xa3, 0x6d, 0xbb, 0xd0, 0xae, 0x30, + 0x5, 0xc9, 0xec, 0x67, 0x0, 0xd0, 0x9a, 0x5, + 0x1c, 0x84, 0xa3, 0x6e, 0xcc, 0xd4, 0xeb, 0xb, + 0x0, 0x0, 0xa3, 0x67, 0x0, 0x9a, 0x1e, 0x88, + 0x0, 0x0, 0xa3, 0x0, 0x3, 0xa0, 0x5, 0xe2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+807D "聽" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3e, 0xfe, 0xef, 0xe1, 0x0, 0x5a, 0x0, 0x0, + 0x3, 0xb0, 0xc, 0x3d, 0xdd, 0xfe, 0xdd, 0xd3, + 0x3, 0xe8, 0x8e, 0x30, 0x0, 0xa4, 0x0, 0x0, + 0x3, 0xc3, 0x3d, 0x38, 0xdd, 0xfd, 0xdd, 0xc0, + 0x3, 0xe8, 0x8e, 0x39, 0x44, 0x61, 0x90, 0xe0, + 0x3, 0xc3, 0x3d, 0x39, 0x44, 0x61, 0x90, 0xe0, + 0x18, 0xd8, 0x9e, 0x38, 0xdd, 0xdd, 0xdd, 0xc0, + 0x28, 0x76, 0x5d, 0x33, 0x33, 0x33, 0x33, 0x31, + 0xc, 0xcc, 0x8c, 0x4a, 0xaa, 0xaa, 0xaa, 0xa4, + 0x0, 0x75, 0xc, 0x30, 0x0, 0xc2, 0x1, 0x0, + 0x9, 0xdd, 0x6c, 0x35, 0x5b, 0x3d, 0xa, 0x50, + 0x0, 0x75, 0xc, 0x3c, 0x3d, 0x7, 0x24, 0xd1, + 0x17, 0xcd, 0xac, 0x8a, 0x1d, 0x0, 0xc, 0x77, + 0x16, 0x41, 0xc, 0x51, 0xd, 0xdd, 0xe7, 0x0, + + /* U+8089 "肉" */ + 0x0, 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3f, 0x0, 0x0, 0x0, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfd, 0x3d, 0x0, 0x0, + 0xba, 0x0, 0x0, 0x3d, 0x3d, 0x0, 0x4, 0xed, + 0xb2, 0x0, 0x2d, 0x3d, 0x0, 0x4e, 0x30, 0x7e, + 0x80, 0x2d, 0x3d, 0x1b, 0xe4, 0x19, 0x2, 0xca, + 0x2d, 0x3d, 0x4, 0x0, 0x6b, 0x0, 0x1, 0x2d, + 0x3d, 0x0, 0x0, 0xee, 0x30, 0x0, 0x2d, 0x3d, + 0x0, 0xa, 0xa4, 0xe8, 0x0, 0x2d, 0x3d, 0x4, + 0xcb, 0x0, 0x1b, 0xc1, 0x2d, 0x3d, 0x2c, 0x50, + 0x0, 0x0, 0x87, 0x2d, 0x3d, 0x0, 0x0, 0x0, + 0x0, 0x10, 0x4d, 0x3d, 0x0, 0x0, 0x0, 0x0, + 0xdf, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+80A9 "肩" */ + 0x0, 0x0, 0x0, 0x26, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x40, 0x0, 0x0, 0x0, 0xce, + 0xee, 0xef, 0xfe, 0xee, 0xe3, 0x0, 0xc3, 0x0, + 0x0, 0x0, 0x0, 0xc3, 0x0, 0xc3, 0x0, 0x0, + 0x0, 0x0, 0xc3, 0x0, 0xdf, 0xee, 0xee, 0xee, + 0xee, 0xe3, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe3, 0xed, 0xdd, 0xdd, 0xdd, 0xe8, + 0x0, 0xf1, 0xe2, 0x0, 0x0, 0x0, 0x88, 0x1, + 0xf0, 0xec, 0xcc, 0xcc, 0xcc, 0xe8, 0x5, 0xc0, + 0xe2, 0x0, 0x0, 0x0, 0x88, 0x9, 0x80, 0xe3, + 0x0, 0x0, 0x0, 0x88, 0xe, 0x30, 0xec, 0xbb, + 0xbb, 0xbb, 0xe8, 0x7b, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0x98, 0x2, 0x0, 0xe2, 0x0, 0x0, 0xae, + 0xc3, + + /* U+80AF "肯" */ + 0x0, 0x79, 0x0, 0x88, 0x0, 0x0, 0x0, 0x0, + 0x79, 0x0, 0x8f, 0xee, 0xee, 0x50, 0x0, 0x79, + 0x0, 0x88, 0x0, 0x0, 0x0, 0x0, 0x79, 0x0, + 0x88, 0x0, 0x0, 0x0, 0xef, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xfe, 0xee, 0xee, 0xee, 0xef, + 0x0, 0x0, 0xf1, 0x0, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0xfd, 0xdd, 0xdd, 0xdd, 0xdf, 0x0, 0x0, + 0xf1, 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0xfc, + 0xbb, 0xbb, 0xbb, 0xcf, 0x0, 0x0, 0xf3, 0x22, + 0x22, 0x22, 0x3f, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0x2f, 0x0, 0x0, 0xf1, 0x0, 0x0, 0x7f, + 0xea, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+80B2 "育" */ + 0x0, 0x0, 0x0, 0x72, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9, 0xb0, 0x0, 0x0, 0x0, 0xee, + 0xee, 0xee, 0xff, 0xfe, 0xee, 0xee, 0x0, 0x0, + 0x3e, 0x70, 0x2, 0xe4, 0x0, 0x0, 0x0, 0x5e, + 0x50, 0x0, 0x5, 0xf6, 0x0, 0x0, 0x8f, 0xed, + 0xde, 0xee, 0xdc, 0xe8, 0x0, 0x2, 0x43, 0x21, + 0x0, 0x0, 0x1, 0x91, 0x0, 0xb, 0xee, 0xee, + 0xee, 0xee, 0xd0, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0xc, 0xdb, 0xbb, 0xbb, + 0xbc, 0xe0, 0x0, 0x0, 0xc5, 0x0, 0x0, 0x0, + 0x3e, 0x0, 0x0, 0xc, 0x62, 0x22, 0x22, 0x24, + 0xe0, 0x0, 0x0, 0xcc, 0xaa, 0xaa, 0xaa, 0xbe, + 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0x3, 0xe0, + 0x0, 0x0, 0xc4, 0x0, 0x1, 0xed, 0xd8, 0x0, + 0x0, + + /* U+80CC "背" */ + 0x0, 0x0, 0xe, 0x20, 0x2e, 0x0, 0x15, 0x0, + 0xd, 0xdd, 0xdf, 0x20, 0x2f, 0x7c, 0xd7, 0x10, + 0x0, 0x0, 0xe, 0x20, 0x2f, 0x72, 0x0, 0x0, + 0x0, 0x1, 0x4f, 0x20, 0x2e, 0x0, 0x0, 0x90, + 0x3b, 0xee, 0xaf, 0x20, 0x2f, 0x65, 0x56, 0xe0, + 0x15, 0x10, 0xd, 0x20, 0x8, 0xbb, 0xbb, 0x50, + 0x0, 0xe, 0xdd, 0xdd, 0xdd, 0xdd, 0xe0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0xe, 0xdc, 0xcc, 0xcc, 0xcd, 0xe0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0xe, 0x31, 0x11, 0x11, 0x14, 0xe0, 0x0, + 0x0, 0xe, 0xbb, 0xbb, 0xbb, 0xbb, 0xe0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x6, 0xee, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+80F8 "胸" */ + 0x0, 0x0, 0x0, 0x0, 0x62, 0x0, 0x0, 0x0, + 0x2, 0xff, 0xfd, 0x0, 0xf3, 0x0, 0x0, 0x0, + 0x2, 0xc0, 0x1d, 0x6, 0xe1, 0x11, 0x11, 0x10, + 0x2, 0xc0, 0x1d, 0xd, 0xee, 0xee, 0xee, 0xf9, + 0x2, 0xd0, 0x1d, 0x8d, 0x0, 0x0, 0x0, 0x69, + 0x2, 0xff, 0xfe, 0xe3, 0x90, 0xc, 0x11, 0x69, + 0x2, 0xc0, 0x1d, 0x2c, 0x4a, 0x49, 0x2a, 0x69, + 0x2, 0xc0, 0x1d, 0xc, 0x9, 0xe1, 0x2a, 0x69, + 0x3, 0xc0, 0x1d, 0xc, 0x5, 0xf1, 0x2a, 0x69, + 0x4, 0xff, 0xfd, 0xc, 0x2d, 0x5b, 0x3a, 0x78, + 0x4, 0xa0, 0x1d, 0xd, 0xc4, 0x9, 0x8a, 0x78, + 0x7, 0x80, 0x1d, 0xd, 0x30, 0x1, 0x4a, 0x78, + 0x9, 0x50, 0x1d, 0xd, 0xdd, 0xdd, 0xd9, 0x87, + 0xe, 0x10, 0x1d, 0x0, 0x0, 0x0, 0x0, 0xb5, + 0x1a, 0xc, 0xf9, 0x0, 0x0, 0x5, 0xff, 0xd1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+80FD "能" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x50, 0x0, 0xf, 0x10, 0x0, 0x0, 0x4, + 0xc0, 0xa6, 0x0, 0xf1, 0x5, 0xc3, 0x1, 0xd2, + 0x2, 0xe2, 0xf, 0xad, 0x94, 0x0, 0xaf, 0xed, + 0xcc, 0xb0, 0xf4, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x6, 0xf, 0x10, 0x0, 0xb3, 0x18, 0x88, 0x88, + 0x20, 0xe5, 0x22, 0x3e, 0x22, 0xe6, 0x66, 0xd4, + 0x9, 0xcc, 0xcc, 0x80, 0x2e, 0x11, 0x1c, 0x40, + 0xf1, 0x0, 0x0, 0x2, 0xfb, 0xbb, 0xf4, 0xf, + 0x10, 0x29, 0x50, 0x2d, 0x0, 0xc, 0x40, 0xf7, + 0xbd, 0x71, 0x2, 0xfd, 0xdd, 0xf4, 0xf, 0x72, + 0x0, 0x0, 0x2d, 0x0, 0xc, 0x40, 0xf1, 0x0, + 0x8, 0x42, 0xd0, 0x0, 0xd4, 0xe, 0x41, 0x12, + 0xc4, 0x2d, 0x7, 0xfd, 0x10, 0x7d, 0xdd, 0xda, + 0x0, + + /* U+8131 "脱" */ + 0x0, 0x0, 0x0, 0x0, 0x51, 0x0, 0x6, 0x10, + 0x1, 0xff, 0xff, 0x10, 0x9a, 0x0, 0x2e, 0x0, + 0x1, 0xc0, 0xe, 0x10, 0x1f, 0x20, 0xa8, 0x0, + 0x1, 0xc0, 0xe, 0x14, 0x4b, 0x75, 0xf5, 0x30, + 0x1, 0xd0, 0xe, 0x1e, 0xcb, 0xbb, 0xbd, 0xa0, + 0x1, 0xfe, 0xef, 0x1e, 0x20, 0x0, 0x4, 0xa0, + 0x2, 0xc0, 0xe, 0x1e, 0x20, 0x0, 0x4, 0xa0, + 0x2, 0xc0, 0xe, 0x1e, 0x20, 0x0, 0x5, 0xa0, + 0x3, 0xc0, 0xe, 0x1d, 0xff, 0xff, 0xff, 0xa0, + 0x3, 0xff, 0xff, 0x10, 0xb, 0x52, 0xd0, 0x0, + 0x4, 0xa0, 0xe, 0x10, 0xe, 0x22, 0xd0, 0x0, + 0x6, 0x80, 0xe, 0x10, 0x3e, 0x2, 0xd0, 0x0, + 0x9, 0x60, 0xe, 0x10, 0xa8, 0x2, 0xd0, 0x38, + 0xd, 0x10, 0xe, 0x19, 0xc0, 0x2, 0xe1, 0x6a, + 0x1c, 0x9, 0xfb, 0xa9, 0x10, 0x0, 0xce, 0xe4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+814A "腊" */ + 0x0, 0xff, 0xff, 0x0, 0x3c, 0x0, 0xe1, 0x0, + 0x0, 0xe0, 0xe, 0x10, 0x3c, 0x0, 0xe2, 0x0, + 0x0, 0xe0, 0xe, 0x1e, 0xff, 0xee, 0xfe, 0xe0, + 0x0, 0xe0, 0xe, 0x0, 0x3c, 0x0, 0xe1, 0x0, + 0x0, 0xfe, 0xef, 0x10, 0x3c, 0x0, 0xe2, 0x0, + 0x0, 0xe0, 0xe, 0x6e, 0xee, 0xee, 0xee, 0xe5, + 0x0, 0xe0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xe0, 0xe, 0x1, 0xbb, 0xbb, 0xbb, 0x10, + 0x2, 0xff, 0xff, 0x1, 0xf3, 0x33, 0x3e, 0x10, + 0x3, 0xb0, 0xe, 0x1, 0xe0, 0x0, 0xe, 0x10, + 0x5, 0x90, 0xe, 0x1, 0xfd, 0xdd, 0xdf, 0x10, + 0x8, 0x70, 0xe, 0x1, 0xe0, 0x0, 0xe, 0x10, + 0xc, 0x22, 0x2f, 0x1, 0xf3, 0x33, 0x3e, 0x10, + 0x1c, 0xa, 0xd9, 0x1, 0xfb, 0xbb, 0xbe, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8155 "腕" */ + 0x0, 0x0, 0x0, 0x0, 0x2, 0x60, 0x0, 0x0, + 0xaf, 0xff, 0x0, 0x0, 0xe, 0x20, 0x0, 0xa, + 0x40, 0xd0, 0xee, 0xee, 0xff, 0xee, 0xa0, 0xa4, + 0xd, 0xf, 0x0, 0x0, 0x0, 0x5a, 0xa, 0x63, + 0xe0, 0xb8, 0x30, 0x0, 0x3, 0x70, 0xaf, 0xff, + 0x0, 0xf3, 0x10, 0x88, 0x81, 0xa, 0x51, 0xe0, + 0x4f, 0xce, 0x5f, 0x6d, 0x30, 0xb4, 0xd, 0xb, + 0x70, 0xb3, 0xe0, 0xa3, 0xb, 0x63, 0xe6, 0xe4, + 0xe, 0xe, 0xa, 0x30, 0xcb, 0xaf, 0x85, 0x7d, + 0xd0, 0xe0, 0xa3, 0xd, 0x10, 0xd0, 0x0, 0x98, + 0xe, 0x9e, 0x10, 0xe0, 0xd, 0x0, 0x1f, 0x30, + 0xe0, 0x0, 0x1c, 0x0, 0xd0, 0x8, 0xa0, 0xe, + 0x0, 0xa6, 0x80, 0xe, 0x7, 0xe1, 0x0, 0xe0, + 0xc, 0x93, 0x6f, 0xc3, 0xe2, 0x0, 0xa, 0xdd, + 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8166 "腦" */ + 0x0, 0x0, 0x0, 0x0, 0x60, 0x6, 0x0, 0x70, + 0x2, 0xff, 0xfd, 0x6, 0x90, 0x88, 0x7, 0xa0, + 0x2, 0xc0, 0x1d, 0x1d, 0x12, 0xd0, 0x2d, 0x10, + 0x2, 0xc0, 0x1d, 0x6a, 0x8, 0x80, 0x98, 0x0, + 0x2, 0xd0, 0x1d, 0xd, 0x31, 0xd3, 0x1d, 0x30, + 0x2, 0xfe, 0xfd, 0x4, 0xc0, 0x4d, 0x3, 0xd0, + 0x2, 0xc0, 0x1d, 0x0, 0x91, 0x9a, 0x10, 0x83, + 0x2, 0xc0, 0x1d, 0x4, 0x45, 0xf4, 0x44, 0x40, + 0x3, 0xc0, 0x1d, 0xf, 0xba, 0xaa, 0xaa, 0xf1, + 0x4, 0xff, 0xfd, 0xf, 0x5, 0x1, 0xc0, 0xe1, + 0x4, 0xa0, 0x1d, 0xf, 0x8, 0xcc, 0x50, 0xe1, + 0x6, 0x80, 0x1d, 0xf, 0x1, 0xde, 0x30, 0xe1, + 0x9, 0x50, 0x1d, 0xf, 0x4d, 0x42, 0xd1, 0xe1, + 0xc, 0x10, 0x1d, 0xf, 0x33, 0x11, 0x21, 0xe1, + 0x1b, 0xc, 0xf9, 0xf, 0xdc, 0xcc, 0xcc, 0xe1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8170 "腰" */ + 0xb, 0xff, 0xf5, 0xff, 0xff, 0xff, 0xff, 0x70, + 0xb3, 0xe, 0x0, 0x3, 0xb0, 0xe0, 0x0, 0xb, + 0x30, 0xe0, 0x66, 0x8d, 0x6f, 0x66, 0x0, 0xb3, + 0xe, 0xd, 0xab, 0xea, 0xfa, 0xf0, 0xb, 0xfe, + 0xf0, 0xd0, 0x2a, 0xd, 0xe, 0x0, 0xb3, 0xe, + 0xd, 0x2, 0xa0, 0xd0, 0xe0, 0xc, 0x30, 0xe0, + 0xce, 0xee, 0xee, 0xee, 0x0, 0xc6, 0x4f, 0x0, + 0x2, 0xc0, 0x0, 0x0, 0xd, 0x99, 0xf4, 0xee, + 0xff, 0xee, 0xee, 0x90, 0xd0, 0xe, 0x0, 0x6c, + 0x0, 0x1e, 0x10, 0xd, 0x0, 0xe0, 0x1f, 0x60, + 0x8, 0x90, 0x3, 0xb0, 0xe, 0x1, 0x6b, 0xda, + 0xe0, 0x0, 0x77, 0x0, 0xe0, 0x0, 0x5c, 0xbd, + 0xb4, 0xb, 0x27, 0xeb, 0x2d, 0xd9, 0x30, 0x5, + 0xd5, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x0, + + /* U+819D "膝" */ + 0x1, 0xff, 0xff, 0x0, 0x0, 0xd2, 0x0, 0x0, + 0x1, 0xc0, 0xf, 0x6f, 0xff, 0xff, 0xff, 0xf1, + 0x1, 0xc0, 0xf, 0x0, 0x2d, 0xeb, 0xa0, 0x0, + 0x1, 0xd0, 0xf, 0x1, 0xd3, 0xd2, 0x7b, 0x0, + 0x1, 0xfe, 0xff, 0x5c, 0x30, 0xf2, 0x7, 0xb0, + 0x2, 0xc0, 0xf, 0x30, 0x3, 0xe7, 0x0, 0x30, + 0x2, 0xc0, 0xf, 0x0, 0x3b, 0x19, 0x90, 0x0, + 0x3, 0xc0, 0xf, 0x8, 0xc1, 0x81, 0x7d, 0x50, + 0x3, 0xff, 0xff, 0xb9, 0x10, 0xd1, 0x5, 0xc4, + 0x4, 0xa0, 0xf, 0x3, 0xc1, 0xd1, 0x7b, 0x0, + 0x7, 0x80, 0xf, 0x0, 0x48, 0xeb, 0x90, 0x0, + 0x9, 0x50, 0xf, 0x3, 0xaa, 0xe7, 0xc6, 0x0, + 0xe, 0x10, 0xf, 0x6b, 0x30, 0xd1, 0x9, 0xa0, + 0x1a, 0xb, 0xfa, 0x0, 0x3c, 0xd0, 0x0, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+81C9 "臉" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x83, 0x0, 0x0, + 0x1, 0xff, 0xfd, 0x0, 0x5, 0xf9, 0x0, 0x0, + 0x1, 0xc0, 0x1d, 0x0, 0x3d, 0x2a, 0xa0, 0x0, + 0x1, 0xc0, 0x1d, 0x6, 0xd2, 0x0, 0x8e, 0x50, + 0x1, 0xd1, 0x3d, 0x7c, 0xce, 0xee, 0xe3, 0xc3, + 0x1, 0xfc, 0xcd, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xc0, 0x1d, 0x2c, 0xcc, 0xb, 0xcc, 0x70, + 0x2, 0xc0, 0x1d, 0x39, 0xc, 0xd, 0x5, 0x80, + 0x3, 0xd5, 0x6d, 0x38, 0xc, 0xc, 0x4, 0x80, + 0x3, 0xe9, 0xad, 0x3e, 0xdf, 0xe, 0xde, 0x80, + 0x4, 0x90, 0x1d, 0x0, 0x60, 0x0, 0x63, 0x0, + 0x6, 0x70, 0x1d, 0x4, 0xb0, 0x0, 0xf2, 0x0, + 0x9, 0x50, 0x1d, 0xa, 0xe6, 0x6, 0xfa, 0x0, + 0xd, 0x10, 0x1d, 0x6c, 0x1b, 0x5e, 0x38, 0xd1, + 0x1b, 0xe, 0xfa, 0xd2, 0x0, 0xc5, 0x0, 0x74, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+81EA "自" */ + 0x0, 0x0, 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x90, 0x0, 0x0, 0x1, 0x11, 0x1e, 0x41, + 0x11, 0x11, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x2e, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x2e, 0x0, + 0x0, 0x0, 0x0, 0x2e, 0x2f, 0xdd, 0xdd, 0xdd, + 0xdd, 0xee, 0x2e, 0x22, 0x22, 0x22, 0x22, 0x4e, + 0x2e, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x2e, 0x0, + 0x0, 0x0, 0x0, 0x3e, 0x2f, 0xee, 0xee, 0xee, + 0xee, 0xfe, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x2e, + 0x2e, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x2f, 0xdd, + 0xdd, 0xdd, 0xdd, 0xee, 0x2e, 0x22, 0x22, 0x22, + 0x22, 0x4d, + + /* U+81F3 "至" */ + 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa0, + 0x0, 0x0, 0xb, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7e, 0x10, 0x2, 0xc1, 0x0, 0x0, + 0x0, 0x3, 0xf4, 0x0, 0x0, 0xad, 0x20, 0x0, + 0x0, 0x3e, 0x70, 0x0, 0x1, 0x2c, 0xe1, 0x0, + 0x0, 0xef, 0xde, 0xff, 0xed, 0xdc, 0xdd, 0x0, + 0x0, 0x33, 0x11, 0x4, 0x40, 0x0, 0x9, 0x20, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x8b, 0xbb, 0xbe, 0xeb, 0xbb, 0xb9, 0x0, + 0x0, 0x34, 0x44, 0x4a, 0xa4, 0x44, 0x43, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x3, 0x33, 0x33, 0x3a, 0xa3, 0x33, 0x33, 0x30, + 0x1c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc1, + + /* U+81FA "臺" */ + 0xb, 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xcc, 0xc0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x9b, 0xbb, 0xbd, 0xdb, 0xbb, 0xba, 0x0, + 0x0, 0x4, 0x44, 0x44, 0x44, 0x44, 0x40, 0x0, + 0x0, 0x1f, 0x55, 0x55, 0x55, 0x55, 0xf2, 0x0, + 0x0, 0x1f, 0xaa, 0xaa, 0xaa, 0xaa, 0xf2, 0x0, + 0x3, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x30, + 0xa, 0xa7, 0x77, 0x77, 0x77, 0x77, 0x7a, 0xb0, + 0xa, 0x6b, 0xbb, 0xcb, 0xbb, 0xcb, 0xb6, 0xb0, + 0x0, 0x2, 0x7c, 0x63, 0x33, 0xad, 0x40, 0x0, + 0x0, 0x6, 0x88, 0x7c, 0xb6, 0x65, 0xb2, 0x0, + 0x0, 0x5b, 0xbb, 0xbe, 0xdb, 0xbb, 0xb6, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0xc, 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xcc, 0xc0, + + /* U+8207 "與" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x69, 0x72, 0xb3, 0x0, 0x7f, 0xfe, 0x0, + 0x0, 0xd2, 0x0, 0xbe, 0xdc, 0x0, 0x1e, 0x0, + 0x0, 0xd2, 0x0, 0xb4, 0x0, 0x0, 0x1e, 0x0, + 0x0, 0xcb, 0x94, 0xb3, 0x0, 0x39, 0x9d, 0x0, + 0x0, 0xc8, 0x52, 0xbe, 0xdb, 0x26, 0x7d, 0x0, + 0x0, 0xb4, 0x0, 0x41, 0x1d, 0x0, 0x2d, 0x0, + 0x0, 0xad, 0xc5, 0xa3, 0x1d, 0x4b, 0xcc, 0x0, + 0x0, 0xa7, 0x21, 0xa3, 0x1d, 0x13, 0x6c, 0x0, + 0x0, 0x95, 0x0, 0xa3, 0x1d, 0x0, 0x4b, 0x0, + 0x2b, 0xed, 0xbb, 0xec, 0xcf, 0xbb, 0xde, 0xb2, + 0x3, 0x33, 0x47, 0x43, 0x34, 0x84, 0x33, 0x30, + 0x0, 0x1, 0xbc, 0x10, 0x2, 0xcc, 0x40, 0x0, + 0x1, 0x8e, 0x70, 0x0, 0x0, 0x4, 0xda, 0x10, + 0xa, 0x81, 0x0, 0x0, 0x0, 0x0, 0x8, 0x80, + + /* U+8208 "興" */ + 0x0, 0x1, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xbe, 0x9a, 0xdd, 0xdd, 0xab, 0xef, 0x20, + 0x2, 0xd0, 0xb, 0x10, 0x1, 0xb0, 0xc, 0x20, + 0x1, 0xd0, 0xb, 0x7c, 0xc6, 0xb0, 0xc, 0x20, + 0x1, 0xfc, 0x8b, 0x10, 0x1, 0xb8, 0xbf, 0x10, + 0x0, 0xe3, 0x2b, 0x3b, 0xb4, 0xb3, 0x4e, 0x10, + 0x0, 0xe0, 0xb, 0x45, 0x55, 0xb0, 0xd, 0x10, + 0x0, 0xfa, 0x8b, 0x45, 0x55, 0xb7, 0x9f, 0x0, + 0x0, 0xf4, 0x3b, 0x4d, 0xd5, 0xb3, 0x4f, 0x0, + 0x0, 0xf0, 0xb, 0x10, 0x1, 0xb0, 0xf, 0x0, + 0x2c, 0xfc, 0xcf, 0xcc, 0xcc, 0xfc, 0xcf, 0xc2, + 0x3, 0x33, 0x37, 0x33, 0x33, 0x83, 0x33, 0x30, + 0x0, 0x2, 0xbc, 0x10, 0x1, 0xbd, 0x50, 0x0, + 0x1, 0x9e, 0x60, 0x0, 0x0, 0x3, 0xcb, 0x20, + 0xb, 0x81, 0x0, 0x0, 0x0, 0x0, 0x7, 0x70, + + /* U+8209 "舉" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7a, 0x83, 0x6b, 0x65, 0x9c, 0xdb, 0x0, + 0x0, 0xa4, 0x0, 0x6b, 0x76, 0x0, 0x4a, 0x0, + 0x0, 0xad, 0xc7, 0x69, 0x31, 0x7c, 0xda, 0x0, + 0x0, 0x95, 0x0, 0x38, 0xb7, 0x0, 0x69, 0x0, + 0x0, 0x8d, 0xc8, 0x72, 0x67, 0x8c, 0xd8, 0x0, + 0x0, 0x87, 0x0, 0x93, 0x67, 0x0, 0x77, 0x0, + 0x2e, 0xff, 0xee, 0xfe, 0xff, 0xee, 0xff, 0xe3, + 0x0, 0x1, 0xc4, 0x6, 0x60, 0x4d, 0x20, 0x0, + 0x0, 0x1d, 0x60, 0x8, 0x80, 0x4, 0xd2, 0x0, + 0x7, 0xd5, 0x6d, 0xdf, 0xfd, 0xd6, 0x4d, 0x91, + 0x19, 0x10, 0x0, 0x8, 0x80, 0x0, 0x0, 0x61, + 0x0, 0xae, 0xee, 0xef, 0xfe, 0xee, 0xee, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + + /* U+822A "航" */ + 0x0, 0x3, 0x80, 0x0, 0x5, 0x50, 0x0, 0x0, + 0x0, 0x8, 0x90, 0x0, 0x3, 0xe0, 0x0, 0x0, + 0x2, 0xae, 0xca, 0x80, 0x0, 0xb4, 0x0, 0x0, + 0x2, 0xd3, 0x35, 0xcc, 0xee, 0xee, 0xee, 0xe5, + 0x2, 0xc7, 0x32, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xc3, 0xa2, 0xc0, 0x11, 0x11, 0x10, 0x0, + 0x2, 0xc0, 0xb3, 0xc0, 0xbf, 0xff, 0xf2, 0x0, + 0x5, 0xd3, 0x35, 0xc0, 0xb3, 0x0, 0xd2, 0x0, + 0x1c, 0xeb, 0xbc, 0xc0, 0xb3, 0x0, 0xd2, 0x0, + 0x3, 0xb5, 0x12, 0xc0, 0xc3, 0x0, 0xd2, 0x0, + 0x4, 0xa4, 0xa2, 0xc0, 0xd2, 0x0, 0xd2, 0x0, + 0x5, 0x90, 0xa4, 0xc0, 0xe0, 0x0, 0xd2, 0x0, + 0x7, 0x70, 0x2, 0xc1, 0xe0, 0x0, 0xd2, 0x18, + 0xb, 0x30, 0x3, 0xc7, 0x80, 0x0, 0xd2, 0x29, + 0xd, 0x0, 0xde, 0x8d, 0x10, 0x0, 0x8f, 0xe4, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+822C "般" */ + 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xd0, 0x0, 0x1f, 0xee, 0xfb, 0x0, + 0x0, 0xef, 0xfe, 0xe1, 0x1e, 0x0, 0x4b, 0x0, + 0x0, 0xe0, 0x0, 0xe1, 0x2d, 0x0, 0x4b, 0x0, + 0x0, 0xe3, 0x70, 0xe1, 0x5b, 0x0, 0x4b, 0x0, + 0x0, 0xe0, 0xc1, 0xe2, 0xd5, 0x0, 0x1e, 0xb7, + 0x0, 0xe0, 0x31, 0xe1, 0x60, 0x0, 0x0, 0x20, + 0x3b, 0xfb, 0xbb, 0xf1, 0xbc, 0xcc, 0xcc, 0x90, + 0x14, 0xe3, 0x33, 0xf1, 0x9a, 0x33, 0x39, 0x80, + 0x2, 0xc3, 0x80, 0xe1, 0x2e, 0x0, 0xe, 0x20, + 0x4, 0xa0, 0xd1, 0xe1, 0xa, 0x90, 0x6b, 0x0, + 0x6, 0x90, 0x63, 0xe1, 0x1, 0xd9, 0xe1, 0x0, + 0xa, 0x50, 0x0, 0xe1, 0x0, 0x7f, 0xb0, 0x0, + 0xe, 0x0, 0x0, 0xf1, 0x3a, 0xd5, 0xcd, 0x60, + 0x3b, 0x0, 0xcf, 0xb3, 0xe7, 0x0, 0x5, 0xc2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8239 "船" */ + 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xb0, 0x0, 0xf, 0xff, 0xfc, 0x0, + 0x0, 0x39, 0x93, 0x30, 0xf, 0x0, 0x2c, 0x0, + 0x2, 0xea, 0xaa, 0xf0, 0x1f, 0x0, 0x2c, 0x0, + 0x2, 0xc2, 0x30, 0xf0, 0x2e, 0x0, 0x2c, 0x0, + 0x2, 0xc2, 0xc0, 0xf0, 0x5b, 0x0, 0x2c, 0x0, + 0x2, 0xc0, 0xb1, 0xf0, 0xc5, 0x0, 0x2d, 0x10, + 0x5, 0xd3, 0x33, 0xf6, 0x90, 0x0, 0xa, 0xc6, + 0x3c, 0xeb, 0xbb, 0xf0, 0x23, 0x33, 0x33, 0x10, + 0x3, 0xb3, 0x40, 0xf0, 0xbd, 0xcc, 0xce, 0x90, + 0x4, 0xa1, 0xc0, 0xf0, 0xb3, 0x0, 0x6, 0x90, + 0x5, 0x90, 0x63, 0xf0, 0xb3, 0x0, 0x6, 0x90, + 0x8, 0x60, 0x0, 0xf0, 0xb3, 0x0, 0x6, 0x90, + 0xd, 0x20, 0x0, 0xf0, 0xbc, 0xbb, 0xbd, 0x90, + 0x3a, 0x0, 0x9e, 0xa0, 0xb7, 0x44, 0x48, 0x80, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+826F "良" */ + 0x0, 0x0, 0x5, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, 0x1e, 0xee, + 0xef, 0xfe, 0xee, 0xe2, 0x0, 0x1f, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x1f, 0x0, 0x0, 0x0, + 0x0, 0xe2, 0x0, 0x1f, 0xee, 0xee, 0xee, 0xee, + 0xf2, 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe2, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x1f, 0xee, 0xff, 0xee, 0xee, 0xe2, 0x0, 0x1f, + 0x0, 0x1e, 0x10, 0x0, 0x3a, 0x0, 0x1f, 0x0, + 0x7, 0xb0, 0x7, 0xe6, 0x0, 0x1f, 0x0, 0x0, + 0xab, 0xcb, 0x20, 0x0, 0x1f, 0x0, 0x1, 0xa, + 0xe4, 0x0, 0x0, 0x3f, 0x59, 0xde, 0x0, 0x5e, + 0xb5, 0x0, 0xaf, 0xb7, 0x20, 0x0, 0x1, 0x6c, + 0xd0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8272 "色" */ + 0x0, 0x0, 0x1, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0xff, 0xff, 0xf3, 0x0, 0x0, + 0x0, 0x4, 0xe2, 0x0, 0x8, 0xa0, 0x0, 0x0, + 0x0, 0x7f, 0x30, 0x0, 0x6d, 0x0, 0x0, 0x0, + 0xa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0xa, 0x4e, 0x0, 0x2, 0xe0, 0x0, 0x2e, 0x0, + 0x0, 0x2e, 0x0, 0x2, 0xe0, 0x0, 0x2e, 0x0, + 0x0, 0x2e, 0x0, 0x2, 0xe0, 0x0, 0x2e, 0x0, + 0x0, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x1a, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa6, + 0x0, 0xf, 0x30, 0x0, 0x0, 0x0, 0x2, 0xe3, + 0x0, 0x6, 0xdf, 0xff, 0xff, 0xff, 0xfe, 0x70, + + /* U+8282 "节" */ + 0x0, 0x0, 0x4c, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x1c, 0xcc, 0xdf, 0xcc, 0xcc, 0xfd, 0xcc, 0xc1, + 0x3, 0x33, 0x7d, 0x33, 0x33, 0xd7, 0x33, 0x30, + 0x0, 0x0, 0x4c, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0x0, 0x0, 0x39, 0x0, 0x0, 0xa3, 0x0, 0x0, + 0x6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, + 0x0, 0x11, 0x13, 0xf1, 0x11, 0x11, 0x98, 0x0, + 0x0, 0x0, 0x2, 0xf0, 0x0, 0x0, 0x98, 0x0, + 0x0, 0x0, 0x2, 0xf0, 0x0, 0x0, 0x98, 0x0, + 0x0, 0x0, 0x2, 0xf0, 0x0, 0x0, 0x98, 0x0, + 0x0, 0x0, 0x2, 0xf0, 0x0, 0x11, 0xa8, 0x0, + 0x0, 0x0, 0x2, 0xf0, 0x6, 0xff, 0xe3, 0x0, + 0x0, 0x0, 0x2, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xf0, 0x0, 0x0, 0x0, 0x0, + + /* U+82B1 "花" */ + 0x0, 0x0, 0x1f, 0x0, 0x0, 0xe3, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x1, 0x11, 0x3f, 0x11, 0x11, 0xe4, 0x11, 0x10, + 0x0, 0x0, 0x17, 0x0, 0x0, 0x81, 0x0, 0x0, + 0x0, 0x0, 0x6b, 0x0, 0xa6, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xf3, 0x0, 0xa6, 0x0, 0x8, 0x0, + 0x0, 0xb, 0xa0, 0x0, 0xa6, 0x3, 0xdc, 0x10, + 0x0, 0xbf, 0x90, 0x0, 0xa8, 0xae, 0x60, 0x0, + 0xb, 0xc9, 0x90, 0x2, 0xce, 0x70, 0x0, 0x0, + 0x5, 0x8, 0x90, 0xae, 0xd7, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x90, 0x30, 0xa6, 0x0, 0x0, 0x40, + 0x0, 0x8, 0x90, 0x0, 0xa6, 0x0, 0x0, 0xb4, + 0x0, 0x8, 0x90, 0x0, 0x99, 0x0, 0x1, 0xe1, + 0x0, 0x8, 0x90, 0x0, 0x4e, 0xff, 0xff, 0x90, + + /* U+82E5 "若" */ + 0x0, 0x0, 0x5a, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x6b, 0x0, 0x0, 0xb6, 0x0, 0x0, + 0x0, 0x0, 0x5a, 0x26, 0x0, 0xb5, 0x0, 0x0, + 0x0, 0x0, 0x12, 0xa8, 0x0, 0x21, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x1c, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0xfe, 0xee, 0xee, 0xee, 0xea, 0x0, + 0x0, 0x8e, 0xe4, 0x11, 0x11, 0x11, 0x6b, 0x0, + 0x2c, 0xc1, 0xd3, 0x0, 0x0, 0x0, 0x5b, 0x0, + 0x7, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x5b, 0x0, + 0x0, 0x0, 0xdc, 0xbb, 0xbb, 0xbb, 0xdb, 0x0, + 0x0, 0x0, 0xd6, 0x33, 0x33, 0x33, 0x7b, 0x0, + + /* U+82E6 "苦" */ + 0x0, 0x6, 0xa0, 0x0, 0xb, 0x50, 0x0, 0xef, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x6, + 0xa0, 0x0, 0xb, 0x50, 0x0, 0x0, 0x6, 0xa0, + 0x76, 0xb, 0x50, 0x0, 0x0, 0x1, 0x30, 0x98, + 0x3, 0x10, 0x0, 0xef, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x0, 0x0, 0x0, 0x98, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x98, 0x0, 0x0, 0x0, + 0x1, 0xcc, 0xcc, 0xee, 0xcc, 0xcc, 0x40, 0x1, + 0xf3, 0x33, 0x33, 0x33, 0x3c, 0x50, 0x1, 0xe0, + 0x0, 0x0, 0x0, 0xb, 0x50, 0x1, 0xe0, 0x0, + 0x0, 0x0, 0xb, 0x50, 0x1, 0xfc, 0xcc, 0xcc, + 0xcc, 0xcf, 0x50, 0x1, 0xf3, 0x33, 0x33, 0x33, + 0x3c, 0x50, + + /* U+82F1 "英" */ + 0x0, 0x0, 0x69, 0x0, 0x0, 0xa5, 0x0, 0x0, + 0xd, 0xee, 0xff, 0xee, 0xee, 0xff, 0xee, 0xc0, + 0x0, 0x0, 0x7a, 0x0, 0x0, 0xb6, 0x0, 0x0, + 0x0, 0x0, 0x69, 0x8, 0x60, 0xa5, 0x0, 0x0, + 0x0, 0x0, 0x11, 0x9, 0x70, 0x21, 0x0, 0x0, + 0x0, 0x6f, 0xee, 0xef, 0xfe, 0xee, 0xf7, 0x0, + 0x0, 0x69, 0x0, 0x9, 0x70, 0x0, 0x97, 0x0, + 0x0, 0x69, 0x0, 0xa, 0x70, 0x0, 0x97, 0x0, + 0x2, 0x8b, 0x22, 0x2b, 0x82, 0x22, 0xa9, 0x20, + 0x1d, 0xdd, 0xdd, 0xdf, 0xfd, 0xdd, 0xdd, 0xd1, + 0x0, 0x0, 0x0, 0x6d, 0xa8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0xe3, 0x1e, 0x70, 0x0, 0x0, + 0x0, 0x4, 0xcd, 0x30, 0x1, 0xdb, 0x40, 0x0, + 0x1a, 0xec, 0x60, 0x0, 0x0, 0x6, 0xde, 0xb2, + 0x6, 0x20, 0x0, 0x0, 0x0, 0x0, 0x2, 0x60, + + /* U+8336 "茶" */ + 0x0, 0x0, 0x88, 0x0, 0x0, 0x97, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x89, 0x2, 0x20, 0xa8, 0x0, 0x0, + 0x0, 0x0, 0x88, 0xc, 0xc0, 0x97, 0x0, 0x0, + 0x0, 0x0, 0x13, 0xcd, 0xbb, 0x31, 0x0, 0x0, + 0x0, 0x0, 0x6e, 0xb4, 0x37, 0xe7, 0x0, 0x0, + 0x0, 0x5d, 0xe5, 0x8, 0x90, 0x2b, 0xe8, 0x20, + 0x1e, 0xc5, 0x0, 0x8, 0x90, 0x0, 0x4b, 0xf3, + 0x1, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xf2, 0x10, + 0x0, 0x0, 0x20, 0x8, 0x90, 0x11, 0x0, 0x0, + 0x0, 0x3, 0xe3, 0x8, 0x90, 0x7d, 0x20, 0x0, + 0x0, 0x3e, 0x50, 0x8, 0x90, 0x5, 0xe4, 0x0, + 0x4, 0xe4, 0x0, 0x9, 0x90, 0x0, 0x4e, 0x20, + 0x0, 0x10, 0x5, 0xfe, 0x50, 0x0, 0x1, 0x0, + + /* U+8377 "荷" */ + 0x0, 0x0, 0x5c, 0x0, 0x0, 0xc5, 0x0, 0x0, + 0xe, 0xee, 0xff, 0xee, 0xee, 0xff, 0xee, 0xe1, + 0x0, 0x0, 0x4b, 0x0, 0x0, 0xb4, 0x0, 0x0, + 0x0, 0x0, 0x96, 0x0, 0x0, 0x52, 0x0, 0x0, + 0x0, 0x6, 0xd6, 0xee, 0xee, 0xee, 0xee, 0xe3, + 0x0, 0x1f, 0x40, 0x0, 0x0, 0x0, 0x79, 0x0, + 0x0, 0xbe, 0x0, 0x0, 0x0, 0x0, 0x79, 0x0, + 0xb, 0xee, 0x2, 0xfe, 0xee, 0xe0, 0x79, 0x0, + 0x4c, 0x3e, 0x2, 0xd0, 0x1, 0xe0, 0x79, 0x0, + 0x0, 0x1e, 0x2, 0xd0, 0x1, 0xe0, 0x79, 0x0, + 0x0, 0x1e, 0x2, 0xfd, 0xde, 0xe0, 0x79, 0x0, + 0x0, 0x1e, 0x2, 0xd0, 0x0, 0x0, 0x79, 0x0, + 0x0, 0x1e, 0x1, 0x60, 0x0, 0x0, 0x79, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x1, 0xff, 0xd4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+83D3 "菓" */ + 0x0, 0x0, 0x5b, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x5b, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0x0, 0x5d, 0xdd, 0xdd, 0xdd, 0xdd, 0xd6, 0x0, + 0x0, 0x69, 0x0, 0x9, 0x70, 0x0, 0x87, 0x0, + 0x0, 0x6e, 0xcc, 0xce, 0xec, 0xcc, 0xe7, 0x0, + 0x0, 0x69, 0x0, 0x9, 0x70, 0x0, 0x87, 0x0, + 0x0, 0x6d, 0x99, 0x9d, 0xc9, 0x99, 0xd7, 0x0, + 0x0, 0x13, 0x33, 0x3a, 0x93, 0x33, 0x31, 0x0, + 0x1b, 0xbb, 0xbb, 0xbd, 0xdb, 0xbb, 0xbb, 0xb2, + 0x3, 0x33, 0x39, 0xec, 0xbe, 0x63, 0x33, 0x30, + 0x0, 0x3, 0xcc, 0x29, 0x73, 0xd9, 0x10, 0x0, + 0x17, 0xdd, 0x60, 0x9, 0x70, 0x7, 0xdb, 0x61, + 0x19, 0x40, 0x0, 0x9, 0x70, 0x0, 0x4, 0xa1, + + /* U+83DC "菜" */ + 0x0, 0x0, 0x4d, 0x0, 0x0, 0xe4, 0x0, 0x0, + 0xe, 0xee, 0xff, 0xee, 0xee, 0xff, 0xee, 0xe0, + 0x0, 0x0, 0x3d, 0x0, 0x0, 0xd3, 0x0, 0x0, + 0x0, 0x1, 0x36, 0x45, 0x68, 0xbd, 0xf6, 0x0, + 0x5, 0xed, 0xcb, 0xa9, 0x86, 0x53, 0x1, 0x0, + 0x0, 0x54, 0x0, 0x2d, 0x0, 0x0, 0x7c, 0x0, + 0x0, 0x2e, 0x20, 0xa, 0x60, 0x2, 0xe2, 0x0, + 0x0, 0x7, 0x40, 0x7, 0x50, 0x9, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x1e, 0xee, 0xee, 0xff, 0xff, 0xee, 0xee, 0xe1, + 0x0, 0x0, 0x7, 0xdc, 0xbd, 0x50, 0x0, 0x0, + 0x0, 0x4, 0xdb, 0x19, 0x81, 0xbb, 0x30, 0x0, + 0x17, 0xdc, 0x40, 0x9, 0x80, 0x5, 0xce, 0x81, + 0x19, 0x30, 0x0, 0x9, 0x80, 0x0, 0x2, 0x70, + + /* U+843D "落" */ + 0x0, 0x0, 0x5b, 0x0, 0x0, 0xd4, 0x0, 0x0, + 0xe, 0xee, 0xff, 0xee, 0xee, 0xff, 0xee, 0xe0, + 0x0, 0x0, 0x5b, 0x0, 0x10, 0xc3, 0x0, 0x0, + 0x0, 0xa3, 0x13, 0x2, 0xe2, 0x41, 0x0, 0x0, + 0x0, 0x4d, 0xa0, 0x1d, 0xdd, 0xdd, 0xee, 0x0, + 0x0, 0x0, 0x42, 0xdd, 0xa0, 0x2, 0xd4, 0x0, + 0x1b, 0x50, 0xd, 0x40, 0x7d, 0x7d, 0x40, 0x0, + 0x2, 0xbb, 0x0, 0x0, 0x5d, 0xdc, 0x40, 0x0, + 0x0, 0x1, 0x5, 0x9d, 0x81, 0x4, 0xcd, 0x92, + 0x0, 0x2, 0x88, 0xab, 0xbb, 0xbb, 0xbb, 0x71, + 0x0, 0xd, 0x50, 0x79, 0x22, 0x22, 0x5d, 0x0, + 0x0, 0x9a, 0x0, 0x78, 0x0, 0x0, 0x3d, 0x0, + 0x7, 0xd1, 0x0, 0x79, 0x11, 0x11, 0x4d, 0x0, + 0x9, 0x30, 0x0, 0x7e, 0xcc, 0xcc, 0xdd, 0x0, + + /* U+8449 "葉" */ + 0x1, 0x11, 0x5c, 0x11, 0x11, 0xd4, 0x11, 0x10, + 0x1c, 0xcc, 0xdf, 0xcc, 0xcc, 0xfd, 0xcc, 0xc1, + 0x0, 0x4, 0x5c, 0x7, 0x0, 0xd6, 0x30, 0x0, + 0x0, 0xe, 0x30, 0xf, 0x0, 0x19, 0x80, 0x0, + 0x1e, 0xef, 0xee, 0xef, 0xee, 0xef, 0xfe, 0xe1, + 0x0, 0xe, 0x20, 0xf, 0x0, 0x8, 0x80, 0x0, + 0x0, 0xe, 0x20, 0xb, 0xbb, 0xbb, 0x60, 0x0, + 0x0, 0xe, 0x42, 0x22, 0x22, 0x22, 0x22, 0x10, + 0x0, 0xa, 0xbb, 0xbe, 0xdb, 0xbb, 0xbb, 0x70, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x1d, 0xdd, 0xdd, 0xff, 0xff, 0xdd, 0xdd, 0xd2, + 0x0, 0x0, 0x3b, 0xba, 0x9b, 0x91, 0x0, 0x0, + 0x3, 0x8c, 0xb3, 0x9, 0x70, 0x5c, 0xb7, 0x30, + 0x2a, 0x51, 0x0, 0x9, 0x70, 0x0, 0x16, 0xb2, + + /* U+8457 "著" */ + 0x0, 0x0, 0x5b, 0x0, 0x0, 0xd3, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x5b, 0x65, 0x0, 0xd3, 0x0, 0x0, + 0x0, 0x11, 0x23, 0x98, 0x11, 0x41, 0x5c, 0x0, + 0x0, 0x9c, 0xcc, 0xee, 0xcc, 0xdb, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0x87, 0x3, 0xb9, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x0, 0x3, 0xad, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x16, 0xcf, 0xfc, 0xcc, 0xcc, 0xc7, 0x0, + 0x2c, 0xfa, 0xf3, 0x0, 0x0, 0x0, 0x88, 0x0, + 0x8, 0x20, 0xe4, 0x11, 0x11, 0x11, 0x88, 0x0, + 0x0, 0x0, 0xeb, 0xaa, 0xaa, 0xaa, 0xd8, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x78, 0x0, + 0x0, 0x0, 0xee, 0xdd, 0xdd, 0xdd, 0xe8, 0x0, + + /* U+8535 "蔵" */ + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0x0, 0x3c, 0x0, 0x0, 0xb2, 0x93, 0x0, + 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x6e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc3, 0x7, 0x0, + 0x3, 0xfd, 0xdd, 0xdd, 0xdd, 0xfe, 0xdd, 0xa0, + 0x3, 0xc1, 0x33, 0x33, 0x31, 0xb4, 0x2, 0x0, + 0x3, 0xc5, 0xb6, 0xc7, 0x62, 0x95, 0x2e, 0x0, + 0x3, 0xc5, 0xc9, 0xda, 0x92, 0x87, 0x89, 0x0, + 0x4, 0xb5, 0x92, 0x22, 0x93, 0x5a, 0xe3, 0x0, + 0x5, 0xa5, 0x80, 0x0, 0x83, 0x2f, 0xb0, 0x0, + 0x7, 0x85, 0xdb, 0xec, 0xb2, 0x1f, 0x40, 0x0, + 0xa, 0x55, 0x80, 0xa2, 0x0, 0xbf, 0x60, 0x10, + 0x1e, 0x14, 0xcc, 0xcc, 0xdd, 0x63, 0xe3, 0x96, + 0x27, 0x0, 0x0, 0x0, 0xa2, 0x0, 0x5e, 0xd2, + + /* U+8584 "薄" */ + 0x1, 0x11, 0x5c, 0x11, 0x11, 0xd4, 0x11, 0x10, + 0x1d, 0xdd, 0xef, 0xdd, 0xdd, 0xfd, 0xdd, 0xd2, + 0x0, 0x10, 0x4a, 0x0, 0x2, 0xd3, 0xa4, 0x0, + 0x3, 0xd9, 0x16, 0x66, 0x6b, 0xa6, 0x8f, 0x80, + 0x0, 0x7, 0x64, 0x44, 0x4b, 0x94, 0x44, 0x40, + 0x1, 0x0, 0x6, 0xeb, 0xbe, 0xdb, 0xbe, 0x50, + 0x1d, 0xa1, 0x6, 0xc6, 0x6b, 0xa6, 0x6c, 0x50, + 0x0, 0x7b, 0x6, 0xb3, 0x3a, 0x83, 0x3c, 0x50, + 0x0, 0x0, 0x6, 0xda, 0xad, 0xca, 0xae, 0x50, + 0x0, 0x8, 0x14, 0x60, 0x5, 0x34, 0x76, 0x30, + 0x0, 0x3d, 0x3d, 0xdd, 0xdd, 0xde, 0xfd, 0xd3, + 0x0, 0xc5, 0x0, 0x6b, 0x10, 0x5, 0x90, 0x0, + 0x6, 0xc0, 0x0, 0x5, 0xc0, 0x6, 0x90, 0x0, + 0x9, 0x30, 0x0, 0x0, 0x2, 0xee, 0x60, 0x0, + + /* U+85AC "薬" */ + 0x0, 0x0, 0x5c, 0x0, 0x0, 0xd4, 0x0, 0x0, + 0xe, 0xee, 0xef, 0xee, 0xee, 0xfe, 0xee, 0xe1, + 0x0, 0x0, 0x4b, 0x6, 0x30, 0xc3, 0x1, 0x0, + 0x3, 0xa1, 0xc, 0xcf, 0xdc, 0xd0, 0x2d, 0x40, + 0x0, 0x5e, 0x2d, 0x10, 0x0, 0xf4, 0xc2, 0x0, + 0x0, 0x2, 0xd, 0xbb, 0xbb, 0xf1, 0x0, 0x0, + 0x0, 0x18, 0x9d, 0x20, 0x1, 0xf8, 0xc4, 0x0, + 0xa, 0xe7, 0xd, 0x99, 0x99, 0xf0, 0x3d, 0xa0, + 0x5, 0x0, 0x3, 0x3a, 0x93, 0x30, 0x0, 0x40, + 0xc, 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xcc, 0xc1, + 0x2, 0x22, 0x27, 0xec, 0xcd, 0x52, 0x22, 0x20, + 0x0, 0x1, 0xbc, 0x28, 0x73, 0xd8, 0x10, 0x0, + 0x5, 0xbd, 0x60, 0x8, 0x70, 0x7, 0xdb, 0x60, + 0x1a, 0x40, 0x0, 0x8, 0x70, 0x0, 0x4, 0x90, + + /* U+85DD "藝" */ + 0x1d, 0xdd, 0xef, 0xdd, 0xdd, 0xfe, 0xdd, 0xd1, + 0x0, 0x0, 0x28, 0x0, 0x0, 0x81, 0x0, 0x0, + 0x0, 0x22, 0x92, 0x20, 0x0, 0x61, 0x0, 0x0, + 0x0, 0x88, 0xe9, 0x81, 0x46, 0xd8, 0x63, 0x0, + 0x9, 0xab, 0xdb, 0xba, 0x36, 0xe6, 0xa7, 0x0, + 0x1, 0x98, 0x22, 0xb5, 0x7b, 0xd0, 0x67, 0x0, + 0xa, 0x85, 0xe6, 0x6a, 0x8, 0xf7, 0x58, 0x20, + 0x1, 0x44, 0xe5, 0x42, 0x3d, 0x27, 0x2c, 0x73, + 0xa, 0xbb, 0xc9, 0x99, 0xd3, 0x0, 0x9, 0xc0, + 0x0, 0x19, 0x99, 0x99, 0xa9, 0x99, 0x92, 0x0, + 0x0, 0x2, 0x22, 0x22, 0x22, 0x22, 0x20, 0x0, + 0x1b, 0xbb, 0xbe, 0xdb, 0xbb, 0xcb, 0xbb, 0xb1, + 0x0, 0x2, 0xb9, 0x0, 0x0, 0x7c, 0x40, 0x0, + 0x0, 0xaf, 0xda, 0xbb, 0xcb, 0xbc, 0xda, 0x10, + 0x0, 0x54, 0x22, 0x10, 0x0, 0x0, 0x6, 0x20, + + /* U+8607 "蘇" */ + 0x0, 0x0, 0x3c, 0x0, 0x0, 0xd2, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x3, 0x5c, 0x0, 0x0, 0xd2, 0x1, 0x0, + 0x0, 0x3f, 0x77, 0x30, 0x1, 0x58, 0xcc, 0x30, + 0x1, 0xd6, 0x4e, 0x30, 0x8a, 0x7f, 0x20, 0x0, + 0x1d, 0xec, 0xde, 0xc8, 0x0, 0xe, 0x0, 0x0, + 0x8, 0xa0, 0xc1, 0x4a, 0xbb, 0xbf, 0xcb, 0xb2, + 0x4, 0xd9, 0xea, 0xba, 0x33, 0x9f, 0xb3, 0x30, + 0x4, 0xa1, 0xc2, 0x5a, 0x0, 0xdf, 0xd1, 0x0, + 0x4, 0xa1, 0xc1, 0x5a, 0x6, 0x9e, 0x5a, 0x0, + 0x2, 0xbb, 0xbb, 0xb7, 0x1e, 0x1e, 0x1b, 0x40, + 0x3, 0x67, 0x27, 0x65, 0xc5, 0xe, 0x1, 0xd2, + 0x9, 0x49, 0x3c, 0x1d, 0x50, 0xe, 0x0, 0x31, + 0x3a, 0x4, 0x24, 0x13, 0x0, 0xe, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8655 "處" */ + 0x0, 0x0, 0x0, 0xe, 0xdd, 0xdd, 0xd9, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, 0x0, + 0x0, 0xaa, 0xaa, 0xaf, 0xba, 0xaa, 0xaa, 0x80, + 0x0, 0xf3, 0x33, 0x3f, 0x43, 0x33, 0x3a, 0x80, + 0x0, 0xf0, 0x1, 0x2f, 0x77, 0x89, 0x4c, 0x20, + 0x0, 0xf1, 0xba, 0x9f, 0x86, 0x54, 0x17, 0x20, + 0x0, 0xf0, 0x1, 0xc, 0xa8, 0x88, 0x8c, 0x70, + 0x0, 0xf0, 0x3c, 0x0, 0x23, 0x33, 0x32, 0x0, + 0x1, 0xf0, 0xbd, 0xdf, 0xd, 0xdd, 0xf1, 0x0, + 0x2, 0xd7, 0xf2, 0x4a, 0xe, 0x0, 0xd1, 0x10, + 0x5, 0xcb, 0x4a, 0xc3, 0x2d, 0x0, 0xd1, 0xb0, + 0x8, 0x70, 0xc, 0xb0, 0xc5, 0x0, 0xad, 0xb0, + 0xe, 0x30, 0x9b, 0xca, 0x61, 0x0, 0x0, 0x0, + 0x3c, 0x3d, 0x70, 0x6, 0xbd, 0xee, 0xee, 0xe1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+884C "行" */ + 0x0, 0x3, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x50, 0x3f, 0xff, 0xff, 0xff, 0xa0, + 0x2, 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0x80, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x17, 0x0, 0xb9, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0x50, 0xef, 0xff, 0xff, 0xff, 0xf1, + 0x4, 0xff, 0x10, 0x0, 0x0, 0x6, 0xa0, 0x0, + 0x4f, 0x7e, 0x10, 0x0, 0x0, 0x6, 0xa0, 0x0, + 0x15, 0xe, 0x10, 0x0, 0x0, 0x6, 0xa0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x6, 0xa0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x6, 0xa0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x6, 0xa0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0x8, 0xa0, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x3f, 0xfe, 0x50, 0x0, + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8853 "術" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3e, 0x10, 0xb, 0x42, 0x0, 0x0, 0x0, + 0x1, 0xe4, 0x0, 0xb, 0x4c, 0x3a, 0xee, 0xe1, + 0x3e, 0x60, 0x0, 0xb, 0x33, 0xb0, 0x0, 0x0, + 0x45, 0x9, 0x95, 0x5d, 0x75, 0x50, 0x0, 0x0, + 0x0, 0x3e, 0x3b, 0xcf, 0xcb, 0xb2, 0x22, 0x20, + 0x1, 0xd5, 0x0, 0x6f, 0x30, 0x2c, 0xdf, 0xc4, + 0x1c, 0xf3, 0x0, 0xcf, 0x85, 0x0, 0x2d, 0x0, + 0xba, 0xc3, 0x2, 0xec, 0x5d, 0x10, 0x2d, 0x0, + 0x20, 0xc3, 0x9, 0x7b, 0x35, 0xa0, 0x2d, 0x0, + 0x0, 0xc3, 0x3e, 0xb, 0x30, 0xd3, 0x2d, 0x0, + 0x0, 0xc4, 0xd4, 0xb, 0x30, 0x32, 0x2d, 0x0, + 0x0, 0xc5, 0x70, 0xb, 0x30, 0x0, 0x2d, 0x0, + 0x0, 0xc3, 0x0, 0xb, 0x30, 0x0, 0x3d, 0x0, + 0x0, 0xc3, 0x0, 0xb, 0x30, 0x3f, 0xe8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8868 "表" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x4, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0x50, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x6c, 0xcc, 0xce, 0xec, 0xcc, 0xc8, 0x0, + 0x0, 0x1, 0x11, 0x1a, 0x91, 0x11, 0x11, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, + 0x0, 0x0, 0x5, 0xd4, 0xd4, 0x0, 0x2, 0x0, + 0x0, 0x0, 0xad, 0x20, 0x5d, 0x0, 0x7d, 0x20, + 0x1, 0x8e, 0xf4, 0x0, 0xc, 0x8a, 0xa0, 0x0, + 0x1e, 0x92, 0xc4, 0x0, 0x1, 0xea, 0x0, 0x0, + 0x0, 0x0, 0xc4, 0x0, 0x31, 0x3e, 0x90, 0x0, + 0x0, 0x0, 0xd8, 0x9e, 0xd3, 0x1, 0xce, 0x71, + 0x0, 0x3, 0xfc, 0x72, 0x0, 0x0, 0x4, 0xa1, + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+88AB "被" */ + 0x0, 0x66, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0xd, 0x20, 0x1, 0x11, 0xe3, 0x11, 0x10, + 0x2c, 0xcc, 0xc8, 0xf, 0xcc, 0xfc, 0xcd, 0xe0, + 0x3, 0x33, 0xb6, 0xf, 0x0, 0xe1, 0x7, 0x90, + 0x0, 0x2, 0xd0, 0xf, 0x0, 0xe1, 0xb, 0x40, + 0x0, 0xb, 0x62, 0x1f, 0x0, 0xe2, 0x3, 0x0, + 0x0, 0x4f, 0x3d, 0x4f, 0xfe, 0xee, 0xef, 0x20, + 0x2, 0xef, 0xf3, 0x2e, 0xa3, 0x0, 0x3c, 0x0, + 0x1d, 0x7e, 0x79, 0x4c, 0x4a, 0x0, 0xa6, 0x0, + 0x17, 0x1e, 0x8, 0x59, 0xc, 0x45, 0xd0, 0x0, + 0x0, 0x1e, 0x0, 0x97, 0x3, 0xee, 0x20, 0x0, + 0x0, 0x1e, 0x0, 0xe2, 0x4, 0xee, 0x40, 0x0, + 0x0, 0x1e, 0x8, 0xb1, 0x9e, 0x34, 0xea, 0x30, + 0x0, 0x1e, 0x9, 0x2a, 0x81, 0x0, 0x7, 0xc0, + + /* U+88CF "裏" */ + 0x0, 0x0, 0x0, 0x7, 0x20, 0x0, 0x0, 0x0, + 0x5, 0x55, 0x55, 0x5a, 0xb5, 0x55, 0x55, 0x50, + 0x7, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, + 0x0, 0x2a, 0xaa, 0xaa, 0xaa, 0xaa, 0xa2, 0x0, + 0x0, 0x3c, 0x0, 0x8, 0x70, 0x0, 0xc3, 0x0, + 0x0, 0x3e, 0xaa, 0xad, 0xda, 0xaa, 0xe3, 0x0, + 0x0, 0x3c, 0x0, 0x8, 0x70, 0x0, 0xc3, 0x0, + 0x0, 0x2b, 0xbb, 0xbd, 0xdb, 0xbb, 0xb2, 0x0, + 0x0, 0x77, 0x77, 0x7c, 0xb7, 0x77, 0x77, 0x0, + 0x0, 0x44, 0x44, 0x4a, 0x94, 0x44, 0x44, 0x0, + 0x1d, 0xdd, 0xdd, 0xef, 0xfd, 0xdd, 0xdd, 0xd2, + 0x0, 0x0, 0x3a, 0xa2, 0x99, 0x0, 0x48, 0x0, + 0x4, 0x8c, 0xe7, 0x0, 0xb, 0xab, 0x81, 0x0, + 0x19, 0x40, 0xa6, 0x13, 0x65, 0x7d, 0x71, 0x0, + 0x0, 0x3, 0xff, 0xc9, 0x62, 0x1, 0x8e, 0xc2, + 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x20, + + /* U+88DC "補" */ + 0x0, 0x68, 0x0, 0x0, 0x0, 0xf0, 0x88, 0x10, + 0x0, 0xb, 0x30, 0x33, 0x33, 0xf4, 0x37, 0xc1, + 0xc, 0xcc, 0xc6, 0xaa, 0xaa, 0xfa, 0xaa, 0xa4, + 0x3, 0x33, 0xd4, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0x4, 0xe0, 0x23, 0x33, 0xf4, 0x33, 0x20, + 0x0, 0xd, 0x62, 0x8d, 0xbb, 0xfb, 0xbc, 0xc0, + 0x0, 0x6f, 0x5c, 0x97, 0x0, 0xf0, 0x3, 0xc0, + 0x2, 0xef, 0xf1, 0x8f, 0xee, 0xfe, 0xee, 0xc0, + 0x1d, 0x6e, 0x7a, 0x87, 0x0, 0xf0, 0x3, 0xc0, + 0x57, 0x1e, 0x5, 0x87, 0x0, 0xf0, 0x3, 0xc0, + 0x0, 0x1e, 0x0, 0x8f, 0xee, 0xfe, 0xee, 0xc0, + 0x0, 0x1e, 0x0, 0x87, 0x0, 0xf0, 0x3, 0xc0, + 0x0, 0x1e, 0x0, 0x87, 0x0, 0xf0, 0x4, 0xc0, + 0x0, 0x1e, 0x0, 0x87, 0x0, 0xe0, 0xbf, 0x80, + + /* U+88E1 "裡" */ + 0x0, 0x34, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0x10, 0x3f, 0xee, 0xfe, 0xef, 0x80, + 0x0, 0x7, 0x30, 0x3c, 0x0, 0xe1, 0x8, 0x80, + 0x2c, 0xcc, 0xc8, 0x3c, 0x0, 0xe1, 0x8, 0x80, + 0x3, 0x33, 0xb6, 0x3f, 0xbb, 0xfc, 0xbe, 0x80, + 0x0, 0x3, 0xe0, 0x3c, 0x22, 0xe3, 0x29, 0x80, + 0x0, 0xc, 0x72, 0x3c, 0x0, 0xe1, 0x8, 0x80, + 0x0, 0x8f, 0x2d, 0x5d, 0x22, 0xe3, 0x29, 0x80, + 0x6, 0xff, 0xe4, 0x2c, 0xcc, 0xfc, 0xcc, 0x60, + 0x5f, 0x5f, 0x8a, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x23, 0xf, 0x6, 0x2c, 0xcc, 0xfc, 0xcc, 0x70, + 0x0, 0xf, 0x0, 0x2, 0x22, 0xe4, 0x22, 0x10, + 0x0, 0xf, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0xf, 0x0, 0xef, 0xff, 0xff, 0xff, 0xf3, + + /* U+88FD "製" */ + 0x0, 0x10, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd2, 0x88, 0x0, 0x0, 0xe1, 0xe, 0x10, + 0x6, 0xdb, 0xdd, 0xbb, 0x40, 0xe1, 0xe, 0x10, + 0xb, 0x64, 0xaa, 0x44, 0x40, 0xe1, 0xe, 0x10, + 0x16, 0x66, 0xbb, 0x66, 0x60, 0xe1, 0xe, 0x10, + 0x3, 0xbb, 0xdd, 0xbb, 0x50, 0xe1, 0xe, 0x10, + 0x4, 0x90, 0x77, 0x6, 0x70, 0x30, 0xe, 0x10, + 0x4, 0x90, 0x77, 0x6d, 0x60, 0x6, 0x6f, 0x10, + 0x1, 0x30, 0x77, 0x1a, 0x80, 0xb, 0xc9, 0x0, + 0x1d, 0xdd, 0xdd, 0xde, 0xfd, 0xdd, 0xdd, 0xd0, + 0x0, 0x0, 0x7, 0xd6, 0xb6, 0x0, 0x49, 0x0, + 0x0, 0x48, 0xe9, 0x10, 0x2e, 0x4a, 0xb2, 0x0, + 0x1d, 0xa5, 0xe1, 0x0, 0x3, 0xe9, 0x0, 0x0, + 0x0, 0x1, 0xf7, 0x9c, 0xb0, 0x2a, 0xd7, 0x30, + 0x0, 0x6, 0xc8, 0x40, 0x0, 0x0, 0x38, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8907 "複" */ + 0x0, 0x32, 0x0, 0x0, 0x71, 0x0, 0x0, 0x0, + 0x0, 0x5c, 0x0, 0x4, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x20, 0xb, 0xfe, 0xee, 0xee, 0xe0, + 0x4a, 0xaa, 0xa6, 0x6e, 0x0, 0x0, 0x0, 0x0, + 0x36, 0x66, 0xc8, 0xfe, 0xcc, 0xcc, 0xcc, 0x10, + 0x0, 0x2, 0xd0, 0x3e, 0x10, 0x0, 0xe, 0x10, + 0x0, 0xb, 0x63, 0xe, 0xcb, 0xbb, 0xbf, 0x10, + 0x0, 0x5f, 0x4c, 0x1e, 0x10, 0x0, 0xe, 0x10, + 0x3, 0xef, 0xf2, 0xb, 0xcf, 0xcc, 0xcc, 0x10, + 0x3e, 0x5e, 0x79, 0x0, 0x9b, 0x0, 0x0, 0x0, + 0x65, 0xe, 0xb, 0x7, 0xfd, 0xdd, 0xed, 0x0, + 0x0, 0xe, 0x1, 0xad, 0xd5, 0x2, 0xd4, 0x0, + 0x0, 0xe, 0x2, 0x80, 0x1d, 0xad, 0x30, 0x0, + 0x0, 0xe, 0x0, 0x4, 0x9d, 0xae, 0xa5, 0x10, + 0x0, 0xe, 0x7, 0xda, 0x50, 0x1, 0x7b, 0xd1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+897F "西" */ + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x4b, 0x0, 0xd3, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xb0, 0xd, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x3b, 0x0, 0xd2, 0x0, 0x0, 0x2, 0xee, + 0xef, 0xfe, 0xef, 0xfe, 0xee, 0x30, 0x2e, 0x0, + 0x5a, 0x0, 0xd3, 0x0, 0xd3, 0x2, 0xe0, 0x9, + 0x70, 0xd, 0x20, 0xd, 0x30, 0x2e, 0x3, 0xe1, + 0x0, 0xd3, 0x0, 0xd3, 0x2, 0xe6, 0xe4, 0x0, + 0xa, 0xfe, 0xff, 0x30, 0x2e, 0x72, 0x0, 0x0, + 0x0, 0x0, 0xd3, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x30, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd3, 0x2, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x30, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc3, + + /* U+8981 "要" */ + 0xd, 0xee, 0xef, 0xfe, 0xef, 0xfe, 0xee, 0xd0, + 0x0, 0x0, 0x7, 0x80, 0xb, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x8, 0x90, 0xb, 0x50, 0x0, 0x0, + 0x0, 0xfd, 0xde, 0xed, 0xdf, 0xed, 0xdf, 0x20, + 0x0, 0xf0, 0x7, 0x80, 0xb, 0x40, 0xe, 0x20, + 0x0, 0xf0, 0x7, 0x80, 0xb, 0x40, 0xe, 0x20, + 0x0, 0xee, 0xee, 0xfe, 0xee, 0xee, 0xee, 0x20, + 0x0, 0x0, 0x3, 0xe1, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xee, 0xe1, + 0x0, 0x0, 0xa9, 0x0, 0x0, 0x8b, 0x0, 0x0, + 0x0, 0x7, 0xf5, 0x10, 0x6, 0xe2, 0x0, 0x0, + 0x0, 0x3, 0x7a, 0xed, 0xcf, 0x40, 0x0, 0x0, + 0x0, 0x13, 0x59, 0xdc, 0x7a, 0xed, 0x83, 0x0, + 0xc, 0xdb, 0x96, 0x10, 0x0, 0x3, 0x9e, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+898B "見" */ + 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xf0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xf0, 0x0, + 0x0, 0xf, 0xee, 0xee, 0xee, 0xee, 0xf0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xf0, 0x0, + 0x0, 0xf, 0x33, 0x33, 0x33, 0x33, 0xf0, 0x0, + 0x0, 0xf, 0xbb, 0xbb, 0xbb, 0xbb, 0xf0, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xf0, 0x0, + 0x0, 0xf, 0xee, 0xee, 0xee, 0xee, 0xf0, 0x0, + 0x0, 0x0, 0xe, 0x40, 0xe, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x3f, 0x0, 0xe, 0x20, 0x0, 0x20, + 0x0, 0x1, 0xd7, 0x0, 0xe, 0x20, 0x0, 0xb3, + 0x1, 0x6e, 0xa0, 0x0, 0xe, 0x40, 0x1, 0xe2, + 0x1f, 0xb5, 0x0, 0x0, 0x9, 0xff, 0xff, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+898F "規" */ + 0x0, 0x9, 0x60, 0x4, 0xff, 0xff, 0xff, 0x40, + 0x0, 0x9, 0x60, 0x4, 0xb0, 0x0, 0x8, 0x40, + 0xb, 0xbe, 0xdb, 0x84, 0xb0, 0x0, 0x8, 0x40, + 0x5, 0x5b, 0xa5, 0x44, 0xfe, 0xee, 0xef, 0x40, + 0x0, 0x9, 0x60, 0x4, 0xb0, 0x0, 0x8, 0x40, + 0x0, 0x9, 0x70, 0x5, 0xd7, 0x77, 0x7c, 0x40, + 0x4f, 0xff, 0xff, 0xf5, 0xd5, 0x55, 0x5b, 0x40, + 0x0, 0xa, 0x50, 0x4, 0xb0, 0x0, 0x8, 0x40, + 0x0, 0xc, 0xb0, 0x4, 0xfe, 0xee, 0xef, 0x40, + 0x0, 0xe, 0x8a, 0x0, 0x1f, 0x14, 0xc0, 0x0, + 0x0, 0x5a, 0xb, 0x90, 0x4d, 0x4, 0xb0, 0x0, + 0x0, 0xd5, 0x1, 0x80, 0xb6, 0x4, 0xb0, 0xa3, + 0x9, 0xc0, 0x0, 0xa, 0xc0, 0x4, 0xc0, 0xb2, + 0x2d, 0x10, 0x2, 0xe9, 0x0, 0x1, 0xef, 0xd0, + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + + /* U+8996 "視" */ + 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0x20, 0xd, 0xee, 0xee, 0xef, 0x10, + 0x0, 0x7, 0x70, 0xd, 0x20, 0x0, 0xe, 0x10, + 0x3a, 0xab, 0xba, 0xd, 0x20, 0x0, 0xe, 0x10, + 0x27, 0x77, 0x9d, 0xd, 0xed, 0xdd, 0xdf, 0x10, + 0x0, 0x0, 0xb4, 0xd, 0x20, 0x0, 0xe, 0x10, + 0x0, 0x7, 0x90, 0xd, 0xcc, 0xcc, 0xcf, 0x10, + 0x0, 0x5f, 0xb0, 0xd, 0x31, 0x11, 0x1e, 0x10, + 0x6, 0xef, 0xb9, 0xd, 0x20, 0x0, 0xe, 0x10, + 0x7c, 0x1e, 0x2c, 0x3c, 0xef, 0xef, 0xee, 0x10, + 0x20, 0xe, 0x11, 0x0, 0x68, 0xe, 0x20, 0x0, + 0x0, 0xe, 0x10, 0x0, 0xa6, 0xe, 0x20, 0x0, + 0x0, 0xe, 0x10, 0x2, 0xe0, 0xe, 0x20, 0x90, + 0x0, 0xe, 0x10, 0x3d, 0x60, 0xe, 0x20, 0xe0, + 0x0, 0xe, 0x15, 0xd5, 0x0, 0xa, 0xff, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+899A "覚" */ + 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x20, 0x0, + 0x9, 0x90, 0x5, 0xd0, 0x0, 0x7c, 0x0, 0x0, + 0xd, 0x40, 0xb, 0x40, 0x2e, 0x10, 0x0, 0xbe, + 0xfe, 0xee, 0xee, 0xef, 0xfe, 0xe4, 0xc, 0x30, + 0x0, 0x0, 0x0, 0x0, 0xb, 0x40, 0xc3, 0x9b, + 0xbb, 0xbb, 0xbb, 0xb1, 0xb4, 0x2, 0xc, 0x30, + 0x0, 0x0, 0xe, 0x12, 0x10, 0x0, 0xcc, 0xbb, + 0xbb, 0xbb, 0xf1, 0x0, 0x0, 0xc, 0x30, 0x0, + 0x0, 0xe, 0x10, 0x0, 0x0, 0xcc, 0xbb, 0xbb, + 0xbb, 0xf1, 0x0, 0x0, 0xc, 0x30, 0x0, 0x0, + 0xe, 0x10, 0x0, 0x0, 0xac, 0xdd, 0xbc, 0xeb, + 0xd1, 0x0, 0x0, 0x0, 0x1f, 0x20, 0xf, 0x0, + 0x1, 0x60, 0x2, 0x7e, 0x70, 0x0, 0xf0, 0x0, + 0x4b, 0x3f, 0xd9, 0x20, 0x0, 0xb, 0xff, 0xff, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+89AA "親" */ + 0x0, 0x4, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xd1, 0x0, 0x8f, 0xee, 0xef, 0xa0, + 0xf, 0xff, 0xff, 0xfa, 0x87, 0x0, 0x6, 0xa0, + 0x0, 0x81, 0x2, 0x90, 0x87, 0x0, 0x6, 0xa0, + 0x0, 0xa4, 0x5, 0xa0, 0x8f, 0xee, 0xef, 0xa0, + 0x0, 0x67, 0xa, 0x40, 0x87, 0x0, 0x6, 0xa0, + 0x4d, 0xdd, 0xdf, 0xdc, 0x88, 0x11, 0x17, 0xa0, + 0x2, 0x22, 0xe3, 0x22, 0x8d, 0xcc, 0xcd, 0xa0, + 0x6, 0x66, 0xf7, 0x65, 0x87, 0x0, 0x6, 0xa0, + 0x5, 0x55, 0xf6, 0x54, 0x8e, 0xdd, 0xde, 0xa0, + 0x0, 0xc2, 0xe2, 0xb0, 0x8, 0x92, 0xe1, 0x0, + 0x3, 0xc0, 0xe1, 0xa4, 0xa, 0x51, 0xe0, 0x0, + 0xc, 0x50, 0xe1, 0x38, 0xe, 0x11, 0xe0, 0x39, + 0x5, 0x0, 0xe1, 0x0, 0xa9, 0x1, 0xe0, 0x49, + 0x0, 0x4e, 0xc0, 0x1d, 0xa0, 0x0, 0xed, 0xe5, + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2, 0x10, + + /* U+89BA "覺" */ + 0x0, 0x0, 0x46, 0x11, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x5a, 0x61, 0x2d, 0xa0, 0xab, 0xf6, 0x0, + 0x0, 0x99, 0x65, 0x86, 0x80, 0x46, 0xe5, 0x0, + 0x0, 0x88, 0x54, 0x27, 0xa2, 0x35, 0xf5, 0x0, + 0x0, 0x7d, 0xba, 0x1c, 0xc1, 0x9b, 0xf3, 0x0, + 0x5, 0xaa, 0x55, 0xc8, 0x97, 0x56, 0xf7, 0x40, + 0xe, 0x76, 0x66, 0x66, 0x66, 0x66, 0x68, 0xc0, + 0xc, 0x1a, 0xba, 0xaa, 0xaa, 0xac, 0x12, 0xb0, + 0x0, 0xd, 0x53, 0x33, 0x33, 0x3f, 0x20, 0x0, + 0x0, 0xd, 0x76, 0x66, 0x66, 0x6f, 0x20, 0x0, + 0x0, 0xd, 0xba, 0xaa, 0xaa, 0xaf, 0x20, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x0, 0xe, 0x20, 0x0, + 0x0, 0x9, 0xae, 0xca, 0xbf, 0xaa, 0x10, 0x10, + 0x0, 0x1, 0x8d, 0x10, 0x1e, 0x0, 0x0, 0xa4, + 0x3b, 0xdc, 0x70, 0x0, 0xc, 0xed, 0xde, 0xd0, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+89C0 "觀" */ + 0x0, 0x3c, 0x0, 0xe0, 0xb, 0xdc, 0xce, 0xa0, + 0xc, 0xcf, 0xcc, 0xfc, 0x8b, 0x10, 0x6, 0xa0, + 0x0, 0x2, 0x0, 0x20, 0xb, 0x10, 0x6, 0xa0, + 0x9, 0xbc, 0x5b, 0xad, 0x3b, 0xcc, 0xcd, 0xa0, + 0x9, 0x16, 0x5b, 0x8, 0x3b, 0x10, 0x6, 0xa0, + 0x6, 0xbb, 0x38, 0xaa, 0x2b, 0x98, 0x8b, 0xa0, + 0x0, 0x76, 0xc, 0x0, 0xb, 0x43, 0x38, 0xa0, + 0x1, 0xec, 0xcf, 0xdc, 0x5b, 0x10, 0x6, 0xa0, + 0xb, 0xf0, 0xe, 0x0, 0xa, 0xff, 0xff, 0xa0, + 0x2a, 0xec, 0xcf, 0xcc, 0x0, 0xc0, 0xc0, 0x0, + 0x0, 0xe5, 0x5e, 0x55, 0x0, 0xc0, 0xc0, 0x0, + 0x0, 0xe5, 0x5e, 0x55, 0x3, 0xa0, 0xc0, 0x7, + 0x0, 0xea, 0xaf, 0xaa, 0x4c, 0x30, 0xc0, 0xa, + 0x0, 0xe2, 0x22, 0x22, 0x97, 0x0, 0x9e, 0xe5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+89D2 "角" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6f, 0xee, 0xee, 0xf6, 0x0, 0x0, 0x2, 0xf2, + 0x0, 0x3, 0xe1, 0x0, 0x0, 0x3e, 0x70, 0x0, + 0xd, 0x60, 0x0, 0x3, 0xef, 0xee, 0xee, 0xef, + 0xee, 0xee, 0xc, 0x8e, 0x30, 0x3, 0xe0, 0x0, + 0x3f, 0x0, 0xe, 0x20, 0x2, 0xe0, 0x0, 0x2f, + 0x0, 0xe, 0xdc, 0xcd, 0xfc, 0xcc, 0xdf, 0x0, + 0xf, 0x42, 0x24, 0xe2, 0x22, 0x4f, 0x0, 0xf, + 0x10, 0x2, 0xe0, 0x0, 0x2f, 0x0, 0x1f, 0x33, + 0x35, 0xf3, 0x33, 0x5f, 0x0, 0x4f, 0xbb, 0xbc, + 0xfb, 0xbb, 0xcf, 0x0, 0xa8, 0x0, 0x2, 0xe0, + 0x0, 0x2f, 0x3, 0xf2, 0x0, 0x2, 0xe0, 0x0, + 0x3f, 0xa, 0x60, 0x0, 0x2, 0xe0, 0x9f, 0xe9, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+89E3 "解" */ + 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4d, 0x0, 0x0, 0x5e, 0xef, 0xee, 0xf4, + 0x0, 0x9e, 0xde, 0xe0, 0x0, 0x5b, 0x0, 0xb3, + 0x1, 0xf2, 0xa, 0x70, 0x0, 0xb6, 0x0, 0xd2, + 0xa, 0xe7, 0x8f, 0x86, 0x3, 0xe0, 0x0, 0xf0, + 0x1e, 0xe5, 0xd5, 0x5e, 0x4d, 0x30, 0xbd, 0xb0, + 0x0, 0xe0, 0xc0, 0xe, 0x24, 0x51, 0xb1, 0x0, + 0x0, 0xf9, 0xea, 0x9e, 0x7, 0x82, 0xe0, 0x0, + 0x0, 0xe3, 0xd4, 0x3e, 0xc, 0xff, 0xff, 0xf5, + 0x1, 0xe0, 0xc0, 0xe, 0x4c, 0x2, 0xe0, 0x0, + 0x2, 0xe8, 0xe8, 0x8e, 0x33, 0x2, 0xe0, 0x0, + 0x3, 0xc5, 0xd5, 0x5e, 0x6f, 0xff, 0xff, 0xfb, + 0x6, 0x80, 0xc0, 0xe, 0x0, 0x2, 0xe0, 0x0, + 0xa, 0x40, 0xc0, 0xe, 0x0, 0x2, 0xe0, 0x0, + 0x1c, 0x0, 0x59, 0xe9, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+89E6 "触" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x0, 0x0, 0x0, 0xf, 0x10, 0x0, + 0x0, 0x6f, 0xde, 0xe0, 0x0, 0xf, 0x10, 0x0, + 0x0, 0xb4, 0xa, 0x90, 0x13, 0x3f, 0x43, 0x30, + 0x5, 0xe2, 0x3f, 0x31, 0x7e, 0xdf, 0xdd, 0xd0, + 0xe, 0xfb, 0xfb, 0xbc, 0x76, 0xe, 0x1, 0xd0, + 0x3, 0xd0, 0xd0, 0x1c, 0x76, 0xe, 0x1, 0xd0, + 0x0, 0xfb, 0xfb, 0xcc, 0x76, 0xe, 0x1, 0xd0, + 0x0, 0xe1, 0xd1, 0x2c, 0x7b, 0x8f, 0x89, 0xd0, + 0x0, 0xd0, 0xd0, 0x1c, 0x36, 0x6f, 0x76, 0x50, + 0x1, 0xfd, 0xfd, 0xdc, 0x0, 0xf, 0x17, 0x0, + 0x2, 0xb0, 0xd0, 0x1c, 0x0, 0xf, 0x19, 0x60, + 0x5, 0x80, 0xd0, 0x1c, 0x0, 0xf, 0x46, 0xd0, + 0x8, 0x40, 0xd0, 0x1c, 0x9c, 0xef, 0xfc, 0xd3, + 0xc, 0x0, 0xd5, 0xe8, 0x87, 0x41, 0x0, 0x68, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8A00 "言" */ + 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xf1, 0x0, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xdd, 0xdd, 0xdd, 0xdd, 0xa0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xdd, 0xdd, 0xdd, 0xdd, 0xa0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0xee, 0xee, 0xee, 0xee, 0xe0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0x1, 0xf0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0x1, 0xf0, 0x0, + 0x0, 0xe, 0x42, 0x22, 0x22, 0x24, 0xf0, 0x0, + 0x0, 0xe, 0xcb, 0xbb, 0xbb, 0xbc, 0xf0, 0x0, + + /* U+8A08 "計" */ + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x50, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, + 0x2b, 0x0, 0x0, 0x2, 0xe0, 0x0, 0xb, 0xbb, + 0xcb, 0xb7, 0x0, 0x2e, 0x0, 0x0, 0x11, 0x11, + 0x11, 0x0, 0x2, 0xe0, 0x0, 0x2, 0xcc, 0xcc, + 0xc0, 0x0, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6f, 0xff, 0xff, 0xff, 0x42, 0xbb, 0xbb, 0xa0, + 0x0, 0x2e, 0x0, 0x0, 0x2, 0x22, 0x22, 0x0, + 0x2, 0xe0, 0x0, 0x0, 0x22, 0x22, 0x20, 0x0, + 0x2e, 0x0, 0x0, 0x1f, 0xcc, 0xce, 0x0, 0x2, + 0xe0, 0x0, 0x1, 0xc0, 0x0, 0xe0, 0x0, 0x2e, + 0x0, 0x0, 0x1c, 0x0, 0xe, 0x0, 0x2, 0xe0, + 0x0, 0x1, 0xfd, 0xdd, 0xe0, 0x0, 0x2e, 0x0, + 0x0, 0x1d, 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, + + /* U+8A0A "訊" */ + 0x0, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x40, 0x2f, 0xff, 0xff, 0xfd, 0x0, + 0x1, 0x15, 0x41, 0x10, 0x1f, 0x0, 0x3d, 0x0, + 0x1d, 0xdd, 0xdd, 0x90, 0x1e, 0x0, 0x3d, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x3c, 0x0, + 0x5, 0xcc, 0xcc, 0x0, 0x1e, 0x0, 0x3c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x3c, 0x0, + 0x5, 0xbb, 0xbb, 0x5d, 0xdf, 0xdd, 0x6c, 0x0, + 0x1, 0x22, 0x22, 0x12, 0x4f, 0x22, 0x3d, 0x0, + 0x1, 0x22, 0x22, 0x0, 0x1e, 0x0, 0x2d, 0x0, + 0x6, 0xdc, 0xcf, 0x10, 0x1e, 0x0, 0x1e, 0x0, + 0x6, 0x60, 0xc, 0x10, 0x1e, 0x0, 0xf, 0x0, + 0x6, 0x60, 0xc, 0x10, 0x1e, 0x0, 0xe, 0x38, + 0x6, 0xed, 0xdf, 0x10, 0x1e, 0x0, 0xa, 0x97, + 0x6, 0x70, 0x0, 0x0, 0x1e, 0x0, 0x3, 0xd2, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, + + /* U+8A0E "討" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x8, 0x70, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x1a, 0xaa, 0xaa, 0x90, 0x0, 0x0, 0xe2, 0x0, + 0x2, 0x22, 0x22, 0x2b, 0xbb, 0xbb, 0xfc, 0xb1, + 0x6, 0xcc, 0xcc, 0x32, 0x22, 0x22, 0xe4, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x5, 0xbb, 0xbb, 0x30, 0xe2, 0x0, 0xe2, 0x0, + 0x1, 0x22, 0x22, 0x0, 0x7a, 0x0, 0xe2, 0x0, + 0x1, 0x22, 0x22, 0x0, 0xe, 0x10, 0xe2, 0x0, + 0x7, 0xdc, 0xce, 0x40, 0xa, 0x70, 0xe2, 0x0, + 0x7, 0x70, 0xa, 0x40, 0x1, 0x0, 0xe2, 0x0, + 0x7, 0x70, 0xa, 0x40, 0x0, 0x0, 0xe2, 0x0, + 0x7, 0xed, 0xdf, 0x40, 0x0, 0x11, 0xf2, 0x0, + 0x7, 0x70, 0x0, 0x0, 0x7, 0xff, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8A13 "訓" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x40, 0x0, 0xb2, 0xf, 0x0, 0xf0, + 0x2, 0x25, 0x52, 0x10, 0xd2, 0xf, 0x0, 0xf0, + 0x1d, 0xdd, 0xdd, 0x90, 0xd2, 0xf, 0x0, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0xd2, 0xf, 0x0, 0xf0, + 0x5, 0xcc, 0xcc, 0x10, 0xd2, 0xf, 0x0, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0xd2, 0xf, 0x0, 0xf0, + 0x5, 0xbb, 0xbb, 0x10, 0xe2, 0xf, 0x0, 0xf0, + 0x1, 0x22, 0x22, 0x0, 0xf2, 0xf, 0x0, 0xf0, + 0x1, 0x22, 0x22, 0x0, 0xf0, 0xf, 0x0, 0xf0, + 0x7, 0xec, 0xce, 0x31, 0xe0, 0xf, 0x0, 0xf0, + 0x7, 0x70, 0xb, 0x35, 0xb0, 0xf, 0x0, 0xf0, + 0x7, 0x70, 0xb, 0x3a, 0x60, 0xe, 0x0, 0xf0, + 0x7, 0xed, 0xdf, 0x6e, 0x10, 0x0, 0x0, 0xf0, + 0x7, 0x70, 0x0, 0x96, 0x0, 0x0, 0x0, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8A18 "記" */ + 0x0, 0x2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x80, 0x6, 0xff, 0xff, 0xff, 0x10, + 0x0, 0x3, 0x40, 0x0, 0x0, 0x0, 0xe, 0x10, + 0x4e, 0xee, 0xee, 0xe1, 0x0, 0x0, 0xe, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x10, + 0x7, 0xdd, 0xdd, 0x30, 0x0, 0x0, 0xe, 0x10, + 0x0, 0x0, 0x0, 0x1, 0x77, 0x77, 0x7f, 0x10, + 0x8, 0xaa, 0xaa, 0x62, 0xf8, 0x88, 0x8f, 0x10, + 0x2, 0x33, 0x33, 0x22, 0xe0, 0x0, 0x5, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x9, 0xed, 0xdf, 0x42, 0xe0, 0x0, 0x0, 0x0, + 0x9, 0x50, 0xa, 0x42, 0xe0, 0x0, 0x0, 0x70, + 0x9, 0x50, 0xa, 0x42, 0xe0, 0x0, 0x0, 0xe1, + 0x9, 0xdb, 0xbe, 0x42, 0xf1, 0x0, 0x3, 0xe0, + 0x9, 0x72, 0x22, 0x0, 0xbf, 0xff, 0xfe, 0x60, + + /* U+8A2A "訪" */ + 0x0, 0x25, 0x0, 0x0, 0x0, 0x51, 0x0, 0x0, + 0x0, 0x1e, 0x10, 0x0, 0x0, 0xa6, 0x0, 0x0, + 0x0, 0x7, 0x30, 0x0, 0x0, 0x5a, 0x0, 0x0, + 0x1e, 0xee, 0xee, 0x8d, 0xdd, 0xde, 0xdd, 0xd1, + 0x0, 0x0, 0x0, 0x2, 0x2d, 0x52, 0x22, 0x20, + 0x5, 0xcc, 0xcc, 0x0, 0xd, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe, 0x64, 0x44, 0x10, + 0x5, 0xbb, 0xbb, 0x0, 0xf, 0xbb, 0xbe, 0x50, + 0x1, 0x22, 0x22, 0x0, 0x2e, 0x0, 0xb, 0x40, + 0x1, 0x22, 0x22, 0x0, 0x4b, 0x0, 0xc, 0x30, + 0x7, 0xdc, 0xcf, 0x0, 0x97, 0x0, 0xd, 0x20, + 0x7, 0x60, 0xe, 0x0, 0xf2, 0x0, 0xe, 0x10, + 0x7, 0x60, 0xe, 0x7, 0xb0, 0x0, 0xf, 0x0, + 0x7, 0xed, 0xdf, 0x5f, 0x20, 0x0, 0x4d, 0x0, + 0x6, 0x60, 0x0, 0xd4, 0x0, 0x8f, 0xf6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8A2D "設" */ + 0x0, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x30, 0x0, 0xdf, 0xff, 0xf1, 0x0, + 0x0, 0x5, 0x60, 0x0, 0xe1, 0x0, 0xe1, 0x0, + 0x2e, 0xee, 0xee, 0xd0, 0xf1, 0x0, 0xe1, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xe0, 0x0, 0xe1, 0x0, + 0x5, 0xcc, 0xcc, 0x3c, 0x80, 0x0, 0xdc, 0xb1, + 0x0, 0x0, 0x0, 0x7c, 0x0, 0x0, 0x13, 0x30, + 0x2, 0x55, 0x55, 0x22, 0x11, 0x11, 0x11, 0x0, + 0x4, 0x99, 0x99, 0x5e, 0xee, 0xee, 0xef, 0x30, + 0x1, 0x22, 0x22, 0x5, 0x90, 0x0, 0x4c, 0x0, + 0x7, 0xec, 0xce, 0x30, 0xc4, 0x1, 0xd4, 0x0, + 0x7, 0x70, 0xb, 0x30, 0x2e, 0x5d, 0x60, 0x0, + 0x7, 0x70, 0xb, 0x30, 0x9, 0xfc, 0x10, 0x0, + 0x7, 0xed, 0xdf, 0x45, 0xcd, 0x3a, 0xf8, 0x30, + 0x7, 0x70, 0x0, 0x9e, 0x70, 0x0, 0x4b, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8A31 "許" */ + 0x0, 0x4, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x10, 0x0, 0x6d, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x40, 0x0, 0xb9, 0x22, 0x22, 0x20, + 0x5e, 0xee, 0xee, 0xd2, 0xfd, 0xdf, 0xdd, 0xd0, + 0x0, 0x0, 0x0, 0xb, 0xa0, 0x2e, 0x0, 0x0, + 0x7, 0xcc, 0xcc, 0x9f, 0x20, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x14, 0x0, 0x2e, 0x0, 0x0, + 0x3, 0x66, 0x66, 0x21, 0x11, 0x3e, 0x11, 0x10, + 0x5, 0x88, 0x88, 0x5f, 0xff, 0xff, 0xff, 0xf5, + 0x0, 0x11, 0x11, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x9, 0xed, 0xdf, 0x40, 0x0, 0x2e, 0x0, 0x0, + 0x9, 0x50, 0xa, 0x40, 0x0, 0x2e, 0x0, 0x0, + 0x9, 0x50, 0xa, 0x40, 0x0, 0x2e, 0x0, 0x0, + 0x9, 0xdc, 0xce, 0x40, 0x0, 0x2e, 0x0, 0x0, + 0x8, 0x51, 0x11, 0x0, 0x0, 0x2e, 0x0, 0x0, + + /* U+8A33 "訳" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x80, 0x0, 0xff, 0xff, 0xff, 0xe0, + 0x3, 0x35, 0x63, 0x30, 0xf0, 0x0, 0x1, 0xe0, + 0x1c, 0xcc, 0xcc, 0x90, 0xf0, 0x0, 0x1, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x1, 0xe0, + 0x5, 0xcc, 0xcc, 0x20, 0xf0, 0x0, 0x1, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0xf7, 0x77, 0x78, 0xe0, + 0x5, 0xbb, 0xbb, 0x21, 0xf8, 0x8c, 0xb8, 0x70, + 0x1, 0x22, 0x22, 0x3, 0xd0, 0x6, 0x90, 0x0, + 0x1, 0x22, 0x22, 0x4, 0xb0, 0x2, 0xd0, 0x0, + 0x7, 0xec, 0xce, 0x46, 0x90, 0x0, 0xd3, 0x0, + 0x7, 0x70, 0xa, 0x4a, 0x70, 0x0, 0x7b, 0x0, + 0x7, 0x70, 0xa, 0x5e, 0x20, 0x0, 0x1e, 0x50, + 0x7, 0xed, 0xdf, 0xbc, 0x0, 0x0, 0x5, 0xf5, + 0x7, 0x80, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x6a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8A34 "訴" */ + 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x5, 0x10, + 0x0, 0xc, 0x40, 0x0, 0x3, 0x6a, 0xeb, 0x50, + 0x0, 0x4, 0x70, 0x0, 0xec, 0x85, 0x10, 0x0, + 0x1e, 0xee, 0xee, 0xa0, 0xf1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf1, 0x0, 0x0, 0x0, + 0x5, 0xcc, 0xcc, 0x0, 0xf7, 0x66, 0x66, 0x63, + 0x0, 0x0, 0x0, 0x0, 0xf9, 0x99, 0xf9, 0x94, + 0x5, 0xbb, 0xbb, 0x10, 0xf1, 0x0, 0xf1, 0x0, + 0x1, 0x22, 0x22, 0x2, 0xf8, 0x71, 0xf1, 0x0, + 0x1, 0x22, 0x22, 0x3, 0xe6, 0xee, 0xf1, 0x0, + 0x6, 0xec, 0xcf, 0x15, 0xc0, 0x6, 0xfc, 0x50, + 0x6, 0x80, 0xd, 0x1a, 0x70, 0x0, 0xf6, 0xd5, + 0x6, 0x80, 0xd, 0x2f, 0x20, 0x0, 0xf1, 0x0, + 0x6, 0xed, 0xdf, 0xbb, 0x0, 0x0, 0xf1, 0x0, + 0x6, 0x90, 0x0, 0x92, 0x0, 0x0, 0xf1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + + /* U+8A55 "評" */ + 0x0, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x40, 0xa, 0xff, 0xff, 0xff, 0xf6, + 0x1, 0x15, 0x41, 0x10, 0x0, 0x2e, 0x0, 0x0, + 0x1e, 0xee, 0xee, 0xa1, 0xb0, 0x1e, 0x1, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0xe1, 0x1e, 0x4, 0xb0, + 0x5, 0xcc, 0xcc, 0x0, 0xa5, 0x1e, 0x8, 0x60, + 0x0, 0x0, 0x0, 0x0, 0x78, 0x1e, 0xd, 0x10, + 0x5, 0xbb, 0xbb, 0x0, 0x22, 0x1e, 0x4, 0x0, + 0x1, 0x22, 0x22, 0x4c, 0xcc, 0xdf, 0xcc, 0xc9, + 0x1, 0x22, 0x22, 0x28, 0x88, 0x9f, 0x88, 0x86, + 0x7, 0xdc, 0xcf, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x7, 0x60, 0xd, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x7, 0x60, 0xd, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x7, 0xed, 0xdf, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x7, 0x70, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, + + /* U+8A66 "試" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x78, 0x0, 0x0, 0x0, 0xf, 0x47, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x0, 0xe, 0x1b, 0x50, + 0x2a, 0xaa, 0xaa, 0x23, 0x33, 0x3e, 0x55, 0x60, + 0x2, 0x22, 0x22, 0x5a, 0xaa, 0xaf, 0xba, 0xa2, + 0x6, 0xcc, 0xc9, 0x0, 0x0, 0xc, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x11, 0x11, 0x1b, 0x40, 0x0, + 0x6, 0xbb, 0xb8, 0xae, 0xfe, 0xaa, 0x50, 0x0, + 0x1, 0x22, 0x21, 0x0, 0xf0, 0x8, 0x70, 0x0, + 0x1, 0x22, 0x21, 0x0, 0xf0, 0x6, 0x90, 0x0, + 0x8, 0xdc, 0xdb, 0x0, 0xf0, 0x4, 0xb0, 0x0, + 0x8, 0x50, 0x3b, 0x0, 0xf0, 0x23, 0xe0, 0x10, + 0x8, 0x50, 0x3b, 0x37, 0xfd, 0xa2, 0xd2, 0x94, + 0x8, 0xed, 0xeb, 0x87, 0x30, 0x0, 0x89, 0xb2, + 0x8, 0x60, 0x0, 0x0, 0x0, 0x0, 0x1d, 0xb0, + + /* U+8A71 "話" */ + 0x0, 0x17, 0x0, 0x0, 0x0, 0x0, 0x4, 0x30, + 0x0, 0xd, 0x40, 0x1, 0x47, 0x9c, 0xeb, 0x50, + 0x0, 0x4, 0x70, 0x6, 0xa8, 0x7e, 0x0, 0x0, + 0x1e, 0xee, 0xee, 0xa0, 0x0, 0x1e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x5, 0xcc, 0xcc, 0x28, 0xaa, 0xbf, 0xaa, 0xa8, + 0x0, 0x0, 0x0, 0x3, 0x55, 0x6f, 0x55, 0x53, + 0x5, 0xbb, 0xbb, 0x20, 0x0, 0x1e, 0x0, 0x0, + 0x1, 0x22, 0x22, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x1, 0x22, 0x22, 0x1, 0x99, 0x9f, 0x99, 0x80, + 0x7, 0xec, 0xce, 0x41, 0xf8, 0x88, 0x89, 0xe0, + 0x7, 0x70, 0xa, 0x41, 0xe0, 0x0, 0x2, 0xe0, + 0x7, 0x70, 0xa, 0x41, 0xe0, 0x0, 0x2, 0xe0, + 0x7, 0xb6, 0x6c, 0x41, 0xe2, 0x22, 0x25, 0xe0, + 0x7, 0xb7, 0x77, 0x21, 0xfc, 0xcc, 0xcd, 0xd0, + + /* U+8A72 "該" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x1e, 0x10, 0x0, 0x0, 0x6a, 0x0, 0x0, + 0x0, 0x8, 0x80, 0x0, 0x0, 0x1f, 0x10, 0x0, + 0x8, 0x89, 0x98, 0x7c, 0xff, 0xff, 0xff, 0xf7, + 0x4, 0x44, 0x44, 0x30, 0x5, 0xc0, 0x0, 0x0, + 0x5, 0xcc, 0xcc, 0x30, 0xd, 0x20, 0x58, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xba, 0x55, 0xe2, 0x0, + 0x4, 0xbb, 0xbb, 0x37, 0xca, 0xaf, 0x70, 0x0, + 0x1, 0x22, 0x22, 0x0, 0x0, 0xc9, 0x5, 0xc0, + 0x1, 0x22, 0x22, 0x0, 0x1c, 0x80, 0x1e, 0x40, + 0x6, 0xec, 0xce, 0x45, 0xe6, 0x1, 0xd9, 0x0, + 0x6, 0x80, 0x9, 0x47, 0x10, 0x2d, 0xc0, 0x0, + 0x6, 0x80, 0x9, 0x40, 0x7, 0xf8, 0xd7, 0x0, + 0x6, 0xed, 0xdf, 0x45, 0xdd, 0x30, 0x1d, 0x90, + 0x6, 0x80, 0x0, 0xbd, 0x50, 0x0, 0x1, 0xd4, + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + + /* U+8A73 "詳" */ + 0x0, 0x16, 0x0, 0x0, 0x50, 0x0, 0x3, 0x50, + 0x0, 0xd, 0x40, 0x0, 0xb7, 0x0, 0xb, 0x70, + 0x0, 0x4, 0x60, 0x0, 0x2e, 0x0, 0x3d, 0x0, + 0x1e, 0xee, 0xee, 0x95, 0x7d, 0x87, 0xab, 0x73, + 0x0, 0x0, 0x0, 0x5, 0x77, 0x8f, 0x77, 0x73, + 0x5, 0xcc, 0xcc, 0x10, 0x0, 0x1e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x11, 0x3e, 0x11, 0x10, + 0x5, 0xbb, 0xbb, 0x13, 0xee, 0xef, 0xee, 0xe0, + 0x1, 0x22, 0x22, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x2, 0x55, 0x55, 0x10, 0x0, 0x1e, 0x0, 0x0, + 0x7, 0xdb, 0xbe, 0x40, 0x0, 0x2e, 0x0, 0x0, + 0x7, 0x70, 0xa, 0x4f, 0xff, 0xff, 0xff, 0xfb, + 0x7, 0x70, 0xa, 0x40, 0x0, 0x1e, 0x0, 0x0, + 0x7, 0xed, 0xdf, 0x40, 0x0, 0x1e, 0x0, 0x0, + 0x7, 0x70, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, + + /* U+8A8C "誌" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7a, 0x0, 0x0, 0x0, 0xc2, 0x0, 0x0, + 0x0, 0xb, 0x40, 0x0, 0x0, 0xd3, 0x0, 0x0, + 0x3a, 0xab, 0xaa, 0x7f, 0xff, 0xff, 0xff, 0xf1, + 0x2, 0x22, 0x22, 0x0, 0x0, 0xc2, 0x0, 0x0, + 0x9, 0xcc, 0xc6, 0x0, 0x0, 0xc2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2b, 0xbb, 0xfc, 0xbb, 0x90, + 0x8, 0xbb, 0xb5, 0x3, 0x35, 0x93, 0x33, 0x30, + 0x1, 0x22, 0x21, 0x0, 0x2, 0xd5, 0x0, 0x0, + 0x1, 0x22, 0x21, 0x0, 0x27, 0x2e, 0x20, 0x0, + 0xa, 0xdc, 0xd8, 0x1d, 0x3c, 0x3, 0x1d, 0x10, + 0xa, 0x30, 0x48, 0x4c, 0x3c, 0x0, 0x17, 0x90, + 0xa, 0x30, 0x48, 0x98, 0x3c, 0x0, 0xd2, 0xe0, + 0xa, 0x86, 0x99, 0xc1, 0x3d, 0x0, 0xe0, 0xa2, + 0xa, 0x97, 0x74, 0x0, 0xc, 0xee, 0x90, 0x0, + + /* U+8A8D "認" */ + 0x0, 0x35, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0x20, 0xb, 0xee, 0xef, 0xee, 0xf0, + 0x0, 0x5, 0x50, 0x0, 0x50, 0x4a, 0x0, 0xf0, + 0x1e, 0xee, 0xee, 0x91, 0xd0, 0x87, 0x0, 0xf0, + 0x0, 0x0, 0x0, 0xb, 0x40, 0xe1, 0x1, 0xe0, + 0x5, 0xcc, 0xcc, 0x14, 0x8, 0xa0, 0x3, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x6d, 0x13, 0x6a, 0x90, + 0x5, 0xbb, 0xbb, 0xb, 0xb2, 0x2, 0x87, 0x10, + 0x1, 0x22, 0x22, 0x1, 0x0, 0xb0, 0x0, 0x0, + 0x1, 0x22, 0x22, 0x0, 0x2, 0x88, 0x2, 0x0, + 0x7, 0xdc, 0xcf, 0x2a, 0x3d, 0xd, 0xa, 0x50, + 0x7, 0x70, 0xc, 0x2d, 0x1d, 0x4, 0x1, 0xe0, + 0x7, 0x70, 0xc, 0x7a, 0x1d, 0x0, 0xb, 0x96, + 0x7, 0xed, 0xdf, 0x92, 0x1e, 0x0, 0x2c, 0x22, + 0x7, 0x70, 0x0, 0x0, 0xc, 0xff, 0xf7, 0x0, + + /* U+8A95 "誕" */ + 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x5, 0x50, + 0x0, 0xb4, 0x6, 0xff, 0xe2, 0x7a, 0xeb, 0x50, + 0x0, 0x55, 0x0, 0x6, 0x94, 0x84, 0xe0, 0x0, + 0x5f, 0xff, 0xf0, 0xd, 0x30, 0x0, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x4b, 0x0, 0x10, 0xe0, 0x0, + 0xa, 0xdd, 0x90, 0xd6, 0x20, 0xd0, 0xe2, 0x20, + 0x0, 0x0, 0x5, 0xbb, 0xf0, 0xd0, 0xfc, 0xc0, + 0x8, 0xbb, 0x70, 0x0, 0xd0, 0xd0, 0xe0, 0x0, + 0x1, 0x22, 0x13, 0x52, 0xc0, 0xd0, 0xe0, 0x0, + 0x1, 0x22, 0x12, 0xa5, 0x90, 0xd0, 0xe0, 0x0, + 0xd, 0xcc, 0xb0, 0xda, 0x40, 0xd0, 0xe0, 0x0, + 0xd, 0x2, 0xb0, 0x6f, 0x0, 0xe9, 0xf9, 0x91, + 0xd, 0x2, 0xb0, 0x8f, 0x60, 0x33, 0x33, 0x30, + 0xd, 0xcd, 0xb5, 0xd1, 0xca, 0x30, 0x0, 0x0, + 0xd, 0x11, 0x2e, 0x30, 0x7, 0xce, 0xff, 0xf3, + 0x2, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8A98 "誘" */ + 0x0, 0x63, 0x0, 0x0, 0x12, 0x46, 0x9b, 0x10, + 0x0, 0x2e, 0x0, 0x5d, 0xcb, 0xf8, 0x52, 0x0, + 0x0, 0x9, 0x30, 0x0, 0x0, 0xd1, 0x0, 0x0, + 0x5e, 0xee, 0xee, 0x56, 0x66, 0xe7, 0x66, 0x61, + 0x0, 0x0, 0x0, 0x57, 0x8f, 0xff, 0xa7, 0x71, + 0x8, 0xcc, 0xc7, 0x0, 0xa8, 0xd5, 0xd2, 0x0, + 0x0, 0x0, 0x0, 0x1b, 0x90, 0xd1, 0x4e, 0x60, + 0x7, 0xaa, 0xa6, 0xd6, 0x0, 0xb1, 0x2, 0xc3, + 0x2, 0x33, 0x31, 0x5b, 0xbb, 0xbb, 0x80, 0x0, + 0x5, 0x88, 0x85, 0x13, 0xb8, 0x3a, 0x80, 0x0, + 0xb, 0x85, 0x89, 0x0, 0xb4, 0xd, 0xdb, 0xa0, + 0xb, 0x30, 0x49, 0x0, 0xe1, 0x2, 0x25, 0xc0, + 0xb, 0x30, 0x49, 0x5, 0xb0, 0x0, 0x5, 0xb0, + 0xb, 0xdc, 0xd9, 0x3e, 0x20, 0x0, 0x8, 0x80, + 0x9, 0x41, 0x11, 0xc4, 0x0, 0x1d, 0xed, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8A9E "語" */ + 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x50, 0xe, 0xef, 0xfe, 0xee, 0xe3, + 0x0, 0x3, 0x60, 0x0, 0x4, 0xb0, 0x0, 0x0, + 0x1e, 0xee, 0xee, 0xb2, 0x4a, 0xb4, 0x44, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xae, 0xca, 0xaf, 0x0, + 0x5, 0xcc, 0xcc, 0x20, 0xd, 0x20, 0xf, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1f, 0x0, 0xf, 0x0, + 0x4, 0xbb, 0xbb, 0x7d, 0xdf, 0xdd, 0xdf, 0xd7, + 0x1, 0x22, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x22, 0x22, 0x2, 0x44, 0x44, 0x44, 0x20, + 0x6, 0xec, 0xce, 0x47, 0xda, 0xaa, 0xad, 0x80, + 0x6, 0x80, 0xa, 0x47, 0x80, 0x0, 0x7, 0x80, + 0x6, 0x80, 0xa, 0x47, 0x80, 0x0, 0x7, 0x80, + 0x6, 0xb6, 0x6c, 0x47, 0xa3, 0x33, 0x39, 0x80, + 0x6, 0xc7, 0x77, 0x27, 0xeb, 0xbb, 0xbd, 0x80, + + /* U+8AAA "說" */ + 0x0, 0x52, 0x0, 0x0, 0x31, 0x5, 0x20, 0x0, + 0x0, 0x5b, 0x0, 0x0, 0xd1, 0x4, 0xc0, 0x0, + 0x0, 0xa, 0x0, 0x7, 0x80, 0x0, 0xb5, 0x0, + 0x7e, 0xee, 0xee, 0x4d, 0x10, 0x0, 0x2e, 0x30, + 0x0, 0x0, 0x0, 0xe7, 0x44, 0x44, 0x48, 0xe1, + 0xa, 0xcc, 0xc6, 0x2e, 0xba, 0xaa, 0xbf, 0x10, + 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, 0xf, 0x0, + 0x9, 0xbb, 0xb6, 0xe, 0x10, 0x0, 0xf, 0x0, + 0x2, 0x22, 0x21, 0xe, 0x98, 0x88, 0x8f, 0x0, + 0x2, 0x22, 0x21, 0xa, 0xde, 0xbf, 0xcb, 0x0, + 0xd, 0xcc, 0xda, 0x0, 0x87, 0xe, 0x10, 0x0, + 0xd, 0x0, 0x4a, 0x0, 0xb5, 0xe, 0x10, 0x0, + 0xd, 0x0, 0x4a, 0x2, 0xf0, 0xe, 0x10, 0xa0, + 0xd, 0xdd, 0xea, 0x3e, 0x60, 0xe, 0x10, 0xe0, + 0xc, 0x10, 0x2, 0xd5, 0x0, 0xa, 0xff, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8AAC "説" */ + 0x0, 0x16, 0x0, 0x0, 0x60, 0x0, 0x5, 0x30, + 0x0, 0xd, 0x30, 0x0, 0x99, 0x0, 0xe, 0x30, + 0x0, 0x4, 0x60, 0x0, 0x1f, 0x10, 0x4c, 0x0, + 0x1e, 0xee, 0xee, 0x92, 0x6b, 0x76, 0xca, 0x40, + 0x0, 0x0, 0x0, 0x7, 0xc8, 0x88, 0x8a, 0xc0, + 0x5, 0xcc, 0xcc, 0x17, 0x80, 0x0, 0x2, 0xc0, + 0x0, 0x0, 0x0, 0x7, 0x80, 0x0, 0x2, 0xc0, + 0x5, 0xbb, 0xbb, 0x17, 0xa2, 0x22, 0x25, 0xc0, + 0x1, 0x22, 0x22, 0x7, 0xff, 0xff, 0xff, 0xc0, + 0x1, 0x22, 0x22, 0x0, 0xc, 0x42, 0xd0, 0x0, + 0x7, 0xec, 0xcf, 0x30, 0xf, 0x12, 0xd0, 0x0, + 0x7, 0x70, 0xb, 0x30, 0x4d, 0x2, 0xd0, 0x0, + 0x7, 0x70, 0xb, 0x30, 0xc6, 0x2, 0xd0, 0x37, + 0x7, 0xed, 0xdf, 0x4b, 0xb0, 0x2, 0xe0, 0x59, + 0x7, 0x70, 0x0, 0xca, 0x10, 0x0, 0xdf, 0xf4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8AAD "読" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x87, 0x0, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0x0, 0xc, 0x10, 0x6e, 0xee, 0xff, 0xee, 0xe1, + 0x3b, 0xbb, 0xbb, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xaa, 0xec, 0xaa, 0x50, + 0x9, 0xcc, 0xc5, 0x3, 0x33, 0x33, 0x33, 0x10, + 0x0, 0x11, 0x10, 0x4a, 0xaa, 0xaa, 0xaa, 0xa0, + 0x8, 0xbb, 0xb5, 0x6a, 0x33, 0x33, 0x33, 0xe1, + 0x2, 0x33, 0x31, 0x68, 0x14, 0x2, 0x30, 0xd1, + 0x1, 0x22, 0x21, 0x23, 0x3c, 0x6, 0x90, 0x50, + 0xb, 0xdc, 0xd9, 0x0, 0x4b, 0x6, 0x90, 0x0, + 0xb, 0x30, 0x59, 0x0, 0x88, 0x6, 0x90, 0x0, + 0xb, 0x30, 0x59, 0x2, 0xf2, 0x6, 0x90, 0x63, + 0xb, 0xed, 0xe9, 0x2d, 0x80, 0x6, 0x90, 0x94, + 0xb, 0x40, 0x0, 0xe8, 0x0, 0x3, 0xef, 0xe1, + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + + /* U+8AB0 "誰" */ + 0x0, 0x17, 0x0, 0x0, 0x6, 0x14, 0x0, 0x0, + 0x0, 0xd, 0x40, 0x0, 0x5c, 0x2e, 0x0, 0x0, + 0x0, 0x4, 0x70, 0x0, 0xb5, 0xa, 0x50, 0x0, + 0x1e, 0xee, 0xee, 0xa1, 0xfc, 0xbb, 0xbb, 0xb1, + 0x0, 0x0, 0x0, 0xa, 0xd3, 0x3e, 0x53, 0x30, + 0x5, 0xcc, 0xcc, 0x7f, 0xc0, 0xd, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x67, 0xe9, 0x9f, 0xa9, 0x60, + 0x5, 0xbb, 0xbb, 0x22, 0xd5, 0x5e, 0x65, 0x30, + 0x1, 0x22, 0x22, 0x2, 0xc0, 0xd, 0x10, 0x0, + 0x1, 0x33, 0x33, 0x12, 0xc0, 0xe, 0x20, 0x0, + 0x7, 0xdb, 0xbe, 0x42, 0xfe, 0xef, 0xee, 0x90, + 0x7, 0x70, 0xa, 0x42, 0xc0, 0xd, 0x10, 0x0, + 0x7, 0x70, 0xa, 0x42, 0xc1, 0x1e, 0x21, 0x10, + 0x7, 0xed, 0xdf, 0x42, 0xfd, 0xdd, 0xdd, 0xd2, + 0x7, 0x80, 0x0, 0x2, 0xc0, 0x0, 0x0, 0x0, + + /* U+8AB2 "課" */ + 0x0, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x40, 0x9, 0xee, 0xef, 0xee, 0xe0, + 0x0, 0x3, 0x60, 0x9, 0x60, 0x3b, 0x1, 0xe0, + 0x1e, 0xee, 0xee, 0xa9, 0x95, 0x7d, 0x56, 0xe0, + 0x0, 0x0, 0x0, 0x9, 0xb8, 0xae, 0x89, 0xe0, + 0x5, 0xcc, 0xcc, 0x29, 0x60, 0x3b, 0x1, 0xe0, + 0x0, 0x0, 0x0, 0x9, 0xca, 0xbe, 0xab, 0xe0, + 0x5, 0xbb, 0xbb, 0x22, 0x33, 0x7d, 0x33, 0x30, + 0x1, 0x22, 0x22, 0x12, 0x22, 0x6d, 0x22, 0x21, + 0x1, 0x22, 0x22, 0x5f, 0xff, 0xff, 0xff, 0xf6, + 0x7, 0xec, 0xce, 0x40, 0x5, 0xff, 0xb0, 0x0, + 0x7, 0x70, 0xa, 0x40, 0x3e, 0x7c, 0x99, 0x0, + 0x7, 0x70, 0xa, 0x46, 0xe5, 0x4c, 0xc, 0xa0, + 0x7, 0xed, 0xdf, 0xce, 0x30, 0x4c, 0x0, 0xb8, + 0x7, 0x80, 0x0, 0x11, 0x0, 0x4c, 0x0, 0x0, + + /* U+8ABF "調" */ + 0x0, 0x44, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xd0, 0x0, 0xff, 0xff, 0xff, 0xfa, 0x0, + 0xb, 0x20, 0xc, 0x0, 0x20, 0x3, 0xa3, 0xbb, + 0xbb, 0xb1, 0xc0, 0xb, 0x10, 0x3a, 0x1, 0x11, + 0x11, 0xc, 0x5b, 0xec, 0xa3, 0xa0, 0x9c, 0xcc, + 0x60, 0xc0, 0xb, 0x10, 0x3a, 0x0, 0x0, 0x0, + 0xc, 0x46, 0xd7, 0x64, 0xa0, 0x8b, 0xbb, 0x60, + 0xb4, 0x66, 0x66, 0x4a, 0x1, 0x22, 0x21, 0x2a, + 0x0, 0x0, 0x3, 0xa0, 0x12, 0x22, 0x13, 0x96, + 0xff, 0xfa, 0x3a, 0xa, 0xcc, 0xd9, 0x48, 0x66, + 0x2, 0xa3, 0xa0, 0xa2, 0x4, 0x97, 0x66, 0x71, + 0x4a, 0x3a, 0xa, 0x20, 0x49, 0xc1, 0x6c, 0x99, + 0x63, 0xa0, 0xae, 0xde, 0xcc, 0x2, 0x20, 0x0, + 0x4a, 0xa, 0x30, 0xa, 0x40, 0x0, 0x2, 0xde, + 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + + /* U+8AC7 "談" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x86, 0x0, 0x0, 0x2, 0xd0, 0x1, 0x0, + 0x0, 0x1d, 0x0, 0x7, 0x73, 0xc0, 0xe, 0x20, + 0x4a, 0xaa, 0xaa, 0x2d, 0x15, 0xa0, 0x97, 0x0, + 0x12, 0x22, 0x22, 0x34, 0x9, 0xe5, 0x70, 0x0, + 0xa, 0xcc, 0xc6, 0x0, 0x4d, 0x2c, 0xb1, 0x0, + 0x0, 0x0, 0x0, 0x2a, 0xe2, 0x0, 0x7e, 0x50, + 0x9, 0xbb, 0xb6, 0x26, 0x3, 0xc0, 0x3, 0x80, + 0x2, 0x22, 0x21, 0x2, 0x34, 0xa0, 0x4, 0x20, + 0x2, 0x22, 0x21, 0x9, 0x56, 0xa0, 0xe, 0x30, + 0xc, 0xcc, 0xda, 0x1e, 0x9, 0xe0, 0x88, 0x0, + 0xc, 0x10, 0x3a, 0x87, 0xe, 0xe8, 0xb0, 0x0, + 0xc, 0x10, 0x3a, 0x0, 0xad, 0x2e, 0x40, 0x0, + 0xc, 0xdd, 0xea, 0x3b, 0xf3, 0x5, 0xf9, 0x30, + 0xc, 0x10, 0x2, 0xfb, 0x20, 0x0, 0x3c, 0xf1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8ACB "請" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1c, 0x0, 0x1, 0x11, 0x3d, 0x11, 0x10, + 0x0, 0x9, 0x70, 0xa, 0xcc, 0xcf, 0xcc, 0xc4, + 0x19, 0x99, 0x99, 0x52, 0x55, 0x7e, 0x55, 0x50, + 0x2, 0x22, 0x22, 0x12, 0x55, 0x7e, 0x55, 0x50, + 0x5, 0xcc, 0xcc, 0x3b, 0xbb, 0xcf, 0xbb, 0xb8, + 0x0, 0x0, 0x0, 0x2, 0x22, 0x22, 0x22, 0x21, + 0x5, 0xbb, 0xbb, 0x0, 0xdd, 0xdd, 0xdd, 0xa0, + 0x1, 0x22, 0x22, 0x0, 0xf0, 0x0, 0x3, 0xb0, + 0x1, 0x22, 0x22, 0x0, 0xf7, 0x77, 0x79, 0xb0, + 0x7, 0xdc, 0xcf, 0x20, 0xf6, 0x66, 0x69, 0xb0, + 0x7, 0x60, 0xc, 0x20, 0xf7, 0x77, 0x79, 0xb0, + 0x7, 0x60, 0xc, 0x20, 0xf2, 0x22, 0x26, 0xb0, + 0x7, 0xed, 0xdf, 0x20, 0xf0, 0x0, 0x4, 0xb0, + 0x6, 0x60, 0x0, 0x0, 0xf0, 0x0, 0xde, 0x80, + + /* U+8AD6 "論" */ + 0x0, 0x53, 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, + 0x0, 0x4d, 0x0, 0x0, 0x3, 0xf6, 0x0, 0x0, + 0x0, 0x9, 0x10, 0x0, 0x2e, 0x7e, 0x40, 0x0, + 0x1e, 0xee, 0xea, 0x3, 0xe6, 0x3, 0xe4, 0x0, + 0x0, 0x0, 0x0, 0x6f, 0xa3, 0x33, 0x7f, 0x91, + 0x6, 0xcc, 0xca, 0xe5, 0xbb, 0xbb, 0xb7, 0xc7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xbb, 0xb3, 0x5c, 0xcc, 0xcc, 0xcc, 0xa0, + 0x1, 0x22, 0x20, 0x79, 0x2d, 0x29, 0x63, 0xd0, + 0x3, 0x55, 0x52, 0x78, 0xc, 0x8, 0x41, 0xd0, + 0x9, 0xdb, 0xd6, 0x79, 0x2d, 0x29, 0x63, 0xd0, + 0x9, 0x40, 0x76, 0x7e, 0xbf, 0xbe, 0xdc, 0xd0, + 0x9, 0x40, 0x76, 0x78, 0xc, 0x8, 0x41, 0xd0, + 0x9, 0xed, 0xe6, 0x78, 0xc, 0x8, 0x42, 0xd0, + 0x9, 0x40, 0x0, 0x78, 0xc, 0x8, 0x5d, 0x80, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8AF8 "諸" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x77, 0x0, 0x0, 0x7, 0x70, 0x1, 0x20, + 0x0, 0xb, 0x0, 0x7, 0x7b, 0xb7, 0x4b, 0x60, + 0x6e, 0xee, 0xee, 0x14, 0x4a, 0xa4, 0x7b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7, 0x71, 0xd2, 0x0, + 0x5, 0x66, 0x63, 0x12, 0x29, 0x9b, 0x92, 0x20, + 0x6, 0x77, 0x74, 0xad, 0xdd, 0xfd, 0xdd, 0xd0, + 0x6, 0x77, 0x74, 0x0, 0x2c, 0x70, 0x0, 0x0, + 0x2, 0x22, 0x21, 0x18, 0xff, 0xee, 0xee, 0x20, + 0x6, 0x77, 0x76, 0xe9, 0xf0, 0x0, 0xe, 0x20, + 0xc, 0x98, 0xaa, 0x10, 0xf0, 0x0, 0xe, 0x20, + 0xc, 0x10, 0x3a, 0x0, 0xfe, 0xdd, 0xdf, 0x20, + 0xc, 0x10, 0x3a, 0x0, 0xf0, 0x0, 0xe, 0x20, + 0xc, 0x87, 0x9a, 0x0, 0xf3, 0x22, 0x2e, 0x20, + 0xa, 0x87, 0x74, 0x0, 0xfb, 0xbb, 0xbe, 0x20, + + /* U+8B02 "謂" */ + 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0x40, 0xc, 0xed, 0xdf, 0xdd, 0xf5, + 0x0, 0x4, 0x70, 0xc, 0x40, 0x2c, 0x0, 0xa5, + 0x1d, 0xdd, 0xdd, 0x8c, 0xdb, 0xcf, 0xbb, 0xe5, + 0x0, 0x0, 0x0, 0xc, 0x40, 0x3c, 0x0, 0xa5, + 0x5, 0xcc, 0xcc, 0x1c, 0xa8, 0x9e, 0x88, 0xd5, + 0x0, 0x0, 0x0, 0x3, 0x44, 0x44, 0x44, 0x41, + 0x5, 0xbb, 0xbb, 0x11, 0xbb, 0xbb, 0xbb, 0x80, + 0x1, 0x22, 0x22, 0x1, 0xe2, 0x22, 0x26, 0xc0, + 0x1, 0x22, 0x22, 0x1, 0xe1, 0x11, 0x15, 0xc0, + 0x7, 0xec, 0xcf, 0x21, 0xfb, 0xbb, 0xbc, 0xc0, + 0x7, 0x70, 0xc, 0x21, 0xe2, 0x22, 0x25, 0xc0, + 0x7, 0x70, 0xc, 0x21, 0xf8, 0x88, 0x8a, 0xc0, + 0x7, 0xed, 0xdf, 0x21, 0xe0, 0x0, 0x4, 0xc0, + 0x7, 0x80, 0x0, 0x1, 0xe0, 0x0, 0xdd, 0x70, + + /* U+8B1B "講" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6a, 0x0, 0x0, 0x95, 0x2, 0xb0, 0x0, + 0x0, 0xb, 0x40, 0x7c, 0xee, 0xcd, 0xfc, 0x90, + 0x3b, 0xbb, 0xbb, 0x3, 0xb7, 0x36, 0xc3, 0x10, + 0x1, 0x11, 0x11, 0x17, 0xca, 0x79, 0xd7, 0x30, + 0x9, 0xcc, 0xc6, 0x66, 0xc9, 0x68, 0xd6, 0x60, + 0x0, 0x0, 0x0, 0x66, 0x66, 0xf7, 0x66, 0x60, + 0x8, 0xbb, 0xb5, 0x8, 0x99, 0xf9, 0x99, 0x10, + 0x1, 0x22, 0x21, 0xf, 0x43, 0xf4, 0x3e, 0x20, + 0x1, 0x22, 0x21, 0xf, 0x11, 0xe2, 0x1e, 0x20, + 0xb, 0xcc, 0xd9, 0xf, 0xbb, 0xfb, 0xbf, 0x20, + 0xb, 0x10, 0x39, 0x3f, 0x43, 0xf4, 0x3e, 0x50, + 0xb, 0x10, 0x39, 0x7f, 0x87, 0x77, 0x7e, 0x90, + 0xb, 0xed, 0xe9, 0xf, 0x0, 0x0, 0xe, 0x20, + 0xb, 0x20, 0x0, 0xf, 0x0, 0xa, 0xdd, 0x0, + + /* U+8B1D "謝" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x94, 0x0, 0x9, 0x60, 0x0, 0xd, 0x10, + 0x0, 0x38, 0x0, 0xdf, 0xdc, 0x0, 0xd, 0x10, + 0x1e, 0xee, 0xe4, 0xd0, 0x1e, 0x0, 0xe, 0x20, + 0x0, 0x0, 0x0, 0xe8, 0x8e, 0xae, 0xef, 0xf1, + 0x6, 0xcc, 0xa0, 0xe4, 0x5e, 0x0, 0xd, 0x10, + 0x0, 0x0, 0x0, 0xe3, 0x3e, 0x52, 0xd, 0x10, + 0x5, 0xaa, 0x80, 0xf9, 0xae, 0x68, 0xd, 0x10, + 0x1, 0x33, 0x21, 0xd0, 0x1e, 0x1d, 0xd, 0x10, + 0x0, 0x11, 0x1b, 0xff, 0xfe, 0xc, 0x1d, 0x10, + 0x8, 0xdc, 0xd1, 0x14, 0xee, 0x6, 0x2d, 0x10, + 0x8, 0x40, 0xd0, 0x4d, 0x3e, 0x0, 0xd, 0x10, + 0x8, 0x40, 0xd9, 0xc2, 0xe, 0x0, 0xd, 0x10, + 0x8, 0xdc, 0xd3, 0x0, 0xe, 0x0, 0xe, 0x10, + 0x8, 0x51, 0x10, 0xb, 0xe9, 0xa, 0xfb, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8B58 "識" */ + 0x0, 0xa3, 0x0, 0x8, 0x40, 0xe, 0x13, 0x0, + 0x0, 0x28, 0x4, 0xde, 0xfd, 0x6d, 0x2d, 0x10, + 0x2e, 0xee, 0xe4, 0x72, 0x19, 0xd, 0x17, 0x90, + 0x0, 0x0, 0x0, 0x75, 0x48, 0xc, 0x21, 0x20, + 0x7, 0xcc, 0xb7, 0xde, 0xdd, 0xbf, 0xcb, 0xb1, + 0x0, 0x0, 0x1, 0x33, 0x33, 0x3c, 0x63, 0x30, + 0x6, 0xaa, 0x90, 0xdc, 0xcd, 0x19, 0x52, 0x80, + 0x1, 0x33, 0x20, 0xd0, 0xc, 0x18, 0x68, 0x70, + 0x0, 0x11, 0x10, 0xe0, 0xd, 0x16, 0x8e, 0x10, + 0x9, 0xdc, 0xe0, 0xeb, 0xbf, 0x14, 0xe9, 0x0, + 0x9, 0x30, 0xd0, 0xd0, 0xc, 0x14, 0xf1, 0x0, + 0x9, 0x30, 0xd0, 0xeb, 0xbf, 0x4e, 0xf1, 0x82, + 0x9, 0xdc, 0xe0, 0xd0, 0x8, 0xe4, 0x8a, 0xd0, + 0x9, 0x41, 0x10, 0x0, 0xa, 0x20, 0x1d, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8B70 "議" */ + 0x0, 0x11, 0x0, 0x0, 0x30, 0x0, 0x13, 0x0, + 0x0, 0x69, 0x0, 0x0, 0xd3, 0x0, 0x97, 0x0, + 0x0, 0x1d, 0x0, 0x5c, 0xee, 0xcc, 0xfc, 0xc0, + 0x1b, 0xbb, 0xb9, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0x1, 0x11, 0x11, 0xa, 0xbb, 0xfc, 0xbb, 0x70, + 0x6, 0xcc, 0xc6, 0x22, 0x22, 0xd5, 0x22, 0x20, + 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xf6, + 0x5, 0xaa, 0xa5, 0x24, 0x67, 0x35, 0x15, 0x0, + 0x1, 0x33, 0x31, 0x56, 0xc3, 0xa, 0x37, 0xd1, + 0x0, 0x11, 0x10, 0x22, 0xc5, 0x2a, 0x62, 0x61, + 0x9, 0xdc, 0xe7, 0xbb, 0xec, 0xbd, 0xdb, 0xb5, + 0x9, 0x30, 0x57, 0x1, 0xc7, 0x74, 0x98, 0x60, + 0x9, 0x30, 0x57, 0xca, 0xd8, 0x30, 0xea, 0x0, + 0x9, 0xdc, 0xd7, 0x0, 0xb3, 0x3b, 0xd7, 0x28, + 0x7, 0x41, 0x10, 0x4c, 0xd2, 0xa2, 0xc, 0xd4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8B77 "護" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x78, 0x0, 0xef, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0x1e, 0x20, 0x56, 0xca, 0x66, 0xe6, 0x50, + 0x25, 0x56, 0x55, 0x4, 0xa5, 0x51, 0x90, 0x0, + 0x35, 0x55, 0x55, 0xe, 0x96, 0x9c, 0x66, 0x20, + 0xb, 0xcc, 0xc6, 0x9f, 0x33, 0x3f, 0x33, 0x0, + 0x0, 0x0, 0x1, 0xae, 0x88, 0x8f, 0x88, 0x0, + 0xa, 0xbb, 0xb6, 0xe, 0xaa, 0xaf, 0xaa, 0x0, + 0x2, 0x22, 0x21, 0xe, 0x0, 0xe, 0x0, 0x0, + 0x4, 0x55, 0x53, 0xe, 0xee, 0xef, 0xee, 0x90, + 0xd, 0xcb, 0xd8, 0x1a, 0x22, 0x22, 0x21, 0x0, + 0xd, 0x0, 0x68, 0x6c, 0xfa, 0xaa, 0xdc, 0x0, + 0xd, 0x0, 0x68, 0x0, 0x7b, 0x58, 0xc1, 0x0, + 0xd, 0xdd, 0xe8, 0x3, 0x7c, 0xef, 0xa4, 0x0, + 0xd, 0x10, 0x0, 0xee, 0xa5, 0x1, 0x8e, 0xd0, + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, + + /* U+8B8A "變" */ + 0x0, 0x5, 0x0, 0x3, 0x20, 0x0, 0x23, 0x0, + 0x0, 0x77, 0x0, 0x25, 0xb2, 0x10, 0xa3, 0x0, + 0x2, 0xb0, 0xc5, 0x88, 0x88, 0x75, 0x82, 0xc0, + 0xd, 0xcd, 0x80, 0x9a, 0xaa, 0x6f, 0xce, 0x30, + 0x1, 0x7a, 0x81, 0x33, 0x33, 0x10, 0xa5, 0x90, + 0x7, 0xe7, 0xc7, 0x67, 0x77, 0x3a, 0xc9, 0xe3, + 0x7, 0x63, 0x27, 0x8a, 0xaa, 0x37, 0x41, 0x54, + 0xa, 0x37, 0x93, 0xb0, 0x6, 0x5c, 0x47, 0xa0, + 0xc, 0x1a, 0x57, 0xc8, 0x8b, 0x6b, 0x29, 0x65, + 0x6, 0x3, 0x1c, 0x32, 0x22, 0x13, 0x2, 0x0, + 0x0, 0x2, 0xdf, 0xdd, 0xdd, 0xdd, 0xdd, 0xd1, + 0x2, 0x9d, 0xba, 0x10, 0x0, 0x3d, 0x50, 0x0, + 0xb, 0x70, 0x5, 0xd9, 0x5a, 0xc3, 0x0, 0x0, + 0x0, 0x0, 0x36, 0xaf, 0xcf, 0xa6, 0x20, 0x0, + 0x1c, 0xed, 0xb8, 0x30, 0x0, 0x48, 0xbe, 0xe5, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8B93 "讓" */ + 0x0, 0x11, 0x0, 0x0, 0x0, 0x60, 0x0, 0x0, + 0x0, 0x5a, 0x0, 0x23, 0x33, 0xe6, 0x33, 0x31, + 0x0, 0xd, 0x0, 0x79, 0x99, 0x99, 0x99, 0x93, + 0x1b, 0xbb, 0xba, 0x1b, 0xbb, 0x39, 0xbb, 0x90, + 0x2, 0x22, 0x22, 0x2a, 0x9, 0x4d, 0x0, 0xd0, + 0x6, 0xcc, 0xc5, 0x2c, 0xcd, 0x3b, 0xda, 0xb0, + 0x0, 0x0, 0x0, 0x24, 0xa9, 0x45, 0xf4, 0x40, + 0x5, 0xaa, 0xa4, 0x37, 0xca, 0x78, 0xf7, 0x71, + 0x1, 0x33, 0x31, 0x29, 0xdc, 0x9a, 0xf9, 0x80, + 0x3, 0x66, 0x62, 0x3, 0xa8, 0x34, 0xf3, 0x20, + 0x8, 0xa7, 0xb6, 0xdd, 0xee, 0xdd, 0xfd, 0xd7, + 0x8, 0x40, 0x66, 0x1, 0x9a, 0x2d, 0x12, 0x90, + 0x8, 0x40, 0x67, 0xbb, 0xe0, 0x7, 0xdb, 0x20, + 0x8, 0xdc, 0xe6, 0x10, 0xf5, 0x95, 0x8d, 0x50, + 0x8, 0x51, 0x10, 0x4, 0xd9, 0x51, 0x5, 0xd7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8BA1 "计" */ + 0x0, 0x72, 0x0, 0x0, 0x2, 0xf0, 0x0, 0x0, + 0x0, 0x4e, 0x40, 0x0, 0x2, 0xf0, 0x0, 0x0, + 0x0, 0x3, 0xe1, 0x0, 0x2, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0xf0, 0x0, 0x0, + 0x25, 0x55, 0x10, 0x0, 0x3, 0xf0, 0x0, 0x0, + 0x4a, 0xaf, 0x33, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0xd, 0x30, 0x0, 0x3, 0xf0, 0x0, 0x0, + 0x0, 0xd, 0x30, 0x0, 0x2, 0xf0, 0x0, 0x0, + 0x0, 0xd, 0x30, 0x0, 0x2, 0xf0, 0x0, 0x0, + 0x0, 0xd, 0x30, 0x0, 0x2, 0xf0, 0x0, 0x0, + 0x0, 0xd, 0x37, 0x50, 0x2, 0xf0, 0x0, 0x0, + 0x0, 0xe, 0xdb, 0x10, 0x2, 0xf0, 0x0, 0x0, + 0x0, 0x6f, 0x60, 0x0, 0x2, 0xf0, 0x0, 0x0, + 0x0, 0x23, 0x0, 0x0, 0x2, 0xf0, 0x0, 0x0, + + /* U+8BDE "诞" */ + 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x3, 0x60, + 0x2, 0xe3, 0xc, 0xff, 0xe2, 0x6a, 0xec, 0x70, + 0x0, 0x5e, 0x10, 0x7, 0x85, 0x85, 0xf0, 0x0, + 0x0, 0xa, 0x50, 0xd, 0x20, 0x0, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0x5b, 0x0, 0x30, 0xf0, 0x0, + 0x7, 0x76, 0x0, 0xd3, 0x2, 0xb0, 0xf0, 0x0, + 0xa, 0xbd, 0x7, 0xfe, 0xe3, 0xb0, 0xff, 0xf4, + 0x0, 0x1d, 0x0, 0x0, 0xd2, 0xb0, 0xf0, 0x0, + 0x0, 0x1d, 0x4, 0x43, 0xb2, 0xb0, 0xf0, 0x0, + 0x0, 0x1d, 0x3, 0xb6, 0x82, 0xb0, 0xf0, 0x0, + 0x0, 0x1d, 0x0, 0xdd, 0x32, 0xb0, 0xf0, 0x0, + 0x0, 0x1d, 0x5a, 0x6e, 0x2, 0xfd, 0xfd, 0xd6, + 0x0, 0x2f, 0xe3, 0xae, 0x90, 0x11, 0x11, 0x10, + 0x0, 0x7d, 0x24, 0xd1, 0xcc, 0x41, 0x0, 0x0, + 0x0, 0x71, 0x2e, 0x30, 0x6, 0xbe, 0xff, 0xf8, + 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8C50 "豐" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x2, 0xc3, 0x7a, 0x47, 0x74, 0xa7, 0x3c, 0x20, + 0x2, 0xc3, 0x7a, 0x57, 0x75, 0xb7, 0x3c, 0x20, + 0x2, 0xc4, 0xbd, 0x87, 0x78, 0xdb, 0x5c, 0x20, + 0x2, 0xc5, 0x9b, 0x78, 0x87, 0xb9, 0x5c, 0x20, + 0x2, 0xc2, 0x59, 0x28, 0x82, 0x95, 0x2c, 0x20, + 0x2, 0xdc, 0xdd, 0xcd, 0xdc, 0xdd, 0xcd, 0x20, + 0x4, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x40, + 0x5, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x60, + 0x0, 0xb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb1, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0xf, 0xba, 0xaa, 0xaa, 0xaa, 0xf2, 0x0, + 0x0, 0x0, 0x6b, 0x0, 0x0, 0x98, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x10, 0x1, 0xe1, 0x0, 0x0, + 0x1d, 0xdd, 0xdf, 0xdd, 0xdd, 0xfd, 0xdd, 0xd1, + + /* U+8C61 "象" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xee, 0xee, 0xf9, 0x0, 0x0, 0x0, 0x4, + 0xd1, 0x0, 0x1f, 0x40, 0x0, 0x0, 0x7, 0xf4, + 0x0, 0x8, 0xc0, 0x0, 0x0, 0x8, 0xff, 0xdd, + 0xdd, 0xfd, 0xdd, 0xde, 0x0, 0x24, 0xc0, 0x0, + 0x6b, 0x0, 0x1, 0xe0, 0x0, 0x3f, 0xbb, 0xbf, + 0xcb, 0xbb, 0xbe, 0x0, 0x0, 0x26, 0xef, 0x82, + 0x22, 0x24, 0x70, 0x2, 0x7c, 0xc3, 0x1d, 0x80, + 0x6, 0xe7, 0x0, 0x48, 0x20, 0x3b, 0x9d, 0x8d, + 0xe1, 0x0, 0x0, 0x27, 0xcb, 0x21, 0xbf, 0x2c, + 0x60, 0x0, 0xa, 0x71, 0x6, 0xd6, 0xd4, 0x2e, + 0x20, 0x0, 0x2, 0x8d, 0x91, 0xb, 0x50, 0x6e, + 0x30, 0x2d, 0xd7, 0x10, 0x3, 0xf2, 0x0, 0x6f, + 0x40, 0x20, 0x0, 0xdf, 0xe6, 0x0, 0x0, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8CA0 "負" */ + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xed, 0xdd, 0xdf, 0x40, 0x0, 0x0, 0x5, + 0xe6, 0x0, 0x8, 0x90, 0x0, 0x0, 0x8, 0xff, + 0xee, 0xee, 0xfe, 0xee, 0xe2, 0x0, 0x95, 0xe0, + 0x0, 0x0, 0x0, 0xe, 0x20, 0x0, 0x2e, 0x0, + 0x0, 0x0, 0x0, 0xe2, 0x0, 0x2, 0xfc, 0xcc, + 0xcc, 0xcc, 0xcf, 0x20, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x2, 0xfd, 0xdd, 0xdd, + 0xdd, 0xdf, 0x20, 0x0, 0x2e, 0x0, 0x0, 0x0, + 0x0, 0xe2, 0x0, 0x2, 0xe2, 0x22, 0x22, 0x22, + 0x2e, 0x20, 0x0, 0x1b, 0xbb, 0xbb, 0xbb, 0xbb, + 0xb2, 0x0, 0x0, 0x29, 0xd2, 0x0, 0x4d, 0x72, + 0x0, 0x7, 0xce, 0x70, 0x0, 0x0, 0x17, 0xeb, + 0x30, 0x34, 0x0, 0x0, 0x0, 0x0, 0x0, 0x51, + + /* U+8CA1 "財" */ + 0xd, 0xee, 0xee, 0xe0, 0x0, 0x0, 0xf0, 0x0, + 0xd, 0x30, 0x1, 0xe0, 0x0, 0x0, 0xf0, 0x0, + 0xd, 0x30, 0x1, 0xe0, 0x0, 0x0, 0xf0, 0x0, + 0xd, 0xed, 0xdd, 0xe7, 0xcc, 0xcd, 0xfd, 0xc1, + 0xd, 0x30, 0x1, 0xe1, 0x22, 0x2b, 0xf3, 0x20, + 0xd, 0x30, 0x1, 0xe0, 0x0, 0x2e, 0xf0, 0x0, + 0xd, 0xed, 0xdd, 0xe0, 0x0, 0xa7, 0xf0, 0x0, + 0xd, 0x30, 0x1, 0xe0, 0x2, 0xd0, 0xf0, 0x0, + 0xd, 0x30, 0x1, 0xe0, 0xc, 0x50, 0xf0, 0x0, + 0xd, 0xee, 0xee, 0xe0, 0xaa, 0x0, 0xf0, 0x0, + 0x0, 0x72, 0x6, 0x9, 0xc0, 0x0, 0xf0, 0x0, + 0x3, 0xe0, 0xb, 0x72, 0x0, 0x0, 0xf0, 0x0, + 0x1d, 0x60, 0x1, 0xe2, 0x0, 0x1, 0xf0, 0x0, + 0x59, 0x0, 0x0, 0x20, 0x2, 0xff, 0xa0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8CA7 "貧" */ + 0x0, 0x0, 0x2, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x5e, 0x20, 0x3, 0xd3, 0x0, 0x0, + 0x0, 0x2a, 0xd2, 0x0, 0x0, 0x2e, 0x91, 0x0, + 0x9, 0xe8, 0xee, 0xff, 0xee, 0xef, 0xbe, 0x90, + 0x1, 0x0, 0x3, 0xd2, 0x0, 0xf, 0x11, 0x40, + 0x0, 0x36, 0xbc, 0x20, 0x9c, 0xd9, 0x0, 0x0, + 0x6, 0xbf, 0xc9, 0x99, 0x99, 0x99, 0x91, 0x0, + 0x0, 0x1f, 0x22, 0x22, 0x22, 0x22, 0xe2, 0x0, + 0x0, 0x1f, 0xbb, 0xbb, 0xbb, 0xbb, 0xf2, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x1f, 0xbb, 0xbb, 0xbb, 0xbb, 0xf2, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x1e, 0xbb, 0xbb, 0xbb, 0xbb, 0xe2, 0x0, + 0x0, 0x1, 0x6a, 0x20, 0x4, 0xb6, 0x20, 0x0, + 0x8, 0xdc, 0x71, 0x0, 0x0, 0x26, 0xcd, 0x60, + 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + + /* U+8CA9 "販" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x47, 0x50, + 0xd, 0xee, 0xee, 0x9, 0xce, 0xed, 0xa7, 0x40, + 0xd, 0x10, 0x1e, 0xd, 0x40, 0x0, 0x0, 0x0, + 0xd, 0x10, 0x1e, 0xd, 0x20, 0x0, 0x0, 0x0, + 0xd, 0xed, 0xee, 0xd, 0x20, 0x0, 0x0, 0x0, + 0xd, 0x10, 0x1e, 0xd, 0xba, 0xaa, 0xaa, 0x40, + 0xd, 0x10, 0x1e, 0xd, 0xd9, 0x66, 0x6d, 0x40, + 0xd, 0xdd, 0xde, 0xe, 0x79, 0x0, 0xe, 0x0, + 0xd, 0x10, 0x1e, 0xf, 0x2e, 0x0, 0x5b, 0x0, + 0xd, 0x10, 0x1e, 0xf, 0x8, 0x70, 0xc5, 0x0, + 0xd, 0xee, 0xee, 0x2e, 0x1, 0xe7, 0xc0, 0x0, + 0x0, 0x50, 0x30, 0x5b, 0x0, 0x6f, 0x30, 0x0, + 0x7, 0xb0, 0xa6, 0xa6, 0x1, 0xde, 0xa0, 0x0, + 0x1e, 0x20, 0x1e, 0xe1, 0x3d, 0x80, 0xbb, 0x20, + 0x37, 0x0, 0x9, 0x62, 0xe6, 0x0, 0x8, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8CAC "責" */ + 0x2, 0xdd, 0xdd, 0xde, 0xed, 0xdd, 0xdd, 0x30, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x4c, 0xcc, 0xce, 0xec, 0xcc, 0xc7, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0xc, 0xcc, 0xcc, 0xcd, 0xdc, 0xcc, 0xcc, 0xc1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0xbb, 0xbb, 0xbb, 0xbb, 0xe4, 0x0, + 0x0, 0x1f, 0x44, 0x44, 0x44, 0x44, 0xd4, 0x0, + 0x0, 0x1f, 0x55, 0x55, 0x55, 0x55, 0xd4, 0x0, + 0x0, 0x1f, 0xbb, 0xbb, 0xbb, 0xbb, 0xe4, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xc4, 0x0, + 0x0, 0x1f, 0xbb, 0xbb, 0xbb, 0xbb, 0xe4, 0x0, + 0x0, 0x2, 0x7b, 0x20, 0x2, 0xb7, 0x30, 0x0, + 0x9, 0xdb, 0x60, 0x0, 0x0, 0x5, 0xbd, 0x70, + 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + + /* U+8CB7 "買" */ + 0x1, 0xfd, 0xde, 0xfd, 0xdf, 0xdd, 0xdf, 0x10, + 0x1, 0xe0, 0x2, 0xc0, 0xc, 0x10, 0xe, 0x10, + 0x1, 0xe0, 0x2, 0xc0, 0xc, 0x10, 0xe, 0x10, + 0x1, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0xcc, 0xcc, 0xcc, 0xcc, 0xf2, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x1f, 0xbb, 0xbb, 0xbb, 0xbb, 0xf2, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x1f, 0xcb, 0xbb, 0xbb, 0xbb, 0xf2, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x1c, 0xcc, 0xcc, 0xcc, 0xcc, 0xc2, 0x0, + 0x0, 0x2, 0x7d, 0x50, 0x4, 0xd8, 0x30, 0x0, + 0x8, 0xdc, 0x71, 0x0, 0x0, 0x5, 0xbd, 0x70, + 0x3, 0x20, 0x0, 0x0, 0x0, 0x0, 0x2, 0x20, + + /* U+8CB8 "貸" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xc0, 0x2d, 0x6, 0xb7, 0x10, 0x0, + 0x9, 0xd1, 0x12, 0xe6, 0x45, 0xb8, 0x60, 0x7e, + 0xbb, 0x7c, 0xba, 0xfa, 0x76, 0x53, 0x18, 0x15, + 0xb0, 0x0, 0x5, 0xe6, 0x10, 0xb0, 0x0, 0x49, + 0x0, 0x0, 0x2, 0x9e, 0xe8, 0x0, 0xb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xb1, 0x0, 0x0, 0xf0, 0x0, + 0x0, 0x0, 0xe, 0x20, 0x0, 0xf, 0xbb, 0xbb, + 0xbb, 0xbb, 0xf2, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0xf, 0xbb, 0xbb, 0xbb, + 0xbb, 0xf2, 0x0, 0x0, 0xf0, 0x0, 0x0, 0x0, + 0xe, 0x20, 0x0, 0xb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xb1, 0x0, 0x0, 0x39, 0xc2, 0x0, 0x3d, 0x83, + 0x0, 0x9, 0xeb, 0x50, 0x0, 0x0, 0x5, 0xbd, + 0x50, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + + /* U+8CBB "費" */ + 0x3, 0xbb, 0xbc, 0xfb, 0xbf, 0xcb, 0xcc, 0x0, + 0x0, 0x0, 0x1e, 0x0, 0xe1, 0x3, 0xc0, 0x0, + 0x7c, 0xbc, 0xfb, 0xbf, 0xcb, 0xcc, 0x0, 0xb, + 0x30, 0x4c, 0x0, 0xe1, 0x0, 0x0, 0x0, 0xac, + 0xdf, 0xdc, 0xcf, 0xcc, 0xcd, 0xb0, 0x0, 0x6e, + 0x90, 0x0, 0xe1, 0x7, 0xb8, 0xa, 0xef, 0xbb, + 0xbb, 0xbb, 0xbb, 0xf5, 0x0, 0x11, 0xf4, 0x44, + 0x44, 0x44, 0x4f, 0x20, 0x0, 0x1f, 0x55, 0x55, + 0x55, 0x55, 0xf2, 0x0, 0x1, 0xfb, 0xbb, 0xbb, + 0xbb, 0xbf, 0x20, 0x0, 0x1f, 0x0, 0x0, 0x0, + 0x0, 0xe2, 0x0, 0x1, 0xdb, 0xbb, 0xbb, 0xbc, + 0xbd, 0x20, 0x0, 0x3, 0x9d, 0x40, 0x5, 0xcb, + 0x61, 0x0, 0x9e, 0xa5, 0x0, 0x0, 0x0, 0x28, + 0xe7, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+8CBF "貿" */ + 0x0, 0x0, 0x25, 0x80, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xdb, 0x85, 0x1d, 0xdf, 0xed, 0xf8, 0x0, + 0xe1, 0x7, 0x0, 0x0, 0xe0, 0x9, 0x60, 0xe, + 0x10, 0x7b, 0x0, 0x6b, 0x0, 0xb5, 0x0, 0xf8, + 0xce, 0xd6, 0x5e, 0x34, 0x4e, 0x20, 0x3d, 0x83, + 0x2, 0xab, 0x30, 0x8a, 0x50, 0x0, 0x3b, 0xbb, + 0xbc, 0xbb, 0xbb, 0xb2, 0x0, 0x4, 0xc0, 0x0, + 0x0, 0x0, 0xd, 0x30, 0x0, 0x4f, 0xbb, 0xbb, + 0xbb, 0xbb, 0xf3, 0x0, 0x4, 0xc0, 0x0, 0x0, + 0x0, 0xd, 0x30, 0x0, 0x4f, 0xbb, 0xbb, 0xbb, + 0xbb, 0xf3, 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, + 0xd, 0x30, 0x0, 0x3b, 0xbb, 0xbb, 0xbb, 0xbb, + 0xb2, 0x0, 0x0, 0x39, 0xb1, 0x0, 0x1c, 0x94, + 0x0, 0xb, 0xea, 0x50, 0x0, 0x0, 0x3, 0x9e, + 0x70, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8CC3 "賃" */ + 0x0, 0x0, 0x85, 0x0, 0x12, 0x35, 0x86, 0x0, + 0x0, 0x8, 0xd0, 0xbb, 0xad, 0xb6, 0x42, 0x0, + 0x0, 0x9f, 0x30, 0x0, 0x8, 0x70, 0x0, 0x0, + 0x2d, 0xce, 0x3b, 0xdd, 0xde, 0xed, 0xdd, 0xd1, + 0x17, 0xc, 0x30, 0x0, 0x8, 0x70, 0x0, 0x0, + 0x0, 0xc, 0x31, 0xbb, 0xbe, 0xdb, 0xbb, 0x30, + 0x0, 0x4, 0x10, 0x11, 0x11, 0x11, 0x11, 0x0, + 0x0, 0xf, 0xbb, 0xbb, 0xbb, 0xbb, 0xf4, 0x0, + 0x0, 0xf, 0x44, 0x44, 0x44, 0x44, 0xd4, 0x0, + 0x0, 0xf, 0x55, 0x55, 0x55, 0x55, 0xd4, 0x0, + 0x0, 0xf, 0xbb, 0xbb, 0xbb, 0xbb, 0xe4, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xc4, 0x0, + 0x0, 0xd, 0xbb, 0xbb, 0xbb, 0xbb, 0xd3, 0x0, + 0x0, 0x2, 0x7b, 0x20, 0x3, 0xb7, 0x30, 0x0, + 0x9, 0xdb, 0x60, 0x0, 0x0, 0x15, 0xbd, 0x70, + 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + + /* U+8CC7 "資" */ + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x2a, 0x50, 0x0, 0x98, 0x0, 0x0, 0x0, 0x0, + 0x39, 0xe2, 0x5e, 0xdd, 0xdd, 0xdf, 0x70, 0x0, + 0x1, 0x3d, 0x10, 0xc8, 0x4, 0xc0, 0x0, 0x38, + 0xc4, 0x3, 0xb7, 0x99, 0x31, 0x0, 0xeb, 0x61, + 0x3d, 0xb4, 0x0, 0x4c, 0xb4, 0x0, 0x1b, 0xbc, + 0xcb, 0xbb, 0xbb, 0xb4, 0x10, 0x1, 0xf0, 0x0, + 0x0, 0x0, 0xe, 0x20, 0x0, 0x1f, 0xbb, 0xbb, + 0xbb, 0xbb, 0xf2, 0x0, 0x1, 0xf0, 0x0, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x1f, 0xbb, 0xbb, 0xbb, + 0xbb, 0xf2, 0x0, 0x1, 0xf0, 0x0, 0x0, 0x0, + 0xe, 0x20, 0x0, 0x1b, 0xbc, 0xbb, 0xbb, 0xcb, + 0xb1, 0x0, 0x0, 0x4a, 0xc2, 0x0, 0x2d, 0xa5, + 0x0, 0x9, 0xea, 0x40, 0x0, 0x0, 0x3, 0x9e, + 0x60, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+8CEA "質" */ + 0x0, 0x1, 0x25, 0x81, 0x0, 0x13, 0x58, 0x20, + 0x0, 0xeb, 0x97, 0x40, 0x2e, 0xa9, 0x73, 0x0, + 0x0, 0xf0, 0x0, 0x0, 0x3b, 0x0, 0x0, 0x0, + 0x1, 0xfd, 0xdf, 0xda, 0x5f, 0xde, 0xfd, 0xd5, + 0x5, 0xb0, 0xf, 0x0, 0xb6, 0x2, 0xd0, 0x0, + 0xd, 0x30, 0xc, 0x3, 0xc0, 0x2, 0xc0, 0x0, + 0x1, 0xd, 0xcb, 0xbb, 0xcb, 0xbb, 0xd3, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xd3, 0x0, + 0x0, 0xf, 0xbb, 0xbb, 0xbb, 0xbb, 0xf3, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xd3, 0x0, + 0x0, 0xf, 0xbb, 0xbb, 0xbb, 0xbb, 0xf3, 0x0, + 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0xd3, 0x0, + 0x0, 0xc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc2, 0x0, + 0x0, 0x4, 0xac, 0x10, 0x0, 0xcb, 0x61, 0x0, + 0xa, 0xea, 0x40, 0x0, 0x0, 0x2, 0x7d, 0xb0, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + + /* U+8CFD "賽" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, + 0xd, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe0, + 0xd, 0x20, 0x6, 0x0, 0x0, 0x60, 0x1, 0xe0, + 0x5, 0x5a, 0xaf, 0xba, 0xab, 0xfa, 0xa5, 0x60, + 0x0, 0x3, 0x3f, 0x53, 0x34, 0xf3, 0x30, 0x0, + 0x0, 0x17, 0x7f, 0x87, 0x78, 0xf7, 0x71, 0x0, + 0xc, 0xcc, 0xcf, 0xcc, 0xcc, 0xfc, 0xcc, 0xc1, + 0x0, 0x3, 0xd7, 0x22, 0x22, 0x5e, 0x50, 0x0, + 0x2, 0x9f, 0xd9, 0x99, 0x99, 0x9d, 0xfb, 0x50, + 0x2d, 0x67, 0xd9, 0x99, 0x99, 0x9d, 0x74, 0xb2, + 0x0, 0x6, 0xa2, 0x22, 0x22, 0x2a, 0x70, 0x0, + 0x0, 0x6, 0xc7, 0x77, 0x77, 0x7c, 0x70, 0x0, + 0x0, 0x6, 0xda, 0xaa, 0xaa, 0xad, 0x70, 0x0, + 0x0, 0x3, 0x8d, 0x40, 0x6, 0xda, 0x50, 0x0, + 0x9, 0xd9, 0x50, 0x0, 0x0, 0x3, 0x8d, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8D39 "费" */ + 0x3, 0xdd, 0xdd, 0xfd, 0xdf, 0xdd, 0xdf, 0x0, + 0x0, 0x0, 0x1, 0xe0, 0xc, 0x30, 0xf, 0x0, + 0x0, 0x1, 0x13, 0xe1, 0x1d, 0x51, 0x2f, 0x0, + 0x0, 0xac, 0xab, 0xfa, 0xae, 0xca, 0xaa, 0x0, + 0x0, 0xd2, 0x5, 0xb0, 0xc, 0x40, 0x0, 0x0, + 0x0, 0xbb, 0xcf, 0xcb, 0xbf, 0xcb, 0xbc, 0xd0, + 0x0, 0x3, 0xd9, 0x0, 0xc, 0x30, 0x37, 0xa0, + 0x6, 0xce, 0x62, 0x22, 0x2a, 0x42, 0x99, 0x20, + 0x4, 0x2f, 0xcb, 0xbb, 0xbb, 0xbb, 0xf1, 0x0, + 0x0, 0xf, 0x0, 0x3, 0x40, 0x0, 0xf1, 0x0, + 0x0, 0xf, 0x0, 0xb, 0x30, 0x0, 0xf1, 0x0, + 0x0, 0xf, 0x0, 0x5c, 0x34, 0x0, 0xf1, 0x0, + 0x0, 0x4, 0x28, 0xd1, 0x4a, 0xea, 0x81, 0x0, + 0x18, 0xad, 0xd7, 0x0, 0x0, 0x4, 0xae, 0x90, + 0x6, 0x41, 0x0, 0x0, 0x0, 0x0, 0x1, 0x30, + + /* U+8D64 "赤" */ + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x13, 0x33, 0x3a, 0xa3, 0x33, 0x31, 0x0, + 0x0, 0x4c, 0xcc, 0xce, 0xec, 0xcc, 0xc4, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, + 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x0, 0x0, 0x4, 0xd0, 0x8, 0xa0, 0x0, 0x0, + 0x0, 0xa, 0x14, 0xd0, 0x7, 0xa0, 0xa1, 0x0, + 0x0, 0x7b, 0x5, 0xc0, 0x7, 0xa0, 0x9a, 0x0, + 0x2, 0xe2, 0x9, 0x90, 0x7, 0xa0, 0xd, 0x50, + 0x1d, 0x50, 0xe, 0x40, 0x7, 0xa0, 0x5, 0xe0, + 0x4, 0x0, 0x9b, 0x0, 0x7, 0xa0, 0x0, 0x71, + 0x0, 0xa, 0xe2, 0x0, 0x19, 0xa0, 0x0, 0x0, + 0x0, 0x3c, 0x20, 0xa, 0xfe, 0x50, 0x0, 0x0, + + /* U+8D70 "走" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x24, 0x44, 0x4b, 0xa4, 0x44, 0x43, 0x0, + 0x0, 0x6b, 0xbb, 0xbe, 0xdb, 0xbb, 0xb8, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0xe, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe0, + 0x0, 0x1, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x90, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x60, 0x9, 0xeb, 0xbb, 0xba, 0x0, + 0x0, 0xf, 0x70, 0x9, 0xa3, 0x33, 0x33, 0x0, + 0x0, 0x4d, 0xd1, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0xc5, 0x4d, 0x39, 0x80, 0x0, 0x0, 0x0, + 0x7, 0xd0, 0x5, 0xee, 0xa4, 0x21, 0x0, 0x0, + 0x2e, 0x10, 0x0, 0x17, 0xbe, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8D77 "起" */ + 0x0, 0x0, 0xf0, 0x0, 0x4f, 0xff, 0xff, 0xb0, + 0x9, 0xcc, 0xfc, 0xc8, 0x0, 0x0, 0x4, 0xb0, + 0x2, 0x23, 0xf2, 0x22, 0x0, 0x0, 0x4, 0xb0, + 0x0, 0x0, 0xf0, 0x0, 0x0, 0x0, 0x4, 0xb0, + 0x6, 0x66, 0xf6, 0x66, 0x0, 0x0, 0x4, 0xb0, + 0x1a, 0xaa, 0xeb, 0xaa, 0x2f, 0xff, 0xfe, 0xa0, + 0x1, 0x40, 0xb3, 0x0, 0x1f, 0x0, 0x0, 0x0, + 0x5, 0xb0, 0xb3, 0x0, 0x1f, 0x0, 0x0, 0x0, + 0x6, 0xa0, 0xbf, 0xfe, 0x1f, 0x0, 0x0, 0x22, + 0x7, 0xc0, 0xb3, 0x0, 0x1f, 0x0, 0x0, 0x69, + 0x8, 0xf2, 0xb3, 0x0, 0x1f, 0x20, 0x0, 0x97, + 0xb, 0xbc, 0xc3, 0x0, 0xa, 0xee, 0xee, 0xc1, + 0xe, 0x28, 0xf8, 0x31, 0x0, 0x0, 0x0, 0x0, + 0x4d, 0x0, 0x39, 0xde, 0xff, 0xff, 0xff, 0xf8, + 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8D85 "超" */ + 0x0, 0x2, 0xd0, 0x2, 0xee, 0xff, 0xee, 0xf1, + 0x2, 0x35, 0xd3, 0x31, 0x0, 0xd3, 0x0, 0xf0, + 0x8, 0xbc, 0xfb, 0xb4, 0x1, 0xf0, 0x0, 0xf0, + 0x0, 0x2, 0xd0, 0x0, 0x7, 0xa0, 0x2, 0xe0, + 0x2, 0x25, 0xd2, 0x22, 0x2e, 0x21, 0x27, 0xc0, + 0xc, 0xcc, 0xfc, 0xcc, 0xd4, 0x4, 0xcb, 0x30, + 0x0, 0x0, 0xf0, 0x0, 0x56, 0x66, 0x66, 0x40, + 0x5, 0xa0, 0xf0, 0x0, 0x9b, 0x66, 0x69, 0xc0, + 0x6, 0x90, 0xfe, 0xe8, 0x97, 0x0, 0x4, 0xc0, + 0x7, 0xb0, 0xf0, 0x0, 0x97, 0x0, 0x4, 0xc0, + 0x8, 0xf3, 0xf0, 0x0, 0x9d, 0xbb, 0xbc, 0xc0, + 0xb, 0x6d, 0xf0, 0x0, 0x13, 0x33, 0x33, 0x20, + 0xe, 0x16, 0xf9, 0x41, 0x0, 0x0, 0x0, 0x0, + 0x4c, 0x0, 0x28, 0xce, 0xff, 0xff, 0xff, 0xf8, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8D8A "越" */ + 0x0, 0x0, 0xf0, 0x0, 0x0, 0xd, 0x3a, 0x10, + 0x3, 0x66, 0xf6, 0x63, 0x0, 0xd, 0x14, 0x90, + 0x2, 0x55, 0xf5, 0x52, 0xac, 0xcf, 0xdc, 0xc4, + 0x0, 0x0, 0xf0, 0x0, 0xc3, 0x1b, 0x51, 0x10, + 0x0, 0x0, 0xf0, 0x0, 0xc2, 0xa, 0x40, 0x40, + 0x1e, 0xee, 0xff, 0xeb, 0xc2, 0x8, 0x64, 0xb0, + 0x0, 0x0, 0xb3, 0x0, 0xc2, 0x7, 0x8b, 0x50, + 0x2, 0xc0, 0xb4, 0x0, 0xc2, 0x4, 0xcd, 0x0, + 0x3, 0xc0, 0xbf, 0xf8, 0xd7, 0xd2, 0xf5, 0x20, + 0x3, 0xe0, 0xb3, 0x3, 0xfa, 0x18, 0xf2, 0x75, + 0x5, 0xf7, 0xb3, 0x2, 0x40, 0x7d, 0x8a, 0x93, + 0x8, 0x7e, 0xe3, 0x0, 0x8, 0xd1, 0xa, 0xb0, + 0xc, 0x24, 0xeb, 0x52, 0x12, 0x0, 0x0, 0x0, + 0x2c, 0x0, 0x18, 0xce, 0xff, 0xff, 0xff, 0xf4, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8DA3 "趣" */ + 0x0, 0x7, 0x80, 0x6f, 0xfe, 0xf9, 0x0, 0x0, + 0x7, 0xad, 0xda, 0x5b, 0x20, 0xd6, 0xaa, 0xa0, + 0x2, 0x49, 0xa4, 0x2b, 0x41, 0xe2, 0x34, 0xe0, + 0x0, 0x7, 0x80, 0xb, 0xdc, 0xe6, 0x2, 0xc0, + 0xb, 0xbd, 0xeb, 0x9b, 0x20, 0xd8, 0x75, 0x90, + 0x3, 0x35, 0xe3, 0x2b, 0x20, 0xd1, 0xe9, 0x60, + 0x0, 0x11, 0xd0, 0xb, 0xee, 0xe0, 0x9f, 0x30, + 0x4, 0xa1, 0xd2, 0x1b, 0x41, 0xe0, 0x2f, 0x0, + 0x5, 0xa1, 0xfd, 0x9b, 0x20, 0xe2, 0x6f, 0x50, + 0x5, 0xc2, 0xd0, 0xb, 0x9b, 0xf5, 0xd7, 0xc0, + 0x7, 0xf7, 0xd0, 0x99, 0x40, 0xd8, 0xa0, 0xc2, + 0xa, 0x6f, 0xd0, 0x0, 0x0, 0xd4, 0x10, 0x0, + 0xe, 0x5, 0xfd, 0x62, 0x10, 0x0, 0x0, 0x0, + 0x4a, 0x0, 0x28, 0xce, 0xff, 0xff, 0xff, 0xf4, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8DB3 "足" */ + 0x0, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x3e, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x3e, 0x0, + 0x0, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xd0, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xb0, 0x2, 0xfd, 0xdd, 0xdd, 0x50, + 0x0, 0xa, 0xc0, 0x2, 0xe2, 0x22, 0x22, 0x0, + 0x0, 0xe, 0xc5, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x89, 0x1e, 0x63, 0xe0, 0x0, 0x0, 0x0, + 0x3, 0xe2, 0x3, 0xde, 0xf3, 0x21, 0x0, 0x0, + 0xd, 0x40, 0x0, 0x6, 0xad, 0xef, 0xff, 0xf7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8DDF "跟" */ + 0xc, 0xfe, 0xef, 0x2e, 0xff, 0xff, 0xff, 0x10, + 0xc, 0x20, 0xd, 0x2e, 0x10, 0x0, 0xe, 0x10, + 0xc, 0x20, 0xd, 0x2e, 0x10, 0x0, 0xe, 0x10, + 0xc, 0x20, 0xd, 0x2e, 0xdd, 0xdd, 0xdf, 0x10, + 0xc, 0xee, 0xef, 0x2e, 0x31, 0x11, 0x1e, 0x10, + 0x0, 0xb, 0x30, 0xe, 0x10, 0x0, 0xe, 0x10, + 0x6, 0x1b, 0x30, 0xe, 0xdd, 0xdd, 0xdf, 0x10, + 0xc, 0x2b, 0xdc, 0x3e, 0x22, 0xd1, 0x11, 0x20, + 0xc, 0x2b, 0x52, 0xe, 0x10, 0xc3, 0x1b, 0xa0, + 0xc, 0x2b, 0x30, 0xe, 0x10, 0x6c, 0xd6, 0x0, + 0xc, 0x2b, 0x31, 0x1e, 0x10, 0xe, 0x60, 0x0, + 0xc, 0x6d, 0xee, 0x4e, 0x10, 0x14, 0xe3, 0x0, + 0x7f, 0xb7, 0x20, 0x1f, 0xad, 0xe1, 0x6f, 0x70, + 0x10, 0x0, 0x0, 0x5c, 0x72, 0x0, 0x3, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8DEF "路" */ + 0x0, 0x0, 0x0, 0x0, 0x7, 0x20, 0x0, 0x0, + 0xc, 0xff, 0xff, 0x80, 0x1f, 0x10, 0x0, 0x0, + 0xc, 0x30, 0x6, 0x80, 0x7f, 0xff, 0xfb, 0x0, + 0xc, 0x30, 0x6, 0x81, 0xe8, 0x0, 0xa7, 0x0, + 0xc, 0x30, 0x6, 0x8b, 0xad, 0x13, 0xe1, 0x0, + 0xc, 0xfe, 0xef, 0xdc, 0x5, 0xbc, 0x60, 0x0, + 0x0, 0x4, 0xb0, 0x0, 0x0, 0xdd, 0x0, 0x0, + 0x5, 0x14, 0xb0, 0x0, 0xb, 0xbb, 0xa0, 0x0, + 0xb, 0x24, 0xea, 0x75, 0xd7, 0x0, 0x8d, 0x60, + 0xb, 0x24, 0xc3, 0x9d, 0xeb, 0xbb, 0xbf, 0xc1, + 0xb, 0x24, 0xb0, 0x1, 0xf3, 0x33, 0x3f, 0x0, + 0xb, 0x24, 0xb0, 0x1, 0xe0, 0x0, 0xf, 0x0, + 0xb, 0x35, 0xda, 0xc1, 0xe0, 0x0, 0xf, 0x0, + 0x4e, 0xfe, 0xa6, 0x21, 0xe1, 0x11, 0x1f, 0x0, + 0x47, 0x20, 0x0, 0x1, 0xfd, 0xdd, 0xdf, 0x0, + + /* U+8EAB "身" */ + 0x0, 0x0, 0x0, 0x7, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xee, 0xff, 0xee, 0xee, 0x20, 0x0, 0x0, + 0xc4, 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, 0xc, + 0x62, 0x22, 0x22, 0x2e, 0x20, 0x0, 0x0, 0xcc, + 0xaa, 0xaa, 0xaa, 0xf2, 0x0, 0x0, 0xc, 0x30, + 0x0, 0x0, 0xe, 0x24, 0x30, 0x0, 0xce, 0xdd, + 0xdd, 0xdd, 0xf5, 0xd2, 0x0, 0xc, 0x30, 0x0, + 0x0, 0xe, 0xe2, 0x0, 0xbb, 0xfc, 0xbb, 0xbb, + 0xbb, 0xf3, 0x0, 0x3, 0x33, 0x33, 0x33, 0x6e, + 0xbf, 0x20, 0x0, 0x0, 0x0, 0x1, 0x9d, 0x40, + 0xe2, 0x0, 0x0, 0x0, 0x17, 0xe8, 0x0, 0xe, + 0x20, 0x0, 0x16, 0xbe, 0x82, 0x1, 0x1, 0xf1, + 0x0, 0x4f, 0xa4, 0x0, 0x1, 0xff, 0xea, 0x0, + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8ECA "車" */ + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x9, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0x90, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x6e, 0xee, 0xef, 0xfe, 0xee, 0xe7, 0x0, + 0x0, 0x69, 0x0, 0x9, 0x80, 0x0, 0x97, 0x0, + 0x0, 0x69, 0x0, 0x9, 0x80, 0x0, 0x87, 0x0, + 0x0, 0x6f, 0xdd, 0xdf, 0xfd, 0xdd, 0xf7, 0x0, + 0x0, 0x69, 0x0, 0x9, 0x80, 0x0, 0x87, 0x0, + 0x0, 0x6a, 0x22, 0x2a, 0x92, 0x22, 0xa7, 0x0, + 0x0, 0x5b, 0xbb, 0xbe, 0xdb, 0xbb, 0xb5, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + + /* U+8EDF "軟" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x8, 0x70, 0x0, 0x0, + 0x1d, 0xde, 0xfd, 0xda, 0xc, 0x40, 0x0, 0x0, + 0x1, 0x12, 0xd1, 0x11, 0xf, 0xba, 0xaa, 0xa1, + 0x6, 0xaa, 0xfa, 0xa3, 0x3c, 0x44, 0x45, 0xf0, + 0xa, 0x53, 0xd2, 0x95, 0x96, 0x25, 0x3, 0xc0, + 0xa, 0x20, 0xc0, 0x78, 0xe1, 0x5c, 0x6, 0x80, + 0xa, 0xdd, 0xfc, 0xe7, 0x50, 0x6c, 0x9, 0x40, + 0xa, 0x20, 0xc0, 0x75, 0x0, 0x8f, 0x0, 0x0, + 0xa, 0xdd, 0xfc, 0xe5, 0x0, 0xbf, 0x40, 0x0, + 0x0, 0x0, 0xd0, 0x0, 0x2, 0xf8, 0xa0, 0x0, + 0x3b, 0xbc, 0xfb, 0xbb, 0xa, 0xb0, 0xe1, 0x0, + 0x13, 0x34, 0xe3, 0x33, 0x5f, 0x20, 0x7c, 0x0, + 0x0, 0x0, 0xd0, 0x6, 0xf4, 0x0, 0xc, 0xa0, + 0x0, 0x0, 0xd0, 0x1c, 0x30, 0x0, 0x1, 0xb3, + + /* U+8EE2 "転" */ + 0x0, 0x0, 0xf0, 0x0, 0x2, 0x22, 0x22, 0x20, + 0xc, 0xdd, 0xfd, 0xdc, 0x2b, 0xbb, 0xbb, 0xa0, + 0x1, 0x11, 0xf1, 0x11, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xaa, 0xfa, 0xa5, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x72, 0xd2, 0x78, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x50, 0xd0, 0x58, 0x78, 0x88, 0x88, 0x84, + 0x7, 0xdc, 0xfc, 0xd8, 0x89, 0xbf, 0x99, 0x94, + 0x7, 0x50, 0xd0, 0x58, 0x0, 0xa8, 0x0, 0x0, + 0x7, 0xed, 0xfd, 0xe8, 0x1, 0xf2, 0x1, 0x0, + 0x0, 0x0, 0xf0, 0x0, 0x7, 0xa0, 0x3d, 0x0, + 0x1b, 0xbc, 0xfb, 0xba, 0xe, 0x20, 0xc, 0x50, + 0x3, 0x33, 0xf3, 0x33, 0x89, 0x0, 0x28, 0xc0, + 0x0, 0x0, 0xf0, 0x3, 0xfe, 0xff, 0xdb, 0xe2, + 0x0, 0x0, 0xf0, 0x0, 0x52, 0x0, 0x0, 0x86, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8EFD "軽" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xd0, 0x0, 0xff, 0xff, 0xff, 0xd0, + 0xd, 0xde, 0xfd, 0xd9, 0x1d, 0x0, 0x9, 0x70, + 0x1, 0x13, 0xe1, 0x11, 0xa, 0x70, 0x2f, 0x10, + 0x6, 0xaa, 0xfa, 0xa4, 0x1, 0xe4, 0xd6, 0x0, + 0xa, 0x53, 0xd2, 0x87, 0x0, 0x6f, 0xa0, 0x0, + 0xa, 0x20, 0xc0, 0x67, 0x3, 0xdd, 0xe5, 0x0, + 0xa, 0xdc, 0xfc, 0xea, 0xae, 0x60, 0x4d, 0xc5, + 0xa, 0x20, 0xc0, 0x69, 0x60, 0xe, 0x20, 0x53, + 0xa, 0xdd, 0xfc, 0xe7, 0x11, 0x1e, 0x31, 0x10, + 0x0, 0x1, 0xd0, 0x0, 0x8c, 0xcf, 0xcc, 0xb0, + 0x1c, 0xcc, 0xfc, 0xca, 0x0, 0xe, 0x20, 0x0, + 0x3, 0x34, 0xe3, 0x32, 0x0, 0xe, 0x20, 0x0, + 0x0, 0x1, 0xd0, 0x0, 0x0, 0xe, 0x20, 0x0, + 0x0, 0x1, 0xd0, 0xa, 0xff, 0xff, 0xff, 0xf9, + + /* U+8F03 "較" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x60, 0x0, 0x0, 0xb5, 0x0, 0x0, + 0x1e, 0xef, 0xfe, 0xd3, 0x44, 0x7a, 0x44, 0x40, + 0x0, 0x9, 0x70, 0x8, 0xaa, 0xaa, 0xaa, 0xa1, + 0x8, 0xad, 0xca, 0x70, 0xa, 0x10, 0x74, 0x0, + 0xc, 0x39, 0x65, 0xa0, 0x7a, 0x0, 0x4e, 0x10, + 0xc, 0x18, 0x53, 0xa2, 0xe2, 0x0, 0x8, 0xa0, + 0xc, 0xde, 0xdd, 0xab, 0x77, 0x0, 0x73, 0xd2, + 0xc, 0x18, 0x53, 0xa1, 0xd, 0x31, 0xf2, 0x0, + 0xc, 0xde, 0xdd, 0xa0, 0x6, 0xb8, 0xc0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x0, 0xef, 0x40, 0x0, + 0x13, 0x3b, 0x83, 0x30, 0x0, 0xae, 0x0, 0x0, + 0x3b, 0xbe, 0xdb, 0xb0, 0x8, 0xeb, 0xc0, 0x0, + 0x0, 0x9, 0x60, 0x2, 0xbc, 0x10, 0x9d, 0x50, + 0x0, 0x9, 0x60, 0x1d, 0x60, 0x0, 0x4, 0xc3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8F09 "載" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x69, 0x0, 0x8, 0x81, 0xa2, 0x0, + 0x5, 0xdd, 0xef, 0xdd, 0x78, 0x90, 0x4d, 0x30, + 0x0, 0x0, 0x69, 0x0, 0x7, 0x90, 0x3, 0x30, + 0x1e, 0xee, 0xff, 0xee, 0xef, 0xfe, 0xee, 0xe3, + 0x0, 0x0, 0x56, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x7, 0xbb, 0xde, 0xbb, 0x93, 0xc0, 0xa, 0x30, + 0x1, 0x11, 0x79, 0x11, 0x12, 0xe0, 0x1e, 0x0, + 0x4, 0xda, 0xcd, 0xac, 0x70, 0xf0, 0x89, 0x0, + 0x4, 0xb6, 0x9a, 0x6a, 0x70, 0xd5, 0xe2, 0x0, + 0x4, 0xa3, 0x89, 0x38, 0x70, 0x9e, 0x80, 0x0, + 0x4, 0xca, 0xcd, 0xab, 0x60, 0x8e, 0x0, 0x30, + 0x0, 0x0, 0x68, 0x0, 0x3, 0xff, 0x30, 0x95, + 0xc, 0xdd, 0xee, 0xdd, 0xed, 0x49, 0xc2, 0xc2, + 0x0, 0x0, 0x68, 0x3, 0xb1, 0x0, 0xae, 0xa0, + + /* U+8F15 "輕" */ + 0x0, 0x9, 0x40, 0xb, 0xff, 0xff, 0xff, 0xf5, + 0x2d, 0xdf, 0xed, 0xa0, 0x11, 0x2, 0x0, 0x30, + 0x1, 0x1a, 0x51, 0x10, 0xc4, 0x1e, 0x14, 0xb0, + 0x8, 0xad, 0xca, 0x64, 0xc0, 0x97, 0xd, 0x20, + 0xd, 0x29, 0x56, 0x9d, 0x32, 0xe0, 0x6a, 0x0, + 0xc, 0x8, 0x33, 0x99, 0x80, 0xc4, 0x2d, 0x10, + 0xd, 0xce, 0xdd, 0x90, 0xe2, 0x2d, 0x6, 0x90, + 0xc, 0x8, 0x33, 0x90, 0x68, 0xa, 0x40, 0xc1, + 0xd, 0xde, 0xdd, 0x92, 0x66, 0x56, 0x55, 0x60, + 0x0, 0x9, 0x40, 0x3, 0x77, 0xae, 0x77, 0x70, + 0x4c, 0xce, 0xdc, 0xb0, 0x0, 0x4c, 0x0, 0x0, + 0x13, 0x3b, 0x73, 0x30, 0x0, 0x4c, 0x0, 0x0, + 0x0, 0x9, 0x40, 0x0, 0x0, 0x4c, 0x0, 0x0, + 0x0, 0x9, 0x40, 0x6e, 0xee, 0xff, 0xee, 0xe8, + + /* U+8F2A "輪" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x70, 0x0, 0x0, 0x3d, 0x0, 0x0, + 0xd, 0xef, 0xfe, 0xd0, 0x1, 0xa6, 0xa0, 0x0, + 0x0, 0x7, 0x80, 0x0, 0x1b, 0x20, 0x89, 0x0, + 0x4, 0x7b, 0xb7, 0x43, 0xe5, 0x0, 0xa, 0xb0, + 0x9, 0x8a, 0xa9, 0xcf, 0xae, 0xee, 0xed, 0xaa, + 0x9, 0x35, 0x64, 0x92, 0x0, 0x0, 0x0, 0x1, + 0x9, 0xdd, 0xed, 0x95, 0xaa, 0xaa, 0xaa, 0xa0, + 0x9, 0x35, 0x64, 0x98, 0x85, 0xb3, 0xd3, 0xd0, + 0x9, 0xdd, 0xed, 0x98, 0x62, 0xa0, 0xc0, 0xd0, + 0x0, 0x7, 0x80, 0x8, 0xca, 0xd9, 0xe9, 0xe0, + 0x3, 0x39, 0x93, 0x38, 0xcb, 0xea, 0xea, 0xf0, + 0xb, 0xbd, 0xdb, 0xa8, 0x62, 0xa0, 0xc0, 0xd0, + 0x0, 0x7, 0x70, 0x8, 0x62, 0xa0, 0xc0, 0xd0, + 0x0, 0x7, 0x70, 0x8, 0x62, 0xa0, 0xca, 0xb0, + + /* U+8F38 "輸" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0x70, 0x0, 0x0, 0x6d, 0x0, 0x0, + 0xd, 0xef, 0xfe, 0xc0, 0x5, 0x84, 0xb0, 0x0, + 0x0, 0x8, 0x70, 0x1, 0xa9, 0x0, 0x4d, 0x40, + 0x2, 0x39, 0x93, 0x3e, 0x83, 0x33, 0x35, 0xc7, + 0x9, 0xac, 0xbb, 0x90, 0x7a, 0xaa, 0xaa, 0x0, + 0x9, 0x36, 0x54, 0x94, 0x88, 0x81, 0x0, 0xb1, + 0x9, 0xde, 0xdd, 0x98, 0x96, 0xd2, 0xc0, 0xc1, + 0x9, 0x36, 0x54, 0x98, 0x62, 0xb2, 0xc0, 0xc1, + 0x9, 0x8a, 0xa9, 0x98, 0xb9, 0xe2, 0xc0, 0xc1, + 0x3, 0x6b, 0xa6, 0x38, 0x50, 0xb2, 0xc0, 0xc1, + 0x4, 0x4a, 0x94, 0x48, 0xed, 0xf2, 0xc0, 0xc1, + 0xa, 0xad, 0xca, 0x98, 0x50, 0xb2, 0xb0, 0xc1, + 0x0, 0x7, 0x60, 0x8, 0x50, 0xb2, 0x0, 0xc1, + 0x0, 0x7, 0x60, 0x8, 0x58, 0xc0, 0x4d, 0xc0, + 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + + /* U+8F9B "辛" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x11, 0x11, 0x18, 0xb1, 0x11, 0x11, 0x0, + 0x0, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xdd, 0x10, + 0x0, 0x0, 0xb3, 0x0, 0x0, 0x3d, 0x0, 0x0, + 0x0, 0x0, 0x7b, 0x0, 0x0, 0x98, 0x0, 0x0, + 0x1, 0x11, 0x2e, 0x11, 0x11, 0xf2, 0x11, 0x10, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x4, 0xdd, 0xdd, 0xde, 0xed, 0xdd, 0xdd, 0x60, + 0x0, 0x22, 0x22, 0x2a, 0x92, 0x22, 0x22, 0x10, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + + /* U+8F9E "辞" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x14, 0x8c, 0x90, 0x0, 0x7a, 0x0, 0x0, + 0x2e, 0xde, 0xb3, 0x1, 0x33, 0x3e, 0x43, 0x30, + 0x0, 0x8, 0x70, 0x6, 0xcc, 0xcc, 0xcc, 0xc2, + 0x0, 0x8, 0x70, 0x0, 0x59, 0x0, 0xe, 0x20, + 0x3b, 0xbd, 0xdb, 0xb0, 0xe, 0x0, 0x5c, 0x0, + 0x13, 0x3a, 0x93, 0x31, 0xa, 0x30, 0xb6, 0x0, + 0x0, 0x8, 0x70, 0xe, 0xff, 0xff, 0xff, 0xf8, + 0x0, 0x19, 0x81, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0xb, 0xdc, 0xcd, 0x90, 0x0, 0x2e, 0x0, 0x0, + 0xb, 0x30, 0x5, 0x9a, 0xee, 0xff, 0xee, 0xe4, + 0xb, 0x30, 0x5, 0x90, 0x11, 0x3e, 0x11, 0x10, + 0xb, 0x30, 0x5, 0x90, 0x0, 0x2e, 0x0, 0x0, + 0xb, 0xff, 0xff, 0x90, 0x0, 0x2e, 0x0, 0x0, + 0xb, 0x30, 0x3, 0x50, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, + + /* U+8FA6 "辦" */ + 0x0, 0x74, 0x0, 0xe, 0x0, 0x0, 0xb2, 0x0, + 0x2, 0x5d, 0x21, 0xe, 0x0, 0x13, 0x8b, 0x31, + 0x9, 0x99, 0xa6, 0xd, 0x0, 0x39, 0x98, 0xb4, + 0x6, 0x60, 0xd1, 0xef, 0xee, 0xa, 0x20, 0xd0, + 0x3, 0xa1, 0xc0, 0x1c, 0xe, 0x6, 0x61, 0xb0, + 0x1, 0x84, 0x70, 0x1b, 0xe, 0x3, 0x65, 0x70, + 0x1e, 0xef, 0xea, 0x2a, 0xe, 0x6e, 0xef, 0xe9, + 0x0, 0x2d, 0x0, 0x48, 0xe, 0x0, 0x4b, 0x0, + 0x1, 0x3d, 0x10, 0x76, 0xe, 0x0, 0x4b, 0x0, + 0xb, 0xdf, 0xc6, 0x93, 0xe, 0x1e, 0xef, 0xe7, + 0x0, 0x4a, 0x0, 0xd0, 0xd, 0x0, 0x4b, 0x0, + 0x0, 0x86, 0x2, 0xb0, 0x1c, 0x0, 0x4b, 0x0, + 0x0, 0xd1, 0xa, 0x40, 0x4b, 0x0, 0x4b, 0x0, + 0x9, 0x50, 0x1b, 0xb, 0xe5, 0x0, 0x4b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8FB2 "農" */ + 0x0, 0x11, 0x17, 0xb1, 0x1c, 0x51, 0x11, 0x0, + 0x0, 0xd9, 0x7b, 0xd7, 0x7e, 0x97, 0xb9, 0x0, + 0x0, 0xdb, 0xac, 0xea, 0xae, 0xba, 0xc9, 0x0, + 0x0, 0xd3, 0x17, 0xb1, 0x1c, 0x51, 0x79, 0x0, + 0x0, 0xdb, 0xad, 0xea, 0xae, 0xca, 0xc9, 0x0, + 0x0, 0x12, 0x22, 0x22, 0x22, 0x22, 0x21, 0x0, + 0x0, 0xfd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0x70, + 0x0, 0xf0, 0x44, 0x44, 0x44, 0x44, 0x40, 0x0, + 0x0, 0xf0, 0x66, 0x66, 0x66, 0x66, 0x60, 0x0, + 0x2, 0xfb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xa0, + 0x3, 0xc1, 0x89, 0x13, 0xe4, 0x12, 0x99, 0x10, + 0x8, 0x80, 0x79, 0x0, 0x5e, 0x9c, 0x50, 0x0, + 0xe, 0x30, 0xab, 0x6a, 0xb3, 0xdc, 0x63, 0x0, + 0x4a, 0x1, 0xeb, 0x73, 0x0, 0x4, 0x9d, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8FBA "辺" */ + 0xa, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xd8, 0x8, 0xff, 0xff, 0xff, 0xff, 0x30, + 0x0, 0x1d, 0x50, 0x0, 0xb5, 0x0, 0xd, 0x30, + 0x0, 0x1, 0x0, 0x0, 0xd3, 0x0, 0xd, 0x30, + 0x0, 0x0, 0x0, 0x0, 0xe1, 0x0, 0xe, 0x20, + 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0xf, 0x10, + 0x3f, 0xff, 0x10, 0x5, 0xb0, 0x0, 0xf, 0x10, + 0x0, 0xe, 0x10, 0xc, 0x60, 0x0, 0x1f, 0x0, + 0x0, 0xe, 0x10, 0x4e, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0xe, 0x12, 0xe5, 0x0, 0x0, 0x6c, 0x0, + 0x0, 0xe, 0x1a, 0x60, 0x1, 0xee, 0xf5, 0x0, + 0x0, 0x7f, 0x70, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x9, 0xb2, 0xab, 0x40, 0x0, 0x0, 0x0, 0x10, + 0x2d, 0x0, 0x4, 0xae, 0xfe, 0xef, 0xff, 0xe2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8FBC "込" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xb0, 0x0, 0x6, 0x80, 0x0, 0x0, 0x0, + 0x0, 0xab, 0x0, 0x1, 0xc7, 0x0, 0x0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x1e, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2f, 0xe1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6a, 0x97, 0x0, 0x0, + 0x3f, 0xff, 0x10, 0x0, 0xd5, 0x3d, 0x0, 0x0, + 0x0, 0xe, 0x10, 0x4, 0xe0, 0xd, 0x50, 0x0, + 0x0, 0xe, 0x10, 0x1e, 0x60, 0x6, 0xd0, 0x0, + 0x0, 0xe, 0x11, 0xba, 0x0, 0x0, 0xbb, 0x10, + 0x0, 0xe, 0x1c, 0xb0, 0x0, 0x0, 0x1a, 0xe0, + 0x0, 0x9f, 0x92, 0x0, 0x0, 0x0, 0x0, 0x20, + 0xb, 0x90, 0x6d, 0x83, 0x21, 0x22, 0x34, 0x51, + 0x1a, 0x0, 0x1, 0x7b, 0xcd, 0xdc, 0xcb, 0xb1, + + /* U+8FCE "迎" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + 0x1, 0x0, 0x0, 0x5, 0xd8, 0x0, 0x0, 0x0, + 0x8, 0xc3, 0x0, 0xe9, 0x20, 0xfe, 0xef, 0xe0, + 0x0, 0x4e, 0x51, 0xe0, 0x0, 0xf0, 0x1, 0xe0, + 0x0, 0x1, 0x11, 0xe0, 0x0, 0xf0, 0x1, 0xe0, + 0x0, 0x0, 0x1, 0xe0, 0x0, 0xf0, 0x1, 0xe0, + 0x3f, 0xfe, 0x1, 0xe0, 0x0, 0xf0, 0x1, 0xe0, + 0x0, 0x2f, 0x1, 0xe0, 0x0, 0xf0, 0x1, 0xe0, + 0x0, 0x1f, 0x1, 0xe0, 0x1, 0xf0, 0x1, 0xe0, + 0x0, 0x1f, 0x2, 0xf7, 0xcb, 0xf0, 0x1, 0xe0, + 0x0, 0x1f, 0xa, 0xe8, 0x30, 0xf0, 0xbd, 0xc0, + 0x0, 0x1f, 0x2, 0x0, 0x0, 0xf0, 0x11, 0x0, + 0x0, 0x6f, 0x60, 0x0, 0x0, 0xf0, 0x0, 0x0, + 0x9, 0xc2, 0x9c, 0x50, 0x0, 0x10, 0x1, 0x21, + 0x2d, 0x10, 0x3, 0xae, 0xfe, 0xef, 0xff, 0xf5, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+8FD1 "近" */ + 0x2, 0x30, 0x0, 0x0, 0x12, 0x46, 0x8c, 0x70, + 0x3, 0xe3, 0x0, 0x1f, 0xdc, 0xa9, 0x64, 0x0, + 0x0, 0x5e, 0x20, 0x1f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x40, 0x1f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2f, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2f, 0xee, 0xee, 0xee, 0xe6, + 0x2d, 0xdd, 0x10, 0x4e, 0x22, 0x2e, 0x32, 0x20, + 0x3, 0x3f, 0x10, 0x5c, 0x0, 0xe, 0x10, 0x0, + 0x0, 0xe, 0x10, 0x79, 0x0, 0xe, 0x10, 0x0, + 0x0, 0xe, 0x10, 0xb7, 0x0, 0xe, 0x10, 0x0, + 0x0, 0xe, 0x11, 0xf2, 0x0, 0xe, 0x10, 0x0, + 0x0, 0xe, 0x19, 0xb0, 0x0, 0xe, 0x10, 0x0, + 0x1, 0xcc, 0xb4, 0x20, 0x0, 0x8, 0x10, 0x0, + 0xc, 0x80, 0x5e, 0x83, 0x21, 0x11, 0x23, 0x53, + 0x2c, 0x0, 0x1, 0x7c, 0xde, 0xfe, 0xed, 0xd4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8FD4 "返" */ + 0x4, 0x40, 0x0, 0x12, 0x45, 0x79, 0xbe, 0x40, + 0x3, 0xe3, 0x0, 0xed, 0xba, 0x87, 0x42, 0x0, + 0x0, 0x5e, 0x10, 0xe2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0x0, 0xe2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xef, 0xee, 0xee, 0xff, 0x0, + 0x2, 0x22, 0x0, 0xf1, 0x0, 0x0, 0x6a, 0x0, + 0x2d, 0xde, 0x1, 0xf2, 0xc2, 0x0, 0xe3, 0x0, + 0x0, 0x2e, 0x2, 0xd0, 0x5e, 0x4a, 0x90, 0x0, + 0x0, 0x2e, 0x6, 0xa0, 0x3, 0xfe, 0x0, 0x0, + 0x0, 0x2e, 0xb, 0x50, 0xa, 0xdd, 0x90, 0x0, + 0x0, 0x2e, 0x4e, 0x16, 0xda, 0x1, 0xca, 0x0, + 0x0, 0x5f, 0x34, 0x2b, 0x40, 0x0, 0xa, 0x10, + 0x9, 0xc8, 0xd8, 0x31, 0x0, 0x0, 0x12, 0x30, + 0x3c, 0x0, 0x16, 0xbe, 0xff, 0xff, 0xee, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8FEB "迫" */ + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + 0x5, 0x90, 0x0, 0x0, 0xa, 0x80, 0x0, 0x0, + 0x0, 0xc9, 0x0, 0x0, 0xf, 0x30, 0x0, 0x0, + 0x0, 0xd, 0x60, 0xef, 0xee, 0xee, 0xff, 0x0, + 0x0, 0x1, 0x0, 0xe2, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x1f, 0x0, + 0x4c, 0xcb, 0x0, 0xe2, 0x0, 0x0, 0x1f, 0x0, + 0x13, 0x5e, 0x0, 0xef, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x2e, 0x0, 0xe2, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0x2e, 0x0, 0xe2, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0x2e, 0x0, 0xe3, 0x0, 0x0, 0x1f, 0x0, + 0x0, 0x2e, 0x0, 0xef, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x9f, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xa4, 0xcb, 0x52, 0x10, 0x1, 0x12, 0x42, + 0x4c, 0x0, 0x5, 0xbe, 0xff, 0xff, 0xff, 0xe4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+8FFD "追" */ + 0x0, 0x0, 0x0, 0x0, 0x7, 0x50, 0x0, 0x0, + 0x7, 0x90, 0x0, 0x0, 0xe, 0x40, 0x0, 0x0, + 0x0, 0xb9, 0x0, 0xde, 0xef, 0xee, 0xed, 0x0, + 0x0, 0xb, 0x20, 0xe1, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x0, 0x0, 0xe1, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x0, 0x0, 0xec, 0xbb, 0xbb, 0xce, 0x0, + 0x4f, 0xff, 0x10, 0xe4, 0x33, 0x33, 0x32, 0x0, + 0x1, 0x1e, 0x10, 0xe1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x10, 0xee, 0xee, 0xee, 0xee, 0x60, + 0x0, 0xe, 0x10, 0xe1, 0x0, 0x0, 0x9, 0x70, + 0x0, 0xe, 0x10, 0xe1, 0x0, 0x0, 0x9, 0x70, + 0x0, 0xe, 0x10, 0xe2, 0x0, 0x0, 0x9, 0x70, + 0x0, 0xe, 0x10, 0xcd, 0xdd, 0xdd, 0xdd, 0x60, + 0x4, 0xd8, 0xb6, 0x20, 0x0, 0x0, 0x0, 0x22, + 0x1e, 0x30, 0x7, 0xcf, 0xfe, 0xef, 0xff, 0xf7, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+9000 "退" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xa0, 0x0, 0xee, 0xee, 0xee, 0xec, 0x0, + 0x0, 0xc7, 0x0, 0xe2, 0x0, 0x0, 0x3c, 0x0, + 0x0, 0x1e, 0x30, 0xe2, 0x0, 0x0, 0x3c, 0x0, + 0x0, 0x4, 0x10, 0xee, 0xdd, 0xdd, 0xec, 0x0, + 0x0, 0x0, 0x0, 0xe2, 0x0, 0x0, 0x3c, 0x0, + 0x2e, 0xee, 0x10, 0xed, 0xdd, 0xdd, 0xec, 0x0, + 0x1, 0x1e, 0x10, 0xe3, 0x13, 0x10, 0x17, 0xa0, + 0x0, 0xe, 0x10, 0xe2, 0xb, 0xa2, 0xab, 0x20, + 0x0, 0xe, 0x10, 0xe2, 0x0, 0x7f, 0xa0, 0x0, + 0x0, 0xe, 0x10, 0xf4, 0x6a, 0x4, 0xe6, 0x0, + 0x0, 0xe, 0x14, 0xfe, 0x94, 0x0, 0x2e, 0x60, + 0x0, 0x7f, 0x91, 0x30, 0x0, 0x0, 0x1, 0x10, + 0x9, 0xb0, 0x6c, 0x61, 0x0, 0x0, 0x2, 0x33, + 0x1c, 0x0, 0x1, 0x8d, 0xef, 0xff, 0xfe, 0xe5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9001 "送" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0x90, 0x0, 0x3d, 0x0, 0x0, 0xb7, 0x0, + 0x0, 0xc8, 0x0, 0xb, 0x60, 0x3, 0xe0, 0x0, + 0x0, 0x1e, 0x41, 0x25, 0x82, 0x2c, 0x72, 0x10, + 0x0, 0x2, 0x5, 0xdd, 0xde, 0xed, 0xdd, 0x80, + 0x0, 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, + 0x2d, 0xdc, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, + 0x0, 0x2e, 0xe, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x1e, 0x0, 0x0, 0xe, 0xb1, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x5d, 0xab, 0x0, 0x0, + 0x0, 0x1e, 0x0, 0x3, 0xe4, 0xa, 0xc0, 0x0, + 0x0, 0x1e, 0x0, 0x7e, 0x50, 0x0, 0xac, 0x0, + 0x0, 0x9f, 0x37, 0xb2, 0x0, 0x0, 0xa, 0x30, + 0xc, 0xa4, 0xda, 0x41, 0x0, 0x0, 0x1, 0x31, + 0x4c, 0x0, 0x6, 0xcf, 0xff, 0xff, 0xff, 0xf4, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+9003 "逃" */ + 0x3, 0x0, 0x0, 0x0, 0xe0, 0xd2, 0x0, 0x0, + 0x8, 0xc1, 0x8, 0x0, 0xe0, 0xd2, 0xa, 0x10, + 0x0, 0x6d, 0x1a, 0x70, 0xe0, 0xd2, 0x6b, 0x0, + 0x0, 0x4, 0x1, 0xe2, 0xe0, 0xd4, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0x41, 0xe0, 0xd4, 0x30, 0x0, + 0x2e, 0xee, 0x0, 0x4, 0xd0, 0xd8, 0x0, 0x0, + 0x1, 0x2f, 0x1, 0x9e, 0xd0, 0xda, 0xd2, 0x0, + 0x0, 0x1f, 0x3e, 0x86, 0xb0, 0xd2, 0x5e, 0x30, + 0x0, 0x1f, 0x13, 0xa, 0x70, 0xd2, 0x5, 0x20, + 0x0, 0x1f, 0x0, 0x3e, 0x10, 0xd2, 0x0, 0x70, + 0x0, 0x1f, 0x2, 0xd5, 0x0, 0xc6, 0x34, 0xd0, + 0x0, 0x1f, 0xb, 0x40, 0x0, 0x5b, 0xbb, 0x50, + 0x4, 0xc5, 0xa6, 0x10, 0x0, 0x0, 0x2, 0x41, + 0xe, 0x20, 0x6, 0xcf, 0xee, 0xff, 0xff, 0xf1, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+900F "透" */ + 0x3, 0x0, 0x0, 0x1, 0x23, 0x46, 0x8a, 0x10, + 0xa, 0xb0, 0x6, 0xcb, 0xbd, 0xc6, 0x42, 0x0, + 0x0, 0xba, 0x0, 0x0, 0x7, 0x80, 0x0, 0x0, + 0x0, 0x1e, 0x2a, 0xaa, 0xad, 0xda, 0xaa, 0xa2, + 0x0, 0x0, 0x3, 0x33, 0xaf, 0xfb, 0x33, 0x30, + 0x0, 0x0, 0x0, 0x8, 0xb8, 0x9a, 0x80, 0x0, + 0x0, 0x0, 0x2, 0xbb, 0x7, 0x80, 0xab, 0x30, + 0x1f, 0xff, 0x2e, 0x73, 0x26, 0x62, 0x14, 0xd2, + 0x0, 0x1f, 0x0, 0x68, 0xf9, 0x8e, 0x30, 0x0, + 0x0, 0x1f, 0x0, 0x1, 0xe0, 0xe, 0xdd, 0x80, + 0x0, 0x1f, 0x0, 0x8, 0x90, 0x0, 0x8, 0x70, + 0x0, 0x1f, 0x0, 0x8d, 0x10, 0x0, 0xc, 0x40, + 0x0, 0x2f, 0x4c, 0xa1, 0x0, 0x2d, 0xda, 0x0, + 0x5, 0xec, 0xeb, 0x40, 0x0, 0x0, 0x0, 0x10, + 0x1e, 0x50, 0x6, 0xcf, 0xfe, 0xff, 0xff, 0xf3, + 0x1, 0x0, 0x0, 0x0, 0x1, 0x11, 0x0, 0x0, + + /* U+9010 "逐" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x80, 0x1e, 0xee, 0xef, 0xfe, 0xee, 0xd0, + 0x1, 0xd7, 0x0, 0x0, 0x7d, 0x10, 0x0, 0x0, + 0x0, 0x2d, 0x10, 0xa, 0xf7, 0x0, 0x4, 0x20, + 0x0, 0x0, 0x7, 0xe8, 0x1d, 0x40, 0x4d, 0x20, + 0x0, 0x0, 0x2b, 0x20, 0x4d, 0xc5, 0xd1, 0x0, + 0x2e, 0xed, 0x0, 0x7, 0xc2, 0xcf, 0x10, 0x0, + 0x1, 0x3e, 0x5, 0xd9, 0x1, 0xef, 0xb0, 0x0, + 0x0, 0x1e, 0x5, 0x30, 0x2c, 0x8b, 0x9b, 0x0, + 0x0, 0x1e, 0x0, 0x5, 0xd3, 0x3b, 0xa, 0xa0, + 0x0, 0x1e, 0x4, 0xbb, 0x20, 0x3c, 0x0, 0x90, + 0x0, 0x1e, 0x2c, 0x40, 0x0, 0x99, 0x0, 0x0, + 0x0, 0x5f, 0x40, 0x0, 0xde, 0xd1, 0x0, 0x0, + 0x8, 0xd6, 0xca, 0x41, 0x22, 0x0, 0x1, 0x21, + 0x2d, 0x10, 0x4, 0xad, 0xef, 0xff, 0xee, 0xd2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9019 "這" */ + 0x0, 0x0, 0x0, 0x0, 0x19, 0x10, 0x0, 0x0, + 0x5, 0x40, 0x0, 0x0, 0xb, 0xa0, 0x0, 0x0, + 0x5, 0xf8, 0xb, 0xbb, 0xbc, 0xdb, 0xbb, 0xb1, + 0x0, 0x2e, 0x82, 0x22, 0x22, 0x22, 0x22, 0x20, + 0x0, 0x2, 0x10, 0x12, 0x22, 0x22, 0x22, 0x0, + 0x0, 0x0, 0x0, 0x3a, 0xaa, 0xaa, 0xa6, 0x0, + 0x19, 0x99, 0x0, 0x1, 0x11, 0x11, 0x10, 0x0, + 0x6, 0x7f, 0x0, 0x4b, 0xbb, 0xbb, 0xb8, 0x0, + 0x0, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0x8e, 0xdd, 0xdd, 0xdd, 0x0, + 0x0, 0x1f, 0x0, 0x87, 0x0, 0x0, 0x3d, 0x0, + 0x0, 0x1f, 0x0, 0x87, 0x0, 0x0, 0x3d, 0x0, + 0x0, 0x2f, 0x20, 0x7d, 0xdd, 0xdd, 0xdb, 0x0, + 0x6, 0xc5, 0xb9, 0x30, 0x0, 0x0, 0x0, 0x20, + 0x2e, 0x10, 0x5, 0xbf, 0xfe, 0xef, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+901A "通" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x50, 0x1, 0xdd, 0xdd, 0xdd, 0xef, 0x80, + 0x3, 0xe5, 0x0, 0x1, 0x50, 0x2, 0xca, 0x0, + 0x0, 0x4f, 0x30, 0x2, 0xbe, 0x9e, 0x60, 0x0, + 0x0, 0x6, 0x30, 0x22, 0x26, 0xde, 0x52, 0x20, + 0x0, 0x0, 0x1, 0xfa, 0xab, 0xfa, 0xab, 0xd0, + 0x15, 0x55, 0x1, 0xe0, 0x1, 0xd0, 0x2, 0xd0, + 0x2a, 0xaf, 0x1, 0xfd, 0xdd, 0xfd, 0xdd, 0xd0, + 0x0, 0xf, 0x1, 0xe0, 0x1, 0xd0, 0x2, 0xd0, + 0x0, 0xf, 0x1, 0xfd, 0xdd, 0xfd, 0xdd, 0xd0, + 0x0, 0xf, 0x1, 0xe0, 0x1, 0xd0, 0x2, 0xd0, + 0x0, 0xf, 0x1, 0xe0, 0x1, 0xd0, 0x3, 0xd0, + 0x0, 0x5f, 0x61, 0xd0, 0x1, 0xb0, 0xdd, 0x80, + 0x8, 0xb2, 0x9b, 0x50, 0x0, 0x0, 0x0, 0x12, + 0x2d, 0x10, 0x3, 0x9d, 0xee, 0xef, 0xff, 0xe7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+901F "速" */ + 0x4, 0x10, 0x0, 0x0, 0xd, 0x20, 0x0, 0x0, + 0x7, 0xe2, 0xd, 0xee, 0xef, 0xee, 0xee, 0xc0, + 0x0, 0x8e, 0x10, 0x0, 0xe, 0x20, 0x0, 0x0, + 0x0, 0x8, 0x0, 0x22, 0x2e, 0x42, 0x22, 0x0, + 0x0, 0x0, 0x1, 0xfb, 0xbf, 0xcb, 0xbf, 0x10, + 0x27, 0x77, 0x1, 0xd0, 0xd, 0x20, 0xe, 0x10, + 0x28, 0x8f, 0x11, 0xd1, 0x1e, 0x31, 0x1e, 0x10, + 0x0, 0xe, 0x11, 0xcc, 0xdf, 0xec, 0xcc, 0x10, + 0x0, 0xe, 0x10, 0x1, 0xcf, 0xe8, 0x0, 0x0, + 0x0, 0xe, 0x10, 0xc, 0x5d, 0x39, 0xc1, 0x0, + 0x0, 0xe, 0x14, 0xe7, 0xd, 0x20, 0x6d, 0x20, + 0x0, 0x1f, 0x3a, 0x50, 0xd, 0x20, 0x5, 0x20, + 0x6, 0xd8, 0xd8, 0x30, 0x5, 0x10, 0x0, 0x10, + 0x2e, 0x10, 0x6, 0xcf, 0xee, 0xee, 0xff, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+9020 "造" */ + 0x2, 0x10, 0x0, 0x2a, 0x3, 0xd0, 0x0, 0x0, + 0x6, 0xd2, 0x0, 0x9a, 0x25, 0xd2, 0x22, 0x10, + 0x0, 0x6d, 0x12, 0xec, 0xcd, 0xfc, 0xcc, 0x60, + 0x0, 0x5, 0x1c, 0x60, 0x3, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x5, 0x0, 0x3, 0xd0, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0xee, 0xee, 0xee, 0xee, 0xe2, + 0x2c, 0xcf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0xde, 0xee, 0xee, 0xed, 0x0, + 0x0, 0x1f, 0x0, 0xe1, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x1f, 0x0, 0xe1, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x1f, 0x0, 0xe3, 0x22, 0x22, 0x4e, 0x0, + 0x0, 0x1f, 0x0, 0xbc, 0xcc, 0xcc, 0xcb, 0x0, + 0x4, 0xd8, 0xc6, 0x20, 0x0, 0x0, 0x0, 0x21, + 0xe, 0x30, 0x7, 0xcf, 0xee, 0xef, 0xff, 0xf5, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+9023 "連" */ + 0x4, 0x80, 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, + 0x0, 0xc8, 0x1e, 0xee, 0xef, 0xee, 0xee, 0xc0, + 0x0, 0x1e, 0x40, 0x0, 0xe, 0x10, 0x0, 0x0, + 0x0, 0x1, 0x2, 0xdc, 0xcf, 0xdc, 0xdd, 0x0, + 0x1, 0x11, 0x2, 0xd0, 0xe, 0x10, 0xf, 0x0, + 0x3e, 0xee, 0x2, 0xfc, 0xcf, 0xdc, 0xdf, 0x0, + 0x0, 0x1e, 0x2, 0xd0, 0xe, 0x10, 0xf, 0x0, + 0x0, 0x1e, 0x2, 0xfb, 0xbf, 0xcb, 0xbf, 0x0, + 0x0, 0x1e, 0x0, 0x11, 0x1e, 0x31, 0x11, 0x0, + 0x0, 0x1e, 0x3a, 0xaa, 0xaf, 0xba, 0xaa, 0xa1, + 0x0, 0x1e, 0x13, 0x33, 0x3f, 0x53, 0x33, 0x30, + 0x1, 0xaf, 0x40, 0x0, 0xe, 0x10, 0x0, 0x0, + 0xc, 0x94, 0xda, 0x40, 0xa, 0x10, 0x0, 0x10, + 0x4c, 0x0, 0x17, 0xdf, 0xff, 0xff, 0xff, 0xf5, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+902E "逮" */ + 0x6, 0x50, 0x0, 0x0, 0xe, 0x10, 0x0, 0x0, + 0x2, 0xe4, 0x4, 0xdd, 0xdf, 0xdd, 0xde, 0x0, + 0x0, 0x3c, 0x0, 0x0, 0xe, 0x10, 0x1e, 0x0, + 0x0, 0x0, 0x5c, 0xcc, 0xcf, 0xdc, 0xdf, 0xc4, + 0x0, 0x0, 0x0, 0x0, 0xe, 0x10, 0x1e, 0x0, + 0x3f, 0xfe, 0x5, 0xdd, 0xdf, 0xdd, 0xde, 0x0, + 0x0, 0x2e, 0x3, 0x40, 0xe, 0x10, 0x7, 0x10, + 0x0, 0x1e, 0x1, 0xd3, 0xe, 0x20, 0x99, 0x0, + 0x0, 0x1e, 0x0, 0x29, 0x4f, 0xec, 0x80, 0x0, + 0x0, 0x1e, 0x0, 0x3b, 0xbf, 0x3a, 0xc2, 0x0, + 0x0, 0x1e, 0x1a, 0xd4, 0xe, 0x10, 0x5e, 0x60, + 0x0, 0x6f, 0x16, 0x1, 0x3f, 0x10, 0x1, 0x60, + 0xa, 0xa4, 0xc8, 0x33, 0xa7, 0x0, 0x1, 0x11, + 0x3c, 0x0, 0x6, 0xcf, 0xff, 0xff, 0xff, 0xf7, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+9031 "週" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x60, 0x1, 0xfe, 0xee, 0xee, 0xef, 0x10, + 0x2, 0xe5, 0x1, 0xd0, 0x4, 0x0, 0xe, 0x10, + 0x0, 0x4f, 0x21, 0xd0, 0xd, 0x20, 0xe, 0x10, + 0x0, 0x5, 0x11, 0xd5, 0xbf, 0xcb, 0x4e, 0x10, + 0x0, 0x0, 0x2, 0xd0, 0xc, 0x10, 0xe, 0x10, + 0x2, 0x22, 0x3, 0xc8, 0xcc, 0xcc, 0x6e, 0x10, + 0x1e, 0xff, 0x4, 0xb0, 0x22, 0x22, 0xe, 0x10, + 0x0, 0x1f, 0x5, 0xa3, 0xda, 0xaf, 0xe, 0x10, + 0x0, 0x1f, 0x8, 0x73, 0x70, 0xe, 0xe, 0x10, + 0x0, 0x1f, 0xd, 0x43, 0xb6, 0x6e, 0xe, 0x10, + 0x0, 0x1f, 0x4e, 0x1, 0x55, 0x55, 0xe, 0x10, + 0x0, 0x2f, 0x75, 0x0, 0x0, 0x9, 0xdd, 0x0, + 0x5, 0xe7, 0xca, 0x40, 0x0, 0x0, 0x0, 0x20, + 0x1e, 0x30, 0x5, 0xbe, 0xfe, 0xee, 0xff, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+9032 "進" */ + 0x0, 0x0, 0x0, 0x3, 0x0, 0x10, 0x0, 0x0, + 0xc, 0x90, 0x0, 0x1e, 0x4, 0xd0, 0x0, 0x0, + 0x1, 0xd9, 0x0, 0x89, 0x0, 0xc6, 0x0, 0x0, + 0x0, 0x1d, 0x20, 0xef, 0xee, 0xff, 0xee, 0xb0, + 0x0, 0x0, 0xa, 0xf1, 0x0, 0xd1, 0x0, 0x0, + 0x0, 0x0, 0x6d, 0xf1, 0x0, 0xd1, 0x0, 0x0, + 0x2, 0x22, 0x82, 0xee, 0xdd, 0xfd, 0xdd, 0x40, + 0xa, 0xbf, 0x0, 0xe1, 0x0, 0xd1, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0xec, 0xbb, 0xfb, 0xbb, 0x30, + 0x0, 0x1f, 0x0, 0xe4, 0x22, 0xe3, 0x22, 0x0, + 0x0, 0x1f, 0x0, 0xe1, 0x0, 0xd1, 0x0, 0x0, + 0x0, 0x1f, 0x0, 0xee, 0xee, 0xfe, 0xee, 0xe1, + 0x0, 0x5f, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xe7, 0xdc, 0x62, 0x0, 0x0, 0x12, 0x31, + 0x1e, 0x30, 0x5, 0xbe, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+9045 "遅" */ + 0x5, 0x30, 0x0, 0xfc, 0xcc, 0xcc, 0xcd, 0xe0, + 0x4, 0xd9, 0x0, 0xe0, 0x0, 0x0, 0x1, 0xe0, + 0x0, 0xb, 0x80, 0xfa, 0xaa, 0xaa, 0xab, 0xe0, + 0x0, 0x0, 0x0, 0xe2, 0xa3, 0x22, 0x99, 0x20, + 0x0, 0x0, 0x1, 0xd0, 0x67, 0x1, 0xe3, 0x0, + 0x1d, 0xdd, 0x2, 0xca, 0xdf, 0xde, 0xfd, 0xd0, + 0x2, 0x3f, 0x3, 0xb0, 0x0, 0xd2, 0x0, 0x0, + 0x0, 0x1f, 0x5, 0xa6, 0xdd, 0xfd, 0xdd, 0x70, + 0x0, 0x1f, 0x8, 0x70, 0x0, 0xd2, 0x0, 0x0, + 0x0, 0x1f, 0xd, 0x5d, 0xdd, 0xfd, 0xdd, 0xd3, + 0x0, 0x1f, 0x5d, 0x0, 0x0, 0xd2, 0x0, 0x0, + 0x0, 0x6f, 0x73, 0x0, 0x0, 0xd2, 0x0, 0x0, + 0x8, 0xc3, 0xab, 0x50, 0x0, 0x10, 0x0, 0x21, + 0x2e, 0x10, 0x4, 0xae, 0xfe, 0xef, 0xff, 0xf5, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+904A "遊" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x1, 0x0, 0x0, 0x77, 0x0, 0x4c, 0x0, 0x0, + 0xb, 0x90, 0x0, 0x2c, 0x0, 0xbb, 0x66, 0x61, + 0x0, 0xab, 0x9e, 0xfe, 0xed, 0xe8, 0x77, 0x71, + 0x0, 0x4, 0x0, 0xe0, 0x8, 0x74, 0x44, 0x30, + 0x0, 0x0, 0x0, 0xfb, 0xb3, 0x46, 0x6e, 0x80, + 0x4f, 0xff, 0x0, 0xe3, 0xb4, 0x0, 0xa7, 0x0, + 0x0, 0x2f, 0x2, 0xc0, 0xb3, 0x0, 0xd0, 0x0, + 0x0, 0x1f, 0x3, 0xa0, 0xb6, 0xee, 0xfe, 0xe4, + 0x0, 0x1f, 0x6, 0x80, 0xc2, 0x0, 0xd0, 0x0, + 0x0, 0x1f, 0xc, 0x20, 0xd1, 0x0, 0xd0, 0x0, + 0x0, 0x1f, 0x5b, 0x0, 0xf0, 0x0, 0xe0, 0x0, + 0x0, 0x5f, 0xb2, 0x4d, 0xa0, 0x6d, 0xd0, 0x0, + 0x7, 0xd5, 0xba, 0x41, 0x0, 0x0, 0x0, 0x20, + 0x2e, 0x10, 0x5, 0xbf, 0xfe, 0xef, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+904B "運" */ + 0x7, 0x50, 0xf, 0xdd, 0xdd, 0xdd, 0xdd, 0xd0, + 0x2, 0xe4, 0xf, 0x0, 0x6, 0x10, 0x2, 0xd0, + 0x0, 0x4e, 0x1d, 0x79, 0x9f, 0xa9, 0x97, 0xb0, + 0x0, 0x3, 0x0, 0x23, 0x3e, 0x53, 0x31, 0x0, + 0x0, 0x0, 0x0, 0xbb, 0xbf, 0xcb, 0xbb, 0x0, + 0x3, 0x33, 0x1, 0xd0, 0xd, 0x20, 0xf, 0x0, + 0x3d, 0xdf, 0x1, 0xfb, 0xbf, 0xcb, 0xbf, 0x0, + 0x0, 0xf, 0x1, 0xd0, 0xd, 0x20, 0xf, 0x0, + 0x0, 0xf, 0x1, 0xfb, 0xbf, 0xcb, 0xbf, 0x0, + 0x0, 0xf, 0x0, 0x0, 0xd, 0x20, 0x0, 0x0, + 0x0, 0xf, 0xd, 0xdd, 0xdf, 0xed, 0xdd, 0xd0, + 0x0, 0xae, 0x90, 0x0, 0xd, 0x20, 0x0, 0x0, + 0xb, 0x80, 0x7d, 0x62, 0x15, 0x11, 0x12, 0x41, + 0x1b, 0x0, 0x1, 0x8c, 0xde, 0xed, 0xdd, 0xc2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+904E "過" */ + 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xe2, 0x0, 0x6f, 0xdd, 0xdd, 0xf7, 0x0, + 0x0, 0x5d, 0x10, 0x6c, 0x0, 0x0, 0xb7, 0x0, + 0x0, 0x7, 0x40, 0x6f, 0xcc, 0x70, 0xb7, 0x0, + 0x0, 0x0, 0x0, 0x6c, 0x3, 0x80, 0xb7, 0x0, + 0x0, 0x0, 0x0, 0x6c, 0x3, 0x80, 0xb7, 0x0, + 0x4f, 0xfe, 0xa, 0xef, 0xde, 0xed, 0xfe, 0xa0, + 0x0, 0x2e, 0xb, 0x30, 0x0, 0x0, 0x3, 0xc0, + 0x0, 0x1e, 0xb, 0x30, 0xec, 0xce, 0x3, 0xc0, + 0x0, 0x1e, 0xb, 0x30, 0xd0, 0xd, 0x3, 0xc0, + 0x0, 0x1e, 0xb, 0x30, 0xe4, 0x4e, 0x3, 0xc0, + 0x0, 0x1e, 0xb, 0x30, 0xe7, 0x77, 0x3, 0xc0, + 0x0, 0x9f, 0x3b, 0x30, 0x10, 0x1, 0xde, 0x80, + 0xc, 0x94, 0xda, 0x40, 0x0, 0x0, 0x11, 0x22, + 0x5c, 0x0, 0x6, 0xcf, 0xff, 0xff, 0xff, 0xf8, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+9053 "道" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x10, 0x0, + 0x5, 0x10, 0x0, 0x2e, 0x20, 0x1, 0xe2, 0x0, + 0x6, 0xd1, 0x0, 0x9, 0x70, 0xa, 0x80, 0x0, + 0x0, 0x7c, 0x1d, 0xdd, 0xdf, 0xed, 0xdd, 0xd4, + 0x0, 0x5, 0x0, 0x0, 0xe, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xdd, 0xde, 0xdd, 0xdd, 0x0, + 0x2b, 0xbb, 0x10, 0xe1, 0x0, 0x0, 0x1e, 0x0, + 0x3, 0x3f, 0x10, 0xec, 0xcc, 0xcc, 0xce, 0x0, + 0x0, 0xe, 0x10, 0xe1, 0x0, 0x0, 0x1e, 0x0, + 0x0, 0xe, 0x10, 0xeb, 0xbb, 0xbb, 0xce, 0x0, + 0x0, 0xe, 0x10, 0xe2, 0x11, 0x11, 0x3e, 0x0, + 0x0, 0xe, 0x10, 0xe2, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x1f, 0x30, 0xbc, 0xcc, 0xcc, 0xcb, 0x0, + 0x5, 0xc4, 0xa8, 0x30, 0x0, 0x0, 0x0, 0x21, + 0x1d, 0x10, 0x4, 0xae, 0xed, 0xee, 0xff, 0xf4, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+9054 "達" */ + 0x3, 0x20, 0x0, 0x0, 0x9, 0x60, 0x0, 0x0, + 0x4, 0xe4, 0x2, 0xcc, 0xce, 0xec, 0xcc, 0x10, + 0x0, 0x4e, 0x20, 0x0, 0x9, 0x60, 0x0, 0x0, + 0x0, 0x3, 0x2d, 0xde, 0xdd, 0xdd, 0xed, 0xd2, + 0x0, 0x0, 0x0, 0xe, 0x10, 0x6, 0xb0, 0x0, + 0x2, 0x22, 0x6, 0x7c, 0xa7, 0x7d, 0x97, 0x60, + 0x2b, 0xce, 0x4, 0x44, 0x4b, 0x94, 0x44, 0x40, + 0x0, 0x1e, 0x3, 0x99, 0x9d, 0xc9, 0x99, 0x30, + 0x0, 0x1e, 0x0, 0x22, 0x2b, 0x82, 0x22, 0x0, + 0x0, 0x1e, 0x1, 0x11, 0x1a, 0x71, 0x11, 0x10, + 0x0, 0x1e, 0xb, 0xbb, 0xbe, 0xdb, 0xbb, 0xb0, + 0x0, 0x9e, 0x60, 0x0, 0x9, 0x60, 0x0, 0x0, + 0x9, 0x80, 0x8b, 0x51, 0x2, 0x10, 0x2, 0x32, + 0x1c, 0x0, 0x2, 0x9c, 0xee, 0xfe, 0xed, 0xd3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9055 "違" */ + 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, + 0x6, 0x20, 0x0, 0x0, 0x89, 0x0, 0x0, 0x0, + 0x5, 0xe3, 0x4, 0xcc, 0xfc, 0xcc, 0xf2, 0x0, + 0x0, 0x5e, 0x10, 0x2, 0xe0, 0x0, 0xd2, 0x0, + 0x0, 0x5, 0x5c, 0xcc, 0xcc, 0xcc, 0xcc, 0xc1, + 0x0, 0x0, 0x0, 0x77, 0x77, 0x77, 0x75, 0x0, + 0x0, 0x0, 0x0, 0xf4, 0x44, 0x44, 0x7b, 0x0, + 0x1f, 0xff, 0x0, 0xf6, 0x66, 0x66, 0x9b, 0x0, + 0x0, 0x1f, 0x0, 0x44, 0x44, 0xd7, 0x42, 0x0, + 0x0, 0x1f, 0xb, 0xec, 0xcc, 0xfd, 0xcc, 0xa0, + 0x0, 0x1f, 0x2, 0xd0, 0x0, 0xc3, 0x0, 0x0, + 0x0, 0x1f, 0x7, 0xec, 0xcc, 0xfd, 0xcc, 0x80, + 0x0, 0x3f, 0x30, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0x8, 0xe7, 0xd9, 0x30, 0x0, 0x51, 0x0, 0x10, + 0x3e, 0x20, 0x6, 0xbf, 0xfe, 0xee, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+9060 "遠" */ + 0x1, 0x0, 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, + 0x7, 0xd4, 0x5, 0xdd, 0xdf, 0xed, 0xdd, 0x0, + 0x0, 0x4e, 0x60, 0x0, 0xb, 0x40, 0x0, 0x0, + 0x0, 0x2, 0x5d, 0xdd, 0xdd, 0xdd, 0xdd, 0xd0, + 0x0, 0x0, 0x0, 0x11, 0x11, 0x11, 0x10, 0x0, + 0x18, 0x88, 0x0, 0xfb, 0xbb, 0xbb, 0xd9, 0x0, + 0x5, 0x6f, 0x0, 0xf0, 0x0, 0x0, 0x69, 0x0, + 0x0, 0x1f, 0x0, 0xfc, 0xcc, 0xcc, 0xea, 0x0, + 0x0, 0x1f, 0x0, 0x1, 0xbf, 0x91, 0x3d, 0x40, + 0x0, 0x1f, 0x0, 0x4d, 0x7c, 0x8d, 0xe2, 0x0, + 0x0, 0x1f, 0x1c, 0xc3, 0xc, 0x30, 0x9b, 0x10, + 0x0, 0x5f, 0x44, 0x0, 0xc, 0x30, 0x5, 0x20, + 0x8, 0xd5, 0xba, 0x40, 0x3, 0x0, 0x0, 0x20, + 0x2e, 0x10, 0x5, 0xbf, 0xfe, 0xef, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+9069 "適" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, + 0xb, 0x50, 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, + 0x3, 0xe5, 0x3d, 0xdf, 0xed, 0xde, 0xfe, 0xd5, + 0x0, 0x3f, 0x10, 0xc, 0x60, 0x8, 0xb0, 0x0, + 0x0, 0x2, 0x2, 0x27, 0xb2, 0x3e, 0x52, 0x20, + 0x0, 0x0, 0xb, 0xca, 0xad, 0xca, 0xac, 0xc0, + 0x1, 0x11, 0xb, 0x45, 0x59, 0x85, 0x43, 0xc0, + 0x2c, 0xde, 0xb, 0x44, 0x49, 0x84, 0x43, 0xc0, + 0x0, 0x1e, 0xb, 0x40, 0xac, 0xca, 0x3, 0xc0, + 0x0, 0x1e, 0xb, 0x40, 0xd0, 0xd, 0x3, 0xc0, + 0x0, 0x1e, 0xb, 0x40, 0xe8, 0x8e, 0x3, 0xc0, + 0x0, 0x1e, 0xb, 0x40, 0xd3, 0x34, 0x25, 0xc0, + 0x0, 0x9e, 0x78, 0x30, 0x0, 0x2, 0xcb, 0x50, + 0xa, 0x90, 0x8c, 0x51, 0x0, 0x0, 0x1, 0x22, + 0x1c, 0x0, 0x2, 0x9c, 0xee, 0xee, 0xed, 0xd6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9078 "選" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0x70, 0xe, 0xbb, 0xf2, 0xdc, 0xbc, 0xd0, + 0x2, 0xe6, 0xe, 0x0, 0xc2, 0xd0, 0x0, 0xd0, + 0x0, 0x3f, 0x2e, 0xcc, 0xe2, 0xdc, 0xcc, 0xc0, + 0x0, 0x2, 0xe, 0x0, 0x23, 0xd0, 0x0, 0x43, + 0x0, 0x0, 0xa, 0xcc, 0xd4, 0x9d, 0xcc, 0xc2, + 0x4, 0x44, 0x0, 0x7, 0x20, 0xa, 0x10, 0x0, + 0x7, 0x8f, 0x9, 0xcf, 0xdc, 0xcf, 0xdc, 0x90, + 0x0, 0x1f, 0x0, 0xb, 0x40, 0xf, 0x30, 0x0, + 0x0, 0x1f, 0x0, 0xb, 0x40, 0xf, 0x20, 0x0, + 0x0, 0x1f, 0x5d, 0xdd, 0xdd, 0xdd, 0xdd, 0xd5, + 0x0, 0x1f, 0x0, 0x1b, 0x70, 0x2c, 0x71, 0x0, + 0x0, 0x2f, 0x36, 0xd5, 0x0, 0x0, 0x6d, 0x70, + 0x5, 0xe7, 0xbc, 0x50, 0x0, 0x0, 0x1, 0x31, + 0x1e, 0x30, 0x4, 0xae, 0xfe, 0xee, 0xff, 0xf6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + + /* U+907F "避" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x60, 0x0, + 0x8, 0x80, 0xa, 0xed, 0xf3, 0x2, 0xc0, 0x0, + 0x1, 0xe4, 0xa, 0x30, 0xb4, 0x23, 0xe4, 0x21, + 0x0, 0x4d, 0xb, 0x30, 0xb6, 0xbb, 0xbb, 0xb4, + 0x0, 0x6, 0xb, 0x30, 0xb3, 0x49, 0x6, 0x90, + 0x0, 0x0, 0xc, 0xee, 0xe3, 0xe, 0xc, 0x20, + 0x0, 0x0, 0xd, 0x10, 0x3, 0x9a, 0x9e, 0x94, + 0xe, 0xfe, 0xf, 0x21, 0x13, 0x66, 0xe7, 0x63, + 0x0, 0x1e, 0x2f, 0xd9, 0xc6, 0x0, 0xd1, 0x0, + 0x0, 0x1e, 0x6b, 0xa0, 0x78, 0xee, 0xfe, 0xe4, + 0x0, 0x1e, 0xc5, 0xa0, 0x76, 0x0, 0xd1, 0x0, + 0x0, 0x1e, 0x62, 0xa0, 0x76, 0x0, 0xd1, 0x0, + 0x0, 0x4f, 0x41, 0xdd, 0xd5, 0x0, 0xd1, 0x0, + 0x7, 0xe6, 0xca, 0x40, 0x0, 0x0, 0x0, 0x11, + 0x1e, 0x20, 0x6, 0xbe, 0xed, 0xee, 0xef, 0xf7, + 0x1, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+9084 "還" */ + 0x1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xd1, 0xd, 0xbb, 0xfb, 0xbe, 0xbd, 0x60, + 0x0, 0x7b, 0xd, 0x10, 0xc0, 0x2b, 0x8, 0x60, + 0x0, 0xa, 0x3d, 0xbb, 0xfb, 0xce, 0xbd, 0x60, + 0x0, 0x0, 0x23, 0x33, 0x33, 0x33, 0x33, 0x31, + 0x2, 0x22, 0x58, 0x88, 0x88, 0x88, 0x88, 0x82, + 0x3d, 0xde, 0x3, 0xbb, 0xbb, 0xbb, 0xba, 0x0, + 0x0, 0x1e, 0x5, 0xd0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x1e, 0x5, 0xd1, 0x11, 0x11, 0x3e, 0x0, + 0x0, 0x1e, 0x3, 0x99, 0xcf, 0x99, 0x9b, 0x10, + 0x0, 0x1e, 0x1, 0x5c, 0xd1, 0x89, 0x9a, 0x10, + 0x0, 0x1e, 0x3c, 0x75, 0xb0, 0x5, 0xd5, 0x0, + 0x0, 0x7f, 0x20, 0x8, 0xec, 0xc1, 0x1a, 0x80, + 0xb, 0xa5, 0xd8, 0x28, 0x40, 0x0, 0x1, 0x32, + 0x4d, 0x0, 0x17, 0xdf, 0xff, 0xff, 0xff, 0xf7, + 0x0, 0x0, 0x0, 0x0, 0x11, 0x10, 0x0, 0x0, + + /* U+908A "邊" */ + 0x4, 0x60, 0x0, 0x0, 0xb, 0x40, 0x0, 0x0, + 0x2, 0xe5, 0x0, 0xf9, 0x99, 0x99, 0xad, 0x0, + 0x0, 0x4f, 0x30, 0xf8, 0x88, 0x88, 0x9d, 0x0, + 0x0, 0x8, 0x50, 0xf3, 0x33, 0x33, 0x5d, 0x0, + 0x0, 0x0, 0x0, 0xf9, 0x99, 0x99, 0xad, 0x0, + 0x0, 0x0, 0x0, 0xf8, 0x77, 0x77, 0x9d, 0x0, + 0x3d, 0xdc, 0x0, 0x33, 0x3d, 0x83, 0x33, 0x0, + 0x13, 0x5e, 0x3e, 0x9a, 0xa9, 0x9b, 0x99, 0xf1, + 0x0, 0x1e, 0x27, 0x4b, 0x45, 0x19, 0xa1, 0x81, + 0x0, 0x1e, 0x16, 0xd6, 0x5c, 0x95, 0x9a, 0x51, + 0x0, 0x1e, 0x15, 0x56, 0xf5, 0x55, 0x55, 0x51, + 0x0, 0x1e, 0x0, 0x9, 0xca, 0xaa, 0xd4, 0x0, + 0x0, 0x7f, 0x15, 0xb9, 0x0, 0x0, 0xc0, 0x0, + 0xb, 0xa4, 0xcd, 0x50, 0x0, 0xaa, 0x51, 0x22, + 0x4c, 0x0, 0x6, 0xcf, 0xff, 0xff, 0xff, 0xf8, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0x0, 0x0, + + /* U+90A3 "那" */ + 0x2f, 0xff, 0xff, 0xff, 0xd, 0xee, 0xee, 0xb0, + 0x0, 0xb5, 0x1, 0xf0, 0xe2, 0x11, 0xb7, 0x0, + 0xc, 0x40, 0x1f, 0xe, 0x10, 0x2e, 0x0, 0x0, + 0xc4, 0x1, 0xe0, 0xe1, 0x9, 0x80, 0xe, 0xff, + 0xff, 0xfe, 0xe, 0x11, 0xe1, 0x0, 0x0, 0xd2, + 0x2, 0xe0, 0xe1, 0x8a, 0x0, 0x0, 0xf, 0x10, + 0x2e, 0xe, 0x10, 0xc6, 0x0, 0x1, 0xf0, 0x3, + 0xe0, 0xe1, 0x1, 0xd2, 0x1e, 0xff, 0xee, 0xfe, + 0xe, 0x10, 0x7, 0x90, 0x6, 0x90, 0x3, 0xd0, + 0xe1, 0x0, 0x4b, 0x0, 0xb4, 0x0, 0x4d, 0xe, + 0x21, 0x19, 0x90, 0x2f, 0x0, 0x5, 0xc0, 0xe3, + 0xee, 0xa1, 0xb, 0x70, 0x21, 0xaa, 0xe, 0x10, + 0x0, 0x2, 0xd0, 0xd, 0xfe, 0x30, 0xe1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x0, + + /* U+90AA "邪" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0xff, 0xff, 0xff, 0x89, 0xff, 0xff, 0xe0, + 0x0, 0x0, 0x4, 0xb0, 0x9, 0x60, 0x8, 0xa0, + 0x0, 0xf0, 0x4, 0xb0, 0x9, 0x60, 0xe, 0x40, + 0x2, 0xd0, 0x4, 0xb0, 0x9, 0x60, 0x5c, 0x0, + 0x4, 0xb0, 0x4, 0xb0, 0x9, 0x60, 0xc5, 0x0, + 0x6, 0xa1, 0x15, 0xb1, 0x9, 0x63, 0xd0, 0x0, + 0x8, 0xff, 0xff, 0xff, 0x99, 0x62, 0xd4, 0x0, + 0x0, 0x0, 0x5f, 0xb0, 0x9, 0x60, 0x1e, 0x20, + 0x0, 0x2, 0xe7, 0xb0, 0x9, 0x60, 0x6, 0xa0, + 0x0, 0xd, 0x54, 0xb0, 0x9, 0x60, 0x2, 0xe0, + 0x0, 0xc7, 0x4, 0xb0, 0x9, 0x60, 0x5, 0xd0, + 0x2d, 0x60, 0x4, 0xb0, 0x9, 0x6a, 0xff, 0x50, + 0x35, 0x0, 0x6, 0xb0, 0x9, 0x61, 0x10, 0x0, + 0x0, 0x8, 0xfe, 0x60, 0x9, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+90E8 "部" */ + 0x0, 0x0, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x98, 0x0, 0x0, 0xef, 0xff, 0xe0, + 0x7, 0xbb, 0xde, 0xbb, 0x90, 0xe0, 0x6, 0xb0, + 0x2, 0x87, 0x44, 0x4b, 0x30, 0xe0, 0xb, 0x50, + 0x0, 0x6a, 0x0, 0x4c, 0x0, 0xe0, 0x1e, 0x0, + 0x0, 0xf, 0x0, 0xa6, 0x0, 0xe0, 0x69, 0x0, + 0x0, 0x9, 0x31, 0xe1, 0x0, 0xe0, 0xc3, 0x0, + 0x2e, 0xee, 0xee, 0xee, 0xe3, 0xe0, 0x7b, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0, 0xa, 0x60, + 0x2, 0xee, 0xee, 0xee, 0x60, 0xe0, 0x4, 0xb0, + 0x3, 0xd1, 0x11, 0x1a, 0x60, 0xe0, 0x1, 0xe0, + 0x3, 0xc0, 0x0, 0x9, 0x60, 0xe2, 0x49, 0xb0, + 0x3, 0xc0, 0x0, 0x9, 0x60, 0xe3, 0xb9, 0x20, + 0x3, 0xfd, 0xdd, 0xde, 0x60, 0xe0, 0x0, 0x0, + 0x2, 0xc2, 0x22, 0x2a, 0x60, 0xe0, 0x0, 0x0, + + /* U+90F5 "郵" */ + 0x0, 0x0, 0x0, 0x25, 0x80, 0x0, 0x0, 0x0, + 0x7, 0xbc, 0xef, 0xc9, 0x61, 0xef, 0xff, 0xf4, + 0x3, 0x42, 0x4b, 0x0, 0x0, 0xe1, 0x1, 0xf1, + 0x0, 0x0, 0x4b, 0x0, 0x0, 0xe1, 0x6, 0xa0, + 0xa, 0xfe, 0xff, 0xef, 0xe5, 0xe1, 0xc, 0x40, + 0x0, 0xa3, 0x4b, 0xb, 0x20, 0xe1, 0x2e, 0x0, + 0x0, 0xa3, 0x4b, 0xb, 0x20, 0xe1, 0x88, 0x0, + 0x1e, 0xff, 0xff, 0xef, 0xe8, 0xe1, 0x2d, 0x20, + 0x0, 0xa3, 0x4b, 0xb, 0x20, 0xe1, 0x6, 0xb0, + 0x0, 0xa3, 0x4b, 0xb, 0x20, 0xe1, 0x0, 0xf0, + 0xb, 0xee, 0xef, 0xee, 0xe5, 0xe1, 0x0, 0xd3, + 0x0, 0x0, 0x4b, 0x0, 0x0, 0xe1, 0x1, 0xe2, + 0x0, 0x0, 0x4b, 0x13, 0x53, 0xe2, 0xff, 0xa0, + 0x8, 0x9b, 0xdf, 0xdb, 0x94, 0xe1, 0x0, 0x0, + 0x6, 0x43, 0x10, 0x0, 0x0, 0xe1, 0x0, 0x0, + + /* U+90FD "都" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf0, 0x2, 0xd5, 0xff, 0xff, 0xf2, + 0x6, 0xbb, 0xfb, 0xbb, 0x54, 0xc0, 0x4, 0xe0, + 0x1, 0x33, 0xf3, 0x7b, 0x4, 0xc0, 0xa, 0x70, + 0x0, 0x0, 0xf1, 0xd3, 0x4, 0xc0, 0x1e, 0x0, + 0x3b, 0xbc, 0xfd, 0xfb, 0xb4, 0xc0, 0x88, 0x0, + 0x13, 0x33, 0xda, 0x33, 0x34, 0xc0, 0xf2, 0x0, + 0x0, 0xb, 0xc0, 0x0, 0x4, 0xc0, 0x7c, 0x0, + 0x3, 0xdf, 0xee, 0xef, 0x34, 0xc0, 0x9, 0x90, + 0x5f, 0xe6, 0x0, 0xc, 0x34, 0xc0, 0x1, 0xf0, + 0x13, 0x88, 0x22, 0x2d, 0x34, 0xc0, 0x0, 0xe2, + 0x0, 0x8d, 0xbb, 0xbf, 0x34, 0xc0, 0x1, 0xf0, + 0x0, 0x86, 0x0, 0xc, 0x34, 0xc4, 0xcd, 0x60, + 0x0, 0x8f, 0xee, 0xef, 0x34, 0xc0, 0x0, 0x0, + 0x0, 0x86, 0x0, 0xc, 0x34, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+914D "配" */ + 0x1, 0x11, 0x11, 0x11, 0x0, 0x0, 0x0, 0x0, + 0xd, 0xdf, 0xdf, 0xdd, 0x2f, 0xff, 0xff, 0xe0, + 0x0, 0xb, 0x1c, 0x0, 0x0, 0x0, 0x2, 0xe0, + 0x0, 0xb, 0x1c, 0x0, 0x0, 0x0, 0x1, 0xe0, + 0x9, 0xef, 0xff, 0xea, 0x0, 0x0, 0x1, 0xe0, + 0x9, 0x39, 0xa, 0x2b, 0x0, 0x0, 0x1, 0xe0, + 0x9, 0x39, 0xa, 0x2b, 0xb, 0xbb, 0xbb, 0xe0, + 0x9, 0x3a, 0xa, 0x2b, 0xf, 0x55, 0x56, 0xe0, + 0x9, 0x89, 0xc, 0xbb, 0xf, 0x0, 0x0, 0x20, + 0x9, 0x80, 0x0, 0x2b, 0xf, 0x0, 0x0, 0x0, + 0x9, 0x62, 0x22, 0x5b, 0xf, 0x0, 0x0, 0x0, + 0x9, 0xba, 0xaa, 0xbb, 0xf, 0x0, 0x0, 0x21, + 0x9, 0x30, 0x0, 0x2b, 0xf, 0x0, 0x0, 0x87, + 0x9, 0xed, 0xdd, 0xeb, 0xf, 0x20, 0x0, 0xc5, + 0x9, 0x30, 0x0, 0x2a, 0xa, 0xff, 0xff, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9152 "酒" */ + 0x5, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xf7, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x0, 0x5d, 0x0, 0x2, 0xc0, 0x95, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xc0, 0x95, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xc0, 0x96, 0x0, 0x0, + 0x25, 0x0, 0xf, 0xee, 0xfe, 0xff, 0xef, 0x70, + 0x2b, 0xd4, 0xf, 0x1, 0xc0, 0x93, 0x9, 0x70, + 0x0, 0x43, 0xf, 0x5, 0xa0, 0x94, 0x9, 0x70, + 0x0, 0x0, 0xf, 0x4e, 0x30, 0x6e, 0xdf, 0x70, + 0x0, 0x8, 0xf, 0x93, 0x0, 0x0, 0x9, 0x70, + 0x0, 0x5d, 0xf, 0x32, 0x22, 0x22, 0x2a, 0x70, + 0x0, 0xd6, 0xf, 0xcc, 0xcc, 0xcc, 0xce, 0x70, + 0x5, 0xd0, 0xf, 0x0, 0x0, 0x0, 0x9, 0x70, + 0xe, 0x50, 0xf, 0xbb, 0xbb, 0xbb, 0xbe, 0x70, + 0x18, 0x0, 0xf, 0x43, 0x33, 0x33, 0x3a, 0x60, + + /* U+9154 "酔" */ + 0x1e, 0xef, 0xef, 0xe9, 0x0, 0xe1, 0x0, 0x0, + 0x0, 0xc, 0x29, 0x0, 0xdd, 0xfd, 0xdb, 0x0, + 0x0, 0xc, 0x29, 0x0, 0x25, 0xd2, 0x4d, 0x0, + 0xa, 0xcf, 0xde, 0xc6, 0x7, 0x90, 0x1d, 0x4, + 0xc, 0x3a, 0x48, 0x77, 0xc, 0x40, 0x1d, 0xc, + 0xc, 0x1a, 0x37, 0x68, 0x9d, 0x0, 0xe, 0xb9, + 0xc, 0x1a, 0x37, 0x6a, 0xd2, 0xe, 0x20, 0x20, + 0xc, 0x86, 0xa, 0xd7, 0x0, 0xf, 0x20, 0x0, + 0xc, 0x80, 0x0, 0x68, 0x0, 0xf, 0x30, 0x0, + 0xc, 0x43, 0x33, 0x8a, 0xff, 0xff, 0xff, 0xfb, + 0xc, 0xba, 0xaa, 0xc8, 0x0, 0xf, 0x30, 0x0, + 0xc, 0x10, 0x0, 0x67, 0x0, 0xf, 0x20, 0x0, + 0xc, 0xed, 0xdd, 0xe7, 0x0, 0xf, 0x20, 0x0, + 0xc, 0x10, 0x0, 0x67, 0x0, 0xf, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9178 "酸" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x0, 0x0, + 0x1e, 0xef, 0xff, 0xe6, 0x0, 0xe5, 0x83, 0x0, + 0x0, 0x1a, 0x57, 0x0, 0x9, 0xa0, 0x5d, 0x0, + 0x0, 0x1a, 0x57, 0x0, 0x7f, 0x33, 0x4e, 0x80, + 0xb, 0xff, 0xff, 0xe3, 0xab, 0x97, 0x65, 0xe0, + 0xc, 0x9, 0x54, 0xa3, 0x3, 0xb0, 0x87, 0x0, + 0xc, 0x9, 0x54, 0xa3, 0x1d, 0x40, 0xc, 0x50, + 0xc, 0x28, 0x54, 0xa4, 0xc7, 0x53, 0x1, 0xe2, + 0xc, 0x94, 0x49, 0xc5, 0x81, 0xf2, 0x0, 0x42, + 0xc, 0x70, 0x3, 0xb3, 0xb, 0xed, 0xdf, 0x80, + 0xc, 0x32, 0x22, 0xb3, 0xaf, 0x80, 0x2e, 0x10, + 0xc, 0xaa, 0xaa, 0xd6, 0xb1, 0xd4, 0xc7, 0x0, + 0xc, 0x0, 0x0, 0xa3, 0x0, 0x4f, 0xb0, 0x0, + 0xc, 0xed, 0xdd, 0xf3, 0x17, 0xd7, 0xc9, 0x20, + 0xc, 0x0, 0x0, 0xa8, 0xd7, 0x10, 0x6, 0xc5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+91AB "醫" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x7, 0xdc, 0xdb, 0xbb, 0x18, 0xdb, 0xe3, 0x0, + 0x7, 0x6a, 0xb7, 0x74, 0xc, 0x20, 0xa4, 0x10, + 0x7, 0x9a, 0x3d, 0x32, 0xa8, 0x0, 0x4b, 0x90, + 0x7, 0x9a, 0xbe, 0xaa, 0x3b, 0xbb, 0xdb, 0x0, + 0x7, 0x60, 0xaa, 0x90, 0xc, 0x83, 0xc1, 0x0, + 0x7, 0x7b, 0x61, 0x57, 0x2, 0xcf, 0xc2, 0x0, + 0x4, 0x99, 0x99, 0x99, 0x8b, 0x40, 0x4c, 0x20, + 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, + 0x0, 0x23, 0x33, 0xc6, 0x3e, 0x33, 0x32, 0x0, + 0x0, 0xc9, 0x78, 0xf8, 0x7f, 0x77, 0x9c, 0x0, + 0x0, 0xc6, 0x9c, 0x50, 0xc, 0xa9, 0xbc, 0x0, + 0x0, 0xc9, 0x96, 0x66, 0x66, 0x66, 0x8c, 0x0, + 0x0, 0xc7, 0x55, 0x55, 0x55, 0x55, 0x7c, 0x0, + 0x0, 0xcc, 0xaa, 0xaa, 0xaa, 0xaa, 0xcc, 0x0, + + /* U+91CD "重" */ + 0x0, 0x0, 0x0, 0x1, 0x23, 0x57, 0x91, 0x0, + 0x0, 0x9e, 0xee, 0xde, 0xda, 0x97, 0x41, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0xd, 0xdd, 0xdd, 0xdf, 0xed, 0xdd, 0xdd, 0xd1, + 0x1, 0x11, 0x11, 0x1a, 0x81, 0x11, 0x11, 0x10, + 0x0, 0x5c, 0xcc, 0xce, 0xec, 0xcc, 0xc7, 0x0, + 0x0, 0x69, 0x0, 0x9, 0x70, 0x0, 0x88, 0x0, + 0x0, 0x6e, 0xbb, 0xbe, 0xdb, 0xbb, 0xe8, 0x0, + 0x0, 0x69, 0x0, 0x9, 0x70, 0x0, 0x88, 0x0, + 0x0, 0x6e, 0xbb, 0xbe, 0xdb, 0xbb, 0xd8, 0x0, + 0x0, 0x1, 0x11, 0x1a, 0x81, 0x11, 0x10, 0x0, + 0x0, 0xbb, 0xbb, 0xbe, 0xdb, 0xbb, 0xbb, 0x10, + 0x0, 0x22, 0x22, 0x2a, 0x92, 0x22, 0x22, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x2e, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe2, + + /* U+91CE "野" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xee, 0xfe, 0xef, 0x7f, 0xff, 0xff, 0xe0, + 0xc, 0x10, 0xd1, 0xd, 0x10, 0x0, 0xd, 0x70, + 0xc, 0x10, 0xd1, 0xd, 0x14, 0x50, 0xab, 0x0, + 0xc, 0xed, 0xfe, 0xdf, 0x12, 0xcc, 0xc0, 0x0, + 0xc, 0x10, 0xd1, 0xd, 0x10, 0x9, 0xd1, 0x0, + 0xc, 0x10, 0xd1, 0xd, 0x45, 0x55, 0xcc, 0x51, + 0xb, 0xee, 0xfe, 0xee, 0x7b, 0xbf, 0xcb, 0xf4, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0xe, 0x11, 0xe0, + 0x1, 0x11, 0xe3, 0x11, 0x0, 0xe, 0x16, 0x90, + 0xb, 0xdd, 0xfe, 0xdd, 0x10, 0xe, 0x16, 0x20, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0xe, 0x10, 0x0, + 0x0, 0x0, 0xe4, 0x46, 0x40, 0xe, 0x10, 0x0, + 0x3a, 0xce, 0xdb, 0x97, 0x30, 0x1f, 0x10, 0x0, + 0x14, 0x20, 0x0, 0x0, 0x2f, 0xfc, 0x0, 0x0, + + /* U+91CF "量" */ + 0x0, 0x2f, 0xaa, 0xaa, 0xaa, 0xaa, 0xf2, 0x0, + 0x0, 0x2e, 0x55, 0x55, 0x55, 0x55, 0xf2, 0x0, + 0x0, 0x2e, 0x44, 0x44, 0x44, 0x44, 0xf2, 0x0, + 0x0, 0x2f, 0xaa, 0xaa, 0xaa, 0xaa, 0xf2, 0x0, + 0x4, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x40, + 0x18, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x81, + 0x0, 0x4b, 0xbb, 0xbb, 0xbb, 0xbb, 0xb7, 0x0, + 0x0, 0x68, 0x0, 0x8, 0x70, 0x0, 0x6a, 0x0, + 0x0, 0x6d, 0xaa, 0xad, 0xda, 0xaa, 0xca, 0x0, + 0x0, 0x6b, 0x55, 0x5b, 0xa5, 0x55, 0xaa, 0x0, + 0x0, 0x24, 0x44, 0x4a, 0xa4, 0x44, 0x43, 0x0, + 0x0, 0xbc, 0xcc, 0xce, 0xec, 0xcc, 0xcc, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x70, 0x0, 0x0, 0x0, + 0x3d, 0xdd, 0xdd, 0xde, 0xed, 0xdd, 0xdd, 0xd3, + + /* U+91D1 "金" */ + 0x0, 0x0, 0x0, 0x3, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1e, 0xd1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xe7, 0x7d, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0x60, 0x5, 0xe6, 0x0, 0x0, + 0x0, 0x4d, 0xd3, 0x0, 0x0, 0x2c, 0xd4, 0x0, + 0x3d, 0xe8, 0xdc, 0xcc, 0xcc, 0xcd, 0x8e, 0xd3, + 0x6, 0x0, 0x33, 0x3b, 0xa3, 0x33, 0x0, 0x50, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x11, 0x11, 0x1a, 0x91, 0x11, 0x11, 0x0, + 0x2, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0x30, + 0x0, 0x5, 0x20, 0x9, 0x80, 0x4, 0x50, 0x0, + 0x0, 0x5, 0xc0, 0x9, 0x80, 0xc, 0x50, 0x0, + 0x0, 0x0, 0xc4, 0x9, 0x80, 0x6b, 0x0, 0x0, + 0x0, 0x0, 0x44, 0x9, 0x80, 0x71, 0x0, 0x0, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + + /* U+91DD "針" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xf1, 0x0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0xd, 0xcc, 0x20, 0x0, 0x2e, 0x0, 0x0, + 0x1, 0xc9, 0x6, 0xe4, 0x0, 0x2e, 0x0, 0x0, + 0x1d, 0xc1, 0x11, 0x56, 0x0, 0x2e, 0x0, 0x0, + 0x8, 0xbd, 0xfc, 0xa0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x1, 0xd0, 0x7, 0xcc, 0xdf, 0xcc, 0xc3, + 0xb, 0xcc, 0xfc, 0xc4, 0x0, 0x2e, 0x0, 0x0, + 0x2, 0x24, 0xe2, 0x31, 0x0, 0x2e, 0x0, 0x0, + 0x4, 0x61, 0xd0, 0xd0, 0x0, 0x2e, 0x0, 0x0, + 0x1, 0xb1, 0xd2, 0xa0, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0xd1, 0xd7, 0x50, 0x0, 0x2e, 0x0, 0x0, + 0x0, 0x21, 0xe6, 0x95, 0x0, 0x2e, 0x0, 0x0, + 0x9, 0xce, 0xc8, 0x51, 0x0, 0x2e, 0x0, 0x0, + 0x5, 0x20, 0x0, 0x0, 0x0, 0x2e, 0x0, 0x0, + + /* U+9244 "鉄" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xd0, 0x0, 0x23, 0x2e, 0x0, 0x0, + 0x0, 0xd, 0xd9, 0x0, 0x89, 0x2e, 0x0, 0x0, + 0x1, 0xc7, 0x8, 0xc1, 0xb9, 0x5f, 0x33, 0x30, + 0x1d, 0xa1, 0x11, 0x72, 0xfb, 0xcf, 0xbb, 0xb0, + 0x7, 0xad, 0xfc, 0x57, 0xb0, 0x2e, 0x0, 0x0, + 0x0, 0x1, 0xb0, 0x9, 0x40, 0x2e, 0x0, 0x0, + 0x4, 0x57, 0xd5, 0x50, 0x11, 0x3e, 0x11, 0x10, + 0x7, 0x9a, 0xe9, 0x88, 0xff, 0xff, 0xff, 0xf5, + 0x1, 0x31, 0xb1, 0x60, 0x0, 0x7f, 0x10, 0x0, + 0x1, 0xb1, 0xb4, 0x80, 0x0, 0xbe, 0x60, 0x0, + 0x0, 0xc2, 0xb8, 0x30, 0x3, 0xf4, 0xc0, 0x0, + 0x0, 0x62, 0xb5, 0x40, 0x1d, 0x60, 0xb5, 0x0, + 0x3, 0x6a, 0xfd, 0x93, 0xd9, 0x0, 0x3f, 0x40, + 0xb, 0x84, 0x10, 0x5f, 0x70, 0x0, 0x5, 0xf5, + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x20, + + /* U+925B "鉛" */ + 0x0, 0x2, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0xe3, 0x0, 0x3f, 0xff, 0xfd, 0x0, + 0x0, 0x6b, 0x5e, 0x40, 0x3c, 0x0, 0x1d, 0x0, + 0x4, 0xe1, 0x3, 0xf4, 0x4b, 0x0, 0x1d, 0x0, + 0x3f, 0x71, 0x11, 0x52, 0x69, 0x0, 0x1d, 0x0, + 0x16, 0xcd, 0xec, 0x50, 0xb5, 0x0, 0x1d, 0x0, + 0x0, 0x4, 0xa0, 0x5, 0xd0, 0x0, 0xe, 0x74, + 0x8, 0x9b, 0xd9, 0x9b, 0x20, 0x0, 0x2, 0x52, + 0x2, 0x27, 0xb3, 0x30, 0xcd, 0xdd, 0xdd, 0x70, + 0x7, 0x34, 0xa2, 0xb0, 0xe2, 0x11, 0x17, 0x90, + 0x5, 0x84, 0xa6, 0x70, 0xe0, 0x0, 0x6, 0x90, + 0x2, 0xb4, 0xaa, 0x10, 0xe0, 0x0, 0x6, 0x90, + 0x0, 0x25, 0xc6, 0x91, 0xe0, 0x0, 0x6, 0x90, + 0x1a, 0xde, 0xb8, 0x40, 0xee, 0xee, 0xee, 0x90, + 0x5, 0x20, 0x0, 0x0, 0xe1, 0x0, 0x6, 0x80, + + /* U+9280 "銀" */ + 0x0, 0x2, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0xd1, 0x1, 0xff, 0xff, 0xff, 0x40, + 0x0, 0x6b, 0x7d, 0x11, 0xe0, 0x0, 0xb, 0x40, + 0x5, 0xe1, 0x8, 0xd2, 0xe0, 0x0, 0xb, 0x40, + 0x3f, 0x51, 0x11, 0x71, 0xf8, 0x88, 0x8e, 0x40, + 0x7, 0xde, 0xed, 0x11, 0xf7, 0x77, 0x7d, 0x40, + 0x0, 0x8, 0x60, 0x1, 0xe0, 0x0, 0xb, 0x40, + 0xc, 0xce, 0xdc, 0x81, 0xfe, 0xee, 0xef, 0x40, + 0x3, 0x3a, 0x83, 0x21, 0xe0, 0x87, 0x1, 0x20, + 0x6, 0x48, 0x67, 0x61, 0xe0, 0x3c, 0xa, 0xa0, + 0x4, 0x98, 0x6b, 0x11, 0xe0, 0xd, 0xd8, 0x0, + 0x1, 0xc8, 0x6b, 0x1, 0xe0, 0x6, 0xc0, 0x0, + 0x0, 0x28, 0x98, 0x91, 0xe0, 0x3, 0xc7, 0x0, + 0x1a, 0xee, 0xb7, 0x34, 0xfb, 0xe8, 0x2e, 0x90, + 0x6, 0x20, 0x0, 0xa, 0xa5, 0x0, 0x2, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9322 "錢" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x60, 0x0, 0xa, 0x44, 0xb3, 0x0, + 0x0, 0x4e, 0xd3, 0x0, 0x8, 0x70, 0x29, 0x20, + 0x3, 0xd2, 0x3d, 0x66, 0xbd, 0xfd, 0xdc, 0xb1, + 0x3e, 0x61, 0x13, 0x72, 0x21, 0xd2, 0x5a, 0x0, + 0x28, 0xce, 0xdc, 0x0, 0x0, 0x7d, 0xa0, 0x30, + 0x0, 0x9, 0x30, 0x5, 0x9b, 0x98, 0xb5, 0xc2, + 0xc, 0xce, 0xdc, 0x64, 0x3a, 0x3, 0x66, 0x40, + 0x2, 0x2a, 0x63, 0x10, 0xd, 0x13, 0x9c, 0x0, + 0x9, 0x9, 0x3a, 0x21, 0x2c, 0x87, 0x8a, 0xb3, + 0x7, 0x49, 0x4c, 0x9, 0xbb, 0xd6, 0x59, 0x30, + 0x4, 0x89, 0x59, 0x0, 0x0, 0xe2, 0xb9, 0x0, + 0x0, 0x19, 0x78, 0x50, 0x0, 0x9f, 0x70, 0x32, + 0x1a, 0xed, 0x95, 0x11, 0x7d, 0xab, 0x91, 0x85, + 0x4, 0x10, 0x0, 0xc, 0x81, 0x0, 0x8d, 0xd1, + + /* U+932F "錯" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x70, 0x0, 0x2b, 0x0, 0xc3, 0x0, + 0x0, 0x4e, 0xd4, 0x0, 0x3c, 0x0, 0xc3, 0x0, + 0x3, 0xd2, 0x2d, 0x7a, 0xef, 0xee, 0xff, 0x80, + 0x3f, 0x72, 0x23, 0x60, 0x2b, 0x0, 0xc3, 0x0, + 0x16, 0xad, 0xca, 0x0, 0x3c, 0x0, 0xc3, 0x0, + 0x0, 0x9, 0x40, 0xe, 0xee, 0xee, 0xee, 0xe0, + 0x9, 0x9d, 0xb9, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x3, 0x3a, 0x73, 0x10, 0xee, 0xee, 0xee, 0x10, + 0x8, 0x9, 0x48, 0x30, 0xe0, 0x0, 0xe, 0x10, + 0x7, 0x49, 0x4b, 0x0, 0xe0, 0x0, 0xe, 0x10, + 0x4, 0x79, 0x5b, 0x0, 0xfe, 0xee, 0xef, 0x10, + 0x1, 0x49, 0x55, 0x20, 0xe0, 0x0, 0xe, 0x10, + 0x3, 0x7d, 0xfd, 0x50, 0xf2, 0x22, 0x2e, 0x10, + 0x1b, 0x74, 0x0, 0x0, 0xfb, 0xbb, 0xbe, 0x10, + + /* U+9332 "録" */ + 0x0, 0x5, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x90, 0x9, 0xee, 0xee, 0xef, 0x10, + 0x0, 0x89, 0xba, 0x0, 0x0, 0x0, 0xd, 0x10, + 0x6, 0xd0, 0xb, 0x90, 0x22, 0x22, 0x2e, 0x10, + 0x4f, 0x51, 0x12, 0x64, 0xdd, 0xdd, 0xdf, 0x10, + 0x28, 0xce, 0xdc, 0x0, 0x0, 0x0, 0xd, 0x10, + 0x0, 0x9, 0x30, 0x2b, 0xbb, 0xcb, 0xbf, 0xc2, + 0xc, 0xce, 0xdc, 0x62, 0x0, 0xb3, 0x0, 0x20, + 0x2, 0x2a, 0x63, 0x1a, 0x70, 0xb3, 0x8, 0xc0, + 0x8, 0x9, 0x3a, 0x20, 0xc4, 0xb9, 0xa9, 0x0, + 0x7, 0x49, 0x4c, 0x0, 0x16, 0xfe, 0x90, 0x0, + 0x4, 0x79, 0x69, 0x0, 0xab, 0xd4, 0xd5, 0x0, + 0x0, 0x19, 0x78, 0x8d, 0x80, 0xb3, 0x2d, 0xa1, + 0x1a, 0xde, 0xa6, 0x44, 0x0, 0xc3, 0x0, 0x82, + 0x5, 0x20, 0x0, 0x0, 0x3e, 0xd1, 0x0, 0x0, + + /* U+9577 "長" */ + 0x0, 0x4, 0xfe, 0xee, 0xee, 0xee, 0xe8, 0x0, + 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xd2, 0x22, 0x22, 0x22, 0x20, 0x0, + 0x0, 0x4, 0xfb, 0xbb, 0xbb, 0xbb, 0xb1, 0x0, + 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xfe, 0xee, 0xee, 0xee, 0xe1, 0x0, + 0x0, 0x4, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0xee, 0xfe, 0xee, 0xee, 0xee, 0xee, 0xe2, + 0x0, 0x8, 0x90, 0x8, 0xa1, 0x0, 0x2a, 0x20, + 0x0, 0x7, 0x90, 0x0, 0xe6, 0x6, 0xd6, 0x0, + 0x0, 0x7, 0x90, 0x0, 0x3e, 0xc9, 0x10, 0x0, + 0x0, 0x7, 0x90, 0x2, 0x64, 0xe9, 0x10, 0x0, + 0x0, 0xc, 0xca, 0xec, 0x80, 0x19, 0xfa, 0x51, + 0x0, 0x1d, 0x95, 0x0, 0x0, 0x0, 0x27, 0xc2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9589 "閉" */ + 0x4f, 0xdd, 0xdf, 0x51, 0xfd, 0xdd, 0xde, 0x4c, + 0x0, 0xa, 0x51, 0xe0, 0x0, 0x2e, 0x4e, 0xaa, + 0xae, 0x51, 0xfa, 0xaa, 0xbe, 0x4c, 0x22, 0x2b, + 0x51, 0xe2, 0x22, 0x4e, 0x4c, 0x0, 0xa, 0x51, + 0xe0, 0x0, 0x2e, 0x4f, 0xdd, 0xdd, 0x41, 0xdd, + 0xdd, 0xde, 0x4c, 0x0, 0x0, 0x3, 0x70, 0x0, + 0x2e, 0x4c, 0x2, 0x22, 0x26, 0xb2, 0x20, 0x2e, + 0x4c, 0xa, 0xbb, 0xbf, 0xeb, 0xb2, 0x2e, 0x4c, + 0x0, 0x0, 0x7e, 0xa0, 0x0, 0x2e, 0x4c, 0x0, + 0x8, 0xb5, 0xa0, 0x0, 0x2e, 0x4c, 0x3, 0xca, + 0x4, 0xa0, 0x0, 0x2e, 0x4c, 0x1d, 0x40, 0x4, + 0xa0, 0x11, 0x5e, 0x4c, 0x0, 0x0, 0xce, 0x70, + 0xef, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+958B "開" */ + 0xce, 0xdd, 0xdf, 0x8, 0xed, 0xdd, 0xf2, 0xc4, + 0x0, 0xf, 0x8, 0x70, 0x0, 0xd2, 0xcc, 0xbb, + 0xbf, 0x8, 0xdb, 0xbb, 0xf2, 0xc5, 0x11, 0x1f, + 0x8, 0x81, 0x11, 0xe2, 0xc4, 0x0, 0xf, 0x8, + 0x70, 0x0, 0xd2, 0xce, 0xdd, 0xdd, 0x7, 0xdd, + 0xdd, 0xf2, 0xc4, 0x1, 0x11, 0x11, 0x11, 0x10, + 0xd2, 0xc4, 0x3c, 0xee, 0xcc, 0xfc, 0x80, 0xd2, + 0xc4, 0x0, 0x77, 0x2, 0xd0, 0x0, 0xd2, 0xc4, + 0x7c, 0xee, 0xcd, 0xfc, 0xc1, 0xd2, 0xc4, 0x1, + 0xa6, 0x13, 0xd1, 0x10, 0xd2, 0xc4, 0x0, 0xe1, + 0x2, 0xd0, 0x0, 0xd2, 0xc4, 0x7, 0xa0, 0x2, + 0xd0, 0x11, 0xe2, 0xc4, 0x2b, 0x10, 0x2, 0xd0, + 0xdf, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+9593 "間" */ + 0x4f, 0xdd, 0xdf, 0x50, 0xfd, 0xdd, 0xde, 0x4c, + 0x0, 0xa, 0x50, 0xf0, 0x0, 0x2e, 0x4e, 0xaa, + 0xae, 0x50, 0xfa, 0xaa, 0xbe, 0x4c, 0x22, 0x2b, + 0x50, 0xf2, 0x22, 0x4e, 0x4c, 0x0, 0xa, 0x50, + 0xf0, 0x0, 0x2e, 0x4f, 0xdd, 0xdd, 0x40, 0xdd, + 0xdd, 0xde, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0x4c, 0x0, 0xed, 0xdd, 0xdf, 0x20, 0x2e, + 0x4c, 0x0, 0xe1, 0x0, 0xd, 0x20, 0x2e, 0x4c, + 0x0, 0xed, 0xcc, 0xcf, 0x20, 0x2e, 0x4c, 0x0, + 0xe1, 0x0, 0xd, 0x20, 0x2e, 0x4c, 0x0, 0xe1, + 0x0, 0xd, 0x20, 0x2e, 0x4c, 0x0, 0xed, 0xdd, + 0xdd, 0x31, 0x4e, 0x4c, 0x0, 0x80, 0x0, 0x0, + 0xaf, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+95A2 "関" */ + 0xce, 0xdd, 0xdf, 0x7, 0xed, 0xdd, 0xf2, 0xc4, + 0x0, 0xf, 0x7, 0x80, 0x0, 0xd2, 0xcd, 0xcc, + 0xcf, 0x7, 0xec, 0xcc, 0xf2, 0xc4, 0x0, 0xf, + 0x7, 0x80, 0x0, 0xd2, 0xc6, 0x22, 0x2f, 0x7, + 0x92, 0x22, 0xe2, 0xcc, 0xaa, 0xba, 0x5, 0xcb, + 0xaa, 0xf2, 0xc4, 0x0, 0xc3, 0x0, 0xc3, 0x0, + 0xd2, 0xc4, 0x2d, 0xee, 0xdd, 0xfd, 0x90, 0xd2, + 0xc4, 0x0, 0x0, 0xd2, 0x0, 0x0, 0xd2, 0xc4, + 0x5b, 0xbb, 0xfc, 0xbb, 0xb0, 0xd2, 0xc4, 0x1, + 0x16, 0xfc, 0x21, 0x10, 0xd2, 0xc4, 0x0, 0x5e, + 0x36, 0xd3, 0x0, 0xd2, 0xc4, 0x3d, 0xa2, 0x0, + 0x3e, 0x10, 0xe2, 0xc4, 0x1, 0x0, 0x0, 0x0, + 0x8f, 0xc0, + + /* U+95DC "關" */ + 0xcd, 0xcc, 0xcf, 0x9, 0xec, 0xcc, 0xf3, 0xc3, + 0x0, 0xf, 0x9, 0x70, 0x0, 0xc3, 0xcc, 0xbb, + 0xbf, 0x9, 0xdb, 0xbb, 0xf3, 0xc3, 0x0, 0xf, + 0x9, 0x70, 0x0, 0xc3, 0xcd, 0xcc, 0xcf, 0x9, + 0xec, 0xcc, 0xf3, 0xc3, 0x3, 0x90, 0x0, 0xc1, + 0x0, 0xc3, 0xc3, 0x1b, 0x1a, 0x9, 0x54, 0x70, + 0xc3, 0xc3, 0x6b, 0xe4, 0x2b, 0xd9, 0x10, 0xc3, + 0xc3, 0x3c, 0x7c, 0x28, 0xa6, 0x90, 0xc3, 0xc3, + 0x47, 0x57, 0x7b, 0x64, 0x70, 0xc3, 0xc3, 0xb, + 0x9, 0x2d, 0x0, 0xb0, 0xc3, 0xc3, 0xe, 0xad, + 0x2d, 0xaa, 0xb0, 0xc3, 0xc3, 0x0, 0x4d, 0xd, + 0x0, 0x61, 0xd3, 0xc3, 0x5, 0xb2, 0xd, 0x0, + 0x1f, 0xc1, + + /* U+95F0 "闰" */ + 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0x80, 0xbf, 0xff, 0xff, 0xff, 0xf3, 0x0, 0xd4, + 0x0, 0x0, 0x0, 0x0, 0xc3, 0x10, 0x36, 0x0, + 0x0, 0x0, 0x0, 0xc3, 0xd3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc3, 0xd3, 0x2e, 0xee, 0xfe, 0xee, + 0xc0, 0xc3, 0xd3, 0x0, 0x0, 0xc4, 0x0, 0x0, + 0xc3, 0xd3, 0x0, 0x0, 0xc4, 0x0, 0x0, 0xc3, + 0xd3, 0xb, 0xee, 0xfe, 0xee, 0x40, 0xc3, 0xd3, + 0x0, 0x0, 0xc4, 0x0, 0x0, 0xc3, 0xd3, 0x0, + 0x0, 0xc4, 0x0, 0x0, 0xc3, 0xd3, 0x0, 0x0, + 0xc4, 0x0, 0x0, 0xc3, 0xd3, 0x7e, 0xee, 0xee, + 0xee, 0xe0, 0xc3, 0xd3, 0x0, 0x0, 0x0, 0x0, + 0x11, 0xd3, 0xd3, 0x0, 0x0, 0x0, 0x4, 0xff, + 0xb0, + + /* U+9633 "阳" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, + 0xff, 0xf1, 0xef, 0xff, 0xff, 0xf2, 0xc3, 0x6, + 0x90, 0xe1, 0x0, 0x0, 0xe2, 0xc3, 0xd, 0x10, + 0xe1, 0x0, 0x0, 0xe2, 0xc3, 0x69, 0x0, 0xe1, + 0x0, 0x0, 0xe2, 0xc3, 0xd4, 0x0, 0xe1, 0x0, + 0x0, 0xe2, 0xc3, 0x4d, 0x10, 0xe1, 0x0, 0x0, + 0xe2, 0xc3, 0x6, 0xa0, 0xef, 0xff, 0xff, 0xf2, + 0xc3, 0x0, 0xe0, 0xe2, 0x0, 0x0, 0xe2, 0xc3, + 0x0, 0xf0, 0xe1, 0x0, 0x0, 0xe2, 0xc7, 0xbe, + 0xa0, 0xe1, 0x0, 0x0, 0xe2, 0xc4, 0x32, 0x0, + 0xe1, 0x0, 0x0, 0xe2, 0xc3, 0x0, 0x0, 0xe2, + 0x0, 0x0, 0xe2, 0xc3, 0x0, 0x0, 0xef, 0xff, + 0xff, 0xf2, 0xc3, 0x0, 0x0, 0xe1, 0x0, 0x0, + 0xc1, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9644 "附" */ + 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0xd, + 0xff, 0xf3, 0x2, 0xe0, 0x0, 0x1e, 0x0, 0xd1, + 0xe, 0x0, 0x98, 0x0, 0x1, 0xe0, 0xd, 0x13, + 0xa0, 0x1f, 0x10, 0x0, 0x1e, 0x0, 0xd1, 0x85, + 0xa, 0xe4, 0xee, 0xee, 0xfe, 0x5d, 0x1c, 0x6, + 0xfe, 0x1, 0x11, 0x3e, 0x10, 0xd1, 0x96, 0xf6, + 0xe0, 0x0, 0x1, 0xe0, 0xd, 0x12, 0xd3, 0x1e, + 0xa, 0x40, 0x1e, 0x0, 0xd1, 0xd, 0x11, 0xe0, + 0x3c, 0x1, 0xe0, 0xd, 0x10, 0xc3, 0x1e, 0x0, + 0xc4, 0x1e, 0x0, 0xd2, 0x3e, 0x11, 0xe0, 0x6, + 0x81, 0xe0, 0xd, 0x2c, 0x70, 0x1e, 0x0, 0x0, + 0x1e, 0x0, 0xd1, 0x0, 0x1, 0xe0, 0x0, 0x1, + 0xe0, 0xd, 0x10, 0x0, 0x1e, 0x0, 0x0, 0x3e, + 0x0, 0xd1, 0x0, 0x1, 0xd0, 0x3, 0xff, 0x80, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+964D "降" */ + 0x0, 0x0, 0x0, 0x1, 0x90, 0x0, 0x0, 0xd, + 0xff, 0xfa, 0x0, 0x9a, 0x0, 0x0, 0x0, 0xd1, + 0xb, 0x60, 0x5f, 0xdd, 0xdf, 0x90, 0xd, 0x12, + 0xe0, 0x6e, 0xd2, 0x5, 0xd1, 0x0, 0xd1, 0xa8, + 0xb, 0x23, 0xd8, 0xd2, 0x0, 0xd, 0x2f, 0x20, + 0x0, 0x3c, 0xfa, 0x20, 0x0, 0xd1, 0x7b, 0x17, + 0xce, 0x50, 0x7e, 0xc8, 0xd, 0x10, 0xc6, 0xa5, + 0x0, 0xe1, 0x4, 0x70, 0xd1, 0x6, 0x91, 0x33, + 0x3f, 0x43, 0x31, 0xd, 0x10, 0x4b, 0x5b, 0xbb, + 0xfb, 0xbb, 0x40, 0xd3, 0x4a, 0x82, 0x80, 0xe, + 0x10, 0x0, 0xd, 0x4a, 0x80, 0x68, 0x0, 0xe1, + 0x0, 0x0, 0xd1, 0x0, 0xa, 0xff, 0xff, 0xff, + 0xfe, 0xd, 0x10, 0x0, 0x0, 0x0, 0xe1, 0x0, + 0x0, 0xd1, 0x0, 0x0, 0x0, 0xe, 0x10, 0x0, + 0x0, + + /* U+9650 "限" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xff, 0xff, 0x3b, 0xee, 0xee, 0xee, 0x10, 0x4b, + 0x2, 0xe0, 0xc3, 0x0, 0x0, 0xe1, 0x4, 0xb0, + 0x88, 0xc, 0x30, 0x0, 0xe, 0x10, 0x4b, 0xe, + 0x20, 0xce, 0xee, 0xee, 0xf1, 0x4, 0xb4, 0xd0, + 0xc, 0x30, 0x0, 0xe, 0x10, 0x4b, 0xb, 0x60, + 0xc3, 0x0, 0x0, 0xe1, 0x4, 0xb0, 0x1e, 0xc, + 0xee, 0xee, 0xef, 0x10, 0x4b, 0x0, 0xd1, 0xc4, + 0x1e, 0x10, 0x2, 0x4, 0xb0, 0xd, 0x2c, 0x30, + 0xb5, 0xa, 0xb0, 0x4b, 0x6c, 0xd0, 0xc3, 0x5, + 0xcd, 0x70, 0x4, 0xb1, 0x30, 0xc, 0x30, 0xc, + 0x70, 0x0, 0x4b, 0x0, 0x0, 0xc3, 0x1, 0x3e, + 0x40, 0x4, 0xb0, 0x0, 0xe, 0xbd, 0xe1, 0x4f, + 0x91, 0x4b, 0x0, 0x2, 0xd8, 0x30, 0x0, 0x2b, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9662 "院" */ + 0x0, 0x0, 0x0, 0x0, 0x82, 0x0, 0x0, 0xe, + 0xff, 0xf3, 0x0, 0x9, 0x90, 0x0, 0x0, 0xe1, + 0xe, 0x12, 0x22, 0x5e, 0x32, 0x22, 0xe, 0x13, + 0xa3, 0xfc, 0xcc, 0xcc, 0xcc, 0xf0, 0xe1, 0x74, + 0x3c, 0x0, 0x0, 0x0, 0x2f, 0xe, 0x1b, 0x2, + 0x7b, 0xcc, 0xcc, 0xc7, 0x90, 0xe1, 0x68, 0x0, + 0x22, 0x22, 0x22, 0x10, 0xe, 0x10, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe1, 0xc, 0x5e, 0xee, + 0xee, 0xee, 0xee, 0x1e, 0x10, 0xc3, 0x11, 0xf2, + 0x1f, 0x11, 0x10, 0xe2, 0xbe, 0x0, 0x1f, 0x0, + 0xf0, 0x0, 0xe, 0x13, 0x10, 0x6, 0xb0, 0xf, + 0x0, 0x0, 0xe1, 0x0, 0x1, 0xd4, 0x0, 0xf0, + 0xa, 0x2e, 0x10, 0x3, 0xc9, 0x0, 0xf, 0x0, + 0xc2, 0xe1, 0x4, 0xe6, 0x0, 0x0, 0xcf, 0xfc, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9664 "除" */ + 0x0, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0xd, + 0xff, 0xf3, 0x0, 0x9, 0xf2, 0x0, 0x0, 0xd1, + 0xe, 0x0, 0x7, 0xb5, 0xe2, 0x0, 0xd, 0x15, + 0x80, 0x7, 0xc0, 0x5, 0xe4, 0x0, 0xd1, 0xa2, + 0x1b, 0xb1, 0x0, 0x4, 0xe9, 0xd, 0x1d, 0x6, + 0x7a, 0xbb, 0xbb, 0xb6, 0x70, 0xd1, 0x77, 0x0, + 0x33, 0x6e, 0x33, 0x10, 0xd, 0x10, 0xe0, 0x0, + 0x2, 0xd0, 0x0, 0x0, 0xd1, 0xc, 0x6a, 0xaa, + 0xbf, 0xaa, 0xa9, 0xd, 0x10, 0xc5, 0x44, 0x47, + 0xe4, 0x44, 0x40, 0xd4, 0xcd, 0x0, 0x90, 0x2d, + 0xa, 0x10, 0xd, 0x13, 0x0, 0x7a, 0x2, 0xd0, + 0x6c, 0x0, 0xd1, 0x0, 0x3e, 0x20, 0x2d, 0x0, + 0xa7, 0xd, 0x10, 0xa, 0x50, 0x3, 0xd0, 0x1, + 0xa0, 0xd1, 0x0, 0x0, 0x4f, 0xf8, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9678 "陸" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, + 0xff, 0xfa, 0x0, 0x3, 0xd0, 0x0, 0x0, 0xd1, + 0x9, 0x78, 0xff, 0xff, 0xff, 0xf6, 0xd, 0x10, + 0xe1, 0x0, 0x3, 0xd0, 0x0, 0x0, 0xd1, 0x4b, + 0x0, 0x0, 0x3d, 0x0, 0x0, 0xd, 0x1a, 0x53, + 0xff, 0xff, 0xff, 0xff, 0xf2, 0xd1, 0x4c, 0x0, + 0x5, 0x20, 0x55, 0x0, 0xd, 0x10, 0xa5, 0x6, + 0xc1, 0x1, 0xb9, 0x0, 0xd1, 0x5, 0xaa, 0xa0, + 0x15, 0x0, 0x8a, 0xd, 0x10, 0x5a, 0x40, 0x3, + 0xd0, 0x0, 0x0, 0xd1, 0xbe, 0x58, 0xbb, 0xcf, + 0xbb, 0xb6, 0xd, 0x12, 0x10, 0x23, 0x35, 0xd3, + 0x33, 0x10, 0xd1, 0x0, 0x0, 0x0, 0x3d, 0x0, + 0x0, 0xd, 0x10, 0x0, 0x0, 0x3, 0xd0, 0x0, + 0x0, 0xd1, 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x50, + + /* U+967D "陽" */ + 0xdf, 0xff, 0x31, 0xfd, 0xdd, 0xdd, 0xe0, 0xe, + 0x10, 0xe0, 0x1e, 0x0, 0x0, 0x1e, 0x0, 0xe1, + 0x3a, 0x1, 0xfc, 0xcc, 0xcd, 0xe0, 0xe, 0x17, + 0x40, 0x1e, 0x0, 0x0, 0x1e, 0x0, 0xe1, 0xb0, + 0x1, 0xfa, 0xaa, 0xab, 0xe0, 0xe, 0x17, 0x60, + 0x2, 0x22, 0x22, 0x22, 0x0, 0xe1, 0x1d, 0x9c, + 0xcc, 0xcc, 0xcc, 0xcc, 0x3e, 0x10, 0xd2, 0xa, + 0x80, 0x0, 0x0, 0x0, 0xe1, 0xb, 0x33, 0xf9, + 0x77, 0x77, 0x75, 0xe, 0x14, 0xe3, 0xdb, 0xae, + 0x9d, 0xbb, 0x90, 0xe1, 0xa8, 0xe6, 0xc, 0x41, + 0xd0, 0x78, 0xe, 0x10, 0x3, 0xa, 0x80, 0xa6, + 0x8, 0x60, 0xe1, 0x0, 0x3d, 0x70, 0x8b, 0x0, + 0xc4, 0xe, 0x10, 0x4, 0x40, 0x2a, 0x8, 0xec, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+968E "階" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0xff, 0xf3, 0xe1, 0x0, 0x4b, 0x0, 0x0, 0xe0, + 0xe, 0xe, 0x10, 0x4, 0xb0, 0x7a, 0xe, 0x4, + 0xa0, 0xef, 0xed, 0x4d, 0xca, 0x10, 0xe0, 0x94, + 0xe, 0x10, 0x4, 0xe3, 0x0, 0xe, 0xc, 0x0, + 0xe1, 0x0, 0x4b, 0x0, 0x91, 0xe0, 0xb3, 0x2f, + 0x9b, 0xc4, 0xd3, 0x3e, 0xe, 0x2, 0xc4, 0xc7, + 0x37, 0x6a, 0xbb, 0x70, 0xe0, 0xd, 0x10, 0x11, + 0xf5, 0x11, 0x10, 0xe, 0x0, 0xb3, 0xbd, 0xcc, + 0xcc, 0xcf, 0x0, 0xe2, 0x7e, 0xb, 0x40, 0x0, + 0x0, 0xf0, 0xe, 0x15, 0x20, 0xbe, 0xdd, 0xdd, + 0xdf, 0x0, 0xe0, 0x0, 0xb, 0x40, 0x0, 0x0, + 0xf0, 0xe, 0x0, 0x0, 0xb5, 0x0, 0x0, 0xf, + 0x0, 0xe0, 0x0, 0xb, 0xed, 0xdd, 0xdd, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+969B "際" */ + 0x0, 0x0, 0x0, 0x70, 0x3, 0x0, 0x0, 0xd, + 0xff, 0xf3, 0x2e, 0x0, 0xb0, 0x0, 0x0, 0xd1, + 0xe, 0x19, 0xdc, 0xf8, 0xdc, 0xcc, 0xd, 0x13, + 0xb4, 0xe6, 0x2b, 0x29, 0x8, 0x60, 0xd1, 0x77, + 0xe3, 0x3d, 0x50, 0xc3, 0xd0, 0xd, 0x1b, 0x2, + 0xa5, 0xb0, 0x4, 0xf3, 0x0, 0xd1, 0x85, 0x2, + 0xe2, 0x0, 0xb, 0x50, 0xd, 0x11, 0xd3, 0xd9, + 0xee, 0xee, 0xcc, 0x70, 0xd1, 0xc, 0x62, 0x0, + 0x0, 0x0, 0x7, 0xd, 0x10, 0xc3, 0x9a, 0xaa, + 0xaa, 0xaa, 0x30, 0xd2, 0xce, 0x2, 0x33, 0x7c, + 0x33, 0x31, 0xd, 0x12, 0x0, 0x59, 0x4, 0xb0, + 0x76, 0x0, 0xd1, 0x0, 0x1e, 0x30, 0x4b, 0x1, + 0xd2, 0xd, 0x10, 0xa, 0x80, 0x5, 0xb0, 0x5, + 0xc0, 0xd1, 0x0, 0x10, 0xe, 0xe7, 0x0, 0x1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+969C "障" */ + 0x0, 0x0, 0x0, 0x0, 0x44, 0x0, 0x0, 0xe, + 0xff, 0xfa, 0x0, 0x5, 0xb0, 0x0, 0x0, 0xe1, + 0x9, 0x78, 0xde, 0xdd, 0xee, 0xd7, 0xe, 0x11, + 0xe1, 0x0, 0xd0, 0x5, 0xb0, 0x0, 0xe1, 0x6a, + 0x28, 0x8d, 0xa8, 0xdc, 0x88, 0x1e, 0x1d, 0x31, + 0x44, 0x44, 0x44, 0x44, 0x40, 0xe1, 0x6b, 0x1, + 0xcc, 0xcc, 0xcc, 0xb0, 0xe, 0x10, 0xb4, 0x1e, + 0x0, 0x0, 0x1e, 0x0, 0xe1, 0x6, 0x91, 0xfb, + 0xbb, 0xbc, 0xe0, 0xe, 0x10, 0x4b, 0x1e, 0x0, + 0x0, 0x1e, 0x0, 0xe3, 0x7c, 0x71, 0xcc, 0xcf, + 0xcc, 0xb0, 0xe, 0x17, 0x50, 0x0, 0x1, 0xe0, + 0x0, 0x0, 0xe1, 0x0, 0x4e, 0xee, 0xef, 0xee, + 0xee, 0x4e, 0x10, 0x0, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0xe1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, + 0x0, + + /* U+96A3 "隣" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0xe, + 0xff, 0xf3, 0x2b, 0x1, 0xe0, 0x4c, 0x0, 0xe1, + 0xe, 0x0, 0x87, 0x1e, 0xc, 0x10, 0xe, 0x15, + 0x94, 0xcd, 0xdd, 0xfc, 0xdc, 0xa0, 0xe1, 0xa3, + 0x1, 0x16, 0xef, 0xd4, 0x11, 0xe, 0x1d, 0x0, + 0x18, 0xd3, 0xe2, 0xd6, 0x0, 0xe1, 0x97, 0x3e, + 0xa1, 0x1e, 0x1, 0x9c, 0xe, 0x11, 0xe0, 0x38, + 0x11, 0xe0, 0x1b, 0x0, 0xe1, 0xd, 0x12, 0xf2, + 0x22, 0x23, 0xe2, 0xe, 0x10, 0xc2, 0xac, 0xbf, + 0x7b, 0xbf, 0xa0, 0xe3, 0x8f, 0x8c, 0x12, 0xd4, + 0x91, 0xd0, 0xe, 0x27, 0x37, 0x4d, 0xb6, 0x57, + 0x1d, 0x0, 0xe1, 0x0, 0x0, 0x6c, 0x7, 0xde, + 0xfd, 0x1e, 0x10, 0x0, 0x5c, 0x10, 0x0, 0x1d, + 0x0, 0xe1, 0x0, 0x7a, 0x10, 0x0, 0x1, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+96A8 "隨" */ + 0x0, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0xe, + 0xff, 0xf7, 0x0, 0x3, 0xd0, 0x0, 0x0, 0xe0, + 0x1e, 0x77, 0x5c, 0xfd, 0xcc, 0xcc, 0x2e, 0x6, + 0x90, 0xd0, 0x1e, 0x21, 0x11, 0x0, 0xe0, 0xc3, + 0x6, 0xa, 0x8a, 0xbe, 0xa6, 0xe, 0x2d, 0x0, + 0x8, 0xb5, 0x57, 0xd5, 0x51, 0xe0, 0xd5, 0xbb, + 0x41, 0x55, 0x55, 0x55, 0x1e, 0x3, 0xd2, 0xe0, + 0xc, 0xbb, 0xbc, 0x50, 0xe0, 0xd, 0x1d, 0x1, + 0xd0, 0x0, 0x77, 0xe, 0x0, 0xb2, 0xd0, 0x1f, + 0xbb, 0xbd, 0x70, 0xe4, 0x9d, 0xd, 0x1, 0xe7, + 0x77, 0xb7, 0xe, 0x24, 0x10, 0xd0, 0x1e, 0x22, + 0x29, 0x70, 0xe0, 0x0, 0x1e, 0x41, 0xd0, 0x8, + 0xd5, 0xe, 0x0, 0x1d, 0xbc, 0xa5, 0x21, 0x22, + 0x31, 0xe0, 0x2, 0xa0, 0x4, 0xac, 0xdd, 0xdc, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+96BB "隻" */ + 0x0, 0x0, 0x81, 0x2, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xc0, 0x1, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0xdb, 0xbb, 0xed, 0xbb, 0xbb, 0x10, + 0x0, 0xbe, 0x11, 0x13, 0xe1, 0x11, 0x11, 0x0, + 0xa, 0xdf, 0xbb, 0xbb, 0xfb, 0xbb, 0xb5, 0x0, + 0x3c, 0x2e, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0xcc, 0xcc, 0xfc, 0xcc, 0xc6, 0x0, + 0x0, 0x1e, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0xcc, 0xcd, 0xfc, 0xcc, 0xcc, 0x40, + 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xee, 0xee, 0xee, 0xee, 0xee, 0xc0, 0x0, + 0x0, 0x0, 0xaa, 0x10, 0x0, 0x5e, 0x30, 0x0, + 0x0, 0x0, 0x6, 0xd8, 0x5c, 0xb2, 0x0, 0x0, + 0x0, 0x1, 0x37, 0xbf, 0xdf, 0x97, 0x41, 0x0, + 0xc, 0xfd, 0xb8, 0x30, 0x1, 0x6a, 0xcf, 0xd0, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+96C6 "集" */ + 0x0, 0x0, 0x81, 0x3, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xc0, 0x1, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0xfe, 0xee, 0xff, 0xee, 0xee, 0x20, + 0x2, 0xed, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x1d, 0xbf, 0xcc, 0xcc, 0xfc, 0xcc, 0xc6, 0x0, + 0x16, 0x3d, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0xcc, 0xcd, 0xfc, 0xcc, 0xc7, 0x0, + 0x0, 0x3d, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0xee, 0xee, 0xfe, 0xee, 0xee, 0x90, + 0x0, 0x15, 0x0, 0x8, 0x70, 0x0, 0x0, 0x0, + 0x1c, 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xcc, 0xc1, + 0x1, 0x11, 0x17, 0xed, 0xce, 0x61, 0x11, 0x10, + 0x0, 0x3, 0xbc, 0x29, 0x73, 0xdb, 0x30, 0x0, + 0x16, 0xcd, 0x60, 0x9, 0x70, 0x6, 0xcd, 0x81, + 0x2a, 0x40, 0x0, 0x9, 0x70, 0x0, 0x3, 0x80, + + /* U+96D1 "雑" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x0, 0x0, 0x6, 0x96, 0x90, 0x0, + 0x9, 0x9f, 0x99, 0x10, 0x1d, 0x10, 0xa2, 0x0, + 0x3, 0x5c, 0x3d, 0x11, 0xdf, 0xee, 0xee, 0xe2, + 0x0, 0x87, 0xc, 0x19, 0xc9, 0x1, 0xe0, 0x0, + 0x2, 0xe1, 0xc, 0x24, 0x69, 0x1, 0xe0, 0x0, + 0x2d, 0x50, 0x1a, 0xcd, 0x6d, 0xab, 0xfa, 0xa0, + 0x4, 0x1, 0xd0, 0x0, 0x6b, 0x34, 0xe3, 0x30, + 0x19, 0x9a, 0xe9, 0x95, 0x69, 0x1, 0xe0, 0x0, + 0x7, 0x78, 0xe7, 0x74, 0x69, 0x1, 0xe0, 0x0, + 0x0, 0x52, 0xd2, 0x30, 0x6f, 0xee, 0xfe, 0xe1, + 0x3, 0xc2, 0xd2, 0xd0, 0x69, 0x1, 0xe0, 0x0, + 0x1d, 0x31, 0xd0, 0x95, 0x69, 0x1, 0xe0, 0x0, + 0x5, 0x3, 0xd0, 0x10, 0x6e, 0xbc, 0xfb, 0xb3, + 0x0, 0x7f, 0x90, 0x0, 0x6b, 0x33, 0x33, 0x31, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+96D6 "雖" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0x30, 0x0, 0x0, + 0x9, 0xed, 0xde, 0xe0, 0xc, 0x3b, 0x50, 0x0, + 0x9, 0x60, 0x1, 0xe0, 0x1c, 0x2, 0xe1, 0x0, + 0x9, 0x60, 0x1, 0xe0, 0x7b, 0x88, 0xb8, 0x70, + 0x9, 0xee, 0xee, 0xe1, 0xe8, 0x78, 0xe7, 0x70, + 0x0, 0x4, 0xb0, 0x9, 0xf2, 0x2, 0xd0, 0x0, + 0x5, 0x69, 0xd6, 0x6c, 0xd2, 0x2, 0xd0, 0x0, + 0xd, 0x8a, 0xd8, 0xe1, 0xdf, 0xef, 0xfe, 0xb0, + 0xd, 0x3, 0xa0, 0xc1, 0xd2, 0x2, 0xd0, 0x0, + 0xd, 0x36, 0xc3, 0xd1, 0xd2, 0x2, 0xd0, 0x0, + 0x8, 0x9b, 0xe9, 0x90, 0xdf, 0xff, 0xff, 0xb0, + 0x0, 0x3, 0xb1, 0x80, 0xd2, 0x2, 0xd0, 0x0, + 0x0, 0x3, 0xc2, 0xe1, 0xd2, 0x2, 0xd0, 0x0, + 0x4c, 0xef, 0xdb, 0xc5, 0xdd, 0xcd, 0xfc, 0xc1, + 0x13, 0x10, 0x0, 0x35, 0xd4, 0x22, 0x22, 0x20, + + /* U+96D9 "雙" */ + 0x0, 0x4, 0x12, 0x0, 0x1, 0x30, 0x10, 0x0, + 0x0, 0x79, 0x3c, 0x0, 0x9, 0x74, 0xb0, 0x0, + 0x0, 0xea, 0x8e, 0x97, 0x1f, 0x98, 0xf9, 0x70, + 0x9, 0xf3, 0x3e, 0x32, 0xbe, 0x34, 0xe3, 0x30, + 0x3d, 0xfb, 0xbf, 0xbb, 0xcf, 0xbc, 0xfb, 0x60, + 0x1, 0xe0, 0xe, 0x1, 0x2d, 0x0, 0xd0, 0x0, + 0x0, 0xfb, 0xbf, 0xb5, 0xf, 0xbc, 0xfb, 0x60, + 0x0, 0xf5, 0x5f, 0x55, 0xe, 0x56, 0xe5, 0x50, + 0x0, 0x55, 0x55, 0x55, 0x5, 0x55, 0x55, 0x50, + 0x4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc3, 0x0, + 0x0, 0x24, 0xe9, 0x22, 0x22, 0x2b, 0xb0, 0x0, + 0x0, 0x0, 0x2d, 0xa2, 0x3, 0xca, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9f, 0xcf, 0x50, 0x0, 0x0, + 0x0, 0x24, 0x8c, 0xea, 0x8c, 0xfd, 0xa7, 0x40, + 0x1e, 0xda, 0x83, 0x0, 0x0, 0x16, 0x9b, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+96E2 "離" */ + 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xd0, 0x0, 0x1, 0xe4, 0x90, 0x0, + 0xc, 0xcc, 0xfd, 0xcc, 0x26, 0x90, 0xe2, 0x0, + 0x3, 0x42, 0x14, 0x44, 0xc, 0x62, 0x74, 0x20, + 0x5, 0x87, 0x8b, 0x69, 0x4f, 0xdd, 0xfd, 0xd1, + 0x5, 0x83, 0xca, 0x69, 0xdf, 0x10, 0xe0, 0x0, + 0x5, 0x87, 0x2, 0x79, 0x4e, 0x21, 0xe1, 0x10, + 0x4, 0xdc, 0xfd, 0xd7, 0xe, 0xdd, 0xfd, 0xc0, + 0x1, 0x11, 0xe2, 0x11, 0xe, 0x10, 0xe0, 0x0, + 0xd, 0xcd, 0xeb, 0xbf, 0x1e, 0x10, 0xe0, 0x0, + 0xd, 0x9, 0x46, 0xc, 0x1e, 0xff, 0xff, 0xd0, + 0xd, 0x2d, 0x2b, 0x2c, 0x1e, 0x10, 0xe0, 0x0, + 0xd, 0x6c, 0x97, 0x9c, 0x1e, 0x10, 0xe0, 0x0, + 0xd, 0x0, 0x0, 0xc, 0x1e, 0xdc, 0xfd, 0xc4, + 0xd, 0x0, 0x4, 0xdd, 0xe, 0x42, 0x22, 0x21, + 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, + + /* U+96E3 "難" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + 0x2d, 0xfe, 0xde, 0xfc, 0x6, 0x96, 0x90, 0x0, + 0x0, 0xb3, 0x6, 0x90, 0xc, 0x30, 0xe1, 0x0, + 0x0, 0xbf, 0xff, 0x90, 0x2f, 0xaa, 0xaa, 0xa2, + 0x0, 0x1, 0xc0, 0x0, 0xae, 0xaa, 0xfa, 0xa2, + 0xb, 0xcc, 0xfb, 0xda, 0xfb, 0x0, 0xe0, 0x0, + 0xb, 0x21, 0xc0, 0x7e, 0xac, 0x1, 0xe0, 0x0, + 0xa, 0xcc, 0xfb, 0xd6, 0x4f, 0xdd, 0xfd, 0xd0, + 0x0, 0x1, 0xd0, 0x0, 0x3b, 0x0, 0xe0, 0x0, + 0x9, 0xdd, 0xfd, 0xd7, 0x3b, 0x0, 0xe0, 0x0, + 0x0, 0x2, 0xd0, 0x0, 0x3e, 0xbb, 0xfb, 0xb0, + 0x3d, 0xde, 0xfd, 0xdd, 0x3c, 0x44, 0xf4, 0x40, + 0x0, 0xd, 0xc7, 0x0, 0x3b, 0x0, 0xe0, 0x0, + 0x1, 0xb7, 0x7, 0xc2, 0x3f, 0xcd, 0xfc, 0xc3, + 0x1c, 0x40, 0x0, 0x40, 0x3c, 0x22, 0x22, 0x20, + + /* U+96E8 "雨" */ + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x11, 0x11, 0x1a, 0x81, 0x11, 0x11, 0x0, + 0x5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, + 0x5, 0xa0, 0x0, 0x9, 0x70, 0x0, 0xa, 0x60, + 0x5, 0xa4, 0xc3, 0x9, 0x77, 0xa2, 0xa, 0x60, + 0x5, 0xa0, 0x3c, 0x79, 0x70, 0x4d, 0x5a, 0x60, + 0x5, 0xa0, 0x0, 0x19, 0x70, 0x0, 0x1a, 0x60, + 0x5, 0xa6, 0xa1, 0x9, 0x7b, 0x70, 0xa, 0x60, + 0x5, 0xa0, 0x5d, 0x59, 0x70, 0x8d, 0x3a, 0x60, + 0x5, 0xa0, 0x1, 0x39, 0x70, 0x3, 0x1a, 0x60, + 0x5, 0xa0, 0x0, 0x9, 0x70, 0x1, 0x1b, 0x60, + 0x5, 0xa0, 0x0, 0x8, 0x60, 0x1e, 0xec, 0x20, + + /* U+96EA "雪" */ + 0xd, 0xdd, 0xdd, 0xfe, 0xdd, 0xdd, 0x80, 0x0, + 0x0, 0x0, 0xe2, 0x0, 0x0, 0x0, 0xcd, 0xdd, + 0xdd, 0xfe, 0xdd, 0xdd, 0xd6, 0xe1, 0x0, 0x0, + 0xe2, 0x0, 0x0, 0x77, 0xe2, 0xcc, 0xc4, 0xe2, + 0xbc, 0xc8, 0x77, 0x80, 0x0, 0x0, 0xe2, 0x0, + 0x0, 0x44, 0x5, 0xcc, 0xc5, 0xe2, 0xbc, 0xcc, + 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, + 0x7, 0xee, 0xee, 0xee, 0xee, 0xed, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1f, 0x0, 0x1, 0xcc, + 0xcc, 0xcc, 0xcc, 0xdf, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0x0, 0xa, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdf, 0x0, + + /* U+96F2 "雲" */ + 0x0, 0xcd, 0xdd, 0xdf, 0xed, 0xdd, 0xdc, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0xa, 0xdd, 0xdd, 0xdf, 0xed, 0xdd, 0xdd, 0xa0, + 0xb, 0x30, 0x0, 0x9, 0x70, 0x0, 0x3, 0xb0, + 0xb, 0x3a, 0xbb, 0x69, 0x77, 0xbb, 0xa3, 0xb0, + 0x6, 0x20, 0x0, 0x9, 0x70, 0x0, 0x2, 0x60, + 0x0, 0x2c, 0xcc, 0x69, 0x77, 0xcc, 0xc3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4d, 0xdd, 0xdd, 0xdd, 0xdd, 0xd3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0xdd, 0xef, 0xed, 0xdd, 0xee, 0xdd, 0xd1, + 0x0, 0x0, 0x8c, 0x0, 0x0, 0xaa, 0x0, 0x0, + 0x0, 0x8, 0xd1, 0x0, 0x11, 0x3c, 0xc1, 0x0, + 0x0, 0x6f, 0xfe, 0xee, 0xdc, 0xba, 0xbc, 0x0, + 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, + + /* U+96FB "電" */ + 0xd, 0xdd, 0xdd, 0xfd, 0xdd, 0xdd, 0x80, 0x0, + 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, 0x0, 0xbc, + 0xcc, 0xcc, 0xfd, 0xcc, 0xcc, 0xc7, 0xe, 0x10, + 0x0, 0xe, 0x20, 0x0, 0x6, 0x80, 0xe1, 0xbb, + 0xb4, 0xe2, 0x9b, 0xb7, 0x68, 0x4, 0x37, 0x77, + 0x3e, 0x26, 0x77, 0x72, 0x20, 0x0, 0x11, 0x10, + 0x61, 0x11, 0x11, 0x0, 0x0, 0x7d, 0xdd, 0xdd, + 0xdd, 0xdd, 0xd3, 0x0, 0x8, 0x70, 0x0, 0xe1, + 0x0, 0xc, 0x40, 0x0, 0x8e, 0xcc, 0xcf, 0xcc, + 0xcc, 0xf4, 0x0, 0x8, 0x70, 0x0, 0xe1, 0x0, + 0xc, 0x40, 0x0, 0x8e, 0xcc, 0xcf, 0xdc, 0xcc, + 0xf4, 0x70, 0x6, 0x50, 0x0, 0xe2, 0x0, 0x0, + 0x1e, 0x0, 0x0, 0x0, 0x8, 0xee, 0xee, 0xee, + 0x80, + + /* U+9700 "需" */ + 0xb, 0xdd, 0xdd, 0xfe, 0xdd, 0xdd, 0xb0, 0x0, + 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, 0xad, 0xcc, + 0xcc, 0xee, 0xcc, 0xcc, 0xda, 0xb4, 0x0, 0x0, + 0x87, 0x0, 0x0, 0x4b, 0xb4, 0xab, 0xb6, 0x87, + 0x7b, 0xba, 0x4b, 0x22, 0x77, 0x74, 0x87, 0x57, + 0x77, 0x32, 0x0, 0x22, 0x21, 0x44, 0x12, 0x22, + 0x0, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0x0, 0x0, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x8, + 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xc0, 0xa, 0x61, + 0x3d, 0x11, 0xa7, 0x11, 0xf1, 0xa, 0x50, 0x2d, + 0x0, 0x96, 0x0, 0xf1, 0xa, 0x50, 0x2d, 0x0, + 0x96, 0x0, 0xf1, 0xa, 0x50, 0x2c, 0x0, 0x85, + 0x5e, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+9707 "震" */ + 0x0, 0xdd, 0xdd, 0xde, 0xed, 0xdd, 0xd9, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x60, 0x0, 0x0, 0x0, + 0xe, 0xcb, 0xbb, 0xbe, 0xdb, 0xbb, 0xbd, 0xa0, + 0xe, 0x15, 0x55, 0x39, 0x64, 0x55, 0x47, 0xa0, + 0xa, 0x4, 0x44, 0x29, 0x63, 0x44, 0x35, 0x70, + 0x0, 0x3a, 0xaa, 0x69, 0x67, 0xaa, 0xa1, 0x0, + 0x0, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x40, + 0x0, 0xf7, 0x55, 0x55, 0x55, 0x55, 0x55, 0x20, + 0x0, 0xf4, 0xbb, 0xbb, 0xbb, 0xbb, 0xb4, 0x0, + 0x1, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xfc, 0xee, 0xbb, 0xfc, 0xbb, 0xbc, 0xb2, + 0x5, 0xe0, 0x98, 0x0, 0x4d, 0x22, 0xb8, 0x0, + 0xb, 0x90, 0xa8, 0x0, 0x35, 0xcf, 0x60, 0x0, + 0x5d, 0x12, 0xfe, 0xdc, 0xa3, 0x5, 0xbe, 0xd1, + 0x12, 0x0, 0x52, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+9752 "青" */ + 0x0, 0x11, 0x11, 0x19, 0x81, 0x11, 0x11, 0x0, + 0x0, 0xcc, 0xcc, 0xce, 0xec, 0xcc, 0xcc, 0x20, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x5c, 0xcc, 0xce, 0xec, 0xcc, 0xc6, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0xd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0xdc, 0xcc, 0xcc, 0xcc, 0xe0, 0x0, + 0x0, 0xb, 0x40, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0xb, 0xdc, 0xcc, 0xcc, 0xcd, 0xe0, 0x0, + 0x0, 0xb, 0x40, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0xb, 0xdc, 0xcc, 0xcc, 0xcd, 0xe0, 0x0, + 0x0, 0xb, 0x40, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0xb, 0x40, 0x0, 0x7, 0xdd, 0x90, 0x0, + + /* U+9759 "静" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xe0, 0x0, 0x1, 0xe1, 0x0, 0x0, + 0xa, 0xcd, 0xfc, 0xc9, 0x9, 0xfd, 0xeb, 0x0, + 0x0, 0x1, 0xe0, 0x0, 0x4d, 0x0, 0xb5, 0x0, + 0x7, 0xcd, 0xfc, 0xc8, 0xf4, 0x4, 0xc0, 0x0, + 0x0, 0x1, 0xe0, 0x0, 0x9f, 0xff, 0xff, 0xd0, + 0x1d, 0xdd, 0xdd, 0xdc, 0x0, 0x1e, 0x1, 0xd0, + 0x0, 0x22, 0x22, 0x21, 0x22, 0x4e, 0x24, 0xe2, + 0x2, 0xea, 0xaa, 0xf5, 0xbb, 0xcf, 0xbc, 0xfa, + 0x2, 0xc2, 0x22, 0xe1, 0x0, 0x1e, 0x1, 0xd0, + 0x2, 0xea, 0xaa, 0xf1, 0x25, 0x6f, 0x57, 0xd0, + 0x2, 0xc1, 0x11, 0xd1, 0x38, 0x9f, 0x89, 0xd0, + 0x2, 0xea, 0xaa, 0xf1, 0x0, 0x1e, 0x0, 0x0, + 0x2, 0xc0, 0x0, 0xd1, 0x0, 0x2e, 0x0, 0x0, + 0x2, 0xc0, 0x6d, 0xd0, 0x1f, 0xf9, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+975E "非" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xe0, 0xc, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0x0, 0xc4, 0x0, 0x0, 0x9, 0xff, + 0xff, 0xe0, 0xc, 0xff, 0xff, 0xd0, 0x1, 0x11, + 0x3e, 0x0, 0xc5, 0x11, 0x11, 0x0, 0x0, 0x2, + 0xe0, 0xc, 0x40, 0x0, 0x0, 0x1, 0x11, 0x4e, + 0x0, 0xc5, 0x11, 0x11, 0x5, 0xee, 0xee, 0xe0, + 0xc, 0xfe, 0xee, 0x80, 0x0, 0x0, 0x2e, 0x0, + 0xc4, 0x0, 0x0, 0x0, 0x0, 0x2, 0xe0, 0xc, + 0x40, 0x0, 0x0, 0xee, 0xee, 0xfe, 0x0, 0xcf, + 0xee, 0xee, 0x21, 0x11, 0x14, 0xe0, 0xc, 0x62, + 0x22, 0x20, 0x0, 0x0, 0x2e, 0x0, 0xc4, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xe0, 0xc, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x2e, 0x0, 0xc4, 0x0, 0x0, + 0x0, + + /* U+9762 "面" */ + 0x1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, + 0xe, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe1, + 0x0, 0x0, 0x0, 0xe, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3e, 0x10, 0x0, 0x0, 0x0, + 0x4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, + 0x4, 0xb0, 0xd, 0x20, 0x4, 0xa0, 0xc, 0x40, + 0x4, 0xb0, 0xd, 0x30, 0x5, 0xa0, 0xc, 0x40, + 0x4, 0xb0, 0xd, 0xdd, 0xde, 0xa0, 0xc, 0x40, + 0x4, 0xb0, 0xd, 0x20, 0x4, 0xa0, 0xc, 0x40, + 0x4, 0xb0, 0xd, 0xbb, 0xbc, 0xa0, 0xc, 0x40, + 0x4, 0xb0, 0xd, 0x42, 0x26, 0xa0, 0xc, 0x40, + 0x4, 0xb0, 0xd, 0x20, 0x4, 0xa0, 0xc, 0x40, + 0x4, 0xfd, 0xdf, 0xdd, 0xde, 0xfd, 0xdf, 0x40, + 0x4, 0xc2, 0x22, 0x22, 0x22, 0x22, 0x2d, 0x40, + + /* U+9769 "革" */ + 0x0, 0x0, 0x78, 0x0, 0x0, 0x88, 0x0, 0x0, + 0xd, 0xee, 0xff, 0xee, 0xee, 0xff, 0xee, 0xd0, + 0x0, 0x0, 0x78, 0x0, 0x0, 0x88, 0x0, 0x0, + 0x0, 0x0, 0x7d, 0xaa, 0xaa, 0xd8, 0x0, 0x0, + 0x0, 0x0, 0x1, 0x19, 0x91, 0x10, 0x0, 0x0, + 0x0, 0x4c, 0xcc, 0xce, 0xec, 0xcc, 0xc6, 0x0, + 0x0, 0x5b, 0x11, 0x19, 0x91, 0x11, 0xa7, 0x0, + 0x0, 0x5b, 0x0, 0x8, 0x80, 0x0, 0x97, 0x0, + 0x0, 0x5f, 0xdd, 0xdf, 0xfd, 0xdd, 0xf7, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x19, 0x91, 0x11, 0x11, 0x10, + 0x2e, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe2, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + + /* U+9774 "靴" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd0, 0x1c, 0x0, 0x1d, 0xd, 0x20, 0x0, + 0xe, 0xfe, 0xef, 0xe0, 0x68, 0xd, 0x20, 0x0, + 0x0, 0xd0, 0x1c, 0x0, 0xb3, 0xd, 0x20, 0x40, + 0x0, 0xeb, 0xcc, 0x3, 0xf1, 0xd, 0x23, 0xe1, + 0x0, 0x9, 0x60, 0xc, 0xf1, 0xd, 0x4e, 0x40, + 0x9, 0xdf, 0xed, 0x9a, 0xe1, 0xd, 0xf6, 0x0, + 0xa, 0x27, 0x47, 0x61, 0xe1, 0x2e, 0x60, 0x0, + 0xa, 0x27, 0x47, 0x50, 0xe5, 0xef, 0x20, 0x0, + 0xa, 0xee, 0xee, 0x50, 0xe7, 0x3d, 0x20, 0x0, + 0x0, 0x8, 0x50, 0x0, 0xe1, 0xd, 0x20, 0x0, + 0x1b, 0xbe, 0xdb, 0xa0, 0xe1, 0xd, 0x20, 0x23, + 0x3, 0x3a, 0x73, 0x30, 0xe1, 0xd, 0x20, 0x39, + 0x0, 0x8, 0x50, 0x0, 0xe1, 0xc, 0x40, 0x78, + 0x0, 0x8, 0x50, 0x0, 0xe1, 0x7, 0xef, 0xd2, + 0x0, 0x1, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + + /* U+97F3 "音" */ + 0x0, 0x0, 0x0, 0x6, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0, 0x0, + 0x2, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0x40, + 0x0, 0x0, 0xa3, 0x0, 0x0, 0x2c, 0x10, 0x0, + 0x0, 0x0, 0x7a, 0x0, 0x0, 0x8a, 0x0, 0x0, + 0x0, 0x0, 0x3e, 0x10, 0x1, 0xe3, 0x0, 0x0, + 0x1e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xee, 0xee, 0xee, 0xee, 0xe0, 0x0, + 0x0, 0xd, 0x30, 0x0, 0x0, 0x1, 0xf0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x0, 0x1, 0xf0, 0x0, + 0x0, 0xd, 0xee, 0xee, 0xee, 0xee, 0xf0, 0x0, + 0x0, 0xd, 0x20, 0x0, 0x0, 0x1, 0xf0, 0x0, + 0x0, 0xd, 0x30, 0x0, 0x0, 0x2, 0xf0, 0x0, + 0x0, 0xd, 0xed, 0xdd, 0xdd, 0xdd, 0xf0, 0x0, + + /* U+97FF "響" */ + 0x0, 0x5, 0x0, 0x7, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x95, 0x53, 0xea, 0xad, 0x5e, 0xcd, 0xe0, + 0x7, 0xb4, 0x82, 0xb0, 0x8, 0x5e, 0x5, 0x70, + 0x7, 0xaa, 0x15, 0xea, 0xad, 0x5e, 0xd, 0x10, + 0x8, 0xe7, 0xb9, 0xd5, 0x5b, 0x5e, 0x4, 0xa0, + 0x6, 0x58, 0xc3, 0xc4, 0x8e, 0x2e, 0x0, 0xb2, + 0x1, 0x8b, 0x18, 0xfc, 0xa7, 0x9e, 0x5c, 0xb0, + 0xc, 0x50, 0x2, 0x18, 0x80, 0x8, 0x0, 0x0, + 0x0, 0x6c, 0xde, 0xcc, 0xcc, 0xed, 0xc9, 0x0, + 0x0, 0x0, 0x1d, 0x10, 0x1, 0xd2, 0x0, 0x0, + 0x1c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc2, + 0x0, 0x6, 0x88, 0x88, 0x88, 0x88, 0x80, 0x0, + 0x0, 0xd, 0x53, 0x33, 0x33, 0x33, 0xf0, 0x0, + 0x0, 0xd, 0xa9, 0x99, 0x99, 0x99, 0xf0, 0x0, + 0x0, 0xd, 0xba, 0xaa, 0xaa, 0xaa, 0xf0, 0x0, + + /* U+9803 "頃" */ + 0xf, 0x0, 0xc, 0xee, 0xef, 0xfe, 0xee, 0x10, + 0xf0, 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0xf, + 0x0, 0x0, 0x0, 0x3e, 0x0, 0x0, 0x0, 0xf0, + 0x0, 0xe, 0xdd, 0xdd, 0xde, 0x80, 0xf, 0xcc, + 0xc4, 0xe1, 0x0, 0x0, 0x78, 0x0, 0xf0, 0x0, + 0xe, 0xdc, 0xcc, 0xce, 0x80, 0xf, 0x0, 0x0, + 0xe1, 0x0, 0x0, 0x88, 0x0, 0xf0, 0x0, 0xe, + 0x10, 0x0, 0x7, 0x80, 0xf, 0x0, 0x0, 0xed, + 0xdd, 0xdd, 0xe8, 0x1, 0xf4, 0x9d, 0x4e, 0x10, + 0x0, 0x7, 0x80, 0x7f, 0xb5, 0x0, 0xed, 0xdd, + 0xdd, 0xe8, 0x3, 0x20, 0x0, 0x0, 0x73, 0x2, + 0x60, 0x0, 0x0, 0x0, 0x6, 0xda, 0x10, 0x19, + 0xd4, 0x0, 0x0, 0xb, 0xa3, 0x0, 0x0, 0x4, + 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+9805 "項" */ + 0x0, 0x0, 0x0, 0x9e, 0xee, 0xff, 0xee, 0xe8, + 0x1d, 0xdd, 0xdd, 0x30, 0x0, 0xd6, 0x0, 0x0, + 0x6, 0x6f, 0x76, 0x10, 0x0, 0xf1, 0x0, 0x0, + 0x0, 0xf, 0x10, 0xd, 0xed, 0xdd, 0xde, 0xe0, + 0x0, 0xf, 0x10, 0xd, 0x30, 0x0, 0x1, 0xe0, + 0x0, 0xf, 0x10, 0xd, 0xcb, 0xbb, 0xbc, 0xe0, + 0x0, 0xf, 0x10, 0xd, 0x40, 0x0, 0x2, 0xe0, + 0x0, 0xf, 0x10, 0xd, 0x30, 0x0, 0x1, 0xe0, + 0x0, 0xf, 0x36, 0x6d, 0xdd, 0xdd, 0xdd, 0xe0, + 0x3, 0x8f, 0xd8, 0x2d, 0x30, 0x0, 0x1, 0xe0, + 0x3c, 0x72, 0x0, 0xd, 0xdc, 0xcc, 0xcd, 0xe0, + 0x0, 0x0, 0x0, 0x0, 0x55, 0x1, 0x72, 0x0, + 0x0, 0x0, 0x0, 0x4b, 0xc3, 0x0, 0x7e, 0x70, + 0x0, 0x0, 0x9, 0xb5, 0x0, 0x0, 0x1, 0xb7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9808 "須" */ + 0x0, 0x0, 0x52, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xe1, 0xde, 0xee, 0xfe, 0xee, 0xe1, + 0x0, 0x7e, 0x20, 0x0, 0x3, 0xf0, 0x0, 0x0, + 0x1b, 0xd2, 0x0, 0x0, 0x6, 0xb0, 0x0, 0x0, + 0x29, 0x0, 0x0, 0x2f, 0xdd, 0xdd, 0xde, 0x80, + 0x0, 0x0, 0x55, 0x2d, 0x0, 0x0, 0x8, 0x80, + 0x0, 0x5, 0xe2, 0x2f, 0xcc, 0xcc, 0xce, 0x80, + 0x0, 0x7e, 0x30, 0x2d, 0x0, 0x0, 0x8, 0x80, + 0x1c, 0xd2, 0x0, 0x2d, 0x0, 0x0, 0x8, 0x80, + 0x6, 0x0, 0x0, 0x2f, 0xcc, 0xcc, 0xce, 0x80, + 0x0, 0x0, 0x4d, 0x3d, 0x0, 0x0, 0x8, 0x80, + 0x0, 0x3, 0xe2, 0x2f, 0xdd, 0xdd, 0xde, 0x80, + 0x0, 0x6e, 0x40, 0x0, 0x61, 0x1, 0x50, 0x0, + 0x2c, 0xd2, 0x0, 0x5d, 0xa1, 0x2, 0xbc, 0x30, + 0x17, 0x0, 0xc, 0xa3, 0x0, 0x0, 0x5, 0xe2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9817 "頗" */ + 0x0, 0x0, 0xe0, 0x3, 0xee, 0xef, 0xee, 0xe0, + 0x6, 0x99, 0xf9, 0x97, 0x0, 0x3d, 0x0, 0x0, + 0xb, 0xb9, 0xf9, 0xb9, 0x0, 0x6a, 0x0, 0x0, + 0xb, 0x30, 0xe0, 0x86, 0xcd, 0xdd, 0xde, 0x90, + 0xb, 0x30, 0xe0, 0x71, 0xc2, 0x0, 0x5, 0x90, + 0xb, 0xee, 0xfe, 0xe2, 0xcd, 0xcc, 0xcd, 0x90, + 0xb, 0x30, 0x0, 0xe0, 0xc3, 0x0, 0x6, 0x90, + 0xc, 0x5b, 0x4, 0xb0, 0xc2, 0x0, 0x5, 0x90, + 0xc, 0x18, 0xa9, 0x50, 0xcd, 0xdd, 0xde, 0x90, + 0xd, 0x0, 0x9f, 0x0, 0xc2, 0x0, 0x5, 0x90, + 0xe, 0x0, 0xcd, 0x80, 0xcd, 0xdd, 0xde, 0x90, + 0x3b, 0x9, 0xa0, 0xd3, 0x6, 0x30, 0x52, 0x0, + 0x98, 0xcb, 0x0, 0x11, 0xac, 0x20, 0x5e, 0x40, + 0x31, 0x60, 0x0, 0x1d, 0x70, 0x0, 0x3, 0xd1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9818 "領" */ + 0x0, 0x1, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x80, 0xd, 0xee, 0xff, 0xee, 0xe1, + 0x0, 0x2b, 0xb2, 0x0, 0x0, 0x98, 0x0, 0x0, + 0x0, 0xb1, 0x1c, 0x20, 0x0, 0xc4, 0x0, 0x0, + 0xa, 0x50, 0x2, 0xd5, 0xfd, 0xdd, 0xde, 0x90, + 0x67, 0xd, 0x10, 0x34, 0xb0, 0x0, 0x6, 0x90, + 0x0, 0x6, 0xb0, 0x4, 0xfc, 0xcc, 0xce, 0x90, + 0x0, 0x0, 0x40, 0x4, 0xb0, 0x0, 0x6, 0x90, + 0xd, 0xff, 0xff, 0xb4, 0xb0, 0x0, 0x6, 0x90, + 0x1, 0x11, 0x19, 0x64, 0xfd, 0xdd, 0xde, 0x90, + 0x0, 0x0, 0x2d, 0x4, 0xb0, 0x0, 0x6, 0x90, + 0x1, 0xd4, 0xc5, 0x4, 0xfd, 0xdd, 0xde, 0x90, + 0x0, 0x3e, 0xb0, 0x0, 0x17, 0x0, 0x61, 0x0, + 0x0, 0x2, 0xe3, 0x5, 0xe8, 0x0, 0x7e, 0x40, + 0x0, 0x0, 0x41, 0xab, 0x30, 0x0, 0x3, 0xd2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+982D "頭" */ + 0x0, 0x0, 0x0, 0x0, 0x11, 0x11, 0x11, 0x10, + 0x2f, 0xff, 0xff, 0xf7, 0xcc, 0xdf, 0xcc, 0xc5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x11, 0x8a, 0x11, 0x10, + 0xa, 0xee, 0xee, 0xb0, 0xdc, 0xcc, 0xcc, 0xe0, + 0xa, 0x30, 0x3, 0xc0, 0xd2, 0x0, 0x1, 0xe0, + 0xa, 0x30, 0x3, 0xc0, 0xdd, 0xcc, 0xcd, 0xe0, + 0xa, 0xcb, 0xbc, 0xc0, 0xd2, 0x0, 0x1, 0xe0, + 0x3, 0x55, 0x55, 0x40, 0xd2, 0x0, 0x1, 0xe0, + 0x2, 0xa0, 0xd, 0x10, 0xdd, 0xcc, 0xcd, 0xe0, + 0x0, 0xe1, 0x1e, 0x0, 0xd2, 0x0, 0x1, 0xe0, + 0x0, 0xb2, 0x58, 0x10, 0xdd, 0xdd, 0xdd, 0xe0, + 0x0, 0x37, 0xae, 0xd3, 0x6, 0x20, 0x33, 0x0, + 0x3f, 0xc8, 0x51, 0x3, 0xbb, 0x10, 0x3d, 0x80, + 0x0, 0x0, 0x0, 0x5d, 0x50, 0x0, 0x0, 0xb6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+983C "頼" */ + 0x0, 0x3, 0xb0, 0x5, 0xee, 0xff, 0xfe, 0xe7, + 0x1d, 0xde, 0xfd, 0xd6, 0x0, 0x2f, 0x0, 0x0, + 0x5, 0x58, 0xd5, 0x52, 0x0, 0x5c, 0x0, 0x0, + 0x0, 0x4, 0xb0, 0x0, 0xae, 0xdd, 0xdd, 0xe0, + 0xc, 0xbc, 0xeb, 0xd5, 0xa5, 0x0, 0x1, 0xe0, + 0xc, 0x13, 0xa0, 0x85, 0xad, 0xcc, 0xcc, 0xe0, + 0xc, 0x13, 0xa0, 0x85, 0xa6, 0x0, 0x2, 0xe0, + 0xc, 0xee, 0xfe, 0xf5, 0xa5, 0x0, 0x1, 0xe0, + 0x1, 0x2d, 0xe4, 0x10, 0xae, 0xdd, 0xdd, 0xe0, + 0x0, 0x6d, 0xdd, 0x50, 0xa5, 0x0, 0x1, 0xe0, + 0x2, 0xd5, 0xb1, 0xd3, 0xae, 0xcc, 0xcd, 0xe0, + 0x2e, 0x43, 0xb0, 0x0, 0x6, 0x40, 0x35, 0x0, + 0x25, 0x3, 0xb0, 0x2, 0xad, 0x20, 0x2c, 0x90, + 0x0, 0x3, 0xb0, 0x2d, 0x60, 0x0, 0x0, 0x98, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+984C "題" */ + 0x4, 0xfc, 0xcd, 0xf1, 0xdd, 0xdd, 0xdd, 0xc0, + 0x4, 0xb0, 0x0, 0xf0, 0x0, 0x59, 0x0, 0x0, + 0x4, 0xec, 0xcc, 0xf0, 0x59, 0xdb, 0x99, 0x20, + 0x4, 0xb0, 0x0, 0xf0, 0x88, 0x22, 0x2c, 0x30, + 0x4, 0xfc, 0xcc, 0xf0, 0x8c, 0x99, 0x9e, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x88, 0x22, 0x2c, 0x30, + 0x15, 0x55, 0x55, 0x55, 0x87, 0x11, 0x1c, 0x30, + 0x28, 0x88, 0xf8, 0x88, 0x8c, 0xaa, 0xae, 0x30, + 0x1, 0x80, 0xe0, 0x0, 0x88, 0x22, 0x2c, 0x30, + 0x3, 0xc0, 0xfd, 0xd9, 0x49, 0x98, 0x98, 0x20, + 0x5, 0xe1, 0xe0, 0x0, 0x1c, 0x40, 0xb7, 0x0, + 0x7, 0xbb, 0xe0, 0x4, 0xd5, 0x0, 0xa, 0x90, + 0xc, 0x36, 0xe7, 0x34, 0x20, 0x0, 0x0, 0x50, + 0x3c, 0x0, 0x18, 0xbe, 0xee, 0xee, 0xee, 0xd0, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9854 "顔" */ + 0x0, 0x3, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x11, 0xe3, 0x11, 0xee, 0xef, 0xee, 0xe2, + 0xf, 0xff, 0xff, 0xfd, 0x0, 0xf, 0x10, 0x0, + 0x1, 0xa4, 0x14, 0xa1, 0x0, 0x2d, 0x0, 0x0, + 0x0, 0x87, 0x8, 0x70, 0x7e, 0xdd, 0xdd, 0xe0, + 0x4, 0x9b, 0x6e, 0x86, 0x77, 0x0, 0x1, 0xe0, + 0xb, 0x85, 0x57, 0x75, 0x7e, 0xcc, 0xcd, 0xe0, + 0xb, 0x30, 0x4d, 0x40, 0x77, 0x0, 0x1, 0xe0, + 0xb, 0x6b, 0xb2, 0x0, 0x77, 0x0, 0x1, 0xe0, + 0xc, 0x33, 0x4, 0x90, 0x7e, 0xdd, 0xdd, 0xe0, + 0xd, 0x24, 0xaa, 0x10, 0x77, 0x0, 0x1, 0xe0, + 0xe, 0x28, 0x20, 0x77, 0x7e, 0xdd, 0xdd, 0xe0, + 0x2c, 0x0, 0x9, 0xc0, 0x4, 0x50, 0x44, 0x0, + 0x77, 0x18, 0xd8, 0x0, 0x8e, 0x30, 0x2d, 0x80, + 0x12, 0x67, 0x10, 0xc, 0x91, 0x0, 0x1, 0xc4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9858 "願" */ + 0xb, 0xfe, 0xff, 0xfe, 0x9e, 0xef, 0xfe, 0xe3, + 0xb, 0x30, 0x2e, 0x0, 0x0, 0xd, 0x30, 0x0, + 0xb, 0x30, 0x4a, 0x0, 0x0, 0x1f, 0x10, 0x0, + 0xb, 0x3e, 0xcc, 0xce, 0x1f, 0xcc, 0xcc, 0xc0, + 0xb, 0x3d, 0x0, 0xe, 0x1d, 0x0, 0x2, 0xc0, + 0xb, 0x3e, 0xbb, 0xbe, 0x1f, 0xcc, 0xcd, 0xc0, + 0xc, 0x2d, 0x0, 0xe, 0x1d, 0x0, 0x2, 0xc0, + 0xc, 0x2d, 0x0, 0xe, 0x1d, 0x0, 0x2, 0xc0, + 0xd, 0x1c, 0xdf, 0xdb, 0x1f, 0xcc, 0xcc, 0xc0, + 0xe, 0x5, 0xe, 0x13, 0x1d, 0x0, 0x2, 0xc0, + 0xe, 0xd, 0xe, 0x1d, 0x1f, 0xcc, 0xcd, 0xc0, + 0x3b, 0x69, 0xe, 0xa, 0x31, 0x60, 0x25, 0x0, + 0x87, 0x62, 0xe, 0x1, 0x3d, 0x80, 0x1c, 0x80, + 0x52, 0x4, 0xdb, 0x3, 0xd4, 0x0, 0x0, 0xb4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+985E "類" */ + 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x7, 0x62, 0xc0, 0xd6, 0xee, 0xff, 0xfe, 0xe6, + 0x2, 0xd2, 0xc3, 0xa0, 0x0, 0x3e, 0x0, 0x0, + 0x6, 0x78, 0xe7, 0x74, 0x0, 0x6a, 0x0, 0x0, + 0x8, 0x9e, 0xf9, 0x85, 0xae, 0xdd, 0xdd, 0xe0, + 0x0, 0x8c, 0xec, 0x40, 0xa4, 0x0, 0x1, 0xe0, + 0x1b, 0xd3, 0xc1, 0xc7, 0xad, 0xcc, 0xcd, 0xe0, + 0x1b, 0x12, 0xc0, 0x1, 0xa5, 0x0, 0x1, 0xe0, + 0x0, 0x1, 0x84, 0x90, 0xa4, 0x0, 0x1, 0xe0, + 0x3, 0x35, 0xd3, 0x95, 0xae, 0xdd, 0xdd, 0xe0, + 0x8, 0x8a, 0xd8, 0x86, 0xa4, 0x0, 0x1, 0xe0, + 0x0, 0x8, 0xf5, 0x0, 0xae, 0xdd, 0xdd, 0xe0, + 0x0, 0x3d, 0x3c, 0x90, 0x5, 0x30, 0x34, 0x0, + 0x7, 0xe4, 0x0, 0xa4, 0x9d, 0x20, 0x2d, 0x90, + 0x8, 0x10, 0x0, 0x1d, 0x70, 0x0, 0x0, 0xa7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+986F "顯" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xcb, 0xbb, 0xbe, 0x6e, 0xef, 0xfe, 0xe1, + 0xc, 0x20, 0x0, 0xe, 0x0, 0xd, 0x30, 0x0, + 0xc, 0xcb, 0xbb, 0xbe, 0x0, 0xf, 0x0, 0x0, + 0xc, 0x42, 0x22, 0x2e, 0xf, 0xdd, 0xdd, 0xc0, + 0xb, 0xb9, 0x9a, 0xad, 0xe, 0x0, 0x1, 0xc0, + 0x3, 0xa0, 0x3, 0xa0, 0xf, 0xdd, 0xdd, 0xc0, + 0xa, 0x2b, 0x1b, 0x2c, 0x1e, 0x0, 0x1, 0xc0, + 0x4f, 0xd9, 0x5f, 0xe8, 0xe, 0x0, 0x1, 0xc0, + 0x4, 0xb4, 0x4, 0xa4, 0xf, 0xdd, 0xdd, 0xc0, + 0x2e, 0x8d, 0x6e, 0x9c, 0x8e, 0x0, 0x1, 0xc0, + 0x15, 0x23, 0x44, 0x33, 0x6f, 0xdd, 0xdd, 0xc0, + 0xa, 0x3b, 0x2b, 0x1d, 0x0, 0x51, 0x4, 0x0, + 0x1d, 0xc, 0x1c, 0x7, 0x4a, 0xb1, 0x1c, 0x80, + 0x67, 0x8, 0x23, 0x0, 0xc7, 0x0, 0x0, 0xc3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+98A8 "風" */ + 0x0, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x0, + 0x0, 0xb5, 0x0, 0x0, 0x1, 0x30, 0xc3, 0x0, + 0x0, 0xb6, 0x79, 0xac, 0xed, 0xa1, 0xc3, 0x0, + 0x0, 0xb5, 0x54, 0x3e, 0x10, 0x0, 0xc3, 0x0, + 0x0, 0xb4, 0x0, 0xe, 0x10, 0x0, 0xc3, 0x0, + 0x0, 0xb4, 0xce, 0xef, 0xee, 0xe0, 0xc3, 0x0, + 0x0, 0xc4, 0xe0, 0xe, 0x10, 0xe0, 0xb4, 0x0, + 0x0, 0xd3, 0xe0, 0xe, 0x10, 0xe0, 0xb4, 0x0, + 0x0, 0xf1, 0xe2, 0x2e, 0x32, 0xe0, 0xa5, 0x0, + 0x0, 0xf0, 0xab, 0xbf, 0xcb, 0xb0, 0x95, 0x0, + 0x4, 0xb0, 0x0, 0xe, 0x14, 0x70, 0x87, 0x0, + 0x9, 0x70, 0x0, 0x1e, 0x44, 0xe4, 0x59, 0x90, + 0x2e, 0x1a, 0xff, 0xed, 0xba, 0xad, 0x2d, 0xb0, + 0x58, 0x0, 0x0, 0x0, 0x0, 0x6, 0xa, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+98DB "飛" */ + 0x1, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x8, 0x60, + 0x0, 0x0, 0x0, 0x2, 0x0, 0x4b, 0x6b, 0x0, + 0x0, 0x2, 0x8e, 0x4d, 0x20, 0x1f, 0xf6, 0x0, + 0x7, 0xdf, 0xa2, 0xd, 0x20, 0xd, 0x59, 0xc0, + 0x2, 0x1a, 0x50, 0xd, 0x20, 0x8, 0xa0, 0x21, + 0x0, 0xa, 0x50, 0xd, 0x20, 0x0, 0xc9, 0x95, + 0x2c, 0xce, 0xdc, 0xcf, 0xdc, 0xc9, 0x6, 0x90, + 0x3, 0x3c, 0x63, 0x3e, 0x53, 0x5d, 0x7, 0x80, + 0x0, 0xd, 0x30, 0xd, 0x20, 0x1e, 0x8b, 0x0, + 0x0, 0x1f, 0x0, 0xd, 0x20, 0xf, 0xea, 0x20, + 0x0, 0x5c, 0x0, 0xd, 0x20, 0xd, 0x36, 0xd0, + 0x0, 0xd5, 0x0, 0xd, 0x20, 0x8, 0x80, 0x2, + 0x9, 0xc0, 0x0, 0xd, 0x20, 0x1, 0xe4, 0x38, + 0x2d, 0x10, 0x0, 0xd, 0x20, 0x0, 0x4c, 0xf4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+98DF "食" */ + 0x0, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8c, 0x6d, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x1b, 0xb7, 0x23, 0xd9, 0x10, 0x0, + 0x0, 0x18, 0xe7, 0x5, 0xc0, 0x8, 0xe8, 0x20, + 0xa, 0xfc, 0xfe, 0xee, 0xee, 0xee, 0xf9, 0xe9, + 0x3, 0x14, 0xc0, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0x4, 0xfd, 0xdd, 0xdd, 0xdd, 0xe0, 0x0, + 0x0, 0x4, 0xc0, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0x4, 0xd2, 0x22, 0x22, 0x24, 0xe0, 0x0, + 0x0, 0x4, 0xfb, 0xbb, 0xbb, 0xbb, 0xc9, 0x10, + 0x0, 0x4, 0xc0, 0x6, 0xa2, 0x5, 0xd6, 0x0, + 0x0, 0x4, 0xc0, 0x0, 0x6e, 0xdd, 0x20, 0x0, + 0x0, 0x5, 0xc1, 0x47, 0x70, 0x7e, 0x90, 0x0, + 0x0, 0xa, 0xfe, 0xb7, 0x30, 0x1, 0xae, 0x20, + 0x0, 0x3, 0x20, 0x0, 0x0, 0x0, 0x3, 0x0, + + /* U+98EF "飯" */ + 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xf3, 0x0, 0x1, 0x35, 0x8c, 0x90, + 0x0, 0x6c, 0x4d, 0x50, 0xdc, 0xa8, 0x63, 0x0, + 0xa, 0xd3, 0x41, 0xd4, 0xd1, 0x0, 0x0, 0x0, + 0x2b, 0x1, 0xd0, 0x11, 0xd1, 0x0, 0x0, 0x0, + 0x1, 0xcc, 0xfd, 0xb0, 0xdf, 0xff, 0xff, 0xa0, + 0x1, 0xd0, 0x0, 0xe0, 0xdb, 0x40, 0x6, 0x80, + 0x1, 0xfc, 0xcc, 0xe0, 0xd7, 0x80, 0xa, 0x40, + 0x1, 0xd0, 0x0, 0xe0, 0xe2, 0xd0, 0xe, 0x10, + 0x1, 0xd2, 0x22, 0xe0, 0xe0, 0xc3, 0x4c, 0x0, + 0x1, 0xfb, 0xbb, 0xa0, 0xe0, 0x5a, 0xb4, 0x0, + 0x1, 0xd0, 0xa, 0x1, 0xd0, 0xd, 0xd0, 0x0, + 0x1, 0xd0, 0x1c, 0x54, 0x90, 0x1d, 0xd1, 0x0, + 0x3, 0xea, 0xc7, 0xc8, 0x61, 0xc7, 0x8c, 0x10, + 0xa, 0xb4, 0x0, 0x4d, 0x2e, 0x80, 0x8, 0xe3, + 0x0, 0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 0x30, + + /* U+98F2 "飲" */ + 0x0, 0x0, 0x60, 0x0, 0x3, 0x40, 0x0, 0x0, + 0x0, 0x9, 0xf5, 0x0, 0x9, 0x80, 0x0, 0x0, + 0x0, 0x7d, 0x3d, 0x90, 0xc, 0x50, 0x0, 0x0, + 0x1b, 0xd2, 0x50, 0xba, 0xf, 0xa8, 0x88, 0x81, + 0x2a, 0x0, 0xe0, 0x3, 0x4e, 0x77, 0x77, 0xf1, + 0x1, 0xdd, 0xfd, 0xd1, 0xb7, 0x14, 0x2, 0xd0, + 0x1, 0xe0, 0x0, 0xe5, 0xe1, 0x3d, 0x5, 0x90, + 0x1, 0xfc, 0xcc, 0xf1, 0x20, 0x4d, 0x5, 0x40, + 0x1, 0xe0, 0x0, 0xe1, 0x0, 0x6f, 0x0, 0x0, + 0x1, 0xe2, 0x22, 0xe1, 0x0, 0x9f, 0x40, 0x0, + 0x1, 0xfb, 0xbb, 0xb0, 0x0, 0xec, 0x90, 0x0, + 0x1, 0xe0, 0xa, 0x0, 0x6, 0xe1, 0xe0, 0x0, + 0x1, 0xe0, 0x1b, 0x80, 0x1e, 0x60, 0x99, 0x0, + 0x3, 0xfa, 0xd7, 0xe2, 0xca, 0x0, 0x2f, 0x50, + 0xa, 0xb4, 0x0, 0x7f, 0xa0, 0x0, 0x4, 0xf5, + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x20, + + /* U+9928 "館" */ + 0x0, 0x0, 0x80, 0x0, 0x0, 0x15, 0x0, 0x0, + 0x0, 0xb, 0xe5, 0x0, 0x0, 0xd, 0x0, 0x0, + 0x0, 0x9a, 0x1c, 0x82, 0xcc, 0xce, 0xcc, 0xc0, + 0x1c, 0xb3, 0x60, 0xba, 0xa1, 0x11, 0x11, 0xc1, + 0x18, 0x1, 0xd0, 0x3, 0x85, 0x55, 0x55, 0x90, + 0x1, 0xdd, 0xfd, 0xb0, 0x2e, 0xbb, 0xbd, 0x0, + 0x1, 0xc0, 0x0, 0xe0, 0x2b, 0x0, 0xd, 0x0, + 0x1, 0xe9, 0x99, 0xe0, 0x2b, 0x0, 0xd, 0x0, + 0x1, 0xd4, 0x44, 0xe0, 0x2f, 0xee, 0xec, 0x0, + 0x1, 0xe6, 0x66, 0xe0, 0x2b, 0x0, 0x0, 0x0, + 0x1, 0xd5, 0x56, 0x40, 0x2f, 0xee, 0xee, 0x70, + 0x1, 0xc0, 0xd, 0x10, 0x2b, 0x0, 0x6, 0x70, + 0x1, 0xc0, 0x3d, 0x80, 0x2b, 0x0, 0x6, 0x70, + 0x4, 0xeb, 0xa5, 0xd0, 0x2c, 0x33, 0x38, 0x70, + 0x8, 0x71, 0x0, 0x61, 0x2e, 0xbb, 0xbc, 0x70, + + /* U+9996 "首" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x2, 0x0, 0x0, + 0x0, 0x1, 0xe5, 0x0, 0x0, 0x3f, 0x20, 0x0, + 0x0, 0x0, 0x4d, 0x10, 0x1, 0xd6, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x3d, 0xdd, 0xdf, 0xdd, 0xdd, 0xd3, 0x0, + 0x0, 0x3d, 0x22, 0x22, 0x22, 0x22, 0xd4, 0x0, + 0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0xd4, 0x0, + 0x0, 0x3f, 0xee, 0xee, 0xee, 0xee, 0xf4, 0x0, + 0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0xd4, 0x0, + 0x0, 0x3d, 0x11, 0x11, 0x11, 0x11, 0xd4, 0x0, + 0x0, 0x3f, 0xcc, 0xcc, 0xcc, 0xcc, 0xf4, 0x0, + 0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0xd4, 0x0, + 0x0, 0x3f, 0xdd, 0xdd, 0xdd, 0xdd, 0xf4, 0x0, + 0x0, 0x3d, 0x11, 0x11, 0x11, 0x11, 0xd4, 0x0, + + /* U+9999 "香" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, + 0x0, 0x2, 0x34, 0x67, 0x9b, 0xdf, 0xb1, 0x0, + 0x0, 0x8c, 0xba, 0x9c, 0xb4, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x1e, 0xee, 0xee, 0xef, 0xfe, 0xee, 0xee, 0xe1, + 0x0, 0x0, 0x5, 0xeb, 0xae, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x6e, 0x39, 0x82, 0xe8, 0x0, 0x0, + 0x0, 0x9, 0xe2, 0x9, 0x80, 0x1c, 0xb3, 0x0, + 0x6, 0xea, 0x10, 0x4, 0x40, 0x0, 0x7f, 0xa1, + 0x1b, 0x4b, 0xee, 0xee, 0xee, 0xee, 0xe1, 0x80, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0xb, 0xec, 0xcc, 0xcc, 0xcd, 0xe0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0xb, 0x50, 0x0, 0x0, 0x2, 0xe0, 0x0, + 0x0, 0xb, 0xed, 0xdd, 0xdd, 0xde, 0xe0, 0x0, + + /* U+99C4 "駄" */ + 0xc, 0xee, 0xfe, 0xe1, 0x0, 0x4c, 0x0, 0x0, + 0xc, 0x30, 0xe0, 0x0, 0x0, 0x4c, 0x0, 0x0, + 0xc, 0x41, 0xe0, 0x0, 0x0, 0x4c, 0x0, 0x0, + 0xc, 0xdc, 0xfc, 0x90, 0x0, 0x4c, 0x0, 0x0, + 0xc, 0x30, 0xe0, 0x7, 0xcc, 0xdf, 0xdc, 0xc4, + 0xc, 0xee, 0xfd, 0xa0, 0x0, 0x6f, 0x50, 0x0, + 0xc, 0x30, 0xe0, 0x0, 0x0, 0x9f, 0x80, 0x0, + 0xc, 0x42, 0xe1, 0x10, 0x0, 0xd8, 0xb0, 0x0, + 0x9, 0xcc, 0xcc, 0xf3, 0x1, 0xf1, 0xf0, 0x0, + 0x3, 0x23, 0x33, 0xc2, 0x8, 0xa0, 0xb5, 0x0, + 0xa, 0xa5, 0x5a, 0xe0, 0x1f, 0x90, 0x6b, 0x0, + 0x38, 0x83, 0x92, 0xf0, 0xab, 0x9b, 0x1e, 0x30, + 0x74, 0x31, 0x3, 0xd8, 0xe1, 0xb, 0x87, 0xd0, + 0x0, 0x1, 0xde, 0x7c, 0x30, 0x1, 0x10, 0xb3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+99C5 "駅" */ + 0x9, 0xfe, 0xfe, 0xe3, 0x2f, 0xff, 0xff, 0xe0, + 0x9, 0x50, 0xe0, 0x0, 0x2c, 0x0, 0x1, 0xe0, + 0x9, 0x61, 0xe1, 0x10, 0x2c, 0x0, 0x1, 0xe0, + 0x9, 0xdc, 0xfc, 0xc0, 0x2c, 0x0, 0x1, 0xe0, + 0x9, 0x50, 0xe0, 0x0, 0x2c, 0x0, 0x1, 0xe0, + 0x9, 0xed, 0xfd, 0xd0, 0x2d, 0x44, 0x45, 0xe0, + 0x9, 0x50, 0xe0, 0x0, 0x3e, 0x9d, 0xb9, 0x80, + 0x9, 0xca, 0xfa, 0xa3, 0x4b, 0x7, 0x80, 0x0, + 0x1, 0x22, 0x33, 0xb4, 0x69, 0x3, 0xb0, 0x0, + 0x8, 0x43, 0x48, 0xa3, 0x78, 0x0, 0xe1, 0x0, + 0xb, 0x63, 0x88, 0xd2, 0xa6, 0x0, 0x97, 0x0, + 0xa, 0x54, 0x70, 0xd1, 0xf1, 0x0, 0x2e, 0x10, + 0x55, 0x11, 0x1, 0xe8, 0xb0, 0x0, 0x9, 0xc1, + 0x0, 0x0, 0xbe, 0x7c, 0x20, 0x0, 0x0, 0xa4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9A12 "騒" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xee, 0xee, 0xd4, 0xef, 0xee, 0xef, 0x80, + 0x8, 0x60, 0xe0, 0x0, 0x5b, 0x0, 0x1e, 0x20, + 0x8, 0x71, 0xe1, 0x10, 0xc, 0x60, 0xc9, 0x0, + 0x8, 0xdc, 0xfc, 0x80, 0x1, 0xdb, 0xb0, 0x0, + 0x8, 0x60, 0xe0, 0x0, 0x39, 0xdb, 0xd8, 0x20, + 0x8, 0xed, 0xfd, 0x9c, 0xd7, 0x2a, 0x29, 0xe5, + 0x8, 0x60, 0xe0, 0x1, 0x44, 0x5f, 0x44, 0x40, + 0x8, 0xdb, 0xfb, 0xb4, 0xd7, 0x8f, 0x78, 0xd0, + 0x1, 0x22, 0x22, 0xe4, 0xb0, 0x1e, 0x1, 0xd0, + 0x3, 0x12, 0x44, 0xe3, 0xc3, 0x4f, 0x34, 0xd0, + 0xb, 0x75, 0x69, 0xe2, 0xaa, 0xbf, 0xaa, 0x90, + 0xb, 0x64, 0x94, 0xd0, 0x0, 0x1e, 0xb, 0x20, + 0x56, 0x22, 0x3, 0xb2, 0x35, 0x7f, 0x8c, 0xd0, + 0x0, 0x0, 0xcd, 0x58, 0xa8, 0x75, 0x42, 0x77, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9A13 "験" */ + 0x8, 0xfe, 0xfe, 0xe1, 0x0, 0x8f, 0x40, 0x0, + 0x8, 0x60, 0xe0, 0x0, 0x4, 0xb2, 0xe2, 0x0, + 0x8, 0x94, 0xe4, 0x30, 0x5d, 0x10, 0x4d, 0x30, + 0x8, 0xdb, 0xfb, 0x99, 0xd4, 0x22, 0x27, 0xe6, + 0x8, 0x60, 0xe0, 0x8, 0x1b, 0xbf, 0xba, 0x24, + 0x8, 0xdb, 0xfb, 0x90, 0x0, 0x1d, 0x0, 0x0, + 0x8, 0x71, 0xe1, 0x3, 0xfd, 0xdf, 0xdd, 0xf0, + 0x8, 0x95, 0xe5, 0x54, 0xc0, 0x1d, 0x0, 0xf0, + 0x4, 0x77, 0x77, 0xd6, 0xc0, 0x2c, 0x0, 0xf0, + 0x4, 0x22, 0x45, 0xc5, 0xdd, 0xef, 0xed, 0xc0, + 0xb, 0x74, 0x7a, 0xd1, 0x0, 0xbb, 0xb0, 0x0, + 0xb, 0x54, 0x91, 0xf0, 0x7, 0xc0, 0xb6, 0x0, + 0x56, 0x21, 0x1, 0xd1, 0xad, 0x10, 0x2d, 0x90, + 0x0, 0x0, 0xce, 0x7c, 0x80, 0x0, 0x1, 0xa5, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9A57 "驗" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb2, 0x0, 0x0, + 0xc, 0xee, 0xfe, 0xa0, 0x7, 0xea, 0x0, 0x0, + 0xc, 0x3, 0xa0, 0x0, 0x4c, 0x9, 0xa0, 0x0, + 0xc, 0x57, 0xc4, 0x16, 0xd1, 0x0, 0x9c, 0x20, + 0xc, 0xab, 0xd9, 0x8d, 0xce, 0xee, 0xe8, 0xc0, + 0xc, 0x3, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xde, 0xfd, 0x28, 0xcc, 0x3b, 0xcc, 0x30, + 0xc, 0x3, 0xa0, 0xa, 0x9, 0x3c, 0x8, 0x40, + 0xc, 0x89, 0xd7, 0x5a, 0x9, 0x3c, 0x8, 0x40, + 0x6, 0x77, 0x79, 0xbb, 0xce, 0x3e, 0xce, 0x40, + 0x6, 0x46, 0x83, 0xa0, 0x50, 0x0, 0x61, 0x0, + 0x28, 0xb8, 0x5a, 0x90, 0xe0, 0x1, 0xf0, 0x0, + 0x55, 0xb4, 0x46, 0x86, 0xe9, 0x7, 0xe3, 0x0, + 0x81, 0x40, 0x7, 0x9d, 0x18, 0x9e, 0x5e, 0x50, + 0x0, 0x0, 0xcd, 0xa6, 0x0, 0x95, 0x2, 0x60, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9AD4 "體" */ + 0x2f, 0xdd, 0xf1, 0x0, 0x3a, 0xd, 0x0, 0x2, + 0xc0, 0x9, 0x18, 0xec, 0xfc, 0xfc, 0xd0, 0x2f, + 0xb7, 0x91, 0x87, 0xb, 0xb, 0xd, 0x2, 0xc0, + 0xa9, 0x18, 0xdc, 0xec, 0xeb, 0xd0, 0x7d, 0x5c, + 0xb6, 0x87, 0xb, 0xb, 0xd, 0xf, 0x77, 0x77, + 0xe8, 0xdc, 0xdc, 0xdc, 0xc0, 0xc6, 0x66, 0x6a, + 0x43, 0x33, 0x33, 0x33, 0x11, 0xe4, 0x4c, 0x16, + 0x66, 0x66, 0x66, 0x61, 0x1f, 0xbb, 0xe1, 0xf, + 0xba, 0xaa, 0xd7, 0x1, 0xe0, 0xa, 0x10, 0xf1, + 0x0, 0x7, 0x70, 0x1f, 0xaa, 0xe1, 0xe, 0xcb, + 0xbc, 0xd7, 0x1, 0xe2, 0x2b, 0x10, 0xb, 0x0, + 0x49, 0x0, 0x1e, 0x0, 0xb1, 0x0, 0x95, 0x9, + 0x50, 0x1, 0xe0, 0x9c, 0x1d, 0xde, 0xfd, 0xfd, + 0xd6, + + /* U+9AD8 "高" */ + 0x0, 0x0, 0x0, 0x4, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa7, 0x0, 0x0, 0x0, 0xb, + 0xbb, 0xbb, 0xbd, 0xeb, 0xbb, 0xbb, 0xb0, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x0, 0x7, + 0xdc, 0xcc, 0xcc, 0xcd, 0x80, 0x0, 0x0, 0x87, + 0x0, 0x0, 0x0, 0x6a, 0x0, 0x0, 0x8, 0xda, + 0xaa, 0xaa, 0xad, 0xa0, 0x0, 0x0, 0x12, 0x22, + 0x22, 0x22, 0x21, 0x0, 0x6, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0x60, 0x6a, 0x11, 0x11, 0x11, + 0x11, 0x11, 0xa6, 0x6, 0x90, 0x6d, 0xdd, 0xdd, + 0xd3, 0x9, 0x60, 0x69, 0x7, 0x80, 0x0, 0xb, + 0x30, 0x96, 0x6, 0x90, 0x79, 0x11, 0x11, 0xb3, + 0x9, 0x60, 0x69, 0x7, 0xda, 0xaa, 0xaa, 0x20, + 0xa6, 0x6, 0x90, 0x11, 0x0, 0x0, 0x4, 0xcc, + 0x30, + + /* U+9AEA "髪" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, + 0x0, 0x8d, 0xaa, 0xaa, 0x40, 0x3, 0xba, 0x0, + 0x0, 0x8c, 0xaa, 0xaa, 0x6, 0xda, 0x40, 0x0, + 0x0, 0x89, 0x44, 0x44, 0x1, 0x10, 0x2b, 0x40, + 0x0, 0x8a, 0x66, 0x66, 0x1, 0x6b, 0xb3, 0x0, + 0xa, 0xce, 0xcb, 0xdb, 0xb2, 0x72, 0x0, 0x50, + 0x0, 0x6b, 0x0, 0xa8, 0x0, 0x1, 0x7d, 0x70, + 0x6, 0xfc, 0xbb, 0x9c, 0x58, 0xdb, 0x71, 0x0, + 0x0, 0x0, 0x5, 0xa0, 0x1, 0x0, 0x0, 0x0, + 0xd, 0xdd, 0xdf, 0xed, 0xdd, 0xdd, 0xdd, 0xd0, + 0x0, 0x0, 0x4e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xef, 0xdc, 0xcc, 0xcf, 0x90, 0x0, + 0x0, 0xa, 0xa2, 0xd6, 0x1, 0x9b, 0x0, 0x0, + 0x1, 0xcc, 0x0, 0x2c, 0xef, 0xa1, 0x0, 0x0, + 0x2e, 0x85, 0xbe, 0xd9, 0x45, 0x9d, 0xdb, 0x90, + 0x2, 0x1, 0x31, 0x0, 0x0, 0x0, 0x2, 0x30, + + /* U+9B5A "魚" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0xee, 0xef, 0xc0, 0x0, 0x0, + 0x0, 0x3, 0xf3, 0x0, 0xd, 0x60, 0x0, 0x0, + 0x0, 0x3e, 0x70, 0x0, 0x8d, 0x0, 0x0, 0x0, + 0x4, 0xff, 0xfe, 0xee, 0xff, 0xee, 0xed, 0x0, + 0xc, 0xae, 0x0, 0x5, 0xb0, 0x0, 0x2e, 0x0, + 0x0, 0x1e, 0x0, 0x5, 0xb0, 0x0, 0x2e, 0x0, + 0x0, 0x1f, 0xdd, 0xde, 0xfd, 0xdd, 0xee, 0x0, + 0x0, 0x1e, 0x0, 0x5, 0xb0, 0x0, 0x2e, 0x0, + 0x0, 0x1e, 0x0, 0x5, 0xb0, 0x0, 0x2e, 0x0, + 0x0, 0x1f, 0xee, 0xef, 0xfe, 0xee, 0xfe, 0x0, + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x13, 0x0, + 0x0, 0x5d, 0x2, 0xe0, 0xb, 0x50, 0x3e, 0x30, + 0x1, 0xe4, 0x0, 0xf0, 0x4, 0xd0, 0x5, 0xe1, + 0xc, 0x80, 0x0, 0xf2, 0x0, 0xe2, 0x0, 0xb8, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + + /* U+9CE5 "鳥" */ + 0x0, 0x0, 0x0, 0x3, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0xcc, 0xcc, 0xcc, 0xcd, 0xe0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0x1f, 0xcc, 0xcc, 0xcc, 0xcc, 0xe0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x1, 0xe0, 0x0, + 0x0, 0x1f, 0xcc, 0xcc, 0xcc, 0xcd, 0xc0, 0x0, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xd2, + 0x0, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xa0, + 0x0, 0x51, 0x12, 0x4, 0x10, 0x80, 0x6, 0x90, + 0x0, 0xe1, 0x3b, 0x7, 0x70, 0x86, 0x8, 0x70, + 0x9, 0x90, 0x1e, 0x2, 0xc0, 0x13, 0xc, 0x40, + 0x1a, 0x0, 0x5, 0x0, 0x0, 0x3d, 0xeb, 0x0, + + /* U+9E97 "麗" */ + 0x5, 0xcc, 0xcc, 0xcb, 0x5c, 0xcc, 0xcc, 0xc4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xea, 0xaa, 0xc8, 0xd, 0xaa, 0xaa, 0xe0, + 0x0, 0xe1, 0xc2, 0x68, 0xd, 0x1b, 0x41, 0xe0, + 0x0, 0xc0, 0x35, 0x5b, 0x9b, 0x11, 0x71, 0xb0, + 0x0, 0xdc, 0xcc, 0xec, 0xdd, 0xec, 0xcc, 0xc4, + 0x0, 0xe1, 0x1, 0xe0, 0x2, 0xd0, 0x0, 0x0, + 0x0, 0xec, 0xbc, 0xfb, 0xbc, 0xfb, 0xbc, 0xe0, + 0x0, 0xf1, 0x1, 0xe0, 0x2, 0xd0, 0x1, 0xe0, + 0x0, 0xfc, 0xed, 0xbb, 0xbe, 0xeb, 0xbb, 0xa0, + 0x1, 0xe0, 0xa6, 0x0, 0x8, 0x80, 0x27, 0x80, + 0x5, 0xb0, 0xad, 0xbb, 0x78, 0xdb, 0x95, 0x10, + 0xb, 0x60, 0xb6, 0x13, 0x38, 0x80, 0x0, 0x2b, + 0x1d, 0x3, 0xec, 0x97, 0x34, 0xed, 0xdd, 0xe6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9EBC "麼" */ + 0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x22, 0x22, 0x23, 0xf4, 0x22, 0x22, 0x20, + 0x0, 0xfa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, + 0x0, 0xf0, 0x0, 0xa0, 0x0, 0x9, 0x10, 0x0, + 0x0, 0xf1, 0xbb, 0xfb, 0x7a, 0xbf, 0xbb, 0x70, + 0x0, 0xf0, 0x2a, 0xf7, 0x22, 0x9f, 0xe3, 0x10, + 0x0, 0xf0, 0x3c, 0xeb, 0x53, 0xbc, 0x7b, 0x0, + 0x0, 0xf4, 0xd1, 0xd0, 0x7d, 0x1c, 0x18, 0xc1, + 0x0, 0xf4, 0x20, 0xd0, 0x51, 0xb, 0x10, 0x40, + 0x1, 0xe0, 0x0, 0xb, 0x70, 0x3, 0x0, 0x0, + 0x3, 0xc0, 0x3, 0xc4, 0x2, 0xd9, 0x0, 0x0, + 0x5, 0xa0, 0x5f, 0xcb, 0xde, 0x52, 0x50, 0x0, + 0x8, 0x70, 0x1, 0x3c, 0xa1, 0x0, 0xd2, 0x0, + 0xc, 0x40, 0x2a, 0xd6, 0x35, 0x67, 0xcb, 0x0, + 0x2e, 0x4, 0xff, 0xdc, 0xa9, 0x86, 0x5c, 0x40, + 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x30, + + /* U+9EC4 "黄" */ + 0x0, 0x0, 0x1f, 0x0, 0x0, 0xe2, 0x0, 0x0, + 0x0, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0x10, + 0x0, 0x0, 0x1f, 0x0, 0x0, 0xf2, 0x0, 0x0, + 0x2, 0x22, 0x3f, 0x22, 0x22, 0xf4, 0x22, 0x20, + 0x1d, 0xdd, 0xdd, 0xdf, 0xed, 0xdd, 0xdd, 0xd2, + 0x0, 0x0, 0x0, 0x8, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x5f, 0xdd, 0xde, 0xed, 0xdd, 0xe7, 0x0, + 0x0, 0x5a, 0x0, 0x8, 0x80, 0x0, 0x97, 0x0, + 0x0, 0x5e, 0xcc, 0xce, 0xec, 0xcc, 0xe7, 0x0, + 0x0, 0x5a, 0x0, 0x8, 0x80, 0x0, 0x97, 0x0, + 0x0, 0x5e, 0xbb, 0xbe, 0xdb, 0xbb, 0xe7, 0x0, + 0x0, 0x1, 0x27, 0x31, 0x12, 0x83, 0x10, 0x0, + 0x0, 0x38, 0xe9, 0x20, 0x1, 0x7d, 0xb5, 0x0, + 0xa, 0xc7, 0x10, 0x0, 0x0, 0x0, 0x4b, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9ED2 "黒" */ + 0x0, 0x5f, 0xdd, 0xdf, 0xed, 0xdd, 0xf6, 0x0, + 0x0, 0x5a, 0x0, 0x9, 0x70, 0x0, 0x96, 0x0, + 0x0, 0x5b, 0x11, 0x19, 0x81, 0x11, 0xa6, 0x0, + 0x0, 0x5e, 0xbb, 0xbe, 0xdb, 0xbb, 0xe6, 0x0, + 0x0, 0x5a, 0x0, 0x9, 0x70, 0x0, 0x96, 0x0, + 0x0, 0x5f, 0xee, 0xef, 0xfe, 0xee, 0xf6, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0x0, 0xad, 0xdd, 0xdf, 0xed, 0xdd, 0xdd, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x80, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x11, 0x19, 0x81, 0x11, 0x11, 0x10, + 0x1c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc1, + 0x0, 0x45, 0x1, 0x20, 0x4, 0x0, 0x63, 0x0, + 0x0, 0xd4, 0x5, 0xa0, 0xe, 0x20, 0x4e, 0x20, + 0xa, 0xa0, 0x3, 0xc0, 0x9, 0x80, 0x8, 0xc0, + 0x5, 0x0, 0x1, 0x40, 0x2, 0x20, 0x0, 0x50, + + /* U+9EDE "點" */ + 0xc, 0xdc, 0xec, 0xe6, 0x0, 0x1e, 0x0, 0x0, + 0xc, 0x51, 0xa2, 0x86, 0x0, 0x1e, 0x0, 0x0, + 0xc, 0x84, 0xa9, 0x86, 0x0, 0x1e, 0x0, 0x0, + 0xc, 0x57, 0xa9, 0x66, 0x0, 0x1f, 0xee, 0xe5, + 0xc, 0x22, 0xa2, 0x66, 0x0, 0x1e, 0x11, 0x10, + 0xa, 0xcd, 0xfc, 0xc5, 0x0, 0x1e, 0x0, 0x0, + 0x2, 0x35, 0xd3, 0x31, 0x0, 0x1e, 0x0, 0x0, + 0x9, 0xab, 0xea, 0xa5, 0x7e, 0xff, 0xee, 0xd0, + 0x0, 0x2, 0xc0, 0x1, 0x88, 0x0, 0x3, 0xd0, + 0x2c, 0xde, 0xfe, 0xdb, 0x87, 0x0, 0x2, 0xd0, + 0x3, 0x22, 0x21, 0x70, 0x87, 0x0, 0x2, 0xd0, + 0x9, 0x4b, 0x48, 0x68, 0x87, 0x0, 0x2, 0xd0, + 0xd, 0xc, 0xc, 0x9, 0x8d, 0xbb, 0xbc, 0xd0, + 0x48, 0x5, 0x1, 0x0, 0x89, 0x33, 0x35, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9EE8 "黨" */ + 0x0, 0x3, 0xb0, 0x9, 0x80, 0xb, 0x40, 0x0, + 0x9, 0xa9, 0xca, 0x9b, 0xb9, 0xac, 0x9a, 0x80, + 0xb, 0x41, 0x99, 0x99, 0x99, 0x99, 0x15, 0xa0, + 0x6, 0x21, 0xd0, 0x0, 0x0, 0xe, 0x13, 0x50, + 0x0, 0x1, 0xa9, 0x99, 0x99, 0x9a, 0x10, 0x0, + 0x0, 0x4a, 0xaa, 0xaa, 0xaa, 0xaa, 0xa5, 0x0, + 0x0, 0x78, 0x27, 0x9, 0x70, 0x90, 0x78, 0x0, + 0x0, 0x7a, 0x3b, 0x4a, 0x96, 0x83, 0x98, 0x0, + 0x0, 0x36, 0x66, 0x6c, 0xb6, 0x66, 0x63, 0x0, + 0x0, 0x9b, 0xbb, 0xbe, 0xdb, 0xbb, 0xbb, 0x0, + 0x0, 0x0, 0x0, 0x9, 0x70, 0x0, 0x0, 0x0, + 0xb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb0, + 0x0, 0x49, 0x3, 0x50, 0x8, 0x0, 0x86, 0x0, + 0x5, 0xd2, 0x3, 0xc0, 0xb, 0x50, 0x1d, 0x70, + 0x3, 0x10, 0x0, 0x40, 0x2, 0x10, 0x1, 0x40, + + /* U+9F13 "鼓" */ + 0x0, 0x1, 0xe0, 0x0, 0x0, 0xe, 0x10, 0x0, + 0x1b, 0xbb, 0xfb, 0xba, 0x0, 0xe, 0x10, 0x0, + 0x0, 0x1, 0xe0, 0x1, 0xee, 0xef, 0xfe, 0xe4, + 0x7, 0x9a, 0xf9, 0x96, 0x0, 0xe, 0x20, 0x0, + 0x2, 0x33, 0x33, 0x32, 0x0, 0xe, 0x10, 0x0, + 0x5, 0xaa, 0xaa, 0xa3, 0x89, 0x9f, 0xa9, 0x80, + 0x7, 0xa3, 0x33, 0xc4, 0x8c, 0x66, 0x6a, 0xb0, + 0x7, 0x80, 0x0, 0xb4, 0x1e, 0x0, 0xc, 0x50, + 0x7, 0xfd, 0xdd, 0xf4, 0x9, 0x70, 0x3e, 0x0, + 0x0, 0x80, 0x4, 0x60, 0x2, 0xe2, 0xd4, 0x0, + 0x0, 0xa6, 0x9, 0x60, 0x0, 0x7f, 0x90, 0x0, + 0x0, 0x58, 0xe, 0x56, 0x1, 0xce, 0xc1, 0x0, + 0x28, 0xbd, 0xfd, 0xb9, 0x7e, 0x80, 0x9e, 0x60, + 0x17, 0x42, 0x0, 0x9, 0xb3, 0x0, 0x5, 0xd3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+9F3B "鼻" */ + 0x0, 0x0, 0x0, 0x2, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x50, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xcb, 0xbb, 0xbb, 0xbd, 0xa0, 0x0, + 0x0, 0xa, 0xa7, 0x77, 0x77, 0x7b, 0xa0, 0x0, + 0x0, 0xa, 0xb9, 0x99, 0x99, 0x9b, 0xa0, 0x0, + 0x0, 0xa, 0x72, 0x22, 0x22, 0x27, 0xa0, 0x0, + 0x0, 0x6, 0x99, 0x99, 0x99, 0x99, 0x50, 0x0, + 0x0, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x0, + 0x0, 0xf3, 0x33, 0x3a, 0x93, 0x33, 0x4f, 0x0, + 0x0, 0xf5, 0x55, 0x5b, 0xa5, 0x55, 0x5f, 0x0, + 0x0, 0xca, 0xaa, 0xab, 0xba, 0xaa, 0xbc, 0x0, + 0x2, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x20, + 0x1b, 0xbb, 0xde, 0xbb, 0xbb, 0xfc, 0xbb, 0xb1, + 0x0, 0x3, 0xd4, 0x0, 0x0, 0xc3, 0x0, 0x0, + 0x9, 0xb8, 0x20, 0x0, 0x0, 0xc3, 0x0, 0x0, + + /* U+F001 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x49, 0xdc, + 0x0, 0x0, 0x0, 0x0, 0x16, 0xbf, 0xff, 0xff, + 0x0, 0x0, 0x3, 0x8d, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, + 0x0, 0x0, 0xff, 0xff, 0xea, 0x51, 0x0, 0xff, + 0x0, 0x0, 0xff, 0x83, 0x0, 0x0, 0x0, 0xff, + 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, + 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, + 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, + 0x0, 0x0, 0xff, 0x0, 0x0, 0x2b, 0xff, 0xff, + 0x0, 0x0, 0xff, 0x0, 0x0, 0xdf, 0xff, 0xff, + 0x2b, 0xff, 0xff, 0x0, 0x0, 0xdf, 0xff, 0xfd, + 0xdf, 0xff, 0xff, 0x0, 0x0, 0x2b, 0xff, 0xb2, + 0xdf, 0xff, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2b, 0xff, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F008 "" */ + 0xd0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xd, + 0xff, 0xff, 0xc8, 0x88, 0x88, 0x8c, 0xff, 0xff, + 0xf0, 0xf, 0x80, 0x0, 0x0, 0x8, 0xf0, 0xf, + 0xf0, 0xf, 0x80, 0x0, 0x0, 0x8, 0xf0, 0xf, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x8, 0xff, 0xff, + 0xf0, 0xf, 0xec, 0xcc, 0xcc, 0xce, 0xf0, 0xf, + 0xf0, 0xf, 0xec, 0xcc, 0xcc, 0xce, 0xf0, 0xf, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x8, 0xff, 0xff, + 0xf0, 0xf, 0x80, 0x0, 0x0, 0x8, 0xf0, 0xf, + 0xf0, 0xf, 0x80, 0x0, 0x0, 0x8, 0xf0, 0xf, + 0xff, 0xff, 0xc8, 0x88, 0x88, 0x8c, 0xff, 0xff, + 0xd0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xd, + + /* U+F00B "" */ + 0xdf, 0xff, 0x73, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0xff, 0xff, 0xa5, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xa5, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xdf, 0xff, 0x73, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xdf, 0xff, 0x73, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0xff, 0xff, 0xa5, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xa5, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xdf, 0xff, 0x73, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xdf, 0xff, 0x73, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0xff, 0xff, 0xa5, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xa5, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xdf, 0xff, 0x73, 0xff, 0xff, 0xff, 0xff, 0xfd, + + /* U+F00C "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xb1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf, 0xfc, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xff, 0xfb, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf, 0xff, 0xc0, + 0x1b, 0xa0, 0x0, 0x0, 0xb, 0xff, 0xfc, 0x0, + 0xcf, 0xfb, 0x0, 0x0, 0xbf, 0xff, 0xc0, 0x0, + 0xbf, 0xff, 0xb0, 0xb, 0xff, 0xfc, 0x0, 0x0, + 0xc, 0xff, 0xfb, 0xbf, 0xff, 0xc0, 0x0, 0x0, + 0x0, 0xcf, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xff, 0xff, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xbf, 0xfb, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xb0, 0x0, 0x0, 0x0, 0x0, + + /* U+F00D "" */ + 0x3, 0x0, 0x0, 0x0, 0x3, 0x8, 0xfc, 0x10, + 0x0, 0x1c, 0xf8, 0xff, 0xfc, 0x10, 0x1c, 0xff, + 0xf5, 0xff, 0xfc, 0x2c, 0xff, 0xf5, 0x5, 0xff, + 0xff, 0xff, 0xf5, 0x0, 0x5, 0xff, 0xff, 0xf5, + 0x0, 0x0, 0x1d, 0xff, 0xfd, 0x10, 0x0, 0x1c, + 0xff, 0xff, 0xfc, 0x10, 0x1c, 0xff, 0xf9, 0xff, + 0xfc, 0x1c, 0xff, 0xf5, 0x5, 0xff, 0xfc, 0xdf, + 0xf5, 0x0, 0x5, 0xff, 0xd1, 0xa4, 0x0, 0x0, + 0x4, 0xa1, + + /* U+F011 "" */ + 0x0, 0x0, 0x0, 0x4f, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x10, 0x6f, 0xf1, 0x3, 0x10, 0x0, + 0x0, 0x5f, 0xd0, 0x6f, 0xf1, 0x3f, 0xd1, 0x0, + 0x3, 0xff, 0xf1, 0x6f, 0xf1, 0x5f, 0xfd, 0x0, + 0xd, 0xff, 0x40, 0x6f, 0xf1, 0x9, 0xff, 0x70, + 0x4f, 0xf7, 0x0, 0x6f, 0xf1, 0x0, 0xcf, 0xe0, + 0x9f, 0xf0, 0x0, 0x6f, 0xf1, 0x0, 0x5f, 0xf3, + 0xbf, 0xc0, 0x0, 0x6f, 0xf1, 0x0, 0x2f, 0xf5, + 0xbf, 0xc0, 0x0, 0x4f, 0xe0, 0x0, 0x1f, 0xf6, + 0xaf, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xf4, + 0x6f, 0xf4, 0x0, 0x0, 0x0, 0x0, 0xaf, 0xf0, + 0xf, 0xfe, 0x10, 0x0, 0x0, 0x5, 0xff, 0xa0, + 0x6, 0xff, 0xd3, 0x0, 0x0, 0x7f, 0xff, 0x20, + 0x0, 0x9f, 0xff, 0xda, 0xbe, 0xff, 0xf4, 0x0, + 0x0, 0x6, 0xff, 0xff, 0xff, 0xfd, 0x30, 0x0, + 0x0, 0x0, 0x17, 0xbd, 0xca, 0x50, 0x0, 0x0, + + /* U+F013 "" */ + 0x0, 0x0, 0x0, 0x8b, 0xb8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x30, 0x6, 0xff, 0xff, 0x60, 0x3, 0x0, + 0x4, 0xfd, 0xdf, 0xff, 0xff, 0xfd, 0xef, 0x40, + 0xd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, + 0x4f, 0xff, 0xff, 0xf9, 0x9f, 0xff, 0xff, 0xf4, + 0x8, 0xff, 0xff, 0x20, 0x2, 0xff, 0xff, 0x80, + 0x0, 0xff, 0xf9, 0x0, 0x0, 0x9f, 0xff, 0x0, + 0x0, 0xff, 0xf9, 0x0, 0x0, 0x9f, 0xff, 0x0, + 0x8, 0xff, 0xff, 0x20, 0x2, 0xff, 0xff, 0x80, + 0x4f, 0xff, 0xff, 0xf9, 0x9f, 0xff, 0xff, 0xf4, + 0xd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, + 0x4, 0xfe, 0xdf, 0xff, 0xff, 0xfd, 0xdf, 0x40, + 0x0, 0x30, 0x6, 0xff, 0xff, 0x60, 0x3, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8b, 0xb8, 0x0, 0x0, 0x0, + + /* U+F015 "" */ + 0x0, 0x0, 0x0, 0x3, 0xdd, 0x30, 0x3f, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x6f, 0xff, 0xf5, 0x4f, + 0xf4, 0x0, 0x0, 0x0, 0x9, 0xff, 0x99, 0xff, + 0xbf, 0xf4, 0x0, 0x0, 0x1, 0xbf, 0xf6, 0x22, + 0x6f, 0xff, 0xf4, 0x0, 0x0, 0x2d, 0xfe, 0x35, + 0xff, 0x53, 0xef, 0xf4, 0x0, 0x4, 0xff, 0xc1, + 0x8f, 0xff, 0xf8, 0x2d, 0xfe, 0x40, 0x7f, 0xfa, + 0x1a, 0xff, 0xff, 0xff, 0xa1, 0xaf, 0xf7, 0xcf, + 0x82, 0xdf, 0xff, 0xff, 0xff, 0xfd, 0x28, 0xfc, + 0x14, 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x41, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x0, 0x0, 0xf, 0xff, 0xf9, 0x0, 0x8f, + 0xff, 0xf0, 0x0, 0x0, 0xf, 0xff, 0xf8, 0x0, + 0x8f, 0xff, 0xf0, 0x0, 0x0, 0xf, 0xff, 0xf8, + 0x0, 0x8f, 0xff, 0xf0, 0x0, 0x0, 0xe, 0xff, + 0xf6, 0x0, 0x6f, 0xff, 0xe0, 0x0, + + /* U+F019 "" */ + 0x0, 0x0, 0x0, 0xdf, 0xfd, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x0, + 0x0, 0xb, 0xff, 0xff, 0xff, 0xff, 0xb0, 0x0, + 0x0, 0x0, 0xbf, 0xff, 0xff, 0xfb, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xff, 0xff, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xbf, 0xfb, 0x0, 0x0, 0x0, + 0xdf, 0xff, 0xfc, 0x1b, 0xb1, 0xcf, 0xff, 0xfd, + 0xff, 0xff, 0xff, 0xc2, 0x2c, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xe0, 0xff, + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, + + /* U+F01C "" */ + 0x0, 0x4, 0xef, 0xff, 0xff, 0xff, 0xfe, 0x40, + 0x0, 0x0, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe1, 0x0, 0x0, 0xaf, 0xb0, 0x0, 0x0, 0x0, + 0xb, 0xfa, 0x0, 0x5, 0xff, 0x10, 0x0, 0x0, + 0x0, 0x1, 0xff, 0x50, 0x1e, 0xf6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6f, 0xe1, 0xaf, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb, 0xfa, 0xff, 0xff, + 0xff, 0x80, 0x0, 0x8, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf1, 0x0, 0x1f, 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, 0x8f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf8, + + /* U+F021 "" */ + 0x0, 0x0, 0x6, 0xbd, 0xda, 0x50, 0x2, 0xff, + 0x0, 0x5, 0xef, 0xff, 0xff, 0xfe, 0x42, 0xff, + 0x0, 0x7f, 0xff, 0xa7, 0x7b, 0xff, 0xf9, 0xff, + 0x5, 0xff, 0xc1, 0x0, 0x0, 0x2c, 0xff, 0xff, + 0xe, 0xfc, 0x0, 0x0, 0x2, 0x22, 0xdf, 0xff, + 0x5f, 0xf2, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, + 0x8f, 0xb0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xf0, 0x0, 0x0, 0xb, 0xf8, + 0xff, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x2f, 0xf4, + 0xff, 0xfd, 0x22, 0x20, 0x0, 0x0, 0xcf, 0xe0, + 0xff, 0xff, 0xc2, 0x0, 0x0, 0x2c, 0xff, 0x40, + 0xff, 0x9f, 0xff, 0xb7, 0x6a, 0xff, 0xf7, 0x0, + 0xff, 0x24, 0xdf, 0xff, 0xff, 0xfe, 0x50, 0x0, + 0xff, 0x20, 0x5, 0xac, 0xdb, 0x60, 0x0, 0x0, + + /* U+F026 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8d, + 0x0, 0x0, 0x8, 0xff, 0x0, 0x0, 0x8f, 0xff, + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x8f, 0xff, 0x0, 0x0, 0x8, 0xff, + 0x0, 0x0, 0x0, 0x8d, 0x0, 0x0, 0x0, 0x0, + + /* U+F027 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8d, 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x8f, 0xff, 0x0, 0x0, + 0xcf, 0xff, 0xff, 0xff, 0x1, 0x50, 0xff, 0xff, + 0xff, 0xff, 0x6, 0xf7, 0xff, 0xff, 0xff, 0xff, + 0x0, 0xbe, 0xff, 0xff, 0xff, 0xff, 0x0, 0xae, + 0xff, 0xff, 0xff, 0xff, 0x5, 0xf8, 0xdf, 0xff, + 0xff, 0xff, 0x2, 0x60, 0x0, 0x0, 0x9f, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x9, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+F028 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, + 0xd2, 0x0, 0x0, 0x0, 0x0, 0x8d, 0x0, 0x0, + 0x3, 0xee, 0x10, 0x0, 0x0, 0x8, 0xff, 0x0, + 0xa, 0xb1, 0x2f, 0xb0, 0x0, 0x0, 0x8f, 0xff, + 0x0, 0x5, 0xfc, 0x7, 0xf4, 0xdf, 0xff, 0xff, + 0xff, 0x2, 0x50, 0x5f, 0x60, 0xf9, 0xff, 0xff, + 0xff, 0xff, 0x6, 0xf7, 0xd, 0xc0, 0xbd, 0xff, + 0xff, 0xff, 0xff, 0x0, 0xae, 0x9, 0xf0, 0x9f, + 0xff, 0xff, 0xff, 0xff, 0x0, 0xae, 0x9, 0xf0, + 0x8f, 0xff, 0xff, 0xff, 0xff, 0x6, 0xf7, 0xd, + 0xc0, 0xad, 0xdf, 0xff, 0xff, 0xff, 0x2, 0x50, + 0x5f, 0x60, 0xe9, 0x0, 0x0, 0x8f, 0xff, 0x0, + 0x5, 0xfc, 0x6, 0xf4, 0x0, 0x0, 0x8, 0xff, + 0x0, 0xa, 0xb1, 0x2f, 0xb0, 0x0, 0x0, 0x0, + 0x8d, 0x0, 0x0, 0x2, 0xee, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1f, 0xd2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x10, 0x0, + + /* U+F03E "" */ + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x20, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfc, 0x0, 0xc, 0xff, 0xff, 0xee, 0xff, 0xff, + 0xff, 0x20, 0x2f, 0xff, 0xfe, 0x22, 0xef, 0xff, + 0xff, 0xfc, 0xff, 0xff, 0xe2, 0x0, 0x2e, 0xff, + 0xff, 0xfe, 0x4e, 0xfe, 0x20, 0x0, 0x2, 0xff, + 0xff, 0xe2, 0x2, 0xc2, 0x0, 0x0, 0x0, 0xff, + 0xff, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, + 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + + /* U+F043 "" */ + 0x0, 0x0, 0x4e, 0x40, 0x0, 0x0, 0x0, 0xb, + 0xfb, 0x0, 0x0, 0x0, 0x1, 0xff, 0xf1, 0x0, + 0x0, 0x0, 0x9f, 0xff, 0x90, 0x0, 0x0, 0x2f, + 0xff, 0xff, 0x30, 0x0, 0xc, 0xff, 0xff, 0xfc, + 0x0, 0x7, 0xff, 0xff, 0xff, 0xf8, 0x2, 0xff, + 0xff, 0xff, 0xff, 0xf2, 0x9f, 0xff, 0xff, 0xff, + 0xff, 0x9e, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, + 0x2f, 0xff, 0xff, 0xff, 0xfe, 0xf2, 0xbf, 0xff, + 0xff, 0xfe, 0x9f, 0xa1, 0xbf, 0xff, 0xff, 0x92, + 0xff, 0xa2, 0x2f, 0xff, 0xf2, 0x4, 0xff, 0xff, + 0xff, 0xf4, 0x0, 0x2, 0x9e, 0xfe, 0x92, 0x0, + + /* U+F048 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x30, 0x0, + 0x1, 0xcc, 0xff, 0x40, 0x0, 0x2d, 0xff, 0xff, + 0x40, 0x3, 0xef, 0xff, 0xff, 0x40, 0x3f, 0xff, + 0xff, 0xff, 0x44, 0xff, 0xff, 0xff, 0xff, 0x9f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff, + 0xff, 0xff, 0xff, 0x45, 0xff, 0xff, 0xff, 0xff, + 0x40, 0x4f, 0xff, 0xff, 0xff, 0x40, 0x3, 0xef, + 0xff, 0xff, 0x40, 0x0, 0x2e, 0xff, 0xff, 0x30, + 0x0, 0x1, 0xcc, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F04B "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, + 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, + 0x70, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xfd, + 0x40, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfa, + 0x10, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xf7, + 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, + 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb2, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xb2, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xd5, 0x0, 0xff, 0xff, 0xff, 0xff, + 0xf7, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfa, 0x10, + 0x0, 0x0, 0xff, 0xff, 0xfd, 0x40, 0x0, 0x0, + 0x0, 0xff, 0xff, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x8e, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F04C "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, + 0xff, 0xf8, 0x0, 0x8f, 0xff, 0xf8, 0xff, 0xff, + 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, + 0xff, 0xff, 0x7f, 0xff, 0xf7, 0x0, 0x7f, 0xff, + 0xf7, + + /* U+F04D "" */ + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 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, + 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, 0x8f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf8, + + /* U+F051 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xcc, 0x10, 0x0, + 0x3, 0xff, 0xff, 0xd2, 0x0, 0x4, 0xff, 0xff, + 0xfe, 0x30, 0x4, 0xff, 0xff, 0xff, 0xf4, 0x4, + 0xff, 0xff, 0xff, 0xff, 0x54, 0xff, 0xff, 0xff, + 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf9, 0xff, 0xff, 0xff, 0xff, 0x44, 0xff, 0xff, + 0xff, 0xf3, 0x4, 0xff, 0xff, 0xfe, 0x30, 0x4, + 0xff, 0xff, 0xd2, 0x0, 0x4, 0xff, 0xcc, 0x10, + 0x0, 0x3, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F052 "" */ + 0x0, 0x0, 0x0, 0x2d, 0xd2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xef, 0xfe, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x1d, 0xff, 0xff, 0xd1, 0x0, 0x0, + 0x0, 0x0, 0xcf, 0xff, 0xff, 0xfc, 0x0, 0x0, + 0x0, 0xb, 0xff, 0xff, 0xff, 0xff, 0xb0, 0x0, + 0x0, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x0, + 0x9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + + /* U+F053 "" */ + 0x0, 0x0, 0x0, 0x1a, 0x40, 0x0, 0x0, 0x1, + 0xdf, 0xf0, 0x0, 0x0, 0x1d, 0xff, 0xa0, 0x0, + 0x1, 0xdf, 0xfa, 0x0, 0x0, 0x1d, 0xff, 0xa0, + 0x0, 0x1, 0xdf, 0xfa, 0x0, 0x0, 0xc, 0xff, + 0xa0, 0x0, 0x0, 0xd, 0xff, 0x80, 0x0, 0x0, + 0x1, 0xdf, 0xf8, 0x0, 0x0, 0x0, 0x1d, 0xff, + 0x80, 0x0, 0x0, 0x1, 0xdf, 0xf8, 0x0, 0x0, + 0x0, 0x1d, 0xff, 0x80, 0x0, 0x0, 0x1, 0xdf, + 0xf0, 0x0, 0x0, 0x0, 0x1b, 0x50, + + /* U+F054 "" */ + 0x4, 0xa1, 0x0, 0x0, 0x0, 0xf, 0xfd, 0x10, + 0x0, 0x0, 0xa, 0xff, 0xd1, 0x0, 0x0, 0x0, + 0xaf, 0xfd, 0x10, 0x0, 0x0, 0xa, 0xff, 0xd1, + 0x0, 0x0, 0x0, 0xaf, 0xfd, 0x10, 0x0, 0x0, + 0xa, 0xff, 0xc0, 0x0, 0x0, 0x8, 0xff, 0xd0, + 0x0, 0x0, 0x8f, 0xfd, 0x10, 0x0, 0x8, 0xff, + 0xd1, 0x0, 0x0, 0x8f, 0xfd, 0x10, 0x0, 0x8, + 0xff, 0xd1, 0x0, 0x0, 0xf, 0xfd, 0x10, 0x0, + 0x0, 0x5, 0xb1, 0x0, 0x0, 0x0, + + /* U+F067 "" */ + 0x0, 0x0, 0x4, 0xff, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x8, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, + 0x80, 0x0, 0x0, 0x48, 0x88, 0x8c, 0xff, 0xc8, + 0x88, 0x84, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x48, 0x88, 0x8c, 0xff, 0xc8, 0x88, 0x84, 0x0, + 0x0, 0x8, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, + 0x80, 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, 0x40, + 0x0, 0x0, + + /* U+F068 "" */ + 0x14, 0x44, 0x44, 0x44, 0x44, 0x44, 0x41, 0xef, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x7b, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xb7, + + /* U+F06E "" */ + 0x0, 0x0, 0x5, 0xad, 0xff, 0xda, 0x50, 0x0, + 0x0, 0x0, 0x4, 0xdf, 0xfc, 0x88, 0xcf, 0xfd, + 0x40, 0x0, 0x0, 0x7f, 0xfe, 0x40, 0x0, 0x4, + 0xef, 0xf7, 0x0, 0x7, 0xff, 0xf4, 0x0, 0x9e, + 0x80, 0x4f, 0xff, 0x70, 0x4f, 0xff, 0xc0, 0x0, + 0xaf, 0xf8, 0xc, 0xff, 0xf4, 0xdf, 0xff, 0x80, + 0x9a, 0xff, 0xfe, 0x8, 0xff, 0xfd, 0xdf, 0xff, + 0x80, 0xef, 0xff, 0xfe, 0x8, 0xff, 0xfd, 0x4f, + 0xff, 0xc0, 0x8f, 0xff, 0xf8, 0xc, 0xff, 0xf4, + 0x7, 0xff, 0xf4, 0x8, 0xee, 0x80, 0x4f, 0xff, + 0x70, 0x0, 0x7f, 0xfe, 0x40, 0x0, 0x4, 0xef, + 0xf8, 0x0, 0x0, 0x4, 0xdf, 0xfc, 0x88, 0xcf, + 0xfd, 0x40, 0x0, 0x0, 0x0, 0x5, 0xad, 0xff, + 0xda, 0x50, 0x0, 0x0, + + /* U+F070 "" */ + 0x8c, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xdf, 0xe4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1b, 0xff, 0x80, 0x49, + 0xdf, 0xfd, 0xa5, 0x0, 0x0, 0x0, 0x0, 0x7f, + 0xff, 0xff, 0xd8, 0x8c, 0xff, 0xd4, 0x0, 0x0, + 0x0, 0x4, 0xef, 0xf8, 0x0, 0x0, 0x4e, 0xff, + 0x70, 0x0, 0x0, 0x0, 0x1c, 0xff, 0x69, 0xe8, + 0x4, 0xff, 0xf7, 0x0, 0x4, 0xe3, 0x0, 0x9f, + 0xfe, 0xff, 0x80, 0xcf, 0xff, 0x40, 0xd, 0xff, + 0x70, 0x5, 0xff, 0xff, 0xe0, 0x8f, 0xff, 0xd0, + 0xd, 0xff, 0xf7, 0x0, 0x2d, 0xff, 0xe0, 0x8f, + 0xff, 0xd0, 0x4, 0xff, 0xfc, 0x0, 0x0, 0xaf, + 0xf8, 0xcf, 0xff, 0x30, 0x0, 0x7f, 0xff, 0x40, + 0x0, 0x6, 0xff, 0xff, 0xf7, 0x0, 0x0, 0x8, + 0xff, 0xf4, 0x0, 0x0, 0x3e, 0xff, 0xa0, 0x0, + 0x0, 0x0, 0x4d, 0xff, 0xc8, 0x82, 0x1, 0xbf, + 0xf7, 0x0, 0x0, 0x0, 0x0, 0x5a, 0xdf, 0xfc, + 0x10, 0x8, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4e, 0xfd, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xc8, + + /* U+F071 "" */ + 0x0, 0x0, 0x0, 0x0, 0x2d, 0xd2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf, 0xfb, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xff, 0xff, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0xff, 0xff, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7f, 0xff, 0xff, 0xf7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xd8, 0x8d, + 0xff, 0x10, 0x0, 0x0, 0x0, 0x0, 0xa, 0xff, + 0xa0, 0xa, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x3f, 0xff, 0xb0, 0xb, 0xff, 0xf3, 0x0, 0x0, + 0x0, 0x0, 0xcf, 0xff, 0xc0, 0xc, 0xff, 0xfc, + 0x0, 0x0, 0x0, 0x5, 0xff, 0xff, 0xd0, 0xd, + 0xff, 0xff, 0x50, 0x0, 0x0, 0xe, 0xff, 0xff, + 0xf9, 0x9f, 0xff, 0xff, 0xe0, 0x0, 0x0, 0x8f, + 0xff, 0xff, 0xe2, 0x2e, 0xff, 0xff, 0xf8, 0x0, + 0x2, 0xff, 0xff, 0xff, 0x90, 0x9, 0xff, 0xff, + 0xff, 0x10, 0xa, 0xff, 0xff, 0xff, 0xe3, 0x3e, + 0xff, 0xff, 0xff, 0xa0, 0xf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x8, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, + + /* U+F074 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x80, + 0xff, 0xff, 0x70, 0x0, 0x7, 0xff, 0xff, 0xf8, + 0xff, 0xff, 0xf6, 0x0, 0x6f, 0xff, 0xff, 0xfd, + 0x78, 0x8e, 0xff, 0x15, 0xff, 0xe8, 0xff, 0xe2, + 0x0, 0x2, 0xe5, 0x4f, 0xfe, 0x20, 0xfe, 0x20, + 0x0, 0x0, 0x13, 0xff, 0xf3, 0x0, 0x52, 0x0, + 0x0, 0x0, 0x3f, 0xff, 0x31, 0x0, 0x52, 0x0, + 0x0, 0x2, 0xef, 0xf4, 0x5e, 0x20, 0xfe, 0x20, + 0x78, 0x8e, 0xff, 0x51, 0xff, 0xe8, 0xff, 0xe2, + 0xff, 0xff, 0xf6, 0x0, 0x6f, 0xff, 0xff, 0xfd, + 0xff, 0xff, 0x70, 0x0, 0x7, 0xff, 0xff, 0xf8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x80, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F077 "" */ + 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, 0x99, + 0xff, 0xd1, 0x0, 0x1, 0xdf, 0xf9, 0x0, 0x9f, + 0xfd, 0x10, 0x1d, 0xff, 0x90, 0x0, 0x9, 0xff, + 0xd1, 0xbf, 0xf9, 0x0, 0x0, 0x0, 0x9f, 0xfb, + 0x5f, 0x90, 0x0, 0x0, 0x0, 0x9, 0xf5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F078 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, + 0x90, 0x0, 0x0, 0x0, 0x9, 0xf5, 0xbf, 0xf9, + 0x0, 0x0, 0x0, 0x9f, 0xfb, 0x1d, 0xff, 0x90, + 0x0, 0x9, 0xff, 0xd1, 0x1, 0xdf, 0xf9, 0x0, + 0x9f, 0xfd, 0x10, 0x0, 0x1d, 0xff, 0x99, 0xff, + 0xd1, 0x0, 0x0, 0x1, 0xdf, 0xff, 0xfd, 0x10, + 0x0, 0x0, 0x0, 0x1d, 0xff, 0xd1, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xdd, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F079 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1d, 0xd1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0xdf, 0xfd, 0x10, + 0xef, 0xff, 0xff, 0xff, 0xd0, 0x0, 0x1d, 0xff, + 0xff, 0xd1, 0xaf, 0xff, 0xff, 0xff, 0xf0, 0x0, + 0xcf, 0xcf, 0xfc, 0xfc, 0x0, 0x0, 0x0, 0xf, + 0xf0, 0x0, 0x6b, 0x1f, 0xf1, 0xb6, 0x0, 0x0, + 0x0, 0xf, 0xf0, 0x0, 0x0, 0xf, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0xf, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, + 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, 0x6b, 0x1f, + 0xf1, 0xb6, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, + 0xcf, 0xcf, 0xfc, 0xfc, 0x0, 0xf, 0xff, 0xff, + 0xff, 0xfa, 0x1d, 0xff, 0xff, 0xd1, 0x0, 0xd, + 0xff, 0xff, 0xff, 0xfe, 0x1, 0xdf, 0xfd, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, + 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+F07B "" */ + 0x8f, 0xff, 0xff, 0xe2, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xfe, 0x20, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + + /* U+F093 "" */ + 0x0, 0x0, 0x0, 0xb, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xbf, 0xfb, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xff, 0xff, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0xbf, 0xff, 0xff, 0xfb, 0x0, 0x0, + 0x0, 0xb, 0xff, 0xff, 0xff, 0xff, 0xb0, 0x0, + 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, + 0xdf, 0xff, 0xf0, 0xdf, 0xfd, 0xf, 0xff, 0xfd, + 0xff, 0xff, 0xf9, 0x0, 0x0, 0x9f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xe0, 0xff, + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, + + /* U+F095 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xea, + 0x62, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xff, + 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, + 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, + 0xff, 0xff, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xef, 0xff, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xff, 0xf2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xbf, 0xfb, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0xff, 0x30, 0x0, 0x0, 0x2, + 0x0, 0x0, 0x4f, 0xff, 0x90, 0x0, 0x2, 0x8f, + 0xf3, 0x0, 0x6f, 0xff, 0xd0, 0x0, 0xa, 0xff, + 0xff, 0xe4, 0xbf, 0xff, 0xd1, 0x0, 0x0, 0xef, + 0xff, 0xff, 0xff, 0xff, 0xd1, 0x0, 0x0, 0xa, + 0xff, 0xff, 0xff, 0xff, 0x90, 0x0, 0x0, 0x0, + 0x6f, 0xff, 0xff, 0xfb, 0x30, 0x0, 0x0, 0x0, + 0x2, 0xff, 0xdb, 0x72, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+F0C4 "" */ + 0x8, 0xee, 0x80, 0x0, 0x0, 0x6, 0x61, 0x8, + 0xff, 0xff, 0x80, 0x0, 0x2d, 0xff, 0xd0, 0xef, + 0x33, 0xfe, 0x0, 0x2e, 0xff, 0xf3, 0xe, 0xf3, + 0x3f, 0xe0, 0x2e, 0xff, 0xf3, 0x0, 0x8f, 0xff, + 0xff, 0x6e, 0xff, 0xf3, 0x0, 0x0, 0x8e, 0xff, + 0xff, 0xff, 0xf3, 0x0, 0x0, 0x0, 0x2, 0xef, + 0xff, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x2e, 0xff, + 0xff, 0x30, 0x0, 0x0, 0x8, 0xef, 0xff, 0xff, + 0xff, 0x30, 0x0, 0x8, 0xff, 0xff, 0xf6, 0xef, + 0xff, 0x30, 0x0, 0xef, 0x33, 0xfe, 0x2, 0xef, + 0xff, 0x30, 0xe, 0xf3, 0x3f, 0xe0, 0x2, 0xef, + 0xff, 0x30, 0x8f, 0xff, 0xf8, 0x0, 0x2, 0xdf, + 0xfd, 0x0, 0x8e, 0xe8, 0x0, 0x0, 0x0, 0x66, + 0x10, + + /* U+F0C5 "" */ + 0x0, 0x0, 0xdf, 0xff, 0xff, 0xd, 0x20, 0x0, + 0x0, 0xff, 0xff, 0xff, 0xf, 0xe2, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xf, 0xfd, 0xdf, 0xf0, 0xff, + 0xff, 0xff, 0x20, 0x0, 0xff, 0xf0, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xdf, 0xff, + 0xff, 0xff, 0xfd, 0xff, 0xf9, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0xdf, 0xff, 0xff, 0xff, 0xfd, 0x0, 0x0, + + /* U+F0C7 "" */ + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xc2, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x20, 0xff, 0x0, + 0x0, 0x0, 0x1, 0xff, 0xe2, 0xff, 0x0, 0x0, + 0x0, 0x0, 0xff, 0xfc, 0xff, 0x0, 0x0, 0x0, + 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfb, 0x11, 0xbf, 0xff, 0xff, 0xff, + 0xff, 0xf1, 0x0, 0x1f, 0xff, 0xff, 0xff, 0xff, + 0xf1, 0x0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0x11, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf8, + + /* U+F0C9 "" */ + 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x12, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x21, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x12, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x21, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x21, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x12, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x21, + + /* U+F0E0 "" */ + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0x9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, + 0xd2, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xf5, 0x2d, + 0xff, 0x62, 0xcf, 0xff, 0xff, 0xfc, 0x26, 0xff, + 0xff, 0xfa, 0x18, 0xff, 0xff, 0x81, 0xaf, 0xff, + 0xff, 0xff, 0xe3, 0x4d, 0xd4, 0x3e, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x81, 0x18, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + + /* U+F0E7 "" */ + 0x0, 0xdf, 0xff, 0xfd, 0x0, 0x0, 0x1, 0xff, + 0xff, 0xfc, 0x0, 0x0, 0x3, 0xff, 0xff, 0xf7, + 0x0, 0x0, 0x6, 0xff, 0xff, 0xf2, 0x0, 0x0, + 0x8, 0xff, 0xff, 0xd0, 0x0, 0x0, 0xa, 0xff, + 0xff, 0xff, 0xff, 0xd0, 0xc, 0xff, 0xff, 0xff, + 0xff, 0xa0, 0xe, 0xff, 0xff, 0xff, 0xff, 0x20, + 0xd, 0xff, 0xff, 0xff, 0xf8, 0x0, 0x0, 0x0, + 0xa, 0xff, 0xe0, 0x0, 0x0, 0x0, 0xe, 0xff, + 0x50, 0x0, 0x0, 0x0, 0x2f, 0xfc, 0x0, 0x0, + 0x0, 0x0, 0x5f, 0xf3, 0x0, 0x0, 0x0, 0x0, + 0x9f, 0xa0, 0x0, 0x0, 0x0, 0x0, 0xdf, 0x10, + 0x0, 0x0, 0x0, 0x0, 0xd7, 0x0, 0x0, 0x0, + + /* U+F0EA "" */ + 0x0, 0x4, 0xee, 0x40, 0x0, 0x0, 0x0, 0xdf, + 0xff, 0x99, 0xff, 0xfd, 0x0, 0x0, 0xff, 0xff, + 0x99, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x90, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0xd, 0xff, 0xff, + 0xd, 0x20, 0xff, 0xff, 0xf, 0xff, 0xff, 0xf, + 0xe2, 0xff, 0xff, 0xf, 0xff, 0xff, 0xf, 0xfd, + 0xff, 0xff, 0xf, 0xff, 0xff, 0x20, 0x0, 0xff, + 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, + 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xf, 0xff, + 0xff, 0xff, 0xff, 0x0, 0x0, 0xf, 0xff, 0xff, + 0xff, 0xff, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, + 0xff, 0x0, 0x0, 0xd, 0xff, 0xff, 0xff, 0xfd, + + /* U+F0F3 "" */ + 0x0, 0x0, 0x0, 0xcc, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xff, 0x30, 0x0, 0x0, 0x0, 0x1, + 0xbf, 0xff, 0xfc, 0x20, 0x0, 0x0, 0x1e, 0xff, + 0xff, 0xff, 0xe1, 0x0, 0x0, 0x9f, 0xff, 0xff, + 0xff, 0xf8, 0x0, 0x0, 0xef, 0xff, 0xff, 0xff, + 0xfd, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x1, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, 0x8, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1e, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe1, 0xcf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0xcf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe, 0xff, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xee, 0x40, 0x0, 0x0, + + /* U+F11C "" */ + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0, 0xf0, 0xf, 0x0, 0xf0, + 0xf, 0x0, 0xff, 0xff, 0x0, 0xf0, 0xf, 0x0, + 0xf0, 0xf, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x8, + 0x80, 0x88, 0x8, 0x80, 0x8f, 0xff, 0xff, 0xf8, + 0x8, 0x80, 0x88, 0x8, 0x80, 0x8f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0, 0xf0, 0x0, 0x0, 0x0, 0xf, 0x0, + 0xff, 0xff, 0x0, 0xf0, 0x0, 0x0, 0x0, 0xf, + 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf8, + + /* U+F124 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xaf, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xcf, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x6, + 0xdf, 0xff, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x17, + 0xef, 0xff, 0xff, 0xff, 0x30, 0x0, 0x0, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x0, 0x0, 0x2a, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x0, 0x8, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, + 0x0, 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, + 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, + 0xff, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xff, 0xff, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xff, 0xfa, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8f, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+F15B "" */ + 0xdf, 0xff, 0xff, 0xf0, 0xd2, 0x0, 0xff, 0xff, + 0xff, 0xf0, 0xfe, 0x20, 0xff, 0xff, 0xff, 0xf0, + 0xff, 0xe2, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xfd, + 0xff, 0xff, 0xff, 0xf2, 0x0, 0x0, 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, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xfd, + + /* U+F1EB "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4, 0x9c, 0xef, 0xfe, + 0xc9, 0x40, 0x0, 0x0, 0x0, 0x7, 0xef, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x70, 0x0, 0x4, 0xdf, + 0xff, 0xfc, 0xa8, 0x8a, 0xcf, 0xff, 0xfd, 0x40, + 0x6f, 0xff, 0xd5, 0x0, 0x0, 0x0, 0x0, 0x5d, + 0xff, 0xf6, 0xcf, 0xf6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0xfc, 0x1a, 0x30, 0x0, 0x5a, + 0xdf, 0xfd, 0xa5, 0x0, 0x3, 0xa1, 0x0, 0x0, + 0x4d, 0xff, 0xff, 0xff, 0xff, 0xd4, 0x0, 0x0, + 0x0, 0x5, 0xff, 0xfe, 0xa8, 0x8a, 0xef, 0xff, + 0x50, 0x0, 0x0, 0x1, 0xdf, 0x70, 0x0, 0x0, + 0x7, 0xfd, 0x10, 0x0, 0x0, 0x0, 0x12, 0x0, + 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4e, 0xe4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xef, 0xfe, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xfe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4e, 0xe4, 0x0, 0x0, 0x0, 0x0, + + /* U+F240 "" */ + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, 0xff, 0xf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0xff, + 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x0, 0xff, 0xff, 0xf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x80, + + /* U+F241 "" */ + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, 0xff, 0xf, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, 0xf, 0xff, + 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, + 0x0, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x0, 0x0, 0xff, 0xff, 0xf, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0x0, 0xf, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x80, + + /* U+F242 "" */ + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, 0xff, 0xf, + 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0xf, 0xff, + 0xff, 0xf, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, + 0x0, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0xf, 0xff, 0xff, + 0xff, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x80, + + /* U+F243 "" */ + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, 0xff, 0xf, + 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, + 0xff, 0xf, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xff, 0xff, 0xf, 0xff, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0xf, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x80, + + /* U+F244 "" */ + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, + 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfd, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x80, + + /* U+F287 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, + 0xfd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xcf, 0xff, 0xf5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb9, 0x29, 0xfe, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x10, 0x2, + 0x0, 0x0, 0x0, 0x0, 0x3, 0xdf, 0x80, 0xa, + 0x90, 0x0, 0x0, 0x0, 0x3, 0x70, 0x0, 0xdf, + 0xff, 0x77, 0xf7, 0x55, 0x55, 0x55, 0x55, 0x8f, + 0xd3, 0xf, 0xff, 0xfd, 0xcc, 0xdf, 0xdc, 0xcc, + 0xcc, 0xcd, 0xff, 0xb0, 0x8f, 0xfe, 0x10, 0x0, + 0xaa, 0x0, 0x0, 0x0, 0x4d, 0x40, 0x0, 0x46, + 0x10, 0x0, 0x1, 0xf2, 0x2, 0x33, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xb1, 0xcf, + 0xf9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0xff, 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xbf, 0xf9, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x22, + 0x0, 0x0, 0x0, + + /* U+F293 "" */ + 0x0, 0x18, 0xdf, 0xfd, 0x92, 0x0, 0x2, 0xef, + 0xfb, 0xef, 0xff, 0x30, 0xd, 0xff, 0xfa, 0x2e, + 0xff, 0xe0, 0x4f, 0xff, 0xfa, 0x3, 0xff, 0xf5, + 0x9f, 0xfa, 0xfa, 0x35, 0x4f, 0xfa, 0xcf, 0xc0, + 0x8a, 0x3d, 0xb, 0xfd, 0xef, 0xfb, 0x3, 0x12, + 0x8f, 0xfe, 0xff, 0xff, 0xb0, 0x6, 0xff, 0xff, + 0xff, 0xff, 0xd1, 0x8, 0xff, 0xff, 0xef, 0xfd, + 0x11, 0x10, 0x9f, 0xff, 0xdf, 0xd1, 0x59, 0x3b, + 0xb, 0xfd, 0xaf, 0xd7, 0xfa, 0x38, 0x1d, 0xfb, + 0x5f, 0xff, 0xfa, 0x1, 0xdf, 0xf7, 0xd, 0xff, + 0xfa, 0x1d, 0xff, 0xf1, 0x3, 0xef, 0xfc, 0xdf, + 0xff, 0x50, 0x0, 0x18, 0xdf, 0xfe, 0xa3, 0x0, + + /* U+F2ED "" */ + 0x0, 0x0, 0x7f, 0xff, 0xf7, 0x0, 0x0, 0xef, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xef, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0xf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0xf, 0xf9, 0x9f, 0x99, 0xf9, 0x9f, + 0xf0, 0xf, 0xf8, 0x8f, 0x88, 0xf8, 0x8f, 0xf0, + 0xf, 0xf8, 0x8f, 0x88, 0xf8, 0x8f, 0xf0, 0xf, + 0xf8, 0x8f, 0x88, 0xf8, 0x8f, 0xf0, 0xf, 0xf8, + 0x8f, 0x88, 0xf8, 0x8f, 0xf0, 0xf, 0xf8, 0x8f, + 0x88, 0xf8, 0x8f, 0xf0, 0xf, 0xf8, 0x8f, 0x88, + 0xf8, 0x8f, 0xf0, 0xf, 0xf9, 0x9f, 0x99, 0xf9, + 0x9f, 0xf0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, + + /* U+F304 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xff, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xff, + 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x8a, 0x1d, + 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xfa, + 0x1d, 0xff, 0x70, 0x0, 0x0, 0x0, 0x8f, 0xff, + 0xfa, 0x1d, 0x80, 0x0, 0x0, 0x0, 0x8f, 0xff, + 0xff, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x8f, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x8f, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x8f, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x6f, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0xb, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0xdf, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0xe, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xde, 0xdb, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+F55A "" */ + 0x0, 0x0, 0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe4, 0x0, 0x1, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x0, 0x1d, 0xff, 0xff, + 0xfa, 0xef, 0xfe, 0xaf, 0xff, 0xff, 0x1, 0xdf, + 0xff, 0xff, 0xa0, 0x2e, 0xe2, 0xa, 0xff, 0xff, + 0x1d, 0xff, 0xff, 0xff, 0xe2, 0x2, 0x20, 0x2e, + 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xfe, 0x20, + 0x2, 0xef, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, + 0xfe, 0x20, 0x2, 0xef, 0xff, 0xff, 0x1d, 0xff, + 0xff, 0xff, 0xe2, 0x2, 0x20, 0x2e, 0xff, 0xff, + 0x1, 0xdf, 0xff, 0xff, 0xa0, 0x2e, 0xe2, 0xa, + 0xff, 0xff, 0x0, 0x1d, 0xff, 0xff, 0xfa, 0xef, + 0xfe, 0xaf, 0xff, 0xff, 0x0, 0x1, 0xdf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, + 0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, + + /* U+F7C2 "" */ + 0x0, 0x8, 0xff, 0xff, 0xff, 0xe4, 0x0, 0x8f, + 0xff, 0xff, 0xff, 0xfe, 0x8, 0xf8, 0xf, 0xb, + 0x40, 0xff, 0x8f, 0xf8, 0xf, 0xb, 0x40, 0xff, + 0xff, 0xf8, 0xf, 0xb, 0x40, 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, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x4e, 0xff, 0xff, 0xff, 0xff, 0xe4, + + /* U+F8A2 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xe0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x2, + 0xef, 0x10, 0x0, 0xbf, 0x0, 0x0, 0x0, 0x0, + 0x7f, 0xf1, 0x0, 0xcf, 0xf1, 0x0, 0x0, 0x0, + 0x7, 0xff, 0x11, 0xcf, 0xff, 0x77, 0x77, 0x77, + 0x77, 0xbf, 0xf1, 0xcf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x17, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xe0, 0x7, 0xff, 0xf1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xff, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+FF08 "(" */ + 0x0, 0x7, 0x0, 0x9, 0xa0, 0x3, 0xd0, 0x0, + 0xc5, 0x0, 0x2e, 0x0, 0x7, 0x90, 0x0, 0xa6, + 0x0, 0xb, 0x40, 0x0, 0xb4, 0x0, 0x9, 0x60, + 0x0, 0x79, 0x0, 0x1, 0xe0, 0x0, 0xb, 0x60, + 0x0, 0x2e, 0x10, 0x0, 0x6c, 0x0, 0x0, 0x50, + + /* U+FF09 ")" */ + 0x7, 0x0, 0x0, 0xa9, 0x0, 0x0, 0xd3, 0x0, + 0x5, 0xc0, 0x0, 0xe, 0x20, 0x0, 0x97, 0x0, + 0x6, 0xa0, 0x0, 0x4b, 0x0, 0x4, 0xb0, 0x0, + 0x69, 0x0, 0xa, 0x60, 0x0, 0xe1, 0x0, 0x6b, + 0x0, 0x1e, 0x20, 0xc, 0x60, 0x0, 0x50, 0x0, + + /* U+FF0C "," */ + 0x1b, 0x70, 0x3f, 0xf0, 0x4, 0xf0, 0x6, 0xb0, + 0x8d, 0x20, 0x40, 0x0, + + /* U+FF11 "1" */ + 0x0, 0x39, 0xa0, 0x0, 0x1, 0xee, 0xfe, 0x0, + 0x0, 0x0, 0x6, 0xe0, 0x0, 0x0, 0x0, 0x6e, + 0x0, 0x0, 0x0, 0x6, 0xe0, 0x0, 0x0, 0x0, + 0x6e, 0x0, 0x0, 0x0, 0x6, 0xe0, 0x0, 0x0, + 0x0, 0x6e, 0x0, 0x0, 0x0, 0x6, 0xe0, 0x0, + 0x0, 0x0, 0x6e, 0x0, 0x0, 0x11, 0x17, 0xe1, + 0x11, 0xf, 0xff, 0xff, 0xff, 0xf3, + + /* U+FF12 "2" */ + 0x0, 0x4b, 0xed, 0x91, 0x0, 0x7, 0xf8, 0x44, + 0xcd, 0x0, 0xb, 0x30, 0x0, 0xe, 0x60, 0x0, + 0x0, 0x0, 0xb, 0x90, 0x0, 0x0, 0x0, 0xe, + 0x60, 0x0, 0x0, 0x0, 0x5f, 0x10, 0x0, 0x0, + 0x1, 0xe7, 0x0, 0x0, 0x0, 0x1c, 0xb0, 0x0, + 0x0, 0x1, 0xdc, 0x0, 0x0, 0x0, 0x2d, 0xb0, + 0x0, 0x0, 0x3, 0xea, 0x11, 0x11, 0x10, 0xf, + 0xff, 0xff, 0xff, 0xf3 +}; + + +/*--------------------- + * 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 = 57, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 0, .adv_w = 80, .box_w = 3, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 18, .adv_w = 117, .box_w = 5, .box_h = 5, .ofs_x = 1, .ofs_y = 8}, + {.bitmap_index = 31, .adv_w = 141, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 85, .adv_w = 141, .box_w = 8, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 149, .adv_w = 234, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 233, .adv_w = 172, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 299, .adv_w = 69, .box_w = 2, .box_h = 5, .ofs_x = 1, .ofs_y = 8}, + {.bitmap_index = 304, .adv_w = 85, .box_w = 4, .box_h = 18, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 340, .adv_w = 85, .box_w = 4, .box_h = 18, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 376, .adv_w = 118, .box_w = 6, .box_h = 6, .ofs_x = 1, .ofs_y = 7}, + {.bitmap_index = 394, .adv_w = 141, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 435, .adv_w = 69, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 445, .adv_w = 88, .box_w = 5, .box_h = 2, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 450, .adv_w = 69, .box_w = 3, .box_h = 3, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 455, .adv_w = 100, .box_w = 7, .box_h = 16, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 511, .adv_w = 141, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 559, .adv_w = 141, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 601, .adv_w = 141, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 649, .adv_w = 141, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 697, .adv_w = 141, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 751, .adv_w = 141, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 799, .adv_w = 141, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 853, .adv_w = 141, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 907, .adv_w = 141, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 961, .adv_w = 141, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1009, .adv_w = 69, .box_w = 3, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1023, .adv_w = 69, .box_w = 4, .box_h = 12, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 1047, .adv_w = 141, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 1083, .adv_w = 141, .box_w = 9, .box_h = 5, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 1106, .adv_w = 141, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 1142, .adv_w = 120, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1184, .adv_w = 239, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1289, .adv_w = 154, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1349, .adv_w = 167, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1403, .adv_w = 162, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1463, .adv_w = 175, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1517, .adv_w = 150, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1565, .adv_w = 140, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1613, .adv_w = 175, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1673, .adv_w = 185, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1727, .adv_w = 73, .box_w = 2, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1739, .adv_w = 136, .box_w = 7, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1781, .adv_w = 164, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1841, .adv_w = 137, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1889, .adv_w = 206, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1955, .adv_w = 184, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2009, .adv_w = 189, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2075, .adv_w = 160, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2129, .adv_w = 189, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 2225, .adv_w = 161, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2279, .adv_w = 151, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2333, .adv_w = 152, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2393, .adv_w = 183, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2447, .adv_w = 145, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2507, .adv_w = 223, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2591, .adv_w = 144, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2645, .adv_w = 134, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2699, .adv_w = 154, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2753, .adv_w = 85, .box_w = 4, .box_h = 16, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 2785, .adv_w = 100, .box_w = 7, .box_h = 16, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 2841, .adv_w = 85, .box_w = 4, .box_h = 16, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 2873, .adv_w = 141, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 5}, + {.bitmap_index = 2898, .adv_w = 143, .box_w = 9, .box_h = 1, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2903, .adv_w = 154, .box_w = 4, .box_h = 5, .ofs_x = 2, .ofs_y = 10}, + {.bitmap_index = 2913, .adv_w = 143, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2949, .adv_w = 157, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3001, .adv_w = 130, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3037, .adv_w = 157, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3096, .adv_w = 141, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3137, .adv_w = 81, .box_w = 6, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3176, .adv_w = 143, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 3235, .adv_w = 154, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3287, .adv_w = 69, .box_w = 3, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3307, .adv_w = 69, .box_w = 5, .box_h = 17, .ofs_x = -1, .ofs_y = -4}, + {.bitmap_index = 3350, .adv_w = 139, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3402, .adv_w = 71, .box_w = 3, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3422, .adv_w = 236, .box_w = 13, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3481, .adv_w = 155, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3517, .adv_w = 154, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3558, .adv_w = 157, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 3610, .adv_w = 157, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 3669, .adv_w = 97, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3696, .adv_w = 119, .box_w = 7, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3728, .adv_w = 95, .box_w = 6, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3764, .adv_w = 154, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3800, .adv_w = 131, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3836, .adv_w = 203, .box_w = 13, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3895, .adv_w = 124, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3931, .adv_w = 131, .box_w = 8, .box_h = 13, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 3983, .adv_w = 120, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4019, .adv_w = 85, .box_w = 5, .box_h = 16, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 4059, .adv_w = 68, .box_w = 2, .box_h = 18, .ofs_x = 1, .ofs_y = -5}, + {.bitmap_index = 4077, .adv_w = 85, .box_w = 5, .box_h = 16, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 4117, .adv_w = 141, .box_w = 9, .box_h = 3, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 4131, .adv_w = 256, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 4146, .adv_w = 256, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 4161, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 4252, .adv_w = 256, .box_w = 6, .box_h = 11, .ofs_x = 10, .ofs_y = 2}, + {.bitmap_index = 4285, .adv_w = 256, .box_w = 6, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 4318, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 4390, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 4495, .adv_w = 256, .box_w = 12, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 4561, .adv_w = 256, .box_w = 13, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 4646, .adv_w = 256, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 4723, .adv_w = 256, .box_w = 11, .box_h = 11, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 4784, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 4882, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 4987, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5092, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 5212, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 5296, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5401, .adv_w = 256, .box_w = 10, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 5471, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 5555, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5653, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5766, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 5844, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 5949, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 6033, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 6145, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 6229, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 6313, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6411, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 6531, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 6636, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 6748, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6846, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 6944, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7042, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7147, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7245, .adv_w = 256, .box_w = 12, .box_h = 10, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 7305, .adv_w = 256, .box_w = 14, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 7382, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7495, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7586, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7677, .adv_w = 256, .box_w = 11, .box_h = 14, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 7754, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 7852, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 7950, .adv_w = 256, .box_w = 13, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 8035, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8148, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 8268, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8359, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8464, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8577, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8682, .adv_w = 256, .box_w = 15, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8780, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8893, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 8998, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 9110, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 9222, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 9334, .adv_w = 256, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 9422, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 9518, .adv_w = 256, .box_w = 15, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 9608, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 9713, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 9833, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 9946, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 10030, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 10128, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 10226, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 10324, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 10429, .adv_w = 256, .box_w = 13, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 10514, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 10619, .adv_w = 256, .box_w = 11, .box_h = 12, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 10685, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 10783, .adv_w = 256, .box_w = 10, .box_h = 11, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 10838, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 10922, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 11006, .adv_w = 256, .box_w = 10, .box_h = 15, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 11081, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 11172, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 11292, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 11390, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 11503, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 11601, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 11699, .adv_w = 256, .box_w = 12, .box_h = 10, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 11759, .adv_w = 256, .box_w = 13, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 11844, .adv_w = 256, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 11905, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 11996, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 12080, .adv_w = 256, .box_w = 12, .box_h = 10, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 12140, .adv_w = 256, .box_w = 14, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 12217, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 12315, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 12406, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 12519, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 12617, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 12730, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 12821, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 12949, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 13047, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 13167, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 13239, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 13344, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 13449, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 13561, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 13659, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 13764, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 13855, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 13968, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 14073, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 14193, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 14271, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 14369, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 14489, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 14587, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 14659, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 14750, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 14841, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 14954, .adv_w = 256, .box_w = 9, .box_h = 13, .ofs_x = 5, .ofs_y = 0}, + {.bitmap_index = 15013, .adv_w = 256, .box_w = 10, .box_h = 14, .ofs_x = 4, .ofs_y = -1}, + {.bitmap_index = 15083, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 15181, .adv_w = 256, .box_w = 14, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 15251, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 15349, .adv_w = 256, .box_w = 11, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 15421, .adv_w = 256, .box_w = 14, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 15505, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 15618, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 15723, .adv_w = 256, .box_w = 11, .box_h = 13, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 15795, .adv_w = 256, .box_w = 12, .box_h = 15, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 15885, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 15969, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 16047, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 16152, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 16250, .adv_w = 256, .box_w = 15, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 16340, .adv_w = 256, .box_w = 15, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 16430, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 16528, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 16633, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 16738, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 16829, .adv_w = 256, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 16906, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 17004, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 17095, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 17186, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 17258, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 17356, .adv_w = 256, .box_w = 12, .box_h = 9, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 17410, .adv_w = 256, .box_w = 10, .box_h = 10, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 17460, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 17538, .adv_w = 256, .box_w = 13, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 17629, .adv_w = 256, .box_w = 10, .box_h = 14, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 17699, .adv_w = 256, .box_w = 15, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 17797, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 17875, .adv_w = 256, .box_w = 12, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 17941, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 18019, .adv_w = 256, .box_w = 13, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 18104, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 18176, .adv_w = 256, .box_w = 14, .box_h = 3, .ofs_x = 1, .ofs_y = 5}, + {.bitmap_index = 18197, .adv_w = 256, .box_w = 16, .box_h = 2, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 18213, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 18318, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18438, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 18551, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 18642, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 18754, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 18866, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 18978, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19098, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 19210, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 19330, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 19442, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 19562, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 19660, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 19780, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 19908, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20036, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 20156, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20284, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 20404, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 20524, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 20636, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 20734, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 20847, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 20967, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 21079, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 21175, .adv_w = 256, .box_w = 16, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 21279, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 21391, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 21511, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 21639, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 21767, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 21880, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22000, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22128, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22256, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 22376, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22496, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 22616, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22744, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 22864, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 22992, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23120, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 23240, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23368, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 23488, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 23608, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23736, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 23856, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 23984, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 24104, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24232, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 24352, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 24472, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 24592, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 24712, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 24832, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 24960, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 25080, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 25200, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25328, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25456, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 25576, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 25704, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 25824, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 25936, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26056, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26184, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26312, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 26432, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26560, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26688, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 26808, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 26936, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 27056, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27176, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 27296, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 27416, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 27536, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 27656, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 27776, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 27904, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28032, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28160, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 28280, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 28400, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 28520, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 28640, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 28753, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 28873, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29001, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29129, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29257, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29385, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29513, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29633, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29753, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 29881, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30001, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30121, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30241, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30369, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30497, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30617, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 30745, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 30850, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 30970, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31083, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31203, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31323, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31451, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31571, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31691, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 31811, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 31909, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 32007, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 32119, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 32231, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 32336, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 32434, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32562, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32690, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 32802, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 32930, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33058, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 33156, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33276, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33396, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 33501, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33614, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33734, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33847, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 33960, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34080, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34193, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34313, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34441, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34561, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34674, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34787, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 34915, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 35020, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 35132, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 35245, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35358, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35471, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35591, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35704, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35824, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 35944, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36080, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36200, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36328, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36456, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36584, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36712, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36832, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36945, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 37065, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 37185, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 37297, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 37402, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 37507, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 37619, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 37739, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 37859, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 37971, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 38091, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38211, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38331, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 38451, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38579, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 38677, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38797, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 38917, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 39029, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39157, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 39269, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39397, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39525, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39645, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 39757, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39877, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 39997, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40117, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40253, .adv_w = 256, .box_w = 12, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 40331, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 40443, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40563, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 40676, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 40789, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 40887, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 40999, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 41104, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 41224, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 41344, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 41449, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 41547, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 41660, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 41780, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 41900, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 41998, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 42103, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 42208, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 42320, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 42425, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 42530, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 42642, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 42747, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 42852, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 42957, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 43077, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 43197, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 43310, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 43430, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 43528, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 43648, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 43768, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 43881, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 43994, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 44099, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 44212, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 44332, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 44452, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 44564, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 44662, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 44774, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 44879, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 44984, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 45089, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 45209, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 45329, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 45427, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 45525, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 45623, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 45721, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 45819, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 45917, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 46015, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 46113, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 46211, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 46309, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 46421, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 46541, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 46654, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 46766, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 46886, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47014, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 47126, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 47238, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 47358, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47478, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 47590, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47710, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47830, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 47958, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 48078, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48198, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 48311, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 48424, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48544, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48664, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 48776, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 48889, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49009, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49137, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49257, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 49369, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 49489, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 49609, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49737, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 49865, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .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 = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50345, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50465, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50585, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 50697, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50817, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 50945, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51073, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51201, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51329, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51449, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51562, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51690, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 51802, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 51922, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52050, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52170, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52298, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52426, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 52554, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52674, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52794, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 52914, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53042, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53155, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53275, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53387, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 53492, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53612, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53732, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 53852, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 53980, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54108, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 54228, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 54333, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 54453, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 54558, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 54678, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 54790, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 54918, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 55023, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 55128, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55248, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 55360, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 55488, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 55608, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 55728, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 55833, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 55938, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56058, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 56171, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 56284, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 56404, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 56517, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 56622, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 56750, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 56870, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 56990, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57118, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57238, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 57350, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57470, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 57590, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57718, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 57830, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 57950, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 58070, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58190, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58310, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 58408, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58528, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58656, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58776, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 58881, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 58994, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 59099, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59219, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59339, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 59451, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 59564, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 59662, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 59782, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 59894, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60014, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 60134, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 60230, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 60350, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 60470, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 60568, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 60666, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 60786, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 60906, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 61019, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 61139, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 61252, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61380, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 61500, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 61620, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 61733, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 61845, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 61943, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 62041, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 62153, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 62273, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 62385, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62505, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62633, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62761, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 62889, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63017, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63145, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63273, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63401, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63529, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63657, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63785, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 63913, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64033, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 64145, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 64257, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 64355, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 64460, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64580, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64708, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 64836, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 64934, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65062, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65182, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65310, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65430, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65550, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 65678, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65798, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 65918, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66038, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 66158, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66278, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66398, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66518, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66631, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66751, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66863, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 66983, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 67103, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 67215, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 67335, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 67455, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 67575, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 67695, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 67800, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 67905, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68025, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68137, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68257, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68377, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68489, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68601, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68713, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68818, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 68931, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 69036, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 69148, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69268, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 69388, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 69508, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69628, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 69726, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69846, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 69974, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 70094, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70214, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70334, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 70439, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70567, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70687, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 70807, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 70927, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71055, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 71175, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71288, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71408, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71528, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71648, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71768, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 71888, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72008, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 72113, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72233, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 72353, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 72465, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72585, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 72697, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 72825, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 72945, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 73065, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73193, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 73313, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73433, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 73553, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73681, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73801, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 73929, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74057, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 74169, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74289, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74409, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74529, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 74641, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74761, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 74881, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 74993, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75113, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75241, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75361, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 75473, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75601, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75721, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 75841, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 75961, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76089, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76217, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76337, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76465, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76593, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76721, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76849, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 76969, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 77089, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 77209, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77337, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 77457, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 77577, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 77690, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77810, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 77938, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78066, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78194, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78322, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 78450, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 78563, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 78647, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 78745, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 78857, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 78962, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79082, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 79187, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79300, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 79412, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 79517, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 79630, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 79750, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 79863, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 79983, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 80103, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 80208, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 80328, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 80448, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 80560, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 80665, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 80778, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 80891, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 80996, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 81116, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 81229, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81349, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 81454, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 81552, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 81672, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 81784, .adv_w = 256, .box_w = 12, .box_h = 15, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 81874, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 81986, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 82098, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 82218, .adv_w = 256, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82316, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 82436, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82549, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82669, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 82789, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 82902, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83022, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 83134, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 83246, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 83358, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 83470, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 83590, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83710, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 83830, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 83958, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84070, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84190, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84302, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84414, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84526, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84638, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84750, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84862, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 84974, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 85086, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 85198, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 85310, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 85430, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85558, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85686, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 85806, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 85926, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86054, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86174, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86294, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86414, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86534, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86646, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 86766, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 86894, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87022, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 87134, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 87254, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 87374, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 87494, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 87606, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 87718, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 87838, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 87950, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88070, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 88190, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88318, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88446, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 88566, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88686, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88814, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 88942, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89070, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 89190, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89318, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 89430, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 89542, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89662, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89775, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 89895, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 90007, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90127, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 90239, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90359, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90479, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 90591, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90711, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90839, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 90959, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91087, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91215, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 91327, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 91440, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 91545, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 91650, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 91770, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 91898, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92018, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92138, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 92258, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 92370, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92498, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 92610, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92730, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92850, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92978, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 93083, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 93203, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93331, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 93444, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93557, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93677, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93805, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 93933, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94061, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 94181, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94301, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 94414, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 94534, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94662, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94790, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 94902, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 95022, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95150, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 95255, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 95375, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 95495, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95623, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 95735, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95855, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 95983, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96103, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96231, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 96351, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96479, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 96591, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 96711, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 96831, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 96951, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97071, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 97183, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97303, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 97415, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97535, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97663, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 97791, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 97904, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98032, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98152, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98272, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98400, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98528, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98648, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 98776, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 98881, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 99001, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99129, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 99249, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 99354, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 99466, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 99578, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99706, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 99818, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99938, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100066, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100194, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100322, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100442, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100570, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 100675, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100803, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100923, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101043, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101171, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101291, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 101403, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101523, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 101635, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 101747, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 101859, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 101987, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102107, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102212, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 102310, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 102408, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 102506, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 102604, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 102717, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 102822, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 102920, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103040, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 103145, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 103265, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 103377, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103497, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 103595, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103723, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 103843, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 103963, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104091, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 104219, .adv_w = 256, .box_w = 12, .box_h = 15, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 104309, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 104407, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 104519, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 104617, .adv_w = 256, .box_w = 16, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 104721, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 104841, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 104925, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 105045, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105158, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 105278, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105406, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 105519, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 105631, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 105744, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105864, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 105992, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 106097, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 106209, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 106329, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 106441, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 106561, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 106673, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 106793, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 106905, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 107025, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107161, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107274, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 107394, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 107506, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 107634, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 107754, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 107866, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 107978, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 108090, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108218, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108346, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 108466, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 108586, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108706, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 108834, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 108939, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 109059, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 109179, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 109291, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 109411, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109531, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109659, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109787, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 109915, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 110035, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 110155, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 110275, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 110395, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 110523, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 110643, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 110763, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 110883, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 111003, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 111115, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 111235, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 111355, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 111468, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 111588, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111708, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 111836, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 111948, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 112061, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 112174, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112302, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 112422, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 112550, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 112670, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 112790, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 112910, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113038, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113166, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113294, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 113414, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 113534, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 113647, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 113767, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 113887, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 114007, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 114120, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114248, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 114368, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 114488, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114616, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114744, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 114864, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 114992, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115120, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115248, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 115376, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.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 = -1}, + {.bitmap_index = 115736, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 115834, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 115946, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116066, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 116178, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 116290, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 116402, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 116507, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116635, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 116747, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 116867, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 116987, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 117092, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 117197, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 117302, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 117415, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117535, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117663, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 117776, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 117904, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118024, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118144, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118272, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118385, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118505, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 118633, .adv_w = 256, .box_w = 12, .box_h = 15, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 118723, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 118835, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 118947, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 119067, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 119187, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 119307, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 119435, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 119563, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 119691, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 119803, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 119923, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 120035, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 120147, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 120259, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 120357, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120477, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 120589, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 120709, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 120821, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 120933, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 121045, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 121157, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 121269, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 121381, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 121493, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 121605, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121725, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121845, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 121965, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122093, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122221, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122341, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 122453, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122581, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 122693, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 122813, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 122941, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123069, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 123174, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123294, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123414, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123534, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123662, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123782, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 123910, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 124038, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 124158, .adv_w = 256, .box_w = 14, .box_h = 17, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 124277, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 124405, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 124533, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 124653, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 124766, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 124894, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 125022, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 125150, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 125270, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 125398, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 125526, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 125646, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 125782, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 125910, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 126030, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 126150, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 126270, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 126398, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 126518, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 126638, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 126758, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 126886, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 127014, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 127134, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 127262, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 127390, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 127518, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 127638, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 127758, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 127878, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 128006, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 128126, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 128254, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 128374, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 128494, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 128614, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 128742, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 128862, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 128990, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 129118, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 129246, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 129374, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 129486, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 129614, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 129734, .adv_w = 256, .box_w = 15, .box_h = 17, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 129862, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 129982, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130102, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130230, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130358, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130478, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130598, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130718, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130831, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 130951, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 131079, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 131199, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 131327, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 131463, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 131583, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 131695, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 131815, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 131935, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 132055, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 132175, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 132295, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 132415, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 132535, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 132655, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 132775, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 132887, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 133007, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 133127, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 133247, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 133375, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 133495, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 133607, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 133727, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 133855, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 133975, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 134103, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 134223, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 134343, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 134463, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 134583, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 134711, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 134839, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 134959, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 135087, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 135215, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 135343, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 135471, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.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 = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 135847, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 135975, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 136103, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 136223, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 136343, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 136463, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 136583, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 136711, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 136839, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 136959, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 137087, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 137207, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 137335, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 137463, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 137583, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 137711, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 137831, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 137959, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 138087, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 138215, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 138343, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 138471, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 138584, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 138712, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 138832, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 138952, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 139080, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 139208, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 139328, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 139448, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 139576, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 139696, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 139816, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 139936, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 140048, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 140168, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 140288, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 140416, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 140536, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 140664, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 140784, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 140904, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 141024, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 141144, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 141249, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 141354, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 141459, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 141557, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 141655, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 141760, .adv_w = 256, .box_w = 14, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 141872, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 141992, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 142105, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 142225, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 142345, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 142465, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 142578, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 142691, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 142811, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 142931, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 143044, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 143164, .adv_w = 256, .box_w = 15, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 143284, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 143412, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 143532, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 143660, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 143780, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 143908, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 144036, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 144156, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 144268, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 144366, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 144486, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 144591, .adv_w = 256, .box_w = 14, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 144696, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 144816, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 144928, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 145056, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 145169, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 145281, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 145393, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 145521, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 145641, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 145761, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 145874, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 145994, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 146122, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 146242, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 146370, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 146498, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 146618, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 146738, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 146866, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 146986, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 147114, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 147242, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 147362, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 147482, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 147610, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 147738, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 147866, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 147986, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 148106, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 148226, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 148346, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 148466, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 148594, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 148714, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 148842, .adv_w = 256, .box_w = 15, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 148947, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 149060, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 149188, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 149324, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 149444, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 149564, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 149692, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 149812, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 149932, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 150052, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 150172, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 150292, .adv_w = 256, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 150412, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 150548, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 150644, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 150756, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 150852, .adv_w = 176, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 150918, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 151046, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 151174, .adv_w = 288, .box_w = 18, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 151300, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 151428, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 151536, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 151664, .adv_w = 128, .box_w = 8, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 151720, .adv_w = 192, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 151804, .adv_w = 288, .box_w = 18, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 151948, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 152044, .adv_w = 176, .box_w = 11, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 152132, .adv_w = 224, .box_w = 10, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 152212, .adv_w = 224, .box_w = 14, .box_h = 18, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 152338, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 152443, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 152541, .adv_w = 224, .box_w = 10, .box_h = 16, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 152621, .adv_w = 224, .box_w = 16, .box_h = 14, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 152733, .adv_w = 160, .box_w = 10, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 152803, .adv_w = 160, .box_w = 10, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 152873, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 152971, .adv_w = 224, .box_w = 14, .box_h = 4, .ofs_x = 0, .ofs_y = 4}, + {.bitmap_index = 152999, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 153107, .adv_w = 320, .box_w = 20, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 153267, .adv_w = 288, .box_w = 20, .box_h = 16, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 153427, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 153555, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 153625, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 153695, .adv_w = 320, .box_w = 20, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 153835, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 153931, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 154059, .adv_w = 256, .box_w = 17, .box_h = 17, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 154204, .adv_w = 224, .box_w = 15, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 154309, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 154421, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 154519, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 154617, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 154713, .adv_w = 160, .box_w = 12, .box_h = 16, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 154809, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 154921, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 155033, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 155141, .adv_w = 256, .box_w = 18, .box_h = 18, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 155303, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 155399, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 155549, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 155649, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 155749, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 155849, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 155949, .adv_w = 320, .box_w = 20, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 156049, .adv_w = 320, .box_w = 21, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 156196, .adv_w = 224, .box_w = 12, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 156292, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 156404, .adv_w = 256, .box_w = 17, .box_h = 17, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 156549, .adv_w = 320, .box_w = 20, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 156669, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 156765, .adv_w = 258, .box_w = 17, .box_h = 11, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 156859, .adv_w = 256, .box_w = 5, .box_h = 16, .ofs_x = 11, .ofs_y = -2}, + {.bitmap_index = 156899, .adv_w = 256, .box_w = 5, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 156939, .adv_w = 256, .box_w = 4, .box_h = 6, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 156951, .adv_w = 256, .box_w = 9, .box_h = 12, .ofs_x = 4, .ofs_y = 0}, + {.bitmap_index = 157005, .adv_w = 256, .box_w = 10, .box_h = 12, .ofs_x = 3, .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 = 95, .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 = 96, + .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 = 108, + .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 = 132, + .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 = 175, + .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 = 247, + .unicode_list = unicode_list_5, .glyph_id_ofs_list = NULL, .list_length = 1187, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + } +}; + +/*----------------- + * KERNING + *----------------*/ + + +/*Map glyph_ids to kern left classes*/ +static const uint8_t kern_left_class_mapping[] = { + 0, 0, 0, 1, 0, 0, 0, 0, + 1, 2, 0, 0, 0, 3, 4, 3, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 6, 0, 0, 0, + 0, 0, 7, 8, 9, 10, 11, 12, + 13, 0, 0, 14, 15, 16, 0, 0, + 10, 17, 10, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 2, 27, 0, 0, + 0, 0, 28, 29, 30, 0, 31, 32, + 33, 34, 0, 0, 35, 36, 34, 34, + 29, 29, 37, 38, 39, 40, 37, 41, + 42, 43, 44, 45, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 46, 47, 48, + 49, 50, 0, 51, 0, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 0, + 62, 63, 0, 64, 65, 0, 66, 67, + 67, 68, 69, 0, 70, 71, 72, 73, + 74, 75, 76, 0, 77, 78, 79, 80, + 81, 82, 82, 83, 0, 84, 85, 86, + 86, 87, 88, 89, 0, 0, 90, 91, + 79, 0, 67, 92, 93, 94, 0, 95, + 0, 96, 97, 98, 99, 100, 0, 101, + 0, 102, 58, 103, 0, 104, 105, 0, + 0, 106, 107, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 0, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 0, + 134, 135, 136, 137, 138, 0, 139, 0, + 140, 141, 142, 115, 0, 0, 0, 0, + 143, 0, 144, 145, 0, 46, 146, 147, + 0, 148, 149, 150, 151, 152, 0, 153, + 154, 0, 155, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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 +}; + +/*Map glyph_ids to kern right classes*/ +static const uint8_t kern_right_class_mapping[] = { + 0, 0, 1, 2, 0, 0, 0, 0, + 2, 0, 3, 4, 0, 5, 6, 7, + 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 10, 0, 0, 0, + 11, 0, 12, 0, 13, 0, 0, 0, + 13, 0, 0, 14, 0, 0, 0, 0, + 13, 0, 13, 0, 15, 16, 17, 18, + 19, 20, 21, 22, 0, 23, 3, 0, + 0, 0, 24, 0, 25, 25, 25, 26, + 27, 0, 28, 29, 0, 0, 30, 30, + 25, 30, 25, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 0, 0, 3, 0, + 39, 40, 0, 0, 0, 0, 41, 42, + 43, 44, 45, 0, 46, 47, 48, 49, + 50, 51, 52, 0, 0, 53, 53, 53, + 53, 0, 0, 54, 55, 56, 56, 57, + 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 0, 0, 0, 69, + 70, 71, 71, 72, 72, 72, 73, 74, + 75, 76, 76, 76, 0, 0, 0, 77, + 78, 0, 0, 79, 80, 81, 82, 0, + 83, 84, 0, 85, 86, 87, 88, 0, + 71, 0, 89, 90, 91, 92, 93, 94, + 95, 0, 96, 96, 0, 0, 97, 98, + 0, 99, 100, 100, 101, 102, 103, 103, + 104, 105, 106, 106, 107, 108, 109, 106, + 89, 110, 111, 112, 113, 114, 115, 106, + 116, 117, 118, 119, 120, 0, 0, 0, + 121, 122, 123, 124, 125, 0, 0, 0, + 126, 127, 128, 129, 0, 130, 131, 132, + 0, 0, 133, 0, 134, 135, 0, 0, + 136, 0, 137, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 138, + 0, 0 +}; + +/*Kern values between classes*/ +static const int8_t kern_class_values[] = { + 0, 0, 0, 0, -32, 0, -32, 0, + 0, 0, 0, -15, 0, -26, -3, 0, + 0, 0, 0, -3, 0, 0, 0, 0, + -9, 0, 0, 0, 0, 0, -6, 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, -6, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 23, 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, -26, 0, -38, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -28, -5, -18, -9, 0, + -26, 0, 0, 0, -3, 0, 0, 0, + 7, 0, 0, -12, 0, -9, -6, 0, + -6, 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, -6, -5, -13, 0, -5, + -3, -7, -18, -6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -8, 0, -2, + 0, -4, 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, -12, -3, -23, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -7, + -9, 0, -3, 8, 8, 0, 0, 3, + -6, 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, -15, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -7, 0, + 0, 0, 0, 0, 0, 0, 1, 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, -15, 0, -27, + 0, 0, 0, 0, 0, 0, -7, -2, + -3, 0, 0, -15, -5, -4, 0, 2, + -4, -2, -12, 7, 0, -3, 0, 0, + 0, 0, 7, -4, -2, -2, -1, -1, + -2, 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, -9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -4, -4, -7, 0, -1, + -1, -1, -4, -1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -3, 0, -4, + -3, -3, -4, 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, -7, 0, 0, + 0, 0, 0, 0, -8, -3, -7, -5, + -4, -1, -1, -1, -2, -3, 0, 0, + 0, 0, -6, 0, 0, 0, 0, -7, + -3, -4, -3, 0, -4, 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, -10, 0, 0, + 0, -5, 0, 0, 0, -3, 0, -11, + 0, -7, 0, -3, -2, -5, -6, -6, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -4, 0, -2, + 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, -3, 0, 0, 0, + 0, 0, 0, -7, 0, -3, 0, -8, + -3, 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, -20, 0, -20, -21, 0, 0, + 0, -11, -3, -40, -5, 0, 0, 2, + 2, -7, 1, -9, 0, -9, -4, 0, + -7, 0, 0, -6, -5, -3, -4, -5, + -4, -7, -4, -7, 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, -8, 0, 0, 0, 0, + 0, 0, 0, -1, 0, 0, 0, -6, + 0, -4, -1, 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, -7, 0, + -7, 0, 0, 0, 0, 0, 0, -12, + 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, -5, 0, -12, + 0, -7, 0, 0, 0, 0, -2, -3, + -5, 0, -2, -5, -4, -3, -3, 0, + -4, 0, 0, 0, -2, 0, 0, 0, + -3, 0, 0, -9, -4, -5, -4, -4, + -5, -4, 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, -23, + 0, -43, 0, -16, 0, 0, 0, 0, + -8, 1, -7, 0, -6, -34, -8, -22, + -16, 0, -21, 0, -23, 0, -3, -4, + -1, 0, 0, 0, 0, -5, -3, -9, + -9, 0, -9, 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, -31, -10, -31, -23, + 0, 0, 0, -14, 0, -42, -3, -7, + 0, 0, 0, -7, -3, -23, 0, -13, + -7, 0, -9, 0, 0, 0, -3, 0, + 0, 0, 0, -4, 0, -6, 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, -3, 0, -9, + 0, 0, 0, 0, 0, -1, 0, -5, + -4, -4, 0, 2, 2, -1, 0, -3, + 0, -1, -3, 0, -1, 0, 0, 0, + 0, 0, 0, 0, 0, -2, 0, -2, + 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, -5, + 0, 4, 0, 0, 0, 0, 0, 0, + 0, -4, -4, -6, 0, 0, 0, 0, + -4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -7, 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, -30, -21, -30, -26, -6, -6, + 0, -12, -7, -36, -12, 0, 0, 0, + 0, -6, -4, -16, 0, -21, -18, -5, + -21, 0, 0, -13, -17, -5, -13, -10, + -10, -12, -10, -22, 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, -4, 0, -4, -9, + 0, 0, 0, -5, 0, -13, -3, 0, + 0, -1, 0, -3, -4, 0, 0, -1, + 0, 0, -3, 0, 0, 0, -1, 0, + 0, 0, 0, -2, 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, -18, -5, + -18, -14, 0, 0, 0, -4, -3, -21, + -3, 0, -3, 3, 0, 0, 0, -5, + 0, -6, -4, 0, -6, 0, 0, -6, + -3, 0, -9, -3, -3, -4, -3, -7, + 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, + -9, -3, -9, -9, 0, 0, 0, 0, + -2, -19, -2, 0, 0, 0, 0, 0, + 0, -2, 0, -5, 0, 0, -4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -3, 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, -3, + 0, -3, 0, -7, 0, 0, 0, 0, + 0, 1, -5, 0, -4, -6, -3, 0, + 0, 0, 0, 0, 0, -3, -2, -4, + 0, 0, 0, 0, 0, -4, -3, -4, + -4, -3, -4, -4, 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, -25, -18, -25, -20, + -7, -7, -2, -4, -4, -28, -4, -4, + -3, 0, 0, 0, 0, -8, 0, -19, + -11, 0, -17, 0, 0, -12, -11, -7, + -9, -4, -7, -9, -4, -13, 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, -10, + 0, 0, 0, 0, 0, -2, -6, -10, + -9, 0, -3, -2, -2, 0, -4, -5, + 0, -5, -6, -6, -4, 0, 0, 0, + 0, -4, -7, -5, -5, -7, -5, 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, -25, -9, -15, -9, 0, + -21, 0, 0, 0, 0, 0, 10, 0, + 21, 0, 0, 0, 0, -6, -3, 0, + 4, 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, -16, 0, 0, 0, 0, 0, 0, + -3, 0, 0, 0, 0, -7, 0, -4, + -1, 0, -7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -4, 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, -9, 0, -8, -3, 2, -3, 0, + 0, 0, -3, 0, 0, 0, 0, -16, + 0, -5, 0, -1, -13, 0, -7, -4, + 0, 0, 0, 0, 0, 0, 0, -5, + 0, -1, -1, -5, -1, -1, 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, -5, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -6, 0, -4, 0, 0, -7, 0, + 0, -3, -6, 0, -3, 0, 0, 0, + 0, -3, 0, 2, 2, 3, 2, 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, -10, + 0, 3, 0, 0, 0, 0, -2, 0, + 0, -6, -6, -7, 0, -4, -3, 0, + -7, 0, -5, -4, 0, 0, -3, 0, + 0, 0, 0, -3, 0, 2, 2, -2, + 2, 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, 4, 12, + 15, 0, -14, -4, -14, -4, 0, 0, + 8, 0, 0, 0, 0, 13, 0, 19, + 13, 10, 17, 0, 19, -6, -3, 0, + -4, 0, -3, 0, -1, 0, 0, 4, + 0, -1, 0, -4, 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, 4, -10, 0, 0, 0, 14, + 0, 0, -10, 0, 0, 0, 0, -7, + 0, 0, 0, 0, -4, 0, 0, -4, + -4, 0, 0, 0, 10, 0, 0, 0, + 0, -1, -1, 0, 5, -4, 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, -10, 0, 0, + 0, 0, 0, 0, -2, 0, 0, 0, + 0, -7, 0, -3, 0, 0, -4, 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, -6, + 4, -11, 4, 0, 4, 4, -3, 0, + 0, 0, 0, -9, 0, 0, 0, 0, + -3, 0, 0, -3, -5, 0, -3, 0, + -3, 0, 0, -5, -4, 0, 0, -2, + 0, -2, 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, 2, 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, -7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -6, + 0, -4, 0, 0, -9, 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, -15, -7, + -15, -10, 8, 8, 0, -4, 0, -15, + 0, 0, 0, 0, 0, 0, 0, -3, + 4, -7, -3, 0, -3, 0, 0, 0, + -1, 0, 0, 8, 6, 0, 8, -1, + 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, -15, + 0, 3, 0, 0, 0, 0, -3, 0, + 0, 0, 0, -7, 0, -3, 0, 0, + -6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -6, 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, 3, -7, 3, 3, 4, 4, + -7, 0, 0, 0, 0, -4, 0, 0, + 0, 0, -1, 0, 0, -6, -4, 0, + -3, 0, 0, 0, -3, -6, 0, 0, + 0, -5, 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, -3, -9, -2, -9, -6, + 0, 0, 0, -3, 0, -12, 0, -6, + 0, -3, 0, 0, -4, -3, 0, -6, + -1, 0, 0, 0, -3, 0, 0, 0, + 0, 0, 0, 0, 0, -7, 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, -3, -10, 0, + -10, -2, 0, 0, 0, -1, 0, -9, + 0, -7, 0, -3, 0, -4, -7, 0, + 0, -3, -1, 0, 0, 0, -3, 0, + 0, 0, 0, 0, 0, 0, 0, -5, + 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, -4, 0, 0, -6, + 2, -4, -2, 0, 0, 2, 0, 0, + -3, 0, -1, -10, 0, -4, 0, -3, + -9, 0, 0, -3, -5, 0, 0, 0, + 0, 0, 0, -7, 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, -9, 0, -9, -4, 0, 0, + 0, 0, 0, -12, 0, -6, 0, -1, + 0, -1, -2, 0, 0, -6, -1, 0, + 0, 0, -3, 0, 0, 0, 0, 0, + 0, -4, 0, -7, 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, -4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -8, + 0, 0, 0, 0, -9, 0, 0, -7, + -3, 0, -2, 0, 0, 0, 0, 0, + -3, -1, 0, 0, -1, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -5, -5, 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, 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, -5, -5, 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, -3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, 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, -5, -5, 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, 0, + 0, 0, 0, 0, 0, 0, 0, -8, + -8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -5, 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, -15, 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, -5, -5, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -26, 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, -8, -8, -8, -8, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -8, -8, -13, -8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -18, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, -5, 0, -5, + -5, 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, -5, -5, 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, -10, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -13, 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, -15, + 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, -5, -5, + 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, -13, 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, -15, 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, + -18, -13, 0, -10, 0, -5, -8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -5, + 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, -8, 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, -13, -13, 0, -5, 0, 0, + -5, 0, 0, 0, 0, 0, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, + -10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -5, 0, -8, -13, 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, -15, 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, -5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -8, -8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 0, + 0, 0, 0, -5, 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, -8, + 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, -8, 0, + 0, 0, 0, -5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, + 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 8, 0, 0, + 0, 0, 0, 0, 0, -5, 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, -13, 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, + -13, -13, 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, -13, 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, -18, -13, 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, -26, 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, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -5, -5, 0, 0, 0, + 0, 0, -18, 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, -13, + 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, 3, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 3, + 3, 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, 3, 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, -10, 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, -5, -5, 0, 0, 0, 0, 0, + 0, -15, -15, -8, -8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -5, 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, -20, -26, 0, -5, + 0, 0, -10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -10, 0, 0, 3, 3, 0, + 0, 0, 0, 0, 0, 0, -5, -5, + -5, -18, 0, 0, 0, -5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -15, 0, 0, 0, 0, 0, + 0, -18, -23, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -10, + 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, -18, -26, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -13, 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, -18, 0, 0, 0, + 0, 0, 0, -18, -18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -13, 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, 5, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 8, 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -13, 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, 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, -13, 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, -8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -15, 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, -5, + 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, -8, -8, + 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, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -15, + 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, -13, 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, -13, 0, 0, 0, 0, 8, 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, -10, -10, 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, -13, 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, -8, -8, 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, -10, + 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, -13, -8, + -8, 0, 0, 0, 0, -8, 0, 0, + -8, -8, -8, -8, 0, 0, 0, 0, + -8, 0, 0, 0, -15, -5, -5, 0, + 0, 0, 0, 0, 0, -5, -5, 0, + 0, 0, 0, 0, -13, 0, -13, 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, -18, 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, + -10, -10, -3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 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, -10, 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, -10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -8, 0, + 0, -8, -8, 0, -8, 0, 0, 0, + -8, -10, -10, -8, -8, 0, 0, -8, + -3, 0, 0, 0, 0, 0, 0, -13, + 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, -10, 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, -13, -13, 0, 0, + 0, 0, 0, 0, 0, 0, -8, -8, + -8, -8, -8, 0, 0, 0, -8, 0, + 0, 0, 0, -8, -8, -5, -5, 0, + 0, -5, 0, 0, 0, 0, 0, 0, + 0, -13, 0, -8, 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, -13, + 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, -8, 0, + 0, 0, 0, 0, 0, 0, 0, -5, + 0, 0, -5, -5, -5, 3, 3, 0, + -5, 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, -13, 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, -5, -5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -5, 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, -3, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -10, 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, -8, 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, -15, + 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, -5, -5, 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, + 5, 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, 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, -8, -8, 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, -13, 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, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -18, + 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, -8, 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, -5, 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, 3, 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, -13, 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, -18, -18, -13, -13, 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, -8, 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, -10, -10, 0, + -10, 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, -8, + 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, -10, + -10, -10, -10, 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, -8, 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, 3, 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, -10, -10, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -8, 0, 0, 0, 0, + -10, 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, -13, 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, -8, 0, 0, 0, + -5, -8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -5, 0, + 0, 0, 0, -10, 0, -10, -10, -5, + -5, 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, -10, + 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, -5, + 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, -13, 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, + -8, -3, 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, -10, 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, -5, -13, 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, -5, -8, -8, 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, -13, 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, -8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -5, -8, 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, -5, -5, -5, + 0, 0, 0, 0, 0, 0, 0, -8, + -8, 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, -8, 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, + -10, -5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, + 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, -18, 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, -10, -10, 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, -5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -10, 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, 3, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -5, -5, -8, -8, 0, + 0, 0, 0, 0, 0, 0, 3, 3, + 3, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -13, 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, -5, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -13, -13, 0, -8, 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, -26, -26, 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, -5, -8, 0, + 0, 0, 0, 0, -8, -5, -5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -13, + 0, 0, 0, 0, -13, -13, 0, 0, + 0, 0, -10, 0, 0, -5, 0, 0, + 0, 0, 0, 0, 0, 0, -5, 0, + -23, -10, -10, -5, 0, 0, 0, -5, + -5, 0, -5, -18, -13, 0, 0, 0, + 0, -3, 0, -10, -15, -26, 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, -5, -5, 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, -3, -3, + -3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -3, 0, -5, -5, + 0, 0, 0, 0, 0, -8, -8, 0, + 0, -10, -10, 0, -5, 0, 0, 0, + -5, 0, 0, -5, -5, -5, 0, 0, + 0, 0, 0, 0, 0, -5, 0, 0, + -8, 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, -8, -5, + 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, + 0, 0, 0, 0, 0, 0, 0, 0, + -15, -15, 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, -5, -5, 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, -8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -13, 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, -5, 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, -8, 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, -10, -10, 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, -8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -18, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -8, 0, -8, + 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, -8, -8, + 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, -10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -18, 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, + -23, -20, 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, -3, + 0, 0, -10, -10, 0, 0, 0, 0, + 0, -8, -5, 0, 0, -10, -10, 0, + 0, 0, 0, 0, 0, 0, -15, -13, + -13, -13, 0, 0, 0, 0, 0, 0, + 0, -20, -10, 0, 0, 0, 0, -8, + 0, 0, 0, -23, 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, -18, -20, 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, -5, -5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -18, 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, -20, -23, 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, -5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, -5, 0, 0, + 0, 0, -15, -10, -10, -10, 0, 0, + 0, -8, -8, 0, -8, -18, -8, 0, + 0, 0, 0, 0, -5, -8, 0, -26, + 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, -20, -20, + 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, -8, -5, 0, -5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -8, -5, -5, -5, + 0, 0, 0, 0, 0, 0, -3, -13, + -8, 0, 0, 0, 0, 0, 0, 0, + 0, -18, 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, -10, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 5, 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, -23, -23, 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, -5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -5, -10, -10, -10, 0, 0, + 0, 0, 0, 0, 0, -5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -18, + 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, -20, -18, + 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, -3, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -5, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -15, 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, + -5, -5, 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, -8, + -8, -8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -8, 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, -8, -8, 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, -5, + -5, 0, 0, 0, 0, 0, 0, 0, + -5, -15, -15, -15, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -13, 0, -18, + 0, 0, 0, 0, 0, -8, 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, -18, -18, -8, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -5, 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, + -3, -3, 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, -8, 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, -15, -15, 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, + -8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -18, 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, -8, -8, 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, -8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -8, 0, + 0, 0, 0, 0, 0, 0, 0, -13, + 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, -13, -8, + 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, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, 0, 0, 0, 0, 0, 0, 0, + 0, -13, 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, + -15, -13, 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, -8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -5, 0, -3, 0, 0, 0, 0, + 0, 0, 0, -8, 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, -3, -3, 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, -13, 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, -20, -8, 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, -5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -13, + 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, -8, -8, + 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, -15, 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, -8, -5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -8, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -10, 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, + -8, -8, 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, -18, 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, -5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -13, 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, -5, -5, 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, -8, 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, -10, -5, 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, -5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -5, + 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, -13, -13, + 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, -13, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -8, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -20, 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, -5, 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, -5, -5, 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, -5, 0, -10, 0, + 0, -5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -5, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -5, + 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, -5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 8, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 13, + 0, 3, 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, 8, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 13, 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, -5, 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, -10, -10, 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, + -5, 0, 0, 0, 0, 0, 0, 0, + -3, 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, -8, 0, 0, + 0, 0, 0, 0, 0, 5, 0, -5, + 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, -8, -8, + 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, -8, 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, -13, 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, + -8, -8, 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, -8, 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, -5, 0, 0, + 0, 0, 0, -13, 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, -13, -8, 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, + -8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -13, 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, -15, -15, + -15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -13, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -8, 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, + -20, -20, 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, -5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -20, -5, + -5, -5, 0, 0, 0, 0, 0, 0, + 0, -8, -5, 0, 0, 0, 0, 0, + 0, 0, 0, -18, 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, -5, 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, -5, 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, -5, 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, -5, -5, + -5, 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, -5, -5, + 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, -5, -5, + -5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, -3, -3, -3, + 0, 0, 0, 0, 0, 0, 0, -8, + -8, 0, 0, 0, 0, 0, 0, 0, + 0, -13, 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, + -15, -10, 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, -8, 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, -8, 0, 0, 0, -5, + 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, -5, 0, 0, 0, 0, + 0, 0, 0, -5, 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, 0, -5, 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, -15, -15, + 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, -8, 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, -13, -3, -5, -5, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -13, 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, + -15, -15, 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, -5, -5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -5, -13, 0, + 0, 0, -8, -8, -8, 0, 0, 0, + 0, -5, -8, 0, 0, 0, 0, 0, + 0, 0, 0, -13, 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, -3, -3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -15, -15, 0, 0, 0, + 0, 0, 0, 0, -10, -10, -10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -10, -10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -5, -5, -5, -13, -13, 0, 0, 0, + 0, -5, 0, 0, 0, 0, 0, 0, + -15, -5, -3, -3, -15, -15, -15, 0, + 0, 0, 0, -8, -10, 0, 0, 0, + 0, 0, 0, -13, 0, 0 +}; + + +/*Collect the kern class' data in one place*/ +static const lv_font_fmt_txt_kern_classes_t kern_classes = { + .class_pair_values = kern_class_values, + .left_class_mapping = kern_left_class_mapping, + .right_class_mapping = kern_right_class_mapping, + .left_class_cnt = 155, + .right_class_cnt = 138, +}; + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LV_VERSION_CHECK(8, 0, 0) +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +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 = &kern_classes, + .kern_scale = 16, + .cmap_num = 6, + .bpp = 4, + .kern_classes = 1, + .bitmap_format = 0, +#if LV_VERSION_CHECK(8, 0, 0) + .cache = &cache +#endif +}; + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LVGL_VERSION_MAJOR >= 8 +const lv_font_t lv_font_source_han_sans_sc_16_cjk = { +#else +lv_font_t lv_font_source_han_sans_sc_16_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 = 20, /*The maximum line height required by the font*/ + .base_line = 5, /*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_SOURCE_HAN_SANS_SC_16_CJK*/ + diff --git a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.c b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.c index 3a4a5721a..84ac23f74 100644 --- a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.c +++ b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.c @@ -12,6 +12,7 @@ * INCLUDES ********************/ #include "lv_indev_scroll.h" +#include "lv_indev_gesture.h" #include "../display/lv_display_private.h" #include "../core/lv_global.h" #include "../core/lv_obj_private.h" @@ -71,6 +72,7 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data); static void indev_button_proc(lv_indev_t * i, lv_indev_data_t * data); static void indev_proc_press(lv_indev_t * indev); static void indev_proc_release(lv_indev_t * indev); +static lv_result_t indev_proc_short_click(lv_indev_t * indev); static void indev_proc_pointer_diff(lv_indev_t * indev); static lv_obj_t * pointer_search_obj(lv_display_t * disp, lv_point_t * p); static void indev_proc_reset_query_handler(lv_indev_t * indev); @@ -79,6 +81,7 @@ static void indev_gesture(lv_indev_t * indev); static bool indev_reset_check(lv_indev_t * indev); static void indev_read_core(lv_indev_t * indev, lv_indev_data_t * data); static void indev_reset_core(lv_indev_t * indev, lv_obj_t * obj); +static void indev_init_gesture_recognizers(lv_indev_t * indev); static lv_result_t send_event(lv_event_code_t code, void * param); static void indev_scroll_throw_anim_start(lv_indev_t * indev); @@ -139,6 +142,9 @@ lv_indev_t * lv_indev_create(void) indev->gesture_limit = LV_INDEV_DEF_GESTURE_LIMIT; indev->gesture_min_velocity = LV_INDEV_DEF_GESTURE_MIN_VELOCITY; indev->rotary_sensitivity = LV_INDEV_DEF_ROTARY_SENSITIVITY; + + indev_init_gesture_recognizers(indev); + return indev; } @@ -168,7 +174,7 @@ lv_indev_t * lv_indev_get_next(lv_indev_t * indev) void indev_read_core(lv_indev_t * indev, lv_indev_data_t * data) { - LV_PROFILER_BEGIN; + LV_PROFILER_INDEV_BEGIN; lv_memzero(data, sizeof(lv_indev_data_t)); /* For touchpad sometimes users don't set the last pressed coordinate on release. @@ -193,7 +199,8 @@ void indev_read_core(lv_indev_t * indev, lv_indev_data_t * data) else { LV_LOG_WARN("indev_read_cb is not registered"); } - LV_PROFILER_END; + + LV_PROFILER_INDEV_END; } void lv_indev_read_timer_cb(lv_timer_t * timer) @@ -221,7 +228,7 @@ void lv_indev_read(lv_indev_t * indev) return; } - LV_PROFILER_BEGIN; + LV_PROFILER_INDEV_BEGIN; bool continue_reading; lv_indev_data_t data; @@ -266,7 +273,7 @@ void lv_indev_read(lv_indev_t * indev) indev_obj_act = NULL; LV_TRACE_INDEV("finished"); - LV_PROFILER_END; + LV_PROFILER_INDEV_END; } void lv_indev_enable(lv_indev_t * indev, bool enable) @@ -367,6 +374,13 @@ void lv_indev_set_long_press_time(lv_indev_t * indev, uint16_t long_press_time) indev->long_press_time = long_press_time; } +void lv_indev_set_long_press_repeat_time(lv_indev_t * indev, uint16_t long_press_repeat_time) +{ + if(indev == NULL) return; + + indev->long_press_repeat_time = long_press_repeat_time; +} + void lv_indev_set_scroll_limit(lv_indev_t * indev, uint8_t scroll_limit) { if(indev == NULL) return; @@ -485,6 +499,11 @@ uint32_t lv_indev_get_key(const lv_indev_t * indev) return key; } +uint8_t lv_indev_get_short_click_streak(const lv_indev_t * indev) +{ + return indev->pointer.short_click_streak; +} + lv_dir_t lv_indev_get_scroll_dir(const lv_indev_t * indev) { if(indev == NULL) return false; @@ -512,6 +531,12 @@ void lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point) } } +lv_obj_t * lv_indev_get_cursor(lv_indev_t * indev) +{ + if(indev == NULL) return NULL; + return indev->cursor; +} + void lv_indev_wait_release(lv_indev_t * indev) { if(indev == NULL)return; @@ -708,6 +733,13 @@ static void indev_pointer_proc(lv_indev_t * i, lv_indev_data_t * data) i->pointer.act_point.y = data->point.y; i->pointer.diff = data->enc_diff; +#if LV_USE_GESTURE_RECOGNITION + for(int gest = 0; gest < LV_INDEV_GESTURE_CNT; gest++) { + i->gesture_type[gest] = data->gesture_type[gest]; + i->gesture_data[gest] = data->gesture_data[gest]; + } +#endif + /*Process the diff first as scrolling will be processed in indev_proc_release*/ indev_proc_pointer_diff(i); @@ -718,6 +750,7 @@ static void indev_pointer_proc(lv_indev_t * i, lv_indev_data_t * data) indev_proc_release(i); } + i->prev_state = i->state; i->pointer.last_point.x = i->pointer.act_point.x; i->pointer.last_point.y = i->pointer.act_point.y; } @@ -852,7 +885,7 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data) if(send_event(LV_EVENT_RELEASED, indev_act) == LV_RESULT_INVALID) return; if(i->long_pr_sent == 0) { - if(send_event(LV_EVENT_SHORT_CLICKED, indev_act) == LV_RESULT_INVALID) return; + if(indev_proc_short_click(i) == LV_RESULT_INVALID) return; } if(send_event(LV_EVENT_CLICKED, indev_act) == LV_RESULT_INVALID) return; @@ -864,6 +897,8 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data) indev_obj_act = NULL; } + + /** * Process a new point from LV_INDEV_TYPE_ENCODER input device * @param i pointer to an input device @@ -1015,7 +1050,7 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data) } if(i->long_pr_sent == 0 && is_enabled) { - if(send_event(LV_EVENT_SHORT_CLICKED, indev_act) == LV_RESULT_INVALID) return; + if(indev_proc_short_click(i) == LV_RESULT_INVALID) return; } if(is_enabled) { @@ -1029,7 +1064,7 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data) if(!i->long_pr_sent || lv_group_get_obj_count(g) <= 1) { if(is_enabled) { if(send_event(LV_EVENT_RELEASED, indev_act) == LV_RESULT_INVALID) return; - if(send_event(LV_EVENT_SHORT_CLICKED, indev_act) == LV_RESULT_INVALID) return; + if(indev_proc_short_click(i) == LV_RESULT_INVALID) return; if(send_event(LV_EVENT_CLICKED, indev_act) == LV_RESULT_INVALID) return; } @@ -1132,8 +1167,14 @@ static void indev_button_proc(lv_indev_t * i, lv_indev_data_t * data) i->pointer.act_point.x = x; i->pointer.act_point.y = y; - if(data->state == LV_INDEV_STATE_PRESSED) indev_proc_press(i); - else indev_proc_release(i); + if(data->state == LV_INDEV_STATE_PRESSED) { + indev_proc_press(i); + } + else { + indev_proc_release(i); + } + + i->prev_state = i->state; if(indev_reset_check(i)) return; @@ -1184,6 +1225,7 @@ static void indev_proc_press(lv_indev_t * indev) if(indev_obj_act != indev->pointer.act_obj) { indev->pointer.last_point.x = indev->pointer.act_point.x; indev->pointer.last_point.y = indev->pointer.act_point.y; + indev->pointer.pressed = indev->prev_state == LV_INDEV_STATE_RELEASED; /*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) { @@ -1225,12 +1267,19 @@ static void indev_proc_press(lv_indev_t * indev) 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 the indev was already in a pressed state it means that we got dragged here + * so we shouldn't send any hover nor pressed events for a new object since the + * originally pressed object didn't get released + */ + if(indev->prev_state != LV_INDEV_STATE_PRESSED) { + 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; } - if(send_event(LV_EVENT_PRESSED, indev_act) == LV_RESULT_INVALID) return; } if(indev_act->wait_until_release) return; @@ -1255,15 +1304,41 @@ static void indev_proc_press(lv_indev_t * indev) indev->pointer.press_moved = 1; } +#if LV_USE_GESTURE_RECOGNITION + for(int i = 0; i < LV_INDEV_GESTURE_CNT; i++) { + /* Send a gesture event to a potential indev cb callback, even if no object was found */ + if(indev->gesture_type[i] != LV_INDEV_GESTURE_NONE) { + indev->cur_gesture = (lv_indev_gesture_type_t) i; + lv_indev_send_event(indev, LV_EVENT_GESTURE, indev_act); + break; + } + } +#endif + if(indev_obj_act) { const bool is_enabled = !lv_obj_has_state(indev_obj_act, LV_STATE_DISABLED); +#if LV_USE_GESTURE_RECOGNITION + for(int i = 0; i < LV_INDEV_GESTURE_CNT; i++) { + + if(indev->gesture_type[i] != LV_INDEV_GESTURE_NONE) { + indev->cur_gesture = (lv_indev_gesture_type_t) i; + if(send_event(LV_EVENT_GESTURE, indev_act) == LV_RESULT_INVALID) return; + break; + } + } +#endif if(is_enabled) { if(send_event(LV_EVENT_PRESSING, indev_act) == LV_RESULT_INVALID) return; } + if(indev_act->wait_until_release) return; + if(indev->pointer.scroll_obj) { + lv_obj_stop_scroll_anim(indev->pointer.scroll_obj); + } + lv_indev_scroll_handler(indev); if(indev_reset_check(indev)) return; indev_gesture(indev); @@ -1326,7 +1401,10 @@ static void indev_proc_release(lv_indev_t * indev) 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; + if(indev_reset_check(indev)) { + indev->wait_until_release = 0; + return; + } indev->pointer.act_obj = NULL; indev->pointer.last_obj = NULL; @@ -1341,21 +1419,44 @@ static void indev_proc_release(lv_indev_t * indev) lv_timer_pause(indev->read_timer); } +#if LV_USE_GESTURE_RECOGNITION + /* Send a gesture event to a potential indev cb callback, even if no object was found */ + for(int i = 0; i < LV_INDEV_GESTURE_CNT; i++) { + + if(indev->gesture_type[i] != LV_INDEV_GESTURE_NONE) { + indev_act->cur_gesture = (lv_indev_gesture_type_t) i; + lv_indev_send_event(indev, LV_EVENT_GESTURE, indev_act); + break; + } + } +#endif + if(indev_obj_act) { LV_LOG_INFO("released"); const bool is_enabled = !lv_obj_has_state(indev_obj_act, LV_STATE_DISABLED); +#if LV_USE_GESTURE_RECOGNITION + for(int i = 0; i < LV_INDEV_GESTURE_CNT; i++) { + if(is_enabled && indev->gesture_type[i] != LV_INDEV_GESTURE_NONE) { + indev_act->cur_gesture = (lv_indev_gesture_type_t) i; + if(send_event(LV_EVENT_GESTURE, indev_act) == LV_RESULT_INVALID) return; + break; + } + } +#endif if(is_enabled) { if(send_event(LV_EVENT_RELEASED, indev_act) == LV_RESULT_INVALID) return; } if(is_enabled) { if(scroll_obj == NULL) { - if(indev->long_pr_sent == 0) { - if(send_event(LV_EVENT_SHORT_CLICKED, indev_act) == LV_RESULT_INVALID) return; + if(indev->pointer.pressed) { + if(indev->long_pr_sent == 0) { + if(indev_proc_short_click(indev) == LV_RESULT_INVALID) return; + } + if(send_event(LV_EVENT_CLICKED, indev_act) == LV_RESULT_INVALID) return; } - if(send_event(LV_EVENT_CLICKED, indev_act) == LV_RESULT_INVALID) return; } else { lv_obj_send_event(scroll_obj, LV_EVENT_SCROLL_THROW_BEGIN, indev_act); @@ -1382,6 +1483,14 @@ static void indev_proc_release(lv_indev_t * indev) parent = lv_obj_get_parent(parent); } + if(scale_x == 0) { + scale_x = 1; + } + + if(scale_y == 0) { + scale_y = 1; + } + if(angle != 0 || scale_y != LV_SCALE_NONE || scale_x != LV_SCALE_NONE) { angle = -angle; scale_x = (256 * 256) / scale_x; @@ -1401,6 +1510,40 @@ static void indev_proc_release(lv_indev_t * indev) } } +static lv_result_t indev_proc_short_click(lv_indev_t * indev) +{ + /*Update streak for clicks within small distance and short time*/ + indev->pointer.short_click_streak++; + if(lv_tick_elaps(indev->pointer.last_short_click_timestamp) > indev->long_press_time) { + indev->pointer.short_click_streak = 1; + } + else if(indev->type == LV_INDEV_TYPE_POINTER || indev->type == LV_INDEV_TYPE_BUTTON) { + int32_t dx = indev->pointer.last_short_click_point.x - indev->pointer.act_point.x; + int32_t dy = indev->pointer.last_short_click_point.y - indev->pointer.act_point.y; + if(dx * dx + dy * dy > indev->scroll_limit * indev->scroll_limit) indev->pointer.short_click_streak = 1; + } + + indev->pointer.last_short_click_timestamp = lv_tick_get(); + lv_indev_get_point(indev, &indev->pointer.last_short_click_point); + + /*Simple short click*/ + lv_result_t res = send_event(LV_EVENT_SHORT_CLICKED, indev_act); + if(res == LV_RESULT_INVALID) { + return res; + } + + /*Cycle through single/double/triple click*/ + switch((indev->pointer.short_click_streak - 1) % 3) { + case 0: + return send_event(LV_EVENT_SINGLE_CLICKED, indev_act); + case 1: + return send_event(LV_EVENT_DOUBLE_CLICKED, indev_act); + case 2: + return send_event(LV_EVENT_TRIPLE_CLICKED, indev_act); + } + return res; +} + static void indev_proc_pointer_diff(lv_indev_t * indev) { lv_obj_t * obj = indev->pointer.last_pressed; @@ -1644,29 +1787,29 @@ static void indev_reset_core(lv_indev_t * indev, lv_obj_t * obj) if(obj == NULL || indev->pointer.last_pressed == obj) { indev->pointer.last_pressed = NULL; } - if(obj == NULL || indev->pointer.act_obj == obj) { - if(indev->pointer.act_obj) { - /* Avoid recursive calls */ - act_obj = indev->pointer.act_obj; - indev->pointer.act_obj = NULL; - lv_obj_send_event(act_obj, LV_EVENT_INDEV_RESET, indev); - lv_indev_send_event(indev, LV_EVENT_INDEV_RESET, act_obj); - act_obj = NULL; - } + + if(indev->pointer.act_obj) { + /* Avoid recursive calls */ + act_obj = indev->pointer.act_obj; + indev->pointer.act_obj = NULL; + lv_obj_send_event(act_obj, LV_EVENT_INDEV_RESET, indev); + lv_indev_send_event(indev, LV_EVENT_INDEV_RESET, act_obj); + act_obj = NULL; } + if(obj == NULL || indev->pointer.last_obj == obj) { indev->pointer.last_obj = NULL; } - if(obj == NULL || indev->pointer.scroll_obj == obj) { - if(indev->pointer.scroll_obj) { - /* Avoid recursive calls */ - scroll_obj = indev->pointer.scroll_obj; - indev->pointer.scroll_obj = NULL; - lv_obj_send_event(scroll_obj, LV_EVENT_INDEV_RESET, indev); - lv_indev_send_event(indev, LV_EVENT_INDEV_RESET, act_obj); - scroll_obj = NULL; - } + + if(indev->pointer.scroll_obj) { + /* Avoid recursive calls */ + scroll_obj = indev->pointer.scroll_obj; + indev->pointer.scroll_obj = NULL; + lv_obj_send_event(scroll_obj, LV_EVENT_INDEV_RESET, indev); + lv_indev_send_event(indev, LV_EVENT_INDEV_RESET, scroll_obj); + scroll_obj = NULL; } + if(obj == NULL || indev->pointer.last_hovered == obj) { indev->pointer.last_hovered = NULL; } @@ -1739,3 +1882,21 @@ static void indev_scroll_throw_anim_start(lv_indev_t * indev) indev->scroll_throw_anim = lv_anim_start(&a); } + +/** + * Initialize this indev's recognizers. It specify their recognizer function + * @param indev pointer to the indev containing the recognizers to initialize + */ +static void indev_init_gesture_recognizers(lv_indev_t * indev) +{ +#if LV_USE_GESTURE_RECOGNITION + indev->recognizers[LV_INDEV_GESTURE_NONE].recog_fn = NULL; + indev->recognizers[LV_INDEV_GESTURE_PINCH].recog_fn = lv_indev_gesture_detect_pinch; + indev->recognizers[LV_INDEV_GESTURE_ROTATE].recog_fn = lv_indev_gesture_detect_rotation; + indev->recognizers[LV_INDEV_GESTURE_TWO_FINGERS_SWIPE].recog_fn = lv_indev_gesture_detect_two_fingers_swipe; + indev->recognizers[LV_INDEV_GESTURE_SCROLL].recog_fn = NULL; + indev->recognizers[LV_INDEV_GESTURE_SWIPE].recog_fn = NULL; +#else + LV_UNUSED(indev); +#endif +} diff --git a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.h b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.h index 9b0ee4518..d6c60c404 100644 --- a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.h +++ b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev.h @@ -47,6 +47,18 @@ typedef enum { LV_INDEV_MODE_EVENT, } lv_indev_mode_t; + +/* Supported types of gestures */ +typedef enum { + LV_INDEV_GESTURE_NONE = 0, + LV_INDEV_GESTURE_PINCH, + LV_INDEV_GESTURE_SWIPE, + LV_INDEV_GESTURE_ROTATE, + LV_INDEV_GESTURE_TWO_FINGERS_SWIPE, + LV_INDEV_GESTURE_SCROLL, /* Used with scrollwheels */ + LV_INDEV_GESTURE_CNT, /* Total number of gestures types */ +} lv_indev_gesture_type_t; + /** Data structure passed to an input driver to fill*/ typedef struct { lv_point_t point; /**< For LV_INDEV_TYPE_POINTER the currently pressed point*/ @@ -56,6 +68,10 @@ typedef struct { 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_gesture_type_t gesture_type[LV_INDEV_GESTURE_CNT]; /* Current gesture types, per gesture */ + void * gesture_data[LV_INDEV_GESTURE_CNT]; /* Used to store data per gesture */ + } lv_indev_data_t; typedef void (*lv_indev_read_cb_t)(lv_indev_t * indev, lv_indev_data_t * data); @@ -143,7 +159,7 @@ 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 @@ -152,6 +168,13 @@ 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); +/** + * Set long press repeat time to indev + * @param indev pointer to input device + * @param long_press_repeat_time long press repeat time in ms + */ +void lv_indev_set_long_press_repeat_time(lv_indev_t * indev, uint16_t long_press_repeat_time); + /** * Set scroll limit to the input device * @param indev pointer to an input device @@ -285,6 +308,15 @@ lv_dir_t lv_indev_get_gesture_dir(const lv_indev_t * indev); */ uint32_t lv_indev_get_key(const lv_indev_t * indev); + +/** + * Get the counter for consecutive clicks within a short distance and time. + * The counter is updated before LV_EVENT_SHORT_CLICKED is fired. + * @param indev pointer to an input device + * @return short click streak counter + */ +uint8_t lv_indev_get_short_click_streak(const lv_indev_t * indev); + /** * Check the current scroll direction of an input device (for LV_INDEV_TYPE_POINTER and * LV_INDEV_TYPE_BUTTON) @@ -310,6 +342,13 @@ lv_obj_t * lv_indev_get_scroll_obj(const lv_indev_t * indev); */ void lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point); +/** + * Get the cursor object of an input device (for LV_INDEV_TYPE_POINTER only) + * @param indev pointer to an input device + * @return pointer to the cursor object + */ +lv_obj_t * lv_indev_get_cursor(lv_indev_t * indev); + /** * Do nothing until the next release * @param indev pointer to an input device diff --git a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_gesture.c b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_gesture.c new file mode 100644 index 000000000..928016bb2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_gesture.c @@ -0,0 +1,964 @@ +/****************************************************************** + * @file lv_indev_gesture.c + * + * Recognize gestures that consist of multiple touch events + * + * Copyright (c) 2024 EDGEMTech Ltd + * + * Author EDGEMTech Ltd. (erik.tagirov@edgemtech.ch) + * + ******************************************************************/ + +/******************** + * INCLUDES + ********************/ + +#include "lv_indev_private.h" +#include "../misc/lv_event_private.h" + +#if LV_USE_GESTURE_RECOGNITION + +#include +#include "lv_indev_gesture.h" +#include "lv_indev_gesture_private.h" + +/******************** + * DEFINES + ********************/ + +#define LV_GESTURE_PINCH_DOWN_THRESHOLD 0.75f /* Default value - start sending events when reached */ +#define LV_GESTURE_PINCH_UP_THRESHOLD 1.5f /* Default value - start sending events when reached */ +#define LV_GESTURE_PINCH_MAX_INITIAL_SCALE 2.5f /* Default value */ +#define LV_GESTURE_ROTATION_ANGLE_RAD_THRESHOLD 0.2f /* Default value - start sending events when reached */ + + +/******************** + * TYPEDEFS + ********************/ + +/******************** + * STATIC PROTOTYPES + ********************/ + +static lv_indev_gesture_t * init_gesture_info(void); +static lv_indev_gesture_motion_t * get_motion(uint8_t id, lv_indev_gesture_t * info); +static int8_t get_motion_idx(uint8_t id, lv_indev_gesture_t * info); +static void process_touch_event(lv_indev_touch_data_t * touch, lv_indev_gesture_t * info); +static void gesture_update_center_point(lv_indev_gesture_t * gesture, int touch_points_nb); +static void gesture_calculate_factors(lv_indev_gesture_t * gesture, int touch_points_nb); +static void reset_recognizer(lv_indev_gesture_recognizer_t * recognizer); +static lv_indev_gesture_recognizer_t * lv_indev_get_gesture_recognizer(lv_event_t * gesture_event, + lv_indev_gesture_type_t type); +static lv_dir_t calculate_swipe_dir(lv_indev_gesture_recognizer_t * recognizer); +static lv_indev_gesture_type_t get_first_recognized_or_ended_gesture(lv_indev_t * indev); + +/******************** + * STATIC VARIABLES + ********************/ + +/******************** + * MACROS + ********************/ +#define SQUARE(x) ((x) * (x)) +#define SQUARE_SUM(x, y) (SQUARE(x) + SQUARE(y)) + +/******************** + * GLOBAL FUNCTIONS + ********************/ + +void lv_indev_set_pinch_up_threshold(lv_indev_t * indev, float threshold) +{ + /* A up threshold MUST always be bigger than 1 */ + LV_ASSERT(threshold > 1.0f); + + lv_indev_gesture_recognizer_t * recognizer = &indev->recognizers[LV_INDEV_GESTURE_PINCH]; + + if(recognizer->config == NULL) { + recognizer->config = lv_malloc_zeroed(sizeof(lv_indev_gesture_configuration_t)); + LV_ASSERT_MALLOC(recognizer->config); + recognizer->config->pinch_down_threshold = LV_GESTURE_PINCH_DOWN_THRESHOLD; + } + + recognizer->config->pinch_up_threshold = threshold; +} + +void lv_indev_set_pinch_down_threshold(lv_indev_t * indev, float threshold) +{ + /* A down threshold MUST always be smaller than 1 */ + LV_ASSERT(threshold < 1.0f); + + lv_indev_gesture_recognizer_t * recognizer = &indev->recognizers[LV_INDEV_GESTURE_PINCH]; + + if(recognizer->config == NULL) { + recognizer->config = lv_malloc_zeroed(sizeof(lv_indev_gesture_configuration_t)); + LV_ASSERT_MALLOC(recognizer->config); + recognizer->config->pinch_up_threshold = LV_GESTURE_PINCH_UP_THRESHOLD; + } + + recognizer->config->pinch_down_threshold = threshold; +} + +void lv_indev_set_rotation_rad_threshold(lv_indev_t * indev, float threshold) +{ + /* A rotation threshold MUST always be a positive number */ + LV_ASSERT(threshold > 0.0f); + + lv_indev_gesture_recognizer_t * recognizer = &indev->recognizers[LV_INDEV_GESTURE_ROTATE]; + + if(recognizer->config == NULL) { + + recognizer->config = lv_malloc_zeroed(sizeof(lv_indev_gesture_configuration_t)); + LV_ASSERT(recognizer->config != NULL); + recognizer->config->rotation_angle_rad_threshold = LV_GESTURE_ROTATION_ANGLE_RAD_THRESHOLD; + } + + recognizer->config->rotation_angle_rad_threshold = threshold; +} + +void lv_indev_get_gesture_primary_point(lv_indev_gesture_recognizer_t * recognizer, lv_point_t * point) +{ + if(recognizer->info->motions[0].finger != -1) { + point->x = recognizer->info->motions[0].point.x; + point->y = recognizer->info->motions[0].point.y; + return; + } + + /* There are currently no active contact points */ + point->x = 0; + point->y = 0; +} + +bool lv_indev_recognizer_is_active(lv_indev_gesture_recognizer_t * recognizer) +{ + if(recognizer->state == LV_INDEV_GESTURE_STATE_ENDED || + recognizer->info->finger_cnt == 0) { + return false; + } + + return true; +} + +float lv_event_get_pinch_scale(lv_event_t * gesture_event) +{ + lv_indev_gesture_recognizer_t * recognizer; + + if((recognizer = lv_indev_get_gesture_recognizer(gesture_event, LV_INDEV_GESTURE_PINCH)) == NULL) { + return 0.0f; + } + + return recognizer->scale; +} + +float lv_event_get_rotation(lv_event_t * gesture_event) +{ + lv_indev_gesture_recognizer_t * recognizer; + + if((recognizer = lv_indev_get_gesture_recognizer(gesture_event, LV_INDEV_GESTURE_ROTATE)) == NULL) { + return 0.0f; + } + + return recognizer->rotation; +} + +float lv_event_get_two_fingers_swipe_distance(lv_event_t * gesture_event) +{ + lv_indev_gesture_recognizer_t * recognizer; + + if((recognizer = lv_indev_get_gesture_recognizer(gesture_event, LV_INDEV_GESTURE_TWO_FINGERS_SWIPE)) == NULL) { + return 0.0f; + } + + return recognizer->distance; +} + +lv_dir_t lv_event_get_two_fingers_swipe_dir(lv_event_t * gesture_event) +{ + + lv_indev_gesture_recognizer_t * recognizer; + + if((recognizer = lv_indev_get_gesture_recognizer(gesture_event, LV_INDEV_GESTURE_TWO_FINGERS_SWIPE)) == NULL) { + return LV_DIR_NONE; + } + + return recognizer->two_fingers_swipe_dir; +} + +void lv_indev_get_gesture_center_point(lv_indev_gesture_recognizer_t * recognizer, lv_point_t * point) +{ + if(lv_indev_recognizer_is_active(recognizer) == false) { + point->x = 0; + point->y = 0; + return; + } + + point->x = recognizer->info->center.x; + point->y = recognizer->info->center.y; +} + +lv_indev_gesture_state_t lv_event_get_gesture_state(lv_event_t * gesture_event, lv_indev_gesture_type_t type) +{ + lv_indev_gesture_recognizer_t * recognizer; + + if((recognizer = lv_indev_get_gesture_recognizer(gesture_event, type)) == NULL) { + return LV_INDEV_GESTURE_STATE_NONE; + } + + return recognizer->state; +} + +lv_indev_gesture_type_t lv_event_get_gesture_type(lv_event_t * gesture_event) +{ + lv_indev_t * indev = (lv_indev_t *) gesture_event->param; + + if(indev == NULL) { + return LV_INDEV_GESTURE_NONE; + } + + return indev->cur_gesture; +} + +void lv_indev_set_gesture_data(lv_indev_data_t * data, lv_indev_gesture_recognizer_t * recognizer, + lv_indev_gesture_type_t type) +{ + bool is_active; + lv_point_t cur_pnt; + + if(recognizer == NULL) return; + + /* If there is a single contact point use its coords, + * when there are no contact points it's set to 0,0 + * + * Note: If a gesture was detected, the primary point is overwritten below + */ + + lv_indev_get_gesture_primary_point(recognizer, &cur_pnt); + data->point.x = cur_pnt.x; + data->point.y = cur_pnt.y; + + data->gesture_type[type] = LV_INDEV_GESTURE_NONE; + data->gesture_data[type] = NULL; + + /* The call below returns false if there are no active contact points */ + /* - OR when the gesture has ended, false is considered as a RELEASED state */ + is_active = lv_indev_recognizer_is_active(recognizer); + + if(is_active == false) { + data->state = LV_INDEV_STATE_RELEASED; + } + else { + data->state = LV_INDEV_STATE_PRESSED; + } + + switch(recognizer->state) { + case LV_INDEV_GESTURE_STATE_RECOGNIZED: + lv_indev_get_gesture_center_point(recognizer, &cur_pnt); + data->point.x = cur_pnt.x; + data->point.y = cur_pnt.y; + data->gesture_type[type] = type; + data->gesture_data[type] = (void *) recognizer; + break; + + case LV_INDEV_GESTURE_STATE_ENDED: + data->gesture_type[type] = type; + data->gesture_data[type] = (void *) recognizer; + break; + + default: + break; + } +} + + +void lv_indev_gesture_detect_pinch(lv_indev_gesture_recognizer_t * recognizer, lv_indev_touch_data_t * touches, + uint16_t touch_cnt) +{ + lv_indev_touch_data_t * touch; + lv_indev_gesture_recognizer_t * r = recognizer; + uint8_t i; + + if(r->info == NULL) { + LV_LOG_TRACE("init gesture info"); + r->info = init_gesture_info(); + } + + if(r->config == NULL) { + LV_LOG_TRACE("init gesture configuration - set defaults"); + r->config = lv_malloc_zeroed(sizeof(lv_indev_gesture_configuration_t)); + LV_ASSERT_MALLOC(r->config); + + r->config->pinch_up_threshold = LV_GESTURE_PINCH_UP_THRESHOLD; + r->config->pinch_down_threshold = LV_GESTURE_PINCH_DOWN_THRESHOLD; + } + + /* Process collected touch events */ + for(i = 0; i < touch_cnt; i++) { + touch = touches; + process_touch_event(touch, r->info); + touches++; + + LV_LOG_TRACE("processed touch ev: %d finger id: %d state: %d x: %" LV_PRId32 " y: %" LV_PRId32 " finger_cnt: %d", + i, touch->id, touch->state, touch->point.x, touch->point.y, r->info->finger_cnt); + } + + LV_LOG_TRACE("Current finger count: %d state: %d", r->info->finger_cnt, r->state); + + if(r->info->finger_cnt == 2) { + switch(r->state) { + case LV_INDEV_GESTURE_STATE_NONE: + + /* 2 fingers down - potential pinch or swipe */ + reset_recognizer(recognizer); + gesture_update_center_point(r->info, 2); + r->state = LV_INDEV_GESTURE_STATE_ONGOING; + break; + case LV_INDEV_GESTURE_STATE_ONGOING: + gesture_calculate_factors(r->info, 2); + if(r->info->scale > LV_GESTURE_PINCH_MAX_INITIAL_SCALE) { + r->state = LV_INDEV_GESTURE_STATE_CANCELED; + break; + } + if(r->info->scale > r->config->pinch_up_threshold || + r->info->scale < r->config->pinch_down_threshold) { + r->state = LV_INDEV_GESTURE_STATE_RECOGNIZED; + } + break; + case LV_INDEV_GESTURE_STATE_RECOGNIZED: + /* It's an ongoing pinch gesture - update the factors */ + gesture_calculate_factors(r->info, 2); + LV_ASSERT(r->info != NULL); + r->scale = r->info->scale; + r->type = LV_INDEV_GESTURE_PINCH; + break; + case LV_INDEV_GESTURE_STATE_ENDED: + case LV_INDEV_GESTURE_STATE_CANCELED: + reset_recognizer(r); + break; + default: + LV_ASSERT_MSG(true, "invalid gesture recognizer state"); + } + } + else { + switch(r->state) { + case LV_INDEV_GESTURE_STATE_RECOGNIZED: + /* Gesture has ended */ + r->state = LV_INDEV_GESTURE_STATE_ENDED; + break; + case LV_INDEV_GESTURE_STATE_ONGOING: + /* User lifted a finger before reaching threshold */ + r->state = LV_INDEV_GESTURE_STATE_CANCELED; + break; + case LV_INDEV_GESTURE_STATE_ENDED: + case LV_INDEV_GESTURE_STATE_CANCELED: + reset_recognizer(r); + break; + + default: + LV_ASSERT_MSG(true, "invalid gesture recognizer state"); + } + } +} + +void lv_indev_gesture_detect_rotation(lv_indev_gesture_recognizer_t * recognizer, lv_indev_touch_data_t * touches, + uint16_t touch_cnt) +{ + lv_indev_touch_data_t * touch; + lv_indev_gesture_recognizer_t * r = recognizer; + uint8_t i; + + if(r->info == NULL) { + LV_LOG_TRACE("init gesture info"); + r->info = init_gesture_info(); + } + + if(r->config == NULL) { + LV_LOG_TRACE("init gesture configuration - set defaults"); + r->config = lv_malloc_zeroed(sizeof(lv_indev_gesture_configuration_t)); + + LV_ASSERT(r->config != NULL); + } + + /* Process collected touch events */ + for(i = 0; i < touch_cnt; i++) { + + touch = touches; + process_touch_event(touch, r->info); + touches++; + + LV_LOG_TRACE("processed touch ev: %d finger id: %d state: %d x: %" LV_PRId32 " y: %" LV_PRId32 " finger_cnt: %d", + i, touch->id, touch->state, touch->point.x, touch->point.y, r->info->finger_cnt); + } + + LV_LOG_TRACE("Current finger count: %d state: %d", r->info->finger_cnt, r->state); + + if(r->info->finger_cnt == 2) { + switch(r->state) { + case LV_INDEV_GESTURE_STATE_NONE: + /* 2 fingers down - potential rotation or swipe */ + reset_recognizer(recognizer); + gesture_update_center_point(r->info, 2); + r->state = LV_INDEV_GESTURE_STATE_ONGOING; + break; + case LV_INDEV_GESTURE_STATE_ONGOING: + /* Update the rotation from the inputs */ + gesture_calculate_factors(r->info, 2); + if(fabs(r->info->rotation - r->info->p_rotation) > r->config->rotation_angle_rad_threshold) { + + gesture_update_center_point(r->info, 2); + r->state = LV_INDEV_GESTURE_STATE_RECOGNIZED; + } + break; + case LV_INDEV_GESTURE_STATE_RECOGNIZED: + /* It's a recognized rotation gesture - update the factors */ + gesture_calculate_factors(r->info, 2); + r->type = LV_INDEV_GESTURE_ROTATE; + r->rotation = r->info->rotation; + break; + case LV_INDEV_GESTURE_STATE_ENDED: + case LV_INDEV_GESTURE_STATE_CANCELED: + reset_recognizer(r); + r->type = LV_INDEV_GESTURE_NONE; + r->state = LV_INDEV_GESTURE_STATE_CANCELED; + break; + default: + LV_ASSERT_MSG(true, "invalid gesture recognizer state"); + } + } + else { + switch(r->state) { + case LV_INDEV_GESTURE_STATE_RECOGNIZED: + /* Gesture has ended */ + r->type = LV_INDEV_GESTURE_ROTATE; + r->state = LV_INDEV_GESTURE_STATE_ENDED; + break; + case LV_INDEV_GESTURE_STATE_ONGOING: + /* User lifted a finger before reaching threshold */ + reset_recognizer(r); + break; + case LV_INDEV_GESTURE_STATE_CANCELED: + case LV_INDEV_GESTURE_STATE_ENDED: + reset_recognizer(r); + break; + default: + LV_ASSERT_MSG(true, "invalid gesture recognizer state"); + } + } +} + +void lv_indev_gesture_detect_two_fingers_swipe(lv_indev_gesture_recognizer_t * recognizer, + lv_indev_touch_data_t * touches, + uint16_t touch_cnt) +{ + lv_indev_touch_data_t * touch; + lv_indev_gesture_recognizer_t * r = recognizer; + uint8_t i; + float dist; + + if(r->info == NULL) { + LV_LOG_TRACE("init gesture info"); + r->info = init_gesture_info(); + } + + if(r->config == NULL) { + LV_LOG_TRACE("init gesture configuration - set defaults"); + r->config = lv_malloc_zeroed(sizeof(lv_indev_gesture_configuration_t)); + + LV_ASSERT(r->config != NULL); + } + + /* Process collected touch events */ + for(i = 0; i < touch_cnt; i++) { + + touch = touches; + process_touch_event(touch, r->info); + touches++; + + LV_LOG_TRACE("processed touch ev: %d finger id: %d state: %d x: %" LV_PRId32 " y: %" LV_PRId32 " finger_cnt: %d", + i, touch->id, touch->state, touch->point.x, touch->point.y, r->info->finger_cnt); + } + + LV_LOG_TRACE("Current finger count: %d state: %d", r->info->finger_cnt, r->state); + + if(r->info->finger_cnt == 2) { + + switch(r->state) { + case LV_INDEV_GESTURE_STATE_NONE: + /* 2 fingers down - potential rotation or swipe */ + reset_recognizer(recognizer); + gesture_update_center_point(r->info, 2); + r->state = LV_INDEV_GESTURE_STATE_ONGOING; + break; + case LV_INDEV_GESTURE_STATE_ONGOING: + /* The gesture is ongoing, now wait for the distance from the center + to be higher than the threshold to pass it as recognized */ + gesture_calculate_factors(r->info, 2); + dist = SQUARE_SUM(r->info->delta_x, r->info->delta_y); + if(dist > SQUARE(lv_indev_active()->gesture_limit)) { + r->state = LV_INDEV_GESTURE_STATE_RECOGNIZED; + } + break; + case LV_INDEV_GESTURE_STATE_RECOGNIZED: + /* The gesture is now recognized, and will stay recognized + until a finger is lifted */ + gesture_calculate_factors(r->info, 2); + r->distance = (float) sqrt(SQUARE_SUM(r->info->delta_x, r->info->delta_y)); + r->two_fingers_swipe_dir = calculate_swipe_dir(r); + r->type = LV_INDEV_GESTURE_TWO_FINGERS_SWIPE; + break; + case LV_INDEV_GESTURE_STATE_ENDED: + case LV_INDEV_GESTURE_STATE_CANCELED: + reset_recognizer(r); + break; + default: + LV_ASSERT_MSG(true, "invalid gesture recognizer state"); + } + } + else { + + switch(r->state) { + case LV_INDEV_GESTURE_STATE_RECOGNIZED: + /* Gesture has ended */ + r->state = LV_INDEV_GESTURE_STATE_ENDED; + r->type = LV_INDEV_GESTURE_TWO_FINGERS_SWIPE; + break; + case LV_INDEV_GESTURE_STATE_ONGOING: + /* User lifted a finger before reaching threshold */ + reset_recognizer(r); + r->state = LV_INDEV_GESTURE_STATE_ENDED; + break; + case LV_INDEV_GESTURE_STATE_CANCELED: + case LV_INDEV_GESTURE_STATE_ENDED: + reset_recognizer(r); + r->state = LV_INDEV_GESTURE_STATE_NONE; + break; + default: + LV_ASSERT_MSG(true, "invalid gesture recognizer state"); + } + } +} + +void lv_indev_gesture_recognizers_update(lv_indev_t * indev, lv_indev_touch_data_t * touches, uint16_t touch_cnt) +{ + lv_indev_gesture_type_t type; + + /* First check if a recognizer state is RECOGNIZED or ENDED. * + * In that case, call its recongizer function and reset the other*/ + type = get_first_recognized_or_ended_gesture(indev); + if(type != LV_INDEV_GESTURE_NONE) { + + for(int i = 0; i < LV_INDEV_GESTURE_CNT; i++) { + + if(indev->recognizers[i].recog_fn != NULL) { + + /* Update all recognizers to let them process input */ + indev->recognizers[i].recog_fn(&indev->recognizers[i], &touches[0], touch_cnt); + + /* Then reset the recognizers which did not repport RECONIZED or ENDED */ + if(((lv_indev_gesture_type_t)i) != type) { + reset_recognizer(&indev->recognizers[i]); + } + } + } + + } + else { + + /* Otherwise call all recognizer functions, and stop as soon as one recognizer * + * reports the state RECOGNIZED or ENDED */ + for(int i = 0; i < LV_INDEV_GESTURE_CNT; i++) { + if(indev->recognizers[i].recog_fn != NULL) { + indev->recognizers[i].recog_fn(&indev->recognizers[i], &touches[0], touch_cnt); + + /* If the new state is RECOGNIZED or ENDED */ + if(indev->recognizers[i].state == LV_INDEV_GESTURE_STATE_RECOGNIZED || + indev->recognizers[i].state == LV_INDEV_GESTURE_STATE_ENDED) { + + /* Reset the others registered recognizers */ + for(int j = 0; j < LV_INDEV_GESTURE_CNT; j++) { + if(j != i && indev->recognizers[j].recog_fn != NULL) { + reset_recognizer(&indev->recognizers[j]); + } + } + break; + } + } + } + } +} + +void lv_indev_gesture_recognizers_set_data(lv_indev_t * indev, lv_indev_data_t * data) +{ + lv_indev_gesture_type_t type; + type = get_first_recognized_or_ended_gesture(indev); + + /* If a gesture is RECOGNIZED or ENDED, set only its data */ + if(type != LV_INDEV_GESTURE_NONE) { + lv_indev_set_gesture_data(data, &indev->recognizers[type], type); + } + else { + /* Otherwise, set data from all initialized recognizer */ + for(int i = 0; i < LV_INDEV_GESTURE_CNT; i++) { + if(indev->recognizers[i].recog_fn != NULL) { + lv_indev_set_gesture_data(data, &indev->recognizers[i], i); + } + } + } +} + + +/******************** + * STATIC FUNCTIONS + ********************/ + +/** + * Caluclate the direction from the starting center of a two fingers swipe gesture + * @param recognizer pointer to the recognizer handling the two fingers + * swipe gesture + * @return the direction of the swipe, from the starting center + */ +static lv_dir_t calculate_swipe_dir(lv_indev_gesture_recognizer_t * recognizer) +{ + float abs_x = LV_ABS(recognizer->info->delta_x); + float abs_y = LV_ABS(recognizer->info->delta_y); + + if(abs_x > abs_y) { + return recognizer->info->delta_x > 0 ? LV_DIR_RIGHT : LV_DIR_LEFT; + } + else { + return recognizer->info->delta_y > 0 ? LV_DIR_BOTTOM : LV_DIR_TOP; + } +} + +/** + * Get the gesture recognizer associated to the event + * @param gesture_event an LV_GESTURE_EVENT event + * @param type the type of the recognizer we want to get + * @return a pointer to the gesture recognizer that emitted the event + */ +lv_indev_gesture_recognizer_t * lv_indev_get_gesture_recognizer(lv_event_t * gesture_event, + lv_indev_gesture_type_t type) +{ + lv_indev_t * indev; + + if(gesture_event == NULL || gesture_event->param == NULL) return NULL; + + indev = (lv_indev_t *) gesture_event->param; + + if(indev == NULL || indev->gesture_data[type] == NULL) return NULL; + + return (lv_indev_gesture_recognizer_t *) indev->gesture_data[type]; +} + +/** + * Resets a gesture recognizer, motion descriptors are preserved + * @param recognizer a pointer to the recognizer to reset + */ +static void reset_recognizer(lv_indev_gesture_recognizer_t * recognizer) +{ + uint8_t finger_cnt; + lv_indev_gesture_t * info; + lv_indev_gesture_configuration_t * conf; + lv_recognizer_func_t recog_fn; + + if(recognizer == NULL) return; + + finger_cnt = recognizer->info->finger_cnt; + info = recognizer->info; + conf = recognizer->config; + recog_fn = recognizer->recog_fn; + + /* Set everything to zero but preserve the motion descriptors, + * which are located at the start of the lv_indev_gesture_t struct */ + lv_memzero((uint8_t *)info + sizeof(info->motions), sizeof(lv_indev_gesture_t) - sizeof(info->motions)); + lv_memzero(recognizer, sizeof(lv_indev_gesture_recognizer_t)); + + recognizer->info = info; + recognizer->config = conf; + recognizer->recog_fn = recog_fn; + + recognizer->scale = recognizer->info->scale = 1.0; + recognizer->info->finger_cnt = finger_cnt; + + recognizer->state = LV_INDEV_GESTURE_STATE_NONE; + recognizer->type = LV_INDEV_GESTURE_NONE; +} + +/** + * Initializes a motion descriptors used with the recognizer(s) + * @return a pointer to gesture descriptor + */ +static lv_indev_gesture_t * init_gesture_info(void) +{ + lv_indev_gesture_t * info; + uint8_t i; + + info = lv_malloc_zeroed(sizeof(lv_indev_gesture_t)); + LV_ASSERT_MALLOC(info); + + info->scale = 1; + info->rotation = 0.0; + + for(i = 0; i < LV_GESTURE_MAX_POINTS; i++) { + info->motions[i].finger = -1; + } + + return info; +} + +/** + * Obtains the contact point motion descriptor with id + * @param id the id of the contact point + * @param info a pointer to the gesture descriptor that stores the motion of each contact point + * @return a pointer to the motion descriptor or NULL if not found + */ +static lv_indev_gesture_motion_t * get_motion(uint8_t id, lv_indev_gesture_t * info) +{ + uint8_t i; + + for(i = 0; i < LV_GESTURE_MAX_POINTS; i++) { + if(info->motions[i].finger == id) { + return &info->motions[i]; + } + } + + return NULL; +} + +/** + * Obtains the index of the contact point motion descriptor + * @param id the id of the contact point + * @param info a pointer to the gesture descriptor that stores the motion of each contact point + * @return the index of the motion descriptor or -1 if not found + */ +static int8_t get_motion_idx(uint8_t id, lv_indev_gesture_t * info) +{ + uint8_t i; + + for(i = 0; i < LV_GESTURE_MAX_POINTS; i++) { + if(info->motions[i].finger == id) { + return i; + } + } + + return -1; +} + +/** + * Update the motion descriptors of a gesture + * @param touch a pointer to a touch data structure + * @param info a pointer to a gesture descriptor + */ +static void process_touch_event(lv_indev_touch_data_t * touch, lv_indev_gesture_t * info) +{ + lv_indev_gesture_t * g = info; + lv_indev_gesture_motion_t * motion; + int8_t motion_idx; + int8_t len; + + motion_idx = get_motion_idx(touch->id, g); + + if(motion_idx == -1 && touch->state == LV_INDEV_STATE_PRESSED) { + if(g->finger_cnt >= LV_GESTURE_MAX_POINTS) { + /* Skip touch */ + return; + } + + /* New touch point id */ + motion = &g->motions[g->finger_cnt]; + motion->start_point.x = touch->point.x; + motion->start_point.y = touch->point.y; + motion->point.x = touch->point.x; + motion->point.y = touch->point.y; + motion->finger = touch->id; + motion->state = touch->state; + + g->finger_cnt++; + } + else if(motion_idx >= 0 && touch->state == LV_INDEV_STATE_RELEASED) { + if(motion_idx == g->finger_cnt - 1) { + + /* Mark last item as un-used */ + motion = get_motion(touch->id, g); + + if(motion == NULL) { + LV_LOG_ERROR("Released touch not found (id=%d)", touch->id); + return; + } + + motion->finger = -1; + motion->state = touch->state; + } + else { + + /* Move back by one */ + len = (g->finger_cnt - 1) - motion_idx; + + if(len > 0) { + lv_memmove(g->motions + motion_idx, + g->motions + motion_idx + 1, + sizeof(lv_indev_gesture_motion_t) * len); + } + + if(g->finger_cnt > 0) { + g->motions[g->finger_cnt - 1].finger = -1; + } + + LV_ASSERT(g->motions[motion_idx + 1].finger == -1); + } + + if(g->finger_cnt > 0) { + g->finger_cnt--; + } + else { + g->finger_cnt = 0; + } + } + else if(motion_idx >= 0) { + motion = get_motion(touch->id, g); + + if(motion == NULL) { + LV_LOG_ERROR("Active touch missing (id=%d state=%d)", touch->id, touch->state); + return; + } + + motion->point.x = touch->point.x; + motion->point.y = touch->point.y; + motion->state = touch->state; + } + else { + LV_LOG_TRACE("Ignore extra touch id: %d", touch->id); + } +} + +/** + * Calculate the center point of a gesture, called when there + * is a probability for the gesture to occur + * @param touch a pointer to a touch data structure + * @param touch_points_nb The number of contact point to take into account + */ +static void gesture_update_center_point(lv_indev_gesture_t * gesture, int touch_points_nb) +{ + lv_indev_gesture_motion_t * motion; + lv_indev_gesture_t * g = gesture; + int32_t x = 0; + int32_t y = 0; + uint8_t i; + float scale_factor = 0.0f; + float delta_x[LV_GESTURE_MAX_POINTS] = {0.0f}; + float delta_y[LV_GESTURE_MAX_POINTS] = {0.0f}; + uint8_t touch_cnt = 0; + x = y = 0; + + g->p_scale = g->scale; + g->p_delta_x = g->delta_x; + g->p_delta_y = g->delta_y; + g->p_rotation = g->rotation; + + for(i = 0; i < touch_points_nb; i++) { + motion = &g->motions[i]; + + if(motion->finger >= 0) { + x += motion->point.x; + y += motion->point.y; + touch_cnt++; + } + else { + break; + } + } + + g->center.x = x / touch_cnt; + g->center.y = y / touch_cnt; + + for(i = 0; i < touch_points_nb; i++) { + motion = &g->motions[i]; + if(motion->finger >= 0) { + delta_x[i] = motion->point.x - g->center.x; + delta_y[i] = motion->point.y - g->center.y; + scale_factor += (delta_x[i] * delta_x[i]) + (delta_y[i] * delta_y[i]); + } + } + for(i = 0; i < touch_points_nb; i++) { + motion = &g->motions[i]; + if(motion->finger >= 0) { + g->scale_factors_x[i] = delta_x[i] / scale_factor; + g->scale_factors_y[i] = delta_y[i] / scale_factor; + } + } +} + +/** + * Calculate the scale, translation and rotation of a gesture, called when + * the gesture has been recognized + * @param gesture a pointer to the gesture descriptor + * @param touch_points_nb the number of contact points to take into account + */ +static void gesture_calculate_factors(lv_indev_gesture_t * gesture, int touch_points_nb) +{ + lv_indev_gesture_motion_t * motion; + lv_indev_gesture_t * g = gesture; + float center_x = 0; + float center_y = 0; + float a = 0; + float b = 0; + float d_x; + float d_y; + int8_t i; + int8_t touch_cnt = 0; + + for(i = 0; i < touch_points_nb; i++) { + motion = &g->motions[i]; + + if(motion->finger >= 0) { + center_x += motion->point.x; + center_y += motion->point.y; + touch_cnt++; + } + else { + break; + } + } + + center_x = center_x / touch_cnt; + center_y = center_y / touch_cnt; + + /* translation */ + g->delta_x = g->p_delta_x + (center_x - g->center.x); + g->delta_y = g->p_delta_y + (center_y - g->center.y); + + /* rotation & scaling */ + for(i = 0; i < touch_points_nb; i++) { + motion = &g->motions[i]; + + if(motion->finger >= 0) { + d_x = (motion->point.x - center_x); + d_y = (motion->point.y - center_y); + a += g->scale_factors_x[i] * d_x + g->scale_factors_y[i] * d_y; + b += g->scale_factors_x[i] * d_y - g->scale_factors_y[i] * d_x; + } + } + + g->rotation = g->p_rotation + atan2f(b, a); + g->scale = g->p_scale * sqrtf((a * a) + (b * b)); +} + +/** + * Get the type of the first gesture which reports either a LV_INDEV_GESTURE_STATE_RECOGNIZED + * or LV_INDEV_GESTURE_STATE_ENDED state + * @param indev pointer to the indev device from which we want to check the gestures states + * @return the type of the gesture having the state LV_INDEV_GESTURE_STATE_RECOGNIZED or + * LV_INDEV_GESTURE_STATE_ENDED, if found + * LV_INDEV_GESTURE_NONE otherwise + */ +static lv_indev_gesture_type_t get_first_recognized_or_ended_gesture(lv_indev_t * indev) +{ + for(int i = 0; i < LV_INDEV_GESTURE_CNT; i++) { + if(indev->recognizers[i].state == LV_INDEV_GESTURE_STATE_RECOGNIZED || + indev->recognizers[i].state == LV_INDEV_GESTURE_STATE_ENDED) + return (lv_indev_gesture_type_t) i; + } + + return LV_INDEV_GESTURE_NONE; +} + + +#endif /* LV_USE_GESTURE_RECOGNITION */ diff --git a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_gesture.h b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_gesture.h new file mode 100644 index 000000000..08318b915 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_gesture.h @@ -0,0 +1,244 @@ +/******************************************************************* + * + * @file lv_indev_gesture.h + * + * Copyright (c) 2024 EDGEMTech Ltd. + * + * Author EDGEMTech Ltd, (erik.tagirov@edgemtech.ch) + * + ******************************************************************/ + +#ifndef LV_INDEV_GESTURE_H +#define LV_INDEV_GESTURE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../core/lv_obj.h" + +#if LV_USE_GESTURE_RECOGNITION + +#if LV_USE_FLOAT == 0 +#error "LV_USE_FLOAT is required for gesture detection." +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/* Opaque types defined in the private header */ +struct lv_indev_gesture; +struct lv_indev_gesture_configuration; + +typedef struct lv_indev_gesture_recognizer lv_indev_gesture_recognizer_t; +typedef struct lv_indev_touch_data lv_indev_touch_data_t; + +typedef struct lv_indev_gesture lv_indev_gesture_t; +typedef struct lv_indev_gesture_configuration lv_indev_gesture_configuration_t; + +typedef void (*lv_recognizer_func_t)(lv_indev_gesture_recognizer_t *, lv_indev_touch_data_t *, uint16_t); + +/* The states of a gesture recognizer */ +typedef enum { + LV_INDEV_GESTURE_STATE_NONE = 0, /* Beginning & end */ + LV_INDEV_GESTURE_STATE_ONGOING, /* Set when there is a probability */ + LV_INDEV_GESTURE_STATE_RECOGNIZED, /* Recognized, the event will contain touch info */ + LV_INDEV_GESTURE_STATE_ENDED, /* A recognized gesture has ended */ + LV_INDEV_GESTURE_STATE_CANCELED, /* Canceled - usually a finger is lifted */ +} lv_indev_gesture_state_t; + +/* Data structures for touch events - used to repsensent a libinput event */ +/* Emitted by devices capable of tracking identifiable contacts (type B) */ +struct lv_indev_touch_data { + lv_point_t point; /* Coordinates of the touch */ + lv_indev_state_t state; /* The state i.e PRESSED or RELEASED */ + uint8_t id; /* Identification/slot of the contact point */ + uint32_t timestamp; /* Timestamp in milliseconds */ +}; + +/* Gesture recognizer */ +struct lv_indev_gesture_recognizer { + lv_indev_gesture_type_t type; /* The detected gesture type */ + lv_indev_gesture_state_t state; /* The gesture state ongoing, recognized */ + lv_indev_gesture_t * info; /* Information on the motion of each touch point */ + float scale; /* Relevant for the pinch gesture */ + float rotation; /* Relevant for rotation */ + float distance; /* Relevant for swipes */ + float speed; + lv_dir_t two_fingers_swipe_dir; /* Relevant for swipes */ + + lv_indev_gesture_configuration_t * config; /* The recognizer config, containing the gestures + thresholds */ + lv_recognizer_func_t recog_fn; /* The recognizer function that this recongnizer must execute */ +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + + +/* PINCH Gesture */ + +/** + * Pinch gesture recognizer function + * Will update the recognizer data + * @param recognizer pointer to a gesture recognizer + * @param touches pointer to the first element of the collected touch events + * @param touch_cnt length of passed touch event array. + */ +void lv_indev_gesture_detect_pinch(lv_indev_gesture_recognizer_t * recognizer, lv_indev_touch_data_t * touches, + uint16_t touch_cnt); + +/** + * Rotation gesture recognizer function + * Will update the recognizer data + * @param recognizer pointer to a gesture recognizer + * @param touches pointer to the first element of the collected touch events + * @param touch_cnt length of passed touch event array. + */ +void lv_indev_gesture_detect_rotation(lv_indev_gesture_recognizer_t * recognizer, lv_indev_touch_data_t * touches, + uint16_t touch_cnt); + +/** + * Two finger swipe gesture recognizer function + * Will update the recognizer data + * @param recognizer pointer to a gesture recognizer + * @param touches pointer to the first element of the collected touch events + * @param touch_cnt length of passed touch event array. + */ +void lv_indev_gesture_detect_two_fingers_swipe(lv_indev_gesture_recognizer_t * recognizer, + lv_indev_touch_data_t * touches, + uint16_t touch_cnt); + +/** + * Set the threshold for the pinch gesture scale up, when the scale factor of gesture + * reaches the threshold events get sent + * @param indev pointer to the indev device containing the pinch recognizer + * @param threshold threshold for a pinch up gesture to be recognized + */ +void lv_indev_set_pinch_up_threshold(lv_indev_t * indev, float threshold); + +/** + * Set the threshold for the pinch gesture scale down, when the scale factor of gesture + * reaches the threshold events get sent + * @param indev pointer to the indev device containing the pinch recognizer + * @param threshold threshold for a pinch down gesture to be recognized + */ +void lv_indev_set_pinch_down_threshold(lv_indev_t * indev, float threshold); + +/** + * Set the rotation threshold in radian for the rotation gesture + * @param indev pointer to the indev device containing the rotation recognizer + * @param threshold threshold in radian for a rotation gesture to be recognized + */ +void lv_indev_set_rotation_rad_threshold(lv_indev_t * indev, float threshold); + +/** + * Obtains the current scale of a pinch gesture + * @param gesture_event pointer to a gesture event + * @return the scale of the current gesture + */ +float lv_event_get_pinch_scale(lv_event_t * gesture_event); + +/** + * Obtains the current angle in radian of a rotation gesture + * @param gesture_event pointer to a gesture event + * @return the rotation angle in radian of the current gesture + */ +float lv_event_get_rotation(lv_event_t * gesture_event); + +/** + * Obtains the current distance in pixels of a two fingers swipe gesture, from the starting center + * @param gesture_event pointer to a gesture event + * @return the distance from the center, in pixels, of the current gesture + */ +float lv_event_get_two_fingers_swipe_distance(lv_event_t * gesture_event); + +/** + * Obtains the current direction from the center of a two finger swipe + * @param gesture_event pointer to a gesture event + * @return the rotation angle in radian of the current gesture + */ +lv_dir_t lv_event_get_two_fingers_swipe_dir(lv_event_t * gesture_event); + +/** + * Sets the state of the recognizer to a indev data structure, + * it is usually called from the indev read callback + * @param data the indev data + * @param recognizer pointer to a gesture recognizer + */ +void lv_indev_set_gesture_data(lv_indev_data_t * data, lv_indev_gesture_recognizer_t * recognizer, + lv_indev_gesture_type_t type); + +/** + * Obtains the center point of a gesture + * @param gesture_event pointer to a gesture recognizer event + * @param point pointer to a point + */ +void lv_indev_get_gesture_center_point(lv_indev_gesture_recognizer_t * recognizer, lv_point_t * point); + +/** + * Obtains the current state of the gesture recognizer attached to an event + * @param gesture_event pointer to a gesture recognizer event + * @return current state of the gesture recognizer + */ +lv_indev_gesture_state_t lv_event_get_gesture_state(lv_event_t * gesture_event, lv_indev_gesture_type_t type); + +/** + * Obtains the current event type of the gesture recognizer attached to an event + * @param gesture_event pointer to a gesture recognizer event + * @return current event type of the gesture recognizer + */ +lv_indev_gesture_type_t lv_event_get_gesture_type(lv_event_t * gesture_event); + +/** + * Obtains the coordinates of the current primary point + * @param recognizer pointer to a gesture recognizer + * @param point pointer to a point + */ +void lv_indev_get_gesture_primary_point(lv_indev_gesture_recognizer_t * recognizer, lv_point_t * point); + +/** + * Allows to determine if there is an are ongoing gesture + * @param recognizer pointer to a gesture recognizer + * @return false if there are no contact points, or the gesture has ended - true otherwise + */ +bool lv_indev_recognizer_is_active(lv_indev_gesture_recognizer_t * recognizer); + +/** + * Update the recognizers. It execute the recognizers functions and checks for + * LV_GESTURE_STATE_RECOGNIZED or LV_GESTURE_STATE_ENDED gestures. + * To be called in the indev read_cb. + * @param indev pointer to the indev containing from which the reconizer need an update + * @param touches indev touch data array, containing the last touch data from indev + * since the last recognizers update + * @param touch_cnt number of indev touch data in touches + */ +void lv_indev_gesture_recognizers_update(lv_indev_t * indev, lv_indev_touch_data_t * touches, uint16_t touch_cnt); + +/** + * Set the lv_indev_data_t struct from the recognizer data. + * To be called in the indev read_cb. + */ +void lv_indev_gesture_recognizers_set_data(lv_indev_t * indev, lv_indev_data_t * data); + + +/********************** + * MACROS + **********************/ + +#endif /* END LV_USE_RECOGNITION */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* END LV_INDEV_GESTURE_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_gesture_private.h b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_gesture_private.h new file mode 100644 index 000000000..752672dfc --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_gesture_private.h @@ -0,0 +1,97 @@ +/******************************************************************* + * + * @file lv_indev_gesture_private.h + * + * Contains declarations and definition that are internal + * to the gesture detection logic + * + * Copyright (c) 2024 EDGEMTech Ltd. + * + * Author EDGEMTech Ltd, (erik.tagirov@edgemtech.ch) + * + ******************************************************************/ + +#ifndef LV_INDEV_GESTURE_PRIVATE_H +#define LV_INDEV_GESTURE_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../core/lv_obj.h" + +#if LV_USE_GESTURE_RECOGNITION + +/********************* + * DEFINES + *********************/ + +#define LV_GESTURE_MAX_POINTS 2 + + +/********************** + * TYPEDEFS + **********************/ + +/* Represent the motion of a finger */ +struct lv_indev_gesture_motion { + int8_t finger; /* The ID of the tracked finger */ + lv_point_t start_point; /* The coordinates where the DOWN event occurred */ + lv_point_t point; /* The current coordinates */ + lv_indev_state_t state; /* DEBUG: The state i.e PRESSED or RELEASED */ +}; + +typedef struct lv_indev_gesture_motion lv_indev_gesture_motion_t; + +/* General descriptor for a gesture, used by recognizer state machines to track + * the scale, rotation, and translation NOTE: (this will likely become private) */ +struct lv_indev_gesture { + + /* Motion descriptor, stores the coordinates and velocity of a contact point */ + lv_indev_gesture_motion_t motions[LV_GESTURE_MAX_POINTS]; + + lv_point_t center; /* Center point */ + float scale; /* Scale factor & previous scale factor */ + float p_scale; + float scale_factors_x[LV_GESTURE_MAX_POINTS]; /* Scale factor relative to center for each point */ + float scale_factors_y[LV_GESTURE_MAX_POINTS]; + + float delta_x; /* Translation & previous translation */ + float delta_y; + float p_delta_x; + float p_delta_y; + float rotation; /* Rotation & previous rotation*/ + float p_rotation; + uint8_t finger_cnt; /* Current number of contact points */ + +}; + +/* Recognizer configuration. It stores the thresholds needed to detect the gestures and + * consider them as recognized. Once recognized, indev start sending LV_GESTURE event + */ +struct lv_indev_gesture_configuration { + + float pinch_up_threshold; /* Threshold for the pinch up gesture to be recognized - in pixels */ + float pinch_down_threshold; /* Threshold for the pinch down gesture to be recognized - in pixels */ + float rotation_angle_rad_threshold; /* Threshold for the rotation gesture to be recognized - in radians */ + +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* END LV_USE_RECOGNITION */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* END LV_INDEV_GESTURE_PRIVATE_H */ 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 a5fa23164..83b65c77b 100644 --- a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_private.h +++ b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_private.h @@ -15,6 +15,9 @@ extern "C" { *********************/ #include "lv_indev.h" #include "../misc/lv_anim.h" +#include "lv_indev_scroll.h" +#include "lv_indev_gesture.h" + /********************* * DEFINES *********************/ @@ -23,7 +26,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_indev_t { +struct _lv_indev_t { /** Input device type*/ lv_indev_type_t type; @@ -31,6 +34,7 @@ struct lv_indev_t { lv_indev_read_cb_t read_cb; lv_indev_state_t state; /**< Current state of the input device.*/ + lv_indev_state_t prev_state; /**< Previous state of the input device.*/ lv_indev_mode_t mode; /*Flags*/ @@ -90,12 +94,16 @@ struct lv_indev_t { lv_area_t scroll_area; lv_point_t gesture_sum; /*Count the gesture pixels to check LV_INDEV_DEF_GESTURE_LIMIT*/ int32_t diff; - + /*Short click streaks*/ + uint8_t short_click_streak; + lv_point_t last_short_click_point; + uint32_t last_short_click_timestamp; /*Flags*/ uint8_t scroll_dir : 4; uint8_t gesture_dir : 4; uint8_t gesture_sent : 1; uint8_t press_moved : 1; + uint8_t pressed : 1; } pointer; struct { /*Keypad data*/ @@ -109,6 +117,13 @@ struct lv_indev_t { here by the buttons*/ lv_event_list_t event_list; lv_anim_t * scroll_throw_anim; + +#if LV_USE_GESTURE_RECOGNITION + lv_indev_gesture_recognizer_t recognizers[LV_INDEV_GESTURE_CNT]; + lv_indev_gesture_type_t cur_gesture; + void * gesture_data[LV_INDEV_GESTURE_CNT]; + lv_indev_gesture_type_t gesture_type[LV_INDEV_GESTURE_CNT]; +#endif }; /********************** @@ -123,6 +138,7 @@ struct lv_indev_t { */ lv_obj_t * lv_indev_find_scroll_obj(lv_indev_t * indev); + /********************** * MACROS **********************/ 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 f32786577..7996467a4 100644 --- a/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_scroll.c +++ b/lib/libesp32_lvgl/lvgl/src/indev/lv_indev_scroll.c @@ -30,6 +30,7 @@ static int32_t find_snap_point_y(const lv_obj_t * obj, int32_t min, int32_t max, static void scroll_limit_diff(lv_indev_t * indev, int32_t * diff_x, int32_t * diff_y); 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); +static void has_more_snap_points(lv_obj_t * scroll_obj, lv_dir_t dir, bool * has_start_snap, bool * has_end_snap); /********************** * STATIC VARIABLES @@ -76,6 +77,14 @@ void lv_indev_scroll_handler(lv_indev_t * indev) parent = lv_obj_get_parent(parent); } + if(scale_x == 0) { + scale_x = 1; + } + + if(scale_y == 0) { + scale_y = 1; + } + if(angle != 0 || scale_x != LV_SCALE_NONE || scale_y != LV_SCALE_NONE) { angle = -angle; scale_x = (256 * 256) / scale_x; @@ -292,6 +301,14 @@ lv_obj_t * lv_indev_find_scroll_obj(lv_indev_t * indev) parent = lv_obj_get_parent(parent); } + if(scale_x == 0) { + scale_x = 1; + } + + if(scale_y == 0) { + scale_y = 1; + } + lv_point_t obj_scroll_sum = indev->pointer.scroll_sum; if(angle != 0 || scale_x != LV_SCALE_NONE || scale_y != LV_SCALE_NONE) { angle = -angle; @@ -329,58 +346,43 @@ 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. - *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) { + if(snap_x == LV_SCROLL_SNAP_NONE) { sl = lv_obj_get_scroll_left(obj_act); sr = lv_obj_get_scroll_right(obj_act); } + else { + bool has_start_snap; + bool has_end_snap; + has_more_snap_points(obj_act, LV_DIR_HOR, &has_start_snap, &has_end_snap); + + /*Assume scrolling is there are more snap point + *Assumed scroll in if there are NO more nap points*/ + sl = has_start_snap ? 1 : -1; + sr = has_end_snap ? 1 : -1; + } /*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) { + if(snap_y == LV_SCROLL_SNAP_NONE) { st = lv_obj_get_scroll_top(obj_act); sb = lv_obj_get_scroll_bottom(obj_act); } + else { + bool has_start_snap; + bool has_end_snap; + has_more_snap_points(obj_act, LV_DIR_VER, &has_start_snap, &has_end_snap); + /*Assume scrolling is there are more snap point + *Assumed scroll in if there are NO more nap points*/ + st = has_start_snap ? 1 : -1; + sb = has_end_snap ? 1 : -1; + } /*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 @@ -639,87 +641,47 @@ 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(diff == 0) return 0; + /*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; + /* + * If the scrolling object does not set the `LV_OBJ_FLAG_SCROLL_ELASTIC` flag, + * make sure that `diff` will not cause the scroll to exceed the `start` or `end` boundary of the content. + * If the content has exceeded the boundary due to external factors like `LV_SCROLL_SNAP_CENTER`, + * then respect the current position instead of going straight back to 0. + */ + const int32_t scroll_ended = diff > 0 ? scroll_start : scroll_end; + if(scroll_ended < 0) diff = 0; + else if(scroll_ended - diff < 0) diff = scroll_ended; } /*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); - bool no_more_start_snap = false; - bool no_more_end_snap = false; - - /*Without snapping just scale down the diff is scrolled out*/ + /*Without snapping just scale down the diff when 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; + return diff / ELASTIC_SLOWNESS_FACTOR; } 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; + return diff; } } - if(no_more_start_snap || no_more_end_snap) { + /*With snapping the widget is scrolled out if there are no more snap points + *at least in one direction (start or end)*/ + bool has_start_snap; + bool has_end_snap; + has_more_snap_points(scroll_obj, dir, &has_start_snap, &has_end_snap); + + if(!has_start_snap || !has_end_snap) { + /*Rounding*/ if(diff < 0) diff -= ELASTIC_SLOWNESS_FACTOR / 2; if(diff > 0) diff += ELASTIC_SLOWNESS_FACTOR / 2; return diff / ELASTIC_SLOWNESS_FACTOR; @@ -731,3 +693,76 @@ static int32_t elastic_diff(lv_obj_t * scroll_obj, int32_t diff, int32_t scroll_ return diff; } + +/** + * Tell is there are more snap point in a given direction considering snap position. + * There is a snap point if there is a snapanble object in the given direction + * @param scroll_obj the object on which snap points should be found + * @param dir LV_DIR_HOR or LV_DIR_VER + * @param has_start_snap true: there is snap point in the start direction (top or left depending on dir) + * @param has_end_snap true: there is snap point in the end direction (bottom or right depending on dir) + * @note snap points will be searched relative to the + * center point in case of LV_SCROLL_SNAP_CENTER + * start point (top or left) in case of LV_SCROLL_SNAP_START + * end point (bottom or right) in case of LV_SCROLL_SNAP_END + */ +static void has_more_snap_points(lv_obj_t * scroll_obj, lv_dir_t dir, bool * has_start_snap, bool * has_end_snap) +{ + *has_start_snap = true; + *has_end_snap = true; + 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); + + 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) *has_end_snap = false; + d = find_snap_point_x(scroll_obj, LV_COORD_MIN, x - 1, 0); + if(d == LV_COORD_MAX) *has_start_snap = false; + } + 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 + 1, LV_COORD_MAX, 0); + if(d == LV_COORD_MAX) *has_end_snap = false; + d = find_snap_point_y(scroll_obj, LV_COORD_MIN, y - 1, 0); + if(d == LV_COORD_MAX) *has_start_snap = false; + } +} 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 2af3bf35a..0f8b7d66a 100644 --- a/lib/libesp32_lvgl/lvgl/src/layouts/flex/lv_flex.c +++ b/lib/libesp32_lvgl/lvgl/src/layouts/flex/lv_flex.c @@ -252,21 +252,37 @@ static int32_t find_track_end(lv_obj_t * cont, flex_t * f, int32_t item_start_id t->grow_dsc = NULL; int32_t item_id = item_start_id; - + int32_t grow_min_size_sum = 0; lv_obj_t * item = lv_obj_get_child(cont, item_id); + bool first_item = true; while(item) { if(item_id != item_start_id && lv_obj_has_flag(item, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK)) break; if(!lv_obj_has_flag_any(item, LV_OBJ_FLAG_IGNORE_LAYOUT | LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) { uint8_t grow_value = lv_obj_get_style_flex_grow(item, LV_PART_MAIN); if(grow_value) { + int32_t min_size = f->row ? lv_obj_get_style_min_width(item, LV_PART_MAIN) + : lv_obj_get_style_min_height(item, LV_PART_MAIN); + + int32_t req_size = min_size; + if(item_id != item_start_id) req_size += item_gap; /*No gap before the first item*/ + + /*Wrap if can't fit*/ + if(f->wrap && t->track_fix_main_size + grow_min_size_sum + req_size > max_main_size) break; + + grow_min_size_sum += req_size; + if(item_id != item_start_id) { + t->track_fix_main_size += item_gap; /*The gap is always taken from the space*/ + } + t->grow_item_cnt++; - t->track_fix_main_size += item_gap; + if(t->grow_dsc_calc) { grow_dsc_t * new_dsc = lv_realloc(t->grow_dsc, sizeof(grow_dsc_t) * (t->grow_item_cnt)); LV_ASSERT_MALLOC(new_dsc); if(new_dsc == NULL) return item_id; + new_dsc[t->grow_item_cnt - 1].item = item; new_dsc[t->grow_item_cnt - 1].min_size = f->row ? lv_obj_get_style_min_width(item, LV_PART_MAIN) : lv_obj_get_style_min_height(item, LV_PART_MAIN); @@ -274,15 +290,19 @@ static int32_t find_track_end(lv_obj_t * cont, flex_t * f, int32_t item_start_id : lv_obj_get_style_max_height(item, LV_PART_MAIN); new_dsc[t->grow_item_cnt - 1].grow_value = grow_value; new_dsc[t->grow_item_cnt - 1].clamped = 0; + t->grow_dsc = new_dsc; } } else { int32_t item_size = get_main_size(item); - if(f->wrap && t->track_fix_main_size + item_size > max_main_size) break; - t->track_fix_main_size += item_size + item_gap; + int32_t req_size = item_size; + if(!first_item) req_size += item_gap; /*No gap before the first item*/ + if(f->wrap && t->track_fix_main_size + grow_min_size_sum + req_size > max_main_size) break; + t->track_fix_main_size += req_size; } + first_item = false; t->track_cross_size = LV_MAX(get_cross_size(item), t->track_cross_size); t->item_cnt++; } @@ -292,8 +312,6 @@ static int32_t find_track_end(lv_obj_t * cont, flex_t * f, int32_t item_start_id item = lv_obj_get_child(cont, item_id); } - if(t->track_fix_main_size > 0) t->track_fix_main_size -= item_gap; /*There is no gap after the last item*/ - /*If there is at least one "grow item" the track takes the full space*/ t->track_main_size = t->grow_item_cnt ? max_main_size : t->track_fix_main_size; @@ -377,6 +395,10 @@ static void children_repos(lv_obj_t * cont, flex_t * f, int32_t item_first_id, i item = get_next_item(cont, f->rev, &item_first_id); continue; } + + uint16_t item_w_layout = item->w_layout; + uint16_t item_h_layout = item->h_layout; + int32_t grow_size = lv_obj_get_style_flex_grow(item, LV_PART_MAIN); if(grow_size) { int32_t s = 0; @@ -412,6 +434,10 @@ static void children_repos(lv_obj_t * cont, flex_t * f, int32_t item_first_id, i item->h_layout = 0; } + if(item->w_layout != item_w_layout || item->h_layout != item_h_layout) { + lv_obj_mark_layout_as_dirty(item); + } + int32_t cross_pos = 0; switch(f->cross_place) { case LV_FLEX_ALIGN_CENTER: 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 70d3f7936..c688c2508 100644 --- a/lib/libesp32_lvgl/lvgl/src/layouts/grid/lv_grid.c +++ b/lib/libesp32_lvgl/lvgl/src/layouts/grid/lv_grid.c @@ -115,7 +115,7 @@ 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) +static inline int32_t lv_div_round_closest(int32_t dividend, int32_t divisor) { return (dividend + divisor / 2) / divisor; } @@ -351,7 +351,7 @@ static void calc_cols(lv_obj_t * cont, lv_grid_calc_t * c) int32_t x = col_templ[i]; if(IS_FR(x)) { int32_t f = GET_FR(x); - c->w[i] = div_round_closest(free_w * f, col_fr_cnt); + c->w[i] = lv_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.*/ @@ -440,7 +440,7 @@ static void calc_rows(lv_obj_t * cont, lv_grid_calc_t * c) int32_t x = row_templ[i]; if(IS_FR(x)) { int32_t f = GET_FR(x); - c->h[i] = div_round_closest(free_h * f, row_fr_cnt); + c->h[i] = lv_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.*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/barcode/LICENSE.txt b/lib/libesp32_lvgl/lvgl/src/libs/barcode/LICENSE.txt new file mode 100644 index 000000000..345556683 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/barcode/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2013-2015, LKC Technologies, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. 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. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "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 COPYRIGHT HOLDER OR +CONTRIBUTORS 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. + 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 56885330b..68034fb50 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode.c @@ -41,7 +41,7 @@ const lv_obj_class_t lv_barcode_class = { .width_def = LV_SIZE_CONTENT, .instance_size = sizeof(lv_barcode_t), .base_class = &lv_canvas_class, - .name = "barcode", + .name = "lv_barcode", }; /********************** @@ -105,6 +105,14 @@ void lv_barcode_set_tiled(lv_obj_t * obj, bool tiled) lv_image_set_inner_align(obj, tiled ? LV_IMAGE_ALIGN_TILE : LV_IMAGE_ALIGN_DEFAULT); } +void lv_barcode_set_encoding(lv_obj_t * obj, lv_barcode_encoding_t encoding) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_barcode_t * barcode = (lv_barcode_t *)obj; + barcode->encoding = encoding; +} + lv_result_t lv_barcode_update(lv_obj_t * obj, const char * data) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -127,10 +135,19 @@ lv_result_t lv_barcode_update(lv_obj_t * obj, const char * data) return LV_RESULT_INVALID; } - int32_t barcode_w = (int32_t) code128_encode_gs1(data, out_buf, len); + lv_barcode_t * barcode = (lv_barcode_t *)obj; + + int32_t barcode_w = 0; + switch(barcode->encoding) { + case LV_BARCODE_ENCODING_CODE128_GS1: + barcode_w = (int32_t) code128_encode_gs1(data, out_buf, len); + break; + case LV_BARCODE_ENCODING_CODE128_RAW: + barcode_w = (int32_t) code128_encode_raw(data, out_buf, len); + break; + } 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; @@ -235,6 +252,14 @@ uint16_t lv_barcode_get_scale(lv_obj_t * obj) return barcode->scale; } +lv_barcode_encoding_t lv_barcode_get_encoding(const lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + const lv_barcode_t * barcode = (const lv_barcode_t *)obj; + return barcode->encoding; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -248,6 +273,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; + barcode->encoding = LV_BARCODE_ENCODING_CODE128_GS1; lv_image_set_inner_align(obj, LV_IMAGE_ALIGN_DEFAULT); } 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 c9c0ce657..79f2e519c 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode.h @@ -28,6 +28,17 @@ extern "C" { * TYPEDEFS **********************/ +typedef enum { + /** + * Code 128 with GS1 encoding. Strips `[FCN1]` and spaces. + */ + LV_BARCODE_ENCODING_CODE128_GS1, + /** + * Code 128 with raw encoding. + */ + LV_BARCODE_ENCODING_CODE128_RAW, +} lv_barcode_encoding_t; + LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_barcode_class; /********************** @@ -76,6 +87,13 @@ void lv_barcode_set_direction(lv_obj_t * obj, lv_dir_t direction); */ void lv_barcode_set_tiled(lv_obj_t * obj, bool tiled); +/** + * Set the encoding of a barcode object + * @param obj pointer to barcode object + * @param encoding encoding (default is `LV_BARCODE_CODE128_GS1`) + */ +void lv_barcode_set_encoding(lv_obj_t * obj, lv_barcode_encoding_t encoding); + /** * Set the data of a barcode object * @param obj pointer to barcode object @@ -105,6 +123,13 @@ lv_color_t lv_barcode_get_light_color(lv_obj_t * obj); */ uint16_t lv_barcode_get_scale(lv_obj_t * obj); +/** + * Get the encoding of a barcode object + * @param obj pointer to barcode object + * @return encoding + */ +lv_barcode_encoding_t lv_barcode_get_encoding(const lv_obj_t * obj); + /********************** * MACROS **********************/ 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 index e6d18198f..c4c28c5ee 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode_private.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/barcode/lv_barcode_private.h @@ -28,13 +28,14 @@ extern "C" { **********************/ /*Data of barcode*/ -struct lv_barcode_t { +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; + lv_barcode_encoding_t encoding; }; 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 45edd65eb..7015558dc 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 @@ -39,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*/ @@ -131,7 +131,7 @@ lv_result_t lv_bin_decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_d res = lv_fs_read(&dsc->file, header, sizeof(lv_image_header_t), &rn); if(res != LV_FS_RES_OK || rn != sizeof(lv_image_header_t)) { - LV_LOG_WARN("Read file header failed: %d", res); + LV_LOG_WARN("Read file header failed: %d with len: %" LV_PRIu32 ", expected: %zu", res, rn, sizeof(lv_image_header_t)); return LV_RESULT_INVALID; } @@ -163,6 +163,11 @@ lv_result_t lv_bin_decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_d return LV_RESULT_INVALID; } + if(header->cf == LV_COLOR_FORMAT_UNKNOWN) { + LV_LOG_WARN("Image color format is unknown"); + return LV_RESULT_INVALID; + } + /*For backward compatibility, all images are not premultiplied for now.*/ if(header->magic != LV_IMAGE_HEADER_MAGIC) { header->flags &= ~LV_IMAGE_FLAGS_PREMULTIPLIED; @@ -235,6 +240,7 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d || cf == LV_COLOR_FORMAT_XRGB8888 \ || cf == LV_COLOR_FORMAT_RGB888 \ || cf == LV_COLOR_FORMAT_RGB565 \ + || cf == LV_COLOR_FORMAT_RGB565_SWAPPED \ || cf == LV_COLOR_FORMAT_RGB565A8 \ || cf == LV_COLOR_FORMAT_ARGB8565) { res = decode_rgb(decoder, dsc); @@ -274,7 +280,7 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d res = decode_indexed(decoder, dsc); } } - else if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(cf)) { + else if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(cf) && cf != LV_COLOR_FORMAT_A8) { /*Alpha only image will need decoder data to store pointer to decoded image, to free it when decoder closes*/ decoder_data_t * decoder_data = get_decoder_data(dsc); if(decoder_data == NULL) { @@ -291,6 +297,7 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d lv_draw_buf_t * decoded; if(image->header.flags & LV_IMAGE_FLAGS_ALLOCATED) { decoded = (lv_draw_buf_t *)image; + res = LV_RESULT_OK; } else { decoded = &decoder_data->c_array; @@ -298,21 +305,22 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d /*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); + res = lv_draw_buf_from_image(decoded, &tmp); } else - lv_draw_buf_from_image(decoded, image); + res = lv_draw_buf_from_image(decoded, image); } - dsc->decoded = decoded; + if(res == LV_RESULT_OK) { + dsc->decoded = decoded; - if(decoded->header.stride == 0) { - /*Use the auto calculated value from decoder_info callback*/ - decoded->header.stride = dsc->header.stride; + if(decoded->header.stride == 0) { + /*Use the auto calculated value from decoder_info callback*/ + decoded->header.stride = dsc->header.stride; + } + + use_directly = true; /*A variable image that can be used directly.*/ } - - res = LV_RESULT_OK; - use_directly = true; /*A variable image that can be used directly.*/ } } @@ -324,6 +332,10 @@ lv_result_t lv_bin_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d if(dsc->decoded == NULL) return LV_RESULT_OK; /*Need to read via get_area_cb*/ lv_draw_buf_t * decoded = (lv_draw_buf_t *)dsc->decoded; + if(dsc->header.flags & LV_IMAGE_FLAGS_PREMULTIPLIED) { + lv_draw_buf_set_flag(decoded, LV_IMAGE_FLAGS_PREMULTIPLIED); + } + lv_draw_buf_t * adjusted = lv_image_decoder_post_process(dsc, decoded); if(adjusted == NULL) { free_decoder_data(dsc); @@ -388,6 +400,7 @@ lv_result_t lv_bin_decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod || cf == LV_COLOR_FORMAT_XRGB8888 \ || cf == LV_COLOR_FORMAT_RGB888 \ || cf == LV_COLOR_FORMAT_RGB565 \ + || cf == LV_COLOR_FORMAT_RGB565_SWAPPED \ || cf == LV_COLOR_FORMAT_ARGB8565 \ || cf == LV_COLOR_FORMAT_RGB565A8; if(!supported) { @@ -473,7 +486,7 @@ lv_result_t lv_bin_decoder_get_area(lv_image_decoder_t * decoder, lv_image_decod } if(cf == LV_COLOR_FORMAT_ARGB8888 || cf == LV_COLOR_FORMAT_XRGB8888 || cf == LV_COLOR_FORMAT_RGB888 - || cf == LV_COLOR_FORMAT_RGB565 || cf == LV_COLOR_FORMAT_ARGB8565) { + || cf == LV_COLOR_FORMAT_RGB565 || cf == LV_COLOR_FORMAT_RGB565_SWAPPED || cf == LV_COLOR_FORMAT_ARGB8565) { uint32_t len = (w_px * bpp) / 8; offset += decoded_area->y1 * dsc->header.stride; offset += decoded_area->x1 * bpp / 8; /*Move to x1*/ @@ -582,7 +595,7 @@ static lv_result_t decode_indexed(lv_image_decoder_t * decoder, lv_image_decoder res = fs_read_file_at(f, sizeof(lv_image_header_t), (uint8_t *)palette, palette_len, &rn); if(res != LV_FS_RES_OK || rn != palette_len) { - LV_LOG_WARN("Read palette failed: %d", res); + LV_LOG_WARN("Read palette failed: %d, with len: %" LV_PRIu32 ", expected: %" LV_PRIu32, res, rn, palette_len); lv_free((void *)palette); return LV_RESULT_INVALID; } @@ -610,7 +623,7 @@ static lv_result_t decode_indexed(lv_image_decoder_t * decoder, lv_image_decoder data_len -= data_offset; res = fs_read_file_at(f, data_offset, (uint8_t *)indexed_data, data_len, &rn); if(res != LV_FS_RES_OK || rn != data_len) { - LV_LOG_WARN("Read indexed image failed: %d", res); + LV_LOG_WARN("Read indexed image failed: %d, with len: %" LV_PRIu32 ", expected: %" LV_PRIu32, res, rn, data_len); goto exit_with_buf; } #endif @@ -706,7 +719,10 @@ static lv_result_t load_indexed(lv_image_decoder_t * decoder, lv_image_decoder_d } else { decoded = &decoder_data->c_array; - lv_draw_buf_from_image(decoded, image); + lv_result_t result = lv_draw_buf_from_image(decoded, image); + if(result != LV_RESULT_OK) { + return result; + } } dsc->decoded = decoded; @@ -733,7 +749,7 @@ static lv_result_t load_indexed(lv_image_decoder_t * decoder, lv_image_decoder_d uint32_t palette_len = sizeof(lv_color32_t) * LV_COLOR_INDEXED_PALETTE_SIZE(cf); res = fs_read_file_at(f, sizeof(lv_image_header_t), data, palette_len, &rn); if(res != LV_FS_RES_OK || rn != palette_len) { - LV_LOG_WARN("Read palette failed: %d", res); + LV_LOG_WARN("Read palette failed: %d, with len: %" LV_PRIu32 ", expected: %" LV_PRIu32, res, rn, palette_len); lv_draw_buf_destroy(decoded); return LV_RESULT_INVALID; } @@ -751,7 +767,7 @@ static lv_result_t load_indexed(lv_image_decoder_t * decoder, lv_image_decoder_d data += palette_len; res = fs_read_file_at(f, data_offset, data, data_len, &rn); if(res != LV_FS_RES_OK || rn != data_len) { - LV_LOG_WARN("Read indexed image failed: %d", res); + LV_LOG_WARN("Read indexed image failed: %d, with len: %" LV_PRIu32 ", expected: %" LV_PRIu32, res, rn, data_len); lv_draw_buf_destroy(decoded); return LV_RESULT_INVALID; } @@ -792,7 +808,7 @@ static lv_result_t decode_rgb(lv_image_decoder_t * decoder, lv_image_decoder_dsc uint32_t rn; res = fs_read_file_at(f, sizeof(lv_image_header_t), img_data, len, &rn); if(res != LV_FS_RES_OK || rn != len) { - LV_LOG_WARN("Read rgb file failed: %d", res); + LV_LOG_WARN("Read rgb file failed: %d, with len: %" LV_PRIu32 ", expected: %" LV_PRIu32, res, rn, len); lv_draw_buf_destroy(decoded); return LV_RESULT_INVALID; } @@ -827,6 +843,12 @@ static lv_result_t decode_alpha_only(lv_image_decoder_t * decoder, lv_image_deco uint32_t rn; decoder_data_t * decoder_data = dsc->user_data; uint8_t bpp = lv_color_format_get_bpp(dsc->header.cf); + + if(bpp == 0) { + LV_LOG_ERROR("Error color format: %d", dsc->header.cf); + return LV_RESULT_INVALID; + } + uint32_t w = (dsc->header.stride * 8) / bpp; uint32_t buf_stride = (w * 8 + 7) >> 3; /*stride for img_data*/ uint32_t buf_len = w * dsc->header.h; /*always decode to A8 format*/ @@ -849,7 +871,7 @@ static lv_result_t decode_alpha_only(lv_image_decoder_t * decoder, lv_image_deco else if(dsc->src_type == LV_IMAGE_SRC_FILE) { res = fs_read_file_at(decoder_data->f, sizeof(lv_image_header_t), img_data, file_len, &rn); if(res != LV_FS_RES_OK || rn != file_len) { - LV_LOG_WARN("Read header failed: %d", res); + LV_LOG_WARN("Read header failed: %d, with len: %" LV_PRIu32 ", expected: %" LV_PRIu32, res, rn, file_len); lv_draw_buf_destroy(decoded); return LV_RESULT_INVALID; } @@ -921,7 +943,7 @@ static lv_result_t decode_compressed(lv_image_decoder_t * decoder, lv_image_deco len = 12; 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); + LV_LOG_WARN("Read compressed header failed: %d, with len: %" LV_PRIu32 ", expected: %" LV_PRIu32, fs_res, rn, len); return LV_RESULT_INVALID; } @@ -940,7 +962,8 @@ static lv_result_t decode_compressed(lv_image_decoder_t * decoder, lv_image_deco /*Continue to read the compressed data following compression header*/ 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_LOG_WARN("Read compressed file failed: %d, with len: %" LV_PRIu32 ", expected: %" LV_PRIu32, fs_res, rn, + compressed_len); lv_free(file_buf); return LV_RESULT_INVALID; } @@ -977,7 +1000,7 @@ static lv_result_t decode_compressed(lv_image_decoder_t * decoder, lv_image_deco /*Depends on the cf, need to further decode image like an C-array image*/ lv_image_dsc_t * image = (lv_image_dsc_t *)dsc->src; - if(image->data == NULL) { + if(dsc->src_type == LV_IMAGE_SRC_VARIABLE && image->data == NULL) { return LV_RESULT_INVALID; } @@ -1077,6 +1100,26 @@ static lv_fs_res_t fs_read_file_at(lv_fs_file_t * f, uint32_t pos, void * buff, static lv_result_t decompress_image(lv_image_decoder_dsc_t * dsc, const lv_image_compressed_t * compressed) { + /* At least one compression method must be enabled */ +#if (LV_USE_LZ4 || LV_USE_RLE) + /* Check if the decompression method is enabled and valid */ + if(compressed->method == LV_IMAGE_COMPRESS_RLE) { +#if !LV_USE_RLE + LV_LOG_WARN("RLE decompression is not enabled"); + return LV_RESULT_INVALID; +#endif + } + else if(compressed->method == LV_IMAGE_COMPRESS_LZ4) { +#if !LV_USE_LZ4 + LV_LOG_WARN("LZ4 decompression is not enabled"); + return LV_RESULT_INVALID; +#endif + } + else { + LV_LOG_WARN("Unknown compression method: %" LV_PRIu32, compressed->method); + return LV_RESULT_INVALID; + } + /*Need to store decompressed data to decoder to free on close*/ decoder_data_t * decoder_data = get_decoder_data(dsc); if(decoder_data == NULL) { @@ -1086,8 +1129,7 @@ static lv_result_t decompress_image(lv_image_decoder_dsc_t * dsc, const lv_image uint8_t * img_data; uint32_t out_len = compressed->decompressed_size; uint32_t input_len = compressed->compressed_size; - LV_UNUSED(input_len); - LV_UNUSED(out_len); + uint32_t len = 0; lv_draw_buf_t * decompressed = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, dsc->header.w, dsc->header.h, dsc->header.cf, @@ -1113,45 +1155,38 @@ static lv_result_t decompress_image(lv_image_decoder_dsc_t * dsc, const lv_image pixel_byte = 2; else pixel_byte = (lv_color_format_get_bpp(dsc->header.cf) + 7) >> 3; + const uint8_t * input = compressed->data; uint8_t * output = img_data; - uint32_t len; + len = lv_rle_decompress(input, input_len, output, out_len, pixel_byte); - if(len != compressed->decompressed_size) { - LV_LOG_WARN("Decompress failed: %" LV_PRIu32 ", got: %" LV_PRIu32, out_len, len); - lv_draw_buf_destroy(decompressed); - return LV_RESULT_INVALID; - } -#else - LV_LOG_WARN("RLE decompress is not enabled"); - lv_draw_buf_destroy(decompressed); - return LV_RESULT_INVALID; -#endif +#endif /* LV_USE_RLE */ } else if(compressed->method == LV_IMAGE_COMPRESS_LZ4) { #if LV_USE_LZ4 const char * input = (const char *)compressed->data; char * output = (char *)img_data; - int len; - len = LZ4_decompress_safe(input, output, input_len, out_len); - if(len < 0 || (uint32_t)len != compressed->decompressed_size) { - LV_LOG_WARN("Decompress failed: %" LV_PRId32 ", got: %" LV_PRId32, out_len, len); - lv_draw_buf_destroy(decompressed); - return LV_RESULT_INVALID; + + int ret = LZ4_decompress_safe(input, output, (int)input_len, (int)out_len); + if(ret >= 0) { + /* Cast is safe because of the above check */ + len = (uint32_t)ret; } -#else - LV_LOG_WARN("LZ4 decompress is not enabled"); - lv_draw_buf_destroy(decompressed); - return LV_RESULT_INVALID; -#endif +#endif /* LV_USE_LZ4 */ } - else { - LV_UNUSED(img_data); - LV_LOG_WARN("Unknown compression method: %d", compressed->method); + + if(len != compressed->decompressed_size) { + LV_LOG_WARN("Decompress failed: %" LV_PRIu32 ", got: %" LV_PRIu32, out_len, len); lv_draw_buf_destroy(decompressed); return LV_RESULT_INVALID; } decoder_data->decompressed = decompressed; /*Free on decoder close*/ return LV_RESULT_OK; +#else + LV_UNUSED(dsc); + LV_UNUSED(compressed); + LV_LOG_WARN("At least one compression method must be enabled"); + return LV_RESULT_INVALID; +#endif /* (LV_USE_LZ4 || LV_USE_RLE) */ } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/LICENSE.txt b/lib/libesp32_lvgl/lvgl/src/libs/expat/LICENSE.txt new file mode 100644 index 000000000..c6d184a8a --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/LICENSE.txt @@ -0,0 +1,21 @@ +Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper +Copyright (c) 2001-2025 Expat maintainers + +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. diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/add_lvgl_if.sh b/lib/libesp32_lvgl/lvgl/src/libs/expat/add_lvgl_if.sh new file mode 100644 index 000000000..26752e868 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/add_lvgl_if.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +#Add LVGL #if LV_USE_THORVG_INTERNAL guard +#Usage +# find -name "*.cpp" | xargs ./add_lvgl_if.sh +# find -name "t*.h" | xargs ./add_lvgl_if.sh + +sed '0,/\*\/$/ {/\*\/$/ {n; s|^|\n#include "../../lv_conf_internal.h"\n#if LV_USE_XML\n|}}' $@ -i + +sed -i -e '$a\ +\ +#endif /* LV_USE_XML */\ +' $@ -i diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/ascii.h b/lib/libesp32_lvgl/lvgl/src/libs/expat/ascii.h new file mode 100644 index 000000000..d4a868fe3 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/ascii.h @@ -0,0 +1,129 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1999-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2002 Fred L. Drake, Jr. + Copyright (c) 2007 Karl Waclawek + Copyright (c) 2017 Sebastian Pipping + Licensed under the MIT license: + + 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_XML + +#define ASCII_A 0x41 +#define ASCII_B 0x42 +#define ASCII_C 0x43 +#define ASCII_D 0x44 +#define ASCII_E 0x45 +#define ASCII_F 0x46 +#define ASCII_G 0x47 +#define ASCII_H 0x48 +#define ASCII_I 0x49 +#define ASCII_J 0x4A +#define ASCII_K 0x4B +#define ASCII_L 0x4C +#define ASCII_M 0x4D +#define ASCII_N 0x4E +#define ASCII_O 0x4F +#define ASCII_P 0x50 +#define ASCII_Q 0x51 +#define ASCII_R 0x52 +#define ASCII_S 0x53 +#define ASCII_T 0x54 +#define ASCII_U 0x55 +#define ASCII_V 0x56 +#define ASCII_W 0x57 +#define ASCII_X 0x58 +#define ASCII_Y 0x59 +#define ASCII_Z 0x5A + +#define ASCII_a 0x61 +#define ASCII_b 0x62 +#define ASCII_c 0x63 +#define ASCII_d 0x64 +#define ASCII_e 0x65 +#define ASCII_f 0x66 +#define ASCII_g 0x67 +#define ASCII_h 0x68 +#define ASCII_i 0x69 +#define ASCII_j 0x6A +#define ASCII_k 0x6B +#define ASCII_l 0x6C +#define ASCII_m 0x6D +#define ASCII_n 0x6E +#define ASCII_o 0x6F +#define ASCII_p 0x70 +#define ASCII_q 0x71 +#define ASCII_r 0x72 +#define ASCII_s 0x73 +#define ASCII_t 0x74 +#define ASCII_u 0x75 +#define ASCII_v 0x76 +#define ASCII_w 0x77 +#define ASCII_x 0x78 +#define ASCII_y 0x79 +#define ASCII_z 0x7A + +#define ASCII_0 0x30 +#define ASCII_1 0x31 +#define ASCII_2 0x32 +#define ASCII_3 0x33 +#define ASCII_4 0x34 +#define ASCII_5 0x35 +#define ASCII_6 0x36 +#define ASCII_7 0x37 +#define ASCII_8 0x38 +#define ASCII_9 0x39 + +#define ASCII_TAB 0x09 +#define ASCII_SPACE 0x20 +#define ASCII_EXCL 0x21 +#define ASCII_QUOT 0x22 +#define ASCII_AMP 0x26 +#define ASCII_APOS 0x27 +#define ASCII_MINUS 0x2D +#define ASCII_PERIOD 0x2E +#define ASCII_COLON 0x3A +#define ASCII_SEMI 0x3B +#define ASCII_LT 0x3C +#define ASCII_EQUALS 0x3D +#define ASCII_GT 0x3E +#define ASCII_LSQB 0x5B +#define ASCII_RSQB 0x5D +#define ASCII_UNDERSCORE 0x5F +#define ASCII_LPAREN 0x28 +#define ASCII_RPAREN 0x29 +#define ASCII_FF 0x0C +#define ASCII_SLASH 0x2F +#define ASCII_HASH 0x23 +#define ASCII_PIPE 0x7C +#define ASCII_COMMA 0x2C + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/asciitab.h b/lib/libesp32_lvgl/lvgl/src/libs/expat/asciitab.h new file mode 100644 index 000000000..ed7942dfa --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/asciitab.h @@ -0,0 +1,72 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2002 Fred L. Drake, Jr. + Copyright (c) 2017 Sebastian Pipping + Licensed under the MIT license: + + 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_XML + +/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, + /* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML, + /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, + /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, + /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, + /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, + /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, + /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, + /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, + /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, + /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, + /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, + /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, + /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, + /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, + /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, + /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, + /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/expat.h b/lib/libesp32_lvgl/lvgl/src/libs/expat/expat.h new file mode 100644 index 000000000..959e3b08b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/expat.h @@ -0,0 +1,1081 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2000-2005 Fred L. Drake, Jr. + Copyright (c) 2001-2002 Greg Stein + Copyright (c) 2002-2016 Karl Waclawek + Copyright (c) 2016-2024 Sebastian Pipping + Copyright (c) 2016 Cristian Rodríguez + Copyright (c) 2016 Thomas Beutlich + Copyright (c) 2017 Rhodri James + Copyright (c) 2022 Thijs Schreijer + Copyright (c) 2023 Hanno Böck + Copyright (c) 2023 Sony Corporation / Snild Dolkow + Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp> + Licensed under the MIT license: + + 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_XML + +#ifndef Expat_INCLUDED +#define Expat_INCLUDED 1 + +#include +#include "expat_external.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +typedef unsigned char XML_Bool; +#define XML_TRUE ((XML_Bool)1) +#define XML_FALSE ((XML_Bool)0) + +/* The XML_Status enum gives the possible return values for several + API functions. The preprocessor #defines are included so this + stanza can be added to code that still needs to support older + versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been + dropped. +*/ +enum XML_Status { + XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1, +#define XML_STATUS_OK XML_STATUS_OK + XML_STATUS_SUSPENDED = 2 +#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED +}; + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, + /* Added in 1.95.7. */ + XML_ERROR_UNBOUND_PREFIX, + /* Added in 1.95.8. */ + XML_ERROR_UNDECLARING_PREFIX, + XML_ERROR_INCOMPLETE_PE, + XML_ERROR_XML_DECL, + XML_ERROR_TEXT_DECL, + XML_ERROR_PUBLICID, + XML_ERROR_SUSPENDED, + XML_ERROR_NOT_SUSPENDED, + XML_ERROR_ABORTED, + XML_ERROR_FINISHED, + XML_ERROR_SUSPEND_PE, + /* Added in 2.0. */ + XML_ERROR_RESERVED_PREFIX_XML, + XML_ERROR_RESERVED_PREFIX_XMLNS, + XML_ERROR_RESERVED_NAMESPACE_URI, + /* Added in 2.2.1. */ + XML_ERROR_INVALID_ARGUMENT, + /* Added in 2.3.0. */ + XML_ERROR_NO_BUFFER, + /* Added in 2.4.0. */ + XML_ERROR_AMPLIFICATION_LIMIT_BREACH +}; + +enum XML_Content_Type { + XML_CTYPE_EMPTY = 1, + XML_CTYPE_ANY, + XML_CTYPE_MIXED, + XML_CTYPE_NAME, + XML_CTYPE_CHOICE, + XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { + XML_CQUANT_NONE, + XML_CQUANT_OPT, + XML_CQUANT_REP, + XML_CQUANT_PLUS +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char *name; + unsigned int numchildren; + XML_Content *children; +}; + +/* This is called for an element declaration. See above for + description of the model argument. It's the user code's responsibility + to free model when finished with it. See XML_FreeContentModel. + There is no need to free the model from the handler, it can be kept + around and freed at a later stage. +*/ +typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData, + const XML_Char *name, + XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void(XMLCALL *XML_AttlistDeclHandler)( + void *userData, const XML_Char *elname, const XML_Char *attname, + const XML_Char *att_type, const XML_Char *dflt, int isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +typedef void(XMLCALL *XML_XmlDeclHandler)(void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler xmldecl); + +typedef struct { + void *(*malloc_fcn)(size_t size); + void *(*realloc_fcn)(void *ptr, size_t size); + void (*free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + It is a programming error to use the separator '\0' with namespace + triplets (see XML_SetReturnNSTriplet). + If a namespace separator is chosen that can be part of a URI or + part of an XML name, splitting an expanded name back into its + 1, 2 or 3 original parts on application level in the element handler + may end up vulnerable, so these are advised against; sane choices for + a namespace separator are e.g. '\n' (line feed) and '|' (pipe). + + Note that Expat does not validate namespace URIs (beyond encoding) + against RFC 3986 today (and is not required to do so with regard to + the XML 1.0 namespaces specification) but it may start doing that + in future releases. Before that, an application using Expat must + be ready to receive namespace URIs containing non-URI characters. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be reused. This is particularly + valuable when memory allocation overhead is disproportionately high, + such as when a large number of small documnents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +typedef void(XMLCALL *XML_StartElementHandler)(void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void(XMLCALL *XML_EndElementHandler)(void *userData, + const XML_Char *name); + +/* s is not 0 terminated. */ +typedef void(XMLCALL *XML_CharacterDataHandler)(void *userData, + const XML_Char *s, int len); + +/* target and data are 0 terminated */ +typedef void(XMLCALL *XML_ProcessingInstructionHandler)(void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void(XMLCALL *XML_CommentHandler)(void *userData, const XML_Char *data); + +typedef void(XMLCALL *XML_StartCdataSectionHandler)(void *userData); +typedef void(XMLCALL *XML_EndCdataSectionHandler)(void *userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +typedef void(XMLCALL *XML_DefaultHandler)(void *userData, const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); + +/* This is called for the end of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +typedef void(XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT null-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +typedef void(XMLCALL *XML_EntityDeclHandler)( + void *userData, const XML_Char *entityName, int is_parameter_entity, + const XML_Char *value, int value_length, const XML_Char *base, + const XML_Char *systemId, const XML_Char *publicId, + const XML_Char *notationName); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superseded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +typedef void(XMLCALL *XML_UnparsedEntityDeclHandler)( + void *userData, const XML_Char *entityName, const XML_Char *base, + const XML_Char *systemId, const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +typedef void(XMLCALL *XML_NotationDeclHandler)(void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +typedef void(XMLCALL *XML_StartNamespaceDeclHandler)(void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void(XMLCALL *XML_EndNamespaceDeclHandler)(void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +typedef int(XMLCALL *XML_ExternalEntityRefHandler)(XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +typedef void(XMLCALL *XML_SkippedEntityHandler)(void *userData, + const XML_Char *entityName, + int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +typedef struct { + int map[256]; + void *data; + int(XMLCALL *convert)(void *data, const char *s); + void(XMLCALL *release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_ERROR_UNKNOWN_ENCODING error. +*/ +typedef int(XMLCALL *XML_UnknownEncodingHandler)(void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler handler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler handler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: For the purpose of checking WFC: Entity Declared, passing + useDTD == XML_TRUE will make the parser behave as if the document + had a DTD with an external subset. + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. + Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this corresponds to an index into the atts array passed to the + XML_StartElementHandler. Returns -1 if parser == NULL. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute or + parser == NULL. Each attribute/value pair counts as 2; thus this + corresponds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +#ifdef XML_ATTR_INFO +/* Source file byte offsets for the start and end of attribute names and values. + The value indices are exclusive of surrounding quotes; thus in a UTF-8 source + file an attribute value of "blah" will yield: + info->valueEnd - info->valueStart = 4 bytes. +*/ +typedef struct { + XML_Index nameStart; /* Offset to beginning of the attribute name. */ + XML_Index nameEnd; /* Offset after the attribute name's last byte. */ + XML_Index valueStart; /* Offset to beginning of the attribute value. */ + XML_Index valueEnd; /* Offset after the attribute value's last byte. */ +} XML_AttrInfo; + +/* Returns an array of XML_AttrInfo structures for the attribute/value pairs + passed in last call to the XML_StartElementHandler that were specified + in the start-tag rather than defaulted. Each attribute/value pair counts + as 1; thus the number of entries in the array is + XML_GetSpecifiedAttributeCount(parser) / 2. +*/ +XMLPARSEAPI(const XML_AttrInfo *) +XML_GetAttributeInfo(XML_Parser parser); +#endif + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + Though the return values for these functions has always been + described as a Boolean value, the implementation, at least for the + 1.95.x series, has always returned exactly one of the XML_Status + values. +*/ +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. + Must be called from within a call-back handler, except when aborting + (resumable = 0) an already suspended parser. Some call-backs may + still follow because they would otherwise get lost. Examples: + - endElementHandler() for empty elements when stopped in + startElementHandler(), + - endNameSpaceDeclHandler() when stopped in endElementHandler(), + and possibly others. + + Can be called from most handlers, including DTD related call-backs, + except when parsing an external parameter entity and resumable != 0. + Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. + Possible error codes: + - XML_ERROR_SUSPENDED: when suspending an already suspended parser. + - XML_ERROR_FINISHED: when the parser has already finished. + - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. + + When resumable != 0 (true) then parsing is suspended, that is, + XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. + Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() + return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. + + *Note*: + This will be applied to the current parser instance only, that is, if + there is a parent parser then it will continue parsing when the + externalEntityRefHandler() returns. It is up to the implementation of + the externalEntityRefHandler() to call XML_StopParser() on the parent + parser (recursively), if one wants to stop parsing altogether. + + When suspended, parsing can be resumed by calling XML_ResumeParser(). +*/ +XMLPARSEAPI(enum XML_Status) +XML_StopParser(XML_Parser parser, XML_Bool resumable); + +/* Resumes parsing after it has been suspended with XML_StopParser(). + Must not be called from within a handler call-back. Returns same + status codes as XML_Parse() or XML_ParseBuffer(). + Additional error code XML_ERROR_NOT_SUSPENDED possible. + + *Note*: + This must be called on the most deeply nested child parser instance + first, and on its parent parser only after the child parser has finished, + to be applied recursively until the document entity's parser is restarted. + That is, the parent parser will not resume by itself and it is up to the + application to call XML_ResumeParser() on it at the appropriate moment. +*/ +XMLPARSEAPI(enum XML_Status) +XML_ResumeParser(XML_Parser parser); + +enum XML_Parsing { XML_INITIALIZED, XML_PARSING, XML_FINISHED, XML_SUSPENDED }; + +typedef struct { + enum XML_Parsing parsing; + XML_Bool finalBuffer; +} XML_ParsingStatus; + +/* Returns status of parser with respect to being initialized, parsing, + finished, or suspended and processing the final buffer. + XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, + XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED +*/ +XMLPARSEAPI(void) +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. + Note: If parser == NULL, the function will do nothing and return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* Sets the hash salt to use for internal hash calculations. + Helps in preventing DoS attacks based on predicting hash + function behavior. This must be called before parsing is started. + Returns 1 if successful, 0 when called after parsing has started. + Note: If parser == NULL, the function will do nothing and return 0. +*/ +XMLPARSEAPI(int) +XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of the + first of the sequence of characters that generated the event. When + called from callbacks generated by declarations in the document + prologue, the location identified isn't as neatly defined, but will + be within the relevant markup. When called outside of the callback + functions, the position indicated will be just past the last parse + event (regardless of whether there was an associated callback). + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. + + Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber + return 0 to indicate an error. + Note: XML_GetCurrentByteIndex returns -1 to indicate an error. +*/ +XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is >=1, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, int *offset, int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_ATTR_MALLOC +XML_ATTR_ALLOC_SIZE(2) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_ATTR_ALLOC_SIZE(3) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { + int major; + int minor; + int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { + XML_FEATURE_END = 0, + XML_FEATURE_UNICODE, + XML_FEATURE_UNICODE_WCHAR_T, + XML_FEATURE_DTD, + XML_FEATURE_CONTEXT_BYTES, + XML_FEATURE_MIN_SIZE, + XML_FEATURE_SIZEOF_XML_CHAR, + XML_FEATURE_SIZEOF_XML_LCHAR, + XML_FEATURE_NS, + XML_FEATURE_LARGE_SIZE, + XML_FEATURE_ATTR_INFO, + /* Added in Expat 2.4.0. */ + XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT, + XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT, + /* Added in Expat 2.6.0. */ + XML_FEATURE_GE + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + +#if defined(XML_DTD) || (defined(XML_GE) && XML_GE == 1) +/* Added in Expat 2.4.0 for XML_DTD defined and + * added in Expat 2.6.0 for XML_GE == 1. */ +XMLPARSEAPI(XML_Bool) +XML_SetBillionLaughsAttackProtectionMaximumAmplification( + XML_Parser parser, float maximumAmplificationFactor); + +/* Added in Expat 2.4.0 for XML_DTD defined and + * added in Expat 2.6.0 for XML_GE == 1. */ +XMLPARSEAPI(XML_Bool) +XML_SetBillionLaughsAttackProtectionActivationThreshold( + XML_Parser parser, unsigned long long activationThresholdBytes); +#endif + +/* Added in Expat 2.6.0. */ +XMLPARSEAPI(XML_Bool) +XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled); + +/* Expat follows the semantic versioning convention. + See https://semver.org +*/ +#define XML_MAJOR_VERSION 2 +#define XML_MINOR_VERSION 6 +#define XML_MICRO_VERSION 3 + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_INCLUDED */ + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/expat_config.h b/lib/libesp32_lvgl/lvgl/src/libs/expat/expat_config.h new file mode 100644 index 000000000..f368c9b9a --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/expat_config.h @@ -0,0 +1,151 @@ +/* expat_config.h. Generated from expat_config.h.in by configure. */ + +#include "../../lv_conf_internal.h" +#if LV_USE_XML +/* expat_config.h.in. Generated from configure.ac by autoheader. */ + +#ifndef EXPAT_CONFIG_H +#define EXPAT_CONFIG_H 1 + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* 1234 = LILENDIAN, 4321 = BIGENDIAN */ +#define BYTEORDER 1234 + +#define XML_POOR_ENTROPY 1 + +/* Define to 1 if you have the `arc4random' function. */ +/* #undef HAVE_ARC4RANDOM */ + +/* Define to 1 if you have the `arc4random_buf' function. */ +/* #undef HAVE_ARC4RANDOM_BUF */ + +/* define if the compiler supports basic C++11 syntax */ +/*#define HAVE_CXX11 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_DLFCN_H 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_FCNTL_H 1*/ + +/* Define to 1 if you have the `getpagesize' function. */ +/*#define HAVE_GETPAGESIZE 1*/ + +/* Define to 1 if you have the `getrandom' function. */ +/*#define HAVE_GETRANDOM 1*/ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `bsd' library (-lbsd). */ +/* #undef HAVE_LIBBSD */ + +/* Define to 1 if you have a working `mmap' system call. */ +/*#define HAVE_MMAP 1*/ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +/*#define HAVE_STRINGS_H 1*/ + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have `syscall' and `SYS_getrandom'. */ +//#define HAVE_SYSCALL_GETRANDOM 0 + +/* Define to 1 if you have the header file. */ +/*#define HAVE_SYS_PARAM_H 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_SYS_STAT_H 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_SYS_TYPES_H 1*/ + +/* Define to 1 if you have the header file. */ +/*#define HAVE_UNISTD_H 1*/ + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "expat" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "https://github.com/libexpat/libexpat/issues" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "expat" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "expat 2.6.3" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "expat" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.6.3" + +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "2.6.3" + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Define to allow retrieving the byte offsets for attribute names and values. + */ +/* #undef XML_ATTR_INFO */ + +/* Define to specify how much context to retain around the current parse + point, 0 to disable. */ +#define XML_CONTEXT_BYTES 1024 + +/* Define to include code reading entropy from `/dev/urandom'. */ +/*#define XML_DEV_URANDOM 1*/ + +/* Define to make parameter entity parsing functionality available. */ +/*#define XML_DTD 1*/ + +/* Define as 1/0 to enable/disable support for general entities. */ +#define XML_GE 0 + +/* Define to make XML Namespaces functionality available. */ +/*#define XML_NS 1*/ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `long int' if does not define. */ +/* #undef off_t */ + +#endif // ndef EXPAT_CONFIG_H + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/expat_external.h b/lib/libesp32_lvgl/lvgl/src/libs/expat/expat_external.h new file mode 100644 index 000000000..e4e2992e6 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/expat_external.h @@ -0,0 +1,171 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2000-2004 Fred L. Drake, Jr. + Copyright (c) 2001-2002 Greg Stein + Copyright (c) 2002-2006 Karl Waclawek + Copyright (c) 2016 Cristian Rodríguez + Copyright (c) 2016-2019 Sebastian Pipping + Copyright (c) 2017 Rhodri James + Copyright (c) 2018 Yury Gribov + Licensed under the MIT license: + + 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_XML + +#ifndef Expat_External_INCLUDED +#define Expat_External_INCLUDED 1 + +/* External API definitions */ + +/* Expat tries very hard to make the API boundary very specifically + defined. There are two macros defined to control this boundary; + each of these can be defined before including this header to + achieve some different behavior, but doing so it not recommended or + tested frequently. + + XMLCALL - The calling convention to use for all calls across the + "library boundary." This will default to cdecl, and + try really hard to tell the compiler that's what we + want. + + XMLIMPORT - Whatever magic is needed to note that a function is + to be imported from a dynamically loaded library + (.dll, .so, or .sl, depending on your platform). + + The XMLCALL macro was added in Expat 1.95.7. The only one which is + expected to be directly useful in client code is XMLCALL. + + Note that on at least some Unix versions, the Expat library must be + compiled with the cdecl calling convention as the default since + system headers may assume the cdecl convention. +*/ +#ifndef XMLCALL +# if defined(_MSC_VER) +# define XMLCALL __cdecl +# elif defined(__GNUC__) && defined(__i386) && ! defined(__INTEL_COMPILER) +# define XMLCALL __attribute__((cdecl)) +# else +/* For any platform which uses this definition and supports more than + one calling convention, we need to extend this definition to + declare the convention used on that platform, if it's possible to + do so. + + If this is the case for your platform, please file a bug report + with information on how to identify your platform via the C + pre-processor and how to specify the same calling convention as the + platform's malloc() implementation. +*/ +# define XMLCALL +# endif +#endif /* not defined XMLCALL */ + +#if ! defined(XML_STATIC) && ! defined(XMLIMPORT) +# ifndef XML_BUILDING_EXPAT +/* using Expat from an application */ + +# if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) && ! defined(__CYGWIN__) +# define XMLIMPORT __declspec(dllimport) +# endif + +# endif +#endif /* not defined XML_STATIC */ + +#ifndef XML_ENABLE_VISIBILITY +# define XML_ENABLE_VISIBILITY 0 +#endif + +#if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY +# define XMLIMPORT __attribute__((visibility("default"))) +#endif + +/* If we didn't define it above, define it away: */ +#ifndef XMLIMPORT +# define XMLIMPORT +#endif + +#if defined(__GNUC__) \ + && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)) +# define XML_ATTR_MALLOC __attribute__((__malloc__)) +#else +# define XML_ATTR_MALLOC +#endif + +#if defined(__GNUC__) \ + && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +# define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x))) +#else +# define XML_ATTR_ALLOC_SIZE(x) +#endif + +#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +# ifndef XML_UNICODE +# define XML_UNICODE +# endif +# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2) +# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc" +# endif +#endif + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +# ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +# else +typedef unsigned short XML_Char; +typedef char XML_LChar; +# endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ +typedef long long XML_Index; +typedef unsigned long long XML_Size; +#else +typedef long XML_Index; +typedef unsigned long XML_Size; +#endif /* XML_LARGE_SIZE */ + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_External_INCLUDED */ + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/iasciitab.h b/lib/libesp32_lvgl/lvgl/src/libs/expat/iasciitab.h new file mode 100644 index 000000000..9a2ba4eb9 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/iasciitab.h @@ -0,0 +1,73 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2002 Fred L. Drake, Jr. + Copyright (c) 2017 Sebastian Pipping + Licensed under the MIT license: + + 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_XML + +/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */ +/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, + /* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML, + /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, + /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, + /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, + /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, + /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, + /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, + /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, + /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, + /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, + /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, + /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, + /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, + /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, + /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, + /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, + /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/internal.h b/lib/libesp32_lvgl/lvgl/src/libs/expat/internal.h new file mode 100644 index 000000000..07f1897f9 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/internal.h @@ -0,0 +1,182 @@ +/* internal.h + + Internal definitions used by Expat. This is not needed to compile + client code. + + The following calling convention macros are defined for frequently + called functions: + + FASTCALL - Used for those internal functions that have a simple + body and a low number of arguments and local variables. + + PTRCALL - Used for functions called though function pointers. + + PTRFASTCALL - Like PTRCALL, but for low number of arguments. + + inline - Used for selected internal functions for which inlining + may improve performance on some platforms. + + Note: Use of these macros is based on judgement, not hard rules, + and therefore subject to change. + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 2002-2003 Fred L. Drake, Jr. + Copyright (c) 2002-2006 Karl Waclawek + Copyright (c) 2003 Greg Stein + Copyright (c) 2016-2024 Sebastian Pipping + Copyright (c) 2018 Yury Gribov + Copyright (c) 2019 David Loffredo + Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow + Copyright (c) 2024 Taichi Haradaguchi <20001722@ymail.ne.jp> + Licensed under the MIT license: + + 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_XML + +#if defined(__GNUC__) && defined(__i386__) && ! defined(__MINGW32__) +/* We'll use this version by default only where we know it helps. + + regparm() generates warnings on Solaris boxes. See SF bug #692878. + + Instability reported with egcs on a RedHat Linux 7.3. + Let's comment out: + #define FASTCALL __attribute__((stdcall, regparm(3))) + and let's try this: +*/ +# define FASTCALL __attribute__((regparm(3))) +# define PTRFASTCALL __attribute__((regparm(3))) +#endif + +/* Using __fastcall seems to have an unexpected negative effect under + MS VC++, especially for function pointers, so we won't use it for + now on that platform. It may be reconsidered for a future release + if it can be made more effective. + Likely reason: __fastcall on Windows is like stdcall, therefore + the compiler cannot perform stack optimizations for call clusters. +*/ + +/* Make sure all of these are defined if they aren't already. */ + +#ifndef FASTCALL +# define FASTCALL +#endif + +#ifndef PTRCALL +# define PTRCALL +#endif + +#ifndef PTRFASTCALL +# define PTRFASTCALL +#endif + +#ifndef XML_MIN_SIZE +# if ! defined(__cplusplus) && ! defined(inline) +# ifdef __GNUC__ +# define inline __inline +# endif /* __GNUC__ */ +# endif +#endif /* XML_MIN_SIZE */ + +#ifdef __cplusplus +# define inline inline +#else +# ifndef inline +# define inline +# endif +#endif + +#include // ULONG_MAX + +#if defined(_WIN32) \ + && (! defined(__USE_MINGW_ANSI_STDIO) \ + || (1 - __USE_MINGW_ANSI_STDIO - 1 == 0)) +# define EXPAT_FMT_ULL(midpart) "%" midpart "I64u" +# if defined(_WIN64) // Note: modifiers "td" and "zu" do not work for MinGW +# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "I64d" +# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "I64u" +# else +# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d" +# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u" +# endif +#else +# define EXPAT_FMT_ULL(midpart) "%" midpart "llu" +# if ! defined(ULONG_MAX) +# error Compiler did not define ULONG_MAX for us +# elif ULONG_MAX == 18446744073709551615u // 2^64-1 +# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "ld" +# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "lu" +# else +# define EXPAT_FMT_PTRDIFF_T(midpart) "%" midpart "d" +# define EXPAT_FMT_SIZE_T(midpart) "%" midpart "u" +# endif +#endif + +#ifndef UNUSED_P +# define UNUSED_P(p) (void)p +#endif + +/* NOTE BEGIN If you ever patch these defaults to greater values + for non-attack XML payload in your environment, + please file a bug report with libexpat. Thank you! +*/ +#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT \ + 100.0f +#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT \ + 8388608 // 8 MiB, 2^23 +/* NOTE END */ + +#include "expat.h" // so we can use type XML_Parser below + +#ifdef __cplusplus +extern "C" { +#endif + +void _INTERNAL_trim_to_complete_utf8_characters(const char *from, + const char **fromLimRef); + +#if defined(XML_GE) && XML_GE == 1 +unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser); +unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser); +const char *unsignedCharToPrintable(unsigned char c); +#endif + +extern +#if ! defined(XML_TESTING) + const +#endif + XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c +#if defined(XML_TESTING) +extern unsigned int g_bytesScanned; // used for testing only +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/latin1tab.h b/lib/libesp32_lvgl/lvgl/src/libs/expat/latin1tab.h new file mode 100644 index 000000000..c3a9d5ad8 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/latin1tab.h @@ -0,0 +1,72 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2002 Fred L. Drake, Jr. + Copyright (c) 2017 Sebastian Pipping + Licensed under the MIT license: + + 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_XML + +/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, + /* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME, + /* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, + /* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, + /* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, + /* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, + /* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + /* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/nametab.h b/lib/libesp32_lvgl/lvgl/src/libs/expat/nametab.h new file mode 100644 index 000000000..f698c3c54 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/nametab.h @@ -0,0 +1,142 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 2000 Clark Cooper + Copyright (c) 2017 Sebastian Pipping + Licensed under the MIT license: + + 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_XML + +static const unsigned namingBitmap[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x04000000, + 0x87FFFFFE, 0x07FFFFFE, 0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF, + 0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFE00F, 0xFC31FFFF, 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, + 0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, + 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, 0xFFFF0003, 0xFFFFFFFF, + 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, + 0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF, 0x00000000, 0x07FFFFFE, + 0x000007FE, 0xFFFE0000, 0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060, + 0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003, 0xFFF99FE0, 0x03C5FDFF, + 0xB0000000, 0x00030003, 0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000, + 0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001, 0xFFF99FE0, 0x23CDFDFF, + 0xB0000000, 0x00000003, 0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000, + 0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003, 0xFFFDDFE0, 0x03EFFDFF, + 0x40000000, 0x00000003, 0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x000D7FFF, + 0x0000003F, 0x00000000, 0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000, + 0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF, 0x0007DAED, 0x50000000, + 0x82315001, 0x002C62AB, 0x40000000, 0xF580C900, 0x00000007, 0x02010800, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0FFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0x03FFFFFF, 0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF, + 0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, 0x00000000, 0x00004C40, + 0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x00000000, 0x00000000, + 0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF, 0x001FFFFF, 0xFFFFFFFE, + 0xFFFFFFFF, 0x07FFFFFF, 0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F, + 0x00000000, 0x00000000, 0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE, + 0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF, 0x00FFFFFF, 0x00000000, + 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003, 0xFFFFD7C0, 0xFFFFFFFB, + 0x547F7FFF, 0x000FFFFD, 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, + 0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, + 0x027FFFFF, 0xFFFFFFFE, 0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF, + 0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF, 0xFFFFFFFF, 0x7CFFFFFF, + 0xFFEF7FFF, 0x03FF3DFF, 0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF, + 0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF, 0xFFF987E4, 0xD36DFDFF, + 0x5E003987, 0x001FFFC0, 0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1, + 0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3, 0xD63DC7EC, 0xC3BFC718, + 0x00803DC7, 0x0000FF80, 0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3, + 0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3, 0xFFFDDFEC, 0xC3FFFDFF, + 0x00803DCF, 0x0000FFC3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000, 0xFEF02596, 0x3BFF6CAE, + 0x03FF3F5F, 0x00000000, 0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF, + 0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1FFF0000, 0x00000002, + 0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF, 0x661FFFFF, 0xFFFFFFFE, + 0xFFFFFFFF, 0x77FFFFFF, +}; +static const unsigned char nmstrtPages[] = { + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; +static const unsigned char namePages[] = { + 0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, 0x00, 0x1F, 0x20, 0x21, + 0x22, 0x23, 0x24, 0x25, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x26, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/siphash.h b/lib/libesp32_lvgl/lvgl/src/libs/expat/siphash.h new file mode 100644 index 000000000..a4b2f0dfb --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/siphash.h @@ -0,0 +1,398 @@ +/* ========================================================================== + * siphash.h - SipHash-2-4 in a single header file + * -------------------------------------------------------------------------- + * Derived by William Ahern from the reference implementation[1] published[2] + * by Jean-Philippe Aumasson and Daniel J. Berstein. + * Minimal changes by Sebastian Pipping and Victor Stinner on top, see below. + * Licensed under the CC0 Public Domain Dedication license. + * + * 1. https://www.131002.net/siphash/siphash24.c + * 2. https://www.131002.net/siphash/ + * -------------------------------------------------------------------------- + * HISTORY: + * + * 2020-10-03 (Sebastian Pipping) + * - Drop support for Visual Studio 9.0/2008 and earlier + * + * 2019-08-03 (Sebastian Pipping) + * - Mark part of sip24_valid as to be excluded from clang-format + * - Re-format code using clang-format 9 + * + * 2018-07-08 (Anton Maklakov) + * - Add "fall through" markers for GCC's -Wimplicit-fallthrough + * + * 2017-11-03 (Sebastian Pipping) + * - Hide sip_tobin and sip_binof unless SIPHASH_TOBIN macro is defined + * + * 2017-07-25 (Vadim Zeitlin) + * - Fix use of SIPHASH_MAIN macro + * + * 2017-07-05 (Sebastian Pipping) + * - Use _SIP_ULL macro to not require a C++11 compiler if compiled as C++ + * - Add const qualifiers at two places + * - Ensure <=80 characters line length (assuming tab width 4) + * + * 2017-06-23 (Victor Stinner) + * - Address Win64 compile warnings + * + * 2017-06-18 (Sebastian Pipping) + * - Clarify license note in the header + * - Address C89 issues: + * - Stop using inline keyword (and let compiler decide) + * - Replace _Bool by int + * - Turn macro siphash24 into a function + * - Address invalid conversion (void pointer) by explicit cast + * - Address lack of stdint.h for Visual Studio 2003 to 2008 + * - Always expose sip24_valid (for self-tests) + * + * 2012-11-04 - Born. (William Ahern) + * -------------------------------------------------------------------------- + * USAGE: + * + * SipHash-2-4 takes as input two 64-bit words as the key, some number of + * message bytes, and outputs a 64-bit word as the message digest. This + * implementation employs two data structures: a struct sipkey for + * representing the key, and a struct siphash for representing the hash + * state. + * + * For converting a 16-byte unsigned char array to a key, use either the + * macro sip_keyof or the routine sip_tokey. The former instantiates a + * compound literal key, while the latter requires a key object as a + * parameter. + * + * unsigned char secret[16]; + * arc4random_buf(secret, sizeof secret); + * struct sipkey *key = sip_keyof(secret); + * + * For hashing a message, use either the convenience macro siphash24 or the + * routines sip24_init, sip24_update, and sip24_final. + * + * struct siphash state; + * void *msg; + * size_t len; + * uint64_t hash; + * + * sip24_init(&state, key); + * sip24_update(&state, msg, len); + * hash = sip24_final(&state); + * + * or + * + * hash = siphash24(msg, len, key); + * + * To convert the 64-bit hash value to a canonical 8-byte little-endian + * binary representation, use either the macro sip_binof or the routine + * sip_tobin. The former instantiates and returns a compound literal array, + * while the latter requires an array object as a parameter. + * -------------------------------------------------------------------------- + * NOTES: + * + * o Neither sip_keyof, sip_binof, nor siphash24 will work with compilers + * lacking compound literal support. Instead, you must use the lower-level + * interfaces which take as parameters the temporary state objects. + * + * o Uppercase macros may evaluate parameters more than once. Lowercase + * macros should not exhibit any such side effects. + * ========================================================================== + */ + +#include "../../lv_conf_internal.h" +#if LV_USE_XML +#ifndef SIPHASH_H +#define SIPHASH_H + +#include /* size_t */ +#include /* uint64_t uint32_t uint8_t */ + +/* + * Workaround to not require a C++11 compiler for using ULL suffix + * if this code is included and compiled as C++; related GCC warning is: + * warning: use of C++11 long long integer constant [-Wlong-long] + */ +#define SIP_ULL(high, low) ((((uint64_t)high) << 32) | (low)) + +#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) + +#define SIP_U32TO8_LE(p, v) \ + (p)[0] = (uint8_t)((v) >> 0); \ + (p)[1] = (uint8_t)((v) >> 8); \ + (p)[2] = (uint8_t)((v) >> 16); \ + (p)[3] = (uint8_t)((v) >> 24); + +#define SIP_U64TO8_LE(p, v) \ + SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >> 0)); \ + SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); + +#define SIP_U8TO64_LE(p) \ + (((uint64_t)((p)[0]) << 0) | ((uint64_t)((p)[1]) << 8) \ + | ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) \ + | ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) \ + | ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56)) + +#define SIPHASH_INITIALIZER {0, 0, 0, 0, {0}, 0, 0} + +struct siphash { + uint64_t v0, v1, v2, v3; + + unsigned char buf[8], *p; + uint64_t c; +}; /* struct siphash */ + +#define SIP_KEYLEN 16 + +struct sipkey { + uint64_t k[2]; +}; /* struct sipkey */ + +#define sip_keyof(k) sip_tokey(&(struct sipkey){{0}}, (k)) + +static struct sipkey * +sip_tokey(struct sipkey *key, const void *src) { + key->k[0] = SIP_U8TO64_LE((const unsigned char *)src); + key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8); + return key; +} /* sip_tokey() */ + +#ifdef SIPHASH_TOBIN + +# define sip_binof(v) sip_tobin((unsigned char[8]){0}, (v)) + +static void * +sip_tobin(void *dst, uint64_t u64) { + SIP_U64TO8_LE((unsigned char *)dst, u64); + return dst; +} /* sip_tobin() */ + +#endif /* SIPHASH_TOBIN */ + +static void +sip_round(struct siphash *H, const int rounds) { + int i; + + for (i = 0; i < rounds; i++) { + H->v0 += H->v1; + H->v1 = SIP_ROTL(H->v1, 13); + H->v1 ^= H->v0; + H->v0 = SIP_ROTL(H->v0, 32); + + H->v2 += H->v3; + H->v3 = SIP_ROTL(H->v3, 16); + H->v3 ^= H->v2; + + H->v0 += H->v3; + H->v3 = SIP_ROTL(H->v3, 21); + H->v3 ^= H->v0; + + H->v2 += H->v1; + H->v1 = SIP_ROTL(H->v1, 17); + H->v1 ^= H->v2; + H->v2 = SIP_ROTL(H->v2, 32); + } +} /* sip_round() */ + +static struct siphash * +sip24_init(struct siphash *H, const struct sipkey *key) { + H->v0 = SIP_ULL(0x736f6d65U, 0x70736575U) ^ key->k[0]; + H->v1 = SIP_ULL(0x646f7261U, 0x6e646f6dU) ^ key->k[1]; + H->v2 = SIP_ULL(0x6c796765U, 0x6e657261U) ^ key->k[0]; + H->v3 = SIP_ULL(0x74656462U, 0x79746573U) ^ key->k[1]; + + H->p = H->buf; + H->c = 0; + + return H; +} /* sip24_init() */ + +#define sip_endof(a) (&(a)[sizeof(a) / sizeof *(a)]) + +static struct siphash * +sip24_update(struct siphash *H, const void *src, size_t len) { + const unsigned char *p = (const unsigned char *)src, *pe = p + len; + uint64_t m; + + do { + while (p < pe && H->p < sip_endof(H->buf)) + *H->p++ = *p++; + + if (H->p < sip_endof(H->buf)) + break; + + m = SIP_U8TO64_LE(H->buf); + H->v3 ^= m; + sip_round(H, 2); + H->v0 ^= m; + + H->p = H->buf; + H->c += 8; + } while (p < pe); + + return H; +} /* sip24_update() */ + +static uint64_t +sip24_final(struct siphash *H) { + const char left = (char)(H->p - H->buf); + uint64_t b = (H->c + left) << 56; + + switch (left) { + case 7: + b |= (uint64_t)H->buf[6] << 48; + /* fall through */ + case 6: + b |= (uint64_t)H->buf[5] << 40; + /* fall through */ + case 5: + b |= (uint64_t)H->buf[4] << 32; + /* fall through */ + case 4: + b |= (uint64_t)H->buf[3] << 24; + /* fall through */ + case 3: + b |= (uint64_t)H->buf[2] << 16; + /* fall through */ + case 2: + b |= (uint64_t)H->buf[1] << 8; + /* fall through */ + case 1: + b |= (uint64_t)H->buf[0] << 0; + /* fall through */ + case 0: + break; + } + + H->v3 ^= b; + sip_round(H, 2); + H->v0 ^= b; + H->v2 ^= 0xff; + sip_round(H, 4); + + return H->v0 ^ H->v1 ^ H->v2 ^ H->v3; +} /* sip24_final() */ + +static uint64_t +siphash24(const void *src, size_t len, const struct sipkey *key) { + struct siphash state = SIPHASH_INITIALIZER; + return sip24_final(sip24_update(sip24_init(&state, key), src, len)); +} /* siphash24() */ + +/* + * SipHash-2-4 output with + * k = 00 01 02 ... + * and + * in = (empty string) + * in = 00 (1 byte) + * in = 00 01 (2 bytes) + * in = 00 01 02 (3 bytes) + * ... + * in = 00 01 02 ... 3e (63 bytes) + */ +static int +sip24_valid(void) { + /* clang-format off */ + static const unsigned char vectors[64][8] = { + { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, }, + { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, }, + { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, }, + { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, }, + { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, }, + { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, }, + { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, }, + { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, }, + { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, }, + { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, }, + { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, }, + { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, }, + { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, }, + { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, }, + { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, }, + { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, }, + { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, }, + { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, }, + { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, }, + { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, }, + { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, }, + { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, }, + { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, }, + { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, }, + { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, }, + { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, }, + { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, }, + { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, }, + { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, }, + { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, }, + { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, }, + { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, }, + { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, }, + { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, }, + { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, }, + { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, }, + { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, }, + { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, }, + { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, }, + { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, }, + { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, }, + { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, }, + { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, }, + { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, }, + { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, }, + { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, }, + { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, }, + { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, }, + { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, }, + { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, }, + { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, }, + { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, }, + { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, }, + { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, }, + { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, }, + { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, }, + { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, }, + { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, }, + { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, }, + { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, }, + { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, }, + { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, }, + { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, }, + { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, } + }; + /* clang-format on */ + + unsigned char in[64]; + struct sipkey k; + size_t i; + + sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011" + "\012\013\014\015\016\017"); + + for (i = 0; i < sizeof in; ++i) { + in[i] = (unsigned char)i; + + if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i])) + return 0; + } + + return 1; +} /* sip24_valid() */ + +#ifdef SIPHASH_MAIN + +# include + +int +main(void) { + const int ok = sip24_valid(); + + if (ok) + puts("OK"); + else + puts("FAIL"); + + return ! ok; +} /* main() */ + +#endif /* SIPHASH_MAIN */ + +#endif /* SIPHASH_H */ + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/utf8tab.h b/lib/libesp32_lvgl/lvgl/src/libs/expat/utf8tab.h new file mode 100644 index 000000000..c2548ef8c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/utf8tab.h @@ -0,0 +1,72 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2002 Fred L. Drake, Jr. + Copyright (c) 2017 Sebastian Pipping + Licensed under the MIT license: + + 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_XML + +/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, + /* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, + /* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, + /* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, + /* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, + /* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, + /* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4, + /* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, + /* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM, + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/winconfig.h b/lib/libesp32_lvgl/lvgl/src/libs/expat/winconfig.h new file mode 100644 index 000000000..e45414cc4 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/winconfig.h @@ -0,0 +1,54 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 2000 Clark Cooper + Copyright (c) 2002 Greg Stein + Copyright (c) 2005 Karl Waclawek + Copyright (c) 2017-2023 Sebastian Pipping + Copyright (c) 2023 Orgad Shaneh + Licensed under the MIT license: + + 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_XML + +#ifndef WINCONFIG_H +#define WINCONFIG_H + +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include +#undef WIN32_LEAN_AND_MEAN + +#include +#include + +#endif /* ndef WINCONFIG_H */ + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/xmlparse.c b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmlparse.c new file mode 100644 index 000000000..bde8505b9 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmlparse.c @@ -0,0 +1,8565 @@ +/* ba4cdf9bdb534f355a9def4c9e25d20ee8e72f95b0a4d930be52e563f5080196 (2.6.3+) + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2000-2006 Fred L. Drake, Jr. + Copyright (c) 2001-2002 Greg Stein + Copyright (c) 2002-2016 Karl Waclawek + Copyright (c) 2005-2009 Steven Solie + Copyright (c) 2016 Eric Rahm + Copyright (c) 2016-2024 Sebastian Pipping + Copyright (c) 2016 Gaurav + Copyright (c) 2016 Thomas Beutlich + Copyright (c) 2016 Gustavo Grieco + Copyright (c) 2016 Pascal Cuoq + Copyright (c) 2016 Ed Schouten + Copyright (c) 2017-2022 Rhodri James + Copyright (c) 2017 Václav Slavík + Copyright (c) 2017 Viktor Szakats + Copyright (c) 2017 Chanho Park + Copyright (c) 2017 Rolf Eike Beer + Copyright (c) 2017 Hans Wennborg + Copyright (c) 2018 Anton Maklakov + Copyright (c) 2018 Benjamin Peterson + Copyright (c) 2018 Marco Maggi + Copyright (c) 2018 Mariusz Zaborski + Copyright (c) 2019 David Loffredo + Copyright (c) 2019-2020 Ben Wagner + Copyright (c) 2019 Vadim Zeitlin + Copyright (c) 2021 Donghee Na + Copyright (c) 2022 Samanta Navarro + Copyright (c) 2022 Jeffrey Walton + Copyright (c) 2022 Jann Horn + Copyright (c) 2022 Sean McBride + Copyright (c) 2023 Owain Davies + Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow + Copyright (c) 2024 Berkay Eren Ürün + Licensed under the MIT license: + + 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_XML + +#define XML_BUILDING_EXPAT 1 + +#include "expat_config.h" + +#if ! defined(XML_GE) || (1 - XML_GE - 1 == 2) || (XML_GE < 0) || (XML_GE > 1) +# error XML_GE (for general entities) must be defined, non-empty, either 1 or 0 (0 to disable, 1 to enable; 1 is a common default) +#endif + +#if defined(XML_DTD) && XML_GE == 0 +# error Either undefine XML_DTD or define XML_GE to 1. +#endif + +#if ! defined(XML_CONTEXT_BYTES) || (1 - XML_CONTEXT_BYTES - 1 == 2) \ + || (XML_CONTEXT_BYTES + 0 < 0) +# error XML_CONTEXT_BYTES must be defined, non-empty and >=0 (0 to disable, >=1 to enable; 1024 is a common default) +#endif + +#if defined(HAVE_SYSCALL_GETRANDOM) +# if ! defined(_GNU_SOURCE) +# define _GNU_SOURCE 1 /* syscall prototype */ +# endif +#endif + +#ifdef _WIN32 +/* force stdlib to define rand_s() */ +# if ! defined(_CRT_RAND_S) +# define _CRT_RAND_S +# endif +#endif + +#include +#include +#include /* memset(), memcpy() */ +#include +#include /* UINT_MAX */ +#include /* fprintf */ +#include /* getenv, rand_s */ +#include /* uintptr_t */ +#include /* isnan */ + +#ifdef _WIN32 +# define getpid GetCurrentProcessId +#elif defined(__linux__) +# include /* gettimeofday() */ +# include /* getpid() */ +# include /* getpid() */ +# include /* O_RDONLY */ +# include +#else +# define getpid() 0xAABBCCDD /* Fallback for MCUs */ +#endif + +#ifdef _WIN32 +# include "winconfig.h" +#endif + +#include "ascii.h" +#include "expat.h" +#include "siphash.h" + +#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) +# if defined(HAVE_GETRANDOM) +# include /* getrandom */ +# else +# include /* syscall */ +# include /* SYS_getrandom */ +# endif +# if ! defined(GRND_NONBLOCK) +# define GRND_NONBLOCK 0x0001 +# endif /* defined(GRND_NONBLOCK) */ +#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ + +#if defined(HAVE_LIBBSD) \ + && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM)) +# include +#endif + +#if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32) +# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 +#endif + +#if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM) \ + && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) \ + && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32) \ + && ! defined(XML_POOR_ENTROPY) +# error You do not have support for any sources of high quality entropy \ + enabled. For end user security, that is probably not what you want. \ + \ + Your options include: \ + * Linux >=3.17 + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \ + * Linux >=3.17 + glibc (including <2.25) (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \ + * BSD / macOS >=10.7 / glibc >=2.36 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \ + * BSD / macOS (including <10.7) / glibc >=2.36 (arc4random): HAVE_ARC4RANDOM, \ + * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \ + * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \ + * Linux (including <3.17) / BSD / macOS (including <10.7) / Solaris >=8 (/dev/urandom): XML_DEV_URANDOM, \ + * Windows >=Vista (rand_s): _WIN32. \ + \ + If insist on not using any of these, bypass this error by defining \ + XML_POOR_ENTROPY; you have been warned. \ + \ + If you have reasons to patch this detection code away or need changes \ + to the build system, please open a bug. Thank you! +#endif + +#ifdef XML_UNICODE +# define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX +# define XmlConvert XmlUtf16Convert +# define XmlGetInternalEncoding XmlGetUtf16InternalEncoding +# define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS +# define XmlEncode XmlUtf16Encode +# define MUST_CONVERT(enc, s) (! (enc)->isUtf16 || (((uintptr_t)(s)) & 1)) +typedef unsigned short ICHAR; +#else +# define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX +# define XmlConvert XmlUtf8Convert +# define XmlGetInternalEncoding XmlGetUtf8InternalEncoding +# define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS +# define XmlEncode XmlUtf8Encode +# define MUST_CONVERT(enc, s) (! (enc)->isUtf8) +typedef char ICHAR; +#endif + +#ifndef XML_NS + +# define XmlInitEncodingNS XmlInitEncoding +# define XmlInitUnknownEncodingNS XmlInitUnknownEncoding +# undef XmlGetInternalEncodingNS +# define XmlGetInternalEncodingNS XmlGetInternalEncoding +# define XmlParseXmlDeclNS XmlParseXmlDecl + +#endif + +#ifdef XML_UNICODE + +# ifdef XML_UNICODE_WCHAR_T +# define XML_T(x) (const wchar_t) x +# define XML_L(x) L##x +# else +# define XML_T(x) (const unsigned short)x +# define XML_L(x) x +# endif + +#else + +# define XML_T(x) x +# define XML_L(x) x + +#endif + +/* Round up n to be a multiple of sz, where sz is a power of 2. */ +#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) + +/* Do safe (NULL-aware) pointer arithmetic */ +#define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0) + +#define EXPAT_MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#include "internal.h" +#include "xmltok.h" +#include "xmlrole.h" + +typedef const XML_Char *KEY; + +typedef struct { + KEY name; +} NAMED; + +typedef struct { + NAMED **v; + unsigned char power; + size_t size; + size_t used; + const XML_Memory_Handling_Suite *mem; +} HASH_TABLE; + +static size_t keylen(KEY s); + +static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key); + +/* For probing (after a collision) we need a step size relative prime + to the hash table size, which is a power of 2. We use double-hashing, + since we can calculate a second hash value cheaply by taking those bits + of the first hash value that were discarded (masked out) when the table + index was calculated: index = hash & mask, where mask = table->size - 1. + We limit the maximum step size to table->size / 4 (mask >> 2) and make + it odd, since odd numbers are always relative prime to a power of 2. +*/ +#define SECOND_HASH(hash, mask, power) \ + ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2)) +#define PROBE_STEP(hash, mask, power) \ + ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1)) + +typedef struct { + NAMED **p; + NAMED **end; +} HASH_TABLE_ITER; + +#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ +#define INIT_DATA_BUF_SIZE 1024 +#define INIT_ATTS_SIZE 16 +#define INIT_ATTS_VERSION 0xFFFFFFFF +#define INIT_BLOCK_SIZE 1024 +#define INIT_BUFFER_SIZE 1024 + +#define EXPAND_SPARE 24 + +typedef struct binding { + struct prefix *prefix; + struct binding *nextTagBinding; + struct binding *prevPrefixBinding; + const struct attribute_id *attId; + XML_Char *uri; + int uriLen; + int uriAlloc; +} BINDING; + +typedef struct prefix { + const XML_Char *name; + BINDING *binding; +} PREFIX; + +typedef struct { + const XML_Char *str; + const XML_Char *localPart; + const XML_Char *prefix; + int strLen; + int uriLen; + int prefixLen; +} TAG_NAME; + +/* TAG represents an open element. + The name of the element is stored in both the document and API + encodings. The memory buffer 'buf' is a separately-allocated + memory area which stores the name. During the XML_Parse()/ + XML_ParseBuffer() when the element is open, the memory for the 'raw' + version of the name (in the document encoding) is shared with the + document buffer. If the element is open across calls to + XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to + contain the 'raw' name as well. + + A parser reuses these structures, maintaining a list of allocated + TAG objects in a free list. +*/ +typedef struct tag { + struct tag *parent; /* parent of this element */ + const char *rawName; /* tagName in the original encoding */ + int rawNameLength; + TAG_NAME name; /* tagName in the API encoding */ + char *buf; /* buffer for name components */ + char *bufEnd; /* end of the buffer */ + BINDING *bindings; +} TAG; + +typedef struct { + const XML_Char *name; + const XML_Char *textPtr; + int textLen; /* length in XML_Chars */ + int processed; /* # of processed bytes - when suspended */ + const XML_Char *systemId; + const XML_Char *base; + const XML_Char *publicId; + const XML_Char *notation; + XML_Bool open; + XML_Bool is_param; + XML_Bool is_internal; /* true if declared in internal subset outside PE */ +} ENTITY; + +typedef struct { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + const XML_Char *name; + int firstchild; + int lastchild; + int childcnt; + int nextsib; +} CONTENT_SCAFFOLD; + +#define INIT_SCAFFOLD_ELEMENTS 32 + +typedef struct block { + struct block *next; + int size; + XML_Char s[1]; +} BLOCK; + +typedef struct { + BLOCK *blocks; + BLOCK *freeBlocks; + const XML_Char *end; + XML_Char *ptr; + XML_Char *start; + const XML_Memory_Handling_Suite *mem; +} STRING_POOL; + +/* The XML_Char before the name is used to determine whether + an attribute has been specified. */ +typedef struct attribute_id { + XML_Char *name; + PREFIX *prefix; + XML_Bool maybeTokenized; + XML_Bool xmlns; +} ATTRIBUTE_ID; + +typedef struct { + const ATTRIBUTE_ID *id; + XML_Bool isCdata; + const XML_Char *value; +} DEFAULT_ATTRIBUTE; + +typedef struct { + unsigned long version; + unsigned long hash; + const XML_Char *uriName; +} NS_ATT; + +typedef struct { + const XML_Char *name; + PREFIX *prefix; + const ATTRIBUTE_ID *idAtt; + int nDefaultAtts; + int allocDefaultAtts; + DEFAULT_ATTRIBUTE *defaultAtts; +} ELEMENT_TYPE; + +typedef struct { + HASH_TABLE generalEntities; + HASH_TABLE elementTypes; + HASH_TABLE attributeIds; + HASH_TABLE prefixes; + STRING_POOL pool; + STRING_POOL entityValuePool; + /* false once a parameter entity reference has been skipped */ + XML_Bool keepProcessing; + /* true once an internal or external PE reference has been encountered; + this includes the reference to an external subset */ + XML_Bool hasParamEntityRefs; + XML_Bool standalone; +#ifdef XML_DTD + /* indicates if external PE has been read */ + XML_Bool paramEntityRead; + HASH_TABLE paramEntities; +#endif /* XML_DTD */ + PREFIX defaultPrefix; + /* === scaffolding for building content model === */ + XML_Bool in_eldecl; + CONTENT_SCAFFOLD *scaffold; + unsigned contentStringLen; + unsigned scaffSize; + unsigned scaffCount; + int scaffLevel; + int *scaffIndex; +} DTD; + +typedef struct open_internal_entity { + const char *internalEventPtr; + const char *internalEventEndPtr; + struct open_internal_entity *next; + ENTITY *entity; + int startTagLevel; + XML_Bool betweenDecl; /* WFC: PE Between Declarations */ +} OPEN_INTERNAL_ENTITY; + +enum XML_Account { + XML_ACCOUNT_DIRECT, /* bytes directly passed to the Expat parser */ + XML_ACCOUNT_ENTITY_EXPANSION, /* intermediate bytes produced during entity + expansion */ + XML_ACCOUNT_NONE /* i.e. do not account, was accounted already */ +}; + +#if XML_GE == 1 +typedef unsigned long long XmlBigCount; +typedef struct accounting { + XmlBigCount countBytesDirect; + XmlBigCount countBytesIndirect; + unsigned long debugLevel; + float maximumAmplificationFactor; // >=1.0 + unsigned long long activationThresholdBytes; +} ACCOUNTING; + +typedef struct entity_stats { + unsigned int countEverOpened; + unsigned int currentDepth; + unsigned int maximumDepthSeen; + unsigned long debugLevel; +} ENTITY_STATS; +#endif /* XML_GE == 1 */ + +typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start, + const char *end, const char **endPtr); + +static Processor prologProcessor; +static Processor prologInitProcessor; +static Processor contentProcessor; +static Processor cdataSectionProcessor; +#ifdef XML_DTD +static Processor ignoreSectionProcessor; +static Processor externalParEntProcessor; +static Processor externalParEntInitProcessor; +static Processor entityValueProcessor; +static Processor entityValueInitProcessor; +#endif /* XML_DTD */ +static Processor epilogProcessor; +static Processor errorProcessor; +static Processor externalEntityInitProcessor; +static Processor externalEntityInitProcessor2; +static Processor externalEntityInitProcessor3; +static Processor externalEntityContentProcessor; +static Processor internalEntityProcessor; + +static enum XML_Error handleUnknownEncoding(XML_Parser parser, + const XML_Char *encodingName); +static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity, + const char *s, const char *next); +static enum XML_Error initializeEncoding(XML_Parser parser); +static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc, + const char *s, const char *end, int tok, + const char *next, const char **nextPtr, + XML_Bool haveMore, XML_Bool allowClosingDoctype, + enum XML_Account account); +static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity, + XML_Bool betweenDecl); +static enum XML_Error doContent(XML_Parser parser, int startTagLevel, + const ENCODING *enc, const char *start, + const char *end, const char **endPtr, + XML_Bool haveMore, enum XML_Account account); +static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *enc, + const char **startPtr, const char *end, + const char **nextPtr, XML_Bool haveMore, + enum XML_Account account); +#ifdef XML_DTD +static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *enc, + const char **startPtr, const char *end, + const char **nextPtr, XML_Bool haveMore); +#endif /* XML_DTD */ + +static void freeBindings(XML_Parser parser, BINDING *bindings); +static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, + const char *attStr, TAG_NAME *tagNamePtr, + BINDING **bindingsPtr, + enum XML_Account account); +static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, + const ATTRIBUTE_ID *attId, const XML_Char *uri, + BINDING **bindingsPtr); +static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, + XML_Bool isCdata, XML_Bool isId, + const XML_Char *value, XML_Parser parser); +static enum XML_Error storeAttributeValue(XML_Parser parser, + const ENCODING *enc, XML_Bool isCdata, + const char *ptr, const char *end, + STRING_POOL *pool, + enum XML_Account account); +static enum XML_Error appendAttributeValue(XML_Parser parser, + const ENCODING *enc, + XML_Bool isCdata, const char *ptr, + const char *end, STRING_POOL *pool, + enum XML_Account account); +static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc, + const char *start, const char *end); +static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType); +#if XML_GE == 1 +static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc, + const char *start, const char *end, + enum XML_Account account); +#else +static enum XML_Error storeSelfEntityValue(XML_Parser parser, ENTITY *entity); +#endif +static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, + const char *start, const char *end); +static int reportComment(XML_Parser parser, const ENCODING *enc, + const char *start, const char *end); +static void reportDefault(XML_Parser parser, const ENCODING *enc, + const char *start, const char *end); + +static const XML_Char *getContext(XML_Parser parser); +static XML_Bool setContext(XML_Parser parser, const XML_Char *context); + +static void FASTCALL normalizePublicId(XML_Char *s); + +static DTD *dtdCreate(const XML_Memory_Handling_Suite *ms); +/* do not call if m_parentParser != NULL */ +static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms); +static void dtdDestroy(DTD *p, XML_Bool isDocEntity, + const XML_Memory_Handling_Suite *ms); +static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, + const XML_Memory_Handling_Suite *ms); +static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable, + STRING_POOL *newPool, const HASH_TABLE *oldTable); +static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name, + size_t createSize); +static void FASTCALL hashTableInit(HASH_TABLE *table, + const XML_Memory_Handling_Suite *ms); +static void FASTCALL hashTableClear(HASH_TABLE *table); +static void FASTCALL hashTableDestroy(HASH_TABLE *table); +static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *iter, + const HASH_TABLE *table); +static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *iter); + +static void FASTCALL poolInit(STRING_POOL *pool, + const XML_Memory_Handling_Suite *ms); +static void FASTCALL poolClear(STRING_POOL *pool); +static void FASTCALL poolDestroy(STRING_POOL *pool); +static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc, + const char *ptr, const char *end); +static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, + const char *ptr, const char *end); +static XML_Bool FASTCALL poolGrow(STRING_POOL *pool); +static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool, + const XML_Char *s); +static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, + int n); +static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool, + const XML_Char *s); + +static int FASTCALL nextScaffoldPart(XML_Parser parser); +static XML_Content *build_model(XML_Parser parser); +static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc, + const char *ptr, const char *end); + +static XML_Char *copyString(const XML_Char *s, + const XML_Memory_Handling_Suite *memsuite); + +static unsigned long generate_hash_secret_salt(XML_Parser parser); +static XML_Bool startParsing(XML_Parser parser); + +static XML_Parser parserCreate(const XML_Char *encodingName, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *nameSep, DTD *dtd); + +static void parserInit(XML_Parser parser, const XML_Char *encodingName); + +#if XML_GE == 1 +static float accountingGetCurrentAmplification(XML_Parser rootParser); +static void accountingReportStats(XML_Parser originParser, const char *epilog); +static void accountingOnAbort(XML_Parser originParser); +static void accountingReportDiff(XML_Parser rootParser, + unsigned int levelsAwayFromRootParser, + const char *before, const char *after, + ptrdiff_t bytesMore, int source_line, + enum XML_Account account); +static XML_Bool accountingDiffTolerated(XML_Parser originParser, int tok, + const char *before, const char *after, + int source_line, + enum XML_Account account); + +static void entityTrackingReportStats(XML_Parser parser, ENTITY *entity, + const char *action, int sourceLine); +static void entityTrackingOnOpen(XML_Parser parser, ENTITY *entity, + int sourceLine); +static void entityTrackingOnClose(XML_Parser parser, ENTITY *entity, + int sourceLine); + +static XML_Parser getRootParserOf(XML_Parser parser, + unsigned int *outLevelDiff); +#endif /* XML_GE == 1 */ + +static unsigned long getDebugLevel(const char *variableName, + unsigned long defaultDebugLevel); + +#define poolStart(pool) ((pool)->start) +#define poolLength(pool) ((pool)->ptr - (pool)->start) +#define poolChop(pool) ((void)--(pool->ptr)) +#define poolLastChar(pool) (((pool)->ptr)[-1]) +#define poolDiscard(pool) ((pool)->ptr = (pool)->start) +#define poolFinish(pool) ((pool)->start = (pool)->ptr) +#define poolAppendChar(pool, c) \ + (((pool)->ptr == (pool)->end && ! poolGrow(pool)) \ + ? 0 \ + : ((*((pool)->ptr)++ = c), 1)) + +#if ! defined(XML_TESTING) +const +#endif + XML_Bool g_reparseDeferralEnabledDefault + = XML_TRUE; // write ONLY in runtests.c +#if defined(XML_TESTING) +unsigned int g_bytesScanned = 0; // used for testing only +#endif + +struct XML_ParserStruct { + /* The first member must be m_userData so that the XML_GetUserData + macro works. */ + void *m_userData; + void *m_handlerArg; + + // How the four parse buffer pointers below relate in time and space: + // + // m_buffer <= m_bufferPtr <= m_bufferEnd <= m_bufferLim + // | | | | + // <--parsed-->| | | + // <---parsing--->| | + // <--unoccupied-->| + // <---------total-malloced/realloced-------->| + + char *m_buffer; // malloc/realloc base pointer of parse buffer + const XML_Memory_Handling_Suite m_mem; + const char *m_bufferPtr; // first character to be parsed + char *m_bufferEnd; // past last character to be parsed + const char *m_bufferLim; // allocated end of m_buffer + + XML_Index m_parseEndByteIndex; + const char *m_parseEndPtr; + size_t m_partialTokenBytesBefore; /* used in heuristic to avoid O(n^2) */ + XML_Bool m_reparseDeferralEnabled; + int m_lastBufferRequestSize; + XML_Char *m_dataBuf; + XML_Char *m_dataBufEnd; + XML_StartElementHandler m_startElementHandler; + XML_EndElementHandler m_endElementHandler; + XML_CharacterDataHandler m_characterDataHandler; + XML_ProcessingInstructionHandler m_processingInstructionHandler; + XML_CommentHandler m_commentHandler; + XML_StartCdataSectionHandler m_startCdataSectionHandler; + XML_EndCdataSectionHandler m_endCdataSectionHandler; + XML_DefaultHandler m_defaultHandler; + XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler; + XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler; + XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; + XML_NotationDeclHandler m_notationDeclHandler; + XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; + XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; + XML_NotStandaloneHandler m_notStandaloneHandler; + XML_ExternalEntityRefHandler m_externalEntityRefHandler; + XML_Parser m_externalEntityRefHandlerArg; + XML_SkippedEntityHandler m_skippedEntityHandler; + XML_UnknownEncodingHandler m_unknownEncodingHandler; + XML_ElementDeclHandler m_elementDeclHandler; + XML_AttlistDeclHandler m_attlistDeclHandler; + XML_EntityDeclHandler m_entityDeclHandler; + XML_XmlDeclHandler m_xmlDeclHandler; + const ENCODING *m_encoding; + INIT_ENCODING m_initEncoding; + const ENCODING *m_internalEncoding; + const XML_Char *m_protocolEncodingName; + XML_Bool m_ns; + XML_Bool m_ns_triplets; + void *m_unknownEncodingMem; + void *m_unknownEncodingData; + void *m_unknownEncodingHandlerData; + void(XMLCALL *m_unknownEncodingRelease)(void *); + PROLOG_STATE m_prologState; + Processor *m_processor; + enum XML_Error m_errorCode; + const char *m_eventPtr; + const char *m_eventEndPtr; + const char *m_positionPtr; + OPEN_INTERNAL_ENTITY *m_openInternalEntities; + OPEN_INTERNAL_ENTITY *m_freeInternalEntities; + XML_Bool m_defaultExpandInternalEntities; + int m_tagLevel; + ENTITY *m_declEntity; + const XML_Char *m_doctypeName; + const XML_Char *m_doctypeSysid; + const XML_Char *m_doctypePubid; + const XML_Char *m_declAttributeType; + const XML_Char *m_declNotationName; + const XML_Char *m_declNotationPublicId; + ELEMENT_TYPE *m_declElementType; + ATTRIBUTE_ID *m_declAttributeId; + XML_Bool m_declAttributeIsCdata; + XML_Bool m_declAttributeIsId; + DTD *m_dtd; + const XML_Char *m_curBase; + TAG *m_tagStack; + TAG *m_freeTagList; + BINDING *m_inheritedBindings; + BINDING *m_freeBindingList; + int m_attsSize; + int m_nSpecifiedAtts; + int m_idAttIndex; + ATTRIBUTE *m_atts; + NS_ATT *m_nsAtts; + unsigned long m_nsAttsVersion; + unsigned char m_nsAttsPower; +#ifdef XML_ATTR_INFO + XML_AttrInfo *m_attInfo; +#endif + POSITION m_position; + STRING_POOL m_tempPool; + STRING_POOL m_temp2Pool; + char *m_groupConnector; + unsigned int m_groupSize; + XML_Char m_namespaceSeparator; + XML_Parser m_parentParser; + XML_ParsingStatus m_parsingStatus; +#ifdef XML_DTD + XML_Bool m_isParamEntity; + XML_Bool m_useForeignDTD; + enum XML_ParamEntityParsing m_paramEntityParsing; +#endif + unsigned long m_hash_secret_salt; +#if XML_GE == 1 + ACCOUNTING m_accounting; + ENTITY_STATS m_entity_stats; +#endif +}; + +#define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s))) +#define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s))) +#define FREE(parser, p) (parser->m_mem.free_fcn((p))) + +XML_Parser XMLCALL +XML_ParserCreate(const XML_Char *encodingName) { + return XML_ParserCreate_MM(encodingName, NULL, NULL); +} + +XML_Parser XMLCALL +XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { + XML_Char tmp[2] = {nsSep, 0}; + return XML_ParserCreate_MM(encodingName, NULL, tmp); +} + +// "xml=http://www.w3.org/XML/1998/namespace" +static const XML_Char implicitContext[] + = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, + ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, + ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, + ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, + ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, + ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, + ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e, + ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, + '\0'}; + +/* To avoid warnings about unused functions: */ +#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) + +# if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) + +/* Obtain entropy on Linux 3.17+ */ +static int +writeRandomBytes_getrandom_nonblock(void *target, size_t count) { + int success = 0; /* full count bytes written? */ + size_t bytesWrittenTotal = 0; + const unsigned int getrandomFlags = GRND_NONBLOCK; + + do { + void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); + const size_t bytesToWrite = count - bytesWrittenTotal; + + const int bytesWrittenMore = +# if defined(HAVE_GETRANDOM) + getrandom(currentTarget, bytesToWrite, getrandomFlags); +# else + syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags); +# endif + + if (bytesWrittenMore > 0) { + bytesWrittenTotal += bytesWrittenMore; + if (bytesWrittenTotal >= count) + success = 1; + } + } while (! success && (errno == EINTR)); + + return success; +} + +# endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ + +# if ! defined(_WIN32) && defined(XML_DEV_URANDOM) + +/* Extract entropy from /dev/urandom */ +static int +writeRandomBytes_dev_urandom(void *target, size_t count) { + int success = 0; /* full count bytes written? */ + size_t bytesWrittenTotal = 0; + + const int fd = open("/dev/urandom", O_RDONLY); + if (fd < 0) { + return 0; + } + + do { + void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); + const size_t bytesToWrite = count - bytesWrittenTotal; + + const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite); + + if (bytesWrittenMore > 0) { + bytesWrittenTotal += bytesWrittenMore; + if (bytesWrittenTotal >= count) + success = 1; + } + } while (! success && (errno == EINTR)); + + close(fd); + return success; +} + +# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ + +#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ + +#if defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) + +static void +writeRandomBytes_arc4random(void *target, size_t count) { + size_t bytesWrittenTotal = 0; + + while (bytesWrittenTotal < count) { + const uint32_t random32 = arc4random(); + size_t i = 0; + + for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); + i++, bytesWrittenTotal++) { + const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); + ((uint8_t *)target)[bytesWrittenTotal] = random8; + } + } +} + +#endif /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */ + +#ifdef _WIN32 + +/* Provide declaration of rand_s() for MinGW-32 (not 64, which has it), + as it didn't declare it in its header prior to version 5.3.0 of its + runtime package (mingwrt, containing stdlib.h). The upstream fix + was introduced at https://osdn.net/projects/mingw/ticket/39658 . */ +# if defined(__MINGW32__) && defined(__MINGW32_VERSION) \ + && __MINGW32_VERSION < 5003000L && ! defined(__MINGW64_VERSION_MAJOR) +__declspec(dllimport) int rand_s(unsigned int *); +# endif + +/* Obtain entropy on Windows using the rand_s() function which + * generates cryptographically secure random numbers. Internally it + * uses RtlGenRandom API which is present in Windows XP and later. + */ +static int +writeRandomBytes_rand_s(void *target, size_t count) { + size_t bytesWrittenTotal = 0; + + while (bytesWrittenTotal < count) { + unsigned int random32 = 0; + size_t i = 0; + + if (rand_s(&random32)) + return 0; /* failure */ + + for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); + i++, bytesWrittenTotal++) { + const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); + ((uint8_t *)target)[bytesWrittenTotal] = random8; + } + } + return 1; /* success */ +} + +#endif /* _WIN32 */ + +#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) + +static unsigned long +gather_time_entropy(void) { +# ifdef _WIN32 + FILETIME ft; + GetSystemTimeAsFileTime(&ft); /* never fails */ + return ft.dwHighDateTime ^ ft.dwLowDateTime; +# elif defined(__linux__) + struct timeval tv; + int gettimeofday_res; + + gettimeofday_res = gettimeofday(&tv, NULL); + +# if defined(NDEBUG) + (void)gettimeofday_res; +# else + assert(gettimeofday_res == 0); +# endif /* defined(NDEBUG) */ + /* Microseconds time is <20 bits entropy */ + return tv.tv_usec; +# else + return 0x12345678; /*Fallback for MCUs*/ +# endif +} + +#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ + +static unsigned long +ENTROPY_DEBUG(const char *label, unsigned long entropy) { + if (getDebugLevel("EXPAT_ENTROPY_DEBUG", 0) >= 1u) { + fprintf(stderr, "expat: Entropy: %s --> 0x%0*lx (%lu bytes)\n", label, + (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy)); + } + return entropy; +} + +static unsigned long +generate_hash_secret_salt(XML_Parser parser) { + unsigned long entropy; + (void)parser; + + /* "Failproof" high quality providers: */ +#if defined(HAVE_ARC4RANDOM_BUF) + arc4random_buf(&entropy, sizeof(entropy)); + return ENTROPY_DEBUG("arc4random_buf", entropy); +#elif defined(HAVE_ARC4RANDOM) + writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy)); + return ENTROPY_DEBUG("arc4random", entropy); +#else + /* Try high quality providers first .. */ +# ifdef _WIN32 + if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) { + return ENTROPY_DEBUG("rand_s", entropy); + } +# elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) + if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) { + return ENTROPY_DEBUG("getrandom", entropy); + } +# endif +# if ! defined(_WIN32) && defined(XML_DEV_URANDOM) + if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) { + return ENTROPY_DEBUG("/dev/urandom", entropy); + } +# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ + /* .. and self-made low quality for backup: */ + + /* Process ID is 0 bits entropy if attacker has local access */ + entropy = gather_time_entropy() ^ getpid(); + + /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */ + if (sizeof(unsigned long) == 4) { + return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647); + } else { + return ENTROPY_DEBUG("fallback(8)", + entropy * (unsigned long)2305843009213693951ULL); + } +#endif +} + +static unsigned long +get_hash_secret_salt(XML_Parser parser) { + if (parser->m_parentParser != NULL) + return get_hash_secret_salt(parser->m_parentParser); + return parser->m_hash_secret_salt; +} + +static enum XML_Error +callProcessor(XML_Parser parser, const char *start, const char *end, + const char **endPtr) { + const size_t have_now = EXPAT_SAFE_PTR_DIFF(end, start); + + if (parser->m_reparseDeferralEnabled + && ! parser->m_parsingStatus.finalBuffer) { + // Heuristic: don't try to parse a partial token again until the amount of + // available data has increased significantly. + const size_t had_before = parser->m_partialTokenBytesBefore; + // ...but *do* try anyway if we're close to causing a reallocation. + size_t available_buffer + = EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer); +#if XML_CONTEXT_BYTES > 0 + available_buffer -= EXPAT_MIN(available_buffer, XML_CONTEXT_BYTES); +#endif + available_buffer + += EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd); + // m_lastBufferRequestSize is never assigned a value < 0, so the cast is ok + const bool enough + = (have_now >= 2 * had_before) + || ((size_t)parser->m_lastBufferRequestSize > available_buffer); + + if (! enough) { + *endPtr = start; // callers may expect this to be set + return XML_ERROR_NONE; + } + } +#if defined(XML_TESTING) + g_bytesScanned += (unsigned)have_now; +#endif + const enum XML_Error ret = parser->m_processor(parser, start, end, endPtr); + if (ret == XML_ERROR_NONE) { + // if we consumed nothing, remember what we had on this parse attempt. + if (*endPtr == start) { + parser->m_partialTokenBytesBefore = have_now; + } else { + parser->m_partialTokenBytesBefore = 0; + } + } + return ret; +} + +static XML_Bool /* only valid for root parser */ +startParsing(XML_Parser parser) { + /* hash functions must be initialized before setContext() is called */ + if (parser->m_hash_secret_salt == 0) + parser->m_hash_secret_salt = generate_hash_secret_salt(parser); + if (parser->m_ns) { + /* implicit context only set for root parser, since child + parsers (i.e. external entity parsers) will inherit it + */ + return setContext(parser, implicitContext); + } + return XML_TRUE; +} + +XML_Parser XMLCALL +XML_ParserCreate_MM(const XML_Char *encodingName, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *nameSep) { + return parserCreate(encodingName, memsuite, nameSep, NULL); +} + +static XML_Parser +parserCreate(const XML_Char *encodingName, + const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep, + DTD *dtd) { + XML_Parser parser; + + if (memsuite) { + XML_Memory_Handling_Suite *mtemp; + parser = memsuite->malloc_fcn(sizeof(struct XML_ParserStruct)); + if (parser != NULL) { + mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); + mtemp->malloc_fcn = memsuite->malloc_fcn; + mtemp->realloc_fcn = memsuite->realloc_fcn; + mtemp->free_fcn = memsuite->free_fcn; + } + } else { + XML_Memory_Handling_Suite *mtemp; + parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct)); + if (parser != NULL) { + mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); + mtemp->malloc_fcn = malloc; + mtemp->realloc_fcn = realloc; + mtemp->free_fcn = free; + } + } + + if (! parser) + return parser; + + parser->m_buffer = NULL; + parser->m_bufferLim = NULL; + + parser->m_attsSize = INIT_ATTS_SIZE; + parser->m_atts + = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE)); + if (parser->m_atts == NULL) { + FREE(parser, parser); + return NULL; + } +#ifdef XML_ATTR_INFO + parser->m_attInfo = (XML_AttrInfo *)MALLOC( + parser, parser->m_attsSize * sizeof(XML_AttrInfo)); + if (parser->m_attInfo == NULL) { + FREE(parser, parser->m_atts); + FREE(parser, parser); + return NULL; + } +#endif + parser->m_dataBuf + = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char)); + if (parser->m_dataBuf == NULL) { + FREE(parser, parser->m_atts); +#ifdef XML_ATTR_INFO + FREE(parser, parser->m_attInfo); +#endif + FREE(parser, parser); + return NULL; + } + parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE; + + if (dtd) + parser->m_dtd = dtd; + else { + parser->m_dtd = dtdCreate(&parser->m_mem); + if (parser->m_dtd == NULL) { + FREE(parser, parser->m_dataBuf); + FREE(parser, parser->m_atts); +#ifdef XML_ATTR_INFO + FREE(parser, parser->m_attInfo); +#endif + FREE(parser, parser); + return NULL; + } + } + + parser->m_freeBindingList = NULL; + parser->m_freeTagList = NULL; + parser->m_freeInternalEntities = NULL; + + parser->m_groupSize = 0; + parser->m_groupConnector = NULL; + + parser->m_unknownEncodingHandler = NULL; + parser->m_unknownEncodingHandlerData = NULL; + + parser->m_namespaceSeparator = ASCII_EXCL; + parser->m_ns = XML_FALSE; + parser->m_ns_triplets = XML_FALSE; + + parser->m_nsAtts = NULL; + parser->m_nsAttsVersion = 0; + parser->m_nsAttsPower = 0; + + parser->m_protocolEncodingName = NULL; + + poolInit(&parser->m_tempPool, &(parser->m_mem)); + poolInit(&parser->m_temp2Pool, &(parser->m_mem)); + parserInit(parser, encodingName); + + if (encodingName && ! parser->m_protocolEncodingName) { + if (dtd) { + // We need to stop the upcoming call to XML_ParserFree from happily + // destroying parser->m_dtd because the DTD is shared with the parent + // parser and the only guard that keeps XML_ParserFree from destroying + // parser->m_dtd is parser->m_isParamEntity but it will be set to + // XML_TRUE only later in XML_ExternalEntityParserCreate (or not at all). + parser->m_dtd = NULL; + } + XML_ParserFree(parser); + return NULL; + } + + if (nameSep) { + parser->m_ns = XML_TRUE; + parser->m_internalEncoding = XmlGetInternalEncodingNS(); + parser->m_namespaceSeparator = *nameSep; + } else { + parser->m_internalEncoding = XmlGetInternalEncoding(); + } + + return parser; +} + +static void +parserInit(XML_Parser parser, const XML_Char *encodingName) { + parser->m_processor = prologInitProcessor; + XmlPrologStateInit(&parser->m_prologState); + if (encodingName != NULL) { + parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem)); + } + parser->m_curBase = NULL; + XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0); + parser->m_userData = NULL; + parser->m_handlerArg = NULL; + parser->m_startElementHandler = NULL; + parser->m_endElementHandler = NULL; + parser->m_characterDataHandler = NULL; + parser->m_processingInstructionHandler = NULL; + parser->m_commentHandler = NULL; + parser->m_startCdataSectionHandler = NULL; + parser->m_endCdataSectionHandler = NULL; + parser->m_defaultHandler = NULL; + parser->m_startDoctypeDeclHandler = NULL; + parser->m_endDoctypeDeclHandler = NULL; + parser->m_unparsedEntityDeclHandler = NULL; + parser->m_notationDeclHandler = NULL; + parser->m_startNamespaceDeclHandler = NULL; + parser->m_endNamespaceDeclHandler = NULL; + parser->m_notStandaloneHandler = NULL; + parser->m_externalEntityRefHandler = NULL; + parser->m_externalEntityRefHandlerArg = parser; + parser->m_skippedEntityHandler = NULL; + parser->m_elementDeclHandler = NULL; + parser->m_attlistDeclHandler = NULL; + parser->m_entityDeclHandler = NULL; + parser->m_xmlDeclHandler = NULL; + parser->m_bufferPtr = parser->m_buffer; + parser->m_bufferEnd = parser->m_buffer; + parser->m_parseEndByteIndex = 0; + parser->m_parseEndPtr = NULL; + parser->m_partialTokenBytesBefore = 0; + parser->m_reparseDeferralEnabled = g_reparseDeferralEnabledDefault; + parser->m_lastBufferRequestSize = 0; + parser->m_declElementType = NULL; + parser->m_declAttributeId = NULL; + parser->m_declEntity = NULL; + parser->m_doctypeName = NULL; + parser->m_doctypeSysid = NULL; + parser->m_doctypePubid = NULL; + parser->m_declAttributeType = NULL; + parser->m_declNotationName = NULL; + parser->m_declNotationPublicId = NULL; + parser->m_declAttributeIsCdata = XML_FALSE; + parser->m_declAttributeIsId = XML_FALSE; + memset(&parser->m_position, 0, sizeof(POSITION)); + parser->m_errorCode = XML_ERROR_NONE; + parser->m_eventPtr = NULL; + parser->m_eventEndPtr = NULL; + parser->m_positionPtr = NULL; + parser->m_openInternalEntities = NULL; + parser->m_defaultExpandInternalEntities = XML_TRUE; + parser->m_tagLevel = 0; + parser->m_tagStack = NULL; + parser->m_inheritedBindings = NULL; + parser->m_nSpecifiedAtts = 0; + parser->m_unknownEncodingMem = NULL; + parser->m_unknownEncodingRelease = NULL; + parser->m_unknownEncodingData = NULL; + parser->m_parentParser = NULL; + parser->m_parsingStatus.parsing = XML_INITIALIZED; +#ifdef XML_DTD + parser->m_isParamEntity = XML_FALSE; + parser->m_useForeignDTD = XML_FALSE; + parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; +#endif + parser->m_hash_secret_salt = 0; + +#if XML_GE == 1 + memset(&parser->m_accounting, 0, sizeof(ACCOUNTING)); + parser->m_accounting.debugLevel = getDebugLevel("EXPAT_ACCOUNTING_DEBUG", 0u); + parser->m_accounting.maximumAmplificationFactor + = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT; + parser->m_accounting.activationThresholdBytes + = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT; + + memset(&parser->m_entity_stats, 0, sizeof(ENTITY_STATS)); + parser->m_entity_stats.debugLevel = getDebugLevel("EXPAT_ENTITY_DEBUG", 0u); +#endif +} + +/* moves list of bindings to m_freeBindingList */ +static void FASTCALL +moveToFreeBindingList(XML_Parser parser, BINDING *bindings) { + while (bindings) { + BINDING *b = bindings; + bindings = bindings->nextTagBinding; + b->nextTagBinding = parser->m_freeBindingList; + parser->m_freeBindingList = b; + } +} + +XML_Bool XMLCALL +XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) { + TAG *tStk; + OPEN_INTERNAL_ENTITY *openEntityList; + + if (parser == NULL) + return XML_FALSE; + + if (parser->m_parentParser) + return XML_FALSE; + /* move m_tagStack to m_freeTagList */ + tStk = parser->m_tagStack; + while (tStk) { + TAG *tag = tStk; + tStk = tStk->parent; + tag->parent = parser->m_freeTagList; + moveToFreeBindingList(parser, tag->bindings); + tag->bindings = NULL; + parser->m_freeTagList = tag; + } + /* move m_openInternalEntities to m_freeInternalEntities */ + openEntityList = parser->m_openInternalEntities; + while (openEntityList) { + OPEN_INTERNAL_ENTITY *openEntity = openEntityList; + openEntityList = openEntity->next; + openEntity->next = parser->m_freeInternalEntities; + parser->m_freeInternalEntities = openEntity; + } + moveToFreeBindingList(parser, parser->m_inheritedBindings); + FREE(parser, parser->m_unknownEncodingMem); + if (parser->m_unknownEncodingRelease) + parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); + poolClear(&parser->m_tempPool); + poolClear(&parser->m_temp2Pool); + FREE(parser, (void *)parser->m_protocolEncodingName); + parser->m_protocolEncodingName = NULL; + parserInit(parser, encodingName); + dtdReset(parser->m_dtd, &parser->m_mem); + return XML_TRUE; +} + +enum XML_Status XMLCALL +XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) { + if (parser == NULL) + return XML_STATUS_ERROR; + /* Block after XML_Parse()/XML_ParseBuffer() has been called. + XXX There's no way for the caller to determine which of the + XXX possible error cases caused the XML_STATUS_ERROR return. + */ + if (parser->m_parsingStatus.parsing == XML_PARSING + || parser->m_parsingStatus.parsing == XML_SUSPENDED) + return XML_STATUS_ERROR; + + /* Get rid of any previous encoding name */ + FREE(parser, (void *)parser->m_protocolEncodingName); + + if (encodingName == NULL) + /* No new encoding name */ + parser->m_protocolEncodingName = NULL; + else { + /* Copy the new encoding name into allocated memory */ + parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem)); + if (! parser->m_protocolEncodingName) + return XML_STATUS_ERROR; + } + return XML_STATUS_OK; +} + +XML_Parser XMLCALL +XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, + const XML_Char *encodingName) { + XML_Parser parser = oldParser; + DTD *newDtd = NULL; + DTD *oldDtd; + XML_StartElementHandler oldStartElementHandler; + XML_EndElementHandler oldEndElementHandler; + XML_CharacterDataHandler oldCharacterDataHandler; + XML_ProcessingInstructionHandler oldProcessingInstructionHandler; + XML_CommentHandler oldCommentHandler; + XML_StartCdataSectionHandler oldStartCdataSectionHandler; + XML_EndCdataSectionHandler oldEndCdataSectionHandler; + XML_DefaultHandler oldDefaultHandler; + XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler; + XML_NotationDeclHandler oldNotationDeclHandler; + XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler; + XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler; + XML_NotStandaloneHandler oldNotStandaloneHandler; + XML_ExternalEntityRefHandler oldExternalEntityRefHandler; + XML_SkippedEntityHandler oldSkippedEntityHandler; + XML_UnknownEncodingHandler oldUnknownEncodingHandler; + XML_ElementDeclHandler oldElementDeclHandler; + XML_AttlistDeclHandler oldAttlistDeclHandler; + XML_EntityDeclHandler oldEntityDeclHandler; + XML_XmlDeclHandler oldXmlDeclHandler; + ELEMENT_TYPE *oldDeclElementType; + + void *oldUserData; + void *oldHandlerArg; + XML_Bool oldDefaultExpandInternalEntities; + XML_Parser oldExternalEntityRefHandlerArg; +#ifdef XML_DTD + enum XML_ParamEntityParsing oldParamEntityParsing; + int oldInEntityValue; +#endif + XML_Bool oldns_triplets; + /* Note that the new parser shares the same hash secret as the old + parser, so that dtdCopy and copyEntityTable can lookup values + from hash tables associated with either parser without us having + to worry which hash secrets each table has. + */ + unsigned long oldhash_secret_salt; + XML_Bool oldReparseDeferralEnabled; + + /* Validate the oldParser parameter before we pull everything out of it */ + if (oldParser == NULL) + return NULL; + + /* Stash the original parser contents on the stack */ + oldDtd = parser->m_dtd; + oldStartElementHandler = parser->m_startElementHandler; + oldEndElementHandler = parser->m_endElementHandler; + oldCharacterDataHandler = parser->m_characterDataHandler; + oldProcessingInstructionHandler = parser->m_processingInstructionHandler; + oldCommentHandler = parser->m_commentHandler; + oldStartCdataSectionHandler = parser->m_startCdataSectionHandler; + oldEndCdataSectionHandler = parser->m_endCdataSectionHandler; + oldDefaultHandler = parser->m_defaultHandler; + oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler; + oldNotationDeclHandler = parser->m_notationDeclHandler; + oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler; + oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler; + oldNotStandaloneHandler = parser->m_notStandaloneHandler; + oldExternalEntityRefHandler = parser->m_externalEntityRefHandler; + oldSkippedEntityHandler = parser->m_skippedEntityHandler; + oldUnknownEncodingHandler = parser->m_unknownEncodingHandler; + oldElementDeclHandler = parser->m_elementDeclHandler; + oldAttlistDeclHandler = parser->m_attlistDeclHandler; + oldEntityDeclHandler = parser->m_entityDeclHandler; + oldXmlDeclHandler = parser->m_xmlDeclHandler; + oldDeclElementType = parser->m_declElementType; + + oldUserData = parser->m_userData; + oldHandlerArg = parser->m_handlerArg; + oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities; + oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg; +#ifdef XML_DTD + oldParamEntityParsing = parser->m_paramEntityParsing; + oldInEntityValue = parser->m_prologState.inEntityValue; +#endif + oldns_triplets = parser->m_ns_triplets; + /* Note that the new parser shares the same hash secret as the old + parser, so that dtdCopy and copyEntityTable can lookup values + from hash tables associated with either parser without us having + to worry which hash secrets each table has. + */ + oldhash_secret_salt = parser->m_hash_secret_salt; + oldReparseDeferralEnabled = parser->m_reparseDeferralEnabled; + +#ifdef XML_DTD + if (! context) + newDtd = oldDtd; +#endif /* XML_DTD */ + + /* Note that the magical uses of the pre-processor to make field + access look more like C++ require that `parser' be overwritten + here. This makes this function more painful to follow than it + would be otherwise. + */ + if (parser->m_ns) { + XML_Char tmp[2] = {parser->m_namespaceSeparator, 0}; + parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd); + } else { + parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd); + } + + if (! parser) + return NULL; + + parser->m_startElementHandler = oldStartElementHandler; + parser->m_endElementHandler = oldEndElementHandler; + parser->m_characterDataHandler = oldCharacterDataHandler; + parser->m_processingInstructionHandler = oldProcessingInstructionHandler; + parser->m_commentHandler = oldCommentHandler; + parser->m_startCdataSectionHandler = oldStartCdataSectionHandler; + parser->m_endCdataSectionHandler = oldEndCdataSectionHandler; + parser->m_defaultHandler = oldDefaultHandler; + parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; + parser->m_notationDeclHandler = oldNotationDeclHandler; + parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler; + parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler; + parser->m_notStandaloneHandler = oldNotStandaloneHandler; + parser->m_externalEntityRefHandler = oldExternalEntityRefHandler; + parser->m_skippedEntityHandler = oldSkippedEntityHandler; + parser->m_unknownEncodingHandler = oldUnknownEncodingHandler; + parser->m_elementDeclHandler = oldElementDeclHandler; + parser->m_attlistDeclHandler = oldAttlistDeclHandler; + parser->m_entityDeclHandler = oldEntityDeclHandler; + parser->m_xmlDeclHandler = oldXmlDeclHandler; + parser->m_declElementType = oldDeclElementType; + parser->m_userData = oldUserData; + if (oldUserData == oldHandlerArg) + parser->m_handlerArg = parser->m_userData; + else + parser->m_handlerArg = parser; + if (oldExternalEntityRefHandlerArg != oldParser) + parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; + parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities; + parser->m_ns_triplets = oldns_triplets; + parser->m_hash_secret_salt = oldhash_secret_salt; + parser->m_reparseDeferralEnabled = oldReparseDeferralEnabled; + parser->m_parentParser = oldParser; +#ifdef XML_DTD + parser->m_paramEntityParsing = oldParamEntityParsing; + parser->m_prologState.inEntityValue = oldInEntityValue; + if (context) { +#endif /* XML_DTD */ + if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem) + || ! setContext(parser, context)) { + XML_ParserFree(parser); + return NULL; + } + parser->m_processor = externalEntityInitProcessor; +#ifdef XML_DTD + } else { + /* The DTD instance referenced by parser->m_dtd is shared between the + document's root parser and external PE parsers, therefore one does not + need to call setContext. In addition, one also *must* not call + setContext, because this would overwrite existing prefix->binding + pointers in parser->m_dtd with ones that get destroyed with the external + PE parser. This would leave those prefixes with dangling pointers. + */ + parser->m_isParamEntity = XML_TRUE; + XmlPrologStateInitExternalEntity(&parser->m_prologState); + parser->m_processor = externalParEntInitProcessor; + } +#endif /* XML_DTD */ + return parser; +} + +static void FASTCALL +destroyBindings(BINDING *bindings, XML_Parser parser) { + for (;;) { + BINDING *b = bindings; + if (! b) + break; + bindings = b->nextTagBinding; + FREE(parser, b->uri); + FREE(parser, b); + } +} + +void XMLCALL +XML_ParserFree(XML_Parser parser) { + TAG *tagList; + OPEN_INTERNAL_ENTITY *entityList; + if (parser == NULL) + return; + /* free m_tagStack and m_freeTagList */ + tagList = parser->m_tagStack; + for (;;) { + TAG *p; + if (tagList == NULL) { + if (parser->m_freeTagList == NULL) + break; + tagList = parser->m_freeTagList; + parser->m_freeTagList = NULL; + } + p = tagList; + tagList = tagList->parent; + FREE(parser, p->buf); + destroyBindings(p->bindings, parser); + FREE(parser, p); + } + /* free m_openInternalEntities and m_freeInternalEntities */ + entityList = parser->m_openInternalEntities; + for (;;) { + OPEN_INTERNAL_ENTITY *openEntity; + if (entityList == NULL) { + if (parser->m_freeInternalEntities == NULL) + break; + entityList = parser->m_freeInternalEntities; + parser->m_freeInternalEntities = NULL; + } + openEntity = entityList; + entityList = entityList->next; + FREE(parser, openEntity); + } + + destroyBindings(parser->m_freeBindingList, parser); + destroyBindings(parser->m_inheritedBindings, parser); + poolDestroy(&parser->m_tempPool); + poolDestroy(&parser->m_temp2Pool); + FREE(parser, (void *)parser->m_protocolEncodingName); +#ifdef XML_DTD + /* external parameter entity parsers share the DTD structure + parser->m_dtd with the root parser, so we must not destroy it + */ + if (! parser->m_isParamEntity && parser->m_dtd) +#else + if (parser->m_dtd) +#endif /* XML_DTD */ + dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser, + &parser->m_mem); + FREE(parser, (void *)parser->m_atts); +#ifdef XML_ATTR_INFO + FREE(parser, (void *)parser->m_attInfo); +#endif + FREE(parser, parser->m_groupConnector); + FREE(parser, parser->m_buffer); + FREE(parser, parser->m_dataBuf); + FREE(parser, parser->m_nsAtts); + FREE(parser, parser->m_unknownEncodingMem); + if (parser->m_unknownEncodingRelease) + parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); + FREE(parser, parser); +} + +void XMLCALL +XML_UseParserAsHandlerArg(XML_Parser parser) { + if (parser != NULL) + parser->m_handlerArg = parser; +} + +enum XML_Error XMLCALL +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) { + if (parser == NULL) + return XML_ERROR_INVALID_ARGUMENT; +#ifdef XML_DTD + /* block after XML_Parse()/XML_ParseBuffer() has been called */ + if (parser->m_parsingStatus.parsing == XML_PARSING + || parser->m_parsingStatus.parsing == XML_SUSPENDED) + return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; + parser->m_useForeignDTD = useDTD; + return XML_ERROR_NONE; +#else + UNUSED_P(useDTD); + return XML_ERROR_FEATURE_REQUIRES_XML_DTD; +#endif +} + +void XMLCALL +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) { + if (parser == NULL) + return; + /* block after XML_Parse()/XML_ParseBuffer() has been called */ + if (parser->m_parsingStatus.parsing == XML_PARSING + || parser->m_parsingStatus.parsing == XML_SUSPENDED) + return; + parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE; +} + +void XMLCALL +XML_SetUserData(XML_Parser parser, void *p) { + if (parser == NULL) + return; + if (parser->m_handlerArg == parser->m_userData) + parser->m_handlerArg = parser->m_userData = p; + else + parser->m_userData = p; +} + +enum XML_Status XMLCALL +XML_SetBase(XML_Parser parser, const XML_Char *p) { + if (parser == NULL) + return XML_STATUS_ERROR; + if (p) { + p = poolCopyString(&parser->m_dtd->pool, p); + if (! p) + return XML_STATUS_ERROR; + parser->m_curBase = p; + } else + parser->m_curBase = NULL; + return XML_STATUS_OK; +} + +const XML_Char *XMLCALL +XML_GetBase(XML_Parser parser) { + if (parser == NULL) + return NULL; + return parser->m_curBase; +} + +int XMLCALL +XML_GetSpecifiedAttributeCount(XML_Parser parser) { + if (parser == NULL) + return -1; + return parser->m_nSpecifiedAtts; +} + +int XMLCALL +XML_GetIdAttributeIndex(XML_Parser parser) { + if (parser == NULL) + return -1; + return parser->m_idAttIndex; +} + +#ifdef XML_ATTR_INFO +const XML_AttrInfo *XMLCALL +XML_GetAttributeInfo(XML_Parser parser) { + if (parser == NULL) + return NULL; + return parser->m_attInfo; +} +#endif + +void XMLCALL +XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, + XML_EndElementHandler end) { + if (parser == NULL) + return; + parser->m_startElementHandler = start; + parser->m_endElementHandler = end; +} + +void XMLCALL +XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) { + if (parser != NULL) + parser->m_startElementHandler = start; +} + +void XMLCALL +XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) { + if (parser != NULL) + parser->m_endElementHandler = end; +} + +void XMLCALL +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler) { + if (parser != NULL) + parser->m_characterDataHandler = handler; +} + +void XMLCALL +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler) { + if (parser != NULL) + parser->m_processingInstructionHandler = handler; +} + +void XMLCALL +XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) { + if (parser != NULL) + parser->m_commentHandler = handler; +} + +void XMLCALL +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end) { + if (parser == NULL) + return; + parser->m_startCdataSectionHandler = start; + parser->m_endCdataSectionHandler = end; +} + +void XMLCALL +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start) { + if (parser != NULL) + parser->m_startCdataSectionHandler = start; +} + +void XMLCALL +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end) { + if (parser != NULL) + parser->m_endCdataSectionHandler = end; +} + +void XMLCALL +XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) { + if (parser == NULL) + return; + parser->m_defaultHandler = handler; + parser->m_defaultExpandInternalEntities = XML_FALSE; +} + +void XMLCALL +XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) { + if (parser == NULL) + return; + parser->m_defaultHandler = handler; + parser->m_defaultExpandInternalEntities = XML_TRUE; +} + +void XMLCALL +XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end) { + if (parser == NULL) + return; + parser->m_startDoctypeDeclHandler = start; + parser->m_endDoctypeDeclHandler = end; +} + +void XMLCALL +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start) { + if (parser != NULL) + parser->m_startDoctypeDeclHandler = start; +} + +void XMLCALL +XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) { + if (parser != NULL) + parser->m_endDoctypeDeclHandler = end; +} + +void XMLCALL +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler) { + if (parser != NULL) + parser->m_unparsedEntityDeclHandler = handler; +} + +void XMLCALL +XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) { + if (parser != NULL) + parser->m_notationDeclHandler = handler; +} + +void XMLCALL +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end) { + if (parser == NULL) + return; + parser->m_startNamespaceDeclHandler = start; + parser->m_endNamespaceDeclHandler = end; +} + +void XMLCALL +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start) { + if (parser != NULL) + parser->m_startNamespaceDeclHandler = start; +} + +void XMLCALL +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end) { + if (parser != NULL) + parser->m_endNamespaceDeclHandler = end; +} + +void XMLCALL +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler) { + if (parser != NULL) + parser->m_notStandaloneHandler = handler; +} + +void XMLCALL +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler) { + if (parser != NULL) + parser->m_externalEntityRefHandler = handler; +} + +void XMLCALL +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) { + if (parser == NULL) + return; + if (arg) + parser->m_externalEntityRefHandlerArg = (XML_Parser)arg; + else + parser->m_externalEntityRefHandlerArg = parser; +} + +void XMLCALL +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler) { + if (parser != NULL) + parser->m_skippedEntityHandler = handler; +} + +void XMLCALL +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, void *data) { + if (parser == NULL) + return; + parser->m_unknownEncodingHandler = handler; + parser->m_unknownEncodingHandlerData = data; +} + +void XMLCALL +XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) { + if (parser != NULL) + parser->m_elementDeclHandler = eldecl; +} + +void XMLCALL +XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) { + if (parser != NULL) + parser->m_attlistDeclHandler = attdecl; +} + +void XMLCALL +XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) { + if (parser != NULL) + parser->m_entityDeclHandler = handler; +} + +void XMLCALL +XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) { + if (parser != NULL) + parser->m_xmlDeclHandler = handler; +} + +int XMLCALL +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing peParsing) { + if (parser == NULL) + return 0; + /* block after XML_Parse()/XML_ParseBuffer() has been called */ + if (parser->m_parsingStatus.parsing == XML_PARSING + || parser->m_parsingStatus.parsing == XML_SUSPENDED) + return 0; +#ifdef XML_DTD + parser->m_paramEntityParsing = peParsing; + return 1; +#else + return peParsing == XML_PARAM_ENTITY_PARSING_NEVER; +#endif +} + +int XMLCALL +XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) { + if (parser == NULL) + return 0; + if (parser->m_parentParser) + return XML_SetHashSalt(parser->m_parentParser, hash_salt); + /* block after XML_Parse()/XML_ParseBuffer() has been called */ + if (parser->m_parsingStatus.parsing == XML_PARSING + || parser->m_parsingStatus.parsing == XML_SUSPENDED) + return 0; + parser->m_hash_secret_salt = hash_salt; + return 1; +} + +enum XML_Status XMLCALL +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { + if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) { + if (parser != NULL) + parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT; + return XML_STATUS_ERROR; + } + switch (parser->m_parsingStatus.parsing) { + case XML_SUSPENDED: + parser->m_errorCode = XML_ERROR_SUSPENDED; + return XML_STATUS_ERROR; + case XML_FINISHED: + parser->m_errorCode = XML_ERROR_FINISHED; + return XML_STATUS_ERROR; + case XML_INITIALIZED: + if (parser->m_parentParser == NULL && ! startParsing(parser)) { + parser->m_errorCode = XML_ERROR_NO_MEMORY; + return XML_STATUS_ERROR; + } + /* fall through */ + default: + parser->m_parsingStatus.parsing = XML_PARSING; + } + +#if XML_CONTEXT_BYTES == 0 + if (parser->m_bufferPtr == parser->m_bufferEnd) { + const char *end; + int nLeftOver; + enum XML_Status result; + /* Detect overflow (a+b > MAX <==> b > MAX-a) */ + if ((XML_Size)len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) { + parser->m_errorCode = XML_ERROR_NO_MEMORY; + parser->m_eventPtr = parser->m_eventEndPtr = NULL; + parser->m_processor = errorProcessor; + return XML_STATUS_ERROR; + } + // though this isn't a buffer request, we assume that `len` is the app's + // preferred buffer fill size, and therefore save it here. + parser->m_lastBufferRequestSize = len; + parser->m_parseEndByteIndex += len; + parser->m_positionPtr = s; + parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; + + parser->m_errorCode + = callProcessor(parser, s, parser->m_parseEndPtr = s + len, &end); + + if (parser->m_errorCode != XML_ERROR_NONE) { + parser->m_eventEndPtr = parser->m_eventPtr; + parser->m_processor = errorProcessor; + return XML_STATUS_ERROR; + } else { + switch (parser->m_parsingStatus.parsing) { + case XML_SUSPENDED: + result = XML_STATUS_SUSPENDED; + break; + case XML_INITIALIZED: + case XML_PARSING: + if (isFinal) { + parser->m_parsingStatus.parsing = XML_FINISHED; + return XML_STATUS_OK; + } + /* fall through */ + default: + result = XML_STATUS_OK; + } + } + + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, + &parser->m_position); + nLeftOver = s + len - end; + if (nLeftOver) { + // Back up and restore the parsing status to avoid XML_ERROR_SUSPENDED + // (and XML_ERROR_FINISHED) from XML_GetBuffer. + const enum XML_Parsing originalStatus = parser->m_parsingStatus.parsing; + parser->m_parsingStatus.parsing = XML_PARSING; + void *const temp = XML_GetBuffer(parser, nLeftOver); + parser->m_parsingStatus.parsing = originalStatus; + // GetBuffer may have overwritten this, but we want to remember what the + // app requested, not how many bytes were left over after parsing. + parser->m_lastBufferRequestSize = len; + if (temp == NULL) { + // NOTE: parser->m_errorCode has already been set by XML_GetBuffer(). + parser->m_eventPtr = parser->m_eventEndPtr = NULL; + parser->m_processor = errorProcessor; + return XML_STATUS_ERROR; + } + // Since we know that the buffer was empty and XML_CONTEXT_BYTES is 0, we + // don't have any data to preserve, and can copy straight into the start + // of the buffer rather than the GetBuffer return pointer (which may be + // pointing further into the allocated buffer). + memcpy(parser->m_buffer, end, nLeftOver); + } + parser->m_bufferPtr = parser->m_buffer; + parser->m_bufferEnd = parser->m_buffer + nLeftOver; + parser->m_positionPtr = parser->m_bufferPtr; + parser->m_parseEndPtr = parser->m_bufferEnd; + parser->m_eventPtr = parser->m_bufferPtr; + parser->m_eventEndPtr = parser->m_bufferPtr; + return result; + } +#endif /* XML_CONTEXT_BYTES == 0 */ + void *buff = XML_GetBuffer(parser, len); + if (buff == NULL) + return XML_STATUS_ERROR; + if (len > 0) { + assert(s != NULL); // make sure s==NULL && len!=0 was rejected above + memcpy(buff, s, len); + } + return XML_ParseBuffer(parser, len, isFinal); +} + +enum XML_Status XMLCALL +XML_ParseBuffer(XML_Parser parser, int len, int isFinal) { + const char *start; + enum XML_Status result = XML_STATUS_OK; + + if (parser == NULL) + return XML_STATUS_ERROR; + + if (len < 0) { + parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT; + return XML_STATUS_ERROR; + } + + switch (parser->m_parsingStatus.parsing) { + case XML_SUSPENDED: + parser->m_errorCode = XML_ERROR_SUSPENDED; + return XML_STATUS_ERROR; + case XML_FINISHED: + parser->m_errorCode = XML_ERROR_FINISHED; + return XML_STATUS_ERROR; + case XML_INITIALIZED: + /* Has someone called XML_GetBuffer successfully before? */ + if (! parser->m_bufferPtr) { + parser->m_errorCode = XML_ERROR_NO_BUFFER; + return XML_STATUS_ERROR; + } + + if (parser->m_parentParser == NULL && ! startParsing(parser)) { + parser->m_errorCode = XML_ERROR_NO_MEMORY; + return XML_STATUS_ERROR; + } + /* fall through */ + default: + parser->m_parsingStatus.parsing = XML_PARSING; + } + + start = parser->m_bufferPtr; + parser->m_positionPtr = start; + parser->m_bufferEnd += len; + parser->m_parseEndPtr = parser->m_bufferEnd; + parser->m_parseEndByteIndex += len; + parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; + + parser->m_errorCode = callProcessor(parser, start, parser->m_parseEndPtr, + &parser->m_bufferPtr); + + if (parser->m_errorCode != XML_ERROR_NONE) { + parser->m_eventEndPtr = parser->m_eventPtr; + parser->m_processor = errorProcessor; + return XML_STATUS_ERROR; + } else { + switch (parser->m_parsingStatus.parsing) { + case XML_SUSPENDED: + result = XML_STATUS_SUSPENDED; + break; + case XML_INITIALIZED: + case XML_PARSING: + if (isFinal) { + parser->m_parsingStatus.parsing = XML_FINISHED; + return result; + } + default:; /* should not happen */ + } + } + + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, + parser->m_bufferPtr, &parser->m_position); + parser->m_positionPtr = parser->m_bufferPtr; + return result; +} + +void *XMLCALL +XML_GetBuffer(XML_Parser parser, int len) { + if (parser == NULL) + return NULL; + if (len < 0) { + parser->m_errorCode = XML_ERROR_NO_MEMORY; + return NULL; + } + switch (parser->m_parsingStatus.parsing) { + case XML_SUSPENDED: + parser->m_errorCode = XML_ERROR_SUSPENDED; + return NULL; + case XML_FINISHED: + parser->m_errorCode = XML_ERROR_FINISHED; + return NULL; + default:; + } + + // whether or not the request succeeds, `len` seems to be the app's preferred + // buffer fill size; remember it. + parser->m_lastBufferRequestSize = len; + if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd) + || parser->m_buffer == NULL) { +#if XML_CONTEXT_BYTES > 0 + int keep; +#endif /* XML_CONTEXT_BYTES > 0 */ + /* Do not invoke signed arithmetic overflow: */ + int neededSize = (int)((unsigned)len + + (unsigned)EXPAT_SAFE_PTR_DIFF( + parser->m_bufferEnd, parser->m_bufferPtr)); + if (neededSize < 0) { + parser->m_errorCode = XML_ERROR_NO_MEMORY; + return NULL; + } +#if XML_CONTEXT_BYTES > 0 + keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer); + if (keep > XML_CONTEXT_BYTES) + keep = XML_CONTEXT_BYTES; + /* Detect and prevent integer overflow */ + if (keep > INT_MAX - neededSize) { + parser->m_errorCode = XML_ERROR_NO_MEMORY; + return NULL; + } + neededSize += keep; +#endif /* XML_CONTEXT_BYTES > 0 */ + if (parser->m_buffer && parser->m_bufferPtr + && neededSize + <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) { +#if XML_CONTEXT_BYTES > 0 + if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) { + int offset + = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer) + - keep; + /* The buffer pointers cannot be NULL here; we have at least some bytes + * in the buffer */ + memmove(parser->m_buffer, &parser->m_buffer[offset], + parser->m_bufferEnd - parser->m_bufferPtr + keep); + parser->m_bufferEnd -= offset; + parser->m_bufferPtr -= offset; + } +#else + memmove(parser->m_buffer, parser->m_bufferPtr, + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); + parser->m_bufferEnd + = parser->m_buffer + + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); + parser->m_bufferPtr = parser->m_buffer; +#endif /* XML_CONTEXT_BYTES > 0 */ + } else { + char *newBuf; + int bufferSize + = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer); + if (bufferSize == 0) + bufferSize = INIT_BUFFER_SIZE; + do { + /* Do not invoke signed arithmetic overflow: */ + bufferSize = (int)(2U * (unsigned)bufferSize); + } while (bufferSize < neededSize && bufferSize > 0); + if (bufferSize <= 0) { + parser->m_errorCode = XML_ERROR_NO_MEMORY; + return NULL; + } + newBuf = (char *)MALLOC(parser, bufferSize); + if (newBuf == 0) { + parser->m_errorCode = XML_ERROR_NO_MEMORY; + return NULL; + } + parser->m_bufferLim = newBuf + bufferSize; +#if XML_CONTEXT_BYTES > 0 + if (parser->m_bufferPtr) { + memcpy(newBuf, &parser->m_bufferPtr[-keep], + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) + + keep); + FREE(parser, parser->m_buffer); + parser->m_buffer = newBuf; + parser->m_bufferEnd + = parser->m_buffer + + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) + + keep; + parser->m_bufferPtr = parser->m_buffer + keep; + } else { + /* This must be a brand new buffer with no data in it yet */ + parser->m_bufferEnd = newBuf; + parser->m_bufferPtr = parser->m_buffer = newBuf; + } +#else + if (parser->m_bufferPtr) { + memcpy(newBuf, parser->m_bufferPtr, + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); + FREE(parser, parser->m_buffer); + parser->m_bufferEnd + = newBuf + + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); + } else { + /* This must be a brand new buffer with no data in it yet */ + parser->m_bufferEnd = newBuf; + } + parser->m_bufferPtr = parser->m_buffer = newBuf; +#endif /* XML_CONTEXT_BYTES > 0 */ + } + parser->m_eventPtr = parser->m_eventEndPtr = NULL; + parser->m_positionPtr = NULL; + } + return parser->m_bufferEnd; +} + +enum XML_Status XMLCALL +XML_StopParser(XML_Parser parser, XML_Bool resumable) { + if (parser == NULL) + return XML_STATUS_ERROR; + switch (parser->m_parsingStatus.parsing) { + case XML_SUSPENDED: + if (resumable) { + parser->m_errorCode = XML_ERROR_SUSPENDED; + return XML_STATUS_ERROR; + } + parser->m_parsingStatus.parsing = XML_FINISHED; + break; + case XML_FINISHED: + parser->m_errorCode = XML_ERROR_FINISHED; + return XML_STATUS_ERROR; + default: + if (resumable) { +#ifdef XML_DTD + if (parser->m_isParamEntity) { + parser->m_errorCode = XML_ERROR_SUSPEND_PE; + return XML_STATUS_ERROR; + } +#endif + parser->m_parsingStatus.parsing = XML_SUSPENDED; + } else + parser->m_parsingStatus.parsing = XML_FINISHED; + } + return XML_STATUS_OK; +} + +enum XML_Status XMLCALL +XML_ResumeParser(XML_Parser parser) { + enum XML_Status result = XML_STATUS_OK; + + if (parser == NULL) + return XML_STATUS_ERROR; + if (parser->m_parsingStatus.parsing != XML_SUSPENDED) { + parser->m_errorCode = XML_ERROR_NOT_SUSPENDED; + return XML_STATUS_ERROR; + } + parser->m_parsingStatus.parsing = XML_PARSING; + + parser->m_errorCode = callProcessor( + parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr); + + if (parser->m_errorCode != XML_ERROR_NONE) { + parser->m_eventEndPtr = parser->m_eventPtr; + parser->m_processor = errorProcessor; + return XML_STATUS_ERROR; + } else { + switch (parser->m_parsingStatus.parsing) { + case XML_SUSPENDED: + result = XML_STATUS_SUSPENDED; + break; + case XML_INITIALIZED: + case XML_PARSING: + if (parser->m_parsingStatus.finalBuffer) { + parser->m_parsingStatus.parsing = XML_FINISHED; + return result; + } + default:; + } + } + + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, + parser->m_bufferPtr, &parser->m_position); + parser->m_positionPtr = parser->m_bufferPtr; + return result; +} + +void XMLCALL +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) { + if (parser == NULL) + return; + assert(status != NULL); + *status = parser->m_parsingStatus; +} + +enum XML_Error XMLCALL +XML_GetErrorCode(XML_Parser parser) { + if (parser == NULL) + return XML_ERROR_INVALID_ARGUMENT; + return parser->m_errorCode; +} + +XML_Index XMLCALL +XML_GetCurrentByteIndex(XML_Parser parser) { + if (parser == NULL) + return -1; + if (parser->m_eventPtr) + return (XML_Index)(parser->m_parseEndByteIndex + - (parser->m_parseEndPtr - parser->m_eventPtr)); + return -1; +} + +int XMLCALL +XML_GetCurrentByteCount(XML_Parser parser) { + if (parser == NULL) + return 0; + if (parser->m_eventEndPtr && parser->m_eventPtr) + return (int)(parser->m_eventEndPtr - parser->m_eventPtr); + return 0; +} + +const char *XMLCALL +XML_GetInputContext(XML_Parser parser, int *offset, int *size) { +#if XML_CONTEXT_BYTES > 0 + if (parser == NULL) + return NULL; + if (parser->m_eventPtr && parser->m_buffer) { + if (offset != NULL) + *offset = (int)(parser->m_eventPtr - parser->m_buffer); + if (size != NULL) + *size = (int)(parser->m_bufferEnd - parser->m_buffer); + return parser->m_buffer; + } +#else + (void)parser; + (void)offset; + (void)size; +#endif /* XML_CONTEXT_BYTES > 0 */ + return (const char *)0; +} + +XML_Size XMLCALL +XML_GetCurrentLineNumber(XML_Parser parser) { + if (parser == NULL) + return 0; + if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, + parser->m_eventPtr, &parser->m_position); + parser->m_positionPtr = parser->m_eventPtr; + } + return parser->m_position.lineNumber + 1; +} + +XML_Size XMLCALL +XML_GetCurrentColumnNumber(XML_Parser parser) { + if (parser == NULL) + return 0; + if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { + XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, + parser->m_eventPtr, &parser->m_position); + parser->m_positionPtr = parser->m_eventPtr; + } + return parser->m_position.columnNumber; +} + +void XMLCALL +XML_FreeContentModel(XML_Parser parser, XML_Content *model) { + if (parser != NULL) + FREE(parser, model); +} + +void *XMLCALL +XML_MemMalloc(XML_Parser parser, size_t size) { + if (parser == NULL) + return NULL; + return MALLOC(parser, size); +} + +void *XMLCALL +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) { + if (parser == NULL) + return NULL; + return REALLOC(parser, ptr, size); +} + +void XMLCALL +XML_MemFree(XML_Parser parser, void *ptr) { + if (parser != NULL) + FREE(parser, ptr); +} + +void XMLCALL +XML_DefaultCurrent(XML_Parser parser) { + if (parser == NULL) + return; + if (parser->m_defaultHandler) { + if (parser->m_openInternalEntities) + reportDefault(parser, parser->m_internalEncoding, + parser->m_openInternalEntities->internalEventPtr, + parser->m_openInternalEntities->internalEventEndPtr); + else + reportDefault(parser, parser->m_encoding, parser->m_eventPtr, + parser->m_eventEndPtr); + } +} + +const XML_LChar *XMLCALL +XML_ErrorString(enum XML_Error code) { + switch (code) { + case XML_ERROR_NONE: + return NULL; + case XML_ERROR_NO_MEMORY: + return XML_L("out of memory"); + case XML_ERROR_SYNTAX: + return XML_L("syntax error"); + case XML_ERROR_NO_ELEMENTS: + return XML_L("no element found"); + case XML_ERROR_INVALID_TOKEN: + return XML_L("not well-formed (invalid token)"); + case XML_ERROR_UNCLOSED_TOKEN: + return XML_L("unclosed token"); + case XML_ERROR_PARTIAL_CHAR: + return XML_L("partial character"); + case XML_ERROR_TAG_MISMATCH: + return XML_L("mismatched tag"); + case XML_ERROR_DUPLICATE_ATTRIBUTE: + return XML_L("duplicate attribute"); + case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: + return XML_L("junk after document element"); + case XML_ERROR_PARAM_ENTITY_REF: + return XML_L("illegal parameter entity reference"); + case XML_ERROR_UNDEFINED_ENTITY: + return XML_L("undefined entity"); + case XML_ERROR_RECURSIVE_ENTITY_REF: + return XML_L("recursive entity reference"); + case XML_ERROR_ASYNC_ENTITY: + return XML_L("asynchronous entity"); + case XML_ERROR_BAD_CHAR_REF: + return XML_L("reference to invalid character number"); + case XML_ERROR_BINARY_ENTITY_REF: + return XML_L("reference to binary entity"); + case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: + return XML_L("reference to external entity in attribute"); + case XML_ERROR_MISPLACED_XML_PI: + return XML_L("XML or text declaration not at start of entity"); + case XML_ERROR_UNKNOWN_ENCODING: + return XML_L("unknown encoding"); + case XML_ERROR_INCORRECT_ENCODING: + return XML_L("encoding specified in XML declaration is incorrect"); + case XML_ERROR_UNCLOSED_CDATA_SECTION: + return XML_L("unclosed CDATA section"); + case XML_ERROR_EXTERNAL_ENTITY_HANDLING: + return XML_L("error in processing external entity reference"); + case XML_ERROR_NOT_STANDALONE: + return XML_L("document is not standalone"); + case XML_ERROR_UNEXPECTED_STATE: + return XML_L("unexpected parser state - please send a bug report"); + case XML_ERROR_ENTITY_DECLARED_IN_PE: + return XML_L("entity declared in parameter entity"); + case XML_ERROR_FEATURE_REQUIRES_XML_DTD: + return XML_L("requested feature requires XML_DTD support in Expat"); + case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: + return XML_L("cannot change setting once parsing has begun"); + /* Added in 1.95.7. */ + case XML_ERROR_UNBOUND_PREFIX: + return XML_L("unbound prefix"); + /* Added in 1.95.8. */ + case XML_ERROR_UNDECLARING_PREFIX: + return XML_L("must not undeclare prefix"); + case XML_ERROR_INCOMPLETE_PE: + return XML_L("incomplete markup in parameter entity"); + case XML_ERROR_XML_DECL: + return XML_L("XML declaration not well-formed"); + case XML_ERROR_TEXT_DECL: + return XML_L("text declaration not well-formed"); + case XML_ERROR_PUBLICID: + return XML_L("illegal character(s) in public id"); + case XML_ERROR_SUSPENDED: + return XML_L("parser suspended"); + case XML_ERROR_NOT_SUSPENDED: + return XML_L("parser not suspended"); + case XML_ERROR_ABORTED: + return XML_L("parsing aborted"); + case XML_ERROR_FINISHED: + return XML_L("parsing finished"); + case XML_ERROR_SUSPEND_PE: + return XML_L("cannot suspend in external parameter entity"); + /* Added in 2.0.0. */ + case XML_ERROR_RESERVED_PREFIX_XML: + return XML_L( + "reserved prefix (xml) must not be undeclared or bound to another namespace name"); + case XML_ERROR_RESERVED_PREFIX_XMLNS: + return XML_L("reserved prefix (xmlns) must not be declared or undeclared"); + case XML_ERROR_RESERVED_NAMESPACE_URI: + return XML_L( + "prefix must not be bound to one of the reserved namespace names"); + /* Added in 2.2.5. */ + case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */ + return XML_L("invalid argument"); + /* Added in 2.3.0. */ + case XML_ERROR_NO_BUFFER: + return XML_L( + "a successful prior call to function XML_GetBuffer is required"); + /* Added in 2.4.0. */ + case XML_ERROR_AMPLIFICATION_LIMIT_BREACH: + return XML_L( + "limit on input amplification factor (from DTD and entities) breached"); + } + return NULL; +} + +const XML_LChar *XMLCALL +XML_ExpatVersion(void) { + /* V1 is used to string-ize the version number. However, it would + string-ize the actual version macro *names* unless we get them + substituted before being passed to V1. CPP is defined to expand + a macro, then rescan for more expansions. Thus, we use V2 to expand + the version macros, then CPP will expand the resulting V1() macro + with the correct numerals. */ + /* ### I'm assuming cpp is portable in this respect... */ + +#define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c) +#define V2(a, b, c) XML_L("expat_") V1(a, b, c) + + return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); + +#undef V1 +#undef V2 +} + +XML_Expat_Version XMLCALL +XML_ExpatVersionInfo(void) { + XML_Expat_Version version; + + version.major = XML_MAJOR_VERSION; + version.minor = XML_MINOR_VERSION; + version.micro = XML_MICRO_VERSION; + + return version; +} + +const XML_Feature *XMLCALL +XML_GetFeatureList(void) { + static const XML_Feature features[] = { + {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), + sizeof(XML_Char)}, + {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), + sizeof(XML_LChar)}, +#ifdef XML_UNICODE + {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0}, +#endif +#ifdef XML_UNICODE_WCHAR_T + {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0}, +#endif +#ifdef XML_DTD + {XML_FEATURE_DTD, XML_L("XML_DTD"), 0}, +#endif +#if XML_CONTEXT_BYTES > 0 + {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), + XML_CONTEXT_BYTES}, +#endif +#ifdef XML_MIN_SIZE + {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0}, +#endif +#ifdef XML_NS + {XML_FEATURE_NS, XML_L("XML_NS"), 0}, +#endif +#ifdef XML_LARGE_SIZE + {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0}, +#endif +#ifdef XML_ATTR_INFO + {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0}, +#endif +#if XML_GE == 1 + /* Added in Expat 2.4.0 for XML_DTD defined and + * added in Expat 2.6.0 for XML_GE == 1. */ + {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT, + XML_L("XML_BLAP_MAX_AMP"), + (long int) + EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT}, + {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT, + XML_L("XML_BLAP_ACT_THRES"), + EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT}, + /* Added in Expat 2.6.0. */ + {XML_FEATURE_GE, XML_L("XML_GE"), 0}, +#endif + {XML_FEATURE_END, NULL, 0}}; + + return features; +} + +#if XML_GE == 1 +XML_Bool XMLCALL +XML_SetBillionLaughsAttackProtectionMaximumAmplification( + XML_Parser parser, float maximumAmplificationFactor) { + if ((parser == NULL) || (parser->m_parentParser != NULL) + || isnan(maximumAmplificationFactor) + || (maximumAmplificationFactor < 1.0f)) { + return XML_FALSE; + } + parser->m_accounting.maximumAmplificationFactor = maximumAmplificationFactor; + return XML_TRUE; +} + +XML_Bool XMLCALL +XML_SetBillionLaughsAttackProtectionActivationThreshold( + XML_Parser parser, unsigned long long activationThresholdBytes) { + if ((parser == NULL) || (parser->m_parentParser != NULL)) { + return XML_FALSE; + } + parser->m_accounting.activationThresholdBytes = activationThresholdBytes; + return XML_TRUE; +} +#endif /* XML_GE == 1 */ + +XML_Bool XMLCALL +XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled) { + if (parser != NULL && (enabled == XML_TRUE || enabled == XML_FALSE)) { + parser->m_reparseDeferralEnabled = enabled; + return XML_TRUE; + } + return XML_FALSE; +} + +/* Initially tag->rawName always points into the parse buffer; + for those TAG instances opened while the current parse buffer was + processed, and not yet closed, we need to store tag->rawName in a more + permanent location, since the parse buffer is about to be discarded. +*/ +static XML_Bool +storeRawNames(XML_Parser parser) { + TAG *tag = parser->m_tagStack; + while (tag) { + int bufSize; + int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); + size_t rawNameLen; + char *rawNameBuf = tag->buf + nameLen; + /* Stop if already stored. Since m_tagStack is a stack, we can stop + at the first entry that has already been copied; everything + below it in the stack is already been accounted for in a + previous call to this function. + */ + if (tag->rawName == rawNameBuf) + break; + /* For reuse purposes we need to ensure that the + size of tag->buf is a multiple of sizeof(XML_Char). + */ + rawNameLen = ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); + /* Detect and prevent integer overflow. */ + if (rawNameLen > (size_t)INT_MAX - nameLen) + return XML_FALSE; + bufSize = nameLen + (int)rawNameLen; + if (bufSize > tag->bufEnd - tag->buf) { + char *temp = (char *)REALLOC(parser, tag->buf, bufSize); + if (temp == NULL) + return XML_FALSE; + /* if tag->name.str points to tag->buf (only when namespace + processing is off) then we have to update it + */ + if (tag->name.str == (XML_Char *)tag->buf) + tag->name.str = (XML_Char *)temp; + /* if tag->name.localPart is set (when namespace processing is on) + then update it as well, since it will always point into tag->buf + */ + if (tag->name.localPart) + tag->name.localPart + = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf); + tag->buf = temp; + tag->bufEnd = temp + bufSize; + rawNameBuf = temp + nameLen; + } + memcpy(rawNameBuf, tag->rawName, tag->rawNameLength); + tag->rawName = rawNameBuf; + tag = tag->parent; + } + return XML_TRUE; +} + +static enum XML_Error PTRCALL +contentProcessor(XML_Parser parser, const char *start, const char *end, + const char **endPtr) { + enum XML_Error result = doContent( + parser, 0, parser->m_encoding, start, end, endPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT); + if (result == XML_ERROR_NONE) { + if (! storeRawNames(parser)) + return XML_ERROR_NO_MEMORY; + } + return result; +} + +static enum XML_Error PTRCALL +externalEntityInitProcessor(XML_Parser parser, const char *start, + const char *end, const char **endPtr) { + enum XML_Error result = initializeEncoding(parser); + if (result != XML_ERROR_NONE) + return result; + parser->m_processor = externalEntityInitProcessor2; + return externalEntityInitProcessor2(parser, start, end, endPtr); +} + +static enum XML_Error PTRCALL +externalEntityInitProcessor2(XML_Parser parser, const char *start, + const char *end, const char **endPtr) { + const char *next = start; /* XmlContentTok doesn't always set the last arg */ + int tok = XmlContentTok(parser->m_encoding, start, end, &next); + switch (tok) { + case XML_TOK_BOM: +#if XML_GE == 1 + if (! accountingDiffTolerated(parser, tok, start, next, __LINE__, + XML_ACCOUNT_DIRECT)) { + accountingOnAbort(parser); + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; + } +#endif /* XML_GE == 1 */ + + /* If we are at the end of the buffer, this would cause the next stage, + i.e. externalEntityInitProcessor3, to pass control directly to + doContent (by detecting XML_TOK_NONE) without processing any xml text + declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. + */ + if (next == end && ! parser->m_parsingStatus.finalBuffer) { + *endPtr = next; + return XML_ERROR_NONE; + } + start = next; + break; + case XML_TOK_PARTIAL: + if (! parser->m_parsingStatus.finalBuffer) { + *endPtr = start; + return XML_ERROR_NONE; + } + parser->m_eventPtr = start; + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (! parser->m_parsingStatus.finalBuffer) { + *endPtr = start; + return XML_ERROR_NONE; + } + parser->m_eventPtr = start; + return XML_ERROR_PARTIAL_CHAR; + } + parser->m_processor = externalEntityInitProcessor3; + return externalEntityInitProcessor3(parser, start, end, endPtr); +} + +static enum XML_Error PTRCALL +externalEntityInitProcessor3(XML_Parser parser, const char *start, + const char *end, const char **endPtr) { + int tok; + const char *next = start; /* XmlContentTok doesn't always set the last arg */ + parser->m_eventPtr = start; + tok = XmlContentTok(parser->m_encoding, start, end, &next); + /* Note: These bytes are accounted later in: + - processXmlDecl + - externalEntityContentProcessor + */ + parser->m_eventEndPtr = next; + + switch (tok) { + case XML_TOK_XML_DECL: { + enum XML_Error result; + result = processXmlDecl(parser, 1, start, next); + if (result != XML_ERROR_NONE) + return result; + switch (parser->m_parsingStatus.parsing) { + case XML_SUSPENDED: + *endPtr = next; + return XML_ERROR_NONE; + case XML_FINISHED: + return XML_ERROR_ABORTED; + default: + start = next; + } + } break; + case XML_TOK_PARTIAL: + if (! parser->m_parsingStatus.finalBuffer) { + *endPtr = start; + return XML_ERROR_NONE; + } + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (! parser->m_parsingStatus.finalBuffer) { + *endPtr = start; + return XML_ERROR_NONE; + } + return XML_ERROR_PARTIAL_CHAR; + } + parser->m_processor = externalEntityContentProcessor; + parser->m_tagLevel = 1; + return externalEntityContentProcessor(parser, start, end, endPtr); +} + +static enum XML_Error PTRCALL +externalEntityContentProcessor(XML_Parser parser, const char *start, + const char *end, const char **endPtr) { + enum XML_Error result + = doContent(parser, 1, parser->m_encoding, start, end, endPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer, + XML_ACCOUNT_ENTITY_EXPANSION); + if (result == XML_ERROR_NONE) { + if (! storeRawNames(parser)) + return XML_ERROR_NO_MEMORY; + } + return result; +} + +static enum XML_Error +doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, + const char *s, const char *end, const char **nextPtr, + XML_Bool haveMore, enum XML_Account account) { + /* save one level of indirection */ + DTD *const dtd = parser->m_dtd; + + const char **eventPP; + const char **eventEndPP; + if (enc == parser->m_encoding) { + eventPP = &parser->m_eventPtr; + eventEndPP = &parser->m_eventEndPtr; + } else { + eventPP = &(parser->m_openInternalEntities->internalEventPtr); + eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); + } + *eventPP = s; + + for (;;) { + const char *next = s; /* XmlContentTok doesn't always set the last arg */ + int tok = XmlContentTok(enc, s, end, &next); +#if XML_GE == 1 + const char *accountAfter + = ((tok == XML_TOK_TRAILING_RSQB) || (tok == XML_TOK_TRAILING_CR)) + ? (haveMore ? s /* i.e. 0 bytes */ : end) + : next; + if (! accountingDiffTolerated(parser, tok, s, accountAfter, __LINE__, + account)) { + accountingOnAbort(parser); + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; + } +#endif + *eventEndPP = next; + switch (tok) { + case XML_TOK_TRAILING_CR: + if (haveMore) { + *nextPtr = s; + return XML_ERROR_NONE; + } + *eventEndPP = end; + if (parser->m_characterDataHandler) { + XML_Char c = 0xA; + parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); + } else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, end); + /* We are at the end of the final buffer, should we check for + XML_SUSPENDED, XML_FINISHED? + */ + if (startTagLevel == 0) + return XML_ERROR_NO_ELEMENTS; + if (parser->m_tagLevel != startTagLevel) + return XML_ERROR_ASYNC_ENTITY; + *nextPtr = end; + return XML_ERROR_NONE; + case XML_TOK_NONE: + if (haveMore) { + *nextPtr = s; + return XML_ERROR_NONE; + } + if (startTagLevel > 0) { + if (parser->m_tagLevel != startTagLevel) + return XML_ERROR_ASYNC_ENTITY; + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_NO_ELEMENTS; + case XML_TOK_INVALID: + *eventPP = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + if (haveMore) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (haveMore) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_ENTITY_REF: { + const XML_Char *name; + ENTITY *entity; + XML_Char ch = (XML_Char)XmlPredefinedEntityName( + enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); + if (ch) { +#if XML_GE == 1 + /* NOTE: We are replacing 4-6 characters original input for 1 character + * so there is no amplification and hence recording without + * protection. */ + accountingDiffTolerated(parser, tok, (char *)&ch, + ((char *)&ch) + sizeof(XML_Char), __LINE__, + XML_ACCOUNT_ENTITY_EXPANSION); +#endif /* XML_GE == 1 */ + if (parser->m_characterDataHandler) + parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1); + else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + break; + } + name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (! name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); + poolDiscard(&dtd->pool); + /* First, determine if a check for an existing declaration is needed; + if yes, check that the entity exists, and that it is internal, + otherwise call the skipped entity or default handler. + */ + if (! dtd->hasParamEntityRefs || dtd->standalone) { + if (! entity) + return XML_ERROR_UNDEFINED_ENTITY; + else if (! entity->is_internal) + return XML_ERROR_ENTITY_DECLARED_IN_PE; + } else if (! entity) { + if (parser->m_skippedEntityHandler) + parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); + else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + break; + } + if (entity->open) + return XML_ERROR_RECURSIVE_ENTITY_REF; + if (entity->notation) + return XML_ERROR_BINARY_ENTITY_REF; + if (entity->textPtr) { + enum XML_Error result; + if (! parser->m_defaultExpandInternalEntities) { + if (parser->m_skippedEntityHandler) + parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name, + 0); + else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + break; + } + result = processInternalEntity(parser, entity, XML_FALSE); + if (result != XML_ERROR_NONE) + return result; + } else if (parser->m_externalEntityRefHandler) { + const XML_Char *context; + entity->open = XML_TRUE; + context = getContext(parser); + entity->open = XML_FALSE; + if (! context) + return XML_ERROR_NO_MEMORY; + if (! parser->m_externalEntityRefHandler( + parser->m_externalEntityRefHandlerArg, context, entity->base, + entity->systemId, entity->publicId)) + return XML_ERROR_EXTERNAL_ENTITY_HANDLING; + poolDiscard(&parser->m_tempPool); + } else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + break; + } + case XML_TOK_START_TAG_NO_ATTS: + /* fall through */ + case XML_TOK_START_TAG_WITH_ATTS: { + TAG *tag; + enum XML_Error result; + XML_Char *toPtr; + if (parser->m_freeTagList) { + tag = parser->m_freeTagList; + parser->m_freeTagList = parser->m_freeTagList->parent; + } else { + tag = (TAG *)MALLOC(parser, sizeof(TAG)); + if (! tag) + return XML_ERROR_NO_MEMORY; + tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE); + if (! tag->buf) { + FREE(parser, tag); + return XML_ERROR_NO_MEMORY; + } + tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; + } + tag->bindings = NULL; + tag->parent = parser->m_tagStack; + parser->m_tagStack = tag; + tag->name.localPart = NULL; + tag->name.prefix = NULL; + tag->rawName = s + enc->minBytesPerChar; + tag->rawNameLength = XmlNameLength(enc, tag->rawName); + ++parser->m_tagLevel; + { + const char *rawNameEnd = tag->rawName + tag->rawNameLength; + const char *fromPtr = tag->rawName; + toPtr = (XML_Char *)tag->buf; + for (;;) { + int bufSize; + int convLen; + const enum XML_Convert_Result convert_res + = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr, + (ICHAR *)tag->bufEnd - 1); + convLen = (int)(toPtr - (XML_Char *)tag->buf); + if ((fromPtr >= rawNameEnd) + || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { + tag->name.strLen = convLen; + break; + } + bufSize = (int)(tag->bufEnd - tag->buf) << 1; + { + char *temp = (char *)REALLOC(parser, tag->buf, bufSize); + if (temp == NULL) + return XML_ERROR_NO_MEMORY; + tag->buf = temp; + tag->bufEnd = temp + bufSize; + toPtr = (XML_Char *)temp + convLen; + } + } + } + tag->name.str = (XML_Char *)tag->buf; + *toPtr = XML_T('\0'); + result + = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings), account); + if (result) + return result; + if (parser->m_startElementHandler) + parser->m_startElementHandler(parser->m_handlerArg, tag->name.str, + (const XML_Char **)parser->m_atts); + else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + poolClear(&parser->m_tempPool); + break; + } + case XML_TOK_EMPTY_ELEMENT_NO_ATTS: + /* fall through */ + case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: { + const char *rawName = s + enc->minBytesPerChar; + enum XML_Error result; + BINDING *bindings = NULL; + XML_Bool noElmHandlers = XML_TRUE; + TAG_NAME name; + name.str = poolStoreString(&parser->m_tempPool, enc, rawName, + rawName + XmlNameLength(enc, rawName)); + if (! name.str) + return XML_ERROR_NO_MEMORY; + poolFinish(&parser->m_tempPool); + result = storeAtts(parser, enc, s, &name, &bindings, + XML_ACCOUNT_NONE /* token spans whole start tag */); + if (result != XML_ERROR_NONE) { + freeBindings(parser, bindings); + return result; + } + poolFinish(&parser->m_tempPool); + if (parser->m_startElementHandler) { + parser->m_startElementHandler(parser->m_handlerArg, name.str, + (const XML_Char **)parser->m_atts); + noElmHandlers = XML_FALSE; + } + if (parser->m_endElementHandler) { + if (parser->m_startElementHandler) + *eventPP = *eventEndPP; + parser->m_endElementHandler(parser->m_handlerArg, name.str); + noElmHandlers = XML_FALSE; + } + if (noElmHandlers && parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + poolClear(&parser->m_tempPool); + freeBindings(parser, bindings); + } + if ((parser->m_tagLevel == 0) + && (parser->m_parsingStatus.parsing != XML_FINISHED)) { + if (parser->m_parsingStatus.parsing == XML_SUSPENDED) + parser->m_processor = epilogProcessor; + else + return epilogProcessor(parser, next, end, nextPtr); + } + break; + case XML_TOK_END_TAG: + if (parser->m_tagLevel == startTagLevel) + return XML_ERROR_ASYNC_ENTITY; + else { + int len; + const char *rawName; + TAG *tag = parser->m_tagStack; + rawName = s + enc->minBytesPerChar * 2; + len = XmlNameLength(enc, rawName); + if (len != tag->rawNameLength + || memcmp(tag->rawName, rawName, len) != 0) { + *eventPP = rawName; + return XML_ERROR_TAG_MISMATCH; + } + parser->m_tagStack = tag->parent; + tag->parent = parser->m_freeTagList; + parser->m_freeTagList = tag; + --parser->m_tagLevel; + if (parser->m_endElementHandler) { + const XML_Char *localPart; + const XML_Char *prefix; + XML_Char *uri; + localPart = tag->name.localPart; + if (parser->m_ns && localPart) { + /* localPart and prefix may have been overwritten in + tag->name.str, since this points to the binding->uri + buffer which gets reused; so we have to add them again + */ + uri = (XML_Char *)tag->name.str + tag->name.uriLen; + /* don't need to check for space - already done in storeAtts() */ + while (*localPart) + *uri++ = *localPart++; + prefix = tag->name.prefix; + if (parser->m_ns_triplets && prefix) { + *uri++ = parser->m_namespaceSeparator; + while (*prefix) + *uri++ = *prefix++; + } + *uri = XML_T('\0'); + } + parser->m_endElementHandler(parser->m_handlerArg, tag->name.str); + } else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + while (tag->bindings) { + BINDING *b = tag->bindings; + if (parser->m_endNamespaceDeclHandler) + parser->m_endNamespaceDeclHandler(parser->m_handlerArg, + b->prefix->name); + tag->bindings = tag->bindings->nextTagBinding; + b->nextTagBinding = parser->m_freeBindingList; + parser->m_freeBindingList = b; + b->prefix->binding = b->prevPrefixBinding; + } + if ((parser->m_tagLevel == 0) + && (parser->m_parsingStatus.parsing != XML_FINISHED)) { + if (parser->m_parsingStatus.parsing == XML_SUSPENDED) + parser->m_processor = epilogProcessor; + else + return epilogProcessor(parser, next, end, nextPtr); + } + } + break; + case XML_TOK_CHAR_REF: { + int n = XmlCharRefNumber(enc, s); + if (n < 0) + return XML_ERROR_BAD_CHAR_REF; + if (parser->m_characterDataHandler) { + XML_Char buf[XML_ENCODE_MAX]; + parser->m_characterDataHandler(parser->m_handlerArg, buf, + XmlEncode(n, (ICHAR *)buf)); + } else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + } break; + case XML_TOK_XML_DECL: + return XML_ERROR_MISPLACED_XML_PI; + case XML_TOK_DATA_NEWLINE: + if (parser->m_characterDataHandler) { + XML_Char c = 0xA; + parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); + } else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + break; + case XML_TOK_CDATA_SECT_OPEN: { + enum XML_Error result; + if (parser->m_startCdataSectionHandler) + parser->m_startCdataSectionHandler(parser->m_handlerArg); + /* BEGIN disabled code */ + /* Suppose you doing a transformation on a document that involves + changing only the character data. You set up a defaultHandler + and a characterDataHandler. The defaultHandler simply copies + characters through. The characterDataHandler does the + transformation and writes the characters out escaping them as + necessary. This case will fail to work if we leave out the + following two lines (because & and < inside CDATA sections will + be incorrectly escaped). + + However, now we have a start/endCdataSectionHandler, so it seems + easier to let the user deal with this. + */ + else if ((0) && parser->m_characterDataHandler) + parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, + 0); + /* END disabled code */ + else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + result + = doCdataSection(parser, enc, &next, end, nextPtr, haveMore, account); + if (result != XML_ERROR_NONE) + return result; + else if (! next) { + parser->m_processor = cdataSectionProcessor; + return result; + } + } break; + case XML_TOK_TRAILING_RSQB: + if (haveMore) { + *nextPtr = s; + return XML_ERROR_NONE; + } + if (parser->m_characterDataHandler) { + if (MUST_CONVERT(enc, s)) { + ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; + XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); + parser->m_characterDataHandler( + parser->m_handlerArg, parser->m_dataBuf, + (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); + } else + parser->m_characterDataHandler( + parser->m_handlerArg, (const XML_Char *)s, + (int)((const XML_Char *)end - (const XML_Char *)s)); + } else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, end); + /* We are at the end of the final buffer, should we check for + XML_SUSPENDED, XML_FINISHED? + */ + if (startTagLevel == 0) { + *eventPP = end; + return XML_ERROR_NO_ELEMENTS; + } + if (parser->m_tagLevel != startTagLevel) { + *eventPP = end; + return XML_ERROR_ASYNC_ENTITY; + } + *nextPtr = end; + return XML_ERROR_NONE; + case XML_TOK_DATA_CHARS: { + XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; + if (charDataHandler) { + if (MUST_CONVERT(enc, s)) { + for (;;) { + ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; + const enum XML_Convert_Result convert_res = XmlConvert( + enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); + *eventEndPP = s; + charDataHandler(parser->m_handlerArg, parser->m_dataBuf, + (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); + if ((convert_res == XML_CONVERT_COMPLETED) + || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) + break; + *eventPP = s; + } + } else + charDataHandler(parser->m_handlerArg, (const XML_Char *)s, + (int)((const XML_Char *)next - (const XML_Char *)s)); + } else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + } break; + case XML_TOK_PI: + if (! reportProcessingInstruction(parser, enc, s, next)) + return XML_ERROR_NO_MEMORY; + break; + case XML_TOK_COMMENT: + if (! reportComment(parser, enc, s, next)) + return XML_ERROR_NO_MEMORY; + break; + default: + /* All of the tokens produced by XmlContentTok() have their own + * explicit cases, so this default is not strictly necessary. + * However it is a useful safety net, so we retain the code and + * simply exclude it from the coverage tests. + * + * LCOV_EXCL_START + */ + if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + break; + /* LCOV_EXCL_STOP */ + } + *eventPP = s = next; + switch (parser->m_parsingStatus.parsing) { + case XML_SUSPENDED: + *nextPtr = next; + return XML_ERROR_NONE; + case XML_FINISHED: + return XML_ERROR_ABORTED; + default:; + } + } + /* not reached */ +} + +/* This function does not call free() on the allocated memory, merely + * moving it to the parser's m_freeBindingList where it can be freed or + * reused as appropriate. + */ +static void +freeBindings(XML_Parser parser, BINDING *bindings) { + while (bindings) { + BINDING *b = bindings; + + /* m_startNamespaceDeclHandler will have been called for this + * binding in addBindings(), so call the end handler now. + */ + if (parser->m_endNamespaceDeclHandler) + parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name); + + bindings = bindings->nextTagBinding; + b->nextTagBinding = parser->m_freeBindingList; + parser->m_freeBindingList = b; + b->prefix->binding = b->prevPrefixBinding; + } +} + +/* Precondition: all arguments must be non-NULL; + Purpose: + - normalize attributes + - check attributes for well-formedness + - generate namespace aware attribute names (URI, prefix) + - build list of attributes for startElementHandler + - default attributes + - process namespace declarations (check and report them) + - generate namespace aware element name (URI, prefix) +*/ +static enum XML_Error +storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, + TAG_NAME *tagNamePtr, BINDING **bindingsPtr, + enum XML_Account account) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ + ELEMENT_TYPE *elementType; + int nDefaultAtts; + const XML_Char **appAtts; /* the attribute list for the application */ + int attIndex = 0; + int prefixLen; + int i; + int n; + XML_Char *uri; + int nPrefixes = 0; + BINDING *binding; + const XML_Char *localPart; + + /* lookup the element type name */ + elementType + = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0); + if (! elementType) { + const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str); + if (! name) + return XML_ERROR_NO_MEMORY; + elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, + sizeof(ELEMENT_TYPE)); + if (! elementType) + return XML_ERROR_NO_MEMORY; + if (parser->m_ns && ! setElementTypePrefix(parser, elementType)) + return XML_ERROR_NO_MEMORY; + } + nDefaultAtts = elementType->nDefaultAtts; + + /* get the attributes from the tokenizer */ + n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts); + + /* Detect and prevent integer overflow */ + if (n > INT_MAX - nDefaultAtts) { + return XML_ERROR_NO_MEMORY; + } + + if (n + nDefaultAtts > parser->m_attsSize) { + int oldAttsSize = parser->m_attsSize; + ATTRIBUTE *temp; +#ifdef XML_ATTR_INFO + XML_AttrInfo *temp2; +#endif + + /* Detect and prevent integer overflow */ + if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE) + || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) { + return XML_ERROR_NO_MEMORY; + } + + parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; + + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) { + parser->m_attsSize = oldAttsSize; + return XML_ERROR_NO_MEMORY; + } +#endif + + temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, + parser->m_attsSize * sizeof(ATTRIBUTE)); + if (temp == NULL) { + parser->m_attsSize = oldAttsSize; + return XML_ERROR_NO_MEMORY; + } + parser->m_atts = temp; +#ifdef XML_ATTR_INFO + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +# if UINT_MAX >= SIZE_MAX + if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) { + parser->m_attsSize = oldAttsSize; + return XML_ERROR_NO_MEMORY; + } +# endif + + temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, + parser->m_attsSize * sizeof(XML_AttrInfo)); + if (temp2 == NULL) { + parser->m_attsSize = oldAttsSize; + return XML_ERROR_NO_MEMORY; + } + parser->m_attInfo = temp2; +#endif + if (n > oldAttsSize) + XmlGetAttributes(enc, attStr, n, parser->m_atts); + } + + appAtts = (const XML_Char **)parser->m_atts; + for (i = 0; i < n; i++) { + ATTRIBUTE *currAtt = &parser->m_atts[i]; +#ifdef XML_ATTR_INFO + XML_AttrInfo *currAttInfo = &parser->m_attInfo[i]; +#endif + /* add the name and value to the attribute list */ + ATTRIBUTE_ID *attId + = getAttributeId(parser, enc, currAtt->name, + currAtt->name + XmlNameLength(enc, currAtt->name)); + if (! attId) + return XML_ERROR_NO_MEMORY; +#ifdef XML_ATTR_INFO + currAttInfo->nameStart + = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name); + currAttInfo->nameEnd + = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name); + currAttInfo->valueStart = parser->m_parseEndByteIndex + - (parser->m_parseEndPtr - currAtt->valuePtr); + currAttInfo->valueEnd = parser->m_parseEndByteIndex + - (parser->m_parseEndPtr - currAtt->valueEnd); +#endif + /* Detect duplicate attributes by their QNames. This does not work when + namespace processing is turned on and different prefixes for the same + namespace are used. For this case we have a check further down. + */ + if ((attId->name)[-1]) { + if (enc == parser->m_encoding) + parser->m_eventPtr = parser->m_atts[i].name; + return XML_ERROR_DUPLICATE_ATTRIBUTE; + } + (attId->name)[-1] = 1; + appAtts[attIndex++] = attId->name; + if (! parser->m_atts[i].normalized) { + enum XML_Error result; + XML_Bool isCdata = XML_TRUE; + + /* figure out whether declared as other than CDATA */ + if (attId->maybeTokenized) { + int j; + for (j = 0; j < nDefaultAtts; j++) { + if (attId == elementType->defaultAtts[j].id) { + isCdata = elementType->defaultAtts[j].isCdata; + break; + } + } + } + + /* normalize the attribute value */ + result = storeAttributeValue( + parser, enc, isCdata, parser->m_atts[i].valuePtr, + parser->m_atts[i].valueEnd, &parser->m_tempPool, account); + if (result) + return result; + appAtts[attIndex] = poolStart(&parser->m_tempPool); + poolFinish(&parser->m_tempPool); + } else { + /* the value did not need normalizing */ + appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc, + parser->m_atts[i].valuePtr, + parser->m_atts[i].valueEnd); + if (appAtts[attIndex] == 0) + return XML_ERROR_NO_MEMORY; + poolFinish(&parser->m_tempPool); + } + /* handle prefixed attribute names */ + if (attId->prefix) { + if (attId->xmlns) { + /* deal with namespace declarations here */ + enum XML_Error result = addBinding(parser, attId->prefix, attId, + appAtts[attIndex], bindingsPtr); + if (result) + return result; + --attIndex; + } else { + /* deal with other prefixed names later */ + attIndex++; + nPrefixes++; + (attId->name)[-1] = 2; + } + } else + attIndex++; + } + + /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */ + parser->m_nSpecifiedAtts = attIndex; + if (elementType->idAtt && (elementType->idAtt->name)[-1]) { + for (i = 0; i < attIndex; i += 2) + if (appAtts[i] == elementType->idAtt->name) { + parser->m_idAttIndex = i; + break; + } + } else + parser->m_idAttIndex = -1; + + /* do attribute defaulting */ + for (i = 0; i < nDefaultAtts; i++) { + const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i; + if (! (da->id->name)[-1] && da->value) { + if (da->id->prefix) { + if (da->id->xmlns) { + enum XML_Error result = addBinding(parser, da->id->prefix, da->id, + da->value, bindingsPtr); + if (result) + return result; + } else { + (da->id->name)[-1] = 2; + nPrefixes++; + appAtts[attIndex++] = da->id->name; + appAtts[attIndex++] = da->value; + } + } else { + (da->id->name)[-1] = 1; + appAtts[attIndex++] = da->id->name; + appAtts[attIndex++] = da->value; + } + } + } + appAtts[attIndex] = 0; + + /* expand prefixed attribute names, check for duplicates, + and clear flags that say whether attributes were specified */ + i = 0; + if (nPrefixes) { + int j; /* hash table index */ + unsigned long version = parser->m_nsAttsVersion; + + /* Detect and prevent invalid shift */ + if (parser->m_nsAttsPower >= sizeof(unsigned int) * 8 /* bits per byte */) { + return XML_ERROR_NO_MEMORY; + } + + unsigned int nsAttsSize = 1u << parser->m_nsAttsPower; + unsigned char oldNsAttsPower = parser->m_nsAttsPower; + /* size of hash table must be at least 2 * (# of prefixed attributes) */ + if ((nPrefixes << 1) + >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */ + NS_ATT *temp; + /* hash table size must also be a power of 2 and >= 8 */ + while (nPrefixes >> parser->m_nsAttsPower++) + ; + if (parser->m_nsAttsPower < 3) + parser->m_nsAttsPower = 3; + + /* Detect and prevent invalid shift */ + if (parser->m_nsAttsPower >= sizeof(nsAttsSize) * 8 /* bits per byte */) { + /* Restore actual size of memory in m_nsAtts */ + parser->m_nsAttsPower = oldNsAttsPower; + return XML_ERROR_NO_MEMORY; + } + + nsAttsSize = 1u << parser->m_nsAttsPower; + + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if (nsAttsSize > (size_t)(-1) / sizeof(NS_ATT)) { + /* Restore actual size of memory in m_nsAtts */ + parser->m_nsAttsPower = oldNsAttsPower; + return XML_ERROR_NO_MEMORY; + } +#endif + + temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, + nsAttsSize * sizeof(NS_ATT)); + if (! temp) { + /* Restore actual size of memory in m_nsAtts */ + parser->m_nsAttsPower = oldNsAttsPower; + return XML_ERROR_NO_MEMORY; + } + parser->m_nsAtts = temp; + version = 0; /* force re-initialization of m_nsAtts hash table */ + } + /* using a version flag saves us from initializing m_nsAtts every time */ + if (! version) { /* initialize version flags when version wraps around */ + version = INIT_ATTS_VERSION; + for (j = nsAttsSize; j != 0;) + parser->m_nsAtts[--j].version = version; + } + parser->m_nsAttsVersion = --version; + + /* expand prefixed names and check for duplicates */ + for (; i < attIndex; i += 2) { + const XML_Char *s = appAtts[i]; + if (s[-1] == 2) { /* prefixed */ + ATTRIBUTE_ID *id; + const BINDING *b; + unsigned long uriHash; + struct siphash sip_state; + struct sipkey sip_key; + + copy_salt_to_sipkey(parser, &sip_key); + sip24_init(&sip_state, &sip_key); + + ((XML_Char *)s)[-1] = 0; /* clear flag */ + id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0); + if (! id || ! id->prefix) { + /* This code is walking through the appAtts array, dealing + * with (in this case) a prefixed attribute name. To be in + * the array, the attribute must have already been bound, so + * has to have passed through the hash table lookup once + * already. That implies that an entry for it already + * exists, so the lookup above will return a pointer to + * already allocated memory. There is no opportunaity for + * the allocator to fail, so the condition above cannot be + * fulfilled. + * + * Since it is difficult to be certain that the above + * analysis is complete, we retain the test and merely + * remove the code from coverage tests. + */ + return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ + } + b = id->prefix->binding; + if (! b) + return XML_ERROR_UNBOUND_PREFIX; + + for (j = 0; j < b->uriLen; j++) { + const XML_Char c = b->uri[j]; + if (! poolAppendChar(&parser->m_tempPool, c)) + return XML_ERROR_NO_MEMORY; + } + + sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char)); + + while (*s++ != XML_T(ASCII_COLON)) + ; + + sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char)); + + do { /* copies null terminator */ + if (! poolAppendChar(&parser->m_tempPool, *s)) + return XML_ERROR_NO_MEMORY; + } while (*s++); + + uriHash = (unsigned long)sip24_final(&sip_state); + + { /* Check hash table for duplicate of expanded name (uriName). + Derived from code in lookup(parser, HASH_TABLE *table, ...). + */ + unsigned char step = 0; + unsigned long mask = nsAttsSize - 1; + j = uriHash & mask; /* index into hash table */ + while (parser->m_nsAtts[j].version == version) { + /* for speed we compare stored hash values first */ + if (uriHash == parser->m_nsAtts[j].hash) { + const XML_Char *s1 = poolStart(&parser->m_tempPool); + const XML_Char *s2 = parser->m_nsAtts[j].uriName; + /* s1 is null terminated, but not s2 */ + for (; *s1 == *s2 && *s1 != 0; s1++, s2++) + ; + if (*s1 == 0) + return XML_ERROR_DUPLICATE_ATTRIBUTE; + } + if (! step) + step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower); + j < step ? (j += nsAttsSize - step) : (j -= step); + } + } + + if (parser->m_ns_triplets) { /* append namespace separator and prefix */ + parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator; + s = b->prefix->name; + do { + if (! poolAppendChar(&parser->m_tempPool, *s)) + return XML_ERROR_NO_MEMORY; + } while (*s++); + } + + /* store expanded name in attribute list */ + s = poolStart(&parser->m_tempPool); + poolFinish(&parser->m_tempPool); + appAtts[i] = s; + + /* fill empty slot with new version, uriName and hash value */ + parser->m_nsAtts[j].version = version; + parser->m_nsAtts[j].hash = uriHash; + parser->m_nsAtts[j].uriName = s; + + if (! --nPrefixes) { + i += 2; + break; + } + } else /* not prefixed */ + ((XML_Char *)s)[-1] = 0; /* clear flag */ + } + } + /* clear flags for the remaining attributes */ + for (; i < attIndex; i += 2) + ((XML_Char *)(appAtts[i]))[-1] = 0; + for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) + binding->attId->name[-1] = 0; + + if (! parser->m_ns) + return XML_ERROR_NONE; + + /* expand the element type name */ + if (elementType->prefix) { + binding = elementType->prefix->binding; + if (! binding) + return XML_ERROR_UNBOUND_PREFIX; + localPart = tagNamePtr->str; + while (*localPart++ != XML_T(ASCII_COLON)) + ; + } else if (dtd->defaultPrefix.binding) { + binding = dtd->defaultPrefix.binding; + localPart = tagNamePtr->str; + } else + return XML_ERROR_NONE; + prefixLen = 0; + if (parser->m_ns_triplets && binding->prefix->name) { + for (; binding->prefix->name[prefixLen++];) + ; /* prefixLen includes null terminator */ + } + tagNamePtr->localPart = localPart; + tagNamePtr->uriLen = binding->uriLen; + tagNamePtr->prefix = binding->prefix->name; + tagNamePtr->prefixLen = prefixLen; + for (i = 0; localPart[i++];) + ; /* i includes null terminator */ + + /* Detect and prevent integer overflow */ + if (binding->uriLen > INT_MAX - prefixLen + || i > INT_MAX - (binding->uriLen + prefixLen)) { + return XML_ERROR_NO_MEMORY; + } + + n = i + binding->uriLen + prefixLen; + if (n > binding->uriAlloc) { + TAG *p; + + /* Detect and prevent integer overflow */ + if (n > INT_MAX - EXPAND_SPARE) { + return XML_ERROR_NO_MEMORY; + } + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { + return XML_ERROR_NO_MEMORY; + } +#endif + + uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char)); + if (! uri) + return XML_ERROR_NO_MEMORY; + binding->uriAlloc = n + EXPAND_SPARE; + memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); + for (p = parser->m_tagStack; p; p = p->parent) + if (p->name.str == binding->uri) + p->name.str = uri; + FREE(parser, binding->uri); + binding->uri = uri; + } + /* if m_namespaceSeparator != '\0' then uri includes it already */ + uri = binding->uri + binding->uriLen; + memcpy(uri, localPart, i * sizeof(XML_Char)); + /* we always have a namespace separator between localPart and prefix */ + if (prefixLen) { + uri += i - 1; + *uri = parser->m_namespaceSeparator; /* replace null terminator */ + memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char)); + } + tagNamePtr->str = binding->uri; + return XML_ERROR_NONE; +} + +static XML_Bool +is_rfc3986_uri_char(XML_Char candidate) { + // For the RFC 3986 ANBF grammar see + // https://datatracker.ietf.org/doc/html/rfc3986#appendix-A + + switch (candidate) { + // From rule "ALPHA" (uppercase half) + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + + // From rule "ALPHA" (lowercase half) + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + + // From rule "DIGIT" + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + + // From rule "pct-encoded" + case '%': + + // From rule "unreserved" + case '-': + case '.': + case '_': + case '~': + + // From rule "gen-delims" + case ':': + case '/': + case '?': + case '#': + case '[': + case ']': + case '@': + + // From rule "sub-delims" + case '!': + case '$': + case '&': + case '\'': + case '(': + case ')': + case '*': + case '+': + case ',': + case ';': + case '=': + return XML_TRUE; + + default: + return XML_FALSE; + } +} + +/* addBinding() overwrites the value of prefix->binding without checking. + Therefore one must keep track of the old value outside of addBinding(). +*/ +static enum XML_Error +addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, + const XML_Char *uri, BINDING **bindingsPtr) { + // "http://www.w3.org/XML/1998/namespace" + static const XML_Char xmlNamespace[] + = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, + ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, + ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, + ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, + ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, + ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, + ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, + ASCII_e, '\0'}; + static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1; + // "http://www.w3.org/2000/xmlns/" + static const XML_Char xmlnsNamespace[] + = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, + ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, + ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, + ASCII_2, ASCII_0, ASCII_0, ASCII_0, ASCII_SLASH, ASCII_x, + ASCII_m, ASCII_l, ASCII_n, ASCII_s, ASCII_SLASH, '\0'}; + static const int xmlnsLen + = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1; + + XML_Bool mustBeXML = XML_FALSE; + XML_Bool isXML = XML_TRUE; + XML_Bool isXMLNS = XML_TRUE; + + BINDING *b; + int len; + + /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */ + if (*uri == XML_T('\0') && prefix->name) + return XML_ERROR_UNDECLARING_PREFIX; + + if (prefix->name && prefix->name[0] == XML_T(ASCII_x) + && prefix->name[1] == XML_T(ASCII_m) + && prefix->name[2] == XML_T(ASCII_l)) { + /* Not allowed to bind xmlns */ + if (prefix->name[3] == XML_T(ASCII_n) && prefix->name[4] == XML_T(ASCII_s) + && prefix->name[5] == XML_T('\0')) + return XML_ERROR_RESERVED_PREFIX_XMLNS; + + if (prefix->name[3] == XML_T('\0')) + mustBeXML = XML_TRUE; + } + + for (len = 0; uri[len]; len++) { + if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len])) + isXML = XML_FALSE; + + if (! mustBeXML && isXMLNS + && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) + isXMLNS = XML_FALSE; + + // NOTE: While Expat does not validate namespace URIs against RFC 3986 + // today (and is not REQUIRED to do so with regard to the XML 1.0 + // namespaces specification) we have to at least make sure, that + // the application on top of Expat (that is likely splitting expanded + // element names ("qualified names") of form + // "[uri sep] local [sep prefix] '\0'" back into 1, 2 or 3 pieces + // in its element handler code) cannot be confused by an attacker + // putting additional namespace separator characters into namespace + // declarations. That would be ambiguous and not to be expected. + // + // While the HTML API docs of function XML_ParserCreateNS have been + // advising against use of a namespace separator character that can + // appear in a URI for >20 years now, some widespread applications + // are using URI characters (':' (colon) in particular) for a + // namespace separator, in practice. To keep these applications + // functional, we only reject namespaces URIs containing the + // application-chosen namespace separator if the chosen separator + // is a non-URI character with regard to RFC 3986. + if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator) + && ! is_rfc3986_uri_char(uri[len])) { + return XML_ERROR_SYNTAX; + } + } + isXML = isXML && len == xmlLen; + isXMLNS = isXMLNS && len == xmlnsLen; + + if (mustBeXML != isXML) + return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML + : XML_ERROR_RESERVED_NAMESPACE_URI; + + if (isXMLNS) + return XML_ERROR_RESERVED_NAMESPACE_URI; + + if (parser->m_namespaceSeparator) + len++; + if (parser->m_freeBindingList) { + b = parser->m_freeBindingList; + if (len > b->uriAlloc) { + /* Detect and prevent integer overflow */ + if (len > INT_MAX - EXPAND_SPARE) { + return XML_ERROR_NO_MEMORY; + } + + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { + return XML_ERROR_NO_MEMORY; + } +#endif + + XML_Char *temp = (XML_Char *)REALLOC( + parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE)); + if (temp == NULL) + return XML_ERROR_NO_MEMORY; + b->uri = temp; + b->uriAlloc = len + EXPAND_SPARE; + } + parser->m_freeBindingList = b->nextTagBinding; + } else { + b = (BINDING *)MALLOC(parser, sizeof(BINDING)); + if (! b) + return XML_ERROR_NO_MEMORY; + + /* Detect and prevent integer overflow */ + if (len > INT_MAX - EXPAND_SPARE) { + return XML_ERROR_NO_MEMORY; + } + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { + return XML_ERROR_NO_MEMORY; + } +#endif + + b->uri + = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE)); + if (! b->uri) { + FREE(parser, b); + return XML_ERROR_NO_MEMORY; + } + b->uriAlloc = len + EXPAND_SPARE; + } + b->uriLen = len; + memcpy(b->uri, uri, len * sizeof(XML_Char)); + if (parser->m_namespaceSeparator) + b->uri[len - 1] = parser->m_namespaceSeparator; + b->prefix = prefix; + b->attId = attId; + b->prevPrefixBinding = prefix->binding; + /* NULL binding when default namespace undeclared */ + if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix) + prefix->binding = NULL; + else + prefix->binding = b; + b->nextTagBinding = *bindingsPtr; + *bindingsPtr = b; + /* if attId == NULL then we are not starting a namespace scope */ + if (attId && parser->m_startNamespaceDeclHandler) + parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name, + prefix->binding ? uri : 0); + return XML_ERROR_NONE; +} + +/* The idea here is to avoid using stack for each CDATA section when + the whole file is parsed with one call. +*/ +static enum XML_Error PTRCALL +cdataSectionProcessor(XML_Parser parser, const char *start, const char *end, + const char **endPtr) { + enum XML_Error result = doCdataSection( + parser, parser->m_encoding, &start, end, endPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT); + if (result != XML_ERROR_NONE) + return result; + if (start) { + if (parser->m_parentParser) { /* we are parsing an external entity */ + parser->m_processor = externalEntityContentProcessor; + return externalEntityContentProcessor(parser, start, end, endPtr); + } else { + parser->m_processor = contentProcessor; + return contentProcessor(parser, start, end, endPtr); + } + } + return result; +} + +/* startPtr gets set to non-null if the section is closed, and to null if + the section is not yet closed. +*/ +static enum XML_Error +doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, + const char *end, const char **nextPtr, XML_Bool haveMore, + enum XML_Account account) { + const char *s = *startPtr; + const char **eventPP; + const char **eventEndPP; + if (enc == parser->m_encoding) { + eventPP = &parser->m_eventPtr; + *eventPP = s; + eventEndPP = &parser->m_eventEndPtr; + } else { + eventPP = &(parser->m_openInternalEntities->internalEventPtr); + eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); + } + *eventPP = s; + *startPtr = NULL; + + for (;;) { + const char *next = s; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */ + int tok = XmlCdataSectionTok(enc, s, end, &next); +#if XML_GE == 1 + if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) { + accountingOnAbort(parser); + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; + } +#else + UNUSED_P(account); +#endif + *eventEndPP = next; + switch (tok) { + case XML_TOK_CDATA_SECT_CLOSE: + if (parser->m_endCdataSectionHandler) + parser->m_endCdataSectionHandler(parser->m_handlerArg); + /* BEGIN disabled code */ + /* see comment under XML_TOK_CDATA_SECT_OPEN */ + else if ((0) && parser->m_characterDataHandler) + parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, + 0); + /* END disabled code */ + else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + *startPtr = next; + *nextPtr = next; + if (parser->m_parsingStatus.parsing == XML_FINISHED) + return XML_ERROR_ABORTED; + else + return XML_ERROR_NONE; + case XML_TOK_DATA_NEWLINE: + if (parser->m_characterDataHandler) { + XML_Char c = 0xA; + parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); + } else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + break; + case XML_TOK_DATA_CHARS: { + XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; + if (charDataHandler) { + if (MUST_CONVERT(enc, s)) { + for (;;) { + ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; + const enum XML_Convert_Result convert_res = XmlConvert( + enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); + *eventEndPP = next; + charDataHandler(parser->m_handlerArg, parser->m_dataBuf, + (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); + if ((convert_res == XML_CONVERT_COMPLETED) + || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) + break; + *eventPP = s; + } + } else + charDataHandler(parser->m_handlerArg, (const XML_Char *)s, + (int)((const XML_Char *)next - (const XML_Char *)s)); + } else if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + } break; + case XML_TOK_INVALID: + *eventPP = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (haveMore) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_PARTIAL: + case XML_TOK_NONE: + if (haveMore) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_UNCLOSED_CDATA_SECTION; + default: + /* Every token returned by XmlCdataSectionTok() has its own + * explicit case, so this default case will never be executed. + * We retain it as a safety net and exclude it from the coverage + * statistics. + * + * LCOV_EXCL_START + */ + *eventPP = next; + return XML_ERROR_UNEXPECTED_STATE; + /* LCOV_EXCL_STOP */ + } + + *eventPP = s = next; + switch (parser->m_parsingStatus.parsing) { + case XML_SUSPENDED: + *nextPtr = next; + return XML_ERROR_NONE; + case XML_FINISHED: + return XML_ERROR_ABORTED; + default:; + } + } + /* not reached */ +} + +#ifdef XML_DTD + +/* The idea here is to avoid using stack for each IGNORE section when + the whole file is parsed with one call. +*/ +static enum XML_Error PTRCALL +ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end, + const char **endPtr) { + enum XML_Error result + = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer); + if (result != XML_ERROR_NONE) + return result; + if (start) { + parser->m_processor = prologProcessor; + return prologProcessor(parser, start, end, endPtr); + } + return result; +} + +/* startPtr gets set to non-null is the section is closed, and to null + if the section is not yet closed. +*/ +static enum XML_Error +doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, + const char *end, const char **nextPtr, XML_Bool haveMore) { + const char *next = *startPtr; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */ + int tok; + const char *s = *startPtr; + const char **eventPP; + const char **eventEndPP; + if (enc == parser->m_encoding) { + eventPP = &parser->m_eventPtr; + *eventPP = s; + eventEndPP = &parser->m_eventEndPtr; + } else { + /* It's not entirely clear, but it seems the following two lines + * of code cannot be executed. The only occasions on which 'enc' + * is not 'encoding' are when this function is called + * from the internal entity processing, and IGNORE sections are an + * error in internal entities. + * + * Since it really isn't clear that this is true, we keep the code + * and just remove it from our coverage tests. + * + * LCOV_EXCL_START + */ + eventPP = &(parser->m_openInternalEntities->internalEventPtr); + eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); + /* LCOV_EXCL_STOP */ + } + *eventPP = s; + *startPtr = NULL; + tok = XmlIgnoreSectionTok(enc, s, end, &next); +# if XML_GE == 1 + if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, + XML_ACCOUNT_DIRECT)) { + accountingOnAbort(parser); + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; + } +# endif + *eventEndPP = next; + switch (tok) { + case XML_TOK_IGNORE_SECT: + if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + *startPtr = next; + *nextPtr = next; + if (parser->m_parsingStatus.parsing == XML_FINISHED) + return XML_ERROR_ABORTED; + else + return XML_ERROR_NONE; + case XML_TOK_INVALID: + *eventPP = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (haveMore) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_PARTIAL: + case XML_TOK_NONE: + if (haveMore) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ + default: + /* All of the tokens that XmlIgnoreSectionTok() returns have + * explicit cases to handle them, so this default case is never + * executed. We keep it as a safety net anyway, and remove it + * from our test coverage statistics. + * + * LCOV_EXCL_START + */ + *eventPP = next; + return XML_ERROR_UNEXPECTED_STATE; + /* LCOV_EXCL_STOP */ + } + /* not reached */ +} + +#endif /* XML_DTD */ + +static enum XML_Error +initializeEncoding(XML_Parser parser) { + const char *s; +#ifdef XML_UNICODE + char encodingBuf[128]; + /* See comments about `protocolEncodingName` in parserInit() */ + if (! parser->m_protocolEncodingName) + s = NULL; + else { + int i; + for (i = 0; parser->m_protocolEncodingName[i]; i++) { + if (i == sizeof(encodingBuf) - 1 + || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) { + encodingBuf[0] = '\0'; + break; + } + encodingBuf[i] = (char)parser->m_protocolEncodingName[i]; + } + encodingBuf[i] = '\0'; + s = encodingBuf; + } +#else + s = parser->m_protocolEncodingName; +#endif + if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)( + &parser->m_initEncoding, &parser->m_encoding, s)) + return XML_ERROR_NONE; + return handleUnknownEncoding(parser, parser->m_protocolEncodingName); +} + +static enum XML_Error +processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s, + const char *next) { + const char *encodingName = NULL; + const XML_Char *storedEncName = NULL; + const ENCODING *newEncoding = NULL; + const char *version = NULL; + const char *versionend = NULL; + const XML_Char *storedversion = NULL; + int standalone = -1; + +#if XML_GE == 1 + if (! accountingDiffTolerated(parser, XML_TOK_XML_DECL, s, next, __LINE__, + XML_ACCOUNT_DIRECT)) { + accountingOnAbort(parser); + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; + } +#endif + + if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)( + isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr, + &version, &versionend, &encodingName, &newEncoding, &standalone)) { + if (isGeneralTextEntity) + return XML_ERROR_TEXT_DECL; + else + return XML_ERROR_XML_DECL; + } + if (! isGeneralTextEntity && standalone == 1) { + parser->m_dtd->standalone = XML_TRUE; +#ifdef XML_DTD + if (parser->m_paramEntityParsing + == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) + parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; +#endif /* XML_DTD */ + } + if (parser->m_xmlDeclHandler) { + if (encodingName != NULL) { + storedEncName = poolStoreString( + &parser->m_temp2Pool, parser->m_encoding, encodingName, + encodingName + XmlNameLength(parser->m_encoding, encodingName)); + if (! storedEncName) + return XML_ERROR_NO_MEMORY; + poolFinish(&parser->m_temp2Pool); + } + if (version) { + storedversion + = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version, + versionend - parser->m_encoding->minBytesPerChar); + if (! storedversion) + return XML_ERROR_NO_MEMORY; + } + parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName, + standalone); + } else if (parser->m_defaultHandler) + reportDefault(parser, parser->m_encoding, s, next); + if (parser->m_protocolEncodingName == NULL) { + if (newEncoding) { + /* Check that the specified encoding does not conflict with what + * the parser has already deduced. Do we have the same number + * of bytes in the smallest representation of a character? If + * this is UTF-16, is it the same endianness? + */ + if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar + || (newEncoding->minBytesPerChar == 2 + && newEncoding != parser->m_encoding)) { + parser->m_eventPtr = encodingName; + return XML_ERROR_INCORRECT_ENCODING; + } + parser->m_encoding = newEncoding; + } else if (encodingName) { + enum XML_Error result; + if (! storedEncName) { + storedEncName = poolStoreString( + &parser->m_temp2Pool, parser->m_encoding, encodingName, + encodingName + XmlNameLength(parser->m_encoding, encodingName)); + if (! storedEncName) + return XML_ERROR_NO_MEMORY; + } + result = handleUnknownEncoding(parser, storedEncName); + poolClear(&parser->m_temp2Pool); + if (result == XML_ERROR_UNKNOWN_ENCODING) + parser->m_eventPtr = encodingName; + return result; + } + } + + if (storedEncName || storedversion) + poolClear(&parser->m_temp2Pool); + + return XML_ERROR_NONE; +} + +static enum XML_Error +handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) { + if (parser->m_unknownEncodingHandler) { + XML_Encoding info; + int i; + for (i = 0; i < 256; i++) + info.map[i] = -1; + info.convert = NULL; + info.data = NULL; + info.release = NULL; + if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData, + encodingName, &info)) { + ENCODING *enc; + parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding()); + if (! parser->m_unknownEncodingMem) { + if (info.release) + info.release(info.data); + return XML_ERROR_NO_MEMORY; + } + enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)( + parser->m_unknownEncodingMem, info.map, info.convert, info.data); + if (enc) { + parser->m_unknownEncodingData = info.data; + parser->m_unknownEncodingRelease = info.release; + parser->m_encoding = enc; + return XML_ERROR_NONE; + } + } + if (info.release != NULL) + info.release(info.data); + } + return XML_ERROR_UNKNOWN_ENCODING; +} + +static enum XML_Error PTRCALL +prologInitProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { + enum XML_Error result = initializeEncoding(parser); + if (result != XML_ERROR_NONE) + return result; + parser->m_processor = prologProcessor; + return prologProcessor(parser, s, end, nextPtr); +} + +#ifdef XML_DTD + +static enum XML_Error PTRCALL +externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { + enum XML_Error result = initializeEncoding(parser); + if (result != XML_ERROR_NONE) + return result; + + /* we know now that XML_Parse(Buffer) has been called, + so we consider the external parameter entity read */ + parser->m_dtd->paramEntityRead = XML_TRUE; + + if (parser->m_prologState.inEntityValue) { + parser->m_processor = entityValueInitProcessor; + return entityValueInitProcessor(parser, s, end, nextPtr); + } else { + parser->m_processor = externalParEntProcessor; + return externalParEntProcessor(parser, s, end, nextPtr); + } +} + +static enum XML_Error PTRCALL +entityValueInitProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { + int tok; + const char *start = s; + const char *next = start; + parser->m_eventPtr = start; + + for (;;) { + tok = XmlPrologTok(parser->m_encoding, start, end, &next); + /* Note: Except for XML_TOK_BOM below, these bytes are accounted later in: + - storeEntityValue + - processXmlDecl + */ + parser->m_eventEndPtr = next; + if (tok <= 0) { + if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { + *nextPtr = s; + return XML_ERROR_NONE; + } + switch (tok) { + case XML_TOK_INVALID: + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_NONE: /* start == end */ + default: + break; + } + /* found end of entity value - can store it now */ + return storeEntityValue(parser, parser->m_encoding, s, end, + XML_ACCOUNT_DIRECT); + } else if (tok == XML_TOK_XML_DECL) { + enum XML_Error result; + result = processXmlDecl(parser, 0, start, next); + if (result != XML_ERROR_NONE) + return result; + /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For + * that to happen, a parameter entity parsing handler must have attempted + * to suspend the parser, which fails and raises an error. The parser can + * be aborted, but can't be suspended. + */ + if (parser->m_parsingStatus.parsing == XML_FINISHED) + return XML_ERROR_ABORTED; + *nextPtr = next; + /* stop scanning for text declaration - we found one */ + parser->m_processor = entityValueProcessor; + return entityValueProcessor(parser, next, end, nextPtr); + } + /* XmlPrologTok has now set the encoding based on the BOM it found, and we + must move s and nextPtr forward to consume the BOM. + + If we didn't, and got XML_TOK_NONE from the next XmlPrologTok call, we + would leave the BOM in the buffer and return. On the next call to this + function, our XmlPrologTok call would return XML_TOK_INVALID, since it + is not valid to have multiple BOMs. + */ + else if (tok == XML_TOK_BOM) { +# if XML_GE == 1 + if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, + XML_ACCOUNT_DIRECT)) { + accountingOnAbort(parser); + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; + } +# endif + + *nextPtr = next; + s = next; + } + /* If we get this token, we have the start of what might be a + normal tag, but not a declaration (i.e. it doesn't begin with + "m_eventPtr = start; + } +} + +static enum XML_Error PTRCALL +externalParEntProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { + const char *next = s; + int tok; + + tok = XmlPrologTok(parser->m_encoding, s, end, &next); + if (tok <= 0) { + if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { + *nextPtr = s; + return XML_ERROR_NONE; + } + switch (tok) { + case XML_TOK_INVALID: + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_NONE: /* start == end */ + default: + break; + } + } + /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. + However, when parsing an external subset, doProlog will not accept a BOM + as valid, and report a syntax error, so we have to skip the BOM, and + account for the BOM bytes. + */ + else if (tok == XML_TOK_BOM) { + if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, + XML_ACCOUNT_DIRECT)) { + accountingOnAbort(parser); + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; + } + + s = next; + tok = XmlPrologTok(parser->m_encoding, s, end, &next); + } + + parser->m_processor = prologProcessor; + return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, + XML_ACCOUNT_DIRECT); +} + +static enum XML_Error PTRCALL +entityValueProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { + const char *start = s; + const char *next = s; + const ENCODING *enc = parser->m_encoding; + int tok; + + for (;;) { + tok = XmlPrologTok(enc, start, end, &next); + /* Note: These bytes are accounted later in: + - storeEntityValue + */ + if (tok <= 0) { + if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { + *nextPtr = s; + return XML_ERROR_NONE; + } + switch (tok) { + case XML_TOK_INVALID: + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_NONE: /* start == end */ + default: + break; + } + /* found end of entity value - can store it now */ + return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT); + } + start = next; + } +} + +#endif /* XML_DTD */ + +static enum XML_Error PTRCALL +prologProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { + const char *next = s; + int tok = XmlPrologTok(parser->m_encoding, s, end, &next); + return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, + XML_ACCOUNT_DIRECT); +} + +static enum XML_Error +doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, + int tok, const char *next, const char **nextPtr, XML_Bool haveMore, + XML_Bool allowClosingDoctype, enum XML_Account account) { +#ifdef XML_DTD + static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'}; +#endif /* XML_DTD */ + static const XML_Char atypeCDATA[] + = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; + static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'}; + static const XML_Char atypeIDREF[] + = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'}; + static const XML_Char atypeIDREFS[] + = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'}; + static const XML_Char atypeENTITY[] + = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'}; + static const XML_Char atypeENTITIES[] + = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, + ASCII_I, ASCII_E, ASCII_S, '\0'}; + static const XML_Char atypeNMTOKEN[] + = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'}; + static const XML_Char atypeNMTOKENS[] + = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, + ASCII_E, ASCII_N, ASCII_S, '\0'}; + static const XML_Char notationPrefix[] + = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, + ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'}; + static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'}; + static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'}; + +#ifndef XML_DTD + UNUSED_P(account); +#endif + + /* save one level of indirection */ + DTD *const dtd = parser->m_dtd; + + const char **eventPP; + const char **eventEndPP; + enum XML_Content_Quant quant; + + if (enc == parser->m_encoding) { + eventPP = &parser->m_eventPtr; + eventEndPP = &parser->m_eventEndPtr; + } else { + eventPP = &(parser->m_openInternalEntities->internalEventPtr); + eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); + } + + for (;;) { + int role; + XML_Bool handleDefault = XML_TRUE; + *eventPP = s; + *eventEndPP = next; + if (tok <= 0) { + if (haveMore && tok != XML_TOK_INVALID) { + *nextPtr = s; + return XML_ERROR_NONE; + } + switch (tok) { + case XML_TOK_INVALID: + *eventPP = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + return XML_ERROR_PARTIAL_CHAR; + case -XML_TOK_PROLOG_S: + tok = -tok; + break; + case XML_TOK_NONE: +#ifdef XML_DTD + /* for internal PE NOT referenced between declarations */ + if (enc != parser->m_encoding + && ! parser->m_openInternalEntities->betweenDecl) { + *nextPtr = s; + return XML_ERROR_NONE; + } + /* WFC: PE Between Declarations - must check that PE contains + complete markup, not only for external PEs, but also for + internal PEs if the reference occurs between declarations. + */ + if (parser->m_isParamEntity || enc != parser->m_encoding) { + if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc) + == XML_ROLE_ERROR) + return XML_ERROR_INCOMPLETE_PE; + *nextPtr = s; + return XML_ERROR_NONE; + } +#endif /* XML_DTD */ + return XML_ERROR_NO_ELEMENTS; + default: + tok = -tok; + next = end; + break; + } + } + role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc); +#if XML_GE == 1 + switch (role) { + case XML_ROLE_INSTANCE_START: // bytes accounted in contentProcessor + case XML_ROLE_XML_DECL: // bytes accounted in processXmlDecl +# ifdef XML_DTD + case XML_ROLE_TEXT_DECL: // bytes accounted in processXmlDecl +# endif + break; + default: + if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) { + accountingOnAbort(parser); + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; + } + } +#endif + switch (role) { + case XML_ROLE_XML_DECL: { + enum XML_Error result = processXmlDecl(parser, 0, s, next); + if (result != XML_ERROR_NONE) + return result; + enc = parser->m_encoding; + handleDefault = XML_FALSE; + } break; + case XML_ROLE_DOCTYPE_NAME: + if (parser->m_startDoctypeDeclHandler) { + parser->m_doctypeName + = poolStoreString(&parser->m_tempPool, enc, s, next); + if (! parser->m_doctypeName) + return XML_ERROR_NO_MEMORY; + poolFinish(&parser->m_tempPool); + parser->m_doctypePubid = NULL; + handleDefault = XML_FALSE; + } + parser->m_doctypeSysid = NULL; /* always initialize to NULL */ + break; + case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: + if (parser->m_startDoctypeDeclHandler) { + parser->m_startDoctypeDeclHandler( + parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, + parser->m_doctypePubid, 1); + parser->m_doctypeName = NULL; + poolClear(&parser->m_tempPool); + handleDefault = XML_FALSE; + } + break; +#ifdef XML_DTD + case XML_ROLE_TEXT_DECL: { + enum XML_Error result = processXmlDecl(parser, 1, s, next); + if (result != XML_ERROR_NONE) + return result; + enc = parser->m_encoding; + handleDefault = XML_FALSE; + } break; +#endif /* XML_DTD */ + case XML_ROLE_DOCTYPE_PUBLIC_ID: +#ifdef XML_DTD + parser->m_useForeignDTD = XML_FALSE; + parser->m_declEntity = (ENTITY *)lookup( + parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); + if (! parser->m_declEntity) + return XML_ERROR_NO_MEMORY; +#endif /* XML_DTD */ + dtd->hasParamEntityRefs = XML_TRUE; + if (parser->m_startDoctypeDeclHandler) { + XML_Char *pubId; + if (! XmlIsPublicId(enc, s, next, eventPP)) + return XML_ERROR_PUBLICID; + pubId = poolStoreString(&parser->m_tempPool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (! pubId) + return XML_ERROR_NO_MEMORY; + normalizePublicId(pubId); + poolFinish(&parser->m_tempPool); + parser->m_doctypePubid = pubId; + handleDefault = XML_FALSE; + goto alreadyChecked; + } + /* fall through */ + case XML_ROLE_ENTITY_PUBLIC_ID: + if (! XmlIsPublicId(enc, s, next, eventPP)) + return XML_ERROR_PUBLICID; + alreadyChecked: + if (dtd->keepProcessing && parser->m_declEntity) { + XML_Char *tem + = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (! tem) + return XML_ERROR_NO_MEMORY; + normalizePublicId(tem); + parser->m_declEntity->publicId = tem; + poolFinish(&dtd->pool); + /* Don't suppress the default handler if we fell through from + * the XML_ROLE_DOCTYPE_PUBLIC_ID case. + */ + if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID) + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_DOCTYPE_CLOSE: + if (allowClosingDoctype != XML_TRUE) { + /* Must not close doctype from within expanded parameter entities */ + return XML_ERROR_INVALID_TOKEN; + } + + if (parser->m_doctypeName) { + parser->m_startDoctypeDeclHandler( + parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, + parser->m_doctypePubid, 0); + poolClear(&parser->m_tempPool); + handleDefault = XML_FALSE; + } + /* parser->m_doctypeSysid will be non-NULL in the case of a previous + XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler + was not set, indicating an external subset + */ +#ifdef XML_DTD + if (parser->m_doctypeSysid || parser->m_useForeignDTD) { + XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; + dtd->hasParamEntityRefs = XML_TRUE; + if (parser->m_paramEntityParsing + && parser->m_externalEntityRefHandler) { + ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, + externalSubsetName, sizeof(ENTITY)); + if (! entity) { + /* The external subset name "#" will have already been + * inserted into the hash table at the start of the + * external entity parsing, so no allocation will happen + * and lookup() cannot fail. + */ + return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ + } + if (parser->m_useForeignDTD) + entity->base = parser->m_curBase; + dtd->paramEntityRead = XML_FALSE; + if (! parser->m_externalEntityRefHandler( + parser->m_externalEntityRefHandlerArg, 0, entity->base, + entity->systemId, entity->publicId)) + return XML_ERROR_EXTERNAL_ENTITY_HANDLING; + if (dtd->paramEntityRead) { + if (! dtd->standalone && parser->m_notStandaloneHandler + && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) + return XML_ERROR_NOT_STANDALONE; + } + /* if we didn't read the foreign DTD then this means that there + is no external subset and we must reset dtd->hasParamEntityRefs + */ + else if (! parser->m_doctypeSysid) + dtd->hasParamEntityRefs = hadParamEntityRefs; + /* end of DTD - no need to update dtd->keepProcessing */ + } + parser->m_useForeignDTD = XML_FALSE; + } +#endif /* XML_DTD */ + if (parser->m_endDoctypeDeclHandler) { + parser->m_endDoctypeDeclHandler(parser->m_handlerArg); + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_INSTANCE_START: +#ifdef XML_DTD + /* if there is no DOCTYPE declaration then now is the + last chance to read the foreign DTD + */ + if (parser->m_useForeignDTD) { + XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; + dtd->hasParamEntityRefs = XML_TRUE; + if (parser->m_paramEntityParsing + && parser->m_externalEntityRefHandler) { + ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, + externalSubsetName, sizeof(ENTITY)); + if (! entity) + return XML_ERROR_NO_MEMORY; + entity->base = parser->m_curBase; + dtd->paramEntityRead = XML_FALSE; + if (! parser->m_externalEntityRefHandler( + parser->m_externalEntityRefHandlerArg, 0, entity->base, + entity->systemId, entity->publicId)) + return XML_ERROR_EXTERNAL_ENTITY_HANDLING; + if (dtd->paramEntityRead) { + if (! dtd->standalone && parser->m_notStandaloneHandler + && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) + return XML_ERROR_NOT_STANDALONE; + } + /* if we didn't read the foreign DTD then this means that there + is no external subset and we must reset dtd->hasParamEntityRefs + */ + else + dtd->hasParamEntityRefs = hadParamEntityRefs; + /* end of DTD - no need to update dtd->keepProcessing */ + } + } +#endif /* XML_DTD */ + parser->m_processor = contentProcessor; + return contentProcessor(parser, s, end, nextPtr); + case XML_ROLE_ATTLIST_ELEMENT_NAME: + parser->m_declElementType = getElementType(parser, enc, s, next); + if (! parser->m_declElementType) + return XML_ERROR_NO_MEMORY; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_NAME: + parser->m_declAttributeId = getAttributeId(parser, enc, s, next); + if (! parser->m_declAttributeId) + return XML_ERROR_NO_MEMORY; + parser->m_declAttributeIsCdata = XML_FALSE; + parser->m_declAttributeType = NULL; + parser->m_declAttributeIsId = XML_FALSE; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_CDATA: + parser->m_declAttributeIsCdata = XML_TRUE; + parser->m_declAttributeType = atypeCDATA; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_ID: + parser->m_declAttributeIsId = XML_TRUE; + parser->m_declAttributeType = atypeID; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_IDREF: + parser->m_declAttributeType = atypeIDREF; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: + parser->m_declAttributeType = atypeIDREFS; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: + parser->m_declAttributeType = atypeENTITY; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: + parser->m_declAttributeType = atypeENTITIES; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: + parser->m_declAttributeType = atypeNMTOKEN; + goto checkAttListDeclHandler; + case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: + parser->m_declAttributeType = atypeNMTOKENS; + checkAttListDeclHandler: + if (dtd->keepProcessing && parser->m_attlistDeclHandler) + handleDefault = XML_FALSE; + break; + case XML_ROLE_ATTRIBUTE_ENUM_VALUE: + case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: + if (dtd->keepProcessing && parser->m_attlistDeclHandler) { + const XML_Char *prefix; + if (parser->m_declAttributeType) { + prefix = enumValueSep; + } else { + prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix + : enumValueStart); + } + if (! poolAppendString(&parser->m_tempPool, prefix)) + return XML_ERROR_NO_MEMORY; + if (! poolAppend(&parser->m_tempPool, enc, s, next)) + return XML_ERROR_NO_MEMORY; + parser->m_declAttributeType = parser->m_tempPool.start; + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: + case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: + if (dtd->keepProcessing) { + if (! defineAttribute(parser->m_declElementType, + parser->m_declAttributeId, + parser->m_declAttributeIsCdata, + parser->m_declAttributeIsId, 0, parser)) + return XML_ERROR_NO_MEMORY; + if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { + if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) + || (*parser->m_declAttributeType == XML_T(ASCII_N) + && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { + /* Enumerated or Notation type */ + if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) + || ! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) + return XML_ERROR_NO_MEMORY; + parser->m_declAttributeType = parser->m_tempPool.start; + poolFinish(&parser->m_tempPool); + } + *eventEndPP = s; + parser->m_attlistDeclHandler( + parser->m_handlerArg, parser->m_declElementType->name, + parser->m_declAttributeId->name, parser->m_declAttributeType, 0, + role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); + handleDefault = XML_FALSE; + } + } + poolClear(&parser->m_tempPool); + break; + case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: + case XML_ROLE_FIXED_ATTRIBUTE_VALUE: + if (dtd->keepProcessing) { + const XML_Char *attVal; + enum XML_Error result = storeAttributeValue( + parser, enc, parser->m_declAttributeIsCdata, + s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool, + XML_ACCOUNT_NONE); + if (result) + return result; + attVal = poolStart(&dtd->pool); + poolFinish(&dtd->pool); + /* ID attributes aren't allowed to have a default */ + if (! defineAttribute( + parser->m_declElementType, parser->m_declAttributeId, + parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser)) + return XML_ERROR_NO_MEMORY; + if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { + if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) + || (*parser->m_declAttributeType == XML_T(ASCII_N) + && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { + /* Enumerated or Notation type */ + if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) + || ! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) + return XML_ERROR_NO_MEMORY; + parser->m_declAttributeType = parser->m_tempPool.start; + poolFinish(&parser->m_tempPool); + } + *eventEndPP = s; + parser->m_attlistDeclHandler( + parser->m_handlerArg, parser->m_declElementType->name, + parser->m_declAttributeId->name, parser->m_declAttributeType, + attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); + poolClear(&parser->m_tempPool); + handleDefault = XML_FALSE; + } + } + break; + case XML_ROLE_ENTITY_VALUE: + if (dtd->keepProcessing) { +#if XML_GE == 1 + // This will store the given replacement text in + // parser->m_declEntity->textPtr. + enum XML_Error result + = storeEntityValue(parser, enc, s + enc->minBytesPerChar, + next - enc->minBytesPerChar, XML_ACCOUNT_NONE); + if (parser->m_declEntity) { + parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool); + parser->m_declEntity->textLen + = (int)(poolLength(&dtd->entityValuePool)); + poolFinish(&dtd->entityValuePool); + if (parser->m_entityDeclHandler) { + *eventEndPP = s; + parser->m_entityDeclHandler( + parser->m_handlerArg, parser->m_declEntity->name, + parser->m_declEntity->is_param, parser->m_declEntity->textPtr, + parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0); + handleDefault = XML_FALSE; + } + } else + poolDiscard(&dtd->entityValuePool); + if (result != XML_ERROR_NONE) + return result; +#else + // This will store "&entity123;" in parser->m_declEntity->textPtr + // to end up as "&entity123;" in the handler. + if (parser->m_declEntity != NULL) { + const enum XML_Error result + = storeSelfEntityValue(parser, parser->m_declEntity); + if (result != XML_ERROR_NONE) + return result; + + if (parser->m_entityDeclHandler) { + *eventEndPP = s; + parser->m_entityDeclHandler( + parser->m_handlerArg, parser->m_declEntity->name, + parser->m_declEntity->is_param, parser->m_declEntity->textPtr, + parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0); + handleDefault = XML_FALSE; + } + } +#endif + } + break; + case XML_ROLE_DOCTYPE_SYSTEM_ID: +#ifdef XML_DTD + parser->m_useForeignDTD = XML_FALSE; +#endif /* XML_DTD */ + dtd->hasParamEntityRefs = XML_TRUE; + if (parser->m_startDoctypeDeclHandler) { + parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (parser->m_doctypeSysid == NULL) + return XML_ERROR_NO_MEMORY; + poolFinish(&parser->m_tempPool); + handleDefault = XML_FALSE; + } +#ifdef XML_DTD + else + /* use externalSubsetName to make parser->m_doctypeSysid non-NULL + for the case where no parser->m_startDoctypeDeclHandler is set */ + parser->m_doctypeSysid = externalSubsetName; +#endif /* XML_DTD */ + if (! dtd->standalone +#ifdef XML_DTD + && ! parser->m_paramEntityParsing +#endif /* XML_DTD */ + && parser->m_notStandaloneHandler + && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) + return XML_ERROR_NOT_STANDALONE; +#ifndef XML_DTD + break; +#else /* XML_DTD */ + if (! parser->m_declEntity) { + parser->m_declEntity = (ENTITY *)lookup( + parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); + if (! parser->m_declEntity) + return XML_ERROR_NO_MEMORY; + parser->m_declEntity->publicId = NULL; + } +#endif /* XML_DTD */ + /* fall through */ + case XML_ROLE_ENTITY_SYSTEM_ID: + if (dtd->keepProcessing && parser->m_declEntity) { + parser->m_declEntity->systemId + = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (! parser->m_declEntity->systemId) + return XML_ERROR_NO_MEMORY; + parser->m_declEntity->base = parser->m_curBase; + poolFinish(&dtd->pool); + /* Don't suppress the default handler if we fell through from + * the XML_ROLE_DOCTYPE_SYSTEM_ID case. + */ + if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID) + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_ENTITY_COMPLETE: +#if XML_GE == 0 + // This will store "&entity123;" in entity->textPtr + // to end up as "&entity123;" in the handler. + if (parser->m_declEntity != NULL) { + const enum XML_Error result + = storeSelfEntityValue(parser, parser->m_declEntity); + if (result != XML_ERROR_NONE) + return result; + } +#endif + if (dtd->keepProcessing && parser->m_declEntity + && parser->m_entityDeclHandler) { + *eventEndPP = s; + parser->m_entityDeclHandler( + parser->m_handlerArg, parser->m_declEntity->name, + parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base, + parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0); + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_ENTITY_NOTATION_NAME: + if (dtd->keepProcessing && parser->m_declEntity) { + parser->m_declEntity->notation + = poolStoreString(&dtd->pool, enc, s, next); + if (! parser->m_declEntity->notation) + return XML_ERROR_NO_MEMORY; + poolFinish(&dtd->pool); + if (parser->m_unparsedEntityDeclHandler) { + *eventEndPP = s; + parser->m_unparsedEntityDeclHandler( + parser->m_handlerArg, parser->m_declEntity->name, + parser->m_declEntity->base, parser->m_declEntity->systemId, + parser->m_declEntity->publicId, parser->m_declEntity->notation); + handleDefault = XML_FALSE; + } else if (parser->m_entityDeclHandler) { + *eventEndPP = s; + parser->m_entityDeclHandler( + parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0, + parser->m_declEntity->base, parser->m_declEntity->systemId, + parser->m_declEntity->publicId, parser->m_declEntity->notation); + handleDefault = XML_FALSE; + } + } + break; + case XML_ROLE_GENERAL_ENTITY_NAME: { + if (XmlPredefinedEntityName(enc, s, next)) { + parser->m_declEntity = NULL; + break; + } + if (dtd->keepProcessing) { + const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); + if (! name) + return XML_ERROR_NO_MEMORY; + parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, + name, sizeof(ENTITY)); + if (! parser->m_declEntity) + return XML_ERROR_NO_MEMORY; + if (parser->m_declEntity->name != name) { + poolDiscard(&dtd->pool); + parser->m_declEntity = NULL; + } else { + poolFinish(&dtd->pool); + parser->m_declEntity->publicId = NULL; + parser->m_declEntity->is_param = XML_FALSE; + /* if we have a parent parser or are reading an internal parameter + entity, then the entity declaration is not considered "internal" + */ + parser->m_declEntity->is_internal + = ! (parser->m_parentParser || parser->m_openInternalEntities); + if (parser->m_entityDeclHandler) + handleDefault = XML_FALSE; + } + } else { + poolDiscard(&dtd->pool); + parser->m_declEntity = NULL; + } + } break; + case XML_ROLE_PARAM_ENTITY_NAME: +#ifdef XML_DTD + if (dtd->keepProcessing) { + const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); + if (! name) + return XML_ERROR_NO_MEMORY; + parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities, + name, sizeof(ENTITY)); + if (! parser->m_declEntity) + return XML_ERROR_NO_MEMORY; + if (parser->m_declEntity->name != name) { + poolDiscard(&dtd->pool); + parser->m_declEntity = NULL; + } else { + poolFinish(&dtd->pool); + parser->m_declEntity->publicId = NULL; + parser->m_declEntity->is_param = XML_TRUE; + /* if we have a parent parser or are reading an internal parameter + entity, then the entity declaration is not considered "internal" + */ + parser->m_declEntity->is_internal + = ! (parser->m_parentParser || parser->m_openInternalEntities); + if (parser->m_entityDeclHandler) + handleDefault = XML_FALSE; + } + } else { + poolDiscard(&dtd->pool); + parser->m_declEntity = NULL; + } +#else /* not XML_DTD */ + parser->m_declEntity = NULL; +#endif /* XML_DTD */ + break; + case XML_ROLE_NOTATION_NAME: + parser->m_declNotationPublicId = NULL; + parser->m_declNotationName = NULL; + if (parser->m_notationDeclHandler) { + parser->m_declNotationName + = poolStoreString(&parser->m_tempPool, enc, s, next); + if (! parser->m_declNotationName) + return XML_ERROR_NO_MEMORY; + poolFinish(&parser->m_tempPool); + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_NOTATION_PUBLIC_ID: + if (! XmlIsPublicId(enc, s, next, eventPP)) + return XML_ERROR_PUBLICID; + if (parser + ->m_declNotationName) { /* means m_notationDeclHandler != NULL */ + XML_Char *tem = poolStoreString(&parser->m_tempPool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (! tem) + return XML_ERROR_NO_MEMORY; + normalizePublicId(tem); + parser->m_declNotationPublicId = tem; + poolFinish(&parser->m_tempPool); + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_NOTATION_SYSTEM_ID: + if (parser->m_declNotationName && parser->m_notationDeclHandler) { + const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (! systemId) + return XML_ERROR_NO_MEMORY; + *eventEndPP = s; + parser->m_notationDeclHandler( + parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase, + systemId, parser->m_declNotationPublicId); + handleDefault = XML_FALSE; + } + poolClear(&parser->m_tempPool); + break; + case XML_ROLE_NOTATION_NO_SYSTEM_ID: + if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) { + *eventEndPP = s; + parser->m_notationDeclHandler( + parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase, + 0, parser->m_declNotationPublicId); + handleDefault = XML_FALSE; + } + poolClear(&parser->m_tempPool); + break; + case XML_ROLE_ERROR: + switch (tok) { + case XML_TOK_PARAM_ENTITY_REF: + /* PE references in internal subset are + not allowed within declarations. */ + return XML_ERROR_PARAM_ENTITY_REF; + case XML_TOK_XML_DECL: + return XML_ERROR_MISPLACED_XML_PI; + default: + return XML_ERROR_SYNTAX; + } +#ifdef XML_DTD + case XML_ROLE_IGNORE_SECT: { + enum XML_Error result; + if (parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + handleDefault = XML_FALSE; + result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); + if (result != XML_ERROR_NONE) + return result; + else if (! next) { + parser->m_processor = ignoreSectionProcessor; + return result; + } + } break; +#endif /* XML_DTD */ + case XML_ROLE_GROUP_OPEN: + if (parser->m_prologState.level >= parser->m_groupSize) { + if (parser->m_groupSize) { + { + /* Detect and prevent integer overflow */ + if (parser->m_groupSize > (unsigned int)(-1) / 2u) { + return XML_ERROR_NO_MEMORY; + } + + char *const new_connector = (char *)REALLOC( + parser, parser->m_groupConnector, parser->m_groupSize *= 2); + if (new_connector == NULL) { + parser->m_groupSize /= 2; + return XML_ERROR_NO_MEMORY; + } + parser->m_groupConnector = new_connector; + } + + if (dtd->scaffIndex) { + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if (parser->m_groupSize > (size_t)(-1) / sizeof(int)) { + return XML_ERROR_NO_MEMORY; + } +#endif + + int *const new_scaff_index = (int *)REALLOC( + parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int)); + if (new_scaff_index == NULL) + return XML_ERROR_NO_MEMORY; + dtd->scaffIndex = new_scaff_index; + } + } else { + parser->m_groupConnector + = (char *)MALLOC(parser, parser->m_groupSize = 32); + if (! parser->m_groupConnector) { + parser->m_groupSize = 0; + return XML_ERROR_NO_MEMORY; + } + } + } + parser->m_groupConnector[parser->m_prologState.level] = 0; + if (dtd->in_eldecl) { + int myindex = nextScaffoldPart(parser); + if (myindex < 0) + return XML_ERROR_NO_MEMORY; + assert(dtd->scaffIndex != NULL); + dtd->scaffIndex[dtd->scaffLevel] = myindex; + dtd->scaffLevel++; + dtd->scaffold[myindex].type = XML_CTYPE_SEQ; + if (parser->m_elementDeclHandler) + handleDefault = XML_FALSE; + } + break; + case XML_ROLE_GROUP_SEQUENCE: + if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE) + return XML_ERROR_SYNTAX; + parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA; + if (dtd->in_eldecl && parser->m_elementDeclHandler) + handleDefault = XML_FALSE; + break; + case XML_ROLE_GROUP_CHOICE: + if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA) + return XML_ERROR_SYNTAX; + if (dtd->in_eldecl + && ! parser->m_groupConnector[parser->m_prologState.level] + && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type + != XML_CTYPE_MIXED)) { + dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type + = XML_CTYPE_CHOICE; + if (parser->m_elementDeclHandler) + handleDefault = XML_FALSE; + } + parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE; + break; + case XML_ROLE_PARAM_ENTITY_REF: +#ifdef XML_DTD + case XML_ROLE_INNER_PARAM_ENTITY_REF: + dtd->hasParamEntityRefs = XML_TRUE; + if (! parser->m_paramEntityParsing) + dtd->keepProcessing = dtd->standalone; + else { + const XML_Char *name; + ENTITY *entity; + name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (! name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); + poolDiscard(&dtd->pool); + /* first, determine if a check for an existing declaration is needed; + if yes, check that the entity exists, and that it is internal, + otherwise call the skipped entity handler + */ + if (parser->m_prologState.documentEntity + && (dtd->standalone ? ! parser->m_openInternalEntities + : ! dtd->hasParamEntityRefs)) { + if (! entity) + return XML_ERROR_UNDEFINED_ENTITY; + else if (! entity->is_internal) { + /* It's hard to exhaustively search the code to be sure, + * but there doesn't seem to be a way of executing the + * following line. There are two cases: + * + * If 'standalone' is false, the DTD must have no + * parameter entities or we wouldn't have passed the outer + * 'if' statement. That means the only entity in the hash + * table is the external subset name "#" which cannot be + * given as a parameter entity name in XML syntax, so the + * lookup must have returned NULL and we don't even reach + * the test for an internal entity. + * + * If 'standalone' is true, it does not seem to be + * possible to create entities taking this code path that + * are not internal entities, so fail the test above. + * + * Because this analysis is very uncertain, the code is + * being left in place and merely removed from the + * coverage test statistics. + */ + return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */ + } + } else if (! entity) { + dtd->keepProcessing = dtd->standalone; + /* cannot report skipped entities in declarations */ + if ((role == XML_ROLE_PARAM_ENTITY_REF) + && parser->m_skippedEntityHandler) { + parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1); + handleDefault = XML_FALSE; + } + break; + } + if (entity->open) + return XML_ERROR_RECURSIVE_ENTITY_REF; + if (entity->textPtr) { + enum XML_Error result; + XML_Bool betweenDecl + = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); + result = processInternalEntity(parser, entity, betweenDecl); + if (result != XML_ERROR_NONE) + return result; + handleDefault = XML_FALSE; + break; + } + if (parser->m_externalEntityRefHandler) { + dtd->paramEntityRead = XML_FALSE; + entity->open = XML_TRUE; + entityTrackingOnOpen(parser, entity, __LINE__); + if (! parser->m_externalEntityRefHandler( + parser->m_externalEntityRefHandlerArg, 0, entity->base, + entity->systemId, entity->publicId)) { + entityTrackingOnClose(parser, entity, __LINE__); + entity->open = XML_FALSE; + return XML_ERROR_EXTERNAL_ENTITY_HANDLING; + } + entityTrackingOnClose(parser, entity, __LINE__); + entity->open = XML_FALSE; + handleDefault = XML_FALSE; + if (! dtd->paramEntityRead) { + dtd->keepProcessing = dtd->standalone; + break; + } + } else { + dtd->keepProcessing = dtd->standalone; + break; + } + } +#endif /* XML_DTD */ + if (! dtd->standalone && parser->m_notStandaloneHandler + && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) + return XML_ERROR_NOT_STANDALONE; + break; + + /* Element declaration stuff */ + + case XML_ROLE_ELEMENT_NAME: + if (parser->m_elementDeclHandler) { + parser->m_declElementType = getElementType(parser, enc, s, next); + if (! parser->m_declElementType) + return XML_ERROR_NO_MEMORY; + dtd->scaffLevel = 0; + dtd->scaffCount = 0; + dtd->in_eldecl = XML_TRUE; + handleDefault = XML_FALSE; + } + break; + + case XML_ROLE_CONTENT_ANY: + case XML_ROLE_CONTENT_EMPTY: + if (dtd->in_eldecl) { + if (parser->m_elementDeclHandler) { + XML_Content *content + = (XML_Content *)MALLOC(parser, sizeof(XML_Content)); + if (! content) + return XML_ERROR_NO_MEMORY; + content->quant = XML_CQUANT_NONE; + content->name = NULL; + content->numchildren = 0; + content->children = NULL; + content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY + : XML_CTYPE_EMPTY); + *eventEndPP = s; + parser->m_elementDeclHandler( + parser->m_handlerArg, parser->m_declElementType->name, content); + handleDefault = XML_FALSE; + } + dtd->in_eldecl = XML_FALSE; + } + break; + + case XML_ROLE_CONTENT_PCDATA: + if (dtd->in_eldecl) { + dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type + = XML_CTYPE_MIXED; + if (parser->m_elementDeclHandler) + handleDefault = XML_FALSE; + } + break; + + case XML_ROLE_CONTENT_ELEMENT: + quant = XML_CQUANT_NONE; + goto elementContent; + case XML_ROLE_CONTENT_ELEMENT_OPT: + quant = XML_CQUANT_OPT; + goto elementContent; + case XML_ROLE_CONTENT_ELEMENT_REP: + quant = XML_CQUANT_REP; + goto elementContent; + case XML_ROLE_CONTENT_ELEMENT_PLUS: + quant = XML_CQUANT_PLUS; + elementContent: + if (dtd->in_eldecl) { + ELEMENT_TYPE *el; + const XML_Char *name; + size_t nameLen; + const char *nxt + = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar); + int myindex = nextScaffoldPart(parser); + if (myindex < 0) + return XML_ERROR_NO_MEMORY; + dtd->scaffold[myindex].type = XML_CTYPE_NAME; + dtd->scaffold[myindex].quant = quant; + el = getElementType(parser, enc, s, nxt); + if (! el) + return XML_ERROR_NO_MEMORY; + name = el->name; + dtd->scaffold[myindex].name = name; + nameLen = 0; + for (; name[nameLen++];) + ; + + /* Detect and prevent integer overflow */ + if (nameLen > UINT_MAX - dtd->contentStringLen) { + return XML_ERROR_NO_MEMORY; + } + + dtd->contentStringLen += (unsigned)nameLen; + if (parser->m_elementDeclHandler) + handleDefault = XML_FALSE; + } + break; + + case XML_ROLE_GROUP_CLOSE: + quant = XML_CQUANT_NONE; + goto closeGroup; + case XML_ROLE_GROUP_CLOSE_OPT: + quant = XML_CQUANT_OPT; + goto closeGroup; + case XML_ROLE_GROUP_CLOSE_REP: + quant = XML_CQUANT_REP; + goto closeGroup; + case XML_ROLE_GROUP_CLOSE_PLUS: + quant = XML_CQUANT_PLUS; + closeGroup: + if (dtd->in_eldecl) { + if (parser->m_elementDeclHandler) + handleDefault = XML_FALSE; + dtd->scaffLevel--; + dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant; + if (dtd->scaffLevel == 0) { + if (! handleDefault) { + XML_Content *model = build_model(parser); + if (! model) + return XML_ERROR_NO_MEMORY; + *eventEndPP = s; + parser->m_elementDeclHandler( + parser->m_handlerArg, parser->m_declElementType->name, model); + } + dtd->in_eldecl = XML_FALSE; + dtd->contentStringLen = 0; + } + } + break; + /* End element declaration stuff */ + + case XML_ROLE_PI: + if (! reportProcessingInstruction(parser, enc, s, next)) + return XML_ERROR_NO_MEMORY; + handleDefault = XML_FALSE; + break; + case XML_ROLE_COMMENT: + if (! reportComment(parser, enc, s, next)) + return XML_ERROR_NO_MEMORY; + handleDefault = XML_FALSE; + break; + case XML_ROLE_NONE: + switch (tok) { + case XML_TOK_BOM: + handleDefault = XML_FALSE; + break; + } + break; + case XML_ROLE_DOCTYPE_NONE: + if (parser->m_startDoctypeDeclHandler) + handleDefault = XML_FALSE; + break; + case XML_ROLE_ENTITY_NONE: + if (dtd->keepProcessing && parser->m_entityDeclHandler) + handleDefault = XML_FALSE; + break; + case XML_ROLE_NOTATION_NONE: + if (parser->m_notationDeclHandler) + handleDefault = XML_FALSE; + break; + case XML_ROLE_ATTLIST_NONE: + if (dtd->keepProcessing && parser->m_attlistDeclHandler) + handleDefault = XML_FALSE; + break; + case XML_ROLE_ELEMENT_NONE: + if (parser->m_elementDeclHandler) + handleDefault = XML_FALSE; + break; + } /* end of big switch */ + + if (handleDefault && parser->m_defaultHandler) + reportDefault(parser, enc, s, next); + + switch (parser->m_parsingStatus.parsing) { + case XML_SUSPENDED: + *nextPtr = next; + return XML_ERROR_NONE; + case XML_FINISHED: + return XML_ERROR_ABORTED; + default: + s = next; + tok = XmlPrologTok(enc, s, end, &next); + } + } + /* not reached */ +} + +static enum XML_Error PTRCALL +epilogProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { + parser->m_processor = epilogProcessor; + parser->m_eventPtr = s; + for (;;) { + const char *next = NULL; + int tok = XmlPrologTok(parser->m_encoding, s, end, &next); +#if XML_GE == 1 + if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, + XML_ACCOUNT_DIRECT)) { + accountingOnAbort(parser); + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; + } +#endif + parser->m_eventEndPtr = next; + switch (tok) { + /* report partial linebreak - it might be the last token */ + case -XML_TOK_PROLOG_S: + if (parser->m_defaultHandler) { + reportDefault(parser, parser->m_encoding, s, next); + if (parser->m_parsingStatus.parsing == XML_FINISHED) + return XML_ERROR_ABORTED; + } + *nextPtr = next; + return XML_ERROR_NONE; + case XML_TOK_NONE: + *nextPtr = s; + return XML_ERROR_NONE; + case XML_TOK_PROLOG_S: + if (parser->m_defaultHandler) + reportDefault(parser, parser->m_encoding, s, next); + break; + case XML_TOK_PI: + if (! reportProcessingInstruction(parser, parser->m_encoding, s, next)) + return XML_ERROR_NO_MEMORY; + break; + case XML_TOK_COMMENT: + if (! reportComment(parser, parser->m_encoding, s, next)) + return XML_ERROR_NO_MEMORY; + break; + case XML_TOK_INVALID: + parser->m_eventPtr = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + if (! parser->m_parsingStatus.finalBuffer) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (! parser->m_parsingStatus.finalBuffer) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_PARTIAL_CHAR; + default: + return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; + } + parser->m_eventPtr = s = next; + switch (parser->m_parsingStatus.parsing) { + case XML_SUSPENDED: + *nextPtr = next; + return XML_ERROR_NONE; + case XML_FINISHED: + return XML_ERROR_ABORTED; + default:; + } + } +} + +static enum XML_Error +processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) { + const char *textStart, *textEnd; + const char *next; + enum XML_Error result; + OPEN_INTERNAL_ENTITY *openEntity; + + if (parser->m_freeInternalEntities) { + openEntity = parser->m_freeInternalEntities; + parser->m_freeInternalEntities = openEntity->next; + } else { + openEntity + = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY)); + if (! openEntity) + return XML_ERROR_NO_MEMORY; + } + entity->open = XML_TRUE; +#if XML_GE == 1 + entityTrackingOnOpen(parser, entity, __LINE__); +#endif + entity->processed = 0; + openEntity->next = parser->m_openInternalEntities; + parser->m_openInternalEntities = openEntity; + openEntity->entity = entity; + openEntity->startTagLevel = parser->m_tagLevel; + openEntity->betweenDecl = betweenDecl; + openEntity->internalEventPtr = NULL; + openEntity->internalEventEndPtr = NULL; + textStart = (const char *)entity->textPtr; + textEnd = (const char *)(entity->textPtr + entity->textLen); + /* Set a safe default value in case 'next' does not get set */ + next = textStart; + + if (entity->is_param) { + int tok + = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); + result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, + tok, next, &next, XML_FALSE, XML_FALSE, + XML_ACCOUNT_ENTITY_EXPANSION); + } else { + result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, + textStart, textEnd, &next, XML_FALSE, + XML_ACCOUNT_ENTITY_EXPANSION); + } + + if (result == XML_ERROR_NONE) { + if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { + entity->processed = (int)(next - textStart); + parser->m_processor = internalEntityProcessor; + } else if (parser->m_openInternalEntities->entity == entity) { +#if XML_GE == 1 + entityTrackingOnClose(parser, entity, __LINE__); +#endif /* XML_GE == 1 */ + entity->open = XML_FALSE; + parser->m_openInternalEntities = openEntity->next; + /* put openEntity back in list of free instances */ + openEntity->next = parser->m_freeInternalEntities; + parser->m_freeInternalEntities = openEntity; + } + } + return result; +} + +static enum XML_Error PTRCALL +internalEntityProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { + ENTITY *entity; + const char *textStart, *textEnd; + const char *next; + enum XML_Error result; + OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities; + if (! openEntity) + return XML_ERROR_UNEXPECTED_STATE; + + entity = openEntity->entity; + textStart = ((const char *)entity->textPtr) + entity->processed; + textEnd = (const char *)(entity->textPtr + entity->textLen); + /* Set a safe default value in case 'next' does not get set */ + next = textStart; + + if (entity->is_param) { + int tok + = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); + result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, + tok, next, &next, XML_FALSE, XML_TRUE, + XML_ACCOUNT_ENTITY_EXPANSION); + } else { + result = doContent(parser, openEntity->startTagLevel, + parser->m_internalEncoding, textStart, textEnd, &next, + XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION); + } + + if (result != XML_ERROR_NONE) + return result; + + if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { + entity->processed = (int)(next - (const char *)entity->textPtr); + return result; + } + +#if XML_GE == 1 + entityTrackingOnClose(parser, entity, __LINE__); +#endif + entity->open = XML_FALSE; + parser->m_openInternalEntities = openEntity->next; + /* put openEntity back in list of free instances */ + openEntity->next = parser->m_freeInternalEntities; + parser->m_freeInternalEntities = openEntity; + + // If there are more open entities we want to stop right here and have the + // upcoming call to XML_ResumeParser continue with entity content, or it would + // be ignored altogether. + if (parser->m_openInternalEntities != NULL + && parser->m_parsingStatus.parsing == XML_SUSPENDED) { + return XML_ERROR_NONE; + } + + if (entity->is_param) { + int tok; + parser->m_processor = prologProcessor; + tok = XmlPrologTok(parser->m_encoding, s, end, &next); + return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, + XML_ACCOUNT_DIRECT); + } else { + parser->m_processor = contentProcessor; + /* see externalEntityContentProcessor vs contentProcessor */ + result = doContent(parser, parser->m_parentParser ? 1 : 0, + parser->m_encoding, s, end, nextPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer, + XML_ACCOUNT_DIRECT); + if (result == XML_ERROR_NONE) { + if (! storeRawNames(parser)) + return XML_ERROR_NO_MEMORY; + } + return result; + } +} + +static enum XML_Error PTRCALL +errorProcessor(XML_Parser parser, const char *s, const char *end, + const char **nextPtr) { + UNUSED_P(s); + UNUSED_P(end); + UNUSED_P(nextPtr); + return parser->m_errorCode; +} + +static enum XML_Error +storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, + const char *ptr, const char *end, STRING_POOL *pool, + enum XML_Account account) { + enum XML_Error result + = appendAttributeValue(parser, enc, isCdata, ptr, end, pool, account); + if (result) + return result; + if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) + poolChop(pool); + if (! poolAppendChar(pool, XML_T('\0'))) + return XML_ERROR_NO_MEMORY; + return XML_ERROR_NONE; +} + +static enum XML_Error +appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, + const char *ptr, const char *end, STRING_POOL *pool, + enum XML_Account account) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ +#ifndef XML_DTD + UNUSED_P(account); +#endif + + for (;;) { + const char *next + = ptr; /* XmlAttributeValueTok doesn't always set the last arg */ + int tok = XmlAttributeValueTok(enc, ptr, end, &next); +#if XML_GE == 1 + if (! accountingDiffTolerated(parser, tok, ptr, next, __LINE__, account)) { + accountingOnAbort(parser); + return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; + } +#endif + switch (tok) { + case XML_TOK_NONE: + return XML_ERROR_NONE; + case XML_TOK_INVALID: + if (enc == parser->m_encoding) + parser->m_eventPtr = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + if (enc == parser->m_encoding) + parser->m_eventPtr = ptr; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_CHAR_REF: { + XML_Char buf[XML_ENCODE_MAX]; + int i; + int n = XmlCharRefNumber(enc, ptr); + if (n < 0) { + if (enc == parser->m_encoding) + parser->m_eventPtr = ptr; + return XML_ERROR_BAD_CHAR_REF; + } + if (! isCdata && n == 0x20 /* space */ + && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) + break; + n = XmlEncode(n, (ICHAR *)buf); + /* The XmlEncode() functions can never return 0 here. That + * error return happens if the code point passed in is either + * negative or greater than or equal to 0x110000. The + * XmlCharRefNumber() functions will all return a number + * strictly less than 0x110000 or a negative value if an error + * occurred. The negative value is intercepted above, so + * XmlEncode() is never passed a value it might return an + * error for. + */ + for (i = 0; i < n; i++) { + if (! poolAppendChar(pool, buf[i])) + return XML_ERROR_NO_MEMORY; + } + } break; + case XML_TOK_DATA_CHARS: + if (! poolAppend(pool, enc, ptr, next)) + return XML_ERROR_NO_MEMORY; + break; + case XML_TOK_TRAILING_CR: + next = ptr + enc->minBytesPerChar; + /* fall through */ + case XML_TOK_ATTRIBUTE_VALUE_S: + case XML_TOK_DATA_NEWLINE: + if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) + break; + if (! poolAppendChar(pool, 0x20)) + return XML_ERROR_NO_MEMORY; + break; + case XML_TOK_ENTITY_REF: { + const XML_Char *name; + ENTITY *entity; + char checkEntityDecl; + XML_Char ch = (XML_Char)XmlPredefinedEntityName( + enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar); + if (ch) { +#if XML_GE == 1 + /* NOTE: We are replacing 4-6 characters original input for 1 character + * so there is no amplification and hence recording without + * protection. */ + accountingDiffTolerated(parser, tok, (char *)&ch, + ((char *)&ch) + sizeof(XML_Char), __LINE__, + XML_ACCOUNT_ENTITY_EXPANSION); +#endif /* XML_GE == 1 */ + if (! poolAppendChar(pool, ch)) + return XML_ERROR_NO_MEMORY; + break; + } + name = poolStoreString(&parser->m_temp2Pool, enc, + ptr + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (! name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); + poolDiscard(&parser->m_temp2Pool); + /* First, determine if a check for an existing declaration is needed; + if yes, check that the entity exists, and that it is internal. + */ + if (pool == &dtd->pool) /* are we called from prolog? */ + checkEntityDecl = +#ifdef XML_DTD + parser->m_prologState.documentEntity && +#endif /* XML_DTD */ + (dtd->standalone ? ! parser->m_openInternalEntities + : ! dtd->hasParamEntityRefs); + else /* if (pool == &parser->m_tempPool): we are called from content */ + checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone; + if (checkEntityDecl) { + if (! entity) + return XML_ERROR_UNDEFINED_ENTITY; + else if (! entity->is_internal) + return XML_ERROR_ENTITY_DECLARED_IN_PE; + } else if (! entity) { + /* Cannot report skipped entity here - see comments on + parser->m_skippedEntityHandler. + if (parser->m_skippedEntityHandler) + parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); + */ + /* Cannot call the default handler because this would be + out of sync with the call to the startElementHandler. + if ((pool == &parser->m_tempPool) && parser->m_defaultHandler) + reportDefault(parser, enc, ptr, next); + */ + break; + } + if (entity->open) { + if (enc == parser->m_encoding) { + /* It does not appear that this line can be executed. + * + * The "if (entity->open)" check catches recursive entity + * definitions. In order to be called with an open + * entity, it must have gone through this code before and + * been through the recursive call to + * appendAttributeValue() some lines below. That call + * sets the local encoding ("enc") to the parser's + * internal encoding (internal_utf8 or internal_utf16), + * which can never be the same as the principle encoding. + * It doesn't appear there is another code path that gets + * here with entity->open being TRUE. + * + * Since it is not certain that this logic is watertight, + * we keep the line and merely exclude it from coverage + * tests. + */ + parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */ + } + return XML_ERROR_RECURSIVE_ENTITY_REF; + } + if (entity->notation) { + if (enc == parser->m_encoding) + parser->m_eventPtr = ptr; + return XML_ERROR_BINARY_ENTITY_REF; + } + if (! entity->textPtr) { + if (enc == parser->m_encoding) + parser->m_eventPtr = ptr; + return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; + } else { + enum XML_Error result; + const XML_Char *textEnd = entity->textPtr + entity->textLen; + entity->open = XML_TRUE; +#if XML_GE == 1 + entityTrackingOnOpen(parser, entity, __LINE__); +#endif + result = appendAttributeValue(parser, parser->m_internalEncoding, + isCdata, (const char *)entity->textPtr, + (const char *)textEnd, pool, + XML_ACCOUNT_ENTITY_EXPANSION); +#if XML_GE == 1 + entityTrackingOnClose(parser, entity, __LINE__); +#endif + entity->open = XML_FALSE; + if (result) + return result; + } + } break; + default: + /* The only token returned by XmlAttributeValueTok() that does + * not have an explicit case here is XML_TOK_PARTIAL_CHAR. + * Getting that would require an entity name to contain an + * incomplete XML character (e.g. \xE2\x82); however previous + * tokenisers will have already recognised and rejected such + * names before XmlAttributeValueTok() gets a look-in. This + * default case should be retained as a safety net, but the code + * excluded from coverage tests. + * + * LCOV_EXCL_START + */ + if (enc == parser->m_encoding) + parser->m_eventPtr = ptr; + return XML_ERROR_UNEXPECTED_STATE; + /* LCOV_EXCL_STOP */ + } + ptr = next; + } + /* not reached */ +} + +#if XML_GE == 1 +static enum XML_Error +storeEntityValue(XML_Parser parser, const ENCODING *enc, + const char *entityTextPtr, const char *entityTextEnd, + enum XML_Account account) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ + STRING_POOL *pool = &(dtd->entityValuePool); + enum XML_Error result = XML_ERROR_NONE; +# ifdef XML_DTD + int oldInEntityValue = parser->m_prologState.inEntityValue; + parser->m_prologState.inEntityValue = 1; +# else + UNUSED_P(account); +# endif /* XML_DTD */ + /* never return Null for the value argument in EntityDeclHandler, + since this would indicate an external entity; therefore we + have to make sure that entityValuePool.start is not null */ + if (! pool->blocks) { + if (! poolGrow(pool)) + return XML_ERROR_NO_MEMORY; + } + + for (;;) { + const char *next + = entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */ + int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); + + if (! accountingDiffTolerated(parser, tok, entityTextPtr, next, __LINE__, + account)) { + accountingOnAbort(parser); + result = XML_ERROR_AMPLIFICATION_LIMIT_BREACH; + goto endEntityValue; + } + + switch (tok) { + case XML_TOK_PARAM_ENTITY_REF: +# ifdef XML_DTD + if (parser->m_isParamEntity || enc != parser->m_encoding) { + const XML_Char *name; + ENTITY *entity; + name = poolStoreString(&parser->m_tempPool, enc, + entityTextPtr + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (! name) { + result = XML_ERROR_NO_MEMORY; + goto endEntityValue; + } + entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); + poolDiscard(&parser->m_tempPool); + if (! entity) { + /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ + /* cannot report skipped entity here - see comments on + parser->m_skippedEntityHandler + if (parser->m_skippedEntityHandler) + parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); + */ + dtd->keepProcessing = dtd->standalone; + goto endEntityValue; + } + if (entity->open || (entity == parser->m_declEntity)) { + if (enc == parser->m_encoding) + parser->m_eventPtr = entityTextPtr; + result = XML_ERROR_RECURSIVE_ENTITY_REF; + goto endEntityValue; + } + if (entity->systemId) { + if (parser->m_externalEntityRefHandler) { + dtd->paramEntityRead = XML_FALSE; + entity->open = XML_TRUE; + entityTrackingOnOpen(parser, entity, __LINE__); + if (! parser->m_externalEntityRefHandler( + parser->m_externalEntityRefHandlerArg, 0, entity->base, + entity->systemId, entity->publicId)) { + entityTrackingOnClose(parser, entity, __LINE__); + entity->open = XML_FALSE; + result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; + goto endEntityValue; + } + entityTrackingOnClose(parser, entity, __LINE__); + entity->open = XML_FALSE; + if (! dtd->paramEntityRead) + dtd->keepProcessing = dtd->standalone; + } else + dtd->keepProcessing = dtd->standalone; + } else { + entity->open = XML_TRUE; + entityTrackingOnOpen(parser, entity, __LINE__); + result = storeEntityValue( + parser, parser->m_internalEncoding, (const char *)entity->textPtr, + (const char *)(entity->textPtr + entity->textLen), + XML_ACCOUNT_ENTITY_EXPANSION); + entityTrackingOnClose(parser, entity, __LINE__); + entity->open = XML_FALSE; + if (result) + goto endEntityValue; + } + break; + } +# endif /* XML_DTD */ + /* In the internal subset, PE references are not legal + within markup declarations, e.g entity values in this case. */ + parser->m_eventPtr = entityTextPtr; + result = XML_ERROR_PARAM_ENTITY_REF; + goto endEntityValue; + case XML_TOK_NONE: + result = XML_ERROR_NONE; + goto endEntityValue; + case XML_TOK_ENTITY_REF: + case XML_TOK_DATA_CHARS: + if (! poolAppend(pool, enc, entityTextPtr, next)) { + result = XML_ERROR_NO_MEMORY; + goto endEntityValue; + } + break; + case XML_TOK_TRAILING_CR: + next = entityTextPtr + enc->minBytesPerChar; + /* fall through */ + case XML_TOK_DATA_NEWLINE: + if (pool->end == pool->ptr && ! poolGrow(pool)) { + result = XML_ERROR_NO_MEMORY; + goto endEntityValue; + } + *(pool->ptr)++ = 0xA; + break; + case XML_TOK_CHAR_REF: { + XML_Char buf[XML_ENCODE_MAX]; + int i; + int n = XmlCharRefNumber(enc, entityTextPtr); + if (n < 0) { + if (enc == parser->m_encoding) + parser->m_eventPtr = entityTextPtr; + result = XML_ERROR_BAD_CHAR_REF; + goto endEntityValue; + } + n = XmlEncode(n, (ICHAR *)buf); + /* The XmlEncode() functions can never return 0 here. That + * error return happens if the code point passed in is either + * negative or greater than or equal to 0x110000. The + * XmlCharRefNumber() functions will all return a number + * strictly less than 0x110000 or a negative value if an error + * occurred. The negative value is intercepted above, so + * XmlEncode() is never passed a value it might return an + * error for. + */ + for (i = 0; i < n; i++) { + if (pool->end == pool->ptr && ! poolGrow(pool)) { + result = XML_ERROR_NO_MEMORY; + goto endEntityValue; + } + *(pool->ptr)++ = buf[i]; + } + } break; + case XML_TOK_PARTIAL: + if (enc == parser->m_encoding) + parser->m_eventPtr = entityTextPtr; + result = XML_ERROR_INVALID_TOKEN; + goto endEntityValue; + case XML_TOK_INVALID: + if (enc == parser->m_encoding) + parser->m_eventPtr = next; + result = XML_ERROR_INVALID_TOKEN; + goto endEntityValue; + default: + /* This default case should be unnecessary -- all the tokens + * that XmlEntityValueTok() can return have their own explicit + * cases -- but should be retained for safety. We do however + * exclude it from the coverage statistics. + * + * LCOV_EXCL_START + */ + if (enc == parser->m_encoding) + parser->m_eventPtr = entityTextPtr; + result = XML_ERROR_UNEXPECTED_STATE; + goto endEntityValue; + /* LCOV_EXCL_STOP */ + } + entityTextPtr = next; + } +endEntityValue: +# ifdef XML_DTD + parser->m_prologState.inEntityValue = oldInEntityValue; +# endif /* XML_DTD */ + return result; +} + +#else /* XML_GE == 0 */ + +static enum XML_Error +storeSelfEntityValue(XML_Parser parser, ENTITY *entity) { + // This will store "&entity123;" in entity->textPtr + // to end up as "&entity123;" in the handler. + const char *const entity_start = "&"; + const char *const entity_end = ";"; + + STRING_POOL *const pool = &(parser->m_dtd->entityValuePool); + if (! poolAppendString(pool, entity_start) + || ! poolAppendString(pool, entity->name) + || ! poolAppendString(pool, entity_end)) { + poolDiscard(pool); + return XML_ERROR_NO_MEMORY; + } + + entity->textPtr = poolStart(pool); + entity->textLen = (int)(poolLength(pool)); + poolFinish(pool); + + return XML_ERROR_NONE; +} + +#endif /* XML_GE == 0 */ + +static void FASTCALL +normalizeLines(XML_Char *s) { + XML_Char *p; + for (;; s++) { + if (*s == XML_T('\0')) + return; + if (*s == 0xD) + break; + } + p = s; + do { + if (*s == 0xD) { + *p++ = 0xA; + if (*++s == 0xA) + s++; + } else + *p++ = *s++; + } while (*s); + *p = XML_T('\0'); +} + +static int +reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, + const char *start, const char *end) { + const XML_Char *target; + XML_Char *data; + const char *tem; + if (! parser->m_processingInstructionHandler) { + if (parser->m_defaultHandler) + reportDefault(parser, enc, start, end); + return 1; + } + start += enc->minBytesPerChar * 2; + tem = start + XmlNameLength(enc, start); + target = poolStoreString(&parser->m_tempPool, enc, start, tem); + if (! target) + return 0; + poolFinish(&parser->m_tempPool); + data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem), + end - enc->minBytesPerChar * 2); + if (! data) + return 0; + normalizeLines(data); + parser->m_processingInstructionHandler(parser->m_handlerArg, target, data); + poolClear(&parser->m_tempPool); + return 1; +} + +static int +reportComment(XML_Parser parser, const ENCODING *enc, const char *start, + const char *end) { + XML_Char *data; + if (! parser->m_commentHandler) { + if (parser->m_defaultHandler) + reportDefault(parser, enc, start, end); + return 1; + } + data = poolStoreString(&parser->m_tempPool, enc, + start + enc->minBytesPerChar * 4, + end - enc->minBytesPerChar * 3); + if (! data) + return 0; + normalizeLines(data); + parser->m_commentHandler(parser->m_handlerArg, data); + poolClear(&parser->m_tempPool); + return 1; +} + +static void +reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, + const char *end) { + if (MUST_CONVERT(enc, s)) { + enum XML_Convert_Result convert_res; + const char **eventPP; + const char **eventEndPP; + if (enc == parser->m_encoding) { + eventPP = &parser->m_eventPtr; + eventEndPP = &parser->m_eventEndPtr; + } else { + /* To get here, two things must be true; the parser must be + * using a character encoding that is not the same as the + * encoding passed in, and the encoding passed in must need + * conversion to the internal format (UTF-8 unless XML_UNICODE + * is defined). The only occasions on which the encoding passed + * in is not the same as the parser's encoding are when it is + * the internal encoding (e.g. a previously defined parameter + * entity, already converted to internal format). This by + * definition doesn't need conversion, so the whole branch never + * gets executed. + * + * For safety's sake we don't delete these lines and merely + * exclude them from coverage statistics. + * + * LCOV_EXCL_START + */ + eventPP = &(parser->m_openInternalEntities->internalEventPtr); + eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); + /* LCOV_EXCL_STOP */ + } + do { + ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; + convert_res + = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); + *eventEndPP = s; + parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf, + (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); + *eventPP = s; + } while ((convert_res != XML_CONVERT_COMPLETED) + && (convert_res != XML_CONVERT_INPUT_INCOMPLETE)); + } else + parser->m_defaultHandler( + parser->m_handlerArg, (const XML_Char *)s, + (int)((const XML_Char *)end - (const XML_Char *)s)); +} + +static int +defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, + XML_Bool isId, const XML_Char *value, XML_Parser parser) { + DEFAULT_ATTRIBUTE *att; + if (value || isId) { + /* The handling of default attributes gets messed up if we have + a default which duplicates a non-default. */ + int i; + for (i = 0; i < type->nDefaultAtts; i++) + if (attId == type->defaultAtts[i].id) + return 1; + if (isId && ! type->idAtt && ! attId->xmlns) + type->idAtt = attId; + } + if (type->nDefaultAtts == type->allocDefaultAtts) { + if (type->allocDefaultAtts == 0) { + type->allocDefaultAtts = 8; + type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC( + parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); + if (! type->defaultAtts) { + type->allocDefaultAtts = 0; + return 0; + } + } else { + DEFAULT_ATTRIBUTE *temp; + + /* Detect and prevent integer overflow */ + if (type->allocDefaultAtts > INT_MAX / 2) { + return 0; + } + + int count = type->allocDefaultAtts * 2; + + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((unsigned)count > (size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE)) { + return 0; + } +#endif + + temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts, + (count * sizeof(DEFAULT_ATTRIBUTE))); + if (temp == NULL) + return 0; + type->allocDefaultAtts = count; + type->defaultAtts = temp; + } + } + att = type->defaultAtts + type->nDefaultAtts; + att->id = attId; + att->value = value; + att->isCdata = isCdata; + if (! isCdata) + attId->maybeTokenized = XML_TRUE; + type->nDefaultAtts += 1; + return 1; +} + +static int +setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ + const XML_Char *name; + for (name = elementType->name; *name; name++) { + if (*name == XML_T(ASCII_COLON)) { + PREFIX *prefix; + const XML_Char *s; + for (s = elementType->name; s != name; s++) { + if (! poolAppendChar(&dtd->pool, *s)) + return 0; + } + if (! poolAppendChar(&dtd->pool, XML_T('\0'))) + return 0; + prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool), + sizeof(PREFIX)); + if (! prefix) + return 0; + if (prefix->name == poolStart(&dtd->pool)) + poolFinish(&dtd->pool); + else + poolDiscard(&dtd->pool); + elementType->prefix = prefix; + break; + } + } + return 1; +} + +static ATTRIBUTE_ID * +getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, + const char *end) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ + ATTRIBUTE_ID *id; + const XML_Char *name; + if (! poolAppendChar(&dtd->pool, XML_T('\0'))) + return NULL; + name = poolStoreString(&dtd->pool, enc, start, end); + if (! name) + return NULL; + /* skip quotation mark - its storage will be reused (like in name[-1]) */ + ++name; + id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, + sizeof(ATTRIBUTE_ID)); + if (! id) + return NULL; + if (id->name != name) + poolDiscard(&dtd->pool); + else { + poolFinish(&dtd->pool); + if (! parser->m_ns) + ; + else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m) + && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n) + && name[4] == XML_T(ASCII_s) + && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) { + if (name[5] == XML_T('\0')) + id->prefix = &dtd->defaultPrefix; + else + id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, + sizeof(PREFIX)); + id->xmlns = XML_TRUE; + } else { + int i; + for (i = 0; name[i]; i++) { + /* attributes without prefix are *not* in the default namespace */ + if (name[i] == XML_T(ASCII_COLON)) { + int j; + for (j = 0; j < i; j++) { + if (! poolAppendChar(&dtd->pool, name[j])) + return NULL; + } + if (! poolAppendChar(&dtd->pool, XML_T('\0'))) + return NULL; + id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, + poolStart(&dtd->pool), sizeof(PREFIX)); + if (! id->prefix) + return NULL; + if (id->prefix->name == poolStart(&dtd->pool)) + poolFinish(&dtd->pool); + else + poolDiscard(&dtd->pool); + break; + } + } + } + } + return id; +} + +#define CONTEXT_SEP XML_T(ASCII_FF) + +static const XML_Char * +getContext(XML_Parser parser) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ + HASH_TABLE_ITER iter; + XML_Bool needSep = XML_FALSE; + + if (dtd->defaultPrefix.binding) { + int i; + int len; + if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) + return NULL; + len = dtd->defaultPrefix.binding->uriLen; + if (parser->m_namespaceSeparator) + len--; + for (i = 0; i < len; i++) { + if (! poolAppendChar(&parser->m_tempPool, + dtd->defaultPrefix.binding->uri[i])) { + /* Because of memory caching, I don't believe this line can be + * executed. + * + * This is part of a loop copying the default prefix binding + * URI into the parser's temporary string pool. Previously, + * that URI was copied into the same string pool, with a + * terminating NUL character, as part of setContext(). When + * the pool was cleared, that leaves a block definitely big + * enough to hold the URI on the free block list of the pool. + * The URI copy in getContext() therefore cannot run out of + * memory. + * + * If the pool is used between the setContext() and + * getContext() calls, the worst it can do is leave a bigger + * block on the front of the free list. Given that this is + * all somewhat inobvious and program logic can be changed, we + * don't delete the line but we do exclude it from the test + * coverage statistics. + */ + return NULL; /* LCOV_EXCL_LINE */ + } + } + needSep = XML_TRUE; + } + + hashTableIterInit(&iter, &(dtd->prefixes)); + for (;;) { + int i; + int len; + const XML_Char *s; + PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); + if (! prefix) + break; + if (! prefix->binding) { + /* This test appears to be (justifiable) paranoia. There does + * not seem to be a way of injecting a prefix without a binding + * that doesn't get errored long before this function is called. + * The test should remain for safety's sake, so we instead + * exclude the following line from the coverage statistics. + */ + continue; /* LCOV_EXCL_LINE */ + } + if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) + return NULL; + for (s = prefix->name; *s; s++) + if (! poolAppendChar(&parser->m_tempPool, *s)) + return NULL; + if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) + return NULL; + len = prefix->binding->uriLen; + if (parser->m_namespaceSeparator) + len--; + for (i = 0; i < len; i++) + if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i])) + return NULL; + needSep = XML_TRUE; + } + + hashTableIterInit(&iter, &(dtd->generalEntities)); + for (;;) { + const XML_Char *s; + ENTITY *e = (ENTITY *)hashTableIterNext(&iter); + if (! e) + break; + if (! e->open) + continue; + if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) + return NULL; + for (s = e->name; *s; s++) + if (! poolAppendChar(&parser->m_tempPool, *s)) + return 0; + needSep = XML_TRUE; + } + + if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) + return NULL; + return parser->m_tempPool.start; +} + +static XML_Bool +setContext(XML_Parser parser, const XML_Char *context) { + if (context == NULL) { + return XML_FALSE; + } + + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ + const XML_Char *s = context; + + while (*context != XML_T('\0')) { + if (*s == CONTEXT_SEP || *s == XML_T('\0')) { + ENTITY *e; + if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) + return XML_FALSE; + e = (ENTITY *)lookup(parser, &dtd->generalEntities, + poolStart(&parser->m_tempPool), 0); + if (e) + e->open = XML_TRUE; + if (*s != XML_T('\0')) + s++; + context = s; + poolDiscard(&parser->m_tempPool); + } else if (*s == XML_T(ASCII_EQUALS)) { + PREFIX *prefix; + if (poolLength(&parser->m_tempPool) == 0) + prefix = &dtd->defaultPrefix; + else { + if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) + return XML_FALSE; + prefix + = (PREFIX *)lookup(parser, &dtd->prefixes, + poolStart(&parser->m_tempPool), sizeof(PREFIX)); + if (! prefix) + return XML_FALSE; + if (prefix->name == poolStart(&parser->m_tempPool)) { + prefix->name = poolCopyString(&dtd->pool, prefix->name); + if (! prefix->name) + return XML_FALSE; + } + poolDiscard(&parser->m_tempPool); + } + for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); + context++) + if (! poolAppendChar(&parser->m_tempPool, *context)) + return XML_FALSE; + if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) + return XML_FALSE; + if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool), + &parser->m_inheritedBindings) + != XML_ERROR_NONE) + return XML_FALSE; + poolDiscard(&parser->m_tempPool); + if (*context != XML_T('\0')) + ++context; + s = context; + } else { + if (! poolAppendChar(&parser->m_tempPool, *s)) + return XML_FALSE; + s++; + } + } + return XML_TRUE; +} + +static void FASTCALL +normalizePublicId(XML_Char *publicId) { + XML_Char *p = publicId; + XML_Char *s; + for (s = publicId; *s; s++) { + switch (*s) { + case 0x20: + case 0xD: + case 0xA: + if (p != publicId && p[-1] != 0x20) + *p++ = 0x20; + break; + default: + *p++ = *s; + } + } + if (p != publicId && p[-1] == 0x20) + --p; + *p = XML_T('\0'); +} + +static DTD * +dtdCreate(const XML_Memory_Handling_Suite *ms) { + DTD *p = ms->malloc_fcn(sizeof(DTD)); + if (p == NULL) + return p; + poolInit(&(p->pool), ms); + poolInit(&(p->entityValuePool), ms); + hashTableInit(&(p->generalEntities), ms); + hashTableInit(&(p->elementTypes), ms); + hashTableInit(&(p->attributeIds), ms); + hashTableInit(&(p->prefixes), ms); +#ifdef XML_DTD + p->paramEntityRead = XML_FALSE; + hashTableInit(&(p->paramEntities), ms); +#endif /* XML_DTD */ + p->defaultPrefix.name = NULL; + p->defaultPrefix.binding = NULL; + + p->in_eldecl = XML_FALSE; + p->scaffIndex = NULL; + p->scaffold = NULL; + p->scaffLevel = 0; + p->scaffSize = 0; + p->scaffCount = 0; + p->contentStringLen = 0; + + p->keepProcessing = XML_TRUE; + p->hasParamEntityRefs = XML_FALSE; + p->standalone = XML_FALSE; + return p; +} + +static void +dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) { + HASH_TABLE_ITER iter; + hashTableIterInit(&iter, &(p->elementTypes)); + for (;;) { + ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); + if (! e) + break; + if (e->allocDefaultAtts != 0) + ms->free_fcn(e->defaultAtts); + } + hashTableClear(&(p->generalEntities)); +#ifdef XML_DTD + p->paramEntityRead = XML_FALSE; + hashTableClear(&(p->paramEntities)); +#endif /* XML_DTD */ + hashTableClear(&(p->elementTypes)); + hashTableClear(&(p->attributeIds)); + hashTableClear(&(p->prefixes)); + poolClear(&(p->pool)); + poolClear(&(p->entityValuePool)); + p->defaultPrefix.name = NULL; + p->defaultPrefix.binding = NULL; + + p->in_eldecl = XML_FALSE; + + ms->free_fcn(p->scaffIndex); + p->scaffIndex = NULL; + ms->free_fcn(p->scaffold); + p->scaffold = NULL; + + p->scaffLevel = 0; + p->scaffSize = 0; + p->scaffCount = 0; + p->contentStringLen = 0; + + p->keepProcessing = XML_TRUE; + p->hasParamEntityRefs = XML_FALSE; + p->standalone = XML_FALSE; +} + +static void +dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) { + HASH_TABLE_ITER iter; + hashTableIterInit(&iter, &(p->elementTypes)); + for (;;) { + ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); + if (! e) + break; + if (e->allocDefaultAtts != 0) + ms->free_fcn(e->defaultAtts); + } + hashTableDestroy(&(p->generalEntities)); +#ifdef XML_DTD + hashTableDestroy(&(p->paramEntities)); +#endif /* XML_DTD */ + hashTableDestroy(&(p->elementTypes)); + hashTableDestroy(&(p->attributeIds)); + hashTableDestroy(&(p->prefixes)); + poolDestroy(&(p->pool)); + poolDestroy(&(p->entityValuePool)); + if (isDocEntity) { + ms->free_fcn(p->scaffIndex); + ms->free_fcn(p->scaffold); + } + ms->free_fcn(p); +} + +/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise. + The new DTD has already been initialized. +*/ +static int +dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, + const XML_Memory_Handling_Suite *ms) { + HASH_TABLE_ITER iter; + + /* Copy the prefix table. */ + + hashTableIterInit(&iter, &(oldDtd->prefixes)); + for (;;) { + const XML_Char *name; + const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); + if (! oldP) + break; + name = poolCopyString(&(newDtd->pool), oldP->name); + if (! name) + return 0; + if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX))) + return 0; + } + + hashTableIterInit(&iter, &(oldDtd->attributeIds)); + + /* Copy the attribute id table. */ + + for (;;) { + ATTRIBUTE_ID *newA; + const XML_Char *name; + const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); + + if (! oldA) + break; + /* Remember to allocate the scratch byte before the name. */ + if (! poolAppendChar(&(newDtd->pool), XML_T('\0'))) + return 0; + name = poolCopyString(&(newDtd->pool), oldA->name); + if (! name) + return 0; + ++name; + newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name, + sizeof(ATTRIBUTE_ID)); + if (! newA) + return 0; + newA->maybeTokenized = oldA->maybeTokenized; + if (oldA->prefix) { + newA->xmlns = oldA->xmlns; + if (oldA->prefix == &oldDtd->defaultPrefix) + newA->prefix = &newDtd->defaultPrefix; + else + newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), + oldA->prefix->name, 0); + } + } + + /* Copy the element type table. */ + + hashTableIterInit(&iter, &(oldDtd->elementTypes)); + + for (;;) { + int i; + ELEMENT_TYPE *newE; + const XML_Char *name; + const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); + if (! oldE) + break; + name = poolCopyString(&(newDtd->pool), oldE->name); + if (! name) + return 0; + newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name, + sizeof(ELEMENT_TYPE)); + if (! newE) + return 0; + if (oldE->nDefaultAtts) { + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if ((size_t)oldE->nDefaultAtts + > ((size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE))) { + return 0; + } +#endif + newE->defaultAtts + = ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); + if (! newE->defaultAtts) { + return 0; + } + } + if (oldE->idAtt) + newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), + oldE->idAtt->name, 0); + newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; + if (oldE->prefix) + newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), + oldE->prefix->name, 0); + for (i = 0; i < newE->nDefaultAtts; i++) { + newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup( + oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); + newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; + if (oldE->defaultAtts[i].value) { + newE->defaultAtts[i].value + = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); + if (! newE->defaultAtts[i].value) + return 0; + } else + newE->defaultAtts[i].value = NULL; + } + } + + /* Copy the entity tables. */ + if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool), + &(oldDtd->generalEntities))) + return 0; + +#ifdef XML_DTD + if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool), + &(oldDtd->paramEntities))) + return 0; + newDtd->paramEntityRead = oldDtd->paramEntityRead; +#endif /* XML_DTD */ + + newDtd->keepProcessing = oldDtd->keepProcessing; + newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs; + newDtd->standalone = oldDtd->standalone; + + /* Don't want deep copying for scaffolding */ + newDtd->in_eldecl = oldDtd->in_eldecl; + newDtd->scaffold = oldDtd->scaffold; + newDtd->contentStringLen = oldDtd->contentStringLen; + newDtd->scaffSize = oldDtd->scaffSize; + newDtd->scaffLevel = oldDtd->scaffLevel; + newDtd->scaffIndex = oldDtd->scaffIndex; + + return 1; +} /* End dtdCopy */ + +static int +copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable, + STRING_POOL *newPool, const HASH_TABLE *oldTable) { + HASH_TABLE_ITER iter; + const XML_Char *cachedOldBase = NULL; + const XML_Char *cachedNewBase = NULL; + + hashTableIterInit(&iter, oldTable); + + for (;;) { + ENTITY *newE; + const XML_Char *name; + const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); + if (! oldE) + break; + name = poolCopyString(newPool, oldE->name); + if (! name) + return 0; + newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY)); + if (! newE) + return 0; + if (oldE->systemId) { + const XML_Char *tem = poolCopyString(newPool, oldE->systemId); + if (! tem) + return 0; + newE->systemId = tem; + if (oldE->base) { + if (oldE->base == cachedOldBase) + newE->base = cachedNewBase; + else { + cachedOldBase = oldE->base; + tem = poolCopyString(newPool, cachedOldBase); + if (! tem) + return 0; + cachedNewBase = newE->base = tem; + } + } + if (oldE->publicId) { + tem = poolCopyString(newPool, oldE->publicId); + if (! tem) + return 0; + newE->publicId = tem; + } + } else { + const XML_Char *tem + = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen); + if (! tem) + return 0; + newE->textPtr = tem; + newE->textLen = oldE->textLen; + } + if (oldE->notation) { + const XML_Char *tem = poolCopyString(newPool, oldE->notation); + if (! tem) + return 0; + newE->notation = tem; + } + newE->is_param = oldE->is_param; + newE->is_internal = oldE->is_internal; + } + return 1; +} + +#define INIT_POWER 6 + +static XML_Bool FASTCALL +keyeq(KEY s1, KEY s2) { + for (; *s1 == *s2; s1++, s2++) + if (*s1 == 0) + return XML_TRUE; + return XML_FALSE; +} + +static size_t +keylen(KEY s) { + size_t len = 0; + for (; *s; s++, len++) + ; + return len; +} + +static void +copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) { + key->k[0] = 0; + key->k[1] = get_hash_secret_salt(parser); +} + +static unsigned long FASTCALL +hash(XML_Parser parser, KEY s) { + struct siphash state; + struct sipkey key; + (void)sip24_valid; + copy_salt_to_sipkey(parser, &key); + sip24_init(&state, &key); + sip24_update(&state, s, keylen(s) * sizeof(XML_Char)); + return (unsigned long)sip24_final(&state); +} + +static NAMED * +lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) { + size_t i; + if (table->size == 0) { + size_t tsize; + if (! createSize) + return NULL; + table->power = INIT_POWER; + /* table->size is a power of 2 */ + table->size = (size_t)1 << INIT_POWER; + tsize = table->size * sizeof(NAMED *); + table->v = table->mem->malloc_fcn(tsize); + if (! table->v) { + table->size = 0; + return NULL; + } + memset(table->v, 0, tsize); + i = hash(parser, name) & ((unsigned long)table->size - 1); + } else { + unsigned long h = hash(parser, name); + unsigned long mask = (unsigned long)table->size - 1; + unsigned char step = 0; + i = h & mask; + while (table->v[i]) { + if (keyeq(name, table->v[i]->name)) + return table->v[i]; + if (! step) + step = PROBE_STEP(h, mask, table->power); + i < step ? (i += table->size - step) : (i -= step); + } + if (! createSize) + return NULL; + + /* check for overflow (table is half full) */ + if (table->used >> (table->power - 1)) { + unsigned char newPower = table->power + 1; + + /* Detect and prevent invalid shift */ + if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) { + return NULL; + } + + size_t newSize = (size_t)1 << newPower; + unsigned long newMask = (unsigned long)newSize - 1; + + /* Detect and prevent integer overflow */ + if (newSize > (size_t)(-1) / sizeof(NAMED *)) { + return NULL; + } + + size_t tsize = newSize * sizeof(NAMED *); + NAMED **newV = table->mem->malloc_fcn(tsize); + if (! newV) + return NULL; + memset(newV, 0, tsize); + for (i = 0; i < table->size; i++) + if (table->v[i]) { + unsigned long newHash = hash(parser, table->v[i]->name); + size_t j = newHash & newMask; + step = 0; + while (newV[j]) { + if (! step) + step = PROBE_STEP(newHash, newMask, newPower); + j < step ? (j += newSize - step) : (j -= step); + } + newV[j] = table->v[i]; + } + table->mem->free_fcn(table->v); + table->v = newV; + table->power = newPower; + table->size = newSize; + i = h & newMask; + step = 0; + while (table->v[i]) { + if (! step) + step = PROBE_STEP(h, newMask, newPower); + i < step ? (i += newSize - step) : (i -= step); + } + } + } + table->v[i] = table->mem->malloc_fcn(createSize); + if (! table->v[i]) + return NULL; + memset(table->v[i], 0, createSize); + table->v[i]->name = name; + (table->used)++; + return table->v[i]; +} + +static void FASTCALL +hashTableClear(HASH_TABLE *table) { + size_t i; + for (i = 0; i < table->size; i++) { + table->mem->free_fcn(table->v[i]); + table->v[i] = NULL; + } + table->used = 0; +} + +static void FASTCALL +hashTableDestroy(HASH_TABLE *table) { + size_t i; + for (i = 0; i < table->size; i++) + table->mem->free_fcn(table->v[i]); + table->mem->free_fcn(table->v); +} + +static void FASTCALL +hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) { + p->power = 0; + p->size = 0; + p->used = 0; + p->v = NULL; + p->mem = ms; +} + +static void FASTCALL +hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) { + iter->p = table->v; + iter->end = iter->p ? iter->p + table->size : NULL; +} + +static NAMED *FASTCALL +hashTableIterNext(HASH_TABLE_ITER *iter) { + while (iter->p != iter->end) { + NAMED *tem = *(iter->p)++; + if (tem) + return tem; + } + return NULL; +} + +static void FASTCALL +poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) { + pool->blocks = NULL; + pool->freeBlocks = NULL; + pool->start = NULL; + pool->ptr = NULL; + pool->end = NULL; + pool->mem = ms; +} + +static void FASTCALL +poolClear(STRING_POOL *pool) { + if (! pool->freeBlocks) + pool->freeBlocks = pool->blocks; + else { + BLOCK *p = pool->blocks; + while (p) { + BLOCK *tem = p->next; + p->next = pool->freeBlocks; + pool->freeBlocks = p; + p = tem; + } + } + pool->blocks = NULL; + pool->start = NULL; + pool->ptr = NULL; + pool->end = NULL; +} + +static void FASTCALL +poolDestroy(STRING_POOL *pool) { + BLOCK *p = pool->blocks; + while (p) { + BLOCK *tem = p->next; + pool->mem->free_fcn(p); + p = tem; + } + p = pool->freeBlocks; + while (p) { + BLOCK *tem = p->next; + pool->mem->free_fcn(p); + p = tem; + } +} + +static XML_Char * +poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr, + const char *end) { + if (! pool->ptr && ! poolGrow(pool)) + return NULL; + for (;;) { + const enum XML_Convert_Result convert_res = XmlConvert( + enc, &ptr, end, (ICHAR **)&(pool->ptr), (const ICHAR *)pool->end); + if ((convert_res == XML_CONVERT_COMPLETED) + || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) + break; + if (! poolGrow(pool)) + return NULL; + } + return pool->start; +} + +static const XML_Char *FASTCALL +poolCopyString(STRING_POOL *pool, const XML_Char *s) { + do { + if (! poolAppendChar(pool, *s)) + return NULL; + } while (*s++); + s = pool->start; + poolFinish(pool); + return s; +} + +static const XML_Char * +poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) { + if (! pool->ptr && ! poolGrow(pool)) { + /* The following line is unreachable given the current usage of + * poolCopyStringN(). Currently it is called from exactly one + * place to copy the text of a simple general entity. By that + * point, the name of the entity is already stored in the pool, so + * pool->ptr cannot be NULL. + * + * If poolCopyStringN() is used elsewhere as it well might be, + * this line may well become executable again. Regardless, this + * sort of check shouldn't be removed lightly, so we just exclude + * it from the coverage statistics. + */ + return NULL; /* LCOV_EXCL_LINE */ + } + for (; n > 0; --n, s++) { + if (! poolAppendChar(pool, *s)) + return NULL; + } + s = pool->start; + poolFinish(pool); + return s; +} + +static const XML_Char *FASTCALL +poolAppendString(STRING_POOL *pool, const XML_Char *s) { + while (*s) { + if (! poolAppendChar(pool, *s)) + return NULL; + s++; + } + return pool->start; +} + +static XML_Char * +poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr, + const char *end) { + if (! poolAppend(pool, enc, ptr, end)) + return NULL; + if (pool->ptr == pool->end && ! poolGrow(pool)) + return NULL; + *(pool->ptr)++ = 0; + return pool->start; +} + +static size_t +poolBytesToAllocateFor(int blockSize) { + /* Unprotected math would be: + ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); + ** + ** Detect overflow, avoiding _signed_ overflow undefined behavior + ** For a + b * c we check b * c in isolation first, so that addition of a + ** on top has no chance of making us accept a small non-negative number + */ + const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */ + + if (blockSize <= 0) + return 0; + + if (blockSize > (int)(INT_MAX / stretch)) + return 0; + + { + const int stretchedBlockSize = blockSize * (int)stretch; + const int bytesToAllocate + = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize); + if (bytesToAllocate < 0) + return 0; + + return (size_t)bytesToAllocate; + } +} + +static XML_Bool FASTCALL +poolGrow(STRING_POOL *pool) { + if (pool->freeBlocks) { + if (pool->start == 0) { + pool->blocks = pool->freeBlocks; + pool->freeBlocks = pool->freeBlocks->next; + pool->blocks->next = NULL; + pool->start = pool->blocks->s; + pool->end = pool->start + pool->blocks->size; + pool->ptr = pool->start; + return XML_TRUE; + } + if (pool->end - pool->start < pool->freeBlocks->size) { + BLOCK *tem = pool->freeBlocks->next; + pool->freeBlocks->next = pool->blocks; + pool->blocks = pool->freeBlocks; + pool->freeBlocks = tem; + memcpy(pool->blocks->s, pool->start, + (pool->end - pool->start) * sizeof(XML_Char)); + pool->ptr = pool->blocks->s + (pool->ptr - pool->start); + pool->start = pool->blocks->s; + pool->end = pool->start + pool->blocks->size; + return XML_TRUE; + } + } + if (pool->blocks && pool->start == pool->blocks->s) { + BLOCK *temp; + int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U); + size_t bytesToAllocate; + + /* NOTE: Needs to be calculated prior to calling `realloc` + to avoid dangling pointers: */ + const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start; + + if (blockSize < 0) { + /* This condition traps a situation where either more than + * INT_MAX/2 bytes have already been allocated. This isn't + * readily testable, since it is unlikely that an average + * machine will have that much memory, so we exclude it from the + * coverage statistics. + */ + return XML_FALSE; /* LCOV_EXCL_LINE */ + } + + bytesToAllocate = poolBytesToAllocateFor(blockSize); + if (bytesToAllocate == 0) + return XML_FALSE; + + temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks, + (unsigned)bytesToAllocate); + if (temp == NULL) + return XML_FALSE; + pool->blocks = temp; + pool->blocks->size = blockSize; + pool->ptr = pool->blocks->s + offsetInsideBlock; + pool->start = pool->blocks->s; + pool->end = pool->start + blockSize; + } else { + BLOCK *tem; + int blockSize = (int)(pool->end - pool->start); + size_t bytesToAllocate; + + if (blockSize < 0) { + /* This condition traps a situation where either more than + * INT_MAX bytes have already been allocated (which is prevented + * by various pieces of program logic, not least this one, never + * mind the unlikelihood of actually having that much memory) or + * the pool control fields have been corrupted (which could + * conceivably happen in an extremely buggy user handler + * function). Either way it isn't readily testable, so we + * exclude it from the coverage statistics. + */ + return XML_FALSE; /* LCOV_EXCL_LINE */ + } + + if (blockSize < INIT_BLOCK_SIZE) + blockSize = INIT_BLOCK_SIZE; + else { + /* Detect overflow, avoiding _signed_ overflow undefined behavior */ + if ((int)((unsigned)blockSize * 2U) < 0) { + return XML_FALSE; + } + blockSize *= 2; + } + + bytesToAllocate = poolBytesToAllocateFor(blockSize); + if (bytesToAllocate == 0) + return XML_FALSE; + + tem = pool->mem->malloc_fcn(bytesToAllocate); + if (! tem) + return XML_FALSE; + tem->size = blockSize; + tem->next = pool->blocks; + pool->blocks = tem; + if (pool->ptr != pool->start) + memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char)); + pool->ptr = tem->s + (pool->ptr - pool->start); + pool->start = tem->s; + pool->end = tem->s + blockSize; + } + return XML_TRUE; +} + +static int FASTCALL +nextScaffoldPart(XML_Parser parser) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ + CONTENT_SCAFFOLD *me; + int next; + + if (! dtd->scaffIndex) { + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if (parser->m_groupSize > ((size_t)(-1) / sizeof(int))) { + return -1; + } +#endif + dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int)); + if (! dtd->scaffIndex) + return -1; + dtd->scaffIndex[0] = 0; + } + + if (dtd->scaffCount >= dtd->scaffSize) { + CONTENT_SCAFFOLD *temp; + if (dtd->scaffold) { + /* Detect and prevent integer overflow */ + if (dtd->scaffSize > UINT_MAX / 2u) { + return -1; + } + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if (dtd->scaffSize > (size_t)(-1) / 2u / sizeof(CONTENT_SCAFFOLD)) { + return -1; + } +#endif + + temp = (CONTENT_SCAFFOLD *)REALLOC( + parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); + if (temp == NULL) + return -1; + dtd->scaffSize *= 2; + } else { + temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS + * sizeof(CONTENT_SCAFFOLD)); + if (temp == NULL) + return -1; + dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS; + } + dtd->scaffold = temp; + } + next = dtd->scaffCount++; + me = &dtd->scaffold[next]; + if (dtd->scaffLevel) { + CONTENT_SCAFFOLD *parent + = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]]; + if (parent->lastchild) { + dtd->scaffold[parent->lastchild].nextsib = next; + } + if (! parent->childcnt) + parent->firstchild = next; + parent->lastchild = next; + parent->childcnt++; + } + me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0; + return next; +} + +static XML_Content * +build_model(XML_Parser parser) { + /* Function build_model transforms the existing parser->m_dtd->scaffold + * array of CONTENT_SCAFFOLD tree nodes into a new array of + * XML_Content tree nodes followed by a gapless list of zero-terminated + * strings. */ + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ + XML_Content *ret; + XML_Char *str; /* the current string writing location */ + + /* Detect and prevent integer overflow. + * The preprocessor guard addresses the "always false" warning + * from -Wtype-limits on platforms where + * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ +#if UINT_MAX >= SIZE_MAX + if (dtd->scaffCount > (size_t)(-1) / sizeof(XML_Content)) { + return NULL; + } + if (dtd->contentStringLen > (size_t)(-1) / sizeof(XML_Char)) { + return NULL; + } +#endif + if (dtd->scaffCount * sizeof(XML_Content) + > (size_t)(-1) - dtd->contentStringLen * sizeof(XML_Char)) { + return NULL; + } + + const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content) + + (dtd->contentStringLen * sizeof(XML_Char))); + + ret = (XML_Content *)MALLOC(parser, allocsize); + if (! ret) + return NULL; + + /* What follows is an iterative implementation (of what was previously done + * recursively in a dedicated function called "build_node". The old recursive + * build_node could be forced into stack exhaustion from input as small as a + * few megabyte, and so that was a security issue. Hence, a function call + * stack is avoided now by resolving recursion.) + * + * The iterative approach works as follows: + * + * - We have two writing pointers, both walking up the result array; one does + * the work, the other creates "jobs" for its colleague to do, and leads + * the way: + * + * - The faster one, pointer jobDest, always leads and writes "what job + * to do" by the other, once they reach that place in the + * array: leader "jobDest" stores the source node array index (relative + * to array dtd->scaffold) in field "numchildren". + * + * - The slower one, pointer dest, looks at the value stored in the + * "numchildren" field (which actually holds a source node array index + * at that time) and puts the real data from dtd->scaffold in. + * + * - Before the loop starts, jobDest writes source array index 0 + * (where the root node is located) so that dest will have something to do + * when it starts operation. + * + * - Whenever nodes with children are encountered, jobDest appends + * them as new jobs, in order. As a result, tree node siblings are + * adjacent in the resulting array, for example: + * + * [0] root, has two children + * [1] first child of 0, has three children + * [3] first child of 1, does not have children + * [4] second child of 1, does not have children + * [5] third child of 1, does not have children + * [2] second child of 0, does not have children + * + * Or (the same data) presented in flat array view: + * + * [0] root, has two children + * + * [1] first child of 0, has three children + * [2] second child of 0, does not have children + * + * [3] first child of 1, does not have children + * [4] second child of 1, does not have children + * [5] third child of 1, does not have children + * + * - The algorithm repeats until all target array indices have been processed. + */ + XML_Content *dest = ret; /* tree node writing location, moves upwards */ + XML_Content *const destLimit = &ret[dtd->scaffCount]; + XML_Content *jobDest = ret; /* next free writing location in target array */ + str = (XML_Char *)&ret[dtd->scaffCount]; + + /* Add the starting job, the root node (index 0) of the source tree */ + (jobDest++)->numchildren = 0; + + for (; dest < destLimit; dest++) { + /* Retrieve source tree array index from job storage */ + const int src_node = (int)dest->numchildren; + + /* Convert item */ + dest->type = dtd->scaffold[src_node].type; + dest->quant = dtd->scaffold[src_node].quant; + if (dest->type == XML_CTYPE_NAME) { + const XML_Char *src; + dest->name = str; + src = dtd->scaffold[src_node].name; + for (;;) { + *str++ = *src; + if (! *src) + break; + src++; + } + dest->numchildren = 0; + dest->children = NULL; + } else { + unsigned int i; + int cn; + dest->name = NULL; + dest->numchildren = dtd->scaffold[src_node].childcnt; + dest->children = jobDest; + + /* Append scaffold indices of children to array */ + for (i = 0, cn = dtd->scaffold[src_node].firstchild; + i < dest->numchildren; i++, cn = dtd->scaffold[cn].nextsib) + (jobDest++)->numchildren = (unsigned int)cn; + } + } + + return ret; +} + +static ELEMENT_TYPE * +getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr, + const char *end) { + DTD *const dtd = parser->m_dtd; /* save one level of indirection */ + const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); + ELEMENT_TYPE *ret; + + if (! name) + return NULL; + ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, + sizeof(ELEMENT_TYPE)); + if (! ret) + return NULL; + if (ret->name != name) + poolDiscard(&dtd->pool); + else { + poolFinish(&dtd->pool); + if (! setElementTypePrefix(parser, ret)) + return NULL; + } + return ret; +} + +static XML_Char * +copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) { + size_t charsRequired = 0; + XML_Char *result; + + /* First determine how long the string is */ + while (s[charsRequired] != 0) { + charsRequired++; + } + /* Include the terminator */ + charsRequired++; + + /* Now allocate space for the copy */ + result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char)); + if (result == NULL) + return NULL; + /* Copy the original into place */ + memcpy(result, s, charsRequired * sizeof(XML_Char)); + return result; +} + +#if XML_GE == 1 + +static float +accountingGetCurrentAmplification(XML_Parser rootParser) { + // 1.........1.........12 => 22 + const size_t lenOfShortestInclude = sizeof("") - 1; + const XmlBigCount countBytesOutput + = rootParser->m_accounting.countBytesDirect + + rootParser->m_accounting.countBytesIndirect; + const float amplificationFactor + = rootParser->m_accounting.countBytesDirect + ? (countBytesOutput + / (float)(rootParser->m_accounting.countBytesDirect)) + : ((lenOfShortestInclude + + rootParser->m_accounting.countBytesIndirect) + / (float)lenOfShortestInclude); + assert(! rootParser->m_parentParser); + return amplificationFactor; +} + +static void +accountingReportStats(XML_Parser originParser, const char *epilog) { + const XML_Parser rootParser = getRootParserOf(originParser, NULL); + assert(! rootParser->m_parentParser); + + if (rootParser->m_accounting.debugLevel == 0u) { + return; + } + + const float amplificationFactor + = accountingGetCurrentAmplification(rootParser); + fprintf(stderr, + "expat: Accounting(%p): Direct " EXPAT_FMT_ULL( + "10") ", indirect " EXPAT_FMT_ULL("10") ", amplification %8.2f%s", + (void *)rootParser, rootParser->m_accounting.countBytesDirect, + rootParser->m_accounting.countBytesIndirect, + (double)amplificationFactor, epilog); +} + +static void +accountingOnAbort(XML_Parser originParser) { + accountingReportStats(originParser, " ABORTING\n"); +} + +static void +accountingReportDiff(XML_Parser rootParser, + unsigned int levelsAwayFromRootParser, const char *before, + const char *after, ptrdiff_t bytesMore, int source_line, + enum XML_Account account) { + assert(! rootParser->m_parentParser); + + fprintf(stderr, + " (+" EXPAT_FMT_PTRDIFF_T("6") " bytes %s|%d, xmlparse.c:%d) %*s\"", + bytesMore, (account == XML_ACCOUNT_DIRECT) ? "DIR" : "EXP", + levelsAwayFromRootParser, source_line, 10, ""); + + const char ellipis[] = "[..]"; + const size_t ellipsisLength = sizeof(ellipis) /* because compile-time */ - 1; + const unsigned int contextLength = 10; + + /* Note: Performance is of no concern here */ + const char *walker = before; + if ((rootParser->m_accounting.debugLevel >= 3u) + || (after - before) + <= (ptrdiff_t)(contextLength + ellipsisLength + contextLength)) { + for (; walker < after; walker++) { + fprintf(stderr, "%s", unsignedCharToPrintable(walker[0])); + } + } else { + for (; walker < before + contextLength; walker++) { + fprintf(stderr, "%s", unsignedCharToPrintable(walker[0])); + } + fprintf(stderr, ellipis); + walker = after - contextLength; + for (; walker < after; walker++) { + fprintf(stderr, "%s", unsignedCharToPrintable(walker[0])); + } + } + fprintf(stderr, "\"\n"); +} + +static XML_Bool +accountingDiffTolerated(XML_Parser originParser, int tok, const char *before, + const char *after, int source_line, + enum XML_Account account) { + /* Note: We need to check the token type *first* to be sure that + * we can even access variable , safely. + * E.g. for XML_TOK_NONE may hold an invalid pointer. */ + switch (tok) { + case XML_TOK_INVALID: + case XML_TOK_PARTIAL: + case XML_TOK_PARTIAL_CHAR: + case XML_TOK_NONE: + return XML_TRUE; + } + + if (account == XML_ACCOUNT_NONE) + return XML_TRUE; /* because these bytes have been accounted for, already */ + + unsigned int levelsAwayFromRootParser; + const XML_Parser rootParser + = getRootParserOf(originParser, &levelsAwayFromRootParser); + assert(! rootParser->m_parentParser); + + const int isDirect + = (account == XML_ACCOUNT_DIRECT) && (originParser == rootParser); + const ptrdiff_t bytesMore = after - before; + + XmlBigCount *const additionTarget + = isDirect ? &rootParser->m_accounting.countBytesDirect + : &rootParser->m_accounting.countBytesIndirect; + + /* Detect and avoid integer overflow */ + if (*additionTarget > (XmlBigCount)(-1) - (XmlBigCount)bytesMore) + return XML_FALSE; + *additionTarget += bytesMore; + + const XmlBigCount countBytesOutput + = rootParser->m_accounting.countBytesDirect + + rootParser->m_accounting.countBytesIndirect; + const float amplificationFactor + = accountingGetCurrentAmplification(rootParser); + const XML_Bool tolerated + = (countBytesOutput < rootParser->m_accounting.activationThresholdBytes) + || (amplificationFactor + <= rootParser->m_accounting.maximumAmplificationFactor); + + if (rootParser->m_accounting.debugLevel >= 2u) { + accountingReportStats(rootParser, ""); + accountingReportDiff(rootParser, levelsAwayFromRootParser, before, after, + bytesMore, source_line, account); + } + + return tolerated; +} + +unsigned long long +testingAccountingGetCountBytesDirect(XML_Parser parser) { + if (! parser) + return 0; + return parser->m_accounting.countBytesDirect; +} + +unsigned long long +testingAccountingGetCountBytesIndirect(XML_Parser parser) { + if (! parser) + return 0; + return parser->m_accounting.countBytesIndirect; +} + +static void +entityTrackingReportStats(XML_Parser rootParser, ENTITY *entity, + const char *action, int sourceLine) { + assert(! rootParser->m_parentParser); + if (rootParser->m_entity_stats.debugLevel == 0u) + return; + +# if defined(XML_UNICODE) + const char *const entityName = "[..]"; +# else + const char *const entityName = entity->name; +# endif + + fprintf( + stderr, + "expat: Entities(%p): Count %9d, depth %2d/%2d %*s%s%s; %s length %d (xmlparse.c:%d)\n", + (void *)rootParser, rootParser->m_entity_stats.countEverOpened, + rootParser->m_entity_stats.currentDepth, + rootParser->m_entity_stats.maximumDepthSeen, + (rootParser->m_entity_stats.currentDepth - 1) * 2, "", + entity->is_param ? "%" : "&", entityName, action, entity->textLen, + sourceLine); +} + +static void +entityTrackingOnOpen(XML_Parser originParser, ENTITY *entity, int sourceLine) { + const XML_Parser rootParser = getRootParserOf(originParser, NULL); + assert(! rootParser->m_parentParser); + + rootParser->m_entity_stats.countEverOpened++; + rootParser->m_entity_stats.currentDepth++; + if (rootParser->m_entity_stats.currentDepth + > rootParser->m_entity_stats.maximumDepthSeen) { + rootParser->m_entity_stats.maximumDepthSeen++; + } + + entityTrackingReportStats(rootParser, entity, "OPEN ", sourceLine); +} + +static void +entityTrackingOnClose(XML_Parser originParser, ENTITY *entity, int sourceLine) { + const XML_Parser rootParser = getRootParserOf(originParser, NULL); + assert(! rootParser->m_parentParser); + + entityTrackingReportStats(rootParser, entity, "CLOSE", sourceLine); + rootParser->m_entity_stats.currentDepth--; +} + +static XML_Parser +getRootParserOf(XML_Parser parser, unsigned int *outLevelDiff) { + XML_Parser rootParser = parser; + unsigned int stepsTakenUpwards = 0; + while (rootParser->m_parentParser) { + rootParser = rootParser->m_parentParser; + stepsTakenUpwards++; + } + assert(! rootParser->m_parentParser); + if (outLevelDiff != NULL) { + *outLevelDiff = stepsTakenUpwards; + } + return rootParser; +} + +const char * +unsignedCharToPrintable(unsigned char c) { + switch (c) { + case 0: + return "\\0"; + case 1: + return "\\x1"; + case 2: + return "\\x2"; + case 3: + return "\\x3"; + case 4: + return "\\x4"; + case 5: + return "\\x5"; + case 6: + return "\\x6"; + case 7: + return "\\x7"; + case 8: + return "\\x8"; + case 9: + return "\\t"; + case 10: + return "\\n"; + case 11: + return "\\xB"; + case 12: + return "\\xC"; + case 13: + return "\\r"; + case 14: + return "\\xE"; + case 15: + return "\\xF"; + case 16: + return "\\x10"; + case 17: + return "\\x11"; + case 18: + return "\\x12"; + case 19: + return "\\x13"; + case 20: + return "\\x14"; + case 21: + return "\\x15"; + case 22: + return "\\x16"; + case 23: + return "\\x17"; + case 24: + return "\\x18"; + case 25: + return "\\x19"; + case 26: + return "\\x1A"; + case 27: + return "\\x1B"; + case 28: + return "\\x1C"; + case 29: + return "\\x1D"; + case 30: + return "\\x1E"; + case 31: + return "\\x1F"; + case 32: + return " "; + case 33: + return "!"; + case 34: + return "\\\""; + case 35: + return "#"; + case 36: + return "$"; + case 37: + return "%"; + case 38: + return "&"; + case 39: + return "'"; + case 40: + return "("; + case 41: + return ")"; + case 42: + return "*"; + case 43: + return "+"; + case 44: + return ","; + case 45: + return "-"; + case 46: + return "."; + case 47: + return "/"; + case 48: + return "0"; + case 49: + return "1"; + case 50: + return "2"; + case 51: + return "3"; + case 52: + return "4"; + case 53: + return "5"; + case 54: + return "6"; + case 55: + return "7"; + case 56: + return "8"; + case 57: + return "9"; + case 58: + return ":"; + case 59: + return ";"; + case 60: + return "<"; + case 61: + return "="; + case 62: + return ">"; + case 63: + return "?"; + case 64: + return "@"; + case 65: + return "A"; + case 66: + return "B"; + case 67: + return "C"; + case 68: + return "D"; + case 69: + return "E"; + case 70: + return "F"; + case 71: + return "G"; + case 72: + return "H"; + case 73: + return "I"; + case 74: + return "J"; + case 75: + return "K"; + case 76: + return "L"; + case 77: + return "M"; + case 78: + return "N"; + case 79: + return "O"; + case 80: + return "P"; + case 81: + return "Q"; + case 82: + return "R"; + case 83: + return "S"; + case 84: + return "T"; + case 85: + return "U"; + case 86: + return "V"; + case 87: + return "W"; + case 88: + return "X"; + case 89: + return "Y"; + case 90: + return "Z"; + case 91: + return "["; + case 92: + return "\\\\"; + case 93: + return "]"; + case 94: + return "^"; + case 95: + return "_"; + case 96: + return "`"; + case 97: + return "a"; + case 98: + return "b"; + case 99: + return "c"; + case 100: + return "d"; + case 101: + return "e"; + case 102: + return "f"; + case 103: + return "g"; + case 104: + return "h"; + case 105: + return "i"; + case 106: + return "j"; + case 107: + return "k"; + case 108: + return "l"; + case 109: + return "m"; + case 110: + return "n"; + case 111: + return "o"; + case 112: + return "p"; + case 113: + return "q"; + case 114: + return "r"; + case 115: + return "s"; + case 116: + return "t"; + case 117: + return "u"; + case 118: + return "v"; + case 119: + return "w"; + case 120: + return "x"; + case 121: + return "y"; + case 122: + return "z"; + case 123: + return "{"; + case 124: + return "|"; + case 125: + return "}"; + case 126: + return "~"; + case 127: + return "\\x7F"; + case 128: + return "\\x80"; + case 129: + return "\\x81"; + case 130: + return "\\x82"; + case 131: + return "\\x83"; + case 132: + return "\\x84"; + case 133: + return "\\x85"; + case 134: + return "\\x86"; + case 135: + return "\\x87"; + case 136: + return "\\x88"; + case 137: + return "\\x89"; + case 138: + return "\\x8A"; + case 139: + return "\\x8B"; + case 140: + return "\\x8C"; + case 141: + return "\\x8D"; + case 142: + return "\\x8E"; + case 143: + return "\\x8F"; + case 144: + return "\\x90"; + case 145: + return "\\x91"; + case 146: + return "\\x92"; + case 147: + return "\\x93"; + case 148: + return "\\x94"; + case 149: + return "\\x95"; + case 150: + return "\\x96"; + case 151: + return "\\x97"; + case 152: + return "\\x98"; + case 153: + return "\\x99"; + case 154: + return "\\x9A"; + case 155: + return "\\x9B"; + case 156: + return "\\x9C"; + case 157: + return "\\x9D"; + case 158: + return "\\x9E"; + case 159: + return "\\x9F"; + case 160: + return "\\xA0"; + case 161: + return "\\xA1"; + case 162: + return "\\xA2"; + case 163: + return "\\xA3"; + case 164: + return "\\xA4"; + case 165: + return "\\xA5"; + case 166: + return "\\xA6"; + case 167: + return "\\xA7"; + case 168: + return "\\xA8"; + case 169: + return "\\xA9"; + case 170: + return "\\xAA"; + case 171: + return "\\xAB"; + case 172: + return "\\xAC"; + case 173: + return "\\xAD"; + case 174: + return "\\xAE"; + case 175: + return "\\xAF"; + case 176: + return "\\xB0"; + case 177: + return "\\xB1"; + case 178: + return "\\xB2"; + case 179: + return "\\xB3"; + case 180: + return "\\xB4"; + case 181: + return "\\xB5"; + case 182: + return "\\xB6"; + case 183: + return "\\xB7"; + case 184: + return "\\xB8"; + case 185: + return "\\xB9"; + case 186: + return "\\xBA"; + case 187: + return "\\xBB"; + case 188: + return "\\xBC"; + case 189: + return "\\xBD"; + case 190: + return "\\xBE"; + case 191: + return "\\xBF"; + case 192: + return "\\xC0"; + case 193: + return "\\xC1"; + case 194: + return "\\xC2"; + case 195: + return "\\xC3"; + case 196: + return "\\xC4"; + case 197: + return "\\xC5"; + case 198: + return "\\xC6"; + case 199: + return "\\xC7"; + case 200: + return "\\xC8"; + case 201: + return "\\xC9"; + case 202: + return "\\xCA"; + case 203: + return "\\xCB"; + case 204: + return "\\xCC"; + case 205: + return "\\xCD"; + case 206: + return "\\xCE"; + case 207: + return "\\xCF"; + case 208: + return "\\xD0"; + case 209: + return "\\xD1"; + case 210: + return "\\xD2"; + case 211: + return "\\xD3"; + case 212: + return "\\xD4"; + case 213: + return "\\xD5"; + case 214: + return "\\xD6"; + case 215: + return "\\xD7"; + case 216: + return "\\xD8"; + case 217: + return "\\xD9"; + case 218: + return "\\xDA"; + case 219: + return "\\xDB"; + case 220: + return "\\xDC"; + case 221: + return "\\xDD"; + case 222: + return "\\xDE"; + case 223: + return "\\xDF"; + case 224: + return "\\xE0"; + case 225: + return "\\xE1"; + case 226: + return "\\xE2"; + case 227: + return "\\xE3"; + case 228: + return "\\xE4"; + case 229: + return "\\xE5"; + case 230: + return "\\xE6"; + case 231: + return "\\xE7"; + case 232: + return "\\xE8"; + case 233: + return "\\xE9"; + case 234: + return "\\xEA"; + case 235: + return "\\xEB"; + case 236: + return "\\xEC"; + case 237: + return "\\xED"; + case 238: + return "\\xEE"; + case 239: + return "\\xEF"; + case 240: + return "\\xF0"; + case 241: + return "\\xF1"; + case 242: + return "\\xF2"; + case 243: + return "\\xF3"; + case 244: + return "\\xF4"; + case 245: + return "\\xF5"; + case 246: + return "\\xF6"; + case 247: + return "\\xF7"; + case 248: + return "\\xF8"; + case 249: + return "\\xF9"; + case 250: + return "\\xFA"; + case 251: + return "\\xFB"; + case 252: + return "\\xFC"; + case 253: + return "\\xFD"; + case 254: + return "\\xFE"; + case 255: + return "\\xFF"; + default: + assert(0); /* never gets here */ + return "dead code"; + } + assert(0); /* never gets here */ +} + +#endif /* XML_GE == 1 */ + +static unsigned long +getDebugLevel(const char *variableName, unsigned long defaultDebugLevel) { + const char *const valueOrNull = getenv(variableName); + if (valueOrNull == NULL) { + return defaultDebugLevel; + } + const char *const value = valueOrNull; + + char *afterValue = NULL; + unsigned long debugLevel = strtoul(value, &afterValue, 10); + + return debugLevel; +} + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/xmlrole.c b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmlrole.c new file mode 100644 index 000000000..5424f693a --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmlrole.c @@ -0,0 +1,1261 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2002 Greg Stein + Copyright (c) 2002-2006 Karl Waclawek + Copyright (c) 2002-2003 Fred L. Drake, Jr. + Copyright (c) 2005-2009 Steven Solie + Copyright (c) 2016-2023 Sebastian Pipping + Copyright (c) 2017 Rhodri James + Copyright (c) 2019 David Loffredo + Copyright (c) 2021 Donghee Na + Licensed under the MIT license: + + 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_XML + +#include "expat_config.h" + +#include + +#ifdef _WIN32 +# include "winconfig.h" +#endif + +#include "expat_external.h" +#include "internal.h" +#include "xmlrole.h" +#include "ascii.h" + +/* Doesn't check: + + that ,| are not mixed in a model group + content of literals + +*/ + +static const char KW_ANY[] = {ASCII_A, ASCII_N, ASCII_Y, '\0'}; +static const char KW_ATTLIST[] + = {ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0'}; +static const char KW_CDATA[] + = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; +static const char KW_DOCTYPE[] + = {ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0'}; +static const char KW_ELEMENT[] + = {ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0'}; +static const char KW_EMPTY[] + = {ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0'}; +static const char KW_ENTITIES[] = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, + ASCII_I, ASCII_E, ASCII_S, '\0'}; +static const char KW_ENTITY[] + = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'}; +static const char KW_FIXED[] + = {ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0'}; +static const char KW_ID[] = {ASCII_I, ASCII_D, '\0'}; +static const char KW_IDREF[] + = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'}; +static const char KW_IDREFS[] + = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'}; +#ifdef XML_DTD +static const char KW_IGNORE[] + = {ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0'}; +#endif +static const char KW_IMPLIED[] + = {ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0'}; +#ifdef XML_DTD +static const char KW_INCLUDE[] + = {ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0'}; +#endif +static const char KW_NDATA[] + = {ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; +static const char KW_NMTOKEN[] + = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'}; +static const char KW_NMTOKENS[] = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, + ASCII_E, ASCII_N, ASCII_S, '\0'}; +static const char KW_NOTATION[] = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, + ASCII_I, ASCII_O, ASCII_N, '\0'}; +static const char KW_PCDATA[] + = {ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; +static const char KW_PUBLIC[] + = {ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0'}; +static const char KW_REQUIRED[] = {ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, + ASCII_R, ASCII_E, ASCII_D, '\0'}; +static const char KW_SYSTEM[] + = {ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0'}; + +#ifndef MIN_BYTES_PER_CHAR +# define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) +#endif + +#ifdef XML_DTD +# define setTopLevel(state) \ + ((state)->handler \ + = ((state)->documentEntity ? internalSubset : externalSubset1)) +#else /* not XML_DTD */ +# define setTopLevel(state) ((state)->handler = internalSubset) +#endif /* not XML_DTD */ + +typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state, int tok, + const char *ptr, const char *end, + const ENCODING *enc); + +static PROLOG_HANDLER prolog0, prolog1, prolog2, doctype0, doctype1, doctype2, + doctype3, doctype4, doctype5, internalSubset, entity0, entity1, entity2, + entity3, entity4, entity5, entity6, entity7, entity8, entity9, entity10, + notation0, notation1, notation2, notation3, notation4, attlist0, attlist1, + attlist2, attlist3, attlist4, attlist5, attlist6, attlist7, attlist8, + attlist9, element0, element1, element2, element3, element4, element5, + element6, element7, +#ifdef XML_DTD + externalSubset0, externalSubset1, condSect0, condSect1, condSect2, +#endif /* XML_DTD */ + declClose, error; + +static int FASTCALL common(PROLOG_STATE *state, int tok); + +static int PTRCALL +prolog0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + state->handler = prolog1; + return XML_ROLE_NONE; + case XML_TOK_XML_DECL: + state->handler = prolog1; + return XML_ROLE_XML_DECL; + case XML_TOK_PI: + state->handler = prolog1; + return XML_ROLE_PI; + case XML_TOK_COMMENT: + state->handler = prolog1; + return XML_ROLE_COMMENT; + case XML_TOK_BOM: + return XML_ROLE_NONE; + case XML_TOK_DECL_OPEN: + if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, + KW_DOCTYPE)) + break; + state->handler = doctype0; + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_INSTANCE_START: + state->handler = error; + return XML_ROLE_INSTANCE_START; + } + return common(state, tok); +} + +static int PTRCALL +prolog1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_PI: + return XML_ROLE_PI; + case XML_TOK_COMMENT: + return XML_ROLE_COMMENT; + case XML_TOK_BOM: + /* This case can never arise. To reach this role function, the + * parse must have passed through prolog0 and therefore have had + * some form of input, even if only a space. At that point, a + * byte order mark is no longer a valid character (though + * technically it should be interpreted as a non-breaking space), + * so will be rejected by the tokenizing stages. + */ + return XML_ROLE_NONE; /* LCOV_EXCL_LINE */ + case XML_TOK_DECL_OPEN: + if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, + KW_DOCTYPE)) + break; + state->handler = doctype0; + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_INSTANCE_START: + state->handler = error; + return XML_ROLE_INSTANCE_START; + } + return common(state, tok); +} + +static int PTRCALL +prolog2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_PI: + return XML_ROLE_PI; + case XML_TOK_COMMENT: + return XML_ROLE_COMMENT; + case XML_TOK_INSTANCE_START: + state->handler = error; + return XML_ROLE_INSTANCE_START; + } + return common(state, tok); +} + +static int PTRCALL +doctype0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = doctype1; + return XML_ROLE_DOCTYPE_NAME; + } + return common(state, tok); +} + +static int PTRCALL +doctype1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = internalSubset; + return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; + case XML_TOK_DECL_CLOSE: + state->handler = prolog2; + return XML_ROLE_DOCTYPE_CLOSE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = doctype3; + return XML_ROLE_DOCTYPE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = doctype2; + return XML_ROLE_DOCTYPE_NONE; + } + break; + } + return common(state, tok); +} + +static int PTRCALL +doctype2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_LITERAL: + state->handler = doctype3; + return XML_ROLE_DOCTYPE_PUBLIC_ID; + } + return common(state, tok); +} + +static int PTRCALL +doctype3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_LITERAL: + state->handler = doctype4; + return XML_ROLE_DOCTYPE_SYSTEM_ID; + } + return common(state, tok); +} + +static int PTRCALL +doctype4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = internalSubset; + return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; + case XML_TOK_DECL_CLOSE: + state->handler = prolog2; + return XML_ROLE_DOCTYPE_CLOSE; + } + return common(state, tok); +} + +static int PTRCALL +doctype5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_DECL_CLOSE: + state->handler = prolog2; + return XML_ROLE_DOCTYPE_CLOSE; + } + return common(state, tok); +} + +static int PTRCALL +internalSubset(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_DECL_OPEN: + if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, + KW_ENTITY)) { + state->handler = entity0; + return XML_ROLE_ENTITY_NONE; + } + if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, + KW_ATTLIST)) { + state->handler = attlist0; + return XML_ROLE_ATTLIST_NONE; + } + if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, + KW_ELEMENT)) { + state->handler = element0; + return XML_ROLE_ELEMENT_NONE; + } + if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end, + KW_NOTATION)) { + state->handler = notation0; + return XML_ROLE_NOTATION_NONE; + } + break; + case XML_TOK_PI: + return XML_ROLE_PI; + case XML_TOK_COMMENT: + return XML_ROLE_COMMENT; + case XML_TOK_PARAM_ENTITY_REF: + return XML_ROLE_PARAM_ENTITY_REF; + case XML_TOK_CLOSE_BRACKET: + state->handler = doctype5; + return XML_ROLE_DOCTYPE_NONE; + case XML_TOK_NONE: + return XML_ROLE_NONE; + } + return common(state, tok); +} + +#ifdef XML_DTD + +static int PTRCALL +externalSubset0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + state->handler = externalSubset1; + if (tok == XML_TOK_XML_DECL) + return XML_ROLE_TEXT_DECL; + return externalSubset1(state, tok, ptr, end, enc); +} + +static int PTRCALL +externalSubset1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_COND_SECT_OPEN: + state->handler = condSect0; + return XML_ROLE_NONE; + case XML_TOK_COND_SECT_CLOSE: + if (state->includeLevel == 0) + break; + state->includeLevel -= 1; + return XML_ROLE_NONE; + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_BRACKET: + break; + case XML_TOK_NONE: + if (state->includeLevel) + break; + return XML_ROLE_NONE; + default: + return internalSubset(state, tok, ptr, end, enc); + } + return common(state, tok); +} + +#endif /* XML_DTD */ + +static int PTRCALL +entity0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_PERCENT: + state->handler = entity1; + return XML_ROLE_ENTITY_NONE; + case XML_TOK_NAME: + state->handler = entity2; + return XML_ROLE_GENERAL_ENTITY_NAME; + } + return common(state, tok); +} + +static int PTRCALL +entity1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_NAME: + state->handler = entity7; + return XML_ROLE_PARAM_ENTITY_NAME; + } + return common(state, tok); +} + +static int PTRCALL +entity2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = entity4; + return XML_ROLE_ENTITY_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = entity3; + return XML_ROLE_ENTITY_NONE; + } + break; + case XML_TOK_LITERAL: + state->handler = declClose; + state->role_none = XML_ROLE_ENTITY_NONE; + return XML_ROLE_ENTITY_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +entity3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_LITERAL: + state->handler = entity4; + return XML_ROLE_ENTITY_PUBLIC_ID; + } + return common(state, tok); +} + +static int PTRCALL +entity4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_LITERAL: + state->handler = entity5; + return XML_ROLE_ENTITY_SYSTEM_ID; + } + return common(state, tok); +} + +static int PTRCALL +entity5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_ENTITY_COMPLETE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) { + state->handler = entity6; + return XML_ROLE_ENTITY_NONE; + } + break; + } + return common(state, tok); +} + +static int PTRCALL +entity6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_NAME: + state->handler = declClose; + state->role_none = XML_ROLE_ENTITY_NONE; + return XML_ROLE_ENTITY_NOTATION_NAME; + } + return common(state, tok); +} + +static int PTRCALL +entity7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = entity9; + return XML_ROLE_ENTITY_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = entity8; + return XML_ROLE_ENTITY_NONE; + } + break; + case XML_TOK_LITERAL: + state->handler = declClose; + state->role_none = XML_ROLE_ENTITY_NONE; + return XML_ROLE_ENTITY_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +entity8(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_LITERAL: + state->handler = entity9; + return XML_ROLE_ENTITY_PUBLIC_ID; + } + return common(state, tok); +} + +static int PTRCALL +entity9(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_LITERAL: + state->handler = entity10; + return XML_ROLE_ENTITY_SYSTEM_ID; + } + return common(state, tok); +} + +static int PTRCALL +entity10(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ENTITY_NONE; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_ENTITY_COMPLETE; + } + return common(state, tok); +} + +static int PTRCALL +notation0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NOTATION_NONE; + case XML_TOK_NAME: + state->handler = notation1; + return XML_ROLE_NOTATION_NAME; + } + return common(state, tok); +} + +static int PTRCALL +notation1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NOTATION_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { + state->handler = notation3; + return XML_ROLE_NOTATION_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { + state->handler = notation2; + return XML_ROLE_NOTATION_NONE; + } + break; + } + return common(state, tok); +} + +static int PTRCALL +notation2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NOTATION_NONE; + case XML_TOK_LITERAL: + state->handler = notation4; + return XML_ROLE_NOTATION_PUBLIC_ID; + } + return common(state, tok); +} + +static int PTRCALL +notation3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NOTATION_NONE; + case XML_TOK_LITERAL: + state->handler = declClose; + state->role_none = XML_ROLE_NOTATION_NONE; + return XML_ROLE_NOTATION_SYSTEM_ID; + } + return common(state, tok); +} + +static int PTRCALL +notation4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NOTATION_NONE; + case XML_TOK_LITERAL: + state->handler = declClose; + state->role_none = XML_ROLE_NOTATION_NONE; + return XML_ROLE_NOTATION_SYSTEM_ID; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_NOTATION_NO_SYSTEM_ID; + } + return common(state, tok); +} + +static int PTRCALL +attlist0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = attlist1; + return XML_ROLE_ATTLIST_ELEMENT_NAME; + } + return common(state, tok); +} + +static int PTRCALL +attlist1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = attlist2; + return XML_ROLE_ATTRIBUTE_NAME; + } + return common(state, tok); +} + +static int PTRCALL +attlist2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_NAME: { + static const char *const types[] = { + KW_CDATA, KW_ID, KW_IDREF, KW_IDREFS, + KW_ENTITY, KW_ENTITIES, KW_NMTOKEN, KW_NMTOKENS, + }; + int i; + for (i = 0; i < (int)(sizeof(types) / sizeof(types[0])); i++) + if (XmlNameMatchesAscii(enc, ptr, end, types[i])) { + state->handler = attlist8; + return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; + } + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) { + state->handler = attlist5; + return XML_ROLE_ATTLIST_NONE; + } + break; + case XML_TOK_OPEN_PAREN: + state->handler = attlist3; + return XML_ROLE_ATTLIST_NONE; + } + return common(state, tok); +} + +static int PTRCALL +attlist3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_NMTOKEN: + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = attlist4; + return XML_ROLE_ATTRIBUTE_ENUM_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +attlist4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_CLOSE_PAREN: + state->handler = attlist8; + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_OR: + state->handler = attlist3; + return XML_ROLE_ATTLIST_NONE; + } + return common(state, tok); +} + +static int PTRCALL +attlist5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_OPEN_PAREN: + state->handler = attlist6; + return XML_ROLE_ATTLIST_NONE; + } + return common(state, tok); +} + +static int PTRCALL +attlist6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_NAME: + state->handler = attlist7; + return XML_ROLE_ATTRIBUTE_NOTATION_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +attlist7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_CLOSE_PAREN: + state->handler = attlist8; + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_OR: + state->handler = attlist6; + return XML_ROLE_ATTLIST_NONE; + } + return common(state, tok); +} + +/* default value */ +static int PTRCALL +attlist8(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_POUND_NAME: + if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, + KW_IMPLIED)) { + state->handler = attlist1; + return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE; + } + if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, + KW_REQUIRED)) { + state->handler = attlist1; + return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE; + } + if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, + KW_FIXED)) { + state->handler = attlist9; + return XML_ROLE_ATTLIST_NONE; + } + break; + case XML_TOK_LITERAL: + state->handler = attlist1; + return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +attlist9(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ATTLIST_NONE; + case XML_TOK_LITERAL: + state->handler = attlist1; + return XML_ROLE_FIXED_ATTRIBUTE_VALUE; + } + return common(state, tok); +} + +static int PTRCALL +element0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element1; + return XML_ROLE_ELEMENT_NAME; + } + return common(state, tok); +} + +static int PTRCALL +element1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + return XML_ROLE_CONTENT_EMPTY; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + return XML_ROLE_CONTENT_ANY; + } + break; + case XML_TOK_OPEN_PAREN: + state->handler = element2; + state->level = 1; + return XML_ROLE_GROUP_OPEN; + } + return common(state, tok); +} + +static int PTRCALL +element2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_POUND_NAME: + if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end, + KW_PCDATA)) { + state->handler = element3; + return XML_ROLE_CONTENT_PCDATA; + } + break; + case XML_TOK_OPEN_PAREN: + state->level = 2; + state->handler = element6; + return XML_ROLE_GROUP_OPEN; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT; + case XML_TOK_NAME_QUESTION: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_OPT; + case XML_TOK_NAME_ASTERISK: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_REP; + case XML_TOK_NAME_PLUS: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_PLUS; + } + return common(state, tok); +} + +static int PTRCALL +element3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_CLOSE_PAREN: + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + return XML_ROLE_GROUP_CLOSE; + case XML_TOK_CLOSE_PAREN_ASTERISK: + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + return XML_ROLE_GROUP_CLOSE_REP; + case XML_TOK_OR: + state->handler = element4; + return XML_ROLE_ELEMENT_NONE; + } + return common(state, tok); +} + +static int PTRCALL +element4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element5; + return XML_ROLE_CONTENT_ELEMENT; + } + return common(state, tok); +} + +static int PTRCALL +element5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_CLOSE_PAREN_ASTERISK: + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + return XML_ROLE_GROUP_CLOSE_REP; + case XML_TOK_OR: + state->handler = element4; + return XML_ROLE_ELEMENT_NONE; + } + return common(state, tok); +} + +static int PTRCALL +element6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_OPEN_PAREN: + state->level += 1; + return XML_ROLE_GROUP_OPEN; + case XML_TOK_NAME: + case XML_TOK_PREFIXED_NAME: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT; + case XML_TOK_NAME_QUESTION: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_OPT; + case XML_TOK_NAME_ASTERISK: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_REP; + case XML_TOK_NAME_PLUS: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_PLUS; + } + return common(state, tok); +} + +static int PTRCALL +element7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_ELEMENT_NONE; + case XML_TOK_CLOSE_PAREN: + state->level -= 1; + if (state->level == 0) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + } + return XML_ROLE_GROUP_CLOSE; + case XML_TOK_CLOSE_PAREN_ASTERISK: + state->level -= 1; + if (state->level == 0) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + } + return XML_ROLE_GROUP_CLOSE_REP; + case XML_TOK_CLOSE_PAREN_QUESTION: + state->level -= 1; + if (state->level == 0) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + } + return XML_ROLE_GROUP_CLOSE_OPT; + case XML_TOK_CLOSE_PAREN_PLUS: + state->level -= 1; + if (state->level == 0) { + state->handler = declClose; + state->role_none = XML_ROLE_ELEMENT_NONE; + } + return XML_ROLE_GROUP_CLOSE_PLUS; + case XML_TOK_COMMA: + state->handler = element6; + return XML_ROLE_GROUP_SEQUENCE; + case XML_TOK_OR: + state->handler = element6; + return XML_ROLE_GROUP_CHOICE; + } + return common(state, tok); +} + +#ifdef XML_DTD + +static int PTRCALL +condSect0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) { + state->handler = condSect1; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) { + state->handler = condSect2; + return XML_ROLE_NONE; + } + break; + } + return common(state, tok); +} + +static int PTRCALL +condSect1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = externalSubset1; + state->includeLevel += 1; + return XML_ROLE_NONE; + } + return common(state, tok); +} + +static int PTRCALL +condSect2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = externalSubset1; + return XML_ROLE_IGNORE_SECT; + } + return common(state, tok); +} + +#endif /* XML_DTD */ + +static int PTRCALL +declClose(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + switch (tok) { + case XML_TOK_PROLOG_S: + return state->role_none; + case XML_TOK_DECL_CLOSE: + setTopLevel(state); + return state->role_none; + } + return common(state, tok); +} + +/* This function will only be invoked if the internal logic of the + * parser has broken down. It is used in two cases: + * + * 1: When the XML prolog has been finished. At this point the + * processor (the parser level above these role handlers) should + * switch from prologProcessor to contentProcessor and reinitialise + * the handler function. + * + * 2: When an error has been detected (via common() below). At this + * point again the processor should be switched to errorProcessor, + * which will never call a handler. + * + * The result of this is that error() can only be called if the + * processor switch failed to happen, which is an internal error and + * therefore we shouldn't be able to provoke it simply by using the + * library. It is a necessary backstop, however, so we merely exclude + * it from the coverage statistics. + * + * LCOV_EXCL_START + */ +static int PTRCALL +error(PROLOG_STATE *state, int tok, const char *ptr, const char *end, + const ENCODING *enc) { + UNUSED_P(state); + UNUSED_P(tok); + UNUSED_P(ptr); + UNUSED_P(end); + UNUSED_P(enc); + return XML_ROLE_NONE; +} +/* LCOV_EXCL_STOP */ + +static int FASTCALL +common(PROLOG_STATE *state, int tok) { +#ifdef XML_DTD + if (! state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF) + return XML_ROLE_INNER_PARAM_ENTITY_REF; +#else + UNUSED_P(tok); +#endif + state->handler = error; + return XML_ROLE_ERROR; +} + +void +XmlPrologStateInit(PROLOG_STATE *state) { + state->handler = prolog0; +#ifdef XML_DTD + state->documentEntity = 1; + state->includeLevel = 0; + state->inEntityValue = 0; +#endif /* XML_DTD */ +} + +#ifdef XML_DTD + +void +XmlPrologStateInitExternalEntity(PROLOG_STATE *state) { + state->handler = externalSubset0; + state->documentEntity = 0; + state->includeLevel = 0; +} + +#endif /* XML_DTD */ + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/xmlrole.h b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmlrole.h new file mode 100644 index 000000000..587840b54 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmlrole.h @@ -0,0 +1,148 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2002 Karl Waclawek + Copyright (c) 2002 Fred L. Drake, Jr. + Copyright (c) 2017-2024 Sebastian Pipping + Licensed under the MIT license: + + 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_XML + +#ifndef XmlRole_INCLUDED +#define XmlRole_INCLUDED 1 + +#ifdef __VMS +/* 0 1 2 3 0 1 2 3 + 1234567890123456789012345678901 1234567890123456789012345678901 */ +# define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt +#endif + +#include "xmltok.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + XML_ROLE_ERROR = -1, + XML_ROLE_NONE = 0, + XML_ROLE_XML_DECL, + XML_ROLE_INSTANCE_START, + XML_ROLE_DOCTYPE_NONE, + XML_ROLE_DOCTYPE_NAME, + XML_ROLE_DOCTYPE_SYSTEM_ID, + XML_ROLE_DOCTYPE_PUBLIC_ID, + XML_ROLE_DOCTYPE_INTERNAL_SUBSET, + XML_ROLE_DOCTYPE_CLOSE, + XML_ROLE_GENERAL_ENTITY_NAME, + XML_ROLE_PARAM_ENTITY_NAME, + XML_ROLE_ENTITY_NONE, + XML_ROLE_ENTITY_VALUE, + XML_ROLE_ENTITY_SYSTEM_ID, + XML_ROLE_ENTITY_PUBLIC_ID, + XML_ROLE_ENTITY_COMPLETE, + XML_ROLE_ENTITY_NOTATION_NAME, + XML_ROLE_NOTATION_NONE, + XML_ROLE_NOTATION_NAME, + XML_ROLE_NOTATION_SYSTEM_ID, + XML_ROLE_NOTATION_NO_SYSTEM_ID, + XML_ROLE_NOTATION_PUBLIC_ID, + XML_ROLE_ATTRIBUTE_NAME, + XML_ROLE_ATTRIBUTE_TYPE_CDATA, + XML_ROLE_ATTRIBUTE_TYPE_ID, + XML_ROLE_ATTRIBUTE_TYPE_IDREF, + XML_ROLE_ATTRIBUTE_TYPE_IDREFS, + XML_ROLE_ATTRIBUTE_TYPE_ENTITY, + XML_ROLE_ATTRIBUTE_TYPE_ENTITIES, + XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN, + XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS, + XML_ROLE_ATTRIBUTE_ENUM_VALUE, + XML_ROLE_ATTRIBUTE_NOTATION_VALUE, + XML_ROLE_ATTLIST_NONE, + XML_ROLE_ATTLIST_ELEMENT_NAME, + XML_ROLE_IMPLIED_ATTRIBUTE_VALUE, + XML_ROLE_REQUIRED_ATTRIBUTE_VALUE, + XML_ROLE_DEFAULT_ATTRIBUTE_VALUE, + XML_ROLE_FIXED_ATTRIBUTE_VALUE, + XML_ROLE_ELEMENT_NONE, + XML_ROLE_ELEMENT_NAME, + XML_ROLE_CONTENT_ANY, + XML_ROLE_CONTENT_EMPTY, + XML_ROLE_CONTENT_PCDATA, + XML_ROLE_GROUP_OPEN, + XML_ROLE_GROUP_CLOSE, + XML_ROLE_GROUP_CLOSE_REP, + XML_ROLE_GROUP_CLOSE_OPT, + XML_ROLE_GROUP_CLOSE_PLUS, + XML_ROLE_GROUP_CHOICE, + XML_ROLE_GROUP_SEQUENCE, + XML_ROLE_CONTENT_ELEMENT, + XML_ROLE_CONTENT_ELEMENT_REP, + XML_ROLE_CONTENT_ELEMENT_OPT, + XML_ROLE_CONTENT_ELEMENT_PLUS, + XML_ROLE_PI, + XML_ROLE_COMMENT, +#ifdef XML_DTD + XML_ROLE_TEXT_DECL, + XML_ROLE_IGNORE_SECT, + XML_ROLE_INNER_PARAM_ENTITY_REF, +#endif /* XML_DTD */ + XML_ROLE_PARAM_ENTITY_REF +}; + +typedef struct prolog_state { + int(PTRCALL *handler)(struct prolog_state *state, int tok, const char *ptr, + const char *end, const ENCODING *enc); + unsigned level; + int role_none; +#ifdef XML_DTD + unsigned includeLevel; + int documentEntity; + int inEntityValue; +#endif /* XML_DTD */ +} PROLOG_STATE; + +void XmlPrologStateInit(PROLOG_STATE *state); +#ifdef XML_DTD +void XmlPrologStateInitExternalEntity(PROLOG_STATE *state); +#endif /* XML_DTD */ + +#define XmlTokenRole(state, tok, ptr, end, enc) \ + (((state)->handler)(state, tok, ptr, end, enc)) + +#ifdef __cplusplus +} +#endif + +#endif /* not XmlRole_INCLUDED */ + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok.c b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok.c new file mode 100644 index 000000000..c8e265996 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok.c @@ -0,0 +1,1678 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2001-2003 Fred L. Drake, Jr. + Copyright (c) 2002 Greg Stein + Copyright (c) 2002-2016 Karl Waclawek + Copyright (c) 2005-2009 Steven Solie + Copyright (c) 2016-2024 Sebastian Pipping + Copyright (c) 2016 Pascal Cuoq + Copyright (c) 2016 Don Lewis + Copyright (c) 2017 Rhodri James + Copyright (c) 2017 Alexander Bluhm + Copyright (c) 2017 Benbuck Nason + Copyright (c) 2017 José Gutiérrez de la Concha + Copyright (c) 2019 David Loffredo + Copyright (c) 2021 Donghee Na + Copyright (c) 2022 Martin Ettl + Copyright (c) 2022 Sean McBride + Copyright (c) 2023 Hanno Böck + Licensed under the MIT license: + + 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_XML + +#include "expat_config.h" + +#include +#include /* memcpy */ +#include + +#ifdef _WIN32 +# include "winconfig.h" +#endif + +#include "expat_external.h" +#include "internal.h" +#include "xmltok.h" +#include "nametab.h" + +#ifdef XML_DTD +# define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok) +#else +# define IGNORE_SECTION_TOK_VTABLE /* as nothing */ +#endif + +#define VTABLE1 \ + {PREFIX(prologTok), PREFIX(contentTok), \ + PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE}, \ + {PREFIX(attributeValueTok), PREFIX(entityValueTok)}, \ + PREFIX(nameMatchesAscii), PREFIX(nameLength), PREFIX(skipS), \ + PREFIX(getAtts), PREFIX(charRefNumber), PREFIX(predefinedEntityName), \ + PREFIX(updatePosition), PREFIX(isPublicId) + +#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) + +#define UCS2_GET_NAMING(pages, hi, lo) \ + (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F))) + +/* A 2 byte UTF-8 representation splits the characters 11 bits between + the bottom 5 and 6 bits of the bytes. We need 8 bits to index into + pages, 3 bits to add to that index and 5 bits to generate the mask. +*/ +#define UTF8_GET_NAMING2(pages, byte) \ + (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ + + ((((byte)[0]) & 3) << 1) + ((((byte)[1]) >> 5) & 1)] \ + & (1u << (((byte)[1]) & 0x1F))) + +/* A 3 byte UTF-8 representation splits the characters 16 bits between + the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index + into pages, 3 bits to add to that index and 5 bits to generate the + mask. +*/ +#define UTF8_GET_NAMING3(pages, byte) \ + (namingBitmap \ + [((pages)[((((byte)[0]) & 0xF) << 4) + ((((byte)[1]) >> 2) & 0xF)] \ + << 3) \ + + ((((byte)[1]) & 3) << 1) + ((((byte)[2]) >> 5) & 1)] \ + & (1u << (((byte)[2]) & 0x1F))) + +/* Detection of invalid UTF-8 sequences is based on Table 3.1B + of Unicode 3.2: https://www.unicode.org/unicode/reports/tr28/ + with the additional restriction of not allowing the Unicode + code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE). + Implementation details: + (A & 0x80) == 0 means A < 0x80 + and + (A & 0xC0) == 0xC0 means A > 0xBF +*/ + +#define UTF8_INVALID2(p) \ + ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0) + +#define UTF8_INVALID3(p) \ + (((p)[2] & 0x80) == 0 \ + || ((*p) == 0xEF && (p)[1] == 0xBF ? (p)[2] > 0xBD \ + : ((p)[2] & 0xC0) == 0xC0) \ + || ((*p) == 0xE0 \ + ? (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \ + : ((p)[1] & 0x80) == 0 \ + || ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0))) + +#define UTF8_INVALID4(p) \ + (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 || ((p)[2] & 0x80) == 0 \ + || ((p)[2] & 0xC0) == 0xC0 \ + || ((*p) == 0xF0 \ + ? (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \ + : ((p)[1] & 0x80) == 0 \ + || ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0))) + +static int PTRFASTCALL +isNever(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + UNUSED_P(p); + return 0; +} + +static int PTRFASTCALL +utf8_isName2(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isName3(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); +} + +#define utf8_isName4 isNever + +static int PTRFASTCALL +utf8_isNmstrt2(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isNmstrt3(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); +} + +#define utf8_isNmstrt4 isNever + +static int PTRFASTCALL +utf8_isInvalid2(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return UTF8_INVALID2((const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isInvalid3(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return UTF8_INVALID3((const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isInvalid4(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return UTF8_INVALID4((const unsigned char *)p); +} + +struct normal_encoding { + ENCODING enc; + unsigned char type[256]; +#ifdef XML_MIN_SIZE + int(PTRFASTCALL *byteType)(const ENCODING *, const char *); + int(PTRFASTCALL *isNameMin)(const ENCODING *, const char *); + int(PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *); + int(PTRFASTCALL *byteToAscii)(const ENCODING *, const char *); + int(PTRCALL *charMatches)(const ENCODING *, const char *, int); +#endif /* XML_MIN_SIZE */ + int(PTRFASTCALL *isName2)(const ENCODING *, const char *); + int(PTRFASTCALL *isName3)(const ENCODING *, const char *); + int(PTRFASTCALL *isName4)(const ENCODING *, const char *); + int(PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *); + int(PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *); + int(PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *); + int(PTRFASTCALL *isInvalid2)(const ENCODING *, const char *); + int(PTRFASTCALL *isInvalid3)(const ENCODING *, const char *); + int(PTRFASTCALL *isInvalid4)(const ENCODING *, const char *); +}; + +#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *)(enc)) + +#ifdef XML_MIN_SIZE + +# define STANDARD_VTABLE(E) \ + E##byteType, E##isNameMin, E##isNmstrtMin, E##byteToAscii, E##charMatches, + +#else + +# define STANDARD_VTABLE(E) /* as nothing */ + +#endif + +#define NORMAL_VTABLE(E) \ + E##isName2, E##isName3, E##isName4, E##isNmstrt2, E##isNmstrt3, \ + E##isNmstrt4, E##isInvalid2, E##isInvalid3, E##isInvalid4 + +#define NULL_VTABLE \ + /* isName2 */ NULL, /* isName3 */ NULL, /* isName4 */ NULL, \ + /* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL, \ + /* isInvalid2 */ NULL, /* isInvalid3 */ NULL, /* isInvalid4 */ NULL + +static int FASTCALL checkCharRefNumber(int result); + +#include "xmltok_impl.h" +#include "ascii.h" + +#ifdef XML_MIN_SIZE +# define sb_isNameMin isNever +# define sb_isNmstrtMin isNever +#endif + +#ifdef XML_MIN_SIZE +# define MINBPC(enc) ((enc)->minBytesPerChar) +#else +/* minimum bytes per character */ +# define MINBPC(enc) 1 +#endif + +#define SB_BYTE_TYPE(enc, p) \ + (((const struct normal_encoding *)(enc))->type[(unsigned char)*(p)]) + +#ifdef XML_MIN_SIZE +static int PTRFASTCALL +sb_byteType(const ENCODING *enc, const char *p) { + return SB_BYTE_TYPE(enc, p); +} +# define BYTE_TYPE(enc, p) (AS_NORMAL_ENCODING(enc)->byteType(enc, p)) +#else +# define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p) +#endif + +#ifdef XML_MIN_SIZE +# define BYTE_TO_ASCII(enc, p) (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p)) +static int PTRFASTCALL +sb_byteToAscii(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return *p; +} +#else +# define BYTE_TO_ASCII(enc, p) (*(p)) +#endif + +#define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p)) +#define IS_NMSTRT_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isNmstrt##n(enc, p)) +#ifdef XML_MIN_SIZE +# define IS_INVALID_CHAR(enc, p, n) \ + (AS_NORMAL_ENCODING(enc)->isInvalid##n \ + && AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p)) +#else +# define IS_INVALID_CHAR(enc, p, n) \ + (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p)) +#endif + +#ifdef XML_MIN_SIZE +# define IS_NAME_CHAR_MINBPC(enc, p) \ + (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p)) +# define IS_NMSTRT_CHAR_MINBPC(enc, p) \ + (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p)) +#else +# define IS_NAME_CHAR_MINBPC(enc, p) (0) +# define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) +#endif + +#ifdef XML_MIN_SIZE +# define CHAR_MATCHES(enc, p, c) \ + (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c)) +static int PTRCALL +sb_charMatches(const ENCODING *enc, const char *p, int c) { + UNUSED_P(enc); + return *p == c; +} +#else +/* c is an ASCII character */ +# define CHAR_MATCHES(enc, p, c) (*(p) == (c)) +#endif + +#define PREFIX(ident) normal_##ident +#define XML_TOK_IMPL_C +#include "xmltok_impl.c" +#undef XML_TOK_IMPL_C + +#undef MINBPC +#undef BYTE_TYPE +#undef BYTE_TO_ASCII +#undef CHAR_MATCHES +#undef IS_NAME_CHAR +#undef IS_NAME_CHAR_MINBPC +#undef IS_NMSTRT_CHAR +#undef IS_NMSTRT_CHAR_MINBPC +#undef IS_INVALID_CHAR + +enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ + UTF8_cval1 = 0x00, + UTF8_cval2 = 0xc0, + UTF8_cval3 = 0xe0, + UTF8_cval4 = 0xf0 +}; + +void +_INTERNAL_trim_to_complete_utf8_characters(const char *from, + const char **fromLimRef) { + const char *fromLim = *fromLimRef; + size_t walked = 0; + for (; fromLim > from; fromLim--, walked++) { + const unsigned char prev = (unsigned char)fromLim[-1]; + if ((prev & 0xf8u) + == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */ + if (walked + 1 >= 4) { + fromLim += 4 - 1; + break; + } else { + walked = 0; + } + } else if ((prev & 0xf0u) + == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */ + if (walked + 1 >= 3) { + fromLim += 3 - 1; + break; + } else { + walked = 0; + } + } else if ((prev & 0xe0u) + == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */ + if (walked + 1 >= 2) { + fromLim += 2 - 1; + break; + } else { + walked = 0; + } + } else if ((prev & 0x80u) + == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */ + break; + } + } + *fromLimRef = fromLim; +} + +static enum XML_Convert_Result PTRCALL +utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, + char **toP, const char *toLim) { + bool input_incomplete = false; + bool output_exhausted = false; + + /* Avoid copying partial characters (due to limited space). */ + const ptrdiff_t bytesAvailable = fromLim - *fromP; + const ptrdiff_t bytesStorable = toLim - *toP; + UNUSED_P(enc); + if (bytesAvailable > bytesStorable) { + fromLim = *fromP + bytesStorable; + output_exhausted = true; + } + + /* Avoid copying partial characters (from incomplete input). */ + { + const char *const fromLimBefore = fromLim; + _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim); + if (fromLim < fromLimBefore) { + input_incomplete = true; + } + } + + { + const ptrdiff_t bytesToCopy = fromLim - *fromP; + memcpy(*toP, *fromP, bytesToCopy); + *fromP += bytesToCopy; + *toP += bytesToCopy; + } + + if (output_exhausted) /* needs to go first */ + return XML_CONVERT_OUTPUT_EXHAUSTED; + else if (input_incomplete) + return XML_CONVERT_INPUT_INCOMPLETE; + else + return XML_CONVERT_COMPLETED; +} + +static enum XML_Convert_Result PTRCALL +utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) { + enum XML_Convert_Result res = XML_CONVERT_COMPLETED; + unsigned short *to = *toP; + const char *from = *fromP; + while (from < fromLim && to < toLim) { + switch (SB_BYTE_TYPE(enc, from)) { + case BT_LEAD2: + if (fromLim - from < 2) { + res = XML_CONVERT_INPUT_INCOMPLETE; + goto after; + } + *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f)); + from += 2; + break; + case BT_LEAD3: + if (fromLim - from < 3) { + res = XML_CONVERT_INPUT_INCOMPLETE; + goto after; + } + *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) + | (from[2] & 0x3f)); + from += 3; + break; + case BT_LEAD4: { + unsigned long n; + if (toLim - to < 2) { + res = XML_CONVERT_OUTPUT_EXHAUSTED; + goto after; + } + if (fromLim - from < 4) { + res = XML_CONVERT_INPUT_INCOMPLETE; + goto after; + } + n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) + | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); + n -= 0x10000; + to[0] = (unsigned short)((n >> 10) | 0xD800); + to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); + to += 2; + from += 4; + } break; + default: + *to++ = *from++; + break; + } + } + if (from < fromLim) + res = XML_CONVERT_OUTPUT_EXHAUSTED; +after: + *fromP = from; + *toP = to; + return res; +} + +#ifdef XML_NS +static const struct normal_encoding utf8_encoding_ns + = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, + { +# include "asciitab.h" +# include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; +#endif + +static const struct normal_encoding utf8_encoding + = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; + +#ifdef XML_NS + +static const struct normal_encoding internal_utf8_encoding_ns + = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, + { +# include "iasciitab.h" +# include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; + +#endif + +static const struct normal_encoding internal_utf8_encoding + = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0}, + { +#define BT_COLON BT_NMSTRT +#include "iasciitab.h" +#undef BT_COLON +#include "utf8tab.h" + }, + STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)}; + +static enum XML_Convert_Result PTRCALL +latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, + char **toP, const char *toLim) { + UNUSED_P(enc); + for (;;) { + unsigned char c; + if (*fromP == fromLim) + return XML_CONVERT_COMPLETED; + c = (unsigned char)**fromP; + if (c & 0x80) { + if (toLim - *toP < 2) + return XML_CONVERT_OUTPUT_EXHAUSTED; + *(*toP)++ = (char)((c >> 6) | UTF8_cval2); + *(*toP)++ = (char)((c & 0x3f) | 0x80); + (*fromP)++; + } else { + if (*toP == toLim) + return XML_CONVERT_OUTPUT_EXHAUSTED; + *(*toP)++ = *(*fromP)++; + } + } +} + +static enum XML_Convert_Result PTRCALL +latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) { + UNUSED_P(enc); + while (*fromP < fromLim && *toP < toLim) + *(*toP)++ = (unsigned char)*(*fromP)++; + + if ((*toP == toLim) && (*fromP < fromLim)) + return XML_CONVERT_OUTPUT_EXHAUSTED; + else + return XML_CONVERT_COMPLETED; +} + +#ifdef XML_NS + +static const struct normal_encoding latin1_encoding_ns + = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0}, + { +# include "asciitab.h" +# include "latin1tab.h" + }, + STANDARD_VTABLE(sb_) NULL_VTABLE}; + +#endif + +static const struct normal_encoding latin1_encoding + = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0}, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(sb_) NULL_VTABLE}; + +static enum XML_Convert_Result PTRCALL +ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, + char **toP, const char *toLim) { + UNUSED_P(enc); + while (*fromP < fromLim && *toP < toLim) + *(*toP)++ = *(*fromP)++; + + if ((*toP == toLim) && (*fromP < fromLim)) + return XML_CONVERT_OUTPUT_EXHAUSTED; + else + return XML_CONVERT_COMPLETED; +} + +#ifdef XML_NS + +static const struct normal_encoding ascii_encoding_ns + = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0}, + { +# include "asciitab.h" + /* BT_NONXML == 0 */ + }, + STANDARD_VTABLE(sb_) NULL_VTABLE}; + +#endif + +static const struct normal_encoding ascii_encoding + = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0}, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON + /* BT_NONXML == 0 */ + }, + STANDARD_VTABLE(sb_) NULL_VTABLE}; + +static int PTRFASTCALL +unicode_byte_type(char hi, char lo) { + switch ((unsigned char)hi) { + /* 0xD800-0xDBFF first 16-bit code unit or high surrogate (W1) */ + case 0xD8: + case 0xD9: + case 0xDA: + case 0xDB: + return BT_LEAD4; + /* 0xDC00-0xDFFF second 16-bit code unit or low surrogate (W2) */ + case 0xDC: + case 0xDD: + case 0xDE: + case 0xDF: + return BT_TRAIL; + case 0xFF: + switch ((unsigned char)lo) { + case 0xFF: /* noncharacter-FFFF */ + case 0xFE: /* noncharacter-FFFE */ + return BT_NONXML; + } + break; + } + return BT_NONASCII; +} + +#define DEFINE_UTF16_TO_UTF8(E) \ + static enum XML_Convert_Result PTRCALL E##toUtf8( \ + const ENCODING *enc, const char **fromP, const char *fromLim, \ + char **toP, const char *toLim) { \ + const char *from = *fromP; \ + UNUSED_P(enc); \ + fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \ + for (; from < fromLim; from += 2) { \ + int plane; \ + unsigned char lo2; \ + unsigned char lo = GET_LO(from); \ + unsigned char hi = GET_HI(from); \ + switch (hi) { \ + case 0: \ + if (lo < 0x80) { \ + if (*toP == toLim) { \ + *fromP = from; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + } \ + *(*toP)++ = lo; \ + break; \ + } \ + /* fall through */ \ + case 0x1: \ + case 0x2: \ + case 0x3: \ + case 0x4: \ + case 0x5: \ + case 0x6: \ + case 0x7: \ + if (toLim - *toP < 2) { \ + *fromP = from; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + } \ + *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ + *(*toP)++ = ((lo & 0x3f) | 0x80); \ + break; \ + default: \ + if (toLim - *toP < 3) { \ + *fromP = from; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + } \ + /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ + *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ + *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ + *(*toP)++ = ((lo & 0x3f) | 0x80); \ + break; \ + case 0xD8: \ + case 0xD9: \ + case 0xDA: \ + case 0xDB: \ + if (toLim - *toP < 4) { \ + *fromP = from; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + } \ + if (fromLim - from < 4) { \ + *fromP = from; \ + return XML_CONVERT_INPUT_INCOMPLETE; \ + } \ + plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ + *(*toP)++ = (char)((plane >> 2) | UTF8_cval4); \ + *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ + from += 2; \ + lo2 = GET_LO(from); \ + *(*toP)++ = (((lo & 0x3) << 4) | ((GET_HI(from) & 0x3) << 2) \ + | (lo2 >> 6) | 0x80); \ + *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ + break; \ + } \ + } \ + *fromP = from; \ + if (from < fromLim) \ + return XML_CONVERT_INPUT_INCOMPLETE; \ + else \ + return XML_CONVERT_COMPLETED; \ + } + +#define DEFINE_UTF16_TO_UTF16(E) \ + static enum XML_Convert_Result PTRCALL E##toUtf16( \ + const ENCODING *enc, const char **fromP, const char *fromLim, \ + unsigned short **toP, const unsigned short *toLim) { \ + enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \ + UNUSED_P(enc); \ + fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \ + /* Avoid copying first half only of surrogate */ \ + if (fromLim - *fromP > ((toLim - *toP) << 1) \ + && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \ + fromLim -= 2; \ + res = XML_CONVERT_INPUT_INCOMPLETE; \ + } \ + for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \ + *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ + if ((*toP == toLim) && (*fromP < fromLim)) \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + else \ + return res; \ + } + +#define GET_LO(ptr) ((unsigned char)(ptr)[0]) +#define GET_HI(ptr) ((unsigned char)(ptr)[1]) + +DEFINE_UTF16_TO_UTF8(little2_) +DEFINE_UTF16_TO_UTF16(little2_) + +#undef GET_LO +#undef GET_HI + +#define GET_LO(ptr) ((unsigned char)(ptr)[1]) +#define GET_HI(ptr) ((unsigned char)(ptr)[0]) + +DEFINE_UTF16_TO_UTF8(big2_) +DEFINE_UTF16_TO_UTF16(big2_) + +#undef GET_LO +#undef GET_HI + +#define LITTLE2_BYTE_TYPE(enc, p) \ + ((p)[1] == 0 ? SB_BYTE_TYPE(enc, p) : unicode_byte_type((p)[1], (p)[0])) +#define LITTLE2_BYTE_TO_ASCII(p) ((p)[1] == 0 ? (p)[0] : -1) +#define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == (c)) +#define LITTLE2_IS_NAME_CHAR_MINBPC(p) \ + UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) +#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) \ + UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0]) + +#ifdef XML_MIN_SIZE + +static int PTRFASTCALL +little2_byteType(const ENCODING *enc, const char *p) { + return LITTLE2_BYTE_TYPE(enc, p); +} + +static int PTRFASTCALL +little2_byteToAscii(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return LITTLE2_BYTE_TO_ASCII(p); +} + +static int PTRCALL +little2_charMatches(const ENCODING *enc, const char *p, int c) { + UNUSED_P(enc); + return LITTLE2_CHAR_MATCHES(p, c); +} + +static int PTRFASTCALL +little2_isNameMin(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return LITTLE2_IS_NAME_CHAR_MINBPC(p); +} + +static int PTRFASTCALL +little2_isNmstrtMin(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return LITTLE2_IS_NMSTRT_CHAR_MINBPC(p); +} + +# undef VTABLE +# define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16 + +#else /* not XML_MIN_SIZE */ + +# undef PREFIX +# define PREFIX(ident) little2_##ident +# define MINBPC(enc) 2 +/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ +# define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p) +# define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(p) +# define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(p, c) +# define IS_NAME_CHAR(enc, p, n) 0 +# define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p) +# define IS_NMSTRT_CHAR(enc, p, n) (0) +# define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p) + +# define XML_TOK_IMPL_C +# include "xmltok_impl.c" +# undef XML_TOK_IMPL_C + +# undef MINBPC +# undef BYTE_TYPE +# undef BYTE_TO_ASCII +# undef CHAR_MATCHES +# undef IS_NAME_CHAR +# undef IS_NAME_CHAR_MINBPC +# undef IS_NMSTRT_CHAR +# undef IS_NMSTRT_CHAR_MINBPC +# undef IS_INVALID_CHAR + +#endif /* not XML_MIN_SIZE */ + +#ifdef XML_NS + +static const struct normal_encoding little2_encoding_ns + = {{VTABLE, 2, 0, +# if BYTEORDER == 1234 + 1 +# else + 0 +# endif + }, + { +# include "asciitab.h" +# include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) NULL_VTABLE}; + +#endif + +static const struct normal_encoding little2_encoding + = {{VTABLE, 2, 0, +#if BYTEORDER == 1234 + 1 +#else + 0 +#endif + }, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) NULL_VTABLE}; + +#if BYTEORDER != 4321 + +# ifdef XML_NS + +static const struct normal_encoding internal_little2_encoding_ns + = {{VTABLE, 2, 0, 1}, + { +# include "iasciitab.h" +# include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) NULL_VTABLE}; + +# endif + +static const struct normal_encoding internal_little2_encoding + = {{VTABLE, 2, 0, 1}, + { +# define BT_COLON BT_NMSTRT +# include "iasciitab.h" +# undef BT_COLON +# include "latin1tab.h" + }, + STANDARD_VTABLE(little2_) NULL_VTABLE}; + +#endif + +#define BIG2_BYTE_TYPE(enc, p) \ + ((p)[0] == 0 ? SB_BYTE_TYPE(enc, p + 1) : unicode_byte_type((p)[0], (p)[1])) +#define BIG2_BYTE_TO_ASCII(p) ((p)[0] == 0 ? (p)[1] : -1) +#define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == (c)) +#define BIG2_IS_NAME_CHAR_MINBPC(p) \ + UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) +#define BIG2_IS_NMSTRT_CHAR_MINBPC(p) \ + UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1]) + +#ifdef XML_MIN_SIZE + +static int PTRFASTCALL +big2_byteType(const ENCODING *enc, const char *p) { + return BIG2_BYTE_TYPE(enc, p); +} + +static int PTRFASTCALL +big2_byteToAscii(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return BIG2_BYTE_TO_ASCII(p); +} + +static int PTRCALL +big2_charMatches(const ENCODING *enc, const char *p, int c) { + UNUSED_P(enc); + return BIG2_CHAR_MATCHES(p, c); +} + +static int PTRFASTCALL +big2_isNameMin(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return BIG2_IS_NAME_CHAR_MINBPC(p); +} + +static int PTRFASTCALL +big2_isNmstrtMin(const ENCODING *enc, const char *p) { + UNUSED_P(enc); + return BIG2_IS_NMSTRT_CHAR_MINBPC(p); +} + +# undef VTABLE +# define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16 + +#else /* not XML_MIN_SIZE */ + +# undef PREFIX +# define PREFIX(ident) big2_##ident +# define MINBPC(enc) 2 +/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ +# define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p) +# define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(p) +# define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(p, c) +# define IS_NAME_CHAR(enc, p, n) 0 +# define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p) +# define IS_NMSTRT_CHAR(enc, p, n) (0) +# define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p) + +# define XML_TOK_IMPL_C +# include "xmltok_impl.c" +# undef XML_TOK_IMPL_C + +# undef MINBPC +# undef BYTE_TYPE +# undef BYTE_TO_ASCII +# undef CHAR_MATCHES +# undef IS_NAME_CHAR +# undef IS_NAME_CHAR_MINBPC +# undef IS_NMSTRT_CHAR +# undef IS_NMSTRT_CHAR_MINBPC +# undef IS_INVALID_CHAR + +#endif /* not XML_MIN_SIZE */ + +#ifdef XML_NS + +static const struct normal_encoding big2_encoding_ns + = {{VTABLE, 2, 0, +# if BYTEORDER == 4321 + 1 +# else + 0 +# endif + }, + { +# include "asciitab.h" +# include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) NULL_VTABLE}; + +#endif + +static const struct normal_encoding big2_encoding + = {{VTABLE, 2, 0, +#if BYTEORDER == 4321 + 1 +#else + 0 +#endif + }, + { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) NULL_VTABLE}; + +#if BYTEORDER != 1234 + +# ifdef XML_NS + +static const struct normal_encoding internal_big2_encoding_ns + = {{VTABLE, 2, 0, 1}, + { +# include "iasciitab.h" +# include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) NULL_VTABLE}; + +# endif + +static const struct normal_encoding internal_big2_encoding + = {{VTABLE, 2, 0, 1}, + { +# define BT_COLON BT_NMSTRT +# include "iasciitab.h" +# undef BT_COLON +# include "latin1tab.h" + }, + STANDARD_VTABLE(big2_) NULL_VTABLE}; + +#endif + +#undef PREFIX + +static int FASTCALL +streqci(const char *s1, const char *s2) { + for (;;) { + char c1 = *s1++; + char c2 = *s2++; + if (ASCII_a <= c1 && c1 <= ASCII_z) + c1 += ASCII_A - ASCII_a; + if (ASCII_a <= c2 && c2 <= ASCII_z) + /* The following line will never get executed. streqci() is + * only called from two places, both of which guarantee to put + * upper-case strings into s2. + */ + c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */ + if (c1 != c2) + return 0; + if (! c1) + break; + } + return 1; +} + +static void PTRCALL +initUpdatePosition(const ENCODING *enc, const char *ptr, const char *end, + POSITION *pos) { + UNUSED_P(enc); + normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); +} + +static int +toAscii(const ENCODING *enc, const char *ptr, const char *end) { + char buf[1]; + char *p = buf; + XmlUtf8Convert(enc, &ptr, end, &p, p + 1); + if (p == buf) + return -1; + else + return buf[0]; +} + +static int FASTCALL +isSpace(int c) { + switch (c) { + case 0x20: + case 0xD: + case 0xA: + case 0x9: + return 1; + } + return 0; +} + +/* Return 1 if there's just optional white space or there's an S + followed by name=val. +*/ +static int +parsePseudoAttribute(const ENCODING *enc, const char *ptr, const char *end, + const char **namePtr, const char **nameEndPtr, + const char **valPtr, const char **nextTokPtr) { + int c; + char open; + if (ptr == end) { + *namePtr = NULL; + return 1; + } + if (! isSpace(toAscii(enc, ptr, end))) { + *nextTokPtr = ptr; + return 0; + } + do { + ptr += enc->minBytesPerChar; + } while (isSpace(toAscii(enc, ptr, end))); + if (ptr == end) { + *namePtr = NULL; + return 1; + } + *namePtr = ptr; + for (;;) { + c = toAscii(enc, ptr, end); + if (c == -1) { + *nextTokPtr = ptr; + return 0; + } + if (c == ASCII_EQUALS) { + *nameEndPtr = ptr; + break; + } + if (isSpace(c)) { + *nameEndPtr = ptr; + do { + ptr += enc->minBytesPerChar; + } while (isSpace(c = toAscii(enc, ptr, end))); + if (c != ASCII_EQUALS) { + *nextTokPtr = ptr; + return 0; + } + break; + } + ptr += enc->minBytesPerChar; + } + if (ptr == *namePtr) { + *nextTokPtr = ptr; + return 0; + } + ptr += enc->minBytesPerChar; + c = toAscii(enc, ptr, end); + while (isSpace(c)) { + ptr += enc->minBytesPerChar; + c = toAscii(enc, ptr, end); + } + if (c != ASCII_QUOT && c != ASCII_APOS) { + *nextTokPtr = ptr; + return 0; + } + open = (char)c; + ptr += enc->minBytesPerChar; + *valPtr = ptr; + for (;; ptr += enc->minBytesPerChar) { + c = toAscii(enc, ptr, end); + if (c == open) + break; + if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z) + && ! (ASCII_0 <= c && c <= ASCII_9) && c != ASCII_PERIOD + && c != ASCII_MINUS && c != ASCII_UNDERSCORE) { + *nextTokPtr = ptr; + return 0; + } + } + *nextTokPtr = ptr + enc->minBytesPerChar; + return 1; +} + +static const char KW_version[] + = {ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'}; + +static const char KW_encoding[] = {ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, + ASCII_i, ASCII_n, ASCII_g, '\0'}; + +static const char KW_standalone[] + = {ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, + ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'}; + +static const char KW_yes[] = {ASCII_y, ASCII_e, ASCII_s, '\0'}; + +static const char KW_no[] = {ASCII_n, ASCII_o, '\0'}; + +static int +doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, const char *, + const char *), + int isGeneralTextEntity, const ENCODING *enc, const char *ptr, + const char *end, const char **badPtr, const char **versionPtr, + const char **versionEndPtr, const char **encodingName, + const ENCODING **encoding, int *standalone) { + const char *val = NULL; + const char *name = NULL; + const char *nameEnd = NULL; + ptr += 5 * enc->minBytesPerChar; + end -= 2 * enc->minBytesPerChar; + if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) + || ! name) { + *badPtr = ptr; + return 0; + } + if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) { + if (! isGeneralTextEntity) { + *badPtr = name; + return 0; + } + } else { + if (versionPtr) + *versionPtr = val; + if (versionEndPtr) + *versionEndPtr = ptr; + if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { + *badPtr = ptr; + return 0; + } + if (! name) { + if (isGeneralTextEntity) { + /* a TextDecl must have an EncodingDecl */ + *badPtr = ptr; + return 0; + } + return 1; + } + } + if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) { + int c = toAscii(enc, val, end); + if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)) { + *badPtr = val; + return 0; + } + if (encodingName) + *encodingName = val; + if (encoding) + *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); + if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { + *badPtr = ptr; + return 0; + } + if (! name) + return 1; + } + if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) + || isGeneralTextEntity) { + *badPtr = name; + return 0; + } + if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) { + if (standalone) + *standalone = 1; + } else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) { + if (standalone) + *standalone = 0; + } else { + *badPtr = val; + return 0; + } + while (isSpace(toAscii(enc, ptr, end))) + ptr += enc->minBytesPerChar; + if (ptr != end) { + *badPtr = ptr; + return 0; + } + return 1; +} + +static int FASTCALL +checkCharRefNumber(int result) { + switch (result >> 8) { + case 0xD8: + case 0xD9: + case 0xDA: + case 0xDB: + case 0xDC: + case 0xDD: + case 0xDE: + case 0xDF: + return -1; + case 0: + if (latin1_encoding.type[result] == BT_NONXML) + return -1; + break; + case 0xFF: + if (result == 0xFFFE || result == 0xFFFF) + return -1; + break; + } + return result; +} + +int FASTCALL +XmlUtf8Encode(int c, char *buf) { + enum { + /* minN is minimum legal resulting value for N byte sequence */ + min2 = 0x80, + min3 = 0x800, + min4 = 0x10000 + }; + + if (c < 0) + return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */ + if (c < min2) { + buf[0] = (char)(c | UTF8_cval1); + return 1; + } + if (c < min3) { + buf[0] = (char)((c >> 6) | UTF8_cval2); + buf[1] = (char)((c & 0x3f) | 0x80); + return 2; + } + if (c < min4) { + buf[0] = (char)((c >> 12) | UTF8_cval3); + buf[1] = (char)(((c >> 6) & 0x3f) | 0x80); + buf[2] = (char)((c & 0x3f) | 0x80); + return 3; + } + if (c < 0x110000) { + buf[0] = (char)((c >> 18) | UTF8_cval4); + buf[1] = (char)(((c >> 12) & 0x3f) | 0x80); + buf[2] = (char)(((c >> 6) & 0x3f) | 0x80); + buf[3] = (char)((c & 0x3f) | 0x80); + return 4; + } + return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */ +} + +int FASTCALL +XmlUtf16Encode(int charNum, unsigned short *buf) { + if (charNum < 0) + return 0; + if (charNum < 0x10000) { + buf[0] = (unsigned short)charNum; + return 1; + } + if (charNum < 0x110000) { + charNum -= 0x10000; + buf[0] = (unsigned short)((charNum >> 10) + 0xD800); + buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00); + return 2; + } + return 0; +} + +struct unknown_encoding { + struct normal_encoding normal; + CONVERTER convert; + void *userData; + unsigned short utf16[256]; + char utf8[256][4]; +}; + +#define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *)(enc)) + +int +XmlSizeOfUnknownEncoding(void) { + return sizeof(struct unknown_encoding); +} + +static int PTRFASTCALL +unknown_isName(const ENCODING *enc, const char *p) { + const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); + int c = uenc->convert(uenc->userData, p); + if (c & ~0xFFFF) + return 0; + return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF); +} + +static int PTRFASTCALL +unknown_isNmstrt(const ENCODING *enc, const char *p) { + const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); + int c = uenc->convert(uenc->userData, p); + if (c & ~0xFFFF) + return 0; + return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF); +} + +static int PTRFASTCALL +unknown_isInvalid(const ENCODING *enc, const char *p) { + const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); + int c = uenc->convert(uenc->userData, p); + return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; +} + +static enum XML_Convert_Result PTRCALL +unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, + char **toP, const char *toLim) { + const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); + char buf[XML_UTF8_ENCODE_MAX]; + for (;;) { + const char *utf8; + int n; + if (*fromP == fromLim) + return XML_CONVERT_COMPLETED; + utf8 = uenc->utf8[(unsigned char)**fromP]; + n = *utf8++; + if (n == 0) { + int c = uenc->convert(uenc->userData, *fromP); + n = XmlUtf8Encode(c, buf); + if (n > toLim - *toP) + return XML_CONVERT_OUTPUT_EXHAUSTED; + utf8 = buf; + *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] + - (BT_LEAD2 - 2)); + } else { + if (n > toLim - *toP) + return XML_CONVERT_OUTPUT_EXHAUSTED; + (*fromP)++; + } + memcpy(*toP, utf8, n); + *toP += n; + } +} + +static enum XML_Convert_Result PTRCALL +unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) { + const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); + while (*fromP < fromLim && *toP < toLim) { + unsigned short c = uenc->utf16[(unsigned char)**fromP]; + if (c == 0) { + c = (unsigned short)uenc->convert(uenc->userData, *fromP); + *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] + - (BT_LEAD2 - 2)); + } else + (*fromP)++; + *(*toP)++ = c; + } + + if ((*toP == toLim) && (*fromP < fromLim)) + return XML_CONVERT_OUTPUT_EXHAUSTED; + else + return XML_CONVERT_COMPLETED; +} + +ENCODING * +XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert, + void *userData) { + int i; + struct unknown_encoding *e = (struct unknown_encoding *)mem; + memcpy(mem, &latin1_encoding, sizeof(struct normal_encoding)); + for (i = 0; i < 128; i++) + if (latin1_encoding.type[i] != BT_OTHER + && latin1_encoding.type[i] != BT_NONXML && table[i] != i) + return 0; + for (i = 0; i < 256; i++) { + int c = table[i]; + if (c == -1) { + e->normal.type[i] = BT_MALFORM; + /* This shouldn't really get used. */ + e->utf16[i] = 0xFFFF; + e->utf8[i][0] = 1; + e->utf8[i][1] = 0; + } else if (c < 0) { + if (c < -4) + return 0; + /* Multi-byte sequences need a converter function */ + if (! convert) + return 0; + e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2)); + e->utf8[i][0] = 0; + e->utf16[i] = 0; + } else if (c < 0x80) { + if (latin1_encoding.type[c] != BT_OTHER + && latin1_encoding.type[c] != BT_NONXML && c != i) + return 0; + e->normal.type[i] = latin1_encoding.type[c]; + e->utf8[i][0] = 1; + e->utf8[i][1] = (char)c; + e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c); + } else if (checkCharRefNumber(c) < 0) { + e->normal.type[i] = BT_NONXML; + /* This shouldn't really get used. */ + e->utf16[i] = 0xFFFF; + e->utf8[i][0] = 1; + e->utf8[i][1] = 0; + } else { + if (c > 0xFFFF) + return 0; + if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff)) + e->normal.type[i] = BT_NMSTRT; + else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff)) + e->normal.type[i] = BT_NAME; + else + e->normal.type[i] = BT_OTHER; + e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1); + e->utf16[i] = (unsigned short)c; + } + } + e->userData = userData; + e->convert = convert; + if (convert) { + e->normal.isName2 = unknown_isName; + e->normal.isName3 = unknown_isName; + e->normal.isName4 = unknown_isName; + e->normal.isNmstrt2 = unknown_isNmstrt; + e->normal.isNmstrt3 = unknown_isNmstrt; + e->normal.isNmstrt4 = unknown_isNmstrt; + e->normal.isInvalid2 = unknown_isInvalid; + e->normal.isInvalid3 = unknown_isInvalid; + e->normal.isInvalid4 = unknown_isInvalid; + } + e->normal.enc.utf8Convert = unknown_toUtf8; + e->normal.enc.utf16Convert = unknown_toUtf16; + return &(e->normal.enc); +} + +/* If this enumeration is changed, getEncodingIndex and encodings +must also be changed. */ +enum { + UNKNOWN_ENC = -1, + ISO_8859_1_ENC = 0, + US_ASCII_ENC, + UTF_8_ENC, + UTF_16_ENC, + UTF_16BE_ENC, + UTF_16LE_ENC, + /* must match encodingNames up to here */ + NO_ENC +}; + +static const char KW_ISO_8859_1[] + = {ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, + ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, '\0'}; +static const char KW_US_ASCII[] + = {ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, + ASCII_C, ASCII_I, ASCII_I, '\0'}; +static const char KW_UTF_8[] + = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'}; +static const char KW_UTF_16[] + = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'}; +static const char KW_UTF_16BE[] + = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, + ASCII_6, ASCII_B, ASCII_E, '\0'}; +static const char KW_UTF_16LE[] + = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, + ASCII_6, ASCII_L, ASCII_E, '\0'}; + +static int FASTCALL +getEncodingIndex(const char *name) { + static const char *const encodingNames[] = { + KW_ISO_8859_1, KW_US_ASCII, KW_UTF_8, KW_UTF_16, KW_UTF_16BE, KW_UTF_16LE, + }; + int i; + if (name == NULL) + return NO_ENC; + for (i = 0; i < (int)(sizeof(encodingNames) / sizeof(encodingNames[0])); i++) + if (streqci(name, encodingNames[i])) + return i; + return UNKNOWN_ENC; +} + +/* For binary compatibility, we store the index of the encoding + specified at initialization in the isUtf16 member. +*/ + +#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16) +#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i) + +/* This is what detects the encoding. encodingTable maps from + encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of + the external (protocol) specified encoding; state is + XML_CONTENT_STATE if we're parsing an external text entity, and + XML_PROLOG_STATE otherwise. +*/ + +static int +initScan(const ENCODING *const *encodingTable, const INIT_ENCODING *enc, + int state, const char *ptr, const char *end, const char **nextTokPtr) { + const ENCODING **encPtr; + + if (ptr >= end) + return XML_TOK_NONE; + encPtr = enc->encPtr; + if (ptr + 1 == end) { + /* only a single byte available for auto-detection */ +#ifndef XML_DTD /* FIXME */ + /* a well-formed document entity must have more than one byte */ + if (state != XML_CONTENT_STATE) + return XML_TOK_PARTIAL; +#endif + /* so we're parsing an external text entity... */ + /* if UTF-16 was externally specified, then we need at least 2 bytes */ + switch (INIT_ENC_INDEX(enc)) { + case UTF_16_ENC: + case UTF_16LE_ENC: + case UTF_16BE_ENC: + return XML_TOK_PARTIAL; + } + switch ((unsigned char)*ptr) { + case 0xFE: + case 0xFF: + case 0xEF: /* possibly first byte of UTF-8 BOM */ + if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) + break; + /* fall through */ + case 0x00: + case 0x3C: + return XML_TOK_PARTIAL; + } + } else { + switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) { + case 0xFEFF: + if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) + break; + *nextTokPtr = ptr + 2; + *encPtr = encodingTable[UTF_16BE_ENC]; + return XML_TOK_BOM; + /* 00 3C is handled in the default case */ + case 0x3C00: + if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC + || INIT_ENC_INDEX(enc) == UTF_16_ENC) + && state == XML_CONTENT_STATE) + break; + *encPtr = encodingTable[UTF_16LE_ENC]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); + case 0xFFFE: + if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) + break; + *nextTokPtr = ptr + 2; + *encPtr = encodingTable[UTF_16LE_ENC]; + return XML_TOK_BOM; + case 0xEFBB: + /* Maybe a UTF-8 BOM (EF BB BF) */ + /* If there's an explicitly specified (external) encoding + of ISO-8859-1 or some flavour of UTF-16 + and this is an external text entity, + don't look for the BOM, + because it might be a legal data. + */ + if (state == XML_CONTENT_STATE) { + int e = INIT_ENC_INDEX(enc); + if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC + || e == UTF_16_ENC) + break; + } + if (ptr + 2 == end) + return XML_TOK_PARTIAL; + if ((unsigned char)ptr[2] == 0xBF) { + *nextTokPtr = ptr + 3; + *encPtr = encodingTable[UTF_8_ENC]; + return XML_TOK_BOM; + } + break; + default: + if (ptr[0] == '\0') { + /* 0 isn't a legal data character. Furthermore a document + entity can only start with ASCII characters. So the only + way this can fail to be big-endian UTF-16 if it it's an + external parsed general entity that's labelled as + UTF-16LE. + */ + if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC) + break; + *encPtr = encodingTable[UTF_16BE_ENC]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); + } else if (ptr[1] == '\0') { + /* We could recover here in the case: + - parsing an external entity + - second byte is 0 + - no externally specified encoding + - no encoding declaration + by assuming UTF-16LE. But we don't, because this would mean when + presented just with a single byte, we couldn't reliably determine + whether we needed further bytes. + */ + if (state == XML_CONTENT_STATE) + break; + *encPtr = encodingTable[UTF_16LE_ENC]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); + } + break; + } + } + *encPtr = encodingTable[INIT_ENC_INDEX(enc)]; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); +} + +#define NS(x) x +#define ns(x) x +#define XML_TOK_NS_C +#include "xmltok_ns.c" +#undef XML_TOK_NS_C +#undef NS +#undef ns + +#ifdef XML_NS + +# define NS(x) x##NS +# define ns(x) x##_ns + +# define XML_TOK_NS_C +# include "xmltok_ns.c" +# undef XML_TOK_NS_C + +# undef NS +# undef ns + +ENCODING * +XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert, + void *userData) { + ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData); + if (enc) + ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON; + return enc; +} + +#endif /* XML_NS */ + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok.h b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok.h new file mode 100644 index 000000000..5690b0b5f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok.h @@ -0,0 +1,327 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2002 Fred L. Drake, Jr. + Copyright (c) 2002-2005 Karl Waclawek + Copyright (c) 2016-2024 Sebastian Pipping + Copyright (c) 2017 Rhodri James + Licensed under the MIT license: + + 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_XML + +#ifndef XmlTok_INCLUDED +#define XmlTok_INCLUDED 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* The following token may be returned by XmlContentTok */ +#define XML_TOK_TRAILING_RSQB \ + -5 /* ] or ]] at the end of the scan; might be \ + start of illegal ]]> sequence */ +/* The following tokens may be returned by both XmlPrologTok and + XmlContentTok. +*/ +#define XML_TOK_NONE -4 /* The string to be scanned is empty */ +#define XML_TOK_TRAILING_CR \ + -3 /* A CR at the end of the scan; \ + might be part of CRLF sequence */ +#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */ +#define XML_TOK_PARTIAL -1 /* only part of a token */ +#define XML_TOK_INVALID 0 + +/* The following tokens are returned by XmlContentTok; some are also + returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok. +*/ +#define XML_TOK_START_TAG_WITH_ATTS 1 +#define XML_TOK_START_TAG_NO_ATTS 2 +#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag */ +#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4 +#define XML_TOK_END_TAG 5 +#define XML_TOK_DATA_CHARS 6 +#define XML_TOK_DATA_NEWLINE 7 +#define XML_TOK_CDATA_SECT_OPEN 8 +#define XML_TOK_ENTITY_REF 9 +#define XML_TOK_CHAR_REF 10 /* numeric character reference */ + +/* The following tokens may be returned by both XmlPrologTok and + XmlContentTok. +*/ +#define XML_TOK_PI 11 /* processing instruction */ +#define XML_TOK_XML_DECL 12 /* XML decl or text decl */ +#define XML_TOK_COMMENT 13 +#define XML_TOK_BOM 14 /* Byte order mark */ + +/* The following tokens are returned only by XmlPrologTok */ +#define XML_TOK_PROLOG_S 15 +#define XML_TOK_DECL_OPEN 16 /* */ +#define XML_TOK_NAME 18 +#define XML_TOK_NMTOKEN 19 +#define XML_TOK_POUND_NAME 20 /* #name */ +#define XML_TOK_OR 21 /* | */ +#define XML_TOK_PERCENT 22 +#define XML_TOK_OPEN_PAREN 23 +#define XML_TOK_CLOSE_PAREN 24 +#define XML_TOK_OPEN_BRACKET 25 +#define XML_TOK_CLOSE_BRACKET 26 +#define XML_TOK_LITERAL 27 +#define XML_TOK_PARAM_ENTITY_REF 28 +#define XML_TOK_INSTANCE_START 29 + +/* The following occur only in element type declarations */ +#define XML_TOK_NAME_QUESTION 30 /* name? */ +#define XML_TOK_NAME_ASTERISK 31 /* name* */ +#define XML_TOK_NAME_PLUS 32 /* name+ */ +#define XML_TOK_COND_SECT_OPEN 33 /* */ +#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */ +#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */ +#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */ +#define XML_TOK_COMMA 38 + +/* The following token is returned only by XmlAttributeValueTok */ +#define XML_TOK_ATTRIBUTE_VALUE_S 39 + +/* The following token is returned only by XmlCdataSectionTok */ +#define XML_TOK_CDATA_SECT_CLOSE 40 + +/* With namespace processing this is returned by XmlPrologTok for a + name with a colon. +*/ +#define XML_TOK_PREFIXED_NAME 41 + +#ifdef XML_DTD +# define XML_TOK_IGNORE_SECT 42 +#endif /* XML_DTD */ + +#ifdef XML_DTD +# define XML_N_STATES 4 +#else /* not XML_DTD */ +# define XML_N_STATES 3 +#endif /* not XML_DTD */ + +#define XML_PROLOG_STATE 0 +#define XML_CONTENT_STATE 1 +#define XML_CDATA_SECTION_STATE 2 +#ifdef XML_DTD +# define XML_IGNORE_SECTION_STATE 3 +#endif /* XML_DTD */ + +#define XML_N_LITERAL_TYPES 2 +#define XML_ATTRIBUTE_VALUE_LITERAL 0 +#define XML_ENTITY_VALUE_LITERAL 1 + +/* The size of the buffer passed to XmlUtf8Encode must be at least this. */ +#define XML_UTF8_ENCODE_MAX 4 +/* The size of the buffer passed to XmlUtf16Encode must be at least this. */ +#define XML_UTF16_ENCODE_MAX 2 + +typedef struct position { + /* first line and first column are 0 not 1 */ + XML_Size lineNumber; + XML_Size columnNumber; +} POSITION; + +typedef struct { + const char *name; + const char *valuePtr; + const char *valueEnd; + char normalized; +} ATTRIBUTE; + +struct encoding; +typedef struct encoding ENCODING; + +typedef int(PTRCALL *SCANNER)(const ENCODING *, const char *, const char *, + const char **); + +enum XML_Convert_Result { + XML_CONVERT_COMPLETED = 0, + XML_CONVERT_INPUT_INCOMPLETE = 1, + XML_CONVERT_OUTPUT_EXHAUSTED + = 2 /* and therefore potentially input remaining as well */ +}; + +struct encoding { + SCANNER scanners[XML_N_STATES]; + SCANNER literalScanners[XML_N_LITERAL_TYPES]; + int(PTRCALL *nameMatchesAscii)(const ENCODING *, const char *, const char *, + const char *); + int(PTRFASTCALL *nameLength)(const ENCODING *, const char *); + const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *); + int(PTRCALL *getAtts)(const ENCODING *enc, const char *ptr, int attsMax, + ATTRIBUTE *atts); + int(PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr); + int(PTRCALL *predefinedEntityName)(const ENCODING *, const char *, + const char *); + void(PTRCALL *updatePosition)(const ENCODING *, const char *ptr, + const char *end, POSITION *); + int(PTRCALL *isPublicId)(const ENCODING *enc, const char *ptr, + const char *end, const char **badPtr); + enum XML_Convert_Result(PTRCALL *utf8Convert)(const ENCODING *enc, + const char **fromP, + const char *fromLim, char **toP, + const char *toLim); + enum XML_Convert_Result(PTRCALL *utf16Convert)(const ENCODING *enc, + const char **fromP, + const char *fromLim, + unsigned short **toP, + const unsigned short *toLim); + int minBytesPerChar; + char isUtf8; + char isUtf16; +}; + +/* Scan the string starting at ptr until the end of the next complete + token, but do not scan past eptr. Return an integer giving the + type of token. + + Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set. + + Return XML_TOK_PARTIAL when the string does not contain a complete + token; nextTokPtr will not be set. + + Return XML_TOK_INVALID when the string does not start a valid + token; nextTokPtr will be set to point to the character which made + the token invalid. + + Otherwise the string starts with a valid token; nextTokPtr will be + set to point to the character following the end of that token. + + Each data character counts as a single token, but adjacent data + characters may be returned together. Similarly for characters in + the prolog outside literals, comments and processing instructions. +*/ + +#define XmlTok(enc, state, ptr, end, nextTokPtr) \ + (((enc)->scanners[state])(enc, ptr, end, nextTokPtr)) + +#define XmlPrologTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr) + +#define XmlContentTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr) + +#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr) + +#ifdef XML_DTD + +# define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr) + +#endif /* XML_DTD */ + +/* This is used for performing a 2nd-level tokenization on the content + of a literal that has already been returned by XmlTok. +*/ +#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \ + (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr)) + +#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \ + XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr) + +#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \ + XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr) + +#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \ + (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2)) + +#define XmlNameLength(enc, ptr) (((enc)->nameLength)(enc, ptr)) + +#define XmlSkipS(enc, ptr) (((enc)->skipS)(enc, ptr)) + +#define XmlGetAttributes(enc, ptr, attsMax, atts) \ + (((enc)->getAtts)(enc, ptr, attsMax, atts)) + +#define XmlCharRefNumber(enc, ptr) (((enc)->charRefNumber)(enc, ptr)) + +#define XmlPredefinedEntityName(enc, ptr, end) \ + (((enc)->predefinedEntityName)(enc, ptr, end)) + +#define XmlUpdatePosition(enc, ptr, end, pos) \ + (((enc)->updatePosition)(enc, ptr, end, pos)) + +#define XmlIsPublicId(enc, ptr, end, badPtr) \ + (((enc)->isPublicId)(enc, ptr, end, badPtr)) + +#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \ + (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim)) + +#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \ + (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim)) + +typedef struct { + ENCODING initEnc; + const ENCODING **encPtr; +} INIT_ENCODING; + +int XmlParseXmlDecl(int isGeneralTextEntity, const ENCODING *enc, + const char *ptr, const char *end, const char **badPtr, + const char **versionPtr, const char **versionEndPtr, + const char **encodingNamePtr, + const ENCODING **namedEncodingPtr, int *standalonePtr); + +int XmlInitEncoding(INIT_ENCODING *p, const ENCODING **encPtr, + const char *name); +const ENCODING *XmlGetUtf8InternalEncoding(void); +const ENCODING *XmlGetUtf16InternalEncoding(void); +int FASTCALL XmlUtf8Encode(int charNumber, char *buf); +int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf); +int XmlSizeOfUnknownEncoding(void); + +typedef int(XMLCALL *CONVERTER)(void *userData, const char *p); + +ENCODING *XmlInitUnknownEncoding(void *mem, int *table, CONVERTER convert, + void *userData); + +int XmlParseXmlDeclNS(int isGeneralTextEntity, const ENCODING *enc, + const char *ptr, const char *end, const char **badPtr, + const char **versionPtr, const char **versionEndPtr, + const char **encodingNamePtr, + const ENCODING **namedEncodingPtr, int *standalonePtr); + +int XmlInitEncodingNS(INIT_ENCODING *p, const ENCODING **encPtr, + const char *name); +const ENCODING *XmlGetUtf8InternalEncodingNS(void); +const ENCODING *XmlGetUtf16InternalEncodingNS(void); +ENCODING *XmlInitUnknownEncodingNS(void *mem, int *table, CONVERTER convert, + void *userData); +#ifdef __cplusplus +} +#endif + +#endif /* not XmlTok_INCLUDED */ + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok_impl.c b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok_impl.c new file mode 100644 index 000000000..85334d8cf --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok_impl.c @@ -0,0 +1,1825 @@ +/* This file is included (from xmltok.c, 1-3 times depending on XML_MIN_SIZE)! + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2002 Fred L. Drake, Jr. + Copyright (c) 2002-2016 Karl Waclawek + Copyright (c) 2016-2022 Sebastian Pipping + Copyright (c) 2017 Rhodri James + Copyright (c) 2018 Benjamin Peterson + Copyright (c) 2018 Anton Maklakov + Copyright (c) 2019 David Loffredo + Copyright (c) 2020 Boris Kolpackov + Copyright (c) 2022 Martin Ettl + Licensed under the MIT license: + + 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_XML + +#ifdef XML_TOK_IMPL_C + +# ifndef IS_INVALID_CHAR // i.e. for UTF-16 and XML_MIN_SIZE not defined +# define IS_INVALID_CHAR(enc, ptr, n) (0) +# endif + +# define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ + case BT_LEAD##n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_INVALID_CHAR(enc, ptr, n)) { \ + *(nextTokPtr) = (ptr); \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; + +# define INVALID_CASES(ptr, nextTokPtr) \ + INVALID_LEAD_CASE(2, ptr, nextTokPtr) \ + INVALID_LEAD_CASE(3, ptr, nextTokPtr) \ + INVALID_LEAD_CASE(4, ptr, nextTokPtr) \ + case BT_NONXML: \ + case BT_MALFORM: \ + case BT_TRAIL: \ + *(nextTokPtr) = (ptr); \ + return XML_TOK_INVALID; + +# define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \ + case BT_LEAD##n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_INVALID_CHAR(enc, ptr, n) || ! IS_NAME_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; + +# define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \ + case BT_NONASCII: \ + if (! IS_NAME_CHAR_MINBPC(enc, ptr)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + /* fall through */ \ + case BT_NMSTRT: \ + case BT_HEX: \ + case BT_DIGIT: \ + case BT_NAME: \ + case BT_MINUS: \ + ptr += MINBPC(enc); \ + break; \ + CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \ + CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \ + CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr) + +# define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ + case BT_LEAD##n: \ + if ((end) - (ptr) < (n)) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_INVALID_CHAR(enc, ptr, n) || ! IS_NMSTRT_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; + +# define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \ + case BT_NONASCII: \ + if (! IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + /* fall through */ \ + case BT_NMSTRT: \ + case BT_HEX: \ + ptr += MINBPC(enc); \ + break; \ + CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \ + CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \ + CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr) + +# ifndef PREFIX +# define PREFIX(ident) ident +# endif + +# define HAS_CHARS(enc, ptr, end, count) \ + ((end) - (ptr) >= ((count) * MINBPC(enc))) + +# define HAS_CHAR(enc, ptr, end) HAS_CHARS(enc, ptr, end, 1) + +# define REQUIRE_CHARS(enc, ptr, end, count) \ + { \ + if (! HAS_CHARS(enc, ptr, end, count)) { \ + return XML_TOK_PARTIAL; \ + } \ + } + +# define REQUIRE_CHAR(enc, ptr, end) REQUIRE_CHARS(enc, ptr, end, 1) + +/* ptr points to character following " */ + switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { + case BT_S: + case BT_CR: + case BT_LF: + case BT_PERCNT: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + /* fall through */ + case BT_S: + case BT_CR: + case BT_LF: + *nextTokPtr = ptr; + return XML_TOK_DECL_OPEN; + case BT_NMSTRT: + case BT_HEX: + ptr += MINBPC(enc); + break; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return XML_TOK_PARTIAL; +} + +static int PTRCALL +PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end, + int *tokPtr) { + int upper = 0; + UNUSED_P(enc); + *tokPtr = XML_TOK_PI; + if (end - ptr != MINBPC(enc) * 3) + return 1; + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_x: + break; + case ASCII_X: + upper = 1; + break; + default: + return 1; + } + ptr += MINBPC(enc); + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_m: + break; + case ASCII_M: + upper = 1; + break; + default: + return 1; + } + ptr += MINBPC(enc); + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_l: + break; + case ASCII_L: + upper = 1; + break; + default: + return 1; + } + if (upper) + return 0; + *tokPtr = XML_TOK_XML_DECL; + return 1; +} + +/* ptr points to character following "= end) + return XML_TOK_NONE; + if (MINBPC(enc) > 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + if (n == 0) + return XML_TOK_PARTIAL; + end = ptr + n; + } + } + switch (BYTE_TYPE(enc, ptr)) { + case BT_RSQB: + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + if (! CHAR_MATCHES(enc, ptr, ASCII_RSQB)) + break; + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) { + ptr -= MINBPC(enc); + break; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CDATA_SECT_CLOSE; + case BT_CR: + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + case BT_LF: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + INVALID_CASES(ptr, nextTokPtr) + default: + ptr += MINBPC(enc); + break; + } + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_DATA_CHARS; \ + } \ + ptr += n; \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_NONXML: + case BT_MALFORM: + case BT_TRAIL: + case BT_CR: + case BT_LF: + case BT_RSQB: + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +/* ptr points to character following "= end) + return XML_TOK_NONE; + if (MINBPC(enc) > 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + if (n == 0) + return XML_TOK_PARTIAL; + end = ptr + n; + } + } + switch (BYTE_TYPE(enc, ptr)) { + case BT_LT: + return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_AMP: + return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_CR: + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + case BT_LF: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + case BT_RSQB: + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + return XML_TOK_TRAILING_RSQB; + if (! CHAR_MATCHES(enc, ptr, ASCII_RSQB)) + break; + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + return XML_TOK_TRAILING_RSQB; + if (! CHAR_MATCHES(enc, ptr, ASCII_GT)) { + ptr -= MINBPC(enc); + break; + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + INVALID_CASES(ptr, nextTokPtr) + default: + ptr += MINBPC(enc); + break; + } + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_DATA_CHARS; \ + } \ + ptr += n; \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_RSQB: + if (HAS_CHARS(enc, ptr, end, 2)) { + if (! CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) { + ptr += MINBPC(enc); + break; + } + if (HAS_CHARS(enc, ptr, end, 3)) { + if (! CHAR_MATCHES(enc, ptr + 2 * MINBPC(enc), ASCII_GT)) { + ptr += MINBPC(enc); + break; + } + *nextTokPtr = ptr + 2 * MINBPC(enc); + return XML_TOK_INVALID; + } + } + /* fall through */ + case BT_AMP: + case BT_LT: + case BT_NONXML: + case BT_MALFORM: + case BT_TRAIL: + case BT_CR: + case BT_LF: + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +/* ptr points to character following "%" */ + +static int PTRCALL +PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + REQUIRE_CHAR(enc, ptr, end); + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + case BT_S: + case BT_LF: + case BT_CR: + case BT_PERCNT: + *nextTokPtr = ptr; + return XML_TOK_PERCENT; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_SEMI: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_PARAM_ENTITY_REF; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return XML_TOK_PARTIAL; +} + +static int PTRCALL +PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + REQUIRE_CHAR(enc, ptr, end); + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_CR: + case BT_LF: + case BT_S: + case BT_RPAR: + case BT_GT: + case BT_PERCNT: + case BT_VERBAR: + *nextTokPtr = ptr; + return XML_TOK_POUND_NAME; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return -XML_TOK_POUND_NAME; +} + +static int PTRCALL +PREFIX(scanLit)(int open, const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + while (HAS_CHAR(enc, ptr, end)) { + int t = BYTE_TYPE(enc, ptr); + switch (t) { + INVALID_CASES(ptr, nextTokPtr) + case BT_QUOT: + case BT_APOS: + ptr += MINBPC(enc); + if (t != open) + break; + if (! HAS_CHAR(enc, ptr, end)) + return -XML_TOK_LITERAL; + *nextTokPtr = ptr; + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: + case BT_CR: + case BT_LF: + case BT_GT: + case BT_PERCNT: + case BT_LSQB: + return XML_TOK_LITERAL; + default: + return XML_TOK_INVALID; + } + default: + ptr += MINBPC(enc); + break; + } + } + return XML_TOK_PARTIAL; +} + +static int PTRCALL +PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + int tok; + if (ptr >= end) + return XML_TOK_NONE; + if (MINBPC(enc) > 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + if (n == 0) + return XML_TOK_PARTIAL; + end = ptr + n; + } + } + switch (BYTE_TYPE(enc, ptr)) { + case BT_QUOT: + return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_APOS: + return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_LT: { + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + switch (BYTE_TYPE(enc, ptr)) { + case BT_EXCL: + return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_QUEST: + return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_NMSTRT: + case BT_HEX: + case BT_NONASCII: + case BT_LEAD2: + case BT_LEAD3: + case BT_LEAD4: + *nextTokPtr = ptr - MINBPC(enc); + return XML_TOK_INSTANCE_START; + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + case BT_CR: + if (ptr + MINBPC(enc) == end) { + *nextTokPtr = end; + /* indicate that this might be part of a CR/LF pair */ + return -XML_TOK_PROLOG_S; + } + /* fall through */ + case BT_S: + case BT_LF: + for (;;) { + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + break; + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: + case BT_LF: + break; + case BT_CR: + /* don't split CR/LF pair */ + if (ptr + MINBPC(enc) != end) + break; + /* fall through */ + default: + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; + } + } + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; + case BT_PERCNT: + return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); + case BT_COMMA: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_COMMA; + case BT_LSQB: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_OPEN_BRACKET; + case BT_RSQB: + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + return -XML_TOK_CLOSE_BRACKET; + if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { + REQUIRE_CHARS(enc, ptr, end, 2); + if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { + *nextTokPtr = ptr + 2 * MINBPC(enc); + return XML_TOK_COND_SECT_CLOSE; + } + } + *nextTokPtr = ptr; + return XML_TOK_CLOSE_BRACKET; + case BT_LPAR: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_OPEN_PAREN; + case BT_RPAR: + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + return -XML_TOK_CLOSE_PAREN; + switch (BYTE_TYPE(enc, ptr)) { + case BT_AST: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CLOSE_PAREN_ASTERISK; + case BT_QUEST: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CLOSE_PAREN_QUESTION; + case BT_PLUS: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_CLOSE_PAREN_PLUS; + case BT_CR: + case BT_LF: + case BT_S: + case BT_GT: + case BT_COMMA: + case BT_VERBAR: + case BT_RPAR: + *nextTokPtr = ptr; + return XML_TOK_CLOSE_PAREN; + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + case BT_VERBAR: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_OR; + case BT_GT: + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DECL_CLOSE; + case BT_NUM: + return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr); +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NAME; \ + break; \ + } \ + if (IS_NAME_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NMTOKEN; \ + break; \ + } \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_NMSTRT: + case BT_HEX: + tok = XML_TOK_NAME; + ptr += MINBPC(enc); + break; + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: +# ifdef XML_NS + case BT_COLON: +# endif + tok = XML_TOK_NMTOKEN; + ptr += MINBPC(enc); + break; + case BT_NONASCII: + if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { + ptr += MINBPC(enc); + tok = XML_TOK_NAME; + break; + } + if (IS_NAME_CHAR_MINBPC(enc, ptr)) { + ptr += MINBPC(enc); + tok = XML_TOK_NMTOKEN; + break; + } + /* fall through */ + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_GT: + case BT_RPAR: + case BT_COMMA: + case BT_VERBAR: + case BT_LSQB: + case BT_PERCNT: + case BT_S: + case BT_CR: + case BT_LF: + *nextTokPtr = ptr; + return tok; +# ifdef XML_NS + case BT_COLON: + ptr += MINBPC(enc); + switch (tok) { + case XML_TOK_NAME: + REQUIRE_CHAR(enc, ptr, end); + tok = XML_TOK_PREFIXED_NAME; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + default: + tok = XML_TOK_NMTOKEN; + break; + } + break; + case XML_TOK_PREFIXED_NAME: + tok = XML_TOK_NMTOKEN; + break; + } + break; +# endif + case BT_PLUS: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_PLUS; + case BT_AST: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_ASTERISK; + case BT_QUEST: + if (tok == XML_TOK_NMTOKEN) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_NAME_QUESTION; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return -tok; +} + +static int PTRCALL +PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + const char *start; + if (ptr >= end) + return XML_TOK_NONE; + else if (! HAS_CHAR(enc, ptr, end)) { + /* This line cannot be executed. The incoming data has already + * been tokenized once, so incomplete characters like this have + * already been eliminated from the input. Retaining the paranoia + * check is still valuable, however. + */ + return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */ + } + start = ptr; + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + ptr += n; /* NOTE: The encoding has already been validated. */ \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_AMP: + if (ptr == start) + return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_LT: + /* this is for inside entity references */ + *nextTokPtr = ptr; + return XML_TOK_INVALID; + case BT_LF: + if (ptr == start) { + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_CR: + if (ptr == start) { + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_S: + if (ptr == start) { + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_ATTRIBUTE_VALUE_S; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +static int PTRCALL +PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + const char *start; + if (ptr >= end) + return XML_TOK_NONE; + else if (! HAS_CHAR(enc, ptr, end)) { + /* This line cannot be executed. The incoming data has already + * been tokenized once, so incomplete characters like this have + * already been eliminated from the input. Retaining the paranoia + * check is still valuable, however. + */ + return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */ + } + start = ptr; + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + ptr += n; /* NOTE: The encoding has already been validated. */ \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_AMP: + if (ptr == start) + return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_PERCNT: + if (ptr == start) { + int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); + return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_LF: + if (ptr == start) { + *nextTokPtr = ptr + MINBPC(enc); + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_CR: + if (ptr == start) { + ptr += MINBPC(enc); + if (! HAS_CHAR(enc, ptr, end)) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC(enc); + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +# ifdef XML_DTD + +static int PTRCALL +PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + int level = 0; + if (MINBPC(enc) > 1) { + size_t n = end - ptr; + if (n & (MINBPC(enc) - 1)) { + n &= ~(MINBPC(enc) - 1); + end = ptr + n; + } + } + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { + INVALID_CASES(ptr, nextTokPtr) + case BT_LT: + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) { + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { + ++level; + ptr += MINBPC(enc); + } + } + break; + case BT_RSQB: + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); + if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { + ptr += MINBPC(enc); + if (level == 0) { + *nextTokPtr = ptr; + return XML_TOK_IGNORE_SECT; + } + --level; + } + } + break; + default: + ptr += MINBPC(enc); + break; + } + } + return XML_TOK_PARTIAL; +} + +# endif /* XML_DTD */ + +static int PTRCALL +PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, + const char **badPtr) { + ptr += MINBPC(enc); + end -= MINBPC(enc); + for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { + switch (BYTE_TYPE(enc, ptr)) { + case BT_DIGIT: + case BT_HEX: + case BT_MINUS: + case BT_APOS: + case BT_LPAR: + case BT_RPAR: + case BT_PLUS: + case BT_COMMA: + case BT_SOL: + case BT_EQUALS: + case BT_QUEST: + case BT_CR: + case BT_LF: + case BT_SEMI: + case BT_EXCL: + case BT_AST: + case BT_PERCNT: + case BT_NUM: +# ifdef XML_NS + case BT_COLON: +# endif + break; + case BT_S: + if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) { + *badPtr = ptr; + return 0; + } + break; + case BT_NAME: + case BT_NMSTRT: + if (! (BYTE_TO_ASCII(enc, ptr) & ~0x7f)) + break; + /* fall through */ + default: + switch (BYTE_TO_ASCII(enc, ptr)) { + case 0x24: /* $ */ + case 0x40: /* @ */ + break; + default: + *badPtr = ptr; + return 0; + } + break; + } + } + return 1; +} + +/* This must only be called for a well-formed start-tag or empty + element tag. Returns the number of attributes. Pointers to the + first attsMax attributes are stored in atts. +*/ + +static int PTRCALL +PREFIX(getAtts)(const ENCODING *enc, const char *ptr, int attsMax, + ATTRIBUTE *atts) { + enum { other, inName, inValue } state = inName; + int nAtts = 0; + int open = 0; /* defined when state == inValue; + initialization just to shut up compilers */ + + for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { + switch (BYTE_TYPE(enc, ptr)) { +# define START_NAME \ + if (state == other) { \ + if (nAtts < attsMax) { \ + atts[nAtts].name = ptr; \ + atts[nAtts].normalized = 1; \ + } \ + state = inName; \ + } +# define LEAD_CASE(n) \ + case BT_LEAD##n: /* NOTE: The encoding has already been validated. */ \ + START_NAME ptr += (n - MINBPC(enc)); \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_NONASCII: + case BT_NMSTRT: + case BT_HEX: + START_NAME + break; +# undef START_NAME + case BT_QUOT: + if (state != inValue) { + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC(enc); + state = inValue; + open = BT_QUOT; + } else if (open == BT_QUOT) { + state = other; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; + } + break; + case BT_APOS: + if (state != inValue) { + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC(enc); + state = inValue; + open = BT_APOS; + } else if (open == BT_APOS) { + state = other; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; + } + break; + case BT_AMP: + if (nAtts < attsMax) + atts[nAtts].normalized = 0; + break; + case BT_S: + if (state == inName) + state = other; + else if (state == inValue && nAtts < attsMax && atts[nAtts].normalized + && (ptr == atts[nAtts].valuePtr + || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE + || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE + || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) + atts[nAtts].normalized = 0; + break; + case BT_CR: + case BT_LF: + /* This case ensures that the first attribute name is counted + Apart from that we could just change state on the quote. */ + if (state == inName) + state = other; + else if (state == inValue && nAtts < attsMax) + atts[nAtts].normalized = 0; + break; + case BT_GT: + case BT_SOL: + if (state != inValue) + return nAtts; + break; + default: + break; + } + } + /* not reached */ +} + +static int PTRFASTCALL +PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) { + int result = 0; + /* skip &# */ + UNUSED_P(enc); + ptr += 2 * MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_x)) { + for (ptr += MINBPC(enc); ! CHAR_MATCHES(enc, ptr, ASCII_SEMI); + ptr += MINBPC(enc)) { + int c = BYTE_TO_ASCII(enc, ptr); + switch (c) { + case ASCII_0: + case ASCII_1: + case ASCII_2: + case ASCII_3: + case ASCII_4: + case ASCII_5: + case ASCII_6: + case ASCII_7: + case ASCII_8: + case ASCII_9: + result <<= 4; + result |= (c - ASCII_0); + break; + case ASCII_A: + case ASCII_B: + case ASCII_C: + case ASCII_D: + case ASCII_E: + case ASCII_F: + result <<= 4; + result += 10 + (c - ASCII_A); + break; + case ASCII_a: + case ASCII_b: + case ASCII_c: + case ASCII_d: + case ASCII_e: + case ASCII_f: + result <<= 4; + result += 10 + (c - ASCII_a); + break; + } + if (result >= 0x110000) + return -1; + } + } else { + for (; ! CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { + int c = BYTE_TO_ASCII(enc, ptr); + result *= 10; + result += (c - ASCII_0); + if (result >= 0x110000) + return -1; + } + } + return checkCharRefNumber(result); +} + +static int PTRCALL +PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, + const char *end) { + UNUSED_P(enc); + switch ((end - ptr) / MINBPC(enc)) { + case 2: + if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) { + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_l: + return ASCII_LT; + case ASCII_g: + return ASCII_GT; + } + } + break; + case 3: + if (CHAR_MATCHES(enc, ptr, ASCII_a)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_m)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_p)) + return ASCII_AMP; + } + } + break; + case 4: + switch (BYTE_TO_ASCII(enc, ptr)) { + case ASCII_q: + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_u)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_o)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_t)) + return ASCII_QUOT; + } + } + break; + case ASCII_a: + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_p)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_o)) { + ptr += MINBPC(enc); + if (CHAR_MATCHES(enc, ptr, ASCII_s)) + return ASCII_APOS; + } + } + break; + } + } + return 0; +} + +static int PTRCALL +PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, + const char *end1, const char *ptr2) { + UNUSED_P(enc); + for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { + if (end1 - ptr1 < MINBPC(enc)) { + /* This line cannot be executed. The incoming data has already + * been tokenized once, so incomplete characters like this have + * already been eliminated from the input. Retaining the + * paranoia check is still valuable, however. + */ + return 0; /* LCOV_EXCL_LINE */ + } + if (! CHAR_MATCHES(enc, ptr1, *ptr2)) + return 0; + } + return ptr1 == end1; +} + +static int PTRFASTCALL +PREFIX(nameLength)(const ENCODING *enc, const char *ptr) { + const char *start = ptr; + for (;;) { + switch (BYTE_TYPE(enc, ptr)) { +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + ptr += n; /* NOTE: The encoding has already been validated. */ \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_NONASCII: + case BT_NMSTRT: +# ifdef XML_NS + case BT_COLON: +# endif + case BT_HEX: + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: + ptr += MINBPC(enc); + break; + default: + return (int)(ptr - start); + } + } +} + +static const char *PTRFASTCALL +PREFIX(skipS)(const ENCODING *enc, const char *ptr) { + for (;;) { + switch (BYTE_TYPE(enc, ptr)) { + case BT_LF: + case BT_CR: + case BT_S: + ptr += MINBPC(enc); + break; + default: + return ptr; + } + } +} + +static void PTRCALL +PREFIX(updatePosition)(const ENCODING *enc, const char *ptr, const char *end, + POSITION *pos) { + while (HAS_CHAR(enc, ptr, end)) { + switch (BYTE_TYPE(enc, ptr)) { +# define LEAD_CASE(n) \ + case BT_LEAD##n: \ + ptr += n; /* NOTE: The encoding has already been validated. */ \ + pos->columnNumber++; \ + break; + LEAD_CASE(2) + LEAD_CASE(3) + LEAD_CASE(4) +# undef LEAD_CASE + case BT_LF: + pos->columnNumber = 0; + pos->lineNumber++; + ptr += MINBPC(enc); + break; + case BT_CR: + pos->lineNumber++; + ptr += MINBPC(enc); + if (HAS_CHAR(enc, ptr, end) && BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC(enc); + pos->columnNumber = 0; + break; + default: + ptr += MINBPC(enc); + pos->columnNumber++; + break; + } + } +} + +# undef DO_LEAD_CASE +# undef MULTIBYTE_CASES +# undef INVALID_CASES +# undef CHECK_NAME_CASE +# undef CHECK_NAME_CASES +# undef CHECK_NMSTRT_CASE +# undef CHECK_NMSTRT_CASES + +#endif /* XML_TOK_IMPL_C */ + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok_impl.h b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok_impl.h new file mode 100644 index 000000000..0d7848369 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok_impl.h @@ -0,0 +1,80 @@ +/* + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2017-2019 Sebastian Pipping + Licensed under the MIT license: + + 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_XML + +enum { + BT_NONXML, /* e.g. noncharacter-FFFF */ + BT_MALFORM, /* illegal, with regard to encoding */ + BT_LT, /* less than = "<" */ + BT_AMP, /* ampersand = "&" */ + BT_RSQB, /* right square bracket = "[" */ + BT_LEAD2, /* lead byte of a 2-byte UTF-8 character */ + BT_LEAD3, /* lead byte of a 3-byte UTF-8 character */ + BT_LEAD4, /* lead byte of a 4-byte UTF-8 character */ + BT_TRAIL, /* trailing unit, e.g. second 16-bit unit of a 4-byte char. */ + BT_CR, /* carriage return = "\r" */ + BT_LF, /* line feed = "\n" */ + BT_GT, /* greater than = ">" */ + BT_QUOT, /* quotation character = "\"" */ + BT_APOS, /* apostrophe = "'" */ + BT_EQUALS, /* equal sign = "=" */ + BT_QUEST, /* question mark = "?" */ + BT_EXCL, /* exclamation mark = "!" */ + BT_SOL, /* solidus, slash = "/" */ + BT_SEMI, /* semicolon = ";" */ + BT_NUM, /* number sign = "#" */ + BT_LSQB, /* left square bracket = "[" */ + BT_S, /* white space, e.g. "\t", " "[, "\r"] */ + BT_NMSTRT, /* non-hex name start letter = "G".."Z" + "g".."z" + "_" */ + BT_COLON, /* colon = ":" */ + BT_HEX, /* hex letter = "A".."F" + "a".."f" */ + BT_DIGIT, /* digit = "0".."9" */ + BT_NAME, /* dot and middle dot = "." + chr(0xb7) */ + BT_MINUS, /* minus = "-" */ + BT_OTHER, /* known not to be a name or name start character */ + BT_NONASCII, /* might be a name or name start character */ + BT_PERCNT, /* percent sign = "%" */ + BT_LPAR, /* left parenthesis = "(" */ + BT_RPAR, /* right parenthesis = "(" */ + BT_AST, /* asterisk = "*" */ + BT_PLUS, /* plus sign = "+" */ + BT_COMMA, /* comma = "," */ + BT_VERBAR /* vertical bar = "|" */ +}; + +#include + +#endif /* LV_USE_XML */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok_ns.c b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok_ns.c new file mode 100644 index 000000000..595d7084d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/expat/xmltok_ns.c @@ -0,0 +1,128 @@ +/* This file is included! + __ __ _ + ___\ \/ /_ __ __ _| |_ + / _ \\ /| '_ \ / _` | __| + | __// \| |_) | (_| | |_ + \___/_/\_\ .__/ \__,_|\__| + |_| XML parser + + Copyright (c) 1997-2000 Thai Open Source Software Center Ltd + Copyright (c) 2000 Clark Cooper + Copyright (c) 2002 Greg Stein + Copyright (c) 2002 Fred L. Drake, Jr. + Copyright (c) 2002-2006 Karl Waclawek + Copyright (c) 2017-2021 Sebastian Pipping + Licensed under the MIT license: + + 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_XML + +#ifdef XML_TOK_NS_C + +const ENCODING * +NS(XmlGetUtf8InternalEncoding)(void) { + return &ns(internal_utf8_encoding).enc; +} + +const ENCODING * +NS(XmlGetUtf16InternalEncoding)(void) { +# if BYTEORDER == 1234 + return &ns(internal_little2_encoding).enc; +# elif BYTEORDER == 4321 + return &ns(internal_big2_encoding).enc; +# else + const short n = 1; + return (*(const char *)&n ? &ns(internal_little2_encoding).enc + : &ns(internal_big2_encoding).enc); +# endif +} + +static const ENCODING *const NS(encodings)[] = { + &ns(latin1_encoding).enc, &ns(ascii_encoding).enc, + &ns(utf8_encoding).enc, &ns(big2_encoding).enc, + &ns(big2_encoding).enc, &ns(little2_encoding).enc, + &ns(utf8_encoding).enc /* NO_ENC */ +}; + +static int PTRCALL +NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, + ptr, end, nextTokPtr); +} + +static int PTRCALL +NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) { + return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, + ptr, end, nextTokPtr); +} + +int +NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, + const char *name) { + int i = getEncodingIndex(name); + if (i == UNKNOWN_ENC) + return 0; + SET_INIT_ENC_INDEX(p, i); + p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog); + p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent); + p->initEnc.updatePosition = initUpdatePosition; + p->encPtr = encPtr; + *encPtr = &(p->initEnc); + return 1; +} + +static const ENCODING * +NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) { +# define ENCODING_MAX 128 + char buf[ENCODING_MAX] = ""; + char *p = buf; + int i; + XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1); + if (ptr != end) + return 0; + *p = 0; + if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2) + return enc; + i = getEncodingIndex(buf); + if (i == UNKNOWN_ENC) + return 0; + return NS(encodings)[i]; +} + +int +NS(XmlParseXmlDecl)(int isGeneralTextEntity, const ENCODING *enc, + const char *ptr, const char *end, const char **badPtr, + const char **versionPtr, const char **versionEndPtr, + const char **encodingName, const ENCODING **encoding, + int *standalone) { + return doParseXmlDecl(NS(findEncoding), isGeneralTextEntity, enc, ptr, end, + badPtr, versionPtr, versionEndPtr, encodingName, + encoding, standalone); +} + +#endif /* XML_TOK_NS_C */ + +#endif /* LV_USE_XML */ + 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 8290944a5..65f4b7ca6 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg.c @@ -9,6 +9,7 @@ #include "lv_ffmpeg_private.h" #if LV_USE_FFMPEG != 0 #include "../../draw/lv_image_decoder_private.h" +#include "../../draw/lv_draw_buf_private.h" #include "../../core/lv_obj_class_private.h" #include @@ -38,10 +39,14 @@ #define FRAME_DEF_REFR_PERIOD 33 /*[ms]*/ +#define DECODER_BUFFER_SIZE (8 * 1024) + /********************** * TYPEDEFS **********************/ struct ffmpeg_context_s { + AVIOContext * io_ctx; + lv_fs_file_t lv_file; AVFormatContext * fmt_ctx; AVCodecContext * video_dec_ctx; AVStream * video_stream; @@ -56,11 +61,12 @@ struct ffmpeg_context_s { enum AVPixelFormat video_dst_pix_fmt; bool has_alpha; lv_draw_buf_t draw_buf; + lv_draw_buf_handlers_t draw_buf_handlers; }; #pragma pack(1) -struct lv_image_pixel_color_s { +struct _lv_image_pixel_color_s { lv_color_t c; uint8_t alpha; }; @@ -75,12 +81,15 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_d 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 struct ffmpeg_context_s * ffmpeg_open_file(const char * path); +static int ffmpeg_lvfs_read(void * ptr, uint8_t * buf, int buf_size); +static int64_t ffmpeg_lvfs_seek(void * ptr, int64_t pos, int whence); +static AVIOContext * ffmpeg_open_io_context(lv_fs_file_t * file); +static struct ffmpeg_context_s * ffmpeg_open_file(const char * path, bool is_lv_fs_path); static void ffmpeg_close(struct ffmpeg_context_s * ffmpeg_ctx); static void ffmpeg_close_src_ctx(struct ffmpeg_context_s * ffmpeg_ctx); static void ffmpeg_close_dst_ctx(struct ffmpeg_context_s * ffmpeg_ctx); static int ffmpeg_image_allocate(struct ffmpeg_context_s * ffmpeg_ctx); -static int ffmpeg_get_image_header(const char * path, lv_image_header_t * header); +static int ffmpeg_get_image_header(lv_image_decoder_dsc_t * dsc, lv_image_header_t * header); static int ffmpeg_get_frame_refr_period(struct ffmpeg_context_s * ffmpeg_ctx); static uint8_t * ffmpeg_get_image_data(struct ffmpeg_context_s * ffmpeg_ctx); static int ffmpeg_update_next_frame(struct ffmpeg_context_s * ffmpeg_ctx); @@ -100,7 +109,7 @@ const lv_obj_class_t lv_ffmpeg_player_class = { .destructor_cb = lv_ffmpeg_player_destructor, .instance_size = sizeof(lv_ffmpeg_player_t), .base_class = &lv_image_class, - .name = "ffmpeg-player", + .name = "lv_ffmpeg_player", }; /********************** @@ -120,15 +129,26 @@ void lv_ffmpeg_init(void) dec->name = DECODER_NAME; -#if LV_FFMPEG_AV_DUMP_FORMAT == 0 +#if LV_FFMPEG_DUMP_FORMAT == 0 av_log_set_level(AV_LOG_QUIET); #endif } +void lv_ffmpeg_deinit(void) +{ + lv_image_decoder_t * dec = NULL; + while((dec = lv_image_decoder_get_next(dec)) != NULL) { + if(dec->info_cb == decoder_info) { + lv_image_decoder_delete(dec); + break; + } + } +} + int lv_ffmpeg_get_frame_num(const char * path) { int ret = -1; - struct ffmpeg_context_s * ffmpeg_ctx = ffmpeg_open_file(path); + struct ffmpeg_context_s * ffmpeg_ctx = ffmpeg_open_file(path, LV_FFMPEG_PLAYER_USE_LV_FS); if(ffmpeg_ctx) { ret = ffmpeg_ctx->video_stream->nb_frames; @@ -159,32 +179,35 @@ lv_result_t lv_ffmpeg_player_set_src(lv_obj_t * obj, const char * path) lv_timer_pause(player->timer); - player->ffmpeg_ctx = ffmpeg_open_file(path); + player->ffmpeg_ctx = ffmpeg_open_file(path, LV_FFMPEG_PLAYER_USE_LV_FS); if(!player->ffmpeg_ctx) { - LV_LOG_ERROR("ffmpeg file open failed: %s", path); goto failed; } if(ffmpeg_image_allocate(player->ffmpeg_ctx) < 0) { LV_LOG_ERROR("ffmpeg image allocate failed"); ffmpeg_close(player->ffmpeg_ctx); + player->ffmpeg_ctx = NULL; goto failed; } bool has_alpha = player->ffmpeg_ctx->has_alpha; int width = player->ffmpeg_ctx->video_dec_ctx->width; int height = player->ffmpeg_ctx->video_dec_ctx->height; - uint32_t data_size = 0; - data_size = width * height * 4; + uint8_t * data = ffmpeg_get_image_data(player->ffmpeg_ctx); + lv_color_format_t cf = has_alpha ? LV_COLOR_FORMAT_ARGB8888 : LV_COLOR_FORMAT_NATIVE; + uint32_t stride = width * lv_color_format_get_size(cf); + uint32_t data_size = stride * height; + lv_memzero(data, data_size); player->imgdsc.header.w = width; player->imgdsc.header.h = height; player->imgdsc.data_size = data_size; - player->imgdsc.header.cf = has_alpha ? LV_COLOR_FORMAT_ARGB8888 : LV_COLOR_FORMAT_NATIVE; - player->imgdsc.header.stride = width * lv_color_format_get_size(player->imgdsc.header.cf); - player->imgdsc.data = ffmpeg_get_image_data(player->ffmpeg_ctx); + player->imgdsc.header.cf = cf; + player->imgdsc.header.stride = stride; + player->imgdsc.data = data; lv_image_set_src(&player->img.obj, &(player->imgdsc)); @@ -260,13 +283,10 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_d LV_UNUSED(decoder); /* Get the source type */ - 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; - - if(ffmpeg_get_image_header(fn, header) < 0) { + if(ffmpeg_get_image_header(dsc, header) < 0) { LV_LOG_ERROR("ffmpeg can't get image header"); return LV_RESULT_INVALID; } @@ -291,7 +311,7 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d if(dsc->src_type == LV_IMAGE_SRC_FILE) { const char * path = dsc->src; - struct ffmpeg_context_s * ffmpeg_ctx = ffmpeg_open_file(path); + struct ffmpeg_context_s * ffmpeg_ctx = ffmpeg_open_file(path, true); if(ffmpeg_ctx == NULL) { return LV_RESULT_INVALID; @@ -314,11 +334,24 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d dsc->user_data = ffmpeg_ctx; lv_draw_buf_t * decoded = &ffmpeg_ctx->draw_buf; - decoded->header = dsc->header; - decoded->header.flags |= LV_IMAGE_FLAGS_MODIFIABLE; - decoded->data = img_data; - decoded->data_size = (uint32_t)dsc->header.stride * dsc->header.h; - decoded->unaligned_data = NULL; + lv_draw_buf_init( + decoded, + dsc->header.w, + dsc->header.h, + dsc->header.cf, + dsc->header.stride, + img_data, + dsc->header.stride * dsc->header.h); + lv_draw_buf_set_flag(decoded, LV_IMAGE_FLAGS_MODIFIABLE); + + /* Empty handlers to avoid decoder asserts */ + lv_draw_buf_handlers_init(&ffmpeg_ctx->draw_buf_handlers, NULL, NULL, NULL, NULL, NULL, NULL); + decoded->handlers = &ffmpeg_ctx->draw_buf_handlers; + + if(dsc->args.premultiply && ffmpeg_ctx->has_alpha) { + lv_draw_buf_premultiply(decoded); + } + dsc->decoded = decoded; /* The image is fully decoded. Return with its pointer */ @@ -401,8 +434,6 @@ static int ffmpeg_output_video_frame(struct ffmpeg_context_s * ffmpeg_ctx) goto failed; } - LV_LOG_TRACE("video_frame coded_n:%d", frame->coded_picture_number); - /* copy decoded frame to destination buffer: * this is required since rawvideo expects non aligned data */ @@ -564,18 +595,33 @@ static int ffmpeg_open_codec_context(int * stream_idx, return 0; } -static int ffmpeg_get_image_header(const char * filepath, +static int ffmpeg_get_image_header(lv_image_decoder_dsc_t * dsc, lv_image_header_t * header) { int ret = -1; AVFormatContext * fmt_ctx = NULL; AVCodecContext * video_dec_ctx = NULL; + AVIOContext * io_ctx = NULL; int video_stream_idx; + io_ctx = ffmpeg_open_io_context(&dsc->file); + if(io_ctx == NULL) { + LV_LOG_ERROR("io_ctx malloc failed"); + return ret; + } + + fmt_ctx = avformat_alloc_context(); + if(fmt_ctx == NULL) { + LV_LOG_ERROR("fmt_ctx malloc failed"); + goto failed; + } + fmt_ctx->pb = io_ctx; + fmt_ctx->flags |= AVFMT_FLAG_CUSTOM_IO; + /* open input file, and allocate format context */ - if(avformat_open_input(&fmt_ctx, filepath, NULL, NULL) < 0) { - LV_LOG_ERROR("Could not open source file %s", filepath); + if(avformat_open_input(&fmt_ctx, (const char *)dsc->src, NULL, NULL) < 0) { + LV_LOG_ERROR("Could not open source file %s", (const char *)dsc->src); goto failed; } @@ -602,7 +648,10 @@ static int ffmpeg_get_image_header(const char * filepath, failed: avcodec_free_context(&video_dec_ctx); avformat_close_input(&fmt_ctx); - + if(io_ctx != NULL) { + av_free(io_ctx->buffer); + av_free(io_ctx); + } return ret; } @@ -658,20 +707,85 @@ static int ffmpeg_update_next_frame(struct ffmpeg_context_s * ffmpeg_ctx) return ret; } -struct ffmpeg_context_s * ffmpeg_open_file(const char * path) +static int ffmpeg_lvfs_read(void * ptr, uint8_t * buf, int buf_size) +{ + lv_fs_file_t * file = ptr; + uint32_t bytesRead = 0; + lv_fs_res_t res = lv_fs_read(file, buf, buf_size, &bytesRead); + if(bytesRead == 0) + return AVERROR_EOF; /* Let FFmpeg know that we have reached eof */ + if(res != LV_FS_RES_OK) + return AVERROR_EOF; + return bytesRead; +} + +static int64_t ffmpeg_lvfs_seek(void * ptr, int64_t pos, int whence) +{ + lv_fs_file_t * file = ptr; + if(whence == SEEK_SET && lv_fs_seek(file, pos, SEEK_SET) == LV_FS_RES_OK) { + return pos; + } + return -1; +} + +static AVIOContext * ffmpeg_open_io_context(lv_fs_file_t * file) +{ + uint8_t * iBuffer = av_malloc(DECODER_BUFFER_SIZE); + if(iBuffer == NULL) { + LV_LOG_ERROR("iBuffer malloc failed"); + return NULL; + } + AVIOContext * pIOCtx = avio_alloc_context(iBuffer, DECODER_BUFFER_SIZE, /* internal Buffer and its size */ + 0, /* bWriteable (1=true,0=false) */ + file, /* user data ; will be passed to our callback functions */ + ffmpeg_lvfs_read, /* Read callback function */ + 0, /* Write callback function */ + ffmpeg_lvfs_seek); /* Seek callback function */ + if(pIOCtx == NULL) { + av_free(iBuffer); + return NULL; + } + return pIOCtx; +} + +static struct ffmpeg_context_s * ffmpeg_open_file(const char * path, bool is_lv_fs_path) { if(path == NULL || lv_strlen(path) == 0) { LV_LOG_ERROR("file path is empty"); return NULL; } - struct ffmpeg_context_s * ffmpeg_ctx = calloc(1, sizeof(struct ffmpeg_context_s)); - + struct ffmpeg_context_s * ffmpeg_ctx = lv_malloc_zeroed(sizeof(struct ffmpeg_context_s)); + LV_ASSERT_MALLOC(ffmpeg_ctx); if(ffmpeg_ctx == NULL) { LV_LOG_ERROR("ffmpeg_ctx malloc failed"); goto failed; } + if(is_lv_fs_path) { + const lv_fs_res_t fs_res = lv_fs_open(&(ffmpeg_ctx->lv_file), path, LV_FS_MODE_RD); + if(fs_res != LV_FS_RES_OK) { + LV_LOG_WARN("Could not open file: %s, res: %d", path, fs_res); + lv_free(ffmpeg_ctx); + return NULL; + } + + ffmpeg_ctx->io_ctx = ffmpeg_open_io_context(&(ffmpeg_ctx->lv_file)); /* Save the buffer pointer to free it later */ + + if(ffmpeg_ctx->io_ctx == NULL) { + LV_LOG_ERROR("io_ctx malloc failed"); + goto failed; + } + + ffmpeg_ctx->fmt_ctx = avformat_alloc_context(); + if(ffmpeg_ctx->fmt_ctx == NULL) { + LV_LOG_ERROR("fmt_ctx malloc failed"); + goto failed; + } + ffmpeg_ctx->fmt_ctx->pb = ffmpeg_ctx->io_ctx; + ffmpeg_ctx->fmt_ctx->flags |= AVFMT_FLAG_CUSTOM_IO; + } + /* open input file, and allocate format context */ if(avformat_open_input(&(ffmpeg_ctx->fmt_ctx), path, NULL, NULL) < 0) { @@ -698,7 +812,7 @@ struct ffmpeg_context_s * ffmpeg_open_file(const char * path) ffmpeg_ctx->video_dst_pix_fmt = (ffmpeg_ctx->has_alpha ? AV_PIX_FMT_BGRA : AV_PIX_FMT_TRUE_COLOR); } -#if LV_FFMPEG_AV_DUMP_FORMAT != 0 +#if LV_FFMPEG_DUMP_FORMAT /* dump input information to stderr */ av_dump_format(ffmpeg_ctx->fmt_ctx, 0, path, 0); #endif @@ -774,6 +888,7 @@ static void ffmpeg_close_src_ctx(struct ffmpeg_context_s * ffmpeg_ctx) { avcodec_free_context(&(ffmpeg_ctx->video_dec_ctx)); avformat_close_input(&(ffmpeg_ctx->fmt_ctx)); + av_packet_free(&ffmpeg_ctx->pkt); av_frame_free(&(ffmpeg_ctx->frame)); if(ffmpeg_ctx->video_src_data[0] != NULL) { av_free(ffmpeg_ctx->video_src_data[0]); @@ -799,7 +914,12 @@ static void ffmpeg_close(struct ffmpeg_context_s * ffmpeg_ctx) sws_freeContext(ffmpeg_ctx->sws_ctx); ffmpeg_close_src_ctx(ffmpeg_ctx); ffmpeg_close_dst_ctx(ffmpeg_ctx); - free(ffmpeg_ctx); + if(ffmpeg_ctx->io_ctx != NULL) { + av_free(ffmpeg_ctx->io_ctx->buffer); + av_free(ffmpeg_ctx->io_ctx); + lv_fs_close(&(ffmpeg_ctx->lv_file)); + } + lv_free(ffmpeg_ctx); LV_LOG_INFO("ffmpeg_ctx closed"); } @@ -817,6 +937,9 @@ static void lv_ffmpeg_player_frame_update_cb(lv_timer_t * timer) if(has_next < 0) { lv_ffmpeg_player_set_cmd(obj, player->auto_restart ? LV_FFMPEG_PLAYER_CMD_START : LV_FFMPEG_PLAYER_CMD_STOP); + if(!player->auto_restart) { + lv_obj_send_event((lv_obj_t *)player, LV_EVENT_READY, NULL); + } return; } 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 1cb86b9d4..86cb8b05e 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg.h @@ -44,6 +44,11 @@ typedef enum { */ void lv_ffmpeg_init(void); +/** + * De-initialize FFMPEG image decoder + */ +void lv_ffmpeg_deinit(void); + /** * Get the number of frames contained in the file * @param path image or video file name @@ -59,7 +64,7 @@ int lv_ffmpeg_get_frame_num(const char * path); lv_obj_t * lv_ffmpeg_player_create(lv_obj_t * parent); /** - * Set the path of the file to be played + * Set the path of the file to be played. * @param obj pointer to a ffmpeg_player object * @param path video file path * @return LV_RESULT_OK: no error; LV_RESULT_INVALID: can't get the info. 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 index b27b6bf02..e4a0488ae 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg_private.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/ffmpeg/lv_ffmpeg_private.h @@ -26,7 +26,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_ffmpeg_player_t { +struct _lv_ffmpeg_player_t { lv_image_t img; lv_timer_t * timer; lv_image_dsc_t imgdsc; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/freetype/LICENSE.txt b/lib/libesp32_lvgl/lvgl/src/libs/freetype/LICENSE.txt new file mode 100644 index 000000000..b4e23f8ed --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/freetype/LICENSE.txt @@ -0,0 +1,170 @@ + The FreeType Project LICENSE + ---------------------------- + + 2006-Jan-27 + + Copyright 1996-2002, 2006 by + David Turner, Robert Wilhelm, and Werner Lemberg + + + +Introduction +============ + + The FreeType Project is distributed in several archive packages; + some of them may contain, in addition to the FreeType font engine, + various tools and contributions which rely on, or relate to, the + FreeType Project. + + This license applies to all files found in such packages, and + which do not fall under their own explicit license. The license + affects thus the FreeType font engine, the test programs, + documentation and makefiles, at the very least. + + This license was inspired by the BSD, Artistic, and IJG + (Independent JPEG Group) licenses, which all encourage inclusion + and use of free software in commercial and freeware products + alike. As a consequence, its main points are that: + + o We don't promise that this software works. However, we will be + interested in any kind of bug reports. (`as is' distribution) + + o You can use this software for whatever you want, in parts or + full form, without having to pay us. (`royalty-free' usage) + + o You may not pretend that you wrote this software. If you use + it, or only parts of it, in a program, you must acknowledge + somewhere in your documentation that you have used the + FreeType code. (`credits') + + We specifically permit and encourage the inclusion of this + software, with or without modifications, in commercial products. + We disclaim all warranties covering The FreeType Project and + assume no liability related to The FreeType Project. + + + Finally, many people asked us for a preferred form for a + credit/disclaimer to use in compliance with this license. We thus + encourage you to use the following text: + + """ + Portions of this software are copyright © The FreeType + Project (www.freetype.org). All rights reserved. + """ + + Please replace with the value from the FreeType version you + actually use. + + +Legal Terms +=========== + +0. Definitions +-------------- + + Throughout this license, the terms `package', `FreeType Project', + and `FreeType archive' refer to the set of files originally + distributed by the authors (David Turner, Robert Wilhelm, and + Werner Lemberg) as the `FreeType Project', be they named as alpha, + beta or final release. + + `You' refers to the licensee, or person using the project, where + `using' is a generic term including compiling the project's source + code as well as linking it to form a `program' or `executable'. + This program is referred to as `a program using the FreeType + engine'. + + This license applies to all files distributed in the original + FreeType Project, including all source code, binaries and + documentation, unless otherwise stated in the file in its + original, unmodified form as distributed in the original archive. + If you are unsure whether or not a particular file is covered by + this license, you must contact us to verify this. + + The FreeType Project is copyright (C) 1996-2000 by David Turner, + Robert Wilhelm, and Werner Lemberg. All rights reserved except as + specified below. + +1. No Warranty +-------------- + + THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO + USE, OF THE FREETYPE PROJECT. + +2. Redistribution +----------------- + + This license grants a worldwide, royalty-free, perpetual and + irrevocable right and license to use, execute, perform, compile, + display, copy, create derivative works of, distribute and + sublicense the FreeType Project (in both source and object code + forms) and derivative works thereof for any purpose; and to + authorize others to exercise some or all of the rights granted + herein, subject to the following conditions: + + o Redistribution of source code must retain this license file + (`FTL.TXT') unaltered; any additions, deletions or changes to + the original files must be clearly indicated in accompanying + documentation. The copyright notices of the unaltered, + original files must be preserved in all copies of source + files. + + o Redistribution in binary form must provide a disclaimer that + states that the software is based in part of the work of the + FreeType Team, in the distribution documentation. We also + encourage you to put an URL to the FreeType web page in your + documentation, though this isn't mandatory. + + These conditions apply to any software derived from or based on + the FreeType Project, not just the unmodified files. If you use + our work, you must acknowledge us. However, no fee need be paid + to us. + +3. Advertising +-------------- + + Neither the FreeType authors and contributors nor you shall use + the name of the other for commercial, advertising, or promotional + purposes without specific prior written permission. + + We suggest, but do not require, that you use one or more of the + following phrases to refer to this software in your documentation + or advertising materials: `FreeType Project', `FreeType Engine', + `FreeType library', or `FreeType Distribution'. + + As you have not signed this license, you are not required to + accept it. However, as the FreeType Project is copyrighted + material, only this license, or another one contracted with the + authors, grants you the right to use, distribute, and modify it. + Therefore, by using, distributing, or modifying the FreeType + Project, you indicate that you understand and accept all the terms + of this license. + +4. Contacts +----------- + + There are two mailing lists related to FreeType: + + o freetype@nongnu.org + + Discusses general use and applications of FreeType, as well as + future and wanted additions to the library and distribution. + If you are looking for support, start in this list if you + haven't found anything to help you in the documentation. + + o freetype-devel@nongnu.org + + Discusses bugs, as well as engine internals, design issues, + specific licenses, porting, etc. + + Our home page can be found at + + https://www.freetype.org + + +--- end of FTL.TXT --- + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/freetype/ftoption.h b/lib/libesp32_lvgl/lvgl/src/libs/freetype/ftoption.h index 141278b01..1a762bb02 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/freetype/ftoption.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/freetype/ftoption.h @@ -258,7 +258,7 @@ FT_BEGIN_HEADER * options set by those programs have precedence, overwriting the value * here with the configured one. */ -/* #define FT_CONFIG_OPTION_USE_PNG */ +#define FT_CONFIG_OPTION_USE_PNG /************************************************************************** * 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 b1da8f13e..77e33244a 100755 --- a/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype.c @@ -6,12 +6,11 @@ /********************* * INCLUDES *********************/ -#include "../../misc/lv_fs_private.h" #include "lv_freetype_private.h" #if LV_USE_FREETYPE -#include "lv_freetype_private.h" +#include "../../misc/lv_fs_private.h" #include "../../core/lv_global.h" /********************* @@ -51,10 +50,23 @@ static bool cache_node_cache_create_cb(lv_freetype_cache_node_t * node, void * u static void cache_node_cache_free_cb(lv_freetype_cache_node_t * node, void * user_data); static lv_cache_compare_res_t cache_node_cache_compare_cb(const lv_freetype_cache_node_t * lhs, const lv_freetype_cache_node_t * rhs); + +static lv_font_t * freetype_font_create_cb(const lv_font_info_t * info, const void * src); +static void freetype_font_delete_cb(lv_font_t * font); +static void * freetype_font_dup_src_cb(const void * src); +static void freetype_font_free_src_cb(void * src); + /********************** * STATIC VARIABLES **********************/ +const lv_font_class_t lv_freetype_font_class = { + .create_cb = freetype_font_create_cb, + .delete_cb = freetype_font_delete_cb, + .dup_src_cb = freetype_font_dup_src_cb, + .free_src_cb = freetype_font_free_src_cb, +}; + /********************** * MACROS **********************/ @@ -111,21 +123,38 @@ void lv_freetype_uninit(void) ft_ctx = NULL; } -lv_font_t * lv_freetype_font_create(const char * pathname, lv_freetype_font_render_mode_t render_mode, uint32_t size, - lv_freetype_font_style_t style) +void lv_freetype_init_font_info(lv_font_info_t * font_info) { - LV_ASSERT_NULL(pathname); - LV_ASSERT(size > 0); + LV_ASSERT_NULL(font_info); + lv_memzero(font_info, sizeof(lv_font_info_t)); + font_info->class_p = &lv_freetype_font_class; + font_info->render_mode = LV_FREETYPE_FONT_RENDER_MODE_BITMAP; + font_info->style = LV_FREETYPE_FONT_STYLE_NORMAL; + font_info->kerning = LV_FONT_KERNING_NONE; +} - size_t pathname_len = lv_strlen(pathname); - LV_ASSERT(pathname_len > 0); +lv_font_t * lv_freetype_font_create_with_info(const lv_font_info_t * font_info) +{ + LV_ASSERT_NULL(font_info); + if(font_info->size == 0) { + LV_LOG_ERROR("font size can't be zero"); + return NULL; + } + + const char * pathname = font_info->name; + + size_t pathname_len = pathname ? lv_strlen(pathname) : 0; + if(pathname_len == 0) { + LV_LOG_ERROR("font pathname can't be empty"); + return NULL; + } lv_freetype_context_t * ctx = lv_freetype_get_context(); lv_freetype_cache_node_t search_key = { .pathname = lv_freetype_req_face_id(ctx, pathname), - .style = style, - .render_mode = render_mode, + .style = font_info->style, + .render_mode = font_info->render_mode, }; bool cache_hitting = true; @@ -144,10 +173,11 @@ lv_font_t * lv_freetype_font_create(const char * pathname, lv_freetype_font_rend LV_ASSERT_MALLOC(dsc); dsc->face_id = (FTC_FaceID)search_key.pathname; - dsc->render_mode = render_mode; + dsc->render_mode = font_info->render_mode; dsc->context = ctx; - dsc->size = size; - dsc->style = style; + dsc->size = font_info->size; + dsc->style = font_info->style; + dsc->kerning = font_info->kerning; dsc->magic_num = LV_FREETYPE_FONT_DSC_MAGIC_NUM; dsc->cache_node = lv_cache_entry_get_data(cache_node_entry); dsc->cache_node_entry = cache_node_entry; @@ -161,7 +191,22 @@ lv_font_t * lv_freetype_font_create(const char * pathname, lv_freetype_font_rend freetype_on_font_set_cbs(dsc); FT_Face face = dsc->cache_node->face; - FT_Set_Pixel_Sizes(face, 0, size); + FT_Error error; + if(FT_IS_SCALABLE(face)) { + error = FT_Set_Pixel_Sizes(face, 0, font_info->size); + } + else { + LV_LOG_WARN("font is not scalable, selecting available size"); + error = FT_Select_Size(face, 0); + } + if(error) { + FT_ERROR_MSG("FT_Set_Pixel_Sizes", error); + return NULL; + } + + if(dsc->kerning != LV_FONT_KERNING_NONE && !dsc->cache_node->face_has_kerning) { + LV_LOG_WARN("font: '%s' doesn't have kerning info", pathname); + } lv_font_t * font = &dsc->font; font->dsc = dsc; @@ -177,6 +222,18 @@ lv_font_t * lv_freetype_font_create(const char * pathname, lv_freetype_font_rend return font; } +lv_font_t * lv_freetype_font_create(const char * pathname, lv_freetype_font_render_mode_t render_mode, uint32_t size, + lv_freetype_font_style_t style) +{ + lv_font_info_t font_info; + lv_freetype_init_font_info(&font_info); + font_info.name = pathname; + font_info.size = size; + font_info.render_mode = render_mode; + font_info.style = style; + return lv_freetype_font_create_with_info(&font_info); +} + void lv_freetype_font_delete(lv_font_t * font) { LV_ASSERT_NULL(font); @@ -369,6 +426,7 @@ static bool cache_node_cache_create_cb(lv_freetype_cache_node_t * node, void * u } node->face = face; + node->face_has_kerning = FT_HAS_KERNING(face); lv_mutex_init(&node->face_lock); return true; @@ -405,4 +463,26 @@ static lv_cache_compare_res_t cache_node_cache_compare_cb(const lv_freetype_cach return 0; } +static lv_font_t * freetype_font_create_cb(const lv_font_info_t * info, const void * src) +{ + lv_font_info_t font_info = *info; + font_info.name = src; + return lv_freetype_font_create_with_info(&font_info); +} + +static void freetype_font_delete_cb(lv_font_t * font) +{ + lv_freetype_font_delete(font); +} + +static void * freetype_font_dup_src_cb(const void * src) +{ + return lv_strdup(src); +} + +static void freetype_font_free_src_cb(void * src) +{ + lv_free(src); +} + #endif /*LV_USE_FREETYPE*/ 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 76b9f7b56..98837e5ea 100755 --- a/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/freetype/lv_freetype.h @@ -13,15 +13,18 @@ extern "C" { * INCLUDES *********************/ #include "../../lv_conf_internal.h" -#include "../../misc/lv_types.h" -#include "../../misc/lv_event.h" -#include LV_STDBOOL_INCLUDE #if LV_USE_FREETYPE +#include "../../misc/lv_types.h" +#include "../../misc/lv_event.h" +#include "../../misc/lv_color.h" + +#include LV_STDBOOL_INCLUDE + /********************* - * DEFINES - *********************/ +* DEFINES +*********************/ #define LV_FREETYPE_F26DOT6_TO_INT(x) ((x) >> 6) #define LV_FREETYPE_F26DOT6_TO_FLOAT(x) ((float)(x) / 64) @@ -55,8 +58,14 @@ typedef enum { LV_FREETYPE_OUTLINE_LINE_TO, LV_FREETYPE_OUTLINE_CUBIC_TO, LV_FREETYPE_OUTLINE_CONIC_TO, + LV_FREETYPE_OUTLINE_BORDER_START, /* When line width > 0 the border glyph is drawn after the regular glyph */ } lv_freetype_outline_type_t; +/* Only path string is required */ +typedef const char lv_freetype_font_src_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_font_class_t lv_freetype_font_class; + /********************** * GLOBAL PROTOTYPES **********************/ @@ -72,6 +81,19 @@ lv_result_t lv_freetype_init(uint32_t max_glyph_cnt); */ void lv_freetype_uninit(void); +/** + * Initialize a font info structure. + * @param font_info font info structure to be initialized. + */ +void lv_freetype_init_font_info(lv_font_info_t * font_info); + +/** + * Create a freetype font with a font info structure. + * @param font_info font info structure. + * @return Created font, or NULL on failure. + */ +lv_font_t * lv_freetype_font_create_with_info(const lv_font_info_t * font_info); + /** * Create a freetype font. * @param pathname font file path. 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 7ed217883..832d820e0 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 @@ -21,7 +21,7 @@ /********************** * TYPEDEFS **********************/ -typedef struct lv_freetype_glyph_cache_data_t { +typedef struct _lv_freetype_glyph_cache_data_t { uint32_t unicode; uint32_t size; @@ -81,6 +81,7 @@ static bool freetype_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_ { LV_ASSERT_NULL(font); LV_ASSERT_NULL(g_dsc); + LV_PROFILER_FONT_BEGIN; if(unicode_letter < 0x20) { g_dsc->adv_w = 0; @@ -89,6 +90,7 @@ static bool freetype_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_ g_dsc->ofs_x = 0; g_dsc->ofs_y = 0; g_dsc->format = LV_FONT_GLYPH_FORMAT_NONE; + LV_PROFILER_FONT_END; return true; } @@ -105,6 +107,7 @@ static bool freetype_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_ lv_cache_entry_t * entry = lv_cache_acquire_or_create(glyph_cache, &search_key, dsc); if(entry == NULL) { LV_LOG_ERROR("glyph lookup failed for unicode = 0x%" LV_PRIx32, unicode_letter); + LV_PROFILER_FONT_END; return false; } lv_freetype_glyph_cache_data_t * data = lv_cache_entry_get_data(entry); @@ -114,9 +117,25 @@ static bool freetype_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_ g_dsc->adv_w = g_dsc->box_w + g_dsc->ofs_x; } + if(dsc->kerning == LV_FONT_KERNING_NORMAL && dsc->cache_node->face_has_kerning && unicode_letter_next != '\0') { + lv_mutex_lock(&dsc->cache_node->face_lock); + FT_Face face = dsc->cache_node->face; + FT_UInt glyph_index_next = FT_Get_Char_Index(face, unicode_letter_next); + FT_Vector kerning; + FT_Error error = FT_Get_Kerning(face, g_dsc->gid.index, glyph_index_next, FT_KERNING_DEFAULT, &kerning); + if(!error) { + g_dsc->adv_w += LV_FREETYPE_F26DOT6_TO_INT(kerning.x); + } + else { + FT_ERROR_MSG("FT_Get_Kerning", error); + } + lv_mutex_unlock(&dsc->cache_node->face_lock); + } + g_dsc->entry = NULL; lv_cache_release(glyph_cache, entry, NULL); + LV_PROFILER_FONT_END; return true; } @@ -126,27 +145,45 @@ static bool freetype_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_ static bool freetype_glyph_create_cb(lv_freetype_glyph_cache_data_t * data, void * user_data) { - lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)user_data; + LV_PROFILER_FONT_BEGIN; FT_Error error; - + lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)user_data; 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 | FT_LOAD_NO_AUTOHINT); + if(FT_IS_SCALABLE(face)) { + error = FT_Set_Pixel_Sizes(face, 0, dsc->size); + } + else { + error = FT_Select_Size(face, 0); + } + if(error) { + FT_ERROR_MSG("FT_Set_Pixel_Sizes", error); + lv_mutex_unlock(&dsc->cache_node->face_lock); + return false; + } + + if(dsc->render_mode == LV_FREETYPE_FONT_RENDER_MODE_OUTLINE) { + error = FT_Load_Glyph(face, glyph_index, FT_LOAD_COMPUTE_METRICS | FT_LOAD_NO_BITMAP | FT_LOAD_NO_AUTOHINT); + } + else if(dsc->render_mode == LV_FREETYPE_FONT_RENDER_MODE_BITMAP) { + error = FT_Load_Glyph(face, glyph_index, FT_LOAD_COMPUTE_METRICS | FT_LOAD_NO_AUTOHINT); + } if(error) { FT_ERROR_MSG("FT_Load_Glyph", error); lv_mutex_unlock(&dsc->cache_node->face_lock); + LV_PROFILER_FONT_END; return false; } FT_GlyphSlot glyph = face->glyph; if(dsc->render_mode == LV_FREETYPE_FONT_RENDER_MODE_OUTLINE) { + dsc_out->adv_w = FT_F26DOT6_TO_INT(glyph->metrics.horiAdvance); dsc_out->box_h = FT_F26DOT6_TO_INT(glyph->metrics.height); /*Height of the bitmap in [px]*/ dsc_out->box_w = FT_F26DOT6_TO_INT(glyph->metrics.width); /*Width of the bitmap in [px]*/ @@ -155,7 +192,7 @@ static bool freetype_glyph_create_cb(lv_freetype_glyph_cache_data_t * data, void glyph->metrics.height); /*Y offset of the bitmap measured from the as line*/ dsc_out->format = LV_FONT_GLYPH_FORMAT_VECTOR; - /*Transform the glyph to italic if required*/ + /*Transform the glyph to italic if required */ if(dsc->style & LV_FREETYPE_FONT_STYLE_ITALIC) { dsc_out->box_w = lv_freetype_italic_transform_on_pos((lv_point_t) { dsc_out->box_w, dsc_out->box_h @@ -171,7 +208,10 @@ static bool freetype_glyph_create_cb(lv_freetype_glyph_cache_data_t * data, void dsc_out->ofs_x = glyph->bitmap_left; /*X offset of the bitmap in [pf]*/ dsc_out->ofs_y = glyph->bitmap_top - dsc_out->box_h; /*Y offset of the bitmap measured from the as line*/ - dsc_out->format = LV_FONT_GLYPH_FORMAT_A8; + if(glyph->format == FT_GLYPH_FORMAT_BITMAP) + dsc_out->format = LV_FONT_GLYPH_FORMAT_IMAGE; + else + dsc_out->format = LV_FONT_GLYPH_FORMAT_A8; } dsc_out->is_placeholder = glyph_index == 0; @@ -179,6 +219,7 @@ static bool freetype_glyph_create_cb(lv_freetype_glyph_cache_data_t * data, void lv_mutex_unlock(&dsc->cache_node->face_lock); + LV_PROFILER_FONT_END; return true; } static void freetype_glyph_free_cb(lv_freetype_glyph_cache_data_t * data, void * user_data) 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 ab7dad292..b51b21f23 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 @@ -26,7 +26,7 @@ * TYPEDEFS **********************/ -typedef struct lv_freetype_image_cache_data_t { +typedef struct _lv_freetype_image_cache_data_t { FT_UInt glyph_index; uint32_t size; @@ -85,6 +85,7 @@ void lv_freetype_set_cbs_image_font(lv_freetype_font_dsc_t * dsc) 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); + LV_PROFILER_FONT_BEGIN; 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); @@ -99,10 +100,16 @@ static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv }; lv_cache_entry_t * entry = lv_cache_acquire_or_create(cache, &search_key, dsc); + if(entry == NULL) { + LV_LOG_ERROR("glyph bitmap lookup failed for glyph_index = 0x%" LV_PRIx32, (uint32_t)glyph_index); + LV_PROFILER_FONT_END; + return NULL; + } g_dsc->entry = entry; lv_freetype_image_cache_data_t * cache_node = lv_cache_entry_get_data(entry); + LV_PROFILER_FONT_END; return cache_node->draw_buf; } @@ -120,6 +127,8 @@ static void freetype_image_release_cb(const lv_font_t * font, lv_font_glyph_dsc_ static bool freetype_image_create_cb(lv_freetype_image_cache_data_t * data, void * user_data) { + LV_PROFILER_FONT_BEGIN; + lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)user_data; FT_Error error; @@ -127,17 +136,30 @@ static bool freetype_image_create_cb(lv_freetype_image_cache_data_t * data, void 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 | FT_LOAD_NO_AUTOHINT); + if(FT_IS_SCALABLE(face)) { + error = FT_Set_Pixel_Sizes(face, 0, dsc->size); + } + else { + error = FT_Select_Size(face, 0); + } + if(error) { + FT_ERROR_MSG("FT_Set_Pixel_Sizes", error); + lv_mutex_unlock(&dsc->cache_node->face_lock); + return false; + } + error = FT_Load_Glyph(face, data->glyph_index, + FT_LOAD_COLOR | 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); + LV_PROFILER_FONT_END; 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); + LV_PROFILER_FONT_END; return false; } @@ -146,6 +168,7 @@ static bool freetype_image_create_cb(lv_freetype_image_cache_data_t * data, void if(error) { FT_ERROR_MSG("FT_Get_Glyph", error); lv_mutex_unlock(&dsc->cache_node->face_lock); + LV_PROFILER_FONT_END; return false; } @@ -154,18 +177,33 @@ static bool freetype_image_create_cb(lv_freetype_image_cache_data_t * data, void uint16_t box_h = glyph_bitmap->bitmap.rows; /*Height of the bitmap in [px]*/ 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_ex(font_draw_buf_handlers, box_w, box_h, LV_COLOR_FORMAT_A8, stride); + lv_color_format_t col_format; + if(glyph_bitmap->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) { + col_format = LV_COLOR_FORMAT_ARGB8888; + } + else { + col_format = LV_COLOR_FORMAT_A8; + } + uint32_t pitch = glyph_bitmap->bitmap.pitch; + uint32_t stride = lv_draw_buf_width_to_stride(box_w, col_format); + data->draw_buf = lv_draw_buf_create_ex(font_draw_buf_handlers, box_w, box_h, col_format, stride); + if(!data->draw_buf) { + LV_LOG_WARN("Could not create draw buffer"); + FT_Done_Glyph(glyph); + LV_PROFILER_FONT_END; + return false; + } + lv_draw_buf_clear(data->draw_buf, NULL); 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, - box_w); + lv_memcpy((uint8_t *)(data->draw_buf->data) + y * stride, glyph_bitmap->bitmap.buffer + y * pitch, + pitch); } + lv_draw_buf_flush_cache(data->draw_buf, NULL); FT_Done_Glyph(glyph); - lv_mutex_unlock(&dsc->cache_node->face_lock); - + LV_PROFILER_FONT_END; 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 77d40fef3..f7d5edbd0 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 @@ -23,7 +23,7 @@ * 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; @@ -33,7 +33,7 @@ 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); + uint32_t size, uint32_t strength, uint32_t border_width); 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, lv_draw_buf_t * draw_buf); static void freetype_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_t * g_dsc); @@ -120,6 +120,7 @@ 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_PROFILER_FONT_BEGIN; lv_freetype_outline_t outline; lv_mutex_lock(&dsc->cache_node->face_lock); @@ -127,16 +128,19 @@ static bool freetype_glyph_outline_create_cb(lv_freetype_outline_node_t * node, dsc->cache_node->face, node->glyph_index, dsc->cache_node->ref_size, - dsc->style & LV_FREETYPE_FONT_STYLE_BOLD ? 1 : 0); + dsc->style & LV_FREETYPE_FONT_STYLE_BOLD ? 1 : 0, + dsc->outline_stroke_width); lv_mutex_unlock(&dsc->cache_node->face_lock); if(!outline) { + LV_PROFILER_FONT_END; return false; } LV_LOG_INFO("glyph_index = 0x%" LV_PRIx32, (uint32_t)node->glyph_index); node->outline = outline; + LV_PROFILER_FONT_END; return true; } @@ -165,7 +169,11 @@ static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv 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); + + dsc->outline_stroke_width = g_dsc->outline_stroke_width; + lv_cache_entry_t * entry = lv_freetype_outline_lookup(dsc, (FT_UInt)g_dsc->gid.index); + if(entry == NULL) { return NULL; } @@ -190,6 +198,7 @@ static void freetype_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_ static lv_cache_entry_t * lv_freetype_outline_lookup(lv_freetype_font_dsc_t * dsc, FT_UInt glyph_index) { + LV_PROFILER_FONT_BEGIN; lv_freetype_cache_node_t * cache_node = dsc->cache_node; lv_freetype_outline_node_t tmp_node; @@ -198,8 +207,10 @@ static lv_cache_entry_t * lv_freetype_outline_lookup(lv_freetype_font_dsc_t * ds lv_cache_entry_t * entry = lv_cache_acquire_or_create(cache_node->draw_data_cache, &tmp_node, dsc); if(!entry) { LV_LOG_ERROR("glyph outline lookup failed for glyph_index = 0x%" LV_PRIx32, (uint32_t)glyph_index); + LV_PROFILER_FONT_END; return NULL; } + LV_PROFILER_FONT_END; return entry; } @@ -235,6 +246,7 @@ static lv_result_t outline_push_point( const FT_Vector * control2, const FT_Vector * to) { + LV_PROFILER_FONT_BEGIN; lv_freetype_context_t * ctx = lv_freetype_get_context(); lv_freetype_outline_event_param_t param; @@ -245,6 +257,7 @@ static lv_result_t outline_push_point( ft_vector_to_lv_vector(¶m.control2, control2); ft_vector_to_lv_vector(¶m.to, to); + LV_PROFILER_FONT_END; return outline_send_event(ctx, LV_EVENT_INSERT, ¶m); } @@ -292,17 +305,23 @@ static lv_freetype_outline_t outline_create( FT_Face face, FT_UInt glyph_index, uint32_t size, - uint32_t strength) + uint32_t strength, + uint32_t border_width) { + LV_PROFILER_FONT_BEGIN; LV_ASSERT_NULL(ctx); FT_Error error; + FT_Glyph glyph; + FT_Stroker stroker; error = FT_Set_Pixel_Sizes(face, 0, size); if(error) { FT_ERROR_MSG("FT_Set_Char_Size", error); + LV_PROFILER_FONT_END; return NULL; } + /** * Disable AUTOHINT(https://freetype.org/autohinting/hinter.html) to avoid display clipping * caused by inconsistent glyph measurement and outline. @@ -310,6 +329,7 @@ static lv_freetype_outline_t outline_create( 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); + LV_PROFILER_FONT_END; return NULL; } @@ -320,18 +340,6 @@ static lv_freetype_outline_t outline_create( } } - lv_result_t res; - lv_freetype_outline_event_param_t param; - - lv_memzero(¶m, sizeof(param)); - res = outline_send_event(ctx, LV_EVENT_CREATE, ¶m); - - lv_freetype_outline_t outline = param.outline; - - if(res != LV_RESULT_OK || !outline) { - LV_LOG_ERROR("Outline object create failed"); - return NULL; - } FT_Outline_Funcs outline_funcs = { .move_to = outline_move_to_cb, @@ -342,22 +350,122 @@ static lv_freetype_outline_t outline_create( .delta = 0 }; - /* Run outline decompose again to fill outline data */ - error = FT_Outline_Decompose(&face->glyph->outline, &outline_funcs, outline); - if(error) { - FT_ERROR_MSG("FT_Outline_Decompose", error); - outline_delete(ctx, outline); + lv_result_t res; + lv_freetype_outline_event_param_t param; + lv_memzero(¶m, sizeof(param)); + + lv_freetype_outline_t outline; + + res = outline_send_event(ctx, LV_EVENT_CREATE, ¶m); + outline = param.outline; + + if(res != LV_RESULT_OK || !outline) { + LV_LOG_ERROR("Outline object create failed"); + LV_PROFILER_FONT_END; return NULL; } - /* close outline */ - res = outline_push_point(outline, LV_FREETYPE_OUTLINE_END, NULL, NULL, NULL); - if(res != LV_RESULT_OK) { - LV_LOG_ERROR("Outline object close failed"); - outline_delete(ctx, outline); - return NULL; + /* 1 iteration if there is no border */ + /* 2 iterations if there is a a border and the glyph itsef */ + for(int i = 0; i < (border_width > 0 ? 2 : 1); i++) { + + FT_Outline glyph_outline; + + if(i == 1) { + + /* decompose the border glyph */ + FT_Stroker_New(ctx->library, &stroker); + FT_Stroker_Set(stroker, border_width * 64, + FT_STROKER_LINECAP_ROUND, + FT_STROKER_LINEJOIN_ROUND, + 0); + + FT_Get_Glyph(face->glyph, &glyph); + FT_Glyph_StrokeBorder(&glyph, stroker, 0, true); + FT_OutlineGlyph g = (FT_OutlineGlyph) glyph; + + FT_Stroker_Done(stroker); + + glyph_outline = g->outline; + + } + else { + + /* decompose glyph */ + glyph_outline = face->glyph->outline; + } + + /*Calculate Total Segments Before decompose */ + int32_t tag_size = glyph_outline.n_points; + int32_t segments = 0; + int32_t vectors = 0; + + for(int j = 0; j < tag_size; j++) { + +#if 0 + if(j == 0 && (glyph_outline.tags[j] & 0x1) == 0) { + /* TODO handle the case where the first point is 'off curve' */ +https://stackoverflow.com/questions/3465809/how-to-interpret-a-freetype-glyph-outline-when-the-first-point-on-the-contour-is + } +#endif + if((glyph_outline.tags[j] & 0x1) == 0x1) { + segments++; + vectors++; + } + else { + int jj = j + 1 < tag_size ? j + 1 : 0; + if(glyph_outline.tags[jj] & 0x1) { + vectors++; + } + else { + segments++; + vectors += 2; + } + } + } + + /*Also for every contour we may have a line for close*/ + segments += glyph_outline.n_contours; + vectors += glyph_outline.n_contours; + + param.sizes.data_size = vectors * 2; + param.sizes.segments_size = segments; + + /* Run outline decompose again to fill outline data */ + error = FT_Outline_Decompose(&glyph_outline, &outline_funcs, outline); + if(error) { + FT_ERROR_MSG("FT_Outline_Decompose", error); + outline_delete(ctx, outline); + LV_PROFILER_FONT_END; + return NULL; + } + + if(i == 0 && border_width > 0) { + + /* Close the border glyph before decomposing the inside glyph */ + res = outline_push_point(outline, LV_FREETYPE_OUTLINE_BORDER_START, NULL, NULL, NULL); + if(res != LV_RESULT_OK) { + LV_LOG_ERROR("Outline object close failed"); + outline_delete(ctx, outline); + LV_PROFILER_FONT_END; + return NULL; + } + + } + else if(i == 0 || (i == 1 && border_width > 0)) { + + /* Close the border glyph or the regular glyph */ + res = outline_push_point(outline, LV_FREETYPE_OUTLINE_END, NULL, NULL, NULL); + if(res != LV_RESULT_OK) { + LV_LOG_ERROR("Outline object close failed"); + outline_delete(ctx, outline); + LV_PROFILER_FONT_END; + return NULL; + } + } } + LV_PROFILER_FONT_END; return outline; } 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 7644101ab..86c314e97 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 @@ -15,12 +15,12 @@ extern "C" { *********************/ #include "lv_freetype.h" -#include "../../misc/cache/lv_cache.h" -#include "../../misc/lv_ll.h" -#include "../../font/lv_font.h" #if LV_USE_FREETYPE +#include "../../misc/cache/lv_cache.h" +#include "../../misc/lv_ll.h" +#include "../../font/lv_font.h" #include "ft2build.h" #include FT_FREETYPE_H #include FT_GLYPH_H @@ -28,6 +28,7 @@ extern "C" { #include FT_SIZES_H #include FT_IMAGE_H #include FT_OUTLINE_H +#include FT_STROKER_H /********************* * DEFINES @@ -60,23 +61,29 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_freetype_outline_vector_t { +struct _lv_freetype_outline_vector_t { int32_t x; int32_t y; }; -struct lv_freetype_outline_event_param_t { +typedef struct { + int32_t segments_size; + int32_t data_size; +} lv_freetype_outline_sizes_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; + lv_freetype_outline_sizes_t sizes; }; -typedef struct lv_freetype_cache_node_t lv_freetype_cache_node_t; +typedef struct _lv_freetype_cache_node_t lv_freetype_cache_node_t; -struct 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; @@ -85,6 +92,7 @@ struct lv_freetype_cache_node_t { FT_Face face; lv_mutex_t face_lock; + bool face_has_kerning; /*glyph cache*/ lv_cache_t * glyph_cache; @@ -93,7 +101,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; @@ -103,7 +111,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; @@ -113,6 +121,8 @@ typedef struct lv_freetype_font_dsc_t { lv_freetype_cache_node_t * cache_node; lv_cache_entry_t * cache_node_entry; FTC_FaceID face_id; + uint32_t outline_stroke_width; + lv_font_kerning_t kerning; } lv_freetype_font_dsc_t; /********************** 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 index cd8df4cf7..4ce88404f 100644 --- 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 @@ -4,17 +4,8 @@ #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 +#if !LV_FS_IS_VALID_LETTER(LV_FS_ARDUINO_ESP_LITTLEFS_LETTER) + #error "Invalid drive letter" #endif typedef struct ArduinoEspLittleFile { @@ -86,7 +77,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 = FILE_WRITE; - File file = LittleFS.open(path, flags); + char buf[LV_FS_MAX_PATH_LEN]; + lv_snprintf(buf, sizeof(buf), LV_FS_ARDUINO_ESP_LITTLEFS_PATH "%s", path); + + File file = LittleFS.open(buf, flags); if(!file) { return NULL; } @@ -198,4 +192,3 @@ static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) #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 index 14941aca0..fe7b5ec2e 100644 --- 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 @@ -5,17 +5,8 @@ #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 +#if !LV_FS_IS_VALID_LETTER(LV_FS_ARDUINO_SD_LETTER) + #error "Invalid drive letter" #endif typedef struct SdFile { @@ -78,7 +69,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 = FILE_WRITE; - File file = SD.open(path, flags); + char buf[LV_FS_MAX_PATH_LEN]; + lv_snprintf(buf, sizeof(buf), LV_FS_ARDUINO_SD_PATH "%s", path); + + File file = SD.open(buf, flags); if(!file) { return NULL; } 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 79c62a367..5bc6f0253 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 @@ -20,17 +20,8 @@ #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 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 +#if !LV_FS_IS_VALID_LETTER(LV_FS_FATFS_LETTER) + #error "Invalid drive letter" #endif /********************** @@ -126,7 +117,10 @@ static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) FIL * f = lv_malloc(sizeof(FIL)); if(f == NULL) return NULL; - FRESULT res = f_open(f, path, flags); + char buf[LV_FS_MAX_PATH_LEN]; + lv_snprintf(buf, sizeof(buf), LV_FS_FATFS_PATH "%s", path); + + FRESULT res = f_open(f, buf, flags); if(res == FR_OK) { return f; } @@ -241,7 +235,10 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path) DIR * d = lv_malloc(sizeof(DIR)); if(d == NULL) return NULL; - FRESULT res = f_opendir(d, path); + char buf[LV_FS_MAX_PATH_LEN]; + lv_snprintf(buf, sizeof(buf), LV_FS_FATFS_PATH "%s", path); + + FRESULT res = f_opendir(d, buf); if(res != FR_OK) { lv_free(d); d = NULL; 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 490c6feeb..e334dca60 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,17 +4,8 @@ #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 +#if !LV_FS_IS_VALID_LETTER(LV_FS_LITTLEFS_LETTER) + #error "Invalid drive letter" #endif typedef struct LittleFile { @@ -91,8 +82,11 @@ static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) LittleFile * lf = lv_malloc(sizeof(LittleFile)); LV_ASSERT_MALLOC(lf); + char buf[LV_FS_MAX_PATH_LEN]; + lv_snprintf(buf, sizeof(buf), LV_FS_LITTLEFS_PATH "%s", path); + lfs_t * lfs = drv->user_data; - int err = lfs_file_open(lfs, &lf->file, path, flags); + int err = lfs_file_open(lfs, &lf->file, buf, flags); if(err) { return NULL; } @@ -209,8 +203,11 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path) LittleDirectory * ld = lv_malloc(sizeof(LittleDirectory)); LV_ASSERT_MALLOC(ld); + char buf[LV_FS_MAX_PATH_LEN]; + lv_snprintf(buf, sizeof(buf), LV_FS_LITTLEFS_PATH "%s", path); + lfs_t * lfs = drv->user_data; - int err = lfs_dir_open(lfs, &ld->dir, path); + int err = lfs_dir_open(lfs, &ld->dir, buf); if(err != LFS_ERR_OK) { lv_free(ld); return NULL; 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 c207c76fd..4e1b18a39 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 @@ -47,17 +47,9 @@ /********************* * 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 + +#if !LV_FS_IS_VALID_LETTER(LV_FS_MEMFS_LETTER) + #error "Invalid drive letter" #endif /********************** 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 f1e66fd23..9d5af39db 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 @@ -22,17 +22,8 @@ * DEFINES *********************/ -#if LV_FS_POSIX_LETTER == '\0' - #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 +#if !LV_FS_IS_VALID_LETTER(LV_FS_POSIX_LETTER) + #error "Invalid drive letter" #endif /** The reason for 'fd + 1' is because open() may return a legal fd with a value of 0, @@ -57,6 +48,7 @@ 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_read(lv_fs_drv_t * drv, void * dir_p, char * fn, uint32_t fn_len); static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * dir_p); +static lv_fs_res_t fs_errno_to_res(int errno_val); /********************** * STATIC VARIABLES @@ -121,7 +113,7 @@ 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 = O_RDWR | O_CREAT; /*Make the path relative to the current directory (the projects root folder)*/ - char buf[256]; + char buf[LV_FS_MAX_PATH_LEN]; lv_snprintf(buf, sizeof(buf), LV_FS_POSIX_PATH "%s", path); int fd = open(buf, flags, 0666); @@ -148,7 +140,7 @@ static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * 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 fs_errno_to_res(errno); } return LV_FS_RES_OK; @@ -172,7 +164,7 @@ static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_ 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; + return fs_errno_to_res(errno); } *br = (uint32_t)ret; @@ -196,7 +188,7 @@ static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, 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; + return fs_errno_to_res(errno); } *bw = (uint32_t)ret; @@ -233,7 +225,7 @@ static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs 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 fs_errno_to_res(errno); } return LV_FS_RES_OK; @@ -255,7 +247,7 @@ static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_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; + return fs_errno_to_res(errno); } *pos_p = (uint32_t)offset; @@ -327,11 +319,63 @@ static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * 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 fs_errno_to_res(errno); } return LV_FS_RES_OK; } + +/** + * Convert an errno value to a lv_fs_res_t value + * @param errno_val an errno value + * @return a corresponding lv_fs_res_t value + */ +static lv_fs_res_t fs_errno_to_res(int errno_val) +{ + switch(errno_val) { + case 0: + return LV_FS_RES_OK; + + case EIO: /* I/O error */ + return LV_FS_RES_HW_ERR; + + case EFAULT: /* Bad address */ + return LV_FS_RES_FS_ERR; + + case ENOENT: /* No such file or directory */ + return LV_FS_RES_NOT_EX; + + case ENOSPC: /* No space left on device */ + return LV_FS_RES_FULL; + + case EALREADY: /* Operation already in progress */ + return LV_FS_RES_LOCKED; + + case EACCES: /* Permission denied */ + return LV_FS_RES_DENIED; + + case EBUSY: /* Device or resource busy */ + return LV_FS_RES_BUSY; + + case ETIMEDOUT: /* Connection timed out */ + return LV_FS_RES_TOUT; + + case ENOSYS: /* Invalid system call number */ + return LV_FS_RES_NOT_IMP; + + case ENOMEM: /* Out of memory */ + return LV_FS_RES_OUT_OF_MEM; + + case EINVAL: /* "Invalid argument" */ + return LV_FS_RES_INV_PARAM; + + default: + break; + } + + return LV_FS_RES_UNKNOWN; +} + #else /*LV_USE_FS_POSIX == 0*/ #if defined(LV_FS_POSIX_LETTER) && LV_FS_POSIX_LETTER != '\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 a6c901e15..0ceaae2b1 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 @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "../../../lvgl.h" -#if LV_USE_FS_STDIO != '\0' +#if LV_USE_FS_STDIO #include #ifndef WIN32 @@ -21,20 +21,10 @@ /********************* * 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 +#if !LV_FS_IS_VALID_LETTER(LV_FS_STDIO_LETTER) + #error "Invalid drive letter" +#endif /********************** * TYPEDEFS @@ -42,7 +32,7 @@ typedef struct { #ifdef _WIN32 HANDLE dir_p; - char next_fn[MAX_PATH_LEN]; + char next_fn[LV_FS_MAX_PATH_LEN]; #else DIR * dir_p; #endif @@ -126,7 +116,7 @@ static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) /*Make the path relative to the current directory (the projects root folder)*/ - char buf[MAX_PATH_LEN]; + char buf[LV_FS_MAX_PATH_LEN]; lv_snprintf(buf, sizeof(buf), LV_FS_STDIO_PATH "%s", path); return fopen(buf, flags); @@ -236,7 +226,7 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path) dir_handle_t * handle = (dir_handle_t *)lv_malloc(sizeof(dir_handle_t)); #ifndef WIN32 /*Make the path relative to the current directory (the projects root folder)*/ - char buf[MAX_PATH_LEN]; + char buf[LV_FS_MAX_PATH_LEN]; lv_snprintf(buf, sizeof(buf), LV_FS_STDIO_PATH "%s", path); handle->dir_p = opendir(buf); if(handle->dir_p == NULL) { @@ -249,7 +239,7 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path) WIN32_FIND_DATAA fdata; /*Make the path relative to the current directory (the projects root folder)*/ - char buf[MAX_PATH_LEN]; + char buf[LV_FS_MAX_PATH_LEN]; lv_snprintf(buf, sizeof(buf), LV_FS_STDIO_PATH "%s\\*", path); lv_strcpy(handle->next_fn, ""); diff --git a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_uefi.c b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_uefi.c new file mode 100644 index 000000000..4e95078a6 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fs_uefi.c @@ -0,0 +1,607 @@ +/** + * @file lv_fs_uefi.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../../lvgl.h" + +#if LV_USE_FS_UEFI && LV_USE_UEFI + +#include "../../drivers/uefi/lv_uefi_private.h" + +#include "../../core/lv_global.h" + +/********************* + * DEFINES + *********************/ +#if LV_FS_UEFI_LETTER == '\0' + #error "LV_FS_UEFI_LETTER must be set to a valid value" +#else + #if (LV_FS_UEFI_LETTER < 'A') || (LV_FS_UEFI_LETTER > 'Z') + #if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /* When using default driver-identifier letter, strict format (X:) is mandatory. */ + #error "LV_FS_UEFI_LETTER must be an upper case ASCII letter" + #else /*Lean rules for backward compatibility*/ + #warning LV_FS_UEFI_LETTER should be an upper case ASCII letter. \ + Using a slash symbol as driver - identifier letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism. + #endif + #endif +#endif + +/********************** + * TYPEDEFS + **********************/ + +typedef struct _lv_uefi_fs_file_context_t { + EFI_FILE_PROTOCOL * interface; +} lv_uefi_fs_file_context_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void lv_fs_drv_uefi_init(lv_fs_drv_t * drv, char fs_drive_letter, EFI_HANDLE fs_handle); +static void lv_fs_drv_uefi_deinit(lv_fs_drv_t * drv); + +static void lv_fs_uefi_lvgl_path_to_uefi_path(CHAR16 * path); +static void lv_fs_uefi_uefi_path_to_lvgl_path(CHAR16 * path); +static bool lv_fs_uefi_is_dot_path(CONST CHAR16 * path); +static bool lv_fs_uefi_is_dir(EFI_FILE_PROTOCOL * dir); +static bool lv_fs_uefi_is_file(EFI_FILE_PROTOCOL * file); +static EFI_FILE_INFO * lv_fs_uefi_get_info(EFI_FILE_PROTOCOL * file); + +static bool lv_fs_uefi_ready_cb(lv_fs_drv_t * drv); + +static void * lv_fs_uefi_open_cb(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode); +static lv_fs_res_t lv_fs_uefi_close_cb(lv_fs_drv_t * drv, void * file_p); +static lv_fs_res_t lv_fs_uefi_read_cb(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br); +static lv_fs_res_t lv_fs_uefi_write_cb(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw); +static lv_fs_res_t lv_fs_uefi_seek_cb(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence); +static lv_fs_res_t lv_fs_uefi_tell_cb(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p); + +static void * lv_fs_uefi_dir_open_cb(lv_fs_drv_t * drv, const char * path); +static lv_fs_res_t lv_fs_uefi_dir_read_cb(lv_fs_drv_t * drv, void * rddir_p, char * fn, uint32_t fn_len); +static lv_fs_res_t lv_fs_uefi_dir_close_cb(lv_fs_drv_t * drv, void * rddir_p); + +/********************** + * STATIC VARIABLES + **********************/ + +static EFI_GUID _uefi_guid_simple_file_system = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; +static EFI_GUID _uefi_guid_loaded_image = EFI_LOADED_IMAGE_PROTOCOL_GUID; +static EFI_GUID _uefi_guid_file_info = EFI_FILE_INFO_ID; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Register a driver for the File system interface + */ +void lv_fs_uefi_init(void) +{ + EFI_LOADED_IMAGE_PROTOCOL * interface_loaded_image = NULL; + EFI_HANDLE fs_handle = NULL; + + /*--------------------------------------------------- + * Register the file system interface in LVGL + *--------------------------------------------------*/ + + interface_loaded_image = lv_uefi_protocol_open(gLvEfiImageHandle, &_uefi_guid_loaded_image); + LV_ASSERT_NULL(interface_loaded_image); + + fs_handle = interface_loaded_image->DeviceHandle; + + if(fs_handle == NULL) return; + + lv_uefi_protocol_close(gLvEfiImageHandle, &_uefi_guid_loaded_image); + + /*Add a simple driver to open images*/ + lv_fs_drv_t * fs_drv_p = &(LV_GLOBAL_DEFAULT()->uefi_fs_drv); + lv_fs_drv_uefi_init(fs_drv_p, LV_FS_UEFI_LETTER, fs_handle); + + lv_fs_drv_register(fs_drv_p); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static bool lv_fs_uefi_ready_cb(lv_fs_drv_t * drv) +{ + EFI_HANDLE fs_handle = (EFI_HANDLE)drv->user_data; + + return fs_handle != NULL; +} + +static void * lv_fs_uefi_open_cb(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) +{ + EFI_STATUS status; + EFI_FILE_PROTOCOL * fs_root = NULL; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * fs_interface = NULL; + CHAR16 path_ucs2[LV_FS_MAX_PATH_LENGTH + 1]; + lv_uefi_fs_file_context_t * file_ctx = NULL; + UINT64 uefi_mode = 0; + + EFI_HANDLE fs_handle = (EFI_HANDLE)drv->user_data; + + fs_interface = lv_uefi_protocol_open(fs_handle, &_uefi_guid_simple_file_system); + if(fs_interface == NULL) { + LV_LOG_WARN("[lv_uefi] Unable to open file system protocol."); + goto error; + } + + status = fs_interface->OpenVolume(fs_interface, &fs_root); + if(status != EFI_SUCCESS) { + LV_LOG_WARN("[lv_uefi] Unable to open file system root."); + goto error; + } + + if(lv_uefi_ascii_to_ucs2(path, path_ucs2, LV_FS_MAX_PATH_LENGTH + 1) == 0) { + LV_LOG_WARN("[lv_uefi] Unable to convert the ASCII path into an UCS-2 path."); + goto error; + } + + lv_fs_uefi_lvgl_path_to_uefi_path(path_ucs2); + + file_ctx = lv_calloc(1, sizeof(lv_uefi_fs_file_context_t)); + LV_ASSERT_MALLOC(file_ctx); + + if(mode == LV_FS_MODE_WR) { + uefi_mode = EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE; + } + else { + uefi_mode = EFI_FILE_MODE_READ; + } + + status = fs_root->Open( + fs_root, + &file_ctx->interface, + path_ucs2, + uefi_mode, + 0); + if(status != EFI_SUCCESS) { + LV_LOG_WARN("[lv_uefi] Unable to open file '%s'.", path); + goto error; + } + + if(!lv_fs_uefi_is_file(file_ctx->interface)) { + goto error; + } + + goto finish; + +error: + if(file_ctx != NULL) { + if(file_ctx->interface != NULL) file_ctx->interface->Close(file_ctx->interface); + lv_free(file_ctx); + file_ctx = NULL; + } + +finish: + if(fs_interface != NULL) lv_uefi_protocol_close(fs_handle, &_uefi_guid_simple_file_system); + if(fs_root != NULL) fs_root->Close(fs_root); + + return file_ctx; +} + +static lv_fs_res_t lv_fs_uefi_close_cb(lv_fs_drv_t * drv, void * file_p) +{ + EFI_STATUS status; + lv_uefi_fs_file_context_t * file_ctx = (lv_uefi_fs_file_context_t *)file_p; + + if(file_ctx == NULL || file_ctx->interface == NULL) return LV_FS_RES_INV_PARAM; + + status = file_ctx->interface->Close(file_ctx->interface); + if(status != EFI_SUCCESS) return LV_FS_RES_HW_ERR; + + lv_free(file_ctx); + + return LV_FS_RES_OK; +} + +static lv_fs_res_t lv_fs_uefi_read_cb(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) +{ + EFI_STATUS status; + lv_uefi_fs_file_context_t * file_ctx = (lv_uefi_fs_file_context_t *)file_p; + UINTN buf_size = btr; + + if(file_ctx == NULL || file_ctx->interface == NULL) return LV_FS_RES_INV_PARAM; + + status = file_ctx->interface->Read( + file_ctx->interface, + &buf_size, + buf); + if(status != EFI_SUCCESS) return LV_FS_RES_HW_ERR; + + *br = (uint32_t) buf_size; + + return LV_FS_RES_OK; +} + +static lv_fs_res_t lv_fs_uefi_write_cb(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw) +{ + EFI_STATUS status; + lv_uefi_fs_file_context_t * file_ctx = (lv_uefi_fs_file_context_t *)file_p; + UINTN buf_size = btw; + + if(file_ctx == NULL || file_ctx->interface == NULL) return LV_FS_RES_INV_PARAM; + + status = file_ctx->interface->Write( + file_ctx->interface, + &buf_size, + (VOID *)buf); + if(status != EFI_SUCCESS) return LV_FS_RES_HW_ERR; + + file_ctx->interface->Flush(file_ctx->interface); + + *bw = (uint32_t) buf_size; + + return LV_FS_RES_OK; +} + +static lv_fs_res_t lv_fs_uefi_seek_cb(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence) +{ + EFI_STATUS status; + lv_uefi_fs_file_context_t * file_ctx = (lv_uefi_fs_file_context_t *)file_p; + UINT64 new_pos; + + if(file_ctx == NULL || file_ctx->interface == NULL) return LV_FS_RES_INV_PARAM; + + if(whence == LV_FS_SEEK_END) { + status = file_ctx->interface->SetPosition( + file_ctx->interface, + UINT64_MAX); + if(status != EFI_SUCCESS) return LV_FS_RES_HW_ERR; + + status = file_ctx->interface->GetPosition( + file_ctx->interface, + &new_pos); + if(status != EFI_SUCCESS) return LV_FS_RES_HW_ERR; + + if(new_pos < pos) { + new_pos = 0; + } + else { + new_pos -= pos; + } + } + else if(whence == LV_FS_SEEK_SET) { + new_pos = pos; + } + else if(whence == LV_FS_SEEK_CUR) { + status = file_ctx->interface->GetPosition( + file_ctx->interface, + &new_pos); + if(status != EFI_SUCCESS) return LV_FS_RES_HW_ERR; + + new_pos += pos; + } + else { + return LV_FS_RES_INV_PARAM; + } + + status = file_ctx->interface->SetPosition( + file_ctx->interface, + new_pos); + if(status != EFI_SUCCESS) return LV_FS_RES_HW_ERR; + + return LV_FS_RES_OK; +} + +static lv_fs_res_t lv_fs_uefi_tell_cb(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) +{ + EFI_STATUS status; + lv_uefi_fs_file_context_t * file_ctx = (lv_uefi_fs_file_context_t *)file_p; + UINT64 pos; + + if(file_ctx == NULL || file_ctx->interface == NULL) return LV_FS_RES_INV_PARAM; + + status = file_ctx->interface->GetPosition( + file_ctx->interface, + &pos); + if(status != EFI_SUCCESS) return LV_FS_RES_HW_ERR; + + if(pos > UINT32_MAX) return LV_FS_RES_UNKNOWN; + + *pos_p = (uint32_t) pos; + + return LV_FS_RES_OK; +} + +static void * lv_fs_uefi_dir_open_cb(lv_fs_drv_t * drv, const char * path) +{ + EFI_STATUS status; + EFI_FILE_PROTOCOL * fs_root = NULL; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * fs_interface = NULL; + CHAR16 path_ucs2[LV_FS_MAX_PATH_LENGTH + 1]; + lv_uefi_fs_file_context_t * file_ctx = NULL; + UINT64 mode = 0; + UINT64 attributes = 0; + + EFI_HANDLE fs_handle = (EFI_HANDLE)drv->user_data; + + fs_interface = lv_uefi_protocol_open(fs_handle, &_uefi_guid_simple_file_system); + if(fs_interface == NULL) { + LV_LOG_WARN("[lv_uefi] Unable to open file system protocol."); + goto error; + } + + status = fs_interface->OpenVolume(fs_interface, &fs_root); + if(status != EFI_SUCCESS) { + LV_LOG_WARN("[lv_uefi] Unable to open file system root."); + goto error; + } + + if(path != NULL && path[0] != '\0') { + if(lv_uefi_ascii_to_ucs2(path, path_ucs2, LV_FS_MAX_PATH_LENGTH + 1) == 0) { + LV_LOG_WARN("[lv_uefi] Unable to convert the ASCII path into an UCS-2 path."); + goto error; + } + } + else { + path_ucs2[0] = '\\'; + path_ucs2[1] = '\0'; + } + + lv_fs_uefi_lvgl_path_to_uefi_path(path_ucs2); + + file_ctx = lv_calloc(1, sizeof(lv_uefi_fs_file_context_t)); + LV_ASSERT_MALLOC(file_ctx); + + mode = EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE; + attributes = EFI_FILE_DIRECTORY; + + status = fs_root->Open( + fs_root, + &file_ctx->interface, + path_ucs2, + mode, + attributes); + if(status != EFI_SUCCESS) { + LV_LOG_WARN("[lv_uefi] Unable to open directory '%s'.", path); + goto error; + } + + if(!lv_fs_uefi_is_dir(file_ctx->interface)) { + goto error; + } + + goto finish; + +error: + if(file_ctx != NULL) { + if(file_ctx->interface != NULL) { + file_ctx->interface->Close(file_ctx->interface); + } + lv_free(file_ctx); + file_ctx = NULL; + } + +finish: + if(fs_interface != NULL) lv_uefi_protocol_close(fs_handle, &_uefi_guid_simple_file_system); + if(fs_root != NULL) fs_root->Close(fs_root); + + return file_ctx; +} + +static lv_fs_res_t lv_fs_uefi_dir_read_cb(lv_fs_drv_t * drv, void * rddir_p, char * fn, uint32_t fn_len) +{ + lv_fs_res_t return_code; + EFI_STATUS status; + lv_uefi_fs_file_context_t * file_ctx = (lv_uefi_fs_file_context_t *)rddir_p; + + EFI_FILE_INFO * info = NULL; + UINTN size; + + CONST CHAR16 * fn_ucs2; + + if(fn == NULL || fn_len == 0) return LV_FS_RES_INV_PARAM; + if(file_ctx == NULL || file_ctx->interface == NULL) return LV_FS_RES_INV_PARAM; + + // skip . and .. + do { + if(info != NULL) lv_free(info); + info = NULL; + size = 0; + status = file_ctx->interface->Read( + file_ctx->interface, + &size, + info); + if(status == EFI_SUCCESS && size == 0) { + return_code = LV_FS_RES_OK; + *fn = '\0'; + goto finish; + } + else if(status != EFI_BUFFER_TOO_SMALL) { + return_code = LV_FS_RES_NOT_EX; + goto error; + } + + info = lv_calloc(1, size); + LV_ASSERT_MALLOC(info); + + status = file_ctx->interface->Read( + file_ctx->interface, + &size, + info); + if(status != EFI_SUCCESS) { + return_code = LV_FS_RES_HW_ERR; + goto error; + } + } while(lv_fs_uefi_is_dot_path(info->FileName)); + + lv_fs_uefi_uefi_path_to_lvgl_path(info->FileName); + + // skip leading \ and / + for(fn_ucs2 = info->FileName; *fn_ucs2 != L'\0'; fn_ucs2++) { + if(*fn_ucs2 != L'\\' && *fn_ucs2 != L'/') { + break; + } + } + + if((info->Attribute & EFI_FILE_DIRECTORY) != 0) { + if(fn_len == 0) { + return_code = LV_FS_RES_UNKNOWN; + goto error; + } + fn[0] = '/'; + fn++; + fn_len--; + } + + if(lv_uefi_ucs2_to_ascii(fn_ucs2, fn, fn_len) == 0) { + LV_LOG_WARN("[lv_uefi] Unable to convert the UCS-2 path into an ascii path."); + return_code = LV_FS_RES_UNKNOWN; + goto error; + } + + return_code = LV_FS_RES_OK; + goto finish; + +error: + +finish: + if(info) lv_free(info); + + return return_code; +} + +static lv_fs_res_t lv_fs_uefi_dir_close_cb(lv_fs_drv_t * drv, void * rddir_p) +{ + EFI_STATUS status; + lv_uefi_fs_file_context_t * file_ctx = (lv_uefi_fs_file_context_t *)rddir_p; + + if(file_ctx == NULL || file_ctx->interface == NULL) return LV_FS_RES_INV_PARAM; + + status = file_ctx->interface->Close(file_ctx->interface); + if(status != EFI_SUCCESS) return LV_FS_RES_HW_ERR; + + lv_free(file_ctx); + + return LV_FS_RES_OK; +} + +static void lv_fs_drv_uefi_init(lv_fs_drv_t * drv, char fs_drive_letter, EFI_HANDLE fs_handle) +{ + LV_ASSERT_NULL(drv); + LV_ASSERT_NULL(fs_handle); + + lv_fs_drv_init(drv); + + drv->letter = fs_drive_letter; + drv->cache_size = 0; + + drv->ready_cb = lv_fs_uefi_ready_cb; + drv->open_cb = lv_fs_uefi_open_cb; + drv->close_cb = lv_fs_uefi_close_cb; + drv->read_cb = lv_fs_uefi_read_cb; + drv->write_cb = lv_fs_uefi_write_cb; + drv->seek_cb = lv_fs_uefi_seek_cb; + drv->tell_cb = lv_fs_uefi_tell_cb; + + drv->dir_open_cb = lv_fs_uefi_dir_open_cb; + drv->dir_read_cb = lv_fs_uefi_dir_read_cb; + drv->dir_close_cb = lv_fs_uefi_dir_close_cb; + + drv->user_data = (void *) fs_handle; +} + +static void lv_fs_drv_uefi_deinit(lv_fs_drv_t * drv) +{ + LV_ASSERT_NULL(drv); + drv->user_data = NULL; +} + +static void lv_fs_uefi_lvgl_path_to_uefi_path(CHAR16 * path) +{ + if(path == NULL) return; + + for(; *path != '\0'; path++) { + if(*path == L'/') *path = L'\\'; + } +} + +static void lv_fs_uefi_uefi_path_to_lvgl_path(CHAR16 * path) +{ + if(path == NULL) return; + + for(; *path != '\0'; path++) { + if(*path == L'\\') *path = L'/'; + } +} + +static bool lv_fs_uefi_is_dot_path(CONST CHAR16 * path) +{ + if(path == NULL) return FALSE; + + if(path[0] == L'.' && path[1] == L'\0') return TRUE; + if(path[0] == L'.' && path[1] == L'.' && path[2] == L'\0') return TRUE; + + return FALSE; +} + +static bool lv_fs_uefi_is_dir(EFI_FILE_PROTOCOL * dir) +{ + UINT64 attributes; + + if(dir == NULL) return FALSE; + + EFI_FILE_INFO * info = lv_fs_uefi_get_info(dir); + if(info == NULL) return FALSE; + + attributes = info->Attribute; + lv_free(info); + + return (attributes & EFI_FILE_DIRECTORY) != 0; +} + +static bool lv_fs_uefi_is_file(EFI_FILE_PROTOCOL * file) +{ + UINT64 attributes; + + if(file == NULL) return FALSE; + + EFI_FILE_INFO * info = lv_fs_uefi_get_info(file); + if(info == NULL) return FALSE; + + attributes = info->Attribute; + lv_free(info); + + return (attributes & EFI_FILE_DIRECTORY) == 0; +} + +static EFI_FILE_INFO * lv_fs_uefi_get_info(EFI_FILE_PROTOCOL * file) +{ + EFI_STATUS status; + EFI_FILE_INFO * info = NULL; + UINTN size = 0; + + status = file->GetInfo(file, &_uefi_guid_file_info, &size, info); + if(status != EFI_BUFFER_TOO_SMALL) return NULL; + + info = lv_calloc(1, size); + LV_ASSERT_MALLOC(info); + + status = file->GetInfo(file, &_uefi_guid_file_info, &size, info); + if(status != EFI_SUCCESS) { + lv_free(info); + return NULL; + } + + return info; +} + +#else /* LV_FS_UEFI_LETTER == 0*/ + +#if defined(LV_FS_UEFI_LETTER) && LV_FS_UEFI_LETTER != '\0' + #warning "LV_FS_UEFI is not enabled but LV_FS_UEFI_LETTER is set" +#endif + +#endif 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 d5fb36487..ddccf6634 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 @@ -7,7 +7,7 @@ * INCLUDES *********************/ #include "../../../lvgl.h" -#if LV_USE_FS_WIN32 != '\0' +#if LV_USE_FS_WIN32 #include #include @@ -17,27 +17,17 @@ /********************* * 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 +#if !LV_FS_IS_VALID_LETTER(LV_FS_WIN32_LETTER) + #error "Invalid drive letter" +#endif /********************** * TYPEDEFS **********************/ typedef struct { HANDLE dir_p; - char next_fn[MAX_PATH_LEN]; + char next_fn[LV_FS_MAX_PATH_LEN]; lv_fs_res_t next_error; } dir_handle_t; @@ -379,29 +369,28 @@ static void * fs_dir_open(lv_fs_drv_t * drv, const char * path) WIN32_FIND_DATAA fdata; /*Make the path relative to the current directory (the projects root folder)*/ - char buf[MAX_PATH_LEN]; -#ifdef LV_FS_WIN32_PATH + char buf[LV_FS_MAX_PATH_LEN]; lv_snprintf(buf, sizeof(buf), LV_FS_WIN32_PATH "%s\\*", path); -#else - lv_snprintf(buf, sizeof(buf), "%s\\*", path); -#endif lv_strcpy(handle->next_fn, ""); handle->dir_p = FindFirstFileA(buf, &fdata); - do { - if(is_dots_name(fdata.cFileName)) { - continue; - } - else { - if(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "/%s", fdata.cFileName); + + if(handle->dir_p != INVALID_HANDLE_VALUE) { + do { + if(is_dots_name(fdata.cFileName)) { + continue; } else { - lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "%s", fdata.cFileName); + if(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "/%s", fdata.cFileName); + } + else { + lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "%s", fdata.cFileName); + } + break; } - break; - } - } while(FindNextFileA(handle->dir_p, &fdata)); + } while(FindNextFileA(handle->dir_p, &fdata)); + } if(handle->dir_p == INVALID_HANDLE_VALUE) { lv_free(handle); 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 f830c3a2d..cd0f5dd2a 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fsdrv.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/fsdrv/lv_fsdrv.h @@ -19,6 +19,8 @@ extern "C" { * DEFINES *********************/ +#define LV_FS_MAX_PATH_LEN 256 + /********************** * TYPEDEFS **********************/ @@ -61,6 +63,10 @@ void lv_fs_arduino_esp_littlefs_init(void); void lv_fs_arduino_sd_init(void); #endif +#if LV_USE_FS_UEFI +void lv_fs_uefi_init(void); +#endif + /********************** * MACROS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/gif/LICENSE.txt b/lib/libesp32_lvgl/lvgl/src/libs/gif/LICENSE.txt new file mode 100644 index 000000000..c53d51993 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/gif/LICENSE.txt @@ -0,0 +1,2 @@ +All of the source code and documentation for gifdec is released into the +public domain and provided without warranty of any kind. diff --git a/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.c b/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.c index ffe9ec1f5..7c278d6ed 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/gif/gifdec.c @@ -596,8 +596,9 @@ read_image_data(gd_GIF * gif, int interlace) if(ret == 1) key_size++; entry = table->entries[key]; str_len = entry.length; - if(frm_off + str_len >= frm_size){ + if(frm_off + str_len > frm_size){ LV_LOG_WARN("LZW table token overflows the frame buffer"); + lv_free(table); return -1; } for(i = 0; i < str_len; i++) { 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 920f77689..8dab9367d 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif.c @@ -6,10 +6,11 @@ /********************* * INCLUDES *********************/ -#include "../../misc/lv_timer_private.h" -#include "../../core/lv_obj_class_private.h" #include "lv_gif_private.h" #if LV_USE_GIF +#include "../../misc/lv_timer_private.h" +#include "../../misc/cache/lv_cache.h" +#include "../../core/lv_obj_class_private.h" #include "gifdec.h" @@ -38,7 +39,7 @@ const lv_obj_class_t lv_gif_class = { .destructor_cb = lv_gif_destructor, .instance_size = sizeof(lv_gif_t), .base_class = &lv_image_class, - .name = "gif", + .name = "lv_gif", }; /********************** 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 index c4ea17af7..c88507f12 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif_private.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/gif/lv_gif_private.h @@ -31,7 +31,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_gif_t { +struct _lv_gif_t { lv_image_t img; gd_GIF * gif; lv_timer_t * timer; 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 587e5fc69..15578f7ab 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/libpng/lv_libpng.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/libpng/lv_libpng.c @@ -138,16 +138,21 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_d static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc) { LV_UNUSED(decoder); /*Unused*/ + + LV_PROFILER_DECODER_BEGIN_TAG("lv_libpng_decoder_open"); + lv_draw_buf_t * decoded; decoded = decode_png(dsc); if(decoded == NULL) { + LV_PROFILER_DECODER_END_TAG("lv_libpng_decoder_open"); return LV_RESULT_INVALID; } 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); + LV_PROFILER_DECODER_END_TAG("lv_libpng_decoder_open"); return LV_RESULT_INVALID; } @@ -159,10 +164,16 @@ 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_RESULT_OK; + if(dsc->args.no_cache) { + LV_PROFILER_DECODER_END_TAG("lv_libpng_decoder_open"); + 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; + if(!lv_image_cache_is_enabled()) { + LV_PROFILER_DECODER_END_TAG("lv_libpng_decoder_open"); + return LV_RESULT_OK; + } /*Add the decoded image to the cache*/ lv_image_cache_data_t search_key; @@ -174,10 +185,12 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d if(entry == NULL) { lv_draw_buf_destroy_user(image_cache_draw_buf_handlers, decoded); + LV_PROFILER_DECODER_END_TAG("lv_libpng_decoder_open"); return LV_RESULT_INVALID; } dsc->cache_entry = entry; + LV_PROFILER_DECODER_END_TAG("lv_libpng_decoder_open"); return LV_RESULT_OK; /*The image is fully decoded. Return with its pointer*/ } @@ -258,10 +271,6 @@ static lv_draw_buf_t * decode_png(lv_image_decoder_dsc_t * dsc) image.version = PNG_IMAGE_VERSION; 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); @@ -308,6 +317,7 @@ static lv_draw_buf_t * decode_png(lv_image_decoder_dsc_t * dsc) else if(dsc->src_type == LV_IMAGE_SRC_VARIABLE) LV_LOG_ERROR("alloc PNG_IMAGE_SIZE(%" LV_PRIu32 ")", (uint32_t)PNG_IMAGE_SIZE(image)); + png_image_free(&image); return NULL; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/lodepng/LICENSE.txt b/lib/libesp32_lvgl/lvgl/src/libs/lodepng/LICENSE.txt new file mode 100644 index 000000000..83aa1b4b0 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/lodepng/LICENSE.txt @@ -0,0 +1,21 @@ +Copyright (c) 2005-2018 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 +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lodepng.h b/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lodepng.h index 1ae349650..b620b5c39 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lodepng.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lodepng.h @@ -842,7 +842,7 @@ 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 color type is explicitely set + If colortype is 3, PLTE is always created. If color type is explicitly 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 @@ -1007,7 +1007,7 @@ 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. -Returne error code (0 if it went ok) +Return error code (0 if it went ok) */ unsigned lodepng_chunk_create(unsigned char ** out, size_t * outsize, size_t length, const char * type, const unsigned char * data); @@ -1890,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 ouput, see struct LodePNGInfo +state.info_png....: no settings for decoder but output, see struct LodePNGInfo For encoding: 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 e5b55de2b..d9db17dd1 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lv_lodepng.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/lodepng/lv_lodepng.c @@ -139,21 +139,22 @@ static lv_result_t decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_d static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc) { LV_UNUSED(decoder); + LV_PROFILER_DECODER_BEGIN_TAG("lv_lodepng_decoder_open"); const uint8_t * png_data = NULL; size_t png_data_size = 0; if(dsc->src_type == LV_IMAGE_SRC_FILE) { const char * fn = dsc->src; - if(lv_strcmp(lv_fs_get_ext(fn), "png") == 0) { /*Check the extension*/ - unsigned error; - error = lodepng_load_file((void *)&png_data, &png_data_size, fn); /*Load the file*/ - if(error) { - if(png_data != NULL) { - lv_free((void *)png_data); - } - LV_LOG_WARN("error %u: %s\n", error, lodepng_error_text(error)); - return LV_RESULT_INVALID; + + /*Load the file*/ + unsigned error = lodepng_load_file((void *)&png_data, &png_data_size, fn); + if(error) { + if(png_data != NULL) { + lv_free((void *)png_data); } + LV_LOG_WARN("error %u: %s\n", error, lodepng_error_text(error)); + LV_PROFILER_DECODER_END_TAG("lv_lodepng_decoder_open"); + return LV_RESULT_INVALID; } } else if(dsc->src_type == LV_IMAGE_SRC_VARIABLE) { @@ -162,6 +163,7 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d png_data_size = img_dsc->data_size; } else { + LV_PROFILER_DECODER_END_TAG("lv_lodepng_decoder_open"); return LV_RESULT_INVALID; } @@ -171,12 +173,14 @@ static lv_result_t decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_d if(!decoded) { LV_LOG_WARN("Error decoding PNG"); + LV_PROFILER_DECODER_END_TAG("lv_lodepng_decoder_open"); return LV_RESULT_INVALID; } lv_draw_buf_t * adjusted = lv_image_decoder_post_process(dsc, decoded); if(adjusted == NULL) { lv_draw_buf_destroy(decoded); + LV_PROFILER_DECODER_END_TAG("lv_lodepng_decoder_open"); return LV_RESULT_INVALID; } @@ -188,10 +192,16 @@ 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_RESULT_OK; + if(dsc->args.no_cache) { + LV_PROFILER_DECODER_END_TAG("lv_lodepng_decoder_open"); + 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; + if(!lv_image_cache_is_enabled()) { + LV_PROFILER_DECODER_END_TAG("lv_lodepng_decoder_open"); + return LV_RESULT_OK; + } /*Add the decoded image to the cache*/ lv_image_cache_data_t search_key; @@ -202,10 +212,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, decoded, NULL); if(entry == NULL) { + LV_PROFILER_DECODER_END_TAG("lv_lodepng_decoder_open"); return LV_RESULT_INVALID; } dsc->cache_entry = entry; + LV_PROFILER_DECODER_END_TAG("lv_lodepng_decoder_open"); return LV_RESULT_OK; /*If not returned earlier then it failed*/ } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/lz4/LICENSE b/lib/libesp32_lvgl/lvgl/src/libs/lz4/LICENSE.txt similarity index 100% rename from lib/libesp32_lvgl/lvgl/src/libs/lz4/LICENSE rename to lib/libesp32_lvgl/lvgl/src/libs/lz4/LICENSE.txt diff --git a/lib/libesp32_lvgl/lvgl/src/libs/lz4/lz4.c b/lib/libesp32_lvgl/lvgl/src/libs/lz4/lz4.c index 145f5fbd5..852443a28 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/lz4/lz4.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/lz4/lz4.c @@ -1,6 +1,6 @@ /* LZ4 - Fast LZ compression algorithm - Copyright (C) 2011-2020, Yann Collet. + Copyright (C) 2011-2023, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) @@ -109,15 +109,13 @@ # define LZ4_SRC_INCLUDED 1 #endif -#ifndef LZ4_STATIC_LINKING_ONLY -#define LZ4_STATIC_LINKING_ONLY -#endif - #ifndef LZ4_DISABLE_DEPRECATE_WARNINGS -#define LZ4_DISABLE_DEPRECATE_WARNINGS /* due to LZ4_decompress_safe_withPrefix64k */ +# define LZ4_DISABLE_DEPRECATE_WARNINGS /* due to LZ4_decompress_safe_withPrefix64k */ #endif -#define LZ4_STATIC_LINKING_ONLY /* LZ4_DISTANCE_MAX */ +#ifndef LZ4_STATIC_LINKING_ONLY +# define LZ4_STATIC_LINKING_ONLY +#endif #include "lz4.h" /* see also "memory routines" below */ @@ -129,14 +127,17 @@ # include /* only present in VS2005+ */ # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ # pragma warning(disable : 6237) /* disable: C6237: conditional expression is always 0 */ +# pragma warning(disable : 6239) /* disable: C6239: ( && ) always evaluates to the result of */ +# pragma warning(disable : 6240) /* disable: C6240: ( && ) always evaluates to the result of */ +# pragma warning(disable : 6326) /* disable: C6326: Potential comparison of a constant with another constant */ #endif /* _MSC_VER */ #ifndef LZ4_FORCE_INLINE -# ifdef _MSC_VER /* Visual Studio */ +# if defined (_MSC_VER) && !defined (__clang__) /* MSVC */ # define LZ4_FORCE_INLINE static __forceinline # else # if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ -# ifdef __GNUC__ +# if defined (__GNUC__) || defined (__clang__) # define LZ4_FORCE_INLINE static inline __attribute__((always_inline)) # else # define LZ4_FORCE_INLINE static inline @@ -435,10 +436,22 @@ static U16 LZ4_readLE16(const void* memPtr) return LZ4_read16(memPtr); } else { const BYTE* p = (const BYTE*)memPtr; - return (U16)((U16)p[0] + (p[1]<<8)); + return (U16)((U16)p[0] | (p[1]<<8)); } } +#ifdef LZ4_STATIC_LINKING_ONLY_ENDIANNESS_INDEPENDENT_OUTPUT +static U32 LZ4_readLE32(const void* memPtr) +{ + if (LZ4_isLittleEndian()) { + return LZ4_read32(memPtr); + } else { + const BYTE* p = (const BYTE*)memPtr; + return (U32)p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); + } +} +#endif + static void LZ4_writeLE16(void* memPtr, U16 value) { if (LZ4_isLittleEndian()) { @@ -520,7 +533,7 @@ LZ4_wildCopy32(void* dstPtr, const void* srcPtr, void* dstEnd) /* LZ4_memcpy_using_offset() presumes : * - dstEnd >= dstPtr + MINMATCH - * - there is at least 8 bytes available to write after dstEnd */ + * - there is at least 12 bytes available to write after dstEnd */ LZ4_FORCE_INLINE void LZ4_memcpy_using_offset(BYTE* dstPtr, const BYTE* srcPtr, BYTE* dstEnd, const size_t offset) { @@ -787,7 +800,12 @@ LZ4_FORCE_INLINE U32 LZ4_hash5(U64 sequence, tableType_t const tableType) LZ4_FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tableType) { if ((sizeof(reg_t)==8) && (tableType != byU16)) return LZ4_hash5(LZ4_read_ARCH(p), tableType); + +#ifdef LZ4_STATIC_LINKING_ONLY_ENDIANNESS_INDEPENDENT_OUTPUT + return LZ4_hash4(LZ4_readLE32(p), tableType); +#else return LZ4_hash4(LZ4_read32(p), tableType); +#endif } LZ4_FORCE_INLINE void LZ4_clearHash(U32 h, void* tableBase, tableType_t const tableType) @@ -1106,7 +1124,7 @@ LZ4_FORCE_INLINE int LZ4_compress_generic_validated( goto _last_literals; } if (litLength >= RUN_MASK) { - int len = (int)(litLength - RUN_MASK); + unsigned len = litLength - RUN_MASK; *token = (RUN_MASK<= 255 ; len-=255) *op++ = 255; *op++ = (BYTE)len; @@ -1463,22 +1481,30 @@ int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacit /* Note!: This function leaves the stream in an unclean/broken state! * It is not safe to subsequently use the same state with a _fastReset() or * _continue() call without resetting it. */ -static int LZ4_compress_destSize_extState (LZ4_stream_t* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize) +static int LZ4_compress_destSize_extState_internal(LZ4_stream_t* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize, int acceleration) { void* const s = LZ4_initStream(state, sizeof (*state)); assert(s != NULL); (void)s; if (targetDstSize >= LZ4_compressBound(*srcSizePtr)) { /* compression success is guaranteed */ - return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, 1); + return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, acceleration); } else { if (*srcSizePtr < LZ4_64Klimit) { - return LZ4_compress_generic(&state->internal_donotuse, src, dst, *srcSizePtr, srcSizePtr, targetDstSize, fillOutput, byU16, noDict, noDictIssue, 1); + return LZ4_compress_generic(&state->internal_donotuse, src, dst, *srcSizePtr, srcSizePtr, targetDstSize, fillOutput, byU16, noDict, noDictIssue, acceleration); } else { tableType_t const addrMode = ((sizeof(void*)==4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32; - return LZ4_compress_generic(&state->internal_donotuse, src, dst, *srcSizePtr, srcSizePtr, targetDstSize, fillOutput, addrMode, noDict, noDictIssue, 1); + return LZ4_compress_generic(&state->internal_donotuse, src, dst, *srcSizePtr, srcSizePtr, targetDstSize, fillOutput, addrMode, noDict, noDictIssue, acceleration); } } } +int LZ4_compress_destSize_extState(void* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize, int acceleration) +{ + int const r = LZ4_compress_destSize_extState_internal((LZ4_stream_t*)state, src, dst, srcSizePtr, targetDstSize, acceleration); + /* clean the state on exit */ + LZ4_initStream(state, sizeof (LZ4_stream_t)); + return r; +} + int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize) { @@ -1490,7 +1516,7 @@ int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targe LZ4_stream_t* const ctx = &ctxBody; #endif - int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize); + int result = LZ4_compress_destSize_extState_internal(ctx, src, dst, srcSizePtr, targetDstSize, 1); #if (LZ4_HEAPMODE) FREEMEM(ctx); @@ -1559,8 +1585,11 @@ int LZ4_freeStream (LZ4_stream_t* LZ4_stream) #endif +typedef enum { _ld_fast, _ld_slow } LoadDict_mode_e; #define HASH_UNIT sizeof(reg_t) -int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) +static int LZ4_loadDict_internal(LZ4_stream_t* LZ4_dict, + const char* dictionary, int dictSize, + LoadDict_mode_e _ld) { LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse; const tableType_t tableType = byU32; @@ -1596,13 +1625,39 @@ int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) while (p <= dictEnd-HASH_UNIT) { U32 const h = LZ4_hashPosition(p, tableType); + /* Note: overwriting => favors positions end of dictionary */ LZ4_putIndexOnHash(idx32, h, dict->hashTable, tableType); p+=3; idx32+=3; } + if (_ld == _ld_slow) { + /* Fill hash table with additional references, to improve compression capability */ + p = dict->dictionary; + idx32 = dict->currentOffset - dict->dictSize; + while (p <= dictEnd-HASH_UNIT) { + U32 const h = LZ4_hashPosition(p, tableType); + U32 const limit = dict->currentOffset - 64 KB; + if (LZ4_getIndexOnHash(h, dict->hashTable, tableType) <= limit) { + /* Note: not overwriting => favors positions beginning of dictionary */ + LZ4_putIndexOnHash(idx32, h, dict->hashTable, tableType); + } + p++; idx32++; + } + } + return (int)dict->dictSize; } +int LZ4_loadDict(LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) +{ + return LZ4_loadDict_internal(LZ4_dict, dictionary, dictSize, _ld_fast); +} + +int LZ4_loadDictSlow(LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) +{ + return LZ4_loadDict_internal(LZ4_dict, dictionary, dictSize, _ld_slow); +} + void LZ4_attach_dictionary(LZ4_stream_t* workingStream, const LZ4_stream_t* dictionaryStream) { const LZ4_stream_t_internal* dictCtx = (dictionaryStream == NULL) ? NULL : @@ -1934,6 +1989,17 @@ read_variable_length(const BYTE** ip, const BYTE* ilimit, if (initial_check && unlikely((*ip) >= ilimit)) { /* read limit reached */ return rvl_error; } + s = **ip; + (*ip)++; + length += s; + if (unlikely((*ip) > ilimit)) { /* read limit reached */ + return rvl_error; + } + /* accumulator overflow detection (32-bit mode only) */ + if ((sizeof(length) < 8) && unlikely(length > ((Rvl_t)(-1)/2)) ) { + return rvl_error; + } + if (likely(s != 255)) return length; do { s = **ip; (*ip)++; @@ -1942,10 +2008,10 @@ read_variable_length(const BYTE** ip, const BYTE* ilimit, return rvl_error; } /* accumulator overflow detection (32-bit mode only) */ - if ((sizeof(length)<8) && unlikely(length > ((Rvl_t)(-1)/2)) ) { + if ((sizeof(length) < 8) && unlikely(length > ((Rvl_t)(-1)/2)) ) { return rvl_error; } - } while (s==255); + } while (s == 255); return length; } @@ -2011,7 +2077,7 @@ LZ4_decompress_generic( * note : fast loop may show a regression for some client arm chips. */ #if LZ4_FAST_DEC_LOOP if ((oend - op) < FASTLOOP_SAFE_DISTANCE) { - DEBUGLOG(6, "skip fast decode loop"); + DEBUGLOG(6, "move to safe decode loop"); goto safe_decode; } @@ -2023,6 +2089,7 @@ LZ4_decompress_generic( assert(ip < iend); token = *ip++; length = token >> ML_BITS; /* literal length */ + DEBUGLOG(7, "blockPos%6u: litLength token = %u", (unsigned)(op-(BYTE*)dst), (unsigned)length); /* decode literal length */ if (length == RUN_MASK) { @@ -2052,21 +2119,23 @@ LZ4_decompress_generic( /* get offset */ offset = LZ4_readLE16(ip); ip+=2; - DEBUGLOG(6, " offset = %zu", offset); + DEBUGLOG(6, "blockPos%6u: offset = %u", (unsigned)(op-(BYTE*)dst), (unsigned)offset); match = op - offset; assert(match <= op); /* overflow check */ /* get matchlength */ length = token & ML_MASK; + DEBUGLOG(7, " match length token = %u (len==%u)", (unsigned)length, (unsigned)length+MINMATCH); if (length == ML_MASK) { size_t const addl = read_variable_length(&ip, iend - LASTLITERALS + 1, 0); if (addl == rvl_error) { - DEBUGLOG(6, "error reading long match length"); + DEBUGLOG(5, "error reading long match length"); goto _output_error; } length += addl; length += MINMATCH; + DEBUGLOG(7, " long match length == %u", (unsigned)length); if (unlikely((uptrval)(op)+length<(uptrval)op)) { goto _output_error; } /* overflow detection */ if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) { goto safe_match_copy; @@ -2074,6 +2143,7 @@ LZ4_decompress_generic( } else { length += MINMATCH; if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) { + DEBUGLOG(7, "moving to safe_match_copy (ml==%u)", (unsigned)length); goto safe_match_copy; } @@ -2092,7 +2162,7 @@ LZ4_decompress_generic( } } } if ( checkOffset && (unlikely(match + dictSize < lowPrefix)) ) { - DEBUGLOG(6, "Error : pos=%zi, offset=%zi => outside buffers", op-lowPrefix, op-match); + DEBUGLOG(5, "Error : pos=%zi, offset=%zi => outside buffers", op-lowPrefix, op-match); goto _output_error; } /* match starting within external dictionary */ @@ -2149,6 +2219,7 @@ LZ4_decompress_generic( assert(ip < iend); token = *ip++; length = token >> ML_BITS; /* literal length */ + DEBUGLOG(7, "blockPos%6u: litLength token = %u", (unsigned)(op-(BYTE*)dst), (unsigned)length); /* A two-stage shortcut for the most common case: * 1) If the literal length is 0..14, and there is enough space, @@ -2169,6 +2240,7 @@ LZ4_decompress_generic( /* The second stage: prepare for match copying, decode full info. * If it doesn't work out, the info won't be wasted. */ length = token & ML_MASK; /* match length */ + DEBUGLOG(7, "blockPos%6u: matchLength token = %u (len=%u)", (unsigned)(op-(BYTE*)dst), (unsigned)length, (unsigned)length + 4); offset = LZ4_readLE16(ip); ip += 2; match = op - offset; assert(match <= op); /* check overflow */ @@ -2241,9 +2313,10 @@ LZ4_decompress_generic( * so check that we exactly consume the input and don't overrun the output buffer. */ if ((ip+length != iend) || (cpy > oend)) { - DEBUGLOG(6, "should have been last run of literals") - DEBUGLOG(6, "ip(%p) + length(%i) = %p != iend (%p)", ip, (int)length, ip+length, iend); - DEBUGLOG(6, "or cpy(%p) > oend(%p)", cpy, oend); + DEBUGLOG(5, "should have been last run of literals") + DEBUGLOG(5, "ip(%p) + length(%i) = %p != iend (%p)", ip, (int)length, ip+length, iend); + DEBUGLOG(5, "or cpy(%p) > (oend-MFLIMIT)(%p)", cpy, oend-MFLIMIT); + DEBUGLOG(5, "after writing %u bytes / %i bytes available", (unsigned)(op-(BYTE*)dst), outputSize); goto _output_error; } } @@ -2269,6 +2342,7 @@ LZ4_decompress_generic( /* get matchlength */ length = token & ML_MASK; + DEBUGLOG(7, "blockPos%6u: matchLength token = %u", (unsigned)(op-(BYTE*)dst), (unsigned)length); _copy_match: if (length == ML_MASK) { @@ -2358,7 +2432,7 @@ LZ4_decompress_generic( while (op < cpy) { *op++ = *match++; } } else { LZ4_memcpy(op, match, 8); - if (length > 16) { LZ4_wildCopy8(op+8, match+8, cpy); } + if (length > 16) { LZ4_wildCopy8(op+8, match+8, cpy); } } op = cpy; /* wildcopy correction */ } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/lz4/lz4.h b/lib/libesp32_lvgl/lvgl/src/libs/lz4/lz4.h index ce763af13..bbb3f0423 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/lz4/lz4.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/lz4/lz4.h @@ -1,7 +1,7 @@ /* * LZ4 - Fast LZ compression algorithm * Header File - * Copyright (C) 2011-2020, Yann Collet. + * Copyright (C) 2011-2023, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) @@ -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 cannot generate Frames. + lz4.h only handle blocks, it can not generate Frames. Blocks are different from Frames (doc/lz4_Frame_format.md). Frames bundle both blocks and metadata in a specified manner. @@ -141,8 +141,8 @@ extern "C" { /*------ Version ------*/ #define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ -#define LZ4_VERSION_MINOR 9 /* for new (non-breaking) interface capabilities */ -#define LZ4_VERSION_RELEASE 5 /* for tweaks, bug-fixes, or development */ +#define LZ4_VERSION_MINOR 10 /* for new (non-breaking) interface capabilities */ +#define LZ4_VERSION_RELEASE 0 /* for tweaks, bug-fixes, or development */ #define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) @@ -156,23 +156,25 @@ LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; /*-************************************ -* Tuning parameter +* Tuning memory usage **************************************/ -#define LZ4_MEMORY_USAGE_MIN 10 -#define LZ4_MEMORY_USAGE_DEFAULT 14 -#define LZ4_MEMORY_USAGE_MAX 20 - /*! * LZ4_MEMORY_USAGE : - * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; ) - * Increasing memory usage improves compression ratio, at the cost of speed. + * Can be selected at compile time, by setting LZ4_MEMORY_USAGE. + * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB) + * Increasing memory usage improves compression ratio, generally at the cost of speed. * Reduced memory usage may improve speed at the cost of ratio, thanks to better cache locality. - * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache + * Default value is 14, for 16KB, which nicely fits into most L1 caches. */ #ifndef LZ4_MEMORY_USAGE # define LZ4_MEMORY_USAGE LZ4_MEMORY_USAGE_DEFAULT #endif +/* These are absolute limits, they should not be changed by users */ +#define LZ4_MEMORY_USAGE_MIN 10 +#define LZ4_MEMORY_USAGE_DEFAULT 14 +#define LZ4_MEMORY_USAGE_MAX 20 + #if (LZ4_MEMORY_USAGE < LZ4_MEMORY_USAGE_MIN) # error "LZ4_MEMORY_USAGE is too small !" #endif @@ -203,7 +205,7 @@ LZ4LIB_API int LZ4_compress_default(const char* src, char* dst, int srcSize, int /*! LZ4_decompress_safe() : * @compressedSize : is the exact complete size of the compressed block. * @dstCapacity : is the size of destination buffer (which must be already allocated), - * is an upper bound of decompressed size. + * presumed an upper bound of decompressed size. * @return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity) * If destination buffer is not large enough, decoding will stop and output an error code (negative value). * If the source stream is detected malformed, the function will stop decoding and return a negative result. @@ -255,17 +257,17 @@ LZ4LIB_API int LZ4_compress_fast (const char* src, char* dst, int srcSize, int d LZ4LIB_API int LZ4_sizeofState(void); LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); - /*! LZ4_compress_destSize() : * Reverse the logic : compresses as much data as possible from 'src' buffer - * into already allocated buffer 'dst', of size >= 'targetDestSize'. + * into already allocated buffer 'dst', of size >= 'dstCapacity'. * This function either compresses the entire 'src' content into 'dst' if it's large enough, * or fill 'dst' buffer completely with as much data as possible from 'src'. * note: acceleration parameter is fixed to "default". * - * *srcSizePtr : will be modified to indicate how many bytes where read from 'src' to fill 'dst'. + * *srcSizePtr : in+out parameter. Initially contains size of input. + * Will be modified to indicate how many bytes where read from 'src' to fill 'dst'. * New value is necessarily <= input value. - * @return : Nb bytes written into 'dst' (necessarily <= targetDestSize) + * @return : Nb bytes written into 'dst' (necessarily <= dstCapacity) * or 0 if compression fails. * * Note : from v1.8.2 to v1.9.1, this function had a bug (fixed in v1.9.2+): @@ -279,8 +281,7 @@ LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* d * a dstCapacity which is > decompressedSize, by at least 1 byte. * See https://github.com/lz4/lz4/issues/859 for details */ -LZ4LIB_API int LZ4_compress_destSize (const char* src, char* dst, int* srcSizePtr, int targetDstSize); - +LZ4LIB_API int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize); /*! LZ4_decompress_safe_partial() : * Decompress an LZ4 compressed block, of size 'srcSize' at position 'src', @@ -324,7 +325,7 @@ LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcS ***********************************************/ typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */ -/** +/*! Note about RC_INVOKED - RC_INVOKED is predefined symbol of rc.exe (the resource compiler which is part of MSVC/Visual Studio). @@ -374,13 +375,58 @@ LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr); * LZ4_loadDict() triggers a reset, so any previous data will be forgotten. * The same dictionary will have to be loaded on decompression side for successful decoding. * Dictionary are useful for better compression of small data (KB range). - * While LZ4 accept any input as dictionary, - * results are generally better when using Zstandard's Dictionary Builder. + * While LZ4 itself accepts any input as dictionary, dictionary efficiency is also a topic. + * When in doubt, employ the Zstandard's Dictionary Builder. * Loading a size of 0 is allowed, and is the same as reset. - * @return : loaded dictionary size, in bytes (necessarily <= 64 KB) + * @return : loaded dictionary size, in bytes (note: only the last 64 KB are loaded) */ LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); +/*! LZ4_loadDictSlow() : v1.10.0+ + * Same as LZ4_loadDict(), + * but uses a bit more cpu to reference the dictionary content more thoroughly. + * This is expected to slightly improve compression ratio. + * The extra-cpu cost is likely worth it if the dictionary is re-used across multiple sessions. + * @return : loaded dictionary size, in bytes (note: only the last 64 KB are loaded) + */ +LZ4LIB_API int LZ4_loadDictSlow(LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); + +/*! LZ4_attach_dictionary() : stable since v1.10.0 + * + * This allows efficient re-use of a static dictionary multiple times. + * + * Rather than re-loading the dictionary buffer into a working context before + * each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a + * working LZ4_stream_t, this function introduces a no-copy setup mechanism, + * in which the working stream references @dictionaryStream in-place. + * + * Several assumptions are made about the state of @dictionaryStream. + * Currently, only states which have been prepared by LZ4_loadDict() or + * LZ4_loadDictSlow() should be expected to work. + * + * 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. + * The dictionary contents are the only history that can be referenced and + * logically immediately precede the data compressed in the first subsequent + * compression call. + * + * The dictionary will only remain attached to the working stream through the + * first compression call, at the end of which it is cleared. + * @dictionaryStream stream (and source buffer) must remain in-place / accessible / unchanged + * through the completion of the compression session. + * + * Note: there is no equivalent LZ4_attach_*() method on the decompression side + * because there is no initialization cost, hence no need to share the cost across multiple sessions. + * To decompress LZ4 blocks using dictionary, attached or not, + * just employ the regular LZ4_setStreamDecode() for streaming, + * or the stateless LZ4_decompress_safe_usingDict() for one-shot decompression. + */ +LZ4LIB_API void +LZ4_attach_dictionary(LZ4_stream_t* workingStream, + const LZ4_stream_t* dictionaryStream); + /*! LZ4_compress_fast_continue() : * Compress 'src' content using data from previously compressed blocks, for better compression ratio. * 'dst' buffer must be already allocated. @@ -558,9 +604,9 @@ LZ4_decompress_safe_partial_usingDict(const char* src, char* dst, #define LZ4_STATIC_3504398509 #ifdef LZ4_PUBLISH_STATIC_FUNCTIONS -#define LZ4LIB_STATIC_API LZ4LIB_API +# define LZ4LIB_STATIC_API LZ4LIB_API #else -#define LZ4LIB_STATIC_API +# define LZ4LIB_STATIC_API #endif @@ -576,36 +622,11 @@ LZ4_decompress_safe_partial_usingDict(const char* src, char* dst, */ LZ4LIB_STATIC_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); -/*! LZ4_attach_dictionary() : - * This is an experimental API that allows - * efficient use of a static dictionary many times. - * - * Rather than re-loading the dictionary buffer into a working context before - * each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a - * working LZ4_stream_t, this function introduces a no-copy setup mechanism, - * in which the working stream references the dictionary stream in-place. - * - * Several assumptions are made about the state of the dictionary stream. - * Currently, only streams which have been prepared by LZ4_loadDict() should - * be expected to work. - * - * Alternatively, the provided dictionaryStream may be NULL, - * in which case any existing dictionary stream is unset. - * - * 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. - * - * The dictionary will only remain attached to the working stream through the - * first compression call, at the end of which it is cleared. The dictionary - * stream (and source buffer) must remain in-place / accessible / unchanged - * through the completion of the first compression call on the stream. +/*! LZ4_compress_destSize_extState() : introduced in v1.10.0 + * Same as LZ4_compress_destSize(), but using an externally allocated state. + * Also: exposes @acceleration */ -LZ4LIB_STATIC_API void -LZ4_attach_dictionary(LZ4_stream_t* workingStream, - const LZ4_stream_t* dictionaryStream); - +int LZ4_compress_destSize_extState(void* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize, int acceleration); /*! In-place compression and decompression * @@ -717,7 +738,7 @@ struct LZ4_stream_t_internal { /* Implicit padding to ensure structure is aligned */ }; -#define LZ4_STREAM_MINSIZE ((1UL << LZ4_MEMORY_USAGE) + 32) /* static size, for inter-version compatibility */ +#define LZ4_STREAM_MINSIZE ((1UL << (LZ4_MEMORY_USAGE)) + 32) /* static size, for inter-version compatibility */ union LZ4_stream_u { char minStateSize[LZ4_STREAM_MINSIZE]; LZ4_stream_t_internal internal_donotuse; @@ -738,7 +759,7 @@ union LZ4_stream_u { * Note2: An LZ4_stream_t structure guarantees correct alignment and size. * Note3: Before v1.9.0, use LZ4_resetStream() instead **/ -LZ4LIB_API LZ4_stream_t* LZ4_initStream (void* buffer, size_t size); +LZ4LIB_API LZ4_stream_t* LZ4_initStream (void* stateBuffer, size_t size); /*! LZ4_streamDecode_t : @@ -850,11 +871,12 @@ LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") LZ4LIB_API int LZ4 * But they may happen if input data is invalid (error or intentional tampering). * As a consequence, use these functions in trusted environments with trusted data **only**. */ -LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe() instead") +LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_partial() instead") LZ4LIB_API int LZ4_decompress_fast (const char* src, char* dst, int originalSize); -LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_continue() instead") +LZ4_DEPRECATED("This function is deprecated and unsafe. Consider migrating towards LZ4_decompress_safe_continue() instead. " + "Note that the contract will change (requires block's compressed size, instead of decompressed size)") LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int originalSize); -LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_usingDict() instead") +LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_partial_usingDict() instead") LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int originalSize, const char* dictStart, int dictSize); /*! LZ4_resetStream() : diff --git a/lib/libesp32_lvgl/lvgl/src/libs/qrcode/LICENSE.txt b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/LICENSE.txt new file mode 100644 index 000000000..e6cc7e8c4 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/LICENSE.txt @@ -0,0 +1,8 @@ +Copyright © 2025 Project Nayuki. (MIT License) +https://www.nayuki.io/page/qr-code-generator-library + +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. 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 f4b5b5456..8b948f3ae 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode.c @@ -37,7 +37,7 @@ const lv_obj_class_t lv_qrcode_class = { .destructor_cb = lv_qrcode_destructor, .instance_size = sizeof(lv_qrcode_t), .base_class = &lv_canvas_class, - .name = "qrcode", + .name = "lv_qrcode", }; /********************** 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 index b912d6575..bcd2c8c5d 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode_private.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/lv_qrcode_private.h @@ -28,7 +28,7 @@ extern "C" { **********************/ /*Data of qrcode*/ -struct lv_qrcode_t { +struct _lv_qrcode_t { lv_canvas_t canvas; lv_color_t dark_color; lv_color_t light_color; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/qrcode/qrcodegen.h b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/qrcodegen.h index 950948684..7b80645cc 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/qrcode/qrcodegen.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/qrcode/qrcodegen.h @@ -26,9 +26,9 @@ #include "../../../lvgl.h" #ifdef LV_USE_QRCODE -#include -#include -#include +#include LV_STDBOOL_INCLUDE +#include LV_STDDEF_INCLUDE +#include LV_STDINT_INCLUDE #ifdef __cplusplus 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 3c723ec0f..1bc81ba5f 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie.c +++ b/lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie.c @@ -41,7 +41,7 @@ const lv_obj_class_t lv_rlottie_class = { .destructor_cb = lv_rlottie_destructor, .instance_size = sizeof(lv_rlottie_t), .base_class = &lv_image_class, - .name = "rlottie", + .name = "lv_rlottie", }; typedef struct { 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 index 91587bd6c..344c3909d 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie_private.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/rlottie/lv_rlottie_private.h @@ -29,7 +29,7 @@ extern "C" { /** definition in lottieanimation_capi.c */ struct Lottie_Animation_S; -struct lv_rlottie_t { +struct _lv_rlottie_t { lv_image_t img_ext; struct Lottie_Animation_S * animation; lv_timer_t * task; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg.c b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg.c new file mode 100644 index 000000000..8bb6051f0 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg.c @@ -0,0 +1,124 @@ +/** + * @file lv_svg.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_svg.h" +#if LV_USE_SVG + +#include "../../misc/lv_assert.h" +#include "../../misc/lv_log.h" +#include "../../stdlib/lv_mem.h" + +#include "lv_svg_token.h" +#include "lv_svg_parser.h" + +/********************* +* DEFINES +*********************/ + +/********************** +* TYPEDEFS +**********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void lv_svg_node_constructor(const lv_tree_class_t * class_p, lv_tree_node_t * node) +{ + LV_UNUSED(class_p); + lv_svg_node_t * t = (lv_svg_node_t *)node; + t->xml_id = NULL; + t->type = LV_SVG_TAG_INVALID; + lv_array_init(&t->attrs, 4, sizeof(lv_svg_attr_t)); + t->render_obj = NULL; +} + +static void lv_svg_node_destructor(const lv_tree_class_t * class_p, lv_tree_node_t * node) +{ + LV_UNUSED(class_p); + lv_svg_node_t * t = (lv_svg_node_t *)node; + if(t->xml_id) { + lv_free(t->xml_id); + } + for(uint32_t i = 0; i < lv_array_size(&t->attrs); i++) { + lv_svg_attr_t * attr = lv_array_at(&t->attrs, i); + if(attr->val_type == LV_SVG_ATTR_VALUE_PTR) { + lv_free(attr->value.val); + } + } + lv_array_deinit(&t->attrs); +} + +static bool svg_token_process_cb(_lv_svg_token_t * token, void * data) +{ + _lv_svg_parser_t * parser = (_lv_svg_parser_t *)data; + return _lv_svg_parser_token(parser, token); +} + +/********************** + * STATIC VARIABLES + **********************/ +const lv_tree_class_t lv_svg_node_class = { + .base_class = &lv_tree_node_class, + .instance_size = sizeof(lv_svg_node_t), + .constructor_cb = lv_svg_node_constructor, + .destructor_cb = lv_svg_node_destructor, +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ +lv_svg_node_t * lv_svg_load_data(const char * svg_data, uint32_t data_len) +{ + LV_ASSERT_NULL(svg_data); + LV_ASSERT(data_len > 0); + + _lv_svg_parser_t parser; + _lv_svg_parser_init(&parser); + + if(_lv_svg_tokenizer(svg_data, data_len, svg_token_process_cb, &parser)) { + if(_lv_svg_parser_is_finish(&parser)) { + lv_svg_node_t * doc = parser.doc_root; + parser.doc_root = NULL; + _lv_svg_parser_deinit(&parser); +#if LV_USE_SVG_DEBUG + _lv_svg_dump_tree(doc, 0); +#endif + return doc; + } + else { + _lv_svg_parser_deinit(&parser); + LV_LOG_ERROR("svg document parser raise errors!"); + return NULL; + } + } + else { + _lv_svg_parser_deinit(&parser); + LV_LOG_ERROR("svg document tokenizer raise errors!"); + return NULL; + } +} + +lv_svg_node_t * lv_svg_node_create(lv_svg_node_t * parent) +{ + lv_tree_node_t * node = lv_tree_node_create(&lv_svg_node_class, (lv_tree_node_t *)parent); + return (lv_svg_node_t *)node; +} + +void lv_svg_node_delete(lv_svg_node_t * node) +{ + lv_tree_node_delete((lv_tree_node_t *)node); +} + +/********************** + * STATIC FUNCTIONS + **********************/ +#endif /*LV_USE_SVG*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg.h b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg.h new file mode 100644 index 000000000..b5a8965cb --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg.h @@ -0,0 +1,334 @@ +/** + * @file lv_svg.h + * + */ + +#ifndef LV_SVG_H +#define LV_SVG_H + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_SVG + +#include "../../misc/lv_array.h" +#include "../../misc/lv_tree.h" +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +enum { + LV_SVG_TAG_INVALID = -1, + LV_SVG_TAG_CONTENT, + LV_SVG_TAG_SVG, + LV_SVG_TAG_USE, + LV_SVG_TAG_G, + LV_SVG_TAG_PATH, + LV_SVG_TAG_RECT, + LV_SVG_TAG_CIRCLE, + LV_SVG_TAG_ELLIPSE, + LV_SVG_TAG_LINE, + LV_SVG_TAG_POLYLINE, + LV_SVG_TAG_POLYGON, + LV_SVG_TAG_SOLID_COLOR, + LV_SVG_TAG_LINEAR_GRADIENT, + LV_SVG_TAG_RADIAL_GRADIENT, + LV_SVG_TAG_STOP, + LV_SVG_TAG_DEFS, + LV_SVG_TAG_IMAGE, +#if LV_USE_SVG_ANIMATION + LV_SVG_TAG_MPATH, + LV_SVG_TAG_SET, + LV_SVG_TAG_ANIMATE, + LV_SVG_TAG_ANIMATE_COLOR, + LV_SVG_TAG_ANIMATE_TRANSFORM, + LV_SVG_TAG_ANIMATE_MOTION, +#endif + LV_SVG_TAG_TEXT, + LV_SVG_TAG_TSPAN, + LV_SVG_TAG_TEXT_AREA, +}; +typedef int8_t lv_svg_tag_t; + +enum { + LV_SVG_ATTR_INVALID = 0, + LV_SVG_ATTR_ID, + LV_SVG_ATTR_XML_ID, + LV_SVG_ATTR_VERSION, + LV_SVG_ATTR_BASE_PROFILE, + LV_SVG_ATTR_VIEWBOX, + LV_SVG_ATTR_PRESERVE_ASPECT_RATIO, + LV_SVG_ATTR_VIEWPORT_FILL, + LV_SVG_ATTR_VIEWPORT_FILL_OPACITY, + LV_SVG_ATTR_DISPLAY, + LV_SVG_ATTR_VISIBILITY, + LV_SVG_ATTR_X, + LV_SVG_ATTR_Y, + LV_SVG_ATTR_WIDTH, + LV_SVG_ATTR_HEIGHT, + LV_SVG_ATTR_RX, + LV_SVG_ATTR_RY, + LV_SVG_ATTR_CX, + LV_SVG_ATTR_CY, + LV_SVG_ATTR_R, + LV_SVG_ATTR_X1, + LV_SVG_ATTR_Y1, + LV_SVG_ATTR_X2, + LV_SVG_ATTR_Y2, + LV_SVG_ATTR_POINTS, + LV_SVG_ATTR_D, + LV_SVG_ATTR_PATH_LENGTH, + LV_SVG_ATTR_XLINK_HREF, + LV_SVG_ATTR_FILL, + LV_SVG_ATTR_FILL_RULE, + LV_SVG_ATTR_FILL_OPACITY, + LV_SVG_ATTR_STROKE, + LV_SVG_ATTR_STROKE_WIDTH, + LV_SVG_ATTR_STROKE_LINECAP, + LV_SVG_ATTR_STROKE_LINEJOIN, + LV_SVG_ATTR_STROKE_MITER_LIMIT, + LV_SVG_ATTR_STROKE_DASH_ARRAY, + LV_SVG_ATTR_STROKE_DASH_OFFSET, + LV_SVG_ATTR_STROKE_OPACITY, + LV_SVG_ATTR_OPACITY, + LV_SVG_ATTR_SOLID_COLOR, + LV_SVG_ATTR_SOLID_OPACITY, + LV_SVG_ATTR_GRADIENT_UNITS, + LV_SVG_ATTR_GRADIENT_STOP_OFFSET, + LV_SVG_ATTR_GRADIENT_STOP_COLOR, + LV_SVG_ATTR_GRADIENT_STOP_OPACITY, + LV_SVG_ATTR_FONT_FAMILY, + LV_SVG_ATTR_FONT_STYLE, + LV_SVG_ATTR_FONT_VARIANT, + LV_SVG_ATTR_FONT_WEIGHT, + LV_SVG_ATTR_FONT_SIZE, + LV_SVG_ATTR_TRANSFORM, + LV_SVG_ATTR_TEXT_ANCHOR, +#if LV_USE_SVG_ANIMATION + LV_SVG_ATTR_ATTRIBUTE_NAME, + LV_SVG_ATTR_ATTRIBUTE_TYPE, + LV_SVG_ATTR_BEGIN, + LV_SVG_ATTR_END, + LV_SVG_ATTR_DUR, + LV_SVG_ATTR_MIN, + LV_SVG_ATTR_MAX, + LV_SVG_ATTR_RESTART, + LV_SVG_ATTR_REPEAT_COUNT, + LV_SVG_ATTR_REPEAT_DUR, + LV_SVG_ATTR_CALC_MODE, + LV_SVG_ATTR_VALUES, + LV_SVG_ATTR_KEY_TIMES, + LV_SVG_ATTR_KEY_SPLINES, + LV_SVG_ATTR_KEY_POINTS, + LV_SVG_ATTR_FROM, + LV_SVG_ATTR_TO, + LV_SVG_ATTR_BY, + LV_SVG_ATTR_ADDITIVE, + LV_SVG_ATTR_ACCUMULATE, + LV_SVG_ATTR_PATH, + LV_SVG_ATTR_ROTATE, + LV_SVG_ATTR_TRANSFORM_TYPE, +#endif +}; +typedef uint8_t lv_svg_attr_type_t; + +enum { + LV_SVG_TRANSFORM_TYPE_MATRIX = 1, + LV_SVG_TRANSFORM_TYPE_TRANSLATE, + LV_SVG_TRANSFORM_TYPE_ROTATE, + LV_SVG_TRANSFORM_TYPE_SCALE, + LV_SVG_TRANSFORM_TYPE_SKEW_X, + LV_SVG_TRANSFORM_TYPE_SKEW_Y, +}; +typedef uint8_t lv_svg_transform_type_t; + +#if LV_USE_SVG_ANIMATION +enum { + LV_SVG_ANIM_REMOVE = 0, + LV_SVG_ANIM_FREEZE, +}; + +enum { + LV_SVG_ANIM_RESTART_ALWAYS = 0, + LV_SVG_ANIM_RESTART_WHEN_NOT_ACTIVE, + LV_SVG_ANIM_RESTART_NEVER, +}; + +enum { + LV_SVG_ANIM_CALC_MODE_LINEAR = 0, + LV_SVG_ANIM_CALC_MODE_PACED, + LV_SVG_ANIM_CALC_MODE_SPLINE, + LV_SVG_ANIM_CALC_MODE_DISCRETE, +}; + +enum { + LV_SVG_ANIM_ADDITIVE_REPLACE = 0, + LV_SVG_ANIM_ADDITIVE_SUM, +}; + +enum { + LV_SVG_ANIM_ACCUMULATE_NONE = 0, + LV_SVG_ANIM_ACCUMULATE_SUM, +}; +#endif + +enum { + LV_SVG_ASPECT_RATIO_NONE = 0, + LV_SVG_ASPECT_RATIO_XMIN_YMIN = (1 << 1), + LV_SVG_ASPECT_RATIO_XMID_YMIN = (2 << 1), + LV_SVG_ASPECT_RATIO_XMAX_YMIN = (3 << 1), + LV_SVG_ASPECT_RATIO_XMIN_YMID = (4 << 1), + LV_SVG_ASPECT_RATIO_XMID_YMID = (5 << 1), + LV_SVG_ASPECT_RATIO_XMAX_YMID = (6 << 1), + LV_SVG_ASPECT_RATIO_XMIN_YMAX = (7 << 1), + LV_SVG_ASPECT_RATIO_XMID_YMAX = (8 << 1), + LV_SVG_ASPECT_RATIO_XMAX_YMAX = (9 << 1), +}; + +enum { + LV_SVG_ASPECT_RATIO_OPT_MEET = 0, + LV_SVG_ASPECT_RATIO_OPT_SLICE, +}; +typedef uint32_t lv_svg_aspect_ratio_t; + +typedef struct { + float x; + float y; +} lv_svg_point_t; + +typedef struct { + float m[3][3]; +} lv_svg_matrix_t; + +typedef uint32_t lv_svg_color_t; + +enum { + LV_SVG_FILL_NONZERO = 0, + LV_SVG_FILL_EVENODD, +}; +typedef uint8_t lv_svg_fill_rule_t; + +enum { + LV_SVG_LINE_CAP_BUTT = 0, + LV_SVG_LINE_CAP_SQUARE, + LV_SVG_LINE_CAP_ROUND, +}; +typedef uint8_t lv_svg_line_cap_t; + +enum { + LV_SVG_LINE_JOIN_MITER = 0, + LV_SVG_LINE_JOIN_BEVEL, + LV_SVG_LINE_JOIN_ROUND, +}; +typedef uint8_t lv_svg_line_join_t; + +enum { + LV_SVG_GRADIENT_UNITS_OBJECT = 0, + LV_SVG_GRADIENT_UNITS_USER_SPACE, +}; +typedef uint8_t lv_svg_gradient_units_t; + +typedef union { + int32_t ival; + uint32_t uval; + float fval; + char * sval; + void * val; +} lv_svg_attr_value_t; + +/* + * to simplify list buffer management, allocate enough memory for all data and length. + * | size | data[0] | data[1] | data[2] | ... | + */ +typedef struct { + uint32_t length; + uint8_t data[1]; +} lv_svg_attr_values_list_t; + +/* https://www.w3.org/TR/SVGTiny12/svgudomidl.html */ +enum { + LV_SVG_PATH_CMD_MOVE_TO = 77, + LV_SVG_PATH_CMD_LINE_TO = 76, + LV_SVG_PATH_CMD_CURVE_TO = 67, + LV_SVG_PATH_CMD_QUAD_TO = 81, + LV_SVG_PATH_CMD_CLOSE = 90, +}; + +/* + * to simplify list buffer management, allocate enough memory for all path data and cmd. + * | cmd | data[0] | data[1] | data[2] | ... | + */ +typedef struct { + uint32_t cmd; + uint8_t data[1]; +} lv_svg_attr_path_value_t; + +enum { + LV_SVG_ATTR_VALUE_DATA = 0, + LV_SVG_ATTR_VALUE_PTR, +}; +typedef uint8_t lv_svg_attr_value_type_t; + +enum { + LV_SVG_ATTR_VALUE_NONE = 0, + LV_SVG_ATTR_VALUE_INITIAL, + LV_SVG_ATTR_VALUE_INHERIT, +}; +typedef uint8_t lv_svg_attr_value_class_t; + +typedef struct { + lv_svg_attr_type_t id; + lv_svg_attr_value_type_t val_type; + lv_svg_attr_value_class_t class_type; + lv_svg_attr_value_t value; +} lv_svg_attr_t; + +struct _lv_svg_render_obj; + +typedef struct { + lv_tree_node_t base; + char * xml_id; /* xml_id or content */ + lv_svg_tag_t type; + lv_array_t attrs; + struct _lv_svg_render_obj * render_obj; +} lv_svg_node_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * @brief Loading SVG data and creating the DOM tree + * @param svg_data pointer to the SVG data + * @param data_len the SVG data length + */ +lv_svg_node_t * lv_svg_load_data(const char * svg_data, uint32_t data_len); + +/** + * @brief Create an SVG DOM node + * @param parent pointer to the parent node + * @return true: an new SVG DOM node, false: NULL + */ +lv_svg_node_t * lv_svg_node_create(lv_svg_node_t * parent); + +/** + * @brief Delete an SVG DOM subtree + * @param node pointer to an SVG DOM subtree + */ +void lv_svg_node_delete(lv_svg_node_t * node); + +/********************** + * MACROS + **********************/ +#define LV_SVG_NODE_CHILD(n, i) \ + ((lv_svg_node_t *)(LV_TREE_NODE((n))->children[i])) + +#define LV_SVG_NODE(n) ((lv_svg_node_t*)(n)) + +#endif /*LV_USE_SVG*/ + +#endif /*LV_SVG_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_decoder.c b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_decoder.c new file mode 100644 index 000000000..833d01dbb --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_decoder.c @@ -0,0 +1,379 @@ +/** + * @file lv_svg_decoder.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../draw/lv_image_decoder_private.h" +#include "../../../lvgl.h" + +#if LV_USE_SVG +#include "lv_svg_decoder.h" + +#include "lv_svg.h" +#include "../../draw/lv_draw_buf_private.h" +#include "../../display/lv_display_private.h" + +/********************* + * DEFINES + *********************/ + +#define DECODER_NAME "SVG" + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_result_t svg_decoder_info(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * src, + lv_image_header_t * header); +static lv_result_t svg_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); +static void svg_decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc); +static uint8_t * alloc_file(const char * filename, uint32_t * size); +static void svg_draw_buf_free(void * svg_buf); + +static void svg_draw(lv_layer_t * layer, const lv_image_decoder_dsc_t * dsc, const lv_area_t * coords, + const lv_draw_image_dsc_t * draw_dsc, const lv_area_t * clip_area); +/********************** + * STATIC VARIABLES + **********************/ +static struct _lv_draw_buf_handlers_t _svg_draw_buf_handler = { + .buf_free_cb = svg_draw_buf_free, +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Register the SVG decoder functions in LVGL + */ +void lv_svg_decoder_init(void) +{ + lv_image_decoder_t * dec = lv_image_decoder_create(); + lv_image_decoder_set_info_cb(dec, svg_decoder_info); + lv_image_decoder_set_open_cb(dec, svg_decoder_open); + lv_image_decoder_set_close_cb(dec, svg_decoder_close); + + dec->name = DECODER_NAME; +} + +void lv_svg_decoder_deinit(void) +{ + lv_image_decoder_t * dec = NULL; + while((dec = lv_image_decoder_get_next(dec)) != NULL) { + if(dec->info_cb == svg_decoder_info) { + lv_image_decoder_delete(dec); + break; + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ +static bool valid_svg_data(const uint8_t * data, uint32_t data_size) +{ + return (data_size >= 4 && lv_memcmp(data, "= 5 && lv_memcmp(data, "src_type; + + int width = 0; + int height = 0; + + if(src_type == LV_IMAGE_SRC_FILE || src_type == LV_IMAGE_SRC_VARIABLE) { + const void * src_data = src->src; + uint8_t * buf = NULL; + + if(src_type == LV_IMAGE_SRC_FILE) { + /*Support only "*.svg" files*/ + if(lv_strcmp(lv_fs_get_ext(src_data), "svg")) { + return LV_RESULT_INVALID; + } + + uint32_t rn; + lv_fs_res_t res; + uint32_t file_size = 0; + res = lv_fs_seek(&src->file, 0, LV_FS_SEEK_END); + if(res == LV_FS_RES_OK) { + lv_fs_tell(&src->file, &file_size); + lv_fs_seek(&src->file, 0, LV_FS_SEEK_SET); /* Reset position to start */ + } +#ifdef LV_USE_SVG_DEBUG + LV_LOG_INFO("LVGL file_size = %d.", file_size); + +#endif + if(file_size > 512) + file_size = 512; + + buf = (uint8_t *)lv_zalloc(file_size); + LV_ASSERT_NULL(buf); + /* read some bytes for searching svg header */ + res = lv_fs_read(&src->file, buf, file_size, &rn); + if(res != LV_FS_RES_OK) { + LV_LOG_WARN("can't open %s", (char *)src_data); + lv_free(buf); + return LV_RESULT_INVALID; + } + + if(!valid_svg_data(buf, rn)) { + lv_free(buf); + return LV_RESULT_INVALID; + } + + width = LV_DPI_DEF; + height = LV_DPI_DEF; + + uint8_t * svg_start = NULL; + uint8_t * svg_end = NULL; + uint8_t * ptr = buf; + uint8_t * ptr_end = buf + file_size - 1; + while(ptr < ptr_end) { + if(*ptr == '<') { + if(lv_strncmp((char *)(ptr + 1), "svg", 3) == 0) { + svg_start = ptr; + } + } + if(svg_start && (*ptr == '>')) { + svg_end = ptr; + break; + } + ptr++; + } + + if(svg_start && svg_end) { + lv_svg_node_t * svg_doc = lv_svg_load_data((char *)svg_start, svg_end - svg_start); + lv_svg_render_obj_t * svg_header = lv_svg_render_create(svg_doc); + if(svg_header->tag == LV_SVG_TAG_SVG) { + lv_area_t bounds; + svg_header->clz->get_bounds(svg_header, &bounds); + width = lv_area_get_width(&bounds) - 1; + height = lv_area_get_height(&bounds) - 1; + } + lv_svg_render_delete(svg_header); + lv_svg_node_delete(svg_doc); + } + else + LV_LOG_WARN("can't find svg viewport tag end"); + + lv_free(buf); + } + else { + const lv_image_dsc_t * img_dsc = src_data; + uint32_t data_size = img_dsc->data_size; + width = img_dsc->header.w; + height = img_dsc->header.h; + + if(!valid_svg_data(img_dsc->data, data_size)) { + return LV_RESULT_INVALID; + } + } + + header->cf = LV_COLOR_FORMAT_ARGB8888; + header->w = width; + header->h = height; + header->flags |= LV_IMAGE_FLAGS_CUSTOM_DRAW; + + decoder->custom_draw_cb = svg_draw; + + return LV_RESULT_OK; + } + + return LV_RESULT_INVALID; +} + +static lv_result_t svg_decoder_open(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc) +{ + LV_UNUSED(decoder); + LV_PROFILER_DECODER_BEGIN_TAG("lv_svg_decoder_open"); + + uint8_t * svg_data = NULL; + uint32_t svg_data_size = 0; + + if(dsc->src_type == LV_IMAGE_SRC_FILE) { + const char * fn = dsc->src; + if(lv_strcmp(lv_fs_get_ext(fn), "svg") == 0) { /*Check the extension*/ + + svg_data = alloc_file(fn, &svg_data_size); + if(svg_data == NULL) { + LV_LOG_WARN("can't load file: %s", (const char *)dsc->src); + LV_PROFILER_DECODER_END_TAG("lv_svg_decoder_open"); + return LV_RESULT_INVALID; + } + + } + else { + LV_PROFILER_DECODER_END_TAG("lv_svg_decoder_open"); + return LV_RESULT_INVALID; + } + } + else if(dsc->src_type == LV_IMAGE_SRC_VARIABLE) { + const lv_image_dsc_t * img_dsc = dsc->src; + svg_data = (uint8_t *)img_dsc->data; + svg_data_size = (uint32_t)img_dsc->data_size; + } + else { + LV_PROFILER_DECODER_END_TAG("lv_svg_decoder_open"); + return LV_RESULT_INVALID; + } + + lv_svg_node_t * svg_doc = lv_svg_load_data((char *)svg_data, svg_data_size); + lv_svg_render_obj_t * draw_list = lv_svg_render_create(svg_doc); + + if(dsc->src_type == LV_IMAGE_SRC_FILE) { + lv_free(svg_data); + } + lv_svg_node_delete(svg_doc); + + /* create a fake draw_buf object */ + lv_draw_buf_t * draw_buf = lv_zalloc(sizeof(lv_draw_buf_t)); + + draw_buf->header.w = 1; + draw_buf->header.h = 1; + draw_buf->header.cf = LV_COLOR_FORMAT_ARGB8888; + draw_buf->header.flags = LV_IMAGE_FLAGS_ALLOCATED | LV_IMAGE_FLAGS_CUSTOM_DRAW; + draw_buf->header.stride = 4; + draw_buf->header.magic = LV_IMAGE_HEADER_MAGIC; + draw_buf->data = NULL; + draw_buf->unaligned_data = (void *)draw_list; + draw_buf->data_size = lv_svg_render_get_size(draw_list); + draw_buf->handlers = &_svg_draw_buf_handler; + + dsc->decoded = draw_buf; + + if(!dsc->args.no_cache && lv_image_cache_is_enabled()) { + + lv_image_cache_data_t search_key; + search_key.src_type = dsc->src_type; + search_key.src = dsc->src; + search_key.slot.size = dsc->decoded->data_size; + + lv_cache_entry_t * entry = lv_image_decoder_add_to_cache(decoder, &search_key, draw_buf, NULL); + + if(entry == NULL) { + lv_draw_buf_destroy(draw_buf); + LV_PROFILER_DECODER_END_TAG("lv_svg_decoder_open"); + return LV_RESULT_INVALID; + } + dsc->cache_entry = entry; + } + + LV_PROFILER_DECODER_END_TAG("lv_svg_decoder_open"); + return LV_RESULT_OK; +} + +static void svg_decoder_close(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc) +{ + LV_UNUSED(decoder); + + if(dsc->args.no_cache || + !lv_image_cache_is_enabled()) lv_draw_buf_destroy((lv_draw_buf_t *)dsc->decoded); +} + +static uint8_t * alloc_file(const char * filename, uint32_t * size) +{ + uint8_t * data = NULL; + lv_fs_file_t f; + uint32_t data_size; + uint32_t rn; + lv_fs_res_t res; + + *size = 0; + + res = lv_fs_open(&f, filename, LV_FS_MODE_RD); + if(res != LV_FS_RES_OK) { + LV_LOG_WARN("can't open %s", filename); + return NULL; + } + + res = lv_fs_seek(&f, 0, LV_FS_SEEK_END); + if(res != LV_FS_RES_OK) { + goto failed; + } + + res = lv_fs_tell(&f, &data_size); + if(res != LV_FS_RES_OK) { + goto failed; + } + + res = lv_fs_seek(&f, 0, LV_FS_SEEK_SET); + if(res != LV_FS_RES_OK) { + goto failed; + } + + /*Read file to buffer*/ + data = lv_malloc(data_size); + if(data == NULL) { + LV_LOG_WARN("malloc failed for data size %u", data_size); + goto failed; + } + + res = lv_fs_read(&f, data, data_size, &rn); + + if(res == LV_FS_RES_OK && rn == data_size) { + *size = rn; + } + else { + LV_LOG_WARN("read file failed"); + lv_free(data); + data = NULL; + } + +failed: + lv_fs_close(&f); + return data; +} + +static void svg_draw_buf_free(void * svg_buf) +{ + lv_svg_render_obj_t * draw_list = (lv_svg_render_obj_t *)svg_buf; + lv_svg_render_delete(draw_list); +} + +static void svg_draw(lv_layer_t * layer, const lv_image_decoder_dsc_t * dsc, const lv_area_t * coords, + const lv_draw_image_dsc_t * image_dsc, const lv_area_t * clip_area) +{ + const lv_draw_buf_t * draw_buf = dsc->decoded; + const lv_svg_render_obj_t * list = draw_buf->unaligned_data; + + LV_PROFILER_DRAW_BEGIN; + + lv_vector_dsc_t * ctx = lv_vector_dsc_create(layer); + lv_matrix_t matrix; + lv_matrix_identity(&matrix); + lv_matrix_translate(&matrix, coords->x1, coords->y1); + ctx->current_dsc.scissor_area = *clip_area; + if(image_dsc) { + int32_t off_x = (lv_area_get_width(coords) - image_dsc->header.w - 1) / 2; + int32_t off_y = (lv_area_get_height(coords) - image_dsc->header.h - 1) / 2; + + if(image_dsc->pivot.x != 0 || image_dsc->pivot.y != 0) { + lv_matrix_translate(&matrix, off_x, off_y); + } + lv_matrix_translate(&matrix, image_dsc->pivot.x, image_dsc->pivot.y); + lv_matrix_rotate(&matrix, image_dsc->rotation / 10.0f); + lv_matrix_scale(&matrix, image_dsc->scale_x / 256.0f, image_dsc->scale_y / 256.0f); + lv_matrix_translate(&matrix, -image_dsc->pivot.x, -image_dsc->pivot.y); + } + lv_vector_dsc_set_transform(ctx, &matrix); + lv_draw_svg_render(ctx, list); + lv_draw_vector(ctx); + lv_vector_dsc_delete(ctx); + + LV_PROFILER_DRAW_END; +} + +#endif /*LV_USE_SVG*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_decoder.h b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_decoder.h new file mode 100644 index 000000000..b73a64075 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_decoder.h @@ -0,0 +1,51 @@ +/** + * @file lv_svg_decoder.h + * + */ + +#ifndef LV_SVG_DECODER_H +#define LV_SVG_DECODER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_SVG + +#include "../../draw/lv_image_decoder.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Register the SVG decoder functions in LVGL + */ +void lv_svg_decoder_init(void); + +void lv_svg_decoder_deinit(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SVG*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SVG_DECODER_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_parser.c b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_parser.c new file mode 100644 index 000000000..9f720cc7b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_parser.c @@ -0,0 +1,2344 @@ +/** + * @file lv_svg_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_svg_parser.h" +#if LV_USE_SVG + +#include "../../../lvgl.h" +#include +#include +#include +#include + +/********************* +* DEFINES +*********************/ +#ifndef M_PI + #define M_PI 3.1415926f +#endif + +#define MAP_LEN(m) sizeof((m)) / sizeof((m[0])) + +#define CHECK_AND_RESIZE_ATTRS(a) \ + do { \ + if((lv_array_size(&(a)) + 1) > lv_array_capacity(&(a))) { \ + lv_array_resize(&(a), (a).capacity << 1); \ + } \ + } while(0) + +/********************** +* TYPEDEFS +**********************/ +static const struct _lv_svg_tag_map { + const char * name; + uint32_t name_len; + lv_svg_tag_t tag; +} _svg_tag_map[] = { + {"svg", 3, LV_SVG_TAG_SVG}, + {"use", 3, LV_SVG_TAG_USE}, + {"g", 1, LV_SVG_TAG_G}, + {"path", 4, LV_SVG_TAG_PATH}, + {"rect", 4, LV_SVG_TAG_RECT}, + {"circle", 6, LV_SVG_TAG_CIRCLE}, + {"ellipse", 7, LV_SVG_TAG_ELLIPSE}, + {"line", 4, LV_SVG_TAG_LINE}, + {"polyline", 8, LV_SVG_TAG_POLYLINE}, + {"polygon", 7, LV_SVG_TAG_POLYGON}, + {"solidColor", 10, LV_SVG_TAG_SOLID_COLOR}, + {"linearGradient", 14, LV_SVG_TAG_LINEAR_GRADIENT}, + {"radialGradient", 14, LV_SVG_TAG_RADIAL_GRADIENT}, + {"stop", 4, LV_SVG_TAG_STOP}, + {"defs", 4, LV_SVG_TAG_DEFS}, + {"image", 5, LV_SVG_TAG_IMAGE}, +#if LV_USE_SVG_ANIMATION + {"mpath", 5, LV_SVG_TAG_MPATH}, + {"set", 3, LV_SVG_TAG_SET}, + {"animate", 7, LV_SVG_TAG_ANIMATE}, + {"animateColor", 12, LV_SVG_TAG_ANIMATE_COLOR}, + {"animateTransform", 16, LV_SVG_TAG_ANIMATE_TRANSFORM}, + {"animateMotion", 13, LV_SVG_TAG_ANIMATE_MOTION}, +#endif + {"text", 4, LV_SVG_TAG_TEXT}, + {"tspan", 5, LV_SVG_TAG_TSPAN}, + {"textArea", 8, LV_SVG_TAG_TEXT_AREA}, +}; + +static const struct _lv_svg_attr_map { + const char * name; + uint32_t name_len; + lv_svg_attr_type_t attr; +} _svg_attr_map[] = { + {"id", 2, LV_SVG_ATTR_ID}, + {"xml:id", 6, LV_SVG_ATTR_XML_ID}, + {"version", 7, LV_SVG_ATTR_VERSION}, + {"baseProfile", 11, LV_SVG_ATTR_BASE_PROFILE}, + {"viewBox", 7, LV_SVG_ATTR_VIEWBOX}, + {"preserveAspectRatio", 19, LV_SVG_ATTR_PRESERVE_ASPECT_RATIO}, + {"viewport-fill", 13, LV_SVG_ATTR_VIEWPORT_FILL}, + {"viewport-fill-opacity", 21, LV_SVG_ATTR_VIEWPORT_FILL_OPACITY}, + {"display", 7, LV_SVG_ATTR_DISPLAY}, + {"visibility", 10, LV_SVG_ATTR_VISIBILITY}, + {"x", 1, LV_SVG_ATTR_X}, + {"y", 1, LV_SVG_ATTR_Y}, + {"width", 5, LV_SVG_ATTR_WIDTH}, + {"height", 6, LV_SVG_ATTR_HEIGHT}, + {"rx", 2, LV_SVG_ATTR_RX}, + {"ry", 2, LV_SVG_ATTR_RY}, + {"cx", 2, LV_SVG_ATTR_CX}, + {"cy", 2, LV_SVG_ATTR_CY}, + {"r", 1, LV_SVG_ATTR_R}, + {"x1", 2, LV_SVG_ATTR_X1}, + {"y1", 2, LV_SVG_ATTR_Y1}, + {"x2", 2, LV_SVG_ATTR_X2}, + {"y2", 2, LV_SVG_ATTR_Y2}, + {"points", 6, LV_SVG_ATTR_POINTS}, + {"d", 1, LV_SVG_ATTR_D}, + {"pathLength", 10, LV_SVG_ATTR_PATH_LENGTH}, + {"xlink:href", 10, LV_SVG_ATTR_XLINK_HREF}, + {"fill", 4, LV_SVG_ATTR_FILL}, + {"fill-rule", 9, LV_SVG_ATTR_FILL_RULE}, + {"fill-opacity", 12, LV_SVG_ATTR_FILL_OPACITY}, + {"stroke", 6, LV_SVG_ATTR_STROKE}, + {"stroke-width", 12, LV_SVG_ATTR_STROKE_WIDTH}, + {"stroke-linecap", 14, LV_SVG_ATTR_STROKE_LINECAP}, + {"stroke-linejoin", 15, LV_SVG_ATTR_STROKE_LINEJOIN}, + {"stroke-miterlimit", 17, LV_SVG_ATTR_STROKE_MITER_LIMIT}, + {"stroke-dasharray", 16, LV_SVG_ATTR_STROKE_DASH_ARRAY}, + {"stroke-dashoffset", 17, LV_SVG_ATTR_STROKE_DASH_OFFSET}, + {"stroke-opacity", 14, LV_SVG_ATTR_STROKE_OPACITY}, + {"opacity", 7, LV_SVG_ATTR_OPACITY}, + {"solid-color", 11, LV_SVG_ATTR_SOLID_COLOR}, + {"solid-opacity", 13, LV_SVG_ATTR_SOLID_OPACITY}, + {"gradientUnits", 13, LV_SVG_ATTR_GRADIENT_UNITS}, + {"offset", 6, LV_SVG_ATTR_GRADIENT_STOP_OFFSET}, + {"stop-color", 10, LV_SVG_ATTR_GRADIENT_STOP_COLOR}, + {"stop-opacity", 12, LV_SVG_ATTR_GRADIENT_STOP_OPACITY}, + {"font-family", 11, LV_SVG_ATTR_FONT_FAMILY}, + {"font-style", 10, LV_SVG_ATTR_FONT_STYLE}, + {"font-variant", 12, LV_SVG_ATTR_FONT_VARIANT}, + {"font-weight", 11, LV_SVG_ATTR_FONT_WEIGHT}, + {"font-size", 9, LV_SVG_ATTR_FONT_SIZE}, + {"transform", 9, LV_SVG_ATTR_TRANSFORM}, + {"text-anchor", 11, LV_SVG_ATTR_TEXT_ANCHOR}, +#if LV_USE_SVG_ANIMATION + {"attributeName", 13, LV_SVG_ATTR_ATTRIBUTE_NAME}, + {"attributeType", 13, LV_SVG_ATTR_ATTRIBUTE_TYPE}, + {"begin", 5, LV_SVG_ATTR_BEGIN}, + {"end", 3, LV_SVG_ATTR_END}, + {"dur", 3, LV_SVG_ATTR_DUR}, + {"min", 3, LV_SVG_ATTR_MIN}, + {"max", 3, LV_SVG_ATTR_MAX}, + {"restart", 7, LV_SVG_ATTR_RESTART}, + {"repeatCount", 11, LV_SVG_ATTR_REPEAT_COUNT}, + {"repeatDur", 9, LV_SVG_ATTR_REPEAT_DUR}, + {"calcMode", 8, LV_SVG_ATTR_CALC_MODE}, + {"values", 6, LV_SVG_ATTR_VALUES}, + {"keyTimes", 8, LV_SVG_ATTR_KEY_TIMES}, + {"keySplines", 10, LV_SVG_ATTR_KEY_SPLINES}, + {"keyPoints", 9, LV_SVG_ATTR_KEY_POINTS}, + {"from", 4, LV_SVG_ATTR_FROM}, + {"to", 2, LV_SVG_ATTR_TO}, + {"by", 2, LV_SVG_ATTR_BY}, + {"additive", 8, LV_SVG_ATTR_ADDITIVE}, + {"accumulate", 10, LV_SVG_ATTR_ACCUMULATE}, + {"path", 4, LV_SVG_ATTR_PATH}, + {"rotate", 6, LV_SVG_ATTR_ROTATE}, + {"type", 4, LV_SVG_ATTR_TRANSFORM_TYPE}, +#endif +}; + +static const struct _lv_svg_attr_aspect_ratio_map { + const char * name; + uint32_t align; +} _svg_attr_aspect_ratio_map[] = { + {"xMinYMin", LV_SVG_ASPECT_RATIO_XMIN_YMIN}, + {"xMidYMin", LV_SVG_ASPECT_RATIO_XMID_YMIN}, + {"xMaxYMin", LV_SVG_ASPECT_RATIO_XMAX_YMIN}, + {"xMinYMid", LV_SVG_ASPECT_RATIO_XMIN_YMID}, + {"xMidYMid", LV_SVG_ASPECT_RATIO_XMID_YMID}, + {"xMaxYMid", LV_SVG_ASPECT_RATIO_XMAX_YMID}, + {"xMinYMax", LV_SVG_ASPECT_RATIO_XMIN_YMAX}, + {"xMidYMax", LV_SVG_ASPECT_RATIO_XMID_YMAX}, + {"xMaxYMax", LV_SVG_ASPECT_RATIO_XMAX_YMAX}, +}; + +static const struct _lv_svg_color_map { + const char * name; + uint32_t name_len; + uint32_t color; +} _svg_color_map[] = { + {"aliceblue", 9, 0xf0f8ff}, + {"antiquewhite", 12, 0xfaebd7}, + {"aqua", 4, 0x00ffff}, + {"aquamarine", 10, 0x7fffd4}, + {"azure", 5, 0xf0ffff}, + {"beige", 5, 0xf5f5dc}, + {"bisque", 6, 0xffe4c4}, + {"black", 5, 0x000000}, + {"blanchedalmond", 14, 0xffebcd}, + {"blue", 4, 0x0000ff}, + {"blueviolet", 10, 0x8a2be2}, + {"brown", 5, 0xa52a2a}, + {"burlywood", 9, 0xdeb887}, + {"cadetblue", 9, 0x5f9ea0}, + {"chartreuse", 10, 0x7fff00}, + {"chocolate", 9, 0xd2691e}, + {"coral", 5, 0xff7f50}, + {"cornflowerblue", 14, 0x6495ed}, + {"cornsilk", 8, 0xfff8dc}, + {"crimson", 7, 0xdc143c}, + {"cyan", 4, 0x00ffff}, + {"darkblue", 8, 0x00008b}, + {"darkcyan", 8, 0x008b8b}, + {"darkgoldenrod", 13, 0xb8860b}, + {"darkgray", 8, 0xa9a9a9}, + {"darkgrey", 8, 0xa9a9a9}, + {"darkgreen", 9, 0x006400}, + {"darkkhaki", 9, 0xbdb76b}, + {"darkmagenta", 11, 0x8b008b}, + {"darkolivegreen", 14, 0x556b2f}, + {"darkorange", 10, 0xff8c00}, + {"darkorchid", 10, 0x9932cc}, + {"darkred", 7, 0x8b0000}, + {"darksalmon", 10, 0xe9967a}, + {"darkseagreen", 12, 0x8fbc8f}, + {"darkslateblue", 13, 0x483d8b}, + {"darkslategray", 13, 0x2f4f4f}, + {"darkslategrey", 13, 0x2f4f4f}, + {"darkturquoise", 13, 0x00ced1}, + {"darkviolet", 10, 0x9400d3}, + {"deeppink", 8, 0xff1493}, + {"deepskyblue", 11, 0x00bfff}, + {"dimgray", 7, 0x696969}, + {"dimgrey", 7, 0x696969}, + {"dodgerblue", 10, 0x1e90ff}, + {"firebrick", 9, 0xb22222}, + {"floralwhite", 11, 0xfffaf0}, + {"forestgreen", 11, 0x228b22}, + {"fuchsia", 7, 0xff00ff}, + {"gainsboro", 9, 0xdcdcdc}, + {"ghostwhite", 10, 0xf8f8ff}, + {"gold", 4, 0xffd700}, + {"goldenrod", 9, 0xdaa520}, + {"gray", 4, 0x808080}, + {"grey", 4, 0x808080}, + {"green", 5, 0x008000}, + {"greenyellow", 11, 0xadff2f}, + {"honeydew", 8, 0xf0fff0}, + {"hotpink", 7, 0xff69b4}, + {"indianred", 9, 0xcd5c5c}, + {"indigo", 6, 0x4b0082}, + {"ivory", 5, 0xfffff0}, + {"khaki", 5, 0xf0e68c}, + {"lavender", 8, 0xe6e6fa}, + {"lavenderblush", 13, 0xfff0f5}, + {"lawngreen", 9, 0x7cfc00}, + {"lemonchiffon", 12, 0xfffacd}, + {"lightblue", 9, 0xadd8e6}, + {"lightcoral", 10, 0xf08080}, + {"lightcyan", 9, 0xe0ffff}, + {"lightgoldenrodyellow", 20, 0xfafad2}, + {"lightgray", 9, 0xd3d3d3}, + {"lightgrey", 9, 0xd3d3d3}, + {"lightgreen", 10, 0x90ee90}, + {"lightpink", 9, 0xffb6c1}, + {"lightsalmon", 11, 0xffa07a}, + {"lightseagreen", 13, 0x20b2aa}, + {"lightskyblue", 12, 0x87cefa}, + {"lightslategray", 14, 0x778899}, + {"lightslategrey", 14, 0x778899}, + {"lightsteelblue", 14, 0xb0c4de}, + {"lightyellow", 11, 0xffffe0}, + {"lime", 4, 0x00ff00}, + {"limegreen", 9, 0x32cd32}, + {"linen", 5, 0xfaf0e6}, + {"magenta", 7, 0xff00ff}, + {"maroon", 6, 0x800000}, + {"mediumaquamarine", 16, 0x66cdaa}, + {"mediumblue", 10, 0x0000cd}, + {"mediumorchid", 12, 0xba55d3}, + {"mediumpurple", 12, 0x9370d8}, + {"mediumseagreen", 14, 0x3cb371}, + {"mediumslateblue", 15, 0x7b68ee}, + {"mediumspringgreen", 17, 0x00fa9a}, + {"mediumturquoise", 15, 0x48d1cc}, + {"mediumvioletred", 15, 0xc71585}, + {"midnightblue", 12, 0x191970}, + {"mintcream", 9, 0xf5fffa}, + {"mistyrose", 9, 0xffe4e1}, + {"moccasin", 8, 0xffe4b5}, + {"navajowhite", 11, 0xffdead}, + {"navy", 4, 0x000080}, + {"oldlace", 7, 0xfdf5e6}, + {"olive", 5, 0x808000}, + {"olivedrab", 9, 0x6b8e23}, + {"orange", 6, 0xffa500}, + {"orangered", 9, 0xff4500}, + {"orchid", 6, 0xda70d6}, + {"palegoldenrod", 13, 0xeee8aa}, + {"palegreen", 9, 0x98fb98}, + {"paleturquoise", 13, 0xafeeee}, + {"palevioletred", 13, 0xd87093}, + {"papayawhip", 10, 0xffefd5}, + {"peachpuff", 9, 0xffdab9}, + {"peru", 4, 0xcd853f}, + {"pink", 4, 0xffc0cb}, + {"plum", 4, 0xdda0dd}, + {"powderblue", 10, 0xb0e0e6}, + {"purple", 6, 0x800080}, + {"red", 3, 0xff0000}, + {"rosybrown", 9, 0xbc8f8f}, + {"royalblue", 9, 0x4169e1}, + {"saddlebrown", 11, 0x8b4513}, + {"salmon", 6, 0xfa8072}, + {"sandybrown", 10, 0xf4a460}, + {"seagreen", 8, 0x2e8b57}, + {"seashell", 8, 0xfff5ee}, + {"sienna", 6, 0xa0522d}, + {"silver", 6, 0xc0c0c0}, + {"skyblue", 7, 0x87ceeb}, + {"slateblue", 9, 0x6a5acd}, + {"slategray", 9, 0x708090}, + {"slategrey", 9, 0x708090}, + {"snow", 4, 0xfffafa}, + {"springgreen", 11, 0x00ff7f}, + {"steelblue", 9, 0x4682b4}, + {"tan", 3, 0xd2b48c}, + {"teal", 4, 0x008080}, + {"thistle", 7, 0xd8bfd8}, + {"tomato", 6, 0xff6347}, + {"turquoise", 9, 0x40e0d0}, + {"violet", 6, 0xee82ee}, + {"wheat", 5, 0xf5deb3}, + {"white", 5, 0xffffff}, + {"whitesmoke", 10, 0xf5f5f5}, + {"yellow", 6, 0xffff00}, + {"yellowgreen", 11, 0x9acd32}, +}; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static lv_svg_tag_t _get_svg_tag_type(const _lv_svg_token_t * token) +{ + uint32_t len = MAP_LEN(_svg_tag_map); + uint32_t token_len = SVG_TOKEN_LEN(token); + + for(uint32_t i = 0; i < len; i++) { + if(token_len == _svg_tag_map[i].name_len && strncmp(_svg_tag_map[i].name, token->start, token_len) == 0) { + return _svg_tag_map[i].tag; + } + } + return LV_SVG_TAG_INVALID; +} + +static bool _process_end_tag(_lv_svg_parser_t * parser, lv_svg_tag_t tag, const _lv_svg_token_t * token) +{ + if(parser->state == LV_SVG_PARSER_IGNORE) { + uint32_t len = SVG_TOKEN_LEN(token); + if((parser->ignore_len == len) && strncmp(parser->ignore_name, token->start, len) == 0) { + parser->state = LV_SVG_PARSER_PROCESS; + lv_free(parser->ignore_name); + parser->ignore_name = NULL; + parser->ignore_len = 0; + } + return true; + } + + if(parser->cur_node->type != tag) { + LV_LOG_ERROR("svg tag does not match in pairs!"); + return false; + } + + if(parser->cur_node != parser->doc_root) { + parser->cur_node = (lv_svg_node_t *)LV_TREE_NODE(parser->cur_node)->parent; + } + return true; +} + +static lv_svg_attr_type_t _get_svg_attr_type(const char * attr_start, const char * attr_end) +{ + uint32_t len = MAP_LEN(_svg_attr_map); + uint32_t attr_len = attr_end - attr_start; + + for(uint32_t i = 0; i < len; i++) { + if(attr_len == _svg_attr_map[i].name_len && strncmp(_svg_attr_map[i].name, attr_start, attr_len) == 0) { + return _svg_attr_map[i].attr; + } + } + return LV_SVG_ATTR_INVALID; +} + +static void _process_string(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_PTR; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + uint32_t len = val_end - val_start; + char * str = lv_malloc(len + 1); + LV_ASSERT_MALLOC(str); + lv_memcpy(str, val_start, len); + str[len] = '\0'; + attr->value.sval = str; +} + +static void _process_xlink(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_PTR; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + if(*val_start == '#') { + val_start++; + } + + uint32_t len = val_end - val_start; + char * str = lv_malloc(len + 1); + LV_ASSERT_MALLOC(str); + lv_memcpy(str, val_start, len); + str[len] = '\0'; + attr->value.sval = str; +} + +static bool _is_number_begin(char ch) +{ + return ch != 0 && strchr("0123456789+-.", ch) != NULL; +} + +static const char * _skip_space(const char * str, const char * str_end) +{ + while((str < str_end) && isspace(*str)) { + ++str; + } + return str; +} + +static bool _is_separators(char c) +{ + return c == ',' || c == '\t' || c == '\n' || c == '\r'; +} + +static const char * _skip_space_and_separators(const char * str, const char * str_end) +{ + while((str < str_end) && (isspace(*str) || _is_separators(*str))) { + ++str; + } + return str; +} + +static const char * _parse_number(const char * str, const char * str_end, float * val) +{ + if(!str) { + return NULL; + } + // skip loading + while((str < str_end) && !_is_number_begin(*str)) { + ++str; + } + + if(str == str_end) { // parse fail + return NULL; + } + + char * end = NULL; + *val = strtof(str, &end); + return end; +} + +static const char * _parse_length(const char * str, const char * str_end, int32_t dpi, float * val) +{ + str = _parse_number(str, str_end, val); + if(str) { + uint32_t len = str_end - str; + if(len > 0) { + if(len == 1 && (*str == '%')) { + // percentage + *val *= 0.01f; + } + else if(len == 2) { + if(str[0] == 'p' && str[1] == 't') { // pt + *val = *val / 72.0f * (float)dpi; + } + else if(str[0] == 'p' && str[1] == 'c') { // pc + *val = *val / 6.0f * (float)dpi; + } + else if(str[0] == 'i' && str[1] == 'n') { // in + *val = *val * (float)dpi; + } + else if(str[0] == 'm' && str[1] == 'm') { // mm + *val = *val / 25.4f * (float)dpi; + } + else if(str[0] == 'c' && str[1] == 'm') { // cm + *val = *val / 2.54f * (float)dpi; + } + else if(str[0] == 'e' && str[1] == 'm') { // em + *val = *val * 16.0f; // FIXME: browser default font size + } + else if(str[0] == 'e' && str[1] == 'x') { // ex + *val = *val * 16.0f * 0.52f; + } + } + } + str += len; + } + return str; +} + +static const char * _parse_color(const char * str, const char * str_end, uint32_t * val) +{ + if(!str) { + return NULL; + } + + const char * ptr = str; + while((ptr < str_end) && (*ptr != ')')) { // calc letters end + ++ptr; + } + + uint32_t len = ptr - str; + uint8_t r = 0, g = 0, b = 0; + + if(*str == '#') { + if(len == 4) { // three digit hex format '#rgb' + if(isxdigit(str[1]) && isxdigit(str[2]) && isxdigit(str[3])) { + char st[3] = {0}; + st[0] = st[1] = str[1]; + r = (uint8_t)strtol(st, NULL, 16); + st[0] = st[1] = str[2]; + g = (uint8_t)strtol(st, NULL, 16); + st[0] = st[1] = str[3]; + b = (uint8_t)strtol(st, NULL, 16); + } + } + else if(len == 7) { // six digit hex format '#rrggbb' + if(isxdigit(str[1]) && isxdigit(str[2]) && isxdigit(str[3]) + && isxdigit(str[4]) && isxdigit(str[5]) && isxdigit(str[6])) { + char st[3] = {0}; + st[0] = str[1]; + st[1] = str[2]; + r = (uint8_t)strtol(st, NULL, 16); + st[0] = str[3]; + st[1] = str[4]; + g = (uint8_t)strtol(st, NULL, 16); + st[0] = str[5]; + st[1] = str[6]; + b = (uint8_t)strtol(st, NULL, 16); + } + } + // make color + *val = (r << 16) + (g << 8) + b; + } + else if(len > 5 && strncmp(str, "rgba(", 5) == 0) { + str += 5; + bool valid_color = true; + float vals[3] = {0}; + uint8_t alpha = 255; + + for(int i = 0; i < 3; i++) { + str = _parse_number(str, ptr, &vals[i]); + if(!str) valid_color = false; + + if(*str == '%') { + vals[i] *= 2.56f; + } + } + + float a = 0.0f; + str = _parse_number(str, ptr, &a); + if(str) { + if(*str == '%') { + a *= 2.56f; + } + else if(a >= 0.0f && a <= 1.0f) { + a *= 255.0f; + } + alpha = (uint8_t)a; + } + + if(valid_color) { + r = (uint8_t)vals[0]; + g = (uint8_t)vals[1]; + b = (uint8_t)vals[2]; + } + // make color + *val = (alpha << 24) + (r << 16) + (g << 8) + b; + } + else if(len > 4 && strncmp(str, "rgb(", 4) == 0) { + str += 4; + bool valid_color = true; + float vals[3] = {0}; + + for(int i = 0; i < 3; i++) { + str = _parse_number(str, ptr, &vals[i]); + if(!str) valid_color = false; + + if(*str == '%') { + vals[i] *= 2.56f; + } + } + + if(valid_color) { + r = (uint8_t)vals[0]; + g = (uint8_t)vals[1]; + b = (uint8_t)vals[2]; + } + // make color + *val = (r << 16) + (g << 8) + b; + } + else { // color keyword + uint32_t map_len = MAP_LEN(_svg_color_map); + for(uint32_t i = 0; i < map_len; i++) { + if(len == _svg_color_map[i].name_len && strncmp(_svg_color_map[i].name, str, len) == 0) { + *val = _svg_color_map[i].color; + } + } + } + return ++ptr; +} + +static void _multiply_matrix(lv_svg_matrix_t * matrix, const lv_svg_matrix_t * mul) +{ + // TODO: use NEON to optimize this function on ARM architecture. + lv_svg_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_svg_matrix_t)); +} + +static const char * _parse_matrix(const char * str, const char * str_end, lv_svg_transform_type_t type, + lv_svg_matrix_t * matrix) +{ + // skip loading + while((str < str_end) && *str != '(') { + ++str; + } + + if(str == str_end) { // parse fail + return str; + } + + const char * ptr = str; + switch(type) { + case LV_SVG_TRANSFORM_TYPE_MATRIX: { + float vals[6] = {0}; + for(int i = 0; i < 6; i++) { + ptr = _parse_number(ptr, str_end, &vals[i]); + if(!ptr) return str; + str = ptr; + } + + lv_svg_matrix_t mt = {{ + {vals[0], vals[2], vals[4]}, + {vals[1], vals[3], vals[5]}, + {0.0f, 0.0f, 1.0f}, + } + }; + + _multiply_matrix(matrix, &mt); + } + break; + case LV_SVG_TRANSFORM_TYPE_TRANSLATE: { + float tx = 0.0f, ty = 0.0f; + ptr = _parse_number(ptr, str_end, &tx); + if(!ptr) return str; + str = ptr; + + ptr = _skip_space(ptr, str_end); + if(*ptr != ')') { + ptr = _parse_number(ptr, str_end, &ty); + if(ptr) str = ptr; + } + + lv_svg_matrix_t tlm = {{ + {1.0f, 0.0f, tx}, + {0.0f, 1.0f, ty}, + {0.0f, 0.0f, 1.0f}, + } + }; + + _multiply_matrix(matrix, &tlm); + } + break; + case LV_SVG_TRANSFORM_TYPE_ROTATE: { + float degree = 0.0f, cx = 0.0f, cy = 0.0f; + bool trans = false; + + ptr = _parse_number(ptr, str_end, °ree); + if(!ptr) return str; + str = ptr; + + ptr = _skip_space(ptr, str_end); + if(*ptr != ')') { + ptr = _parse_number(ptr, str_end, &cx); + ptr = _parse_number(ptr, str_end, &cy); + if(ptr) { + trans = true; + str = ptr; + } + } + + float radian = degree / 180.0f * (float)M_PI; + float cos_r = cosf(radian); + float sin_r = sinf(radian); + + lv_svg_matrix_t rtm = {{ + {cos_r, -sin_r, 0.0f}, + {sin_r, cos_r, 0.0f}, + {0.0f, 0.0f, 1.0f}, + } + }; + + if(!trans) { + _multiply_matrix(matrix, &rtm); + } + else { + lv_svg_matrix_t tlm = {{ + {1.0f, 0.0f, cx}, + {0.0f, 1.0f, cy}, + {0.0f, 0.0f, 1.0f}, + } + }; + + _multiply_matrix(matrix, &tlm); + _multiply_matrix(matrix, &rtm); + + tlm.m[0][2] = -cx; + tlm.m[1][2] = -cy; + _multiply_matrix(matrix, &tlm); + } + } + break; + case LV_SVG_TRANSFORM_TYPE_SCALE: { + float sx = 0.0f, sy = 0.0f; + ptr = _parse_number(ptr, str_end, &sx); + if(!ptr) return str; + str = ptr; + + sy = sx; + + ptr = _skip_space(ptr, str_end); + if(*ptr != ')') { + ptr = _parse_number(ptr, str_end, &sy); + if(ptr) str = ptr; + } + + lv_svg_matrix_t scm = {{ + {sx, 0.0f, 0.0f}, + {0.0f, sy, 0.0f}, + {0.0f, 0.0f, 1.0f}, + } + }; + + _multiply_matrix(matrix, &scm); + } + break; + case LV_SVG_TRANSFORM_TYPE_SKEW_X: { + float degree = 0.0f; + ptr = _parse_number(ptr, str_end, °ree); + if(!ptr) return str; + str = ptr; + + float radian = degree / 180.0f * (float)M_PI; + float tan = tanf(radian); + + lv_svg_matrix_t skm = {{ + {1.0f, tan, 0.0f}, + {0.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 1.0f}, + } + }; + + _multiply_matrix(matrix, &skm); + } + break; + case LV_SVG_TRANSFORM_TYPE_SKEW_Y: { + float degree = 0.0f; + ptr = _parse_number(ptr, str_end, °ree); + if(!ptr) return str; + str = ptr; + + float radian = degree / 180.0f * (float)M_PI; + float tan = tanf(radian); + + lv_svg_matrix_t skm = {{ + {1.0f, 0.0f, 0.0f}, + {tan, 1.0f, 0.0f}, + {0.0f, 0.0f, 1.0f}, + } + }; + + _multiply_matrix(matrix, &skm); + } + break; + } + return str; +} + +static void _process_view_box(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_PTR; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + uint32_t len = val_end - val_start; + if(len >= 4 && strncmp(val_start, "none", 4) == 0) { + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_NONE; + return; + } + + float * vals = lv_malloc_zeroed(sizeof(float) * 4); + LV_ASSERT_MALLOC(vals); + const char * ptr = val_start; + for(int i = 0; i < 4; i++) { + ptr = _parse_number(ptr, val_end, &vals[i]); + if(!ptr) { + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_NONE; + lv_free(vals); + return; + } + } + attr->value.val = vals; +} + +static void _process_points_value(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_PTR; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + uint32_t list_cap = 4; + lv_svg_attr_values_list_t * list = lv_malloc(sizeof(lv_svg_point_t) * list_cap + sizeof(uint32_t)); + LV_ASSERT_MALLOC(list); + + float val_number = 0.0f; + const char * ptr = val_start; + uint32_t point_cnt = 0; + + while(ptr < val_end) { + if(point_cnt == list_cap) { + list_cap = list_cap << 1; + list = (lv_svg_attr_values_list_t *)lv_realloc(list, sizeof(lv_svg_point_t) * list_cap + sizeof(uint32_t)); + LV_ASSERT_MALLOC(list); + } + lv_svg_point_t * pt = (lv_svg_point_t *)(&list->data) + point_cnt; + val_number = 0.0f; + ptr = _parse_number(ptr, val_end, &val_number); + pt->x = val_number; + val_number = 0.0f; + ptr = _parse_number(ptr, val_end, &val_number); + pt->y = val_number; + if(!ptr) break; + ++point_cnt; + } + + list->length = point_cnt; + attr->value.val = list; +} + +static int _get_path_point_count(char cmd) +{ + switch(cmd) { + case 'M': + case 'm': + case 'L': + case 'l': + case 'H': + case 'h': + case 'V': + case 'v': + case 'Z': + case 'z': + return 1; + case 'C': + case 'c': + case 'S': + case 's': + return 3; + case 'Q': + case 'q': + case 'T': + case 't': + return 2; + default: + return 0; + } +} + +static bool _is_relative_cmd(char cmd) +{ + switch(cmd) { + case 'm': + case 'l': + case 'h': + case 'v': + case 'c': + case 's': + case 'q': + case 't': + case 'z': + return true; + case 'M': + case 'L': + case 'H': + case 'V': + case 'C': + case 'S': + case 'Q': + case 'T': + case 'Z': + default: + return false; + } +} + +static bool _is_path_cmd(char ch) +{ + return ch != 0 && strchr("MLHVCSQTZmlhvcsqtz", ch) != NULL; +} + +static void _process_path_value(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_PTR; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + uint32_t list_cap = 4; + uint32_t list_size = sizeof(lv_svg_point_t) * list_cap + sizeof(uint32_t) * list_cap + sizeof(uint32_t); + lv_svg_attr_values_list_t * list = lv_malloc(list_size); + LV_ASSERT_MALLOC(list); + + uint32_t cmd_cnt = 0; + uint32_t cur_size = 0; + char cur_cmd = 0; + lv_svg_point_t cur_point = {0, 0}; + lv_svg_point_t cur_ctrlPoint = {0, 0}; + lv_svg_point_t first_point = {0, 0}; + + const char * ptr = val_start; + uint8_t * data_ptr = (uint8_t *)(&list->data); + + while(ptr < val_end) { + ptr = _skip_space_and_separators(ptr, val_end); + if(ptr == val_end) break; + + char ch = *ptr; + if(_is_number_begin(ch)) { + if(cur_cmd != 0) { + if(cur_cmd == 'M') { + ch = 'L'; + } + else if(cur_cmd == 'm') { + ch = 'l'; + } + else { + ch = cur_cmd; + } + } + else { + break; + } + } + else if(_is_path_cmd(ch)) { + ++ptr; + } + else { + break; + } + + int point_count = _get_path_point_count(ch); + uint32_t mem_inc = sizeof(lv_svg_point_t) * point_count + sizeof(uint32_t); + + if((cur_size + mem_inc) > (list_size - sizeof(uint32_t))) { + list_cap = list_cap << 1; + list_size = sizeof(lv_svg_point_t) * list_cap + sizeof(uint32_t) * list_cap + sizeof(uint32_t); + list = (lv_svg_attr_values_list_t *)lv_realloc(list, list_size); + LV_ASSERT_MALLOC(list); + } + + data_ptr = (uint8_t *)(&list->data) + cur_size; + lv_svg_attr_path_value_t * path_seg = (lv_svg_attr_path_value_t *)data_ptr; + + bool relative = _is_relative_cmd(ch); + + switch(ch) { + case 'm': + case 'M': { + lv_svg_point_t * point = (lv_svg_point_t *)(&path_seg->data); + float xval = 0.0f; + ptr = _parse_number(ptr, val_end, &xval); + float yval = 0.0f; + ptr = _parse_number(ptr, val_end, &yval); + if(relative) { + xval += cur_point.x; + yval += cur_point.y; + } + path_seg->cmd = LV_SVG_PATH_CMD_MOVE_TO; + point->x = xval; + point->y = yval; + cur_point.x = xval; + cur_point.y = yval; + first_point.x = xval; + first_point.y = yval; + } + break; + case 'L': + case 'l': { + lv_svg_point_t * point = (lv_svg_point_t *)(&path_seg->data); + float xval = 0.0f; + ptr = _parse_number(ptr, val_end, &xval); + float yval = 0.0f; + ptr = _parse_number(ptr, val_end, &yval); + if(relative) { + xval += cur_point.x; + yval += cur_point.y; + } + path_seg->cmd = LV_SVG_PATH_CMD_LINE_TO; + point->x = xval; + point->y = yval; + cur_point.x = xval; + cur_point.y = yval; + } + break; + case 'H': + case 'h': { + lv_svg_point_t * point = (lv_svg_point_t *)(&path_seg->data); + float xval = 0.0f; + ptr = _parse_number(ptr, val_end, &xval); + if(relative) { + xval += cur_point.x; + } + path_seg->cmd = LV_SVG_PATH_CMD_LINE_TO; + point->x = xval; + point->y = cur_point.y; + cur_point.x = xval; + } + break; + case 'V': + case 'v': { + lv_svg_point_t * point = (lv_svg_point_t *)(&path_seg->data); + float yval = 0.0f; + ptr = _parse_number(ptr, val_end, &yval); + if(relative) { + yval += cur_point.y; + } + path_seg->cmd = LV_SVG_PATH_CMD_LINE_TO; + point->x = cur_point.x; + point->y = yval; + cur_point.y = yval; + } + break; + case 'C': + case 'c': { + lv_svg_point_t * point = (lv_svg_point_t *)(&path_seg->data); + for(int i = 0; i < 3; i++) { + float xval = 0.0f; + ptr = _parse_number(ptr, val_end, &xval); + float yval = 0.0f; + ptr = _parse_number(ptr, val_end, &yval); + if(relative) { + xval += cur_point.x; + yval += cur_point.y; + } + path_seg->cmd = LV_SVG_PATH_CMD_CURVE_TO; + point[i].x = xval; + point[i].y = yval; + } + + cur_ctrlPoint.x = point[1].x; + cur_ctrlPoint.y = point[1].y; + cur_point.x = point[2].x; + cur_point.y = point[2].y; + } + break; + case 'S': + case 's': { + lv_svg_point_t * point = (lv_svg_point_t *)(&path_seg->data); + + if(cur_cmd == 'C' || cur_cmd == 'c' || cur_cmd == 'S' || cur_cmd == 's') { + point[0].x = cur_point.x * 2 - cur_ctrlPoint.x; + point[0].y = cur_point.y * 2 - cur_ctrlPoint.y; + } + else { + point[0].x = cur_point.x; + point[0].y = cur_point.y; + } + + for(int i = 1; i < 3; i++) { + float xval = 0.0f; + ptr = _parse_number(ptr, val_end, &xval); + float yval = 0.0f; + ptr = _parse_number(ptr, val_end, &yval); + if(relative) { + xval += cur_point.x; + yval += cur_point.y; + } + path_seg->cmd = LV_SVG_PATH_CMD_CURVE_TO; + point[i].x = xval; + point[i].y = yval; + } + + cur_ctrlPoint.x = point[1].x; + cur_ctrlPoint.y = point[1].y; + cur_point.x = point[2].x; + cur_point.y = point[2].y; + } + break; + case 'Q': + case 'q': { + lv_svg_point_t * point = (lv_svg_point_t *)(&path_seg->data); + for(int i = 0; i < 2; i++) { + float xval = 0.0f; + ptr = _parse_number(ptr, val_end, &xval); + float yval = 0.0f; + ptr = _parse_number(ptr, val_end, &yval); + if(relative) { + xval += cur_point.x; + yval += cur_point.y; + } + path_seg->cmd = LV_SVG_PATH_CMD_QUAD_TO; + point[i].x = xval; + point[i].y = yval; + } + + cur_ctrlPoint.x = point[0].x; + cur_ctrlPoint.y = point[0].y; + cur_point.x = point[1].x; + cur_point.y = point[1].y; + } + break; + case 'T': + case 't': { + lv_svg_point_t * point = (lv_svg_point_t *)(&path_seg->data); + if(cur_cmd == 'Q' || cur_cmd == 'q' || cur_cmd == 'T' || cur_cmd == 't') { + point[0].x = cur_point.x * 2 - cur_ctrlPoint.x; + point[0].y = cur_point.y * 2 - cur_ctrlPoint.y; + } + else { + point[0].x = cur_point.x; + point[0].y = cur_point.y; + } + + for(int i = 1; i < 2; i++) { + float xval = 0.0f; + ptr = _parse_number(ptr, val_end, &xval); + float yval = 0.0f; + ptr = _parse_number(ptr, val_end, &yval); + if(relative) { + xval += cur_point.x; + yval += cur_point.y; + } + path_seg->cmd = LV_SVG_PATH_CMD_QUAD_TO; + point[i].x = xval; + point[i].y = yval; + } + + cur_ctrlPoint.x = point[0].x; + cur_ctrlPoint.y = point[0].y; + cur_point.x = point[1].x; + cur_point.y = point[1].y; + } + break; + case 'Z': + case 'z': { + path_seg->cmd = LV_SVG_PATH_CMD_CLOSE; + cur_point.x = first_point.x; + cur_point.y = first_point.y; + } + break; + } + + if(!ptr) break; + cur_size += mem_inc; + cur_cmd = ch; + ++cmd_cnt; + } + + list->length = cmd_cnt; + attr->value.val = list; +} + +static void _process_gradient_units(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + uint32_t len = val_end - val_start; + int32_t val = 0; + + if(len == 14 && strncmp(val_start, "userSpaceOnUse", 14) == 0) { + val = LV_SVG_GRADIENT_UNITS_USER_SPACE; + } + else { + val = LV_SVG_GRADIENT_UNITS_OBJECT; + } + attr->value.ival = val; +} + +static void _process_paint_dasharray(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + uint32_t len = val_end - val_start; + + if(len >= 4 && strncmp(val_start, "none", 4) == 0) { + attr->class_type = LV_SVG_ATTR_VALUE_NONE; + return; + } + else if(len >= 7 && strncmp(val_start, "inherit", 7) == 0) { + attr->class_type = LV_SVG_ATTR_VALUE_INHERIT; + return; + } + else { + attr->val_type = LV_SVG_ATTR_VALUE_PTR; + + uint32_t list_cap = 4; + lv_svg_attr_values_list_t * list = lv_malloc(sizeof(float) * list_cap + sizeof(uint32_t)); + LV_ASSERT_MALLOC(list); + + uint32_t count = 0; + const char * ptr = val_start; + + while(ptr < val_end) { + if(count == list_cap) { + list_cap = list_cap << 1; + list = lv_realloc(list, sizeof(float) * list_cap + sizeof(uint32_t)); + LV_ASSERT_MALLOC(list); + } + float * val = (float *)(&list->data) + count; + ptr = _parse_number(ptr, val_end, val); + if(!ptr) break; + ++count; + } + + list->length = count; + attr->value.val = list; + } +} + +static void _process_font_attrs(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end, int32_t dpi) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + uint32_t len = val_end - val_start; + + if(len >= 7 && strncmp(val_start, "inherit", 7) == 0) { + attr->class_type = LV_SVG_ATTR_VALUE_INHERIT; + return; + } + + if(type == LV_SVG_ATTR_FONT_SIZE && _is_number_begin(*val_start)) { + float val_number = 0.0f; + val_start = _parse_length(val_start, val_end, dpi, &val_number); + attr->value.fval = val_number; + } + else { + attr->val_type = LV_SVG_ATTR_VALUE_PTR; + + char * str = lv_malloc(len + 1); + LV_ASSERT_MALLOC(str); + lv_memcpy(str, val_start, len); + str[len] = '\0'; + attr->value.sval = str; + } +} + +static void _process_paint_attrs(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + uint32_t len = val_end - val_start; + + if(len >= 7 && strncmp(val_start, "inherit", 7) == 0) { + attr->class_type = LV_SVG_ATTR_VALUE_INHERIT; + return; + } + + if(type == LV_SVG_ATTR_FILL_RULE) { + int32_t val = 0; + if(strncmp(val_start, "evenodd", 7) == 0) { + val = LV_SVG_FILL_EVENODD; + } + else { + val = LV_SVG_FILL_NONZERO; + } + attr->value.ival = val; + } + else if(type == LV_SVG_ATTR_STROKE_LINECAP) { + int32_t val = 0; + if(strncmp(val_start, "round", 5) == 0) { + val = LV_SVG_LINE_CAP_ROUND; + } + else if(strncmp(val_start, "square", 6) == 0) { + val = LV_SVG_LINE_CAP_SQUARE; + } + else { + val = LV_SVG_LINE_CAP_BUTT; + } + attr->value.ival = val; + } + else if(type == LV_SVG_ATTR_STROKE_LINEJOIN) { + int32_t val = 0; + if(strncmp(val_start, "round", 5) == 0) { + val = LV_SVG_LINE_JOIN_ROUND; + } + else if(strncmp(val_start, "bevel", 5) == 0) { + val = LV_SVG_LINE_JOIN_BEVEL; + } + else { + val = LV_SVG_LINE_JOIN_MITER; + } + attr->value.ival = val; + } + else if(type == LV_SVG_ATTR_STROKE_WIDTH) { + float val = 1.0f; + val_start = _parse_number(val_start, val_end, &val); + if(val < 0.0f) { + val = 0.0f; + } + attr->value.fval = val; + } + else if(type == LV_SVG_ATTR_STROKE_MITER_LIMIT) { + float val = 4.0f; + val_start = _parse_number(val_start, val_end, &val); + if(val < 1.0f) { + val = 1.0f; + } + attr->value.ival = (int32_t)val; + } + else if(type == LV_SVG_ATTR_STROKE_DASH_OFFSET) { + float val = 0.0f; + val_start = _parse_number(val_start, val_end, &val); + attr->value.fval = val; + } + else if(type == LV_SVG_ATTR_GRADIENT_STOP_OFFSET) { + float val = 0.0f; + val_start = _parse_number(val_start, val_end, &val); + attr->value.fval = val; + } +} + +static void _process_paint(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + uint32_t len = val_end - val_start; + if(len >= 4 && strncmp(val_start, "none", 4) == 0) { + attr->class_type = LV_SVG_ATTR_VALUE_NONE; + return; + } + else if(len >= 7 && strncmp(val_start, "inherit", 7) == 0) { + attr->class_type = LV_SVG_ATTR_VALUE_INHERIT; + return; + } + else if(len > 4 && strncmp(val_start, "url(", 4) == 0) { + // parse url + const char * ptr = val_start + 4; + const char * url_start = NULL; + const char * url_end = NULL; + + ptr = _skip_space(ptr, val_end); + if(ptr == val_end) { + attr->class_type = LV_SVG_ATTR_VALUE_NONE; + return; + } + + if(*ptr == '#') { + url_start = ptr + 1; + } + + while((ptr < val_end) && !isspace(*ptr) && *ptr != ')') { + ++ptr; + } + + url_end = ptr; + if(url_start && url_end) { + attr->val_type = LV_SVG_ATTR_VALUE_PTR; + len = url_end - url_start; + char * node_id = lv_malloc(len + 1); + LV_ASSERT_MALLOC(node_id); + lv_memcpy(node_id, url_start, len); + node_id[len] = '\0'; + attr->value.sval = node_id; + } + return; + } + else { +#if LV_USE_SVG_ANIMATION + if(len == 6) { + if(strncmp(val_start, "freeze", 6) == 0) { + attr->value.ival = LV_SVG_ANIM_FREEZE; + return; + } + else if(strncmp(val_start, "remove", 6) == 0) { + attr->value.ival = LV_SVG_ANIM_REMOVE; + return; + } + } +#endif + // parse color + uint32_t color = 0; + _parse_color(val_start, val_end, &color); + attr->value.uval = color; + return; + } +} + +static void _process_opacity_value(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + uint32_t len = val_end - val_start; + + if(len >= 7 && strncmp(val_start, "inherit", 7) == 0) { + attr->class_type = LV_SVG_ATTR_VALUE_INHERIT; + return; + } + + float val_number = 1.0f; + val_start = _parse_number(val_start, val_end, &val_number); + + if(val_number < 0.0f) val_number = 0.0f; + else if(val_number > 1.0f) val_number = 1.0f; + + attr->value.fval = val_number; +} + +static void _process_length_value(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end, int32_t dpi) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + float val_number = 0.0f; + val_start = _parse_length(val_start, val_end, dpi, &val_number); + attr->value.fval = val_number; +} + +static void _process_transform(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_PTR; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + uint32_t len = val_end - val_start; + if(len >= 4 && strncmp(val_start, "none", 4) == 0) { + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_NONE; + return; + } + + lv_svg_matrix_t * matrix = lv_malloc_zeroed(sizeof(lv_svg_matrix_t)); + LV_ASSERT_MALLOC(matrix); + matrix->m[0][0] = matrix->m[1][1] = matrix->m[2][2] = 1.0f; // identity + + const char * ptr = val_start; + while(ptr < val_end) { + ptr = _skip_space(ptr, val_end); + if(ptr == val_end) break; + + len = val_end - ptr; + + if(len >= 9 && strncmp(ptr, "translate", 9) == 0) { + ptr = _parse_matrix(ptr, val_end, LV_SVG_TRANSFORM_TYPE_TRANSLATE, matrix); + } + else if(len >= 6 && strncmp(ptr, "matrix", 6) == 0) { + ptr = _parse_matrix(ptr, val_end, LV_SVG_TRANSFORM_TYPE_MATRIX, matrix); + } + else if(len >= 6 && strncmp(ptr, "rotate", 6) == 0) { + ptr = _parse_matrix(ptr, val_end, LV_SVG_TRANSFORM_TYPE_ROTATE, matrix); + } + else if(len >= 5 && strncmp(ptr, "scale", 5) == 0) { + ptr = _parse_matrix(ptr, val_end, LV_SVG_TRANSFORM_TYPE_SCALE, matrix); + } + else if(len >= 5 && strncmp(ptr, "skewX", 5) == 0) { + ptr = _parse_matrix(ptr, val_end, LV_SVG_TRANSFORM_TYPE_SKEW_X, matrix); + } + else if(len >= 5 && strncmp(ptr, "skewY", 5) == 0) { + ptr = _parse_matrix(ptr, val_end, LV_SVG_TRANSFORM_TYPE_SKEW_Y, matrix); + } + + ++ptr; + } + attr->value.val = matrix; +} + +static void _process_preserve_aspect_ratio(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + lv_svg_aspect_ratio_t ratio = LV_SVG_ASPECT_RATIO_XMID_YMID; + uint32_t len = MAP_LEN(_svg_attr_aspect_ratio_map); + + for(uint32_t i = 0; i < len; i++) { + if(strncmp(_svg_attr_aspect_ratio_map[i].name, val_start, 8) == 0) { + ratio = _svg_attr_aspect_ratio_map[i].align; + val_start += 8; + break; + } + else if(strncmp("none", val_start, 4) == 0) { + ratio = LV_SVG_ASPECT_RATIO_NONE; + val_start += 4; + break; + } + } + + if(ratio != LV_SVG_ASPECT_RATIO_NONE) { + len = val_end - val_start; + if(len > 4) { + val_start = _skip_space(val_start, val_end); + if(strncmp(val_start, "meet", 4) == 0) { + ratio |= LV_SVG_ASPECT_RATIO_OPT_MEET; + } + else if(strncmp(val_start, "slice", 5) == 0) { + ratio |= LV_SVG_ASPECT_RATIO_OPT_SLICE; + } + } + } + attr->value.uval = ratio; +} + +#if LV_USE_SVG_ANIMATION +typedef void(*_parse_list_cb)(lv_svg_node_t * node, lv_svg_attr_t * attr, const char * val_start, const char * val_end, + int32_t dpi, void * data); + +static uint32_t _parse_anim_value_list(lv_svg_node_t * node, lv_svg_attr_t * attr, const char * val_start, + const char * val_end, int32_t dpi, _parse_list_cb cb, void * data) +{ + uint32_t count = 0; + val_start = _skip_space(val_start, val_end); + const char * ptr = val_start; + + while(ptr != val_end) { + if(*ptr == ';') { + cb(node, attr, val_start, ptr, dpi, data); + val_start = ++ptr; + val_start = _skip_space(val_start, val_end); + count++; + } + else { + ++ptr; + } + } + if(val_start < val_end) { + cb(node, attr, val_start, ptr, dpi, data); + count++; + } + return count; +} + +static const char * _parse_clock_time(const char * str, const char * str_end, float * val) +{ + str = _parse_number(str, str_end, val); + if(str) { + uint32_t len = str_end - str; + if(len > 0) { + if(len >= 2 && str[0] == 'm' && str[1] == 's') { + *val = roundf(*val); + } + else { + *val = roundf(*val * 1000.0f); + } + } + else { + *val = roundf(*val * 1000.0f); + } + str += len; + return str; + } + *val = roundf(*val * 1000.0f); + return str; +} + +static void _process_clock_time(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + uint32_t len = val_end - val_start; + if(len == 10 && strncmp(val_start, "indefinite", 10) == 0) { + attr->value.fval = 0.0f; + return; + } + + float val_number = 0.0f; + val_start = _parse_clock_time(val_start, val_end, &val_number); + attr->value.fval = val_number; // ms +} + +static void _process_anim_attr_number(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + if(type == LV_SVG_ATTR_REPEAT_COUNT) { + uint32_t len = val_end - val_start; + if(len == 10 && strncmp(val_start, "indefinite", 10) == 0) { + attr->value.uval = 0; + return; + } + + float val_number = 0.0f; + val_start = _parse_number(val_start, val_end, &val_number); + attr->value.uval = (uint32_t)val_number; + } + else { // LV_SVG_ATTR_ROTATE + uint32_t len = val_end - val_start; + if(len == 4 && strncmp(val_start, "auto", 4) == 0) { + attr->class_type = + LV_SVG_ATTR_VALUE_INHERIT; // rotated over time by the angle of the direction (i.e., directional tangent vector) of the motion path + attr->value.fval = 0.0f; + return; + } + else if(len == 12 && strncmp(val_start, "auto-reverse", 12) == 0) { + attr->class_type = + LV_SVG_ATTR_VALUE_INHERIT; // rotated over time by the angle of the direction (i.e., directional tangent vector) of the motion path plus 180 degrees. + attr->value.fval = 180.0f; + return; + } + + float val_number = 0.0f; + val_start = _parse_number(val_start, val_end, &val_number); + attr->value.fval = val_number; + } +} + +static void _process_anim_attr_names(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + attr->value.ival = _get_svg_attr_type(val_start, val_end); +} + +static void _process_anim_attr_options(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + uint32_t len = val_end - val_start; + switch(type) { + case LV_SVG_ATTR_RESTART: { + if(len == 6 && strncmp(val_start, "always", 6) == 0) { + attr->value.ival = LV_SVG_ANIM_RESTART_ALWAYS; + return; + } + else if(len == 13 && strncmp(val_start, "whenNotActive", 13) == 0) { + attr->value.ival = LV_SVG_ANIM_RESTART_WHEN_NOT_ACTIVE; + return; + } + else if(len == 5 && strncmp(val_start, "never", 5) == 0) { + attr->value.ival = LV_SVG_ANIM_RESTART_NEVER; + return; + } + } + break; + case LV_SVG_ATTR_CALC_MODE: { + if(len == 6 && strncmp(val_start, "linear", 6) == 0) { + attr->value.ival = LV_SVG_ANIM_CALC_MODE_LINEAR; + return; + } + else if(len == 5 && strncmp(val_start, "paced", 5) == 0) { + attr->value.ival = LV_SVG_ANIM_CALC_MODE_PACED; + return; + } + else if(len == 6 && strncmp(val_start, "spline", 6) == 0) { + attr->value.ival = LV_SVG_ANIM_CALC_MODE_SPLINE; + return; + } + else if(len == 8 && strncmp(val_start, "discrete", 8) == 0) { + attr->value.ival = LV_SVG_ANIM_CALC_MODE_DISCRETE; + return; + } + } + break; + case LV_SVG_ATTR_ADDITIVE: { + if(len == 7 && strncmp(val_start, "replace", 7) == 0) { + attr->value.ival = LV_SVG_ANIM_ADDITIVE_REPLACE; + return; + } + else if(len == 3 && strncmp(val_start, "sum", 3) == 0) { + attr->value.ival = LV_SVG_ANIM_ADDITIVE_SUM; + return; + } + } + break; + case LV_SVG_ATTR_ACCUMULATE: { + if(len == 4 && strncmp(val_start, "none", 4) == 0) { + attr->value.ival = LV_SVG_ANIM_ACCUMULATE_NONE; + return; + } + else if(len == 3 && strncmp(val_start, "sum", 3) == 0) { + attr->value.ival = LV_SVG_ANIM_ACCUMULATE_SUM; + return; + } + } + break; + case LV_SVG_ATTR_TRANSFORM_TYPE: { + if(len == 9 && strncmp(val_start, "translate", 9) == 0) { + attr->value.ival = LV_SVG_TRANSFORM_TYPE_TRANSLATE; + return; + } + else if(len == 5 && strncmp(val_start, "scale", 5) == 0) { + attr->value.ival = LV_SVG_TRANSFORM_TYPE_SCALE; + return; + } + else if(len == 6 && strncmp(val_start, "rotate", 6) == 0) { + attr->value.ival = LV_SVG_TRANSFORM_TYPE_ROTATE; + return; + } + else if(len == 5 && strncmp(val_start, "skewX", 5) == 0) { + attr->value.ival = LV_SVG_TRANSFORM_TYPE_SKEW_X; + return; + } + else if(len == 5 && strncmp(val_start, "skewY", 5) == 0) { + attr->value.ival = LV_SVG_TRANSFORM_TYPE_SKEW_Y; + return; + } + } + break; + } + attr->value.ival = 0; +} + +static void _parse_anim_value(lv_svg_node_t * node, lv_svg_attr_t * attr, const char * val_start, const char * val_end, + int32_t dpi) +{ + if(node->type == LV_SVG_TAG_ANIMATE || node->type == LV_SVG_TAG_SET) { + float val_number = 0.0f; + val_start = _parse_length(val_start, val_end, dpi, &val_number); + attr->value.fval = val_number; + } + else if(node->type == LV_SVG_TAG_ANIMATE_COLOR) { + uint32_t color = 0; + val_start = _parse_color(val_start, val_end, &color); + attr->value.uval = color; + } + else if(node->type == LV_SVG_TAG_ANIMATE_TRANSFORM) { + attr->val_type = LV_SVG_ATTR_VALUE_PTR; + lv_svg_attr_values_list_t * list = lv_malloc(sizeof(float) * 4 + sizeof(uint32_t)); + LV_ASSERT_MALLOC(list); + + float val_number = 0.0f; + uint32_t cnt = 0; + const char * ptr = val_start; + + while((ptr < val_end) && (cnt < 3)) { + float * val = (float *)(&list->data) + cnt; + + val_number = 0.0f; + ptr = _parse_number(ptr, val_end, &val_number); + *val = val_number; + + if(!ptr) break; + ++cnt; + } + + list->length = cnt; + attr->value.val = list; + } + else if(node->type == LV_SVG_TAG_ANIMATE_MOTION) { + attr->val_type = LV_SVG_ATTR_VALUE_PTR; + lv_svg_attr_values_list_t * list = lv_malloc(sizeof(lv_svg_point_t) + sizeof(uint32_t)); + LV_ASSERT_MALLOC(list); + + lv_svg_point_t * pt = (lv_svg_point_t *)(&list->data); + + float val_number = 0.0f; + val_start = _parse_number(val_start, val_end, &val_number); + pt->x = val_number; + val_number = 0.0f; + val_start = _parse_number(val_start, val_end, &val_number); + pt->y = val_number; + + list->length = 1; + attr->value.val = list; + } +} + +struct _parse_value_list_context { + uint32_t mem_size; + uint32_t list_count; + lv_svg_attr_values_list_t * list; +}; + +struct _transform_values_list { + uint32_t length; + float data[4]; +}; + +#define GET_NEXT_VALUE_PTR(ptr, ctx, type) \ + do { \ + lv_svg_attr_values_list_t * list = ctx->list; \ + if(!list) { \ + ctx->mem_size = sizeof(type) * 4 + sizeof(uint32_t);\ + ctx->list = lv_malloc_zeroed(ctx->mem_size); \ + LV_ASSERT_MALLOC(ctx->list); \ + ptr = (type *)(&(ctx->list->data)); \ + ctx->list_count = 1; \ + } else { \ + uint32_t mem = sizeof(type) * (ctx->list_count + 1) + sizeof(uint32_t); \ + if(ctx->mem_size < mem) { \ + ctx->mem_size = (ctx->list_count << 1) * sizeof(type) + sizeof(uint32_t); \ + ctx->list = (lv_svg_attr_values_list_t *)lv_realloc(ctx->list, ctx->mem_size); \ + LV_ASSERT_MALLOC(ctx->list); \ + } \ + ptr = (type *)(&(ctx->list->data)) + ctx->list_count; \ + ctx->list_count++; \ + } \ + } while(0) + +static void _anim_values_cb(lv_svg_node_t * node, lv_svg_attr_t * attr, const char * val_start, const char * val_end, + int32_t dpi, void * data) +{ + LV_UNUSED(attr); + struct _parse_value_list_context * ctx = (struct _parse_value_list_context *)data; + + if(node->type == LV_SVG_TAG_ANIMATE || node->type == LV_SVG_TAG_SET) { + float * val_number = NULL; + GET_NEXT_VALUE_PTR(val_number, ctx, float); + val_start = _parse_length(val_start, val_end, dpi, val_number); + } + else if(node->type == LV_SVG_TAG_ANIMATE_COLOR) { + uint32_t * color = NULL; + GET_NEXT_VALUE_PTR(color, ctx, uint32_t); + val_start = _parse_color(val_start, val_end, color); + } + else if(node->type == LV_SVG_TAG_ANIMATE_TRANSFORM) { + struct _transform_values_list * trans_vals = NULL; + GET_NEXT_VALUE_PTR(trans_vals, ctx, struct _transform_values_list); + + uint32_t cnt = 0; + const char * ptr = val_start; + + while((ptr < val_end) && (cnt < 3)) { + float * val = &(trans_vals->data[cnt]); + ptr = _parse_number(ptr, val_end, val); + if(!ptr) break; + ++cnt; + } + + trans_vals->length = cnt; + } + else if(node->type == LV_SVG_TAG_ANIMATE_MOTION) { + lv_svg_point_t * point = NULL; + GET_NEXT_VALUE_PTR(point, ctx, lv_svg_point_t); + val_start = _parse_number(val_start, val_end, &point->x); + val_start = _parse_number(val_start, val_end, &point->y); + } + ctx->list->length = ctx->list_count; +} + +static void _anim_keys_cb(lv_svg_node_t * node, lv_svg_attr_t * attr, const char * val_start, const char * val_end, + int32_t dpi, void * data) +{ + LV_UNUSED(node); + LV_UNUSED(attr); + LV_UNUSED(dpi); + struct _parse_value_list_context * ctx = (struct _parse_value_list_context *)data; + + float * val_number = NULL; + GET_NEXT_VALUE_PTR(val_number, ctx, float); + val_start = _parse_number(val_start, val_end, val_number); + + ctx->list->length = ctx->list_count; +} + +static void _anim_key_splines_cb(lv_svg_node_t * node, lv_svg_attr_t * attr, const char * val_start, + const char * val_end, int32_t dpi, void * data) +{ + LV_UNUSED(node); + LV_UNUSED(attr); + LV_UNUSED(dpi); + struct _parse_value_list_context * ctx = (struct _parse_value_list_context *)data; + + lv_svg_point_t * point = NULL; + GET_NEXT_VALUE_PTR(point, ctx, lv_svg_point_t); + val_start = _parse_number(val_start, val_end, &point->x); + val_start = _parse_number(val_start, val_end, &point->y); + + GET_NEXT_VALUE_PTR(point, ctx, lv_svg_point_t); + val_start = _parse_number(val_start, val_end, &point->x); + val_start = _parse_number(val_start, val_end, &point->y); + + ctx->list->length = ctx->list_count; +} + +static void _anim_begin_end_cb(lv_svg_node_t * node, lv_svg_attr_t * attr, const char * val_start, + const char * val_end, int32_t dpi, void * data) +{ + LV_UNUSED(node); + LV_UNUSED(attr); + LV_UNUSED(dpi); + struct _parse_value_list_context * ctx = (struct _parse_value_list_context *)data; + + // offset-value + float * val_number = NULL; + GET_NEXT_VALUE_PTR(val_number, ctx, float); + val_start = _parse_clock_time(val_start, val_end, val_number); + + //FIXME: not support begin-end type + // syncbase-value + // event-value + // repeat-value + // accessKey-value + // indefinite + + ctx->list->length = ctx->list_count; +} + +static void _process_anim_attr_values(lv_svg_node_t * node, lv_svg_attr_type_t type, const char * val_start, + const char * val_end, int32_t dpi) +{ + CHECK_AND_RESIZE_ATTRS(node->attrs); + + node->attrs.size++; + lv_svg_attr_t * attr = lv_array_at(&node->attrs, node->attrs.size - 1); + attr->id = type; + attr->val_type = LV_SVG_ATTR_VALUE_DATA; + attr->class_type = LV_SVG_ATTR_VALUE_INITIAL; + + if(type == LV_SVG_ATTR_VALUES) { + attr->val_type = LV_SVG_ATTR_VALUE_PTR; + struct _parse_value_list_context ctx = {.mem_size = 0, .list_count = 0, .list = NULL}; + _parse_anim_value_list(node, attr, val_start, val_end, dpi, _anim_values_cb, &ctx); + attr->value.val = ctx.list; + } + else if(type == LV_SVG_ATTR_KEY_TIMES || type == LV_SVG_ATTR_KEY_POINTS) { + attr->val_type = LV_SVG_ATTR_VALUE_PTR; + struct _parse_value_list_context ctx = {.mem_size = 0, .list_count = 0, .list = NULL}; + _parse_anim_value_list(node, attr, val_start, val_end, dpi, _anim_keys_cb, &ctx); + attr->value.val = ctx.list; + } + else if(type == LV_SVG_ATTR_KEY_SPLINES) { + attr->val_type = LV_SVG_ATTR_VALUE_PTR; + struct _parse_value_list_context ctx = {.mem_size = 0, .list_count = 0, .list = NULL}; + _parse_anim_value_list(node, attr, val_start, val_end, dpi, _anim_key_splines_cb, &ctx); + attr->value.val = ctx.list; + } + else if(type == LV_SVG_ATTR_BEGIN || type == LV_SVG_ATTR_END) { + attr->val_type = LV_SVG_ATTR_VALUE_PTR; + struct _parse_value_list_context ctx = {.mem_size = 0, .list_count = 0, .list = NULL}; + _parse_anim_value_list(node, attr, val_start, val_end, dpi, _anim_begin_end_cb, &ctx); + attr->value.val = ctx.list; + } + else { + _parse_anim_value(node, attr, val_start, val_end, dpi); + } +} + +#endif + +static void _process_attrs_tag(_lv_svg_parser_t * parser, lv_svg_node_t * node, const _lv_svg_token_t * token) +{ + uint32_t len = lv_array_size(&token->attrs); + for(uint32_t i = 0; i < len; i++) { + _lv_svg_token_attr_t * tok_attr = lv_array_at(&token->attrs, i); + lv_svg_attr_type_t type = _get_svg_attr_type(tok_attr->name_start, tok_attr->name_end); + + tok_attr->value_start = _skip_space(tok_attr->value_start, tok_attr->value_end); + uint32_t value_len = tok_attr->value_end - tok_attr->value_start; + if(value_len == 0) { + continue; // skip empty value attribute + } + + if(type == LV_SVG_ATTR_XML_ID || type == LV_SVG_ATTR_ID) { // get xml:id + char * str = lv_malloc(value_len + 1); + LV_ASSERT_MALLOC(str); + lv_memcpy(str, tok_attr->value_start, value_len); + str[value_len] = '\0'; + node->xml_id = str; + continue; + } + + switch(type) { + case LV_SVG_ATTR_VERSION: + case LV_SVG_ATTR_BASE_PROFILE: + _process_string(node, type, tok_attr->value_start, tok_attr->value_end); + break; + case LV_SVG_ATTR_VIEWBOX: + _process_view_box(node, type, tok_attr->value_start, tok_attr->value_end); + break; + case LV_SVG_ATTR_PRESERVE_ASPECT_RATIO: + _process_preserve_aspect_ratio(node, type, tok_attr->value_start, tok_attr->value_end); + break; + case LV_SVG_ATTR_X: + case LV_SVG_ATTR_Y: + case LV_SVG_ATTR_WIDTH: + case LV_SVG_ATTR_HEIGHT: + case LV_SVG_ATTR_RX: + case LV_SVG_ATTR_RY: + case LV_SVG_ATTR_CX: + case LV_SVG_ATTR_CY: + case LV_SVG_ATTR_R: + case LV_SVG_ATTR_X1: + case LV_SVG_ATTR_Y1: + case LV_SVG_ATTR_X2: + case LV_SVG_ATTR_Y2: + case LV_SVG_ATTR_PATH_LENGTH: + _process_length_value(node, type, tok_attr->value_start, tok_attr->value_end, parser->dpi); + break; + case LV_SVG_ATTR_OPACITY: + case LV_SVG_ATTR_FILL_OPACITY: + case LV_SVG_ATTR_STROKE_OPACITY: + case LV_SVG_ATTR_SOLID_OPACITY: + case LV_SVG_ATTR_VIEWPORT_FILL_OPACITY: + case LV_SVG_ATTR_GRADIENT_STOP_OPACITY: + _process_opacity_value(node, type, tok_attr->value_start, tok_attr->value_end); + break; + case LV_SVG_ATTR_POINTS: + _process_points_value(node, type, tok_attr->value_start, tok_attr->value_end); + break; + case LV_SVG_ATTR_D: +#if LV_USE_SVG_ANIMATION + case LV_SVG_ATTR_PATH: +#endif + _process_path_value(node, type, tok_attr->value_start, tok_attr->value_end); + break; + case LV_SVG_ATTR_TRANSFORM: + _process_transform(node, type, tok_attr->value_start, tok_attr->value_end); + break; + case LV_SVG_ATTR_FILL: + case LV_SVG_ATTR_STROKE: + case LV_SVG_ATTR_VIEWPORT_FILL: + case LV_SVG_ATTR_SOLID_COLOR: + case LV_SVG_ATTR_GRADIENT_STOP_COLOR: + _process_paint(node, type, tok_attr->value_start, tok_attr->value_end); + break; + case LV_SVG_ATTR_FILL_RULE: + case LV_SVG_ATTR_STROKE_LINECAP: + case LV_SVG_ATTR_STROKE_LINEJOIN: + case LV_SVG_ATTR_STROKE_WIDTH: + case LV_SVG_ATTR_STROKE_MITER_LIMIT: + case LV_SVG_ATTR_STROKE_DASH_OFFSET: + case LV_SVG_ATTR_GRADIENT_STOP_OFFSET: + _process_paint_attrs(node, type, tok_attr->value_start, tok_attr->value_end); + break; + case LV_SVG_ATTR_STROKE_DASH_ARRAY: + _process_paint_dasharray(node, type, tok_attr->value_start, tok_attr->value_end); + break; + case LV_SVG_ATTR_GRADIENT_UNITS: + _process_gradient_units(node, type, tok_attr->value_start, tok_attr->value_end); + break; + case LV_SVG_ATTR_FONT_FAMILY: + case LV_SVG_ATTR_FONT_STYLE: + case LV_SVG_ATTR_FONT_VARIANT: + case LV_SVG_ATTR_FONT_WEIGHT: + case LV_SVG_ATTR_FONT_SIZE: + _process_font_attrs(node, type, tok_attr->value_start, tok_attr->value_end, parser->dpi); + break; + case LV_SVG_ATTR_XLINK_HREF: + _process_xlink(node, type, tok_attr->value_start, tok_attr->value_end); + break; +#if LV_USE_SVG_ANIMATION + case LV_SVG_ATTR_DUR: + case LV_SVG_ATTR_MIN: + case LV_SVG_ATTR_MAX: + case LV_SVG_ATTR_REPEAT_DUR: + _process_clock_time(node, type, tok_attr->value_start, tok_attr->value_end); + break; + case LV_SVG_ATTR_ATTRIBUTE_NAME: + _process_anim_attr_names(node, type, tok_attr->value_start, tok_attr->value_end); + break; + case LV_SVG_ATTR_FROM: + case LV_SVG_ATTR_TO: + case LV_SVG_ATTR_BY: + case LV_SVG_ATTR_VALUES: + case LV_SVG_ATTR_KEY_TIMES: + case LV_SVG_ATTR_KEY_POINTS: + case LV_SVG_ATTR_KEY_SPLINES: + case LV_SVG_ATTR_BEGIN: + case LV_SVG_ATTR_END: + _process_anim_attr_values(node, type, tok_attr->value_start, tok_attr->value_end, parser->dpi); + break; + case LV_SVG_ATTR_ROTATE: + case LV_SVG_ATTR_REPEAT_COUNT: + _process_anim_attr_number(node, type, tok_attr->value_start, tok_attr->value_end); + break; + case LV_SVG_ATTR_RESTART: + case LV_SVG_ATTR_CALC_MODE: + case LV_SVG_ATTR_ADDITIVE: + case LV_SVG_ATTR_ACCUMULATE: + case LV_SVG_ATTR_TRANSFORM_TYPE: + _process_anim_attr_options(node, type, tok_attr->value_start, tok_attr->value_end); + break; + case LV_SVG_ATTR_ATTRIBUTE_TYPE: +#endif + case LV_SVG_ATTR_DISPLAY: + case LV_SVG_ATTR_VISIBILITY: + case LV_SVG_ATTR_TEXT_ANCHOR: + // not support yet + break; + } + } +} + +static bool _process_begin_tag(_lv_svg_parser_t * parser, lv_svg_tag_t tag, const _lv_svg_token_t * token) +{ + if(parser->state == LV_SVG_PARSER_IGNORE) { + // ignore ignored tokens + return true; + } + + if(token->type == LV_SVG_TOKEN_CONTENT) { + uint32_t len = SVG_TOKEN_LEN(token); + char * content = lv_malloc(len + 1); + LV_ASSERT_MALLOC(content); + lv_memcpy(content, token->start, len); + content[len] = '\0'; + lv_svg_node_t * node = lv_svg_node_create(parser->cur_node); + node->xml_id = content; + node->type = LV_SVG_TAG_CONTENT; + return true; + } + + // begin invalid tag + if(tag == LV_SVG_TAG_INVALID) { + if(!token->flat) { + parser->state = LV_SVG_PARSER_IGNORE; + uint32_t len = SVG_TOKEN_LEN(token); + parser->ignore_name = lv_malloc(len + 1); + LV_ASSERT_MALLOC(parser->ignore_name); + parser->ignore_len = len; + lv_memcpy(parser->ignore_name, token->start, len); + parser->ignore_name[len] = '\0'; + } + return true; + } + + // create new node + lv_svg_node_t * node = lv_svg_node_create(parser->cur_node); + node->type = tag; + _process_attrs_tag(parser, node, token); + + if(!parser->doc_root) { // root node + parser->doc_root = node; + } + if(!token->flat) { // FIXME: not leaf node + parser->cur_node = node; + } + return true; +} + +/********************** + * GLOBAL FUNCTIONS + **********************/ +void _lv_svg_parser_init(_lv_svg_parser_t * parser) +{ + LV_ASSERT_NULL(parser); + lv_memzero(parser, sizeof(_lv_svg_parser_t)); + parser->state = LV_SVG_PARSER_PROCESS; + parser->ignore_name = NULL; + parser->ignore_len = 0; + parser->dpi = 96; // FIXME: Is it right ? + parser->doc_root = NULL; + parser->cur_node = NULL; +} + +void _lv_svg_parser_deinit(_lv_svg_parser_t * parser) +{ + LV_ASSERT_NULL(parser); + if(parser->ignore_name) { + lv_free(parser->ignore_name); + parser->ignore_name = NULL; + parser->ignore_len = 0; + } + + if(parser->doc_root) { + lv_svg_node_delete(parser->doc_root); + } + parser->doc_root = parser->cur_node = NULL; +} + +bool _lv_svg_parser_is_finish(_lv_svg_parser_t * parser) +{ + LV_ASSERT_NULL(parser); + return (parser->doc_root != NULL) + && (parser->cur_node == parser->doc_root) + && (parser->state != LV_SVG_PARSER_IGNORE); +} + +bool _lv_svg_parser_token(_lv_svg_parser_t * parser, const _lv_svg_token_t * token) +{ + LV_ASSERT_NULL(parser); + LV_ASSERT_NULL(token); + lv_svg_tag_t tag = _get_svg_tag_type(token); + + if(parser->doc_root == NULL) { + if(!(tag == LV_SVG_TAG_SVG && token->type == LV_SVG_TOKEN_BEGIN)) { + LV_LOG_ERROR("root element in svg document must be !"); + return false; + } + } + + if(token->type == LV_SVG_TOKEN_END) { + return _process_end_tag(parser, tag, token); + } + + return _process_begin_tag(parser, tag, token); +} + +#if LV_USE_SVG_DEBUG +#include +void _lv_svg_dump_tree(lv_svg_node_t * root, int depth) +{ + if(!root) { + return; + } + + for(int i = 0; i < depth; i++) { + printf(" "); + } + if(root->type == LV_SVG_TAG_CONTENT) { + printf("content: [%s]\n", root->xml_id); + } + else { + printf("tag <%s>", _svg_tag_map[root->type - 1].name); + if(root->xml_id) { + printf(" - id [%s]", root->xml_id); + } + printf("\n"); + } + + uint32_t len = lv_array_size(&root->attrs); + for(uint32_t i = 0; i < len; i++) { + for(int j = 0; j < depth; j++) { + printf(" "); + } + lv_svg_attr_t * attr = lv_array_at(&root->attrs, i); + printf(" attr <%s>\n", _svg_attr_map[attr->id - 1].name); + } + + lv_tree_node_t * tree_root = (lv_tree_node_t *)root; + + for(uint32_t i = 0; i < tree_root->child_cnt; i++) { + ++depth; + _lv_svg_dump_tree((lv_svg_node_t *)tree_root->children[i], depth); + --depth; + } +} +#endif /*LV_USE_SVG_DEBUG*/ + +/********************** + * STATIC FUNCTIONS + **********************/ +#endif /*LV_USE_SVG*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_parser.h b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_parser.h new file mode 100644 index 000000000..fc99fe8bd --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_parser.h @@ -0,0 +1,84 @@ +/** + * @file lv_svg_parser.h + * + */ + +#ifndef LV_SVG_PARSER_H +#define LV_SVG_PARSER_H + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_SVG + +#include "lv_svg.h" +#include "lv_svg_token.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_SVG_PARSER_PROCESS = 0, + LV_SVG_PARSER_IGNORE, +} _lv_svg_parser_state_t; + +typedef struct { + uint16_t state; + char * ignore_name; + uint32_t ignore_len; + int32_t dpi; + lv_svg_node_t * doc_root; + lv_svg_node_t * cur_node; +} _lv_svg_parser_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * @brief Initialize the SVG parser + * @param parser pointer to a parser object + */ +void _lv_svg_parser_init(_lv_svg_parser_t * parser); + +/** + * @brief Deinitialize the SVG parser + * @param parser pointer to a parser object + */ +void _lv_svg_parser_deinit(_lv_svg_parser_t * parser); + +/** + * @brief Parse an SVG document + * @param parser pointer to a parser object + * @param token pointer to a token object + * @return true: the parsing is finished, false: the parsing is not finished yet. + */ +bool _lv_svg_parser_token(_lv_svg_parser_t * parser, const _lv_svg_token_t * token); + +/** + * @brief Check if the parsing is finished + * @param parser pointer to a parser object + * @return true: the parsing is finished, false: the parsing is not finished yet. + */ +bool _lv_svg_parser_is_finish(_lv_svg_parser_t * parser); + +/** + * @brief Dump the SVG tree + * @param root pointer to the root of the SVG tree + * @param depth the depth of the current node in the tree + */ +void _lv_svg_dump_tree(lv_svg_node_t * root, int depth); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SVG*/ + +#endif /*LV_SVG_PARSER_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_render.c b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_render.c new file mode 100644 index 000000000..478804f64 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_render.c @@ -0,0 +1,2486 @@ +/** + * @file lv_svg_render.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "../../../lvgl.h" +#include "lv_svg_render.h" +#if LV_USE_SVG + +#include "../../misc/lv_text_private.h" +#include +#include + +#if LV_USE_FREETYPE + #include "../../libs/freetype/lv_freetype_private.h" +#endif + +/********************* +* DEFINES +*********************/ +#ifndef M_PI + #define M_PI 3.1415926f +#endif + +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define ABS(a) fabsf(a) + +#define CALC_BOUNDS(p, bounds) \ + do { \ + if((p).x < (bounds).x1) (bounds).x1 = (int32_t)(p).x; \ + if((p).y < (bounds).y1) (bounds).y1 = (int32_t)(p).y; \ + if((p).x > (bounds).x2) (bounds).x2 = (int32_t)(p).x; \ + if((p).y > (bounds).y2) (bounds).y2 = (int32_t)(p).y; \ + } while(0) + +#define PCT_TO_PX(v, base) ((v) > 1 ? (v) : ((v) * (base))) + +enum { + _RENDER_NORMAL = 0, + _RENDER_IN_DEFS = 1, + _RENDER_IN_GROUP = 2, +}; + +enum { + _RENDER_ATTR_FILL = (4 << 1), + _RENDER_ATTR_FILL_RULE = (4 << 2), + _RENDER_ATTR_FILL_OPACITY = (4 << 3), + _RENDER_ATTR_STROKE = (4 << 4), + _RENDER_ATTR_STROKE_OPACITY = (4 << 5), + _RENDER_ATTR_STROKE_WIDTH = (4 << 6), + _RENDER_ATTR_STROKE_LINECAP = (4 << 7), + _RENDER_ATTR_STROKE_LINEJOIN = (4 << 8), + _RENDER_ATTR_STROKE_MITER_LIMIT = (4 << 9), + _RENDER_ATTR_STROKE_DASH_ARRAY = (4 << 10), +}; + +/********************** +* TYPEDEFS +**********************/ +static void _set_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr); +static void _init_draw_dsc(lv_vector_draw_dsc_t * dsc); +static void _deinit_draw_dsc(lv_vector_draw_dsc_t * dsc); +static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_t * src); +static void _prepare_render(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc); +static void _special_render(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc); +#if LV_USE_FREETYPE + static void _freetype_outline_cb(lv_event_t * e); +#endif + +typedef struct { + lv_svg_render_obj_t base; + float width; + float height; + bool viewport_fill; +} lv_svg_render_viewport_t; + +typedef struct { + lv_svg_render_obj_t base; + lv_array_t items; +} lv_svg_render_group_t; + +typedef struct { + lv_svg_render_obj_t base; + float x; + float y; + char * xlink; +} lv_svg_render_use_t; + +typedef struct { + lv_svg_render_obj_t base; + lv_color_t color; + float opacity; +} lv_svg_render_solid_t; + +typedef struct { + lv_svg_render_obj_t base; + lv_vector_gradient_t dsc; + lv_svg_gradient_units_t units; +} lv_svg_render_gradient_t; + +typedef struct { + lv_svg_render_obj_t base; + float x; + float y; + float width; + float height; + float rx; + float ry; +} lv_svg_render_rect_t; + +typedef struct { + lv_svg_render_obj_t base; + float cx; + float cy; + float r; +} lv_svg_render_circle_t; + +typedef struct { + lv_svg_render_obj_t base; + float cx; + float cy; + float rx; + float ry; +} lv_svg_render_ellipse_t; + +typedef struct { + lv_svg_render_obj_t base; + float x1; + float y1; + float x2; + float y2; +} lv_svg_render_line_t; + +typedef struct { + lv_svg_render_obj_t base; + lv_vector_path_t * path; + lv_area_t bounds; +} lv_svg_render_poly_t; + +typedef struct { + lv_svg_render_obj_t base; + float x; + float y; + float width; + float height; + lv_draw_image_dsc_t img_dsc; + lv_svg_aspect_ratio_t ratio; +} lv_svg_render_image_t; + +#if LV_USE_FREETYPE +typedef struct { + lv_svg_render_obj_t base; + lv_array_t contents; + char * family; + float size; + lv_freetype_font_style_t style; + lv_font_t * font; + float x; + float y; + lv_vector_path_t * path; + lv_area_t bounds; +} lv_svg_render_text_t; + +typedef struct _lv_svg_render_content { + lv_svg_render_obj_t base; + void (*render_content)(const struct _lv_svg_render_content * content, + lv_vector_dsc_t * dsc, lv_matrix_t * matrix); + uint32_t * letters; + uint32_t count; +} lv_svg_render_content_t; + +typedef struct { + lv_svg_render_content_t base; + char * family; + float size; + lv_freetype_font_style_t style; + lv_font_t * font; + lv_vector_path_t * path; + lv_area_t bounds; +} lv_svg_render_tspan_t; +#endif + +struct _lv_svg_draw_dsc { + struct _lv_svg_draw_dsc * next; + lv_vector_draw_dsc_t dsc; + const char * fill_ref; + const char * stroke_ref; +}; + +struct _lv_svg_drawing_builder_state { + const lv_svg_node_t * doc; + struct _lv_svg_draw_dsc * draw_dsc; + int in_group_deps; + bool in_defs; +#if LV_USE_FREETYPE + bool in_text; + lv_svg_node_t * cur_text; +#endif + lv_svg_render_obj_t * list; + lv_svg_render_obj_t * tail; +}; + +/********************** + * STATIC VARIABLES + **********************/ +static lv_svg_render_hal_t hal_funcs = {NULL}; + +/********************** + * STATIC PROTOTYPES + **********************/ +void lv_svg_render_init(const lv_svg_render_hal_t * hal) +{ + if(hal) { + hal_funcs = *hal; +#if LV_USE_FREETYPE + lv_freetype_outline_add_event(_freetype_outline_cb, LV_EVENT_ALL, NULL); +#endif + } +} + +static struct _lv_svg_draw_dsc * _lv_svg_draw_dsc_create(void) +{ + struct _lv_svg_draw_dsc * dsc = lv_zalloc(sizeof(struct _lv_svg_draw_dsc)); + LV_ASSERT_MALLOC(dsc); + _init_draw_dsc(&(dsc->dsc)); + return dsc; +} + +static void _lv_svg_draw_dsc_delete(struct _lv_svg_draw_dsc * dsc) +{ + while(dsc) { + struct _lv_svg_draw_dsc * cur = dsc; + dsc = dsc->next; + _deinit_draw_dsc(&(cur->dsc)); + lv_free(cur); + } +} + +static struct _lv_svg_draw_dsc * _lv_svg_draw_dsc_push(struct _lv_svg_draw_dsc * dsc) +{ + if(!dsc) return NULL; + struct _lv_svg_draw_dsc * cur = lv_zalloc(sizeof(struct _lv_svg_draw_dsc)); + LV_ASSERT_MALLOC(cur); + _copy_draw_dsc(&(cur->dsc), &(dsc->dsc)); + cur->fill_ref = dsc->fill_ref; + cur->stroke_ref = dsc->stroke_ref; + cur->next = dsc; + return cur; +} + +static struct _lv_svg_draw_dsc * _lv_svg_draw_dsc_pop(struct _lv_svg_draw_dsc * dsc) +{ + if(!dsc) return NULL; + struct _lv_svg_draw_dsc * cur = dsc->next; + lv_free(dsc); + return cur; +} + +static void _set_viewport_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +{ + lv_svg_render_viewport_t * view = (lv_svg_render_viewport_t *)obj; + switch(attr->id) { + case LV_SVG_ATTR_WIDTH: + view->width = attr->value.fval; + break; + case LV_SVG_ATTR_HEIGHT: + view->height = attr->value.fval; + break; + case LV_SVG_ATTR_VIEWBOX: { + if(attr->class_type == LV_SVG_ATTR_VALUE_INITIAL) { + float * vals = attr->value.val; + float scale_x = 1.0f; + float scale_y = 1.0f; + float trans_x = vals[0]; + float trans_y = vals[1]; + + if(view->width > 0 && vals[2] > 0) { + scale_x = view->width / vals[2]; + } + if(view->height > 0 && vals[3] > 0) { + scale_y = view->height / vals[3]; + } + view->width = scale_x * vals[2]; + view->height = scale_y * vals[3]; + + lv_matrix_scale(&obj->matrix, scale_x, scale_y); + lv_matrix_translate(&obj->matrix, -trans_x, -trans_y); + } + } + break; + case LV_SVG_ATTR_VIEWPORT_FILL: { + if(attr->class_type == LV_SVG_ATTR_VALUE_INITIAL + && attr->val_type == LV_SVG_ATTR_VALUE_DATA) { + dsc->fill_dsc.color = lv_color_to_32(lv_color_hex(attr->value.uval), 0xFF); + view->viewport_fill = true; + } + else if(attr->class_type == LV_SVG_ATTR_VALUE_NONE) { + view->viewport_fill = false; + } + } + break; + case LV_SVG_ATTR_VIEWPORT_FILL_OPACITY: { + if(attr->class_type == LV_SVG_ATTR_VALUE_INITIAL) { + dsc->fill_dsc.opa = (lv_opa_t)(attr->value.fval * 255.0f); + } + } + break; + } +} + +static void _set_use_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +{ + _set_attr(obj, dsc, attr); + lv_svg_render_use_t * use = (lv_svg_render_use_t *)obj; + switch(attr->id) { + case LV_SVG_ATTR_X: + use->x = attr->value.fval; + break; + case LV_SVG_ATTR_Y: + use->y = attr->value.fval; + break; + case LV_SVG_ATTR_XLINK_HREF: { + if(use->xlink) lv_free(use->xlink); + use->xlink = lv_strdup(attr->value.sval); + } + break; + } +} + +static void _set_solid_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +{ + LV_UNUSED(dsc); + lv_svg_render_solid_t * solid = (lv_svg_render_solid_t *)obj; + switch(attr->id) { + case LV_SVG_ATTR_SOLID_COLOR: + solid->color = lv_color_hex(attr->value.uval); + break; + case LV_SVG_ATTR_SOLID_OPACITY: + solid->opacity = attr->value.fval; + break; + } +} + +static void _set_gradient_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +{ + LV_UNUSED(dsc); + lv_svg_render_gradient_t * grad = (lv_svg_render_gradient_t *)obj; + switch(attr->id) { + case LV_SVG_ATTR_CX: + grad->dsc.cx = attr->value.fval; + break; + case LV_SVG_ATTR_CY: + grad->dsc.cy = attr->value.fval; + break; + case LV_SVG_ATTR_R: + grad->dsc.cr = attr->value.fval; + break; + case LV_SVG_ATTR_X1: + grad->dsc.x1 = attr->value.fval; + break; + case LV_SVG_ATTR_Y1: + grad->dsc.y1 = attr->value.fval; + break; + case LV_SVG_ATTR_X2: + grad->dsc.x2 = attr->value.fval; + break; + case LV_SVG_ATTR_Y2: + grad->dsc.y2 = attr->value.fval; + break; + case LV_SVG_ATTR_GRADIENT_UNITS: + grad->units = attr->value.ival; + break; + } +} + +static void _set_rect_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +{ + _set_attr(obj, dsc, attr); + lv_svg_render_rect_t * rect = (lv_svg_render_rect_t *)obj; + switch(attr->id) { + case LV_SVG_ATTR_X: + rect->x = attr->value.fval; + break; + case LV_SVG_ATTR_Y: + rect->y = attr->value.fval; + break; + case LV_SVG_ATTR_WIDTH: + rect->width = attr->value.fval; + break; + case LV_SVG_ATTR_HEIGHT: + rect->height = attr->value.fval; + break; + case LV_SVG_ATTR_RX: + rect->rx = attr->value.fval; + break; + case LV_SVG_ATTR_RY: + rect->ry = attr->value.fval; + break; + } +} + +static void _set_circle_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +{ + _set_attr(obj, dsc, attr); + lv_svg_render_circle_t * circle = (lv_svg_render_circle_t *)obj; + switch(attr->id) { + case LV_SVG_ATTR_CX: + circle->cx = attr->value.fval; + break; + case LV_SVG_ATTR_CY: + circle->cy = attr->value.fval; + break; + case LV_SVG_ATTR_R: + circle->r = attr->value.fval; + break; + } +} + +static void _set_ellipse_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +{ + _set_attr(obj, dsc, attr); + lv_svg_render_ellipse_t * ellipse = (lv_svg_render_ellipse_t *)obj; + switch(attr->id) { + case LV_SVG_ATTR_CX: + ellipse->cx = attr->value.fval; + break; + case LV_SVG_ATTR_CY: + ellipse->cy = attr->value.fval; + break; + case LV_SVG_ATTR_RX: + ellipse->rx = attr->value.fval; + break; + case LV_SVG_ATTR_RY: + ellipse->ry = attr->value.fval; + break; + } +} + +static void _set_line_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +{ + _set_attr(obj, dsc, attr); + lv_svg_render_line_t * line = (lv_svg_render_line_t *)obj; + switch(attr->id) { + case LV_SVG_ATTR_X1: + line->x1 = attr->value.fval; + break; + case LV_SVG_ATTR_Y1: + line->y1 = attr->value.fval; + break; + case LV_SVG_ATTR_X2: + line->x2 = attr->value.fval; + break; + case LV_SVG_ATTR_Y2: + line->y2 = attr->value.fval; + break; + } +} + +static void _set_polyline_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +{ + _set_attr(obj, dsc, attr); + lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj; + if(attr->id == LV_SVG_ATTR_POINTS) { + lv_vector_path_clear(poly->path); + lv_svg_attr_values_list_t * vals = (lv_svg_attr_values_list_t *)(attr->value.val); + uint32_t len = vals->length; + lv_svg_point_t * points = (lv_svg_point_t *)(&vals->data); + + CALC_BOUNDS(points[0], poly->bounds); + lv_fpoint_t pt = {points[0].x, points[0].y}; + lv_vector_path_move_to(poly->path, &pt); + for(uint32_t i = 1; i < len; i++) { + pt.x = points[i].x; + pt.y = points[i].y; + lv_vector_path_line_to(poly->path, &pt); + CALC_BOUNDS(pt, poly->bounds); + } + } +} + +static void _set_polygon_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +{ + _set_polyline_attr(obj, dsc, attr); + lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj; + if(attr->id == LV_SVG_ATTR_POINTS) { + lv_vector_path_close(poly->path); + } +} + +static size_t _get_path_seg_size(uint32_t cmd) +{ + switch(cmd) { + case LV_SVG_PATH_CMD_MOVE_TO: + case LV_SVG_PATH_CMD_LINE_TO: + case LV_SVG_PATH_CMD_CLOSE: + return sizeof(lv_svg_point_t) + sizeof(uint32_t); + case LV_SVG_PATH_CMD_QUAD_TO: + return sizeof(lv_svg_point_t) * 2 + sizeof(uint32_t); + case LV_SVG_PATH_CMD_CURVE_TO: + return sizeof(lv_svg_point_t) * 3 + sizeof(uint32_t); + default: + return 0; + } +} + +static void _set_path_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +{ + _set_attr(obj, dsc, attr); + lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj; + if(attr->id == LV_SVG_ATTR_D) { + lv_vector_path_clear(poly->path); + lv_svg_attr_values_list_t * vals = (lv_svg_attr_values_list_t *)(attr->value.val); + uint32_t len = vals->length; + uint8_t * data_ptr = (uint8_t *)(&vals->data); + + for(uint32_t i = 0; i < len; i++) { + lv_svg_attr_path_value_t * path_seg = (lv_svg_attr_path_value_t *)data_ptr; + uint32_t cmd = path_seg->cmd; + lv_svg_point_t * points = (lv_svg_point_t *)(&path_seg->data); + switch(cmd) { + case LV_SVG_PATH_CMD_MOVE_TO: { + lv_fpoint_t pt = {points[0].x, points[0].y}; + lv_vector_path_move_to(poly->path, &pt); + CALC_BOUNDS(pt, poly->bounds); + } + break; + case LV_SVG_PATH_CMD_LINE_TO: { + lv_fpoint_t pt = {points[0].x, points[0].y}; + lv_vector_path_line_to(poly->path, &pt); + CALC_BOUNDS(pt, poly->bounds); + } + break; + case LV_SVG_PATH_CMD_QUAD_TO: { + lv_fpoint_t pt[2] = { + {points[0].x, points[0].y}, + {points[1].x, points[1].y} + }; + lv_vector_path_quad_to(poly->path, &pt[0], &pt[1]); + CALC_BOUNDS(pt[0], poly->bounds); + CALC_BOUNDS(pt[1], poly->bounds); + } + break; + case LV_SVG_PATH_CMD_CURVE_TO: { + lv_fpoint_t pt[3] = { + {points[0].x, points[0].y}, + {points[1].x, points[1].y}, + {points[2].x, points[2].y} + }; + lv_vector_path_cubic_to(poly->path, &pt[0], &pt[1], &pt[2]); + CALC_BOUNDS(pt[0], poly->bounds); + CALC_BOUNDS(pt[1], poly->bounds); + CALC_BOUNDS(pt[2], poly->bounds); + } + break; + case LV_SVG_PATH_CMD_CLOSE: { + lv_vector_path_close(poly->path); + } + break; + } + size_t mem_inc = _get_path_seg_size(cmd); + data_ptr += mem_inc; + } + } +} + +#if LV_USE_FREETYPE +#define SET_FONT_ATTRS(obj, attr) \ + do { \ + switch(attr->id) { \ + case LV_SVG_ATTR_FONT_FAMILY: { \ + if(attr->val_type == LV_SVG_ATTR_VALUE_PTR) { \ + if((obj)->font) { \ + lv_freetype_font_delete((obj)->font); \ + (obj)->font = NULL; \ + } \ + lv_vector_path_clear((obj)->path); \ + if((obj)->family) lv_free((obj)->family); \ + (obj)->family = lv_strdup(attr->value.sval); \ + } \ + } \ + break; \ + case LV_SVG_ATTR_FONT_SIZE: \ + if(attr->class_type == LV_SVG_ATTR_VALUE_INITIAL) { \ + if(attr->val_type == LV_SVG_ATTR_VALUE_DATA) { \ + if((obj)->font) { \ + lv_freetype_font_delete((obj)->font); \ + (obj)->font = NULL; \ + } \ + (obj)->size = attr->value.fval; \ + lv_vector_path_clear((obj)->path); \ + } \ + } \ + break; \ + case LV_SVG_ATTR_FONT_STYLE: \ + if(attr->class_type == LV_SVG_ATTR_VALUE_INITIAL) { \ + if(attr->val_type == LV_SVG_ATTR_VALUE_PTR) { \ + if((obj)->font) { \ + lv_freetype_font_delete((obj)->font); \ + (obj)->font = NULL; \ + } \ + lv_vector_path_clear((obj)->path); \ + if(strncmp(attr->value.sval, "italic", 6) == 0) { \ + (obj)->style = LV_FREETYPE_FONT_STYLE_ITALIC; \ + } \ + } \ + } \ + break; \ + case LV_SVG_ATTR_FONT_WEIGHT: \ + if(attr->class_type == LV_SVG_ATTR_VALUE_INITIAL) { \ + if(attr->val_type == LV_SVG_ATTR_VALUE_PTR) { \ + if((obj)->font) { \ + lv_freetype_font_delete((obj)->font); \ + (obj)->font = NULL; \ + } \ + lv_vector_path_clear((obj)->path); \ + if(strncmp(attr->value.sval, "bold", 4) == 0) { \ + (obj)->style = LV_FREETYPE_FONT_STYLE_BOLD; \ + } \ + } \ + } \ + break; \ + case LV_SVG_ATTR_FONT_VARIANT: \ + if(attr->class_type == LV_SVG_ATTR_VALUE_INITIAL) { \ + if(attr->val_type == LV_SVG_ATTR_VALUE_PTR) { \ + if((obj)->font) { \ + lv_freetype_font_delete((obj)->font); \ + (obj)->font = NULL; \ + } \ + lv_vector_path_clear((obj)->path); \ + if(strncmp(attr->value.sval, "small-caps", 10) == 0) { \ + (obj)->size /= 2; \ + } \ + } \ + } \ + break; \ + } \ + } while(0) + +static void _set_tspan_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +{ + _set_attr(obj, dsc, attr); + lv_svg_render_tspan_t * tspan = (lv_svg_render_tspan_t *)obj; + + SET_FONT_ATTRS(tspan, attr); +} + +static void _set_text_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +{ + _set_attr(obj, dsc, attr); + lv_svg_render_text_t * text = (lv_svg_render_text_t *)obj; + + SET_FONT_ATTRS(text, attr); + + switch(attr->id) { + case LV_SVG_ATTR_X: + text->x = attr->value.fval; + break; + case LV_SVG_ATTR_Y: + text->y = attr->value.fval; + break; + } +} +#endif + +static void _set_image_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +{ + _set_attr(obj, dsc, attr); + lv_svg_render_image_t * image = (lv_svg_render_image_t *)obj; + switch(attr->id) { + case LV_SVG_ATTR_X: + image->x = attr->value.fval; + break; + case LV_SVG_ATTR_Y: + image->y = attr->value.fval; + break; + case LV_SVG_ATTR_HEIGHT: + image->height = attr->value.fval; + break; + case LV_SVG_ATTR_WIDTH: + image->width = attr->value.fval; + break; + case LV_SVG_ATTR_OPACITY: + image->img_dsc.opa = (lv_opa_t)(attr->value.fval * 255.0f); + break; + case LV_SVG_ATTR_XLINK_HREF: { + const char * xlink = attr->value.sval; + if(hal_funcs.load_image) { + hal_funcs.load_image(xlink, &image->img_dsc); + } + } + break; + case LV_SVG_ATTR_PRESERVE_ASPECT_RATIO: { + if(attr->class_type == LV_SVG_ATTR_VALUE_INITIAL) { + image->ratio = attr->value.uval; + } + } + break; + } +} + +static void _set_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) +{ + LV_UNUSED(obj); + switch(attr->id) { + case LV_SVG_ATTR_FILL: { + if(attr->class_type == LV_SVG_ATTR_VALUE_NONE) { + dsc->fill_dsc.opa = LV_OPA_0; + obj->flags |= _RENDER_ATTR_FILL_OPACITY; + obj->flags |= _RENDER_ATTR_FILL; + return; + } + else if(attr->class_type == LV_SVG_ATTR_VALUE_INHERIT) { + obj->flags &= ~_RENDER_ATTR_FILL; + return; + } + else { + if(obj->fill_ref) { + lv_free(obj->fill_ref); + obj->fill_ref = NULL; + } + if(attr->val_type == LV_SVG_ATTR_VALUE_PTR) { + obj->fill_ref = lv_strdup(attr->value.sval); + } + else { // color + dsc->fill_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID; + dsc->fill_dsc.color = lv_color_to_32(lv_color_hex(attr->value.uval), 0xFF); + } + obj->flags |= _RENDER_ATTR_FILL; + if(obj->dsc.fill_dsc.opa == LV_OPA_0) { + dsc->fill_dsc.opa = LV_OPA_COVER; + obj->flags |= _RENDER_ATTR_FILL_OPACITY; + } + } + } + break; + case LV_SVG_ATTR_STROKE: { + if(attr->class_type == LV_SVG_ATTR_VALUE_NONE) { + dsc->stroke_dsc.opa = LV_OPA_0; + obj->flags |= _RENDER_ATTR_STROKE_OPACITY; + obj->flags |= _RENDER_ATTR_STROKE; + return; + } + else if(attr->class_type == LV_SVG_ATTR_VALUE_INHERIT) { + obj->flags &= ~_RENDER_ATTR_STROKE; + return; + } + else { + if(obj->stroke_ref) { + lv_free(obj->stroke_ref); + obj->stroke_ref = NULL; + } + if(attr->val_type == LV_SVG_ATTR_VALUE_PTR) { + obj->stroke_ref = lv_strdup(attr->value.sval); + } + else { // color + dsc->stroke_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID; + dsc->stroke_dsc.color = lv_color_to_32(lv_color_hex(attr->value.uval), 0xFF); + } + } + + obj->flags |= _RENDER_ATTR_STROKE; + if(obj->dsc.stroke_dsc.opa == LV_OPA_0) { + dsc->stroke_dsc.opa = LV_OPA_COVER; + obj->flags |= _RENDER_ATTR_STROKE_OPACITY; + } + } + break; + case LV_SVG_ATTR_FILL_OPACITY: { + if(attr->class_type == LV_SVG_ATTR_VALUE_INHERIT) { + obj->flags &= ~_RENDER_ATTR_FILL_OPACITY; + return; + } + dsc->fill_dsc.opa = (lv_opa_t)(attr->value.fval * 255.0f); + obj->flags |= _RENDER_ATTR_FILL_OPACITY; + } + break; + case LV_SVG_ATTR_STROKE_OPACITY: { + if(attr->class_type == LV_SVG_ATTR_VALUE_INHERIT) { + obj->flags &= ~_RENDER_ATTR_STROKE_OPACITY; + return; + } + dsc->stroke_dsc.opa = (lv_opa_t)(attr->value.fval * 255.0f); + obj->flags |= _RENDER_ATTR_STROKE_OPACITY; + } + break; + case LV_SVG_ATTR_FILL_RULE: { + if(attr->class_type == LV_SVG_ATTR_VALUE_INHERIT) { + obj->flags &= ~_RENDER_ATTR_FILL_RULE; + return; + } + dsc->fill_dsc.fill_rule = attr->value.ival; + obj->flags |= _RENDER_ATTR_FILL_RULE; + } + break; + case LV_SVG_ATTR_STROKE_WIDTH: { + if(attr->class_type == LV_SVG_ATTR_VALUE_INHERIT) { + obj->flags &= ~_RENDER_ATTR_STROKE_WIDTH; + return; + } + dsc->stroke_dsc.width = attr->value.fval; + obj->flags |= _RENDER_ATTR_STROKE_WIDTH; + } + break; + case LV_SVG_ATTR_STROKE_LINECAP: { + if(attr->class_type == LV_SVG_ATTR_VALUE_INHERIT) { + obj->flags &= ~_RENDER_ATTR_STROKE_LINECAP; + return; + } + dsc->stroke_dsc.cap = attr->value.ival; + obj->flags |= _RENDER_ATTR_STROKE_LINECAP; + } + break; + case LV_SVG_ATTR_STROKE_LINEJOIN: { + if(attr->class_type == LV_SVG_ATTR_VALUE_INHERIT) { + obj->flags &= ~_RENDER_ATTR_STROKE_LINEJOIN; + return; + } + dsc->stroke_dsc.join = attr->value.ival; + obj->flags |= _RENDER_ATTR_STROKE_LINEJOIN; + } + break; + case LV_SVG_ATTR_STROKE_MITER_LIMIT: { + if(attr->class_type == LV_SVG_ATTR_VALUE_INHERIT) { + obj->flags &= ~_RENDER_ATTR_STROKE_MITER_LIMIT; + return; + } + dsc->stroke_dsc.miter_limit = attr->value.ival; + obj->flags |= _RENDER_ATTR_STROKE_MITER_LIMIT; + } + break; + case LV_SVG_ATTR_STROKE_DASH_ARRAY: { + if(attr->class_type == LV_SVG_ATTR_VALUE_NONE) { + lv_array_clear(&(dsc->stroke_dsc.dash_pattern)); + obj->flags |= _RENDER_ATTR_STROKE_DASH_ARRAY; + return; + } + else if(attr->class_type == LV_SVG_ATTR_VALUE_INHERIT) { + obj->flags &= ~_RENDER_ATTR_STROKE_DASH_ARRAY; + return; + } + else { + lv_array_t * dash_array = &(dsc->stroke_dsc.dash_pattern); + + lv_svg_attr_values_list_t * vals = (lv_svg_attr_values_list_t *)(attr->value.val); + uint32_t len = vals->length; + float * dashs = (float *)(&vals->data); + lv_array_clear(dash_array); + + obj->flags |= _RENDER_ATTR_STROKE_DASH_ARRAY; + if(len) { + if(lv_array_capacity(dash_array) == 0) { + lv_array_init(dash_array, len, sizeof(float)); + } + else { + lv_array_resize(dash_array, len); + } + for(uint32_t i = 0; i < len; i++) { + lv_array_push_back(dash_array, (uint8_t *)(&dashs[i])); + } + } + } + } + break; + case LV_SVG_ATTR_TRANSFORM: { + if(attr->class_type == LV_SVG_ATTR_VALUE_NONE) { + return; + } + lv_memcpy(&(obj->matrix), attr->value.val, sizeof(lv_matrix_t)); + } + break; + case LV_SVG_ATTR_STROKE_DASH_OFFSET: + // not support yet + break; + } +} + +static void _set_solid_ref(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, + const lv_svg_render_obj_t * target_obj, bool fill) +{ + LV_UNUSED(target_obj); + lv_svg_render_solid_t * solid = (lv_svg_render_solid_t *)obj; + if(fill) { + dsc->fill_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID; + dsc->fill_dsc.color = lv_color_to_32(solid->color, 0xFF); + dsc->fill_dsc.opa = (lv_opa_t)(solid->opacity * 255.0f); + } + else { + dsc->stroke_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID; + dsc->stroke_dsc.color = lv_color_to_32(solid->color, 0xFF); + dsc->stroke_dsc.opa = (lv_opa_t)(solid->opacity * 255.0f); + } +} + +static void _set_gradient_ref(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, + const lv_svg_render_obj_t * target_obj, bool fill) +{ + if(!target_obj->clz->get_bounds) { + return; + } + + lv_svg_render_gradient_t * grad = (lv_svg_render_gradient_t *)obj; + lv_vector_gradient_t * grad_dsc = NULL; + lv_matrix_t * mtx = NULL; + + if(fill) { + dsc->fill_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; + grad_dsc = &dsc->fill_dsc.gradient; + mtx = &dsc->fill_dsc.matrix; + } + else { + dsc->stroke_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; + grad_dsc = &dsc->stroke_dsc.gradient; + mtx = &dsc->stroke_dsc.matrix; + } + + lv_memcpy(grad_dsc, &grad->dsc, sizeof(lv_vector_gradient_t)); + + lv_area_t bounds = {0, 0, 0, 0}; + target_obj->clz->get_bounds(target_obj, &bounds); + + int32_t w = bounds.x2 - bounds.x1; + int32_t h = bounds.y2 - bounds.y1; + if(grad->dsc.style == LV_VECTOR_GRADIENT_STYLE_RADIAL) { + if(grad->units == LV_SVG_GRADIENT_UNITS_OBJECT) { + grad_dsc->cx = PCT_TO_PX(grad_dsc->cx, w); + grad_dsc->cy = PCT_TO_PX(grad_dsc->cy, h); + grad_dsc->cr = PCT_TO_PX(grad_dsc->cr, MAX(w, h)); + lv_matrix_translate(mtx, bounds.x1, bounds.y1); + } + } + else { // LV_VECTOR_GRADIENT_STYLE_LINEAR + if(grad->units == LV_SVG_GRADIENT_UNITS_OBJECT) { + grad_dsc->x1 = PCT_TO_PX(grad_dsc->x1, w); + grad_dsc->y1 = PCT_TO_PX(grad_dsc->y1, h); + grad_dsc->x2 = PCT_TO_PX(grad_dsc->x2, w); + grad_dsc->y2 = PCT_TO_PX(grad_dsc->y2, h); + lv_matrix_translate(mtx, bounds.x1, bounds.y1); + } + } +} + +static void _init_draw_dsc(lv_vector_draw_dsc_t * dsc) +{ + lv_vector_fill_dsc_t * fill_dsc = &(dsc->fill_dsc); + fill_dsc->style = LV_VECTOR_DRAW_STYLE_SOLID; + fill_dsc->color = lv_color_to_32(lv_color_black(), 0xFF); + fill_dsc->opa = LV_OPA_COVER; + fill_dsc->fill_rule = LV_VECTOR_FILL_NONZERO; + lv_matrix_identity(&(fill_dsc->matrix)); // identity matrix + + lv_vector_stroke_dsc_t * stroke_dsc = &(dsc->stroke_dsc); + stroke_dsc->style = LV_VECTOR_DRAW_STYLE_SOLID; + stroke_dsc->color = lv_color_to_32(lv_color_black(), 0xFF); + stroke_dsc->opa = LV_OPA_0; // default no stroke + stroke_dsc->width = 1.0f; + stroke_dsc->cap = LV_VECTOR_STROKE_CAP_BUTT; + stroke_dsc->join = LV_VECTOR_STROKE_JOIN_MITER; + stroke_dsc->miter_limit = 4.0f; + lv_matrix_identity(&(stroke_dsc->matrix)); // identity matrix + + dsc->blend_mode = LV_VECTOR_BLEND_SRC_OVER; + lv_matrix_identity(&(dsc->matrix)); // identity matrix +} + +static void _deinit_draw_dsc(lv_vector_draw_dsc_t * dsc) +{ + lv_array_deinit(&(dsc->stroke_dsc.dash_pattern)); +} + +static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_t * src) +{ + 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; + dst->stroke_dsc.opa = src->stroke_dsc.opa; + dst->stroke_dsc.width = src->stroke_dsc.width; + dst->stroke_dsc.cap = src->stroke_dsc.cap; + dst->stroke_dsc.join = src->stroke_dsc.join; + dst->stroke_dsc.miter_limit = src->stroke_dsc.miter_limit; + lv_array_copy(&(dst->stroke_dsc.dash_pattern), &(src->stroke_dsc.dash_pattern)); + 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; +} + +static void _copy_draw_dsc_from_ref(lv_vector_dsc_t * dsc, const lv_svg_render_obj_t * obj) +{ + lv_vector_draw_dsc_t * dst = &(dsc->current_dsc); + if(obj->fill_ref) { + lv_svg_render_obj_t * list = obj->head; + while(list) { + if(list->id) { + if(strcmp(obj->fill_ref, list->id) == 0) { + list->clz->set_paint_ref(list, dst, obj, true); + break; + } + } + list = list->next; + } + } + + if(obj->stroke_ref) { + lv_svg_render_obj_t * list = obj->head; + while(list) { + if(list->id) { + if(strcmp(obj->stroke_ref, list->id) == 0) { + list->clz->set_paint_ref(list, dst, obj, false); + break; + } + } + list = list->next; + } + } +} + +static void _set_render_attrs(lv_svg_render_obj_t * obj, const lv_svg_node_t * node, + struct _lv_svg_drawing_builder_state * state) +{ + obj->tag = node->type; + if((node->type != LV_SVG_TAG_CONTENT) && node->xml_id) { + obj->id = lv_strdup(node->xml_id); + } + if(obj->clz->init) { + obj->clz->init(obj, node); + } + if(state->draw_dsc->fill_ref) { + obj->fill_ref = lv_strdup(state->draw_dsc->fill_ref); + } + if(state->draw_dsc->stroke_ref) { + obj->stroke_ref = lv_strdup(state->draw_dsc->stroke_ref); + } + + uint32_t len = lv_array_size(&node->attrs); + for(uint32_t i = 0; i < len; i++) { + lv_svg_attr_t * attr = lv_array_at(&node->attrs, i); + obj->clz->set_attr(obj, &(state->draw_dsc->dsc), attr); + } + if(node->type == LV_SVG_TAG_G) { // only need store it + state->draw_dsc->fill_ref = obj->fill_ref; + state->draw_dsc->stroke_ref = obj->stroke_ref; + } + obj->head = state->list; +} + +// init functions + +static void _init_obj(lv_svg_render_obj_t * obj, const lv_svg_node_t * node) +{ + LV_UNUSED(node); + lv_matrix_identity(&obj->matrix); +} + +static void _init_viewport(lv_svg_render_obj_t * obj, const lv_svg_node_t * node) +{ + _init_obj(obj, node); + lv_svg_render_viewport_t * view = (lv_svg_render_viewport_t *)obj; + view->viewport_fill = false; +} + +static void _init_group(lv_svg_render_obj_t * obj, const lv_svg_node_t * node) +{ + _init_obj(obj, node); + lv_svg_render_group_t * group = (lv_svg_render_group_t *)obj; + lv_array_init(&group->items, LV_TREE_NODE(node)->child_cnt, sizeof(lv_svg_render_obj_t *)); +} + +static void _init_image(lv_svg_render_obj_t * obj, const lv_svg_node_t * node) +{ + _init_obj(obj, node); + lv_svg_render_image_t * image = (lv_svg_render_image_t *)obj; + lv_draw_image_dsc_init(&image->img_dsc); + image->ratio = LV_SVG_ASPECT_RATIO_XMID_YMID | LV_SVG_ASPECT_RATIO_OPT_MEET; +} + +static void _init_poly(lv_svg_render_obj_t * obj, const lv_svg_node_t * node) +{ + _init_obj(obj, node); + lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj; + poly->path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); + lv_area_set(&poly->bounds, 0, 0, 0, 0); +} + +#if LV_USE_FREETYPE +static void _init_text(lv_svg_render_obj_t * obj, const lv_svg_node_t * node) +{ + _init_obj(obj, node); + lv_svg_render_text_t * text = (lv_svg_render_text_t *)obj; + text->family = lv_strdup("sans-serif"); + text->size = 16.0f; + text->style = LV_FREETYPE_FONT_STYLE_NORMAL; + text->font = NULL; + text->x = text->y = 0.0f; + lv_array_init(&text->contents, LV_TREE_NODE(node)->child_cnt, sizeof(lv_svg_render_obj_t *)); + text->path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); +} + +static void _init_content(lv_svg_render_obj_t * obj, const lv_svg_node_t * node) +{ + _init_obj(obj, node); + lv_svg_render_content_t * content = (lv_svg_render_content_t *)obj; + const char * str = node->xml_id; + content->count = lv_text_get_encoded_length(str); + content->letters = lv_malloc(sizeof(uint32_t) * content->count); + LV_ASSERT_MALLOC(content->letters); + uint32_t offset = 0; + for(uint32_t i = 0; i < content->count; i++) { + content->letters[i] = lv_text_encoded_next(str, &offset); + } +} + +static void _init_tspan(lv_svg_render_obj_t * obj, const lv_svg_node_t * node) +{ + _init_obj(obj, node); + lv_svg_render_tspan_t * span = (lv_svg_render_tspan_t *)obj; + lv_svg_node_t * parent = LV_SVG_NODE(LV_TREE_NODE(node)->parent); + if(parent->type != LV_SVG_TAG_TEXT) { + return; + } + + lv_svg_render_text_t * text = (lv_svg_render_text_t *)parent->render_obj; + span->family = lv_strdup(text->family); + span->size = text->size; + span->style = text->style; + span->path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); + + lv_svg_node_t * content_node = LV_SVG_NODE(LV_TREE_NODE(node)->children[0]); + _init_content(obj, content_node); +} +#endif + +static void _init_gradient(lv_svg_render_obj_t * obj, const lv_svg_node_t * node) +{ + _init_obj(obj, node); + lv_svg_render_gradient_t * grad = (lv_svg_render_gradient_t *)obj; + grad->units = LV_SVG_GRADIENT_UNITS_OBJECT; + grad->dsc.cx = 0.5f; + grad->dsc.cy = 0.5f; + grad->dsc.cr = 0.5f; + grad->dsc.x1 = 0.0f; + grad->dsc.y1 = 0.0f; + grad->dsc.x2 = 1.0f; + grad->dsc.y2 = 0.0f; + grad->dsc.spread = LV_VECTOR_GRADIENT_SPREAD_PAD; + + uint32_t count = LV_TREE_NODE(node)->child_cnt; + uint32_t stop_count = 0; + + for(uint32_t i = 0; i < count; i++) { + lv_svg_node_t * child_node = LV_SVG_NODE_CHILD(node, i); + uint32_t len = lv_array_size(&child_node->attrs); + + bool is_stop = false; + lv_color_t stop_color = lv_color_black(); + lv_opa_t stop_opa = LV_OPA_COVER; + uint8_t stop_frac = 0; + + for(uint32_t j = 0; j < len; j++) { + lv_svg_attr_t * attr = lv_array_at(&child_node->attrs, j); + switch(attr->id) { + case LV_SVG_ATTR_GRADIENT_STOP_COLOR: { + stop_color = lv_color_hex(attr->value.uval); + is_stop = true; + } + break; + case LV_SVG_ATTR_GRADIENT_STOP_OPACITY: { + stop_opa = (lv_opa_t)(attr->value.fval * 255.0f); + is_stop = true; + } + break; + case LV_SVG_ATTR_GRADIENT_STOP_OFFSET: { + stop_frac = (uint8_t)(attr->value.fval * 255.0f); + is_stop = true; + } + break; + } + } + + if(is_stop) { + grad->dsc.stops[stop_count].opa = stop_opa; + grad->dsc.stops[stop_count].frac = stop_frac; + grad->dsc.stops[stop_count].color = stop_color; + stop_count++; + } + + if(stop_count == LV_GRADIENT_MAX_STOPS) { + break; + } + } + grad->dsc.stops_count = stop_count; +} + +static void _setup_matrix(lv_matrix_t * matrix, lv_vector_dsc_t * dsc, const lv_svg_render_obj_t * obj) +{ + lv_memcpy(matrix, &dsc->current_dsc.matrix, sizeof(lv_matrix_t)); + lv_matrix_multiply(&dsc->current_dsc.matrix, &obj->matrix); +} + +static void _restore_matrix(lv_matrix_t * matrix, lv_vector_dsc_t * dsc) +{ + lv_memcpy(&dsc->current_dsc.matrix, matrix, sizeof(lv_matrix_t)); +} + +static void _prepare_render(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc) +{ + _copy_draw_dsc(&(dsc->current_dsc), &(obj->dsc)); +} + +static void _special_render(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc) +{ + const lv_vector_draw_dsc_t * src = &(obj->dsc); + lv_vector_draw_dsc_t * dst = &(dsc->current_dsc); + + if(obj->flags & _RENDER_ATTR_FILL) { + lv_memcpy(&(dst->fill_dsc), &(src->fill_dsc), sizeof(lv_vector_fill_dsc_t)); + dst->blend_mode = src->blend_mode; + } + + if(obj->flags & _RENDER_ATTR_FILL_OPACITY) { + dst->fill_dsc.opa = src->fill_dsc.opa; + } + + if(obj->flags & _RENDER_ATTR_FILL_RULE) { + dst->fill_dsc.fill_rule = src->fill_dsc.fill_rule; + } + + if(obj->flags & _RENDER_ATTR_STROKE) { + dst->stroke_dsc.style = src->stroke_dsc.style; + dst->stroke_dsc.color = src->stroke_dsc.color; + 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; + } + + if(obj->flags & _RENDER_ATTR_STROKE_OPACITY) { + dst->stroke_dsc.opa = src->stroke_dsc.opa; + } + + if(obj->flags & _RENDER_ATTR_STROKE_WIDTH) { + dst->stroke_dsc.width = src->stroke_dsc.width; + } + if(obj->flags & _RENDER_ATTR_STROKE_LINECAP) { + dst->stroke_dsc.cap = src->stroke_dsc.cap; + } + if(obj->flags & _RENDER_ATTR_STROKE_LINEJOIN) { + dst->stroke_dsc.join = src->stroke_dsc.join; + } + if(obj->flags & _RENDER_ATTR_STROKE_MITER_LIMIT) { + dst->stroke_dsc.miter_limit = src->stroke_dsc.miter_limit; + } + if(obj->flags & _RENDER_ATTR_STROKE_DASH_ARRAY) { + lv_array_copy(&(dst->stroke_dsc.dash_pattern), &(src->stroke_dsc.dash_pattern)); + } +} + +// render functions +static void _render_viewport(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +{ + LV_UNUSED(matrix); + + lv_svg_render_viewport_t * view = (lv_svg_render_viewport_t *)obj; + lv_matrix_multiply(&dsc->current_dsc.matrix, &obj->matrix); + if(view->viewport_fill) { + lv_area_t rc = {0, 0, (int32_t)view->width, (int32_t)view->height}; + lv_vector_clear_area(dsc, &rc); + } +} + +static void _render_rect(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +{ + lv_matrix_t mtx; + _setup_matrix(&mtx, dsc, obj); + + if(matrix) { + lv_matrix_multiply(&dsc->current_dsc.matrix, matrix); + } + + lv_svg_render_rect_t * rect = (lv_svg_render_rect_t *)obj; + + if(rect->rx > 0 && rect->ry == 0) rect->ry = rect->rx; + else if(rect->ry > 0 && rect->rx == 0) rect->rx = rect->ry; + + lv_vector_path_t * path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); + lv_area_t rc = {(int32_t)rect->x, (int32_t)rect->y, (int32_t)(rect->x + rect->width - 1), (int32_t)(rect->y + rect->height - 1)}; + lv_vector_path_append_rect(path, &rc, rect->rx, rect->ry); + + _copy_draw_dsc_from_ref(dsc, obj); + lv_vector_dsc_add_path(dsc, path); + lv_vector_path_delete(path); + + _restore_matrix(&mtx, dsc); +} + +static void _render_circle(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +{ + lv_matrix_t mtx; + _setup_matrix(&mtx, dsc, obj); + + if(matrix) { + lv_matrix_multiply(&dsc->current_dsc.matrix, matrix); + } + + lv_svg_render_circle_t * circle = (lv_svg_render_circle_t *)obj; + lv_vector_path_t * path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); + lv_fpoint_t cp = {circle->cx, circle->cy}; + lv_vector_path_append_circle(path, &cp, circle->r, circle->r); + + _copy_draw_dsc_from_ref(dsc, obj); + lv_vector_dsc_add_path(dsc, path); + lv_vector_path_delete(path); + + _restore_matrix(&mtx, dsc); +} + +static void _render_ellipse(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +{ + lv_matrix_t mtx; + _setup_matrix(&mtx, dsc, obj); + + if(matrix) { + lv_matrix_multiply(&dsc->current_dsc.matrix, matrix); + } + + lv_svg_render_ellipse_t * ellipse = (lv_svg_render_ellipse_t *)obj; + lv_vector_path_t * path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); + lv_fpoint_t cp = {ellipse->cx, ellipse->cy}; + lv_vector_path_append_circle(path, &cp, ellipse->rx, ellipse->ry); + + _copy_draw_dsc_from_ref(dsc, obj); + lv_vector_dsc_add_path(dsc, path); + lv_vector_path_delete(path); + + _restore_matrix(&mtx, dsc); +} + +static void _render_line(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +{ + lv_matrix_t mtx; + _setup_matrix(&mtx, dsc, obj); + + if(matrix) { + lv_matrix_multiply(&dsc->current_dsc.matrix, matrix); + } + + lv_svg_render_line_t * line = (lv_svg_render_line_t *)obj; + lv_vector_path_t * path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); + lv_fpoint_t sp = {line->x1, line->y1}; + lv_vector_path_move_to(path, &sp); + lv_fpoint_t ep = {line->x2, line->y2}; + lv_vector_path_line_to(path, &ep); + + _copy_draw_dsc_from_ref(dsc, obj); + lv_vector_dsc_add_path(dsc, path); + lv_vector_path_delete(path); + + _restore_matrix(&mtx, dsc); +} + +static void _render_poly(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +{ + lv_matrix_t mtx; + _setup_matrix(&mtx, dsc, obj); + + if(matrix) { + lv_matrix_multiply(&dsc->current_dsc.matrix, matrix); + } + + lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj; + + _copy_draw_dsc_from_ref(dsc, obj); + lv_vector_dsc_add_path(dsc, poly->path); + + _restore_matrix(&mtx, dsc); +} + +static void _render_group(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +{ + lv_svg_render_group_t * group = (lv_svg_render_group_t *)obj; + lv_matrix_t mtx; + _setup_matrix(&mtx, dsc, obj); + + struct _lv_svg_draw_dsc save_dsc; + lv_memzero(&save_dsc, sizeof(struct _lv_svg_draw_dsc)); + + for(uint32_t i = 0; i < group->items.size; i++) { + lv_svg_render_obj_t * list = *((lv_svg_render_obj_t **)lv_array_at(&group->items, i)); + + if(list->clz->render && (list->flags & _RENDER_IN_GROUP)) { + _copy_draw_dsc(&(save_dsc.dsc), &(dsc->current_dsc)); + _special_render(list, dsc); + list->clz->render(list, dsc, matrix); + _copy_draw_dsc(&(dsc->current_dsc), &(save_dsc.dsc)); + } + } + + _restore_matrix(&mtx, dsc); +} + +static void _render_image(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +{ + lv_matrix_t imtx; + _setup_matrix(&imtx, dsc, obj); + + if(matrix) { + lv_matrix_multiply(&dsc->current_dsc.matrix, matrix); + } + + lv_svg_render_image_t * image = (lv_svg_render_image_t *)obj; + if(!image->img_dsc.header.w || !image->img_dsc.header.h || !image->img_dsc.src) { + return; + } + + lv_vector_path_t * path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); + lv_area_t rc = {(int32_t)image->x, (int32_t)image->y, (int32_t)(image->x + image->width - 1), (int32_t)(image->y + image->height - 1)}; + lv_vector_path_append_rect(path, &rc, 0, 0); + + lv_matrix_t mtx; + lv_matrix_identity(&mtx); + + float img_w = (float)image->img_dsc.header.w; + float img_h = (float)image->img_dsc.header.h; + float scale_x = image->width / img_w; + float scale_y = image->height / img_h; + float scale = 1.0f; + + if((image->ratio & 0x1) == LV_SVG_ASPECT_RATIO_OPT_SLICE) { + scale = MAX(scale_x, scale_y); + } + else if((image->ratio & 0x1) == LV_SVG_ASPECT_RATIO_OPT_MEET) { + scale = MIN(scale_x, scale_y); + } + + uint32_t align = image->ratio & ~0x1; + + switch(align) { + case LV_SVG_ASPECT_RATIO_NONE: + lv_matrix_scale(&mtx, scale_x, scale_y); + break; + case LV_SVG_ASPECT_RATIO_XMIN_YMIN: + lv_matrix_scale(&mtx, scale, scale); + break; + case LV_SVG_ASPECT_RATIO_XMID_YMIN: { + float tx = (image->width - img_w * scale) / 2; + lv_matrix_translate(&mtx, tx, 0); + lv_matrix_scale(&mtx, scale, scale); + } + break; + case LV_SVG_ASPECT_RATIO_XMAX_YMIN: { + float tx = image->width - img_w * scale; + lv_matrix_translate(&mtx, tx, 0); + lv_matrix_scale(&mtx, scale, scale); + } + break; + case LV_SVG_ASPECT_RATIO_XMIN_YMID: { + float ty = (image->height - img_h * scale) / 2; + lv_matrix_translate(&mtx, 0, ty); + lv_matrix_scale(&mtx, scale, scale); + } + break; + case LV_SVG_ASPECT_RATIO_XMID_YMID: { + float tx = (image->width - img_w * scale) / 2; + float ty = (image->height - img_h * scale) / 2; + lv_matrix_translate(&mtx, tx, ty); + lv_matrix_scale(&mtx, scale, scale); + } + break; + case LV_SVG_ASPECT_RATIO_XMAX_YMID: { + float tx = image->width - img_w * scale; + float ty = (image->height - img_h * scale) / 2; + lv_matrix_translate(&mtx, tx, ty); + lv_matrix_scale(&mtx, scale, scale); + } + break; + case LV_SVG_ASPECT_RATIO_XMIN_YMAX: { + float ty = image->height - img_h * scale; + lv_matrix_translate(&mtx, 0, ty); + lv_matrix_scale(&mtx, scale, scale); + } + break; + case LV_SVG_ASPECT_RATIO_XMID_YMAX: { + float tx = (image->width - img_w * scale) / 2; + float ty = image->height - img_h * scale; + lv_matrix_translate(&mtx, tx, ty); + lv_matrix_scale(&mtx, scale, scale); + } + break; + case LV_SVG_ASPECT_RATIO_XMAX_YMAX: { + float tx = image->width - img_w * scale; + float ty = image->height - img_h * scale; + lv_matrix_translate(&mtx, tx, ty); + lv_matrix_scale(&mtx, scale, scale); + } + break; + } + + lv_vector_dsc_set_fill_transform(dsc, &mtx); + lv_vector_dsc_set_fill_image(dsc, &image->img_dsc); + + _copy_draw_dsc_from_ref(dsc, obj); + lv_vector_dsc_add_path(dsc, path); + lv_vector_path_delete(path); + + _restore_matrix(&imtx, dsc); +} + +static void _render_use(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +{ + LV_UNUSED(matrix); + lv_matrix_t imtx; + _setup_matrix(&imtx, dsc, obj); + + lv_svg_render_use_t * use = (lv_svg_render_use_t *)obj; + + lv_matrix_t mtx; + lv_matrix_identity(&mtx); + lv_matrix_translate(&mtx, use->x, use->y); + + lv_svg_render_obj_t * list = obj->head; + while(list) { + if(list->id) { + if(strcmp(use->xlink, list->id) == 0) { + if(list->clz->render) { + _prepare_render(list, dsc); + _special_render(obj, dsc); + list->clz->render(list, dsc, &mtx); + } + break; + } + } + list = list->next; + } + + _restore_matrix(&imtx, dsc); +} + +#if LV_USE_FREETYPE +static void _render_text(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) +{ + lv_svg_render_text_t * text = (lv_svg_render_text_t *)obj; + if(!text->font) { + if(!hal_funcs.get_font_path) { + return; + } + const char * font_path = hal_funcs.get_font_path(text->family); + if(!font_path) { + return; + } + text->font = lv_freetype_font_create(font_path, LV_FREETYPE_FONT_RENDER_MODE_OUTLINE, (uint32_t)text->size, + text->style); + } + + if(!text->font || !lv_freetype_is_outline_font(text->font)) { + LV_LOG_ERROR("svg current font is not outline font!"); + return; + } + + lv_matrix_t tmtx; + _setup_matrix(&tmtx, dsc, obj); + + if(matrix) { + lv_matrix_multiply(&dsc->current_dsc.matrix, matrix); + } + + if(lv_array_size(&text->path->ops) == 0) { /* empty path */ + lv_vector_path_t * glyph_path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); + // draw text contents and spans + lv_matrix_t mtx; + lv_matrix_identity(&mtx); + lv_matrix_translate(&mtx, text->x, text->y); + for(uint32_t i = 0; i < lv_array_size(&text->contents); i++) { + lv_svg_render_obj_t * ptext = *((lv_svg_render_obj_t **)lv_array_at(&text->contents, i)); + lv_svg_render_content_t * content = (lv_svg_render_content_t *)ptext; + + if(content->render_content) { + content->render_content(content, dsc, &mtx); + } + else { + float scale = text->size / 128.0f; + for(uint32_t j = 0; j < content->count; j++) { + uint32_t letter = content->letters[j]; + lv_font_glyph_dsc_t g; + lv_font_get_glyph_dsc(text->font, &g, letter, '\0'); + lv_vector_path_t * p = (lv_vector_path_t *)lv_font_get_glyph_bitmap(&g, NULL); + lv_vector_path_clear(glyph_path); + lv_vector_path_copy(glyph_path, p); + uint32_t letter_w = g.box_w > 0 ? g.box_w : g.adv_w; + + lv_matrix_t scale_matrix = mtx; + lv_matrix_translate(&mtx, g.ofs_x, 0); + lv_matrix_scale(&scale_matrix, scale, scale); + lv_matrix_transform_path(&scale_matrix, glyph_path); + + lv_vector_path_append_path(text->path, glyph_path); + text->font->release_glyph(text->font, &g); + lv_matrix_translate(&mtx, letter_w, 0); + } + } + } + lv_vector_path_delete(glyph_path); + lv_vector_path_get_bounding(text->path, &text->bounds); + } + + _copy_draw_dsc_from_ref(dsc, obj); + lv_vector_dsc_add_path(dsc, text->path); + + _restore_matrix(&tmtx, dsc); +} + +static void _render_span(const lv_svg_render_content_t * content, lv_vector_dsc_t * dsc, lv_matrix_t * matrix) +{ + lv_svg_render_obj_t * obj = (lv_svg_render_obj_t *)content; + + lv_svg_render_tspan_t * span = (lv_svg_render_tspan_t *)content; + if(!span->font) { + if(!hal_funcs.get_font_path) { + return; + } + const char * font_path = hal_funcs.get_font_path(span->family); + if(!font_path) { + return; + } + span->font = lv_freetype_font_create(font_path, LV_FREETYPE_FONT_RENDER_MODE_OUTLINE, (uint32_t)span->size, + span->style); + } + + if(!span->font || !lv_freetype_is_outline_font(span->font)) { + LV_LOG_ERROR("svg current font is not outline font!"); + return; + } + + struct _lv_svg_draw_dsc save_dsc; + lv_memzero(&save_dsc, sizeof(struct _lv_svg_draw_dsc)); + _copy_draw_dsc(&(save_dsc.dsc), &(dsc->current_dsc)); + + _copy_draw_dsc(&(dsc->current_dsc), &(obj->dsc)); + + if(lv_array_size(&span->path->ops) == 0) { /* empty path */ + lv_vector_path_t * glyph_path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); + // draw text contents and spans + lv_matrix_t * mtx = matrix; + + float scale = span->size / 128.0f; + for(uint32_t j = 0; j < content->count; j++) { + uint32_t letter = content->letters[j]; + lv_font_glyph_dsc_t g; + lv_font_get_glyph_dsc(span->font, &g, letter, '\0'); + lv_vector_path_t * p = (lv_vector_path_t *)lv_font_get_glyph_bitmap(&g, NULL); + lv_vector_path_clear(glyph_path); + lv_vector_path_copy(glyph_path, p); + uint32_t letter_w = g.box_w > 0 ? g.box_w : g.adv_w; + + lv_matrix_t scale_matrix = *mtx; + lv_matrix_translate(mtx, g.ofs_x, 0); + lv_matrix_scale(&scale_matrix, scale, scale); + lv_matrix_transform_path(&scale_matrix, glyph_path); + + lv_vector_path_append_path(span->path, glyph_path); + span->font->release_glyph(span->font, &g); + lv_matrix_translate(mtx, letter_w, 0); + } + lv_vector_path_delete(glyph_path); + lv_vector_path_get_bounding(span->path, &span->bounds); + } + _copy_draw_dsc_from_ref(dsc, obj); + lv_vector_dsc_add_path(dsc, span->path); + + _copy_draw_dsc(&(dsc->current_dsc), &(save_dsc.dsc)); +} +#endif + +// get bounds functions + +static void _get_viewport_bounds(const lv_svg_render_obj_t * obj, lv_area_t * area) +{ + lv_svg_render_viewport_t * viewport = (lv_svg_render_viewport_t *)obj; + area->x1 = 0; + area->y1 = 0; + area->x2 = (int32_t)roundf(viewport->width); + area->y2 = (int32_t)roundf(viewport->height); +} + +static void _get_rect_bounds(const lv_svg_render_obj_t * obj, lv_area_t * area) +{ + lv_svg_render_rect_t * rect = (lv_svg_render_rect_t *)obj; + area->x1 = (int32_t)rect->x; + area->y1 = (int32_t)rect->y; + area->x2 = (int32_t)(rect->x + rect->width); + area->y2 = (int32_t)(rect->y + rect->height); +} + +static void _get_circle_bounds(const lv_svg_render_obj_t * obj, lv_area_t * area) +{ + lv_svg_render_circle_t * circle = (lv_svg_render_circle_t *)obj; + area->x1 = (int32_t)(circle->cx - circle->r); + area->y1 = (int32_t)(circle->cy - circle->r); + area->x2 = (int32_t)(circle->cx + circle->r); + area->y2 = (int32_t)(circle->cy + circle->r); +} + +static void _get_ellipse_bounds(const lv_svg_render_obj_t * obj, lv_area_t * area) +{ + lv_svg_render_ellipse_t * ellipse = (lv_svg_render_ellipse_t *)obj; + area->x1 = (int32_t)(ellipse->cx - ellipse->rx); + area->y1 = (int32_t)(ellipse->cy - ellipse->ry); + area->x2 = (int32_t)(ellipse->cx + ellipse->rx); + area->y2 = (int32_t)(ellipse->cy + ellipse->ry); +} + +static void _get_line_bounds(const lv_svg_render_obj_t * obj, lv_area_t * area) +{ + lv_svg_render_line_t * line = (lv_svg_render_line_t *)obj; + area->x1 = (int32_t)(line->x1); + area->y1 = (int32_t)(line->y1); + area->x2 = (int32_t)(line->x2); + area->y2 = (int32_t)(line->y2); +} + +static void _get_poly_bounds(const lv_svg_render_obj_t * obj, lv_area_t * area) +{ + lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj; + lv_area_copy(area, &poly->bounds); +} + +#if LV_USE_FREETYPE +static void _get_text_bounds(const lv_svg_render_obj_t * obj, lv_area_t * area) +{ + lv_svg_render_text_t * text = (lv_svg_render_text_t *)obj; + lv_area_copy(area, &text->bounds); +} + +static void _get_tspan_bounds(const lv_svg_render_obj_t * obj, lv_area_t * area) +{ + lv_svg_render_tspan_t * tspan = (lv_svg_render_tspan_t *)obj; + lv_area_copy(area, &tspan->bounds); +} +#endif + +// get size fucctions +static uint32_t _calc_path_data_size(lv_vector_path_t * path) +{ + uint32_t size = 0; + size += path->ops.capacity * path->ops.element_size; + size += path->points.capacity * path->points.element_size; + size += sizeof(int32_t); + return size; +} + +static void _get_obj_size(const struct _lv_svg_render_obj * obj, uint32_t * size) +{ + *size += sizeof(lv_svg_render_obj_t); + if(obj->id) { + *size += strlen(obj->id); + } + if(obj->fill_ref) { + *size += strlen(obj->fill_ref); + } + if(obj->stroke_ref) { + *size += strlen(obj->stroke_ref); + } +} + +static void _get_viewport_size(const struct _lv_svg_render_obj * obj, uint32_t * size) +{ + _get_obj_size(obj, size); + *size += sizeof(float) * 2; + *size += sizeof(bool); +} + +static void _get_rect_size(const struct _lv_svg_render_obj * obj, uint32_t * size) +{ + _get_obj_size(obj, size); + *size += sizeof(float) * 6; +} + +static void _get_circle_size(const struct _lv_svg_render_obj * obj, uint32_t * size) +{ + _get_obj_size(obj, size); + *size += sizeof(float) * 3; +} + +static void _get_ellipse_size(const struct _lv_svg_render_obj * obj, uint32_t * size) +{ + _get_obj_size(obj, size); + *size += sizeof(float) * 4; +} + +static void _get_line_size(const struct _lv_svg_render_obj * obj, uint32_t * size) +{ + _get_obj_size(obj, size); + *size += sizeof(float) * 4; +} + +static void _get_poly_size(const struct _lv_svg_render_obj * obj, uint32_t * size) +{ + _get_obj_size(obj, size); + lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj; + lv_vector_path_t * path = poly->path; + + *size += _calc_path_data_size(path); + *size += sizeof(lv_vector_path_t); + *size += sizeof(lv_area_t); + *size += sizeof(void *); +} + +static void _get_use_size(const struct _lv_svg_render_obj * obj, uint32_t * size) +{ + _get_obj_size(obj, size); + lv_svg_render_use_t * use = (lv_svg_render_use_t *)obj; + if(use->xlink) { + *size += lv_strlen(use->xlink); + } + *size += sizeof(float) * 2; + *size += sizeof(void *); + +} + +static void _get_image_size(const struct _lv_svg_render_obj * obj, uint32_t * size) +{ + _get_obj_size(obj, size); + *size += sizeof(lv_draw_image_dsc_t); + *size += sizeof(lv_svg_aspect_ratio_t); + *size += sizeof(float) * 4; +} + +static void _get_solid_size(const struct _lv_svg_render_obj * obj, uint32_t * size) +{ + _get_obj_size(obj, size); + *size += sizeof(lv_color_t); + *size += sizeof(float); +} + +static void _get_grad_size(const struct _lv_svg_render_obj * obj, uint32_t * size) +{ + _get_obj_size(obj, size); + *size += sizeof(lv_vector_gradient_t); + *size += sizeof(lv_svg_gradient_units_t); +} + +#if LV_USE_FREETYPE +static void _get_span_size(const struct _lv_svg_render_obj * obj, uint32_t * size) +{ + _get_obj_size(obj, size); + lv_svg_render_tspan_t * span = (lv_svg_render_tspan_t *)obj; + if(span->family) { + *size += lv_strlen(span->family); + } + + *size += _calc_path_data_size(span->path); + *size += sizeof(float); + *size += sizeof(lv_freetype_font_style_t); + *size += sizeof(lv_vector_path_t); + *size += sizeof(lv_area_t); + *size += sizeof(void *) * 3; +} + +static void _get_txt_size(const struct _lv_svg_render_obj * obj, uint32_t * size) +{ + _get_obj_size(obj, size); + lv_svg_render_text_t * txt = (lv_svg_render_text_t *)obj; + if(txt->family) { + *size += lv_strlen(txt->family); + } + + *size += lv_array_capacity(&txt->contents) * sizeof(void *); + *size += _calc_path_data_size(txt->path); + *size += sizeof(float) * 3; + *size += sizeof(lv_freetype_font_style_t); + *size += sizeof(lv_vector_path_t); + *size += sizeof(lv_area_t); + *size += sizeof(void *) * 3; +} + +static void _get_content_size(const struct _lv_svg_render_obj * obj, uint32_t * size) +{ + _get_obj_size(obj, size); + lv_svg_render_content_t * content = (lv_svg_render_content_t *)obj; + *size += sizeof(uint32_t) * (content->count + 1); +} +#endif + +static void _get_group_size(const struct _lv_svg_render_obj * obj, uint32_t * size) +{ + _get_obj_size(obj, size); + lv_svg_render_group_t * group = (lv_svg_render_group_t *)obj; + *size += lv_array_capacity(&group->items) * sizeof(void *); +} + +// destroy functions +static void _destroy_poly(lv_svg_render_obj_t * obj) +{ + lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj; + lv_vector_path_delete(poly->path); +} + +static void _destroy_use(lv_svg_render_obj_t * obj) +{ + lv_svg_render_use_t * use = (lv_svg_render_use_t *)obj; + if(use->xlink) { + lv_free(use->xlink); + } +} + +static void _destroy_group(lv_svg_render_obj_t * obj) +{ + lv_svg_render_group_t * group = (lv_svg_render_group_t *)obj; + lv_array_deinit(&group->items); +} + +#if LV_USE_FREETYPE +static void _destroy_text(lv_svg_render_obj_t * obj) +{ + lv_svg_render_text_t * text = (lv_svg_render_text_t *)obj; + if(text->font) { + lv_freetype_font_delete(text->font); + } + if(text->family) { + lv_free(text->family); + } + lv_array_deinit(&text->contents); + lv_vector_path_delete(text->path); +} + +static void _destroy_content(lv_svg_render_obj_t * obj) +{ + lv_svg_render_content_t * content = (lv_svg_render_content_t *)obj; + if(content->letters) { + lv_free(content->letters); + } +} + +static void _destroy_tspan(lv_svg_render_obj_t * obj) +{ + lv_svg_render_tspan_t * span = (lv_svg_render_tspan_t *)obj; + if(span->font) { + lv_freetype_font_delete(span->font); + } + + if(span->family) { + lv_free(span->family); + } + + _destroy_content(obj); + lv_vector_path_delete(span->path); +} + +#endif + +static lv_svg_render_class svg_viewport_class = { + .init = _init_viewport, + .render = _render_viewport, + .set_attr = _set_viewport_attr, + .get_bounds = _get_viewport_bounds, + .get_size = _get_viewport_size, +}; + +static lv_svg_render_class svg_rect_class = { + .init = _init_obj, + .render = _render_rect, + .set_attr = _set_rect_attr, + .get_bounds = _get_rect_bounds, + .get_size = _get_rect_size, +}; + +static lv_svg_render_class svg_circle_class = { + .init = _init_obj, + .render = _render_circle, + .set_attr = _set_circle_attr, + .get_bounds = _get_circle_bounds, + .get_size = _get_circle_size, +}; + +static lv_svg_render_class svg_ellipse_class = { + .init = _init_obj, + .render = _render_ellipse, + .set_attr = _set_ellipse_attr, + .get_bounds = _get_ellipse_bounds, + .get_size = _get_ellipse_size, +}; + +static lv_svg_render_class svg_line_class = { + .init = _init_obj, + .render = _render_line, + .set_attr = _set_line_attr, + .get_bounds = _get_line_bounds, + .get_size = _get_line_size, +}; + +static lv_svg_render_class svg_polyline_class = { + .init = _init_poly, + .render = _render_poly, + .set_attr = _set_polyline_attr, + .get_bounds = _get_poly_bounds, + .destroy = _destroy_poly, + .get_size = _get_poly_size, +}; + +static lv_svg_render_class svg_polygon_class = { + .init = _init_poly, + .render = _render_poly, + .set_attr = _set_polygon_attr, + .get_bounds = _get_poly_bounds, + .destroy = _destroy_poly, + .get_size = _get_poly_size, +}; + +static lv_svg_render_class svg_path_class = { + .init = _init_poly, + .render = _render_poly, + .set_attr = _set_path_attr, + .get_bounds = _get_poly_bounds, + .destroy = _destroy_poly, + .get_size = _get_poly_size, +}; + +#if LV_USE_FREETYPE +static lv_svg_render_class svg_text_class = { + .init = _init_text, + .set_attr = _set_text_attr, + .render = _render_text, + .get_bounds = _get_text_bounds, + .destroy = _destroy_text, + .get_size = _get_txt_size, +}; + +static lv_svg_render_class svg_tspan_class = { + .init = _init_tspan, + .set_attr = _set_tspan_attr, + .get_bounds = _get_tspan_bounds, + .destroy = _destroy_tspan, + .get_size = _get_span_size, +}; + +static lv_svg_render_class svg_content_class = { + .init = _init_content, + .destroy = _destroy_content, + .get_size = _get_content_size, +}; +#endif + +static lv_svg_render_class svg_image_class = { + .init = _init_image, + .render = _render_image, + .set_attr = _set_image_attr, + .get_size = _get_image_size, +}; + +static lv_svg_render_class svg_use_class = { + .init = _init_obj, + .set_attr = _set_use_attr, + .render = _render_use, + .destroy = _destroy_use, + .get_size = _get_use_size, +}; + +static lv_svg_render_class svg_solid_class = { + .init = _init_obj, + .set_attr = _set_solid_attr, + .set_paint_ref = _set_solid_ref, + .get_size = _get_solid_size, +}; + +static lv_svg_render_class svg_grad_class = { + .init = _init_gradient, + .set_attr = _set_gradient_attr, + .set_paint_ref = _set_gradient_ref, + .get_size = _get_grad_size, +}; + +static lv_svg_render_class svg_group_class = { + .init = _init_group, + .set_attr = _set_attr, + .render = _render_group, + .destroy = _destroy_group, + .get_size = _get_group_size, +}; + +static lv_svg_render_obj_t * _lv_svg_render_create(const lv_svg_node_t * node, + struct _lv_svg_drawing_builder_state * state) +{ + switch(node->type) { + case LV_SVG_TAG_SVG: { + lv_svg_render_viewport_t * view = lv_zalloc(sizeof(lv_svg_render_viewport_t)); + LV_ASSERT_MALLOC(view); + view->base.clz = &svg_viewport_class; + _set_render_attrs(LV_SVG_RENDER_OBJ(view), node, state); + return LV_SVG_RENDER_OBJ(view); + } + case LV_SVG_TAG_RECT: { + lv_svg_render_rect_t * rect = lv_zalloc(sizeof(lv_svg_render_rect_t)); + LV_ASSERT_MALLOC(rect); + rect->base.clz = &svg_rect_class; + _set_render_attrs(LV_SVG_RENDER_OBJ(rect), node, state); + return LV_SVG_RENDER_OBJ(rect); + } + case LV_SVG_TAG_CIRCLE: { + lv_svg_render_circle_t * circle = lv_zalloc(sizeof(lv_svg_render_circle_t)); + LV_ASSERT_MALLOC(circle); + circle->base.clz = &svg_circle_class; + _set_render_attrs(LV_SVG_RENDER_OBJ(circle), node, state); + return LV_SVG_RENDER_OBJ(circle); + } + case LV_SVG_TAG_ELLIPSE: { + lv_svg_render_ellipse_t * ellipse = lv_zalloc(sizeof(lv_svg_render_ellipse_t)); + LV_ASSERT_MALLOC(ellipse); + ellipse->base.clz = &svg_ellipse_class; + _set_render_attrs(LV_SVG_RENDER_OBJ(ellipse), node, state); + return LV_SVG_RENDER_OBJ(ellipse); + } + case LV_SVG_TAG_LINE: { + lv_svg_render_line_t * line = lv_zalloc(sizeof(lv_svg_render_line_t)); + LV_ASSERT_MALLOC(line); + line->base.clz = &svg_line_class; + _set_render_attrs(LV_SVG_RENDER_OBJ(line), node, state); + return LV_SVG_RENDER_OBJ(line); + } + case LV_SVG_TAG_POLYLINE: { + lv_svg_render_poly_t * poly = lv_zalloc(sizeof(lv_svg_render_poly_t)); + LV_ASSERT_MALLOC(poly); + poly->base.clz = &svg_polyline_class; + _set_render_attrs(LV_SVG_RENDER_OBJ(poly), node, state); + return LV_SVG_RENDER_OBJ(poly); + } + case LV_SVG_TAG_POLYGON: { + lv_svg_render_poly_t * poly = lv_zalloc(sizeof(lv_svg_render_poly_t)); + LV_ASSERT_MALLOC(poly); + poly->base.clz = &svg_polygon_class; + _set_render_attrs(LV_SVG_RENDER_OBJ(poly), node, state); + return LV_SVG_RENDER_OBJ(poly); + } + case LV_SVG_TAG_PATH: { + lv_svg_render_poly_t * poly = lv_zalloc(sizeof(lv_svg_render_poly_t)); + LV_ASSERT_MALLOC(poly); + poly->base.clz = &svg_path_class; + _set_render_attrs(LV_SVG_RENDER_OBJ(poly), node, state); + return LV_SVG_RENDER_OBJ(poly); + } +#if LV_USE_FREETYPE + case LV_SVG_TAG_TEXT: { + lv_svg_render_text_t * txt = lv_zalloc(sizeof(lv_svg_render_text_t)); + LV_ASSERT_MALLOC(txt); + txt->base.clz = &svg_text_class; + _set_render_attrs(LV_SVG_RENDER_OBJ(txt), node, state); + return LV_SVG_RENDER_OBJ(txt); + } + case LV_SVG_TAG_TSPAN: { + lv_svg_render_tspan_t * span = lv_zalloc(sizeof(lv_svg_render_tspan_t)); + LV_ASSERT_MALLOC(span); + lv_svg_render_content_t * content = (lv_svg_render_content_t *)span; + content->render_content = _render_span; + content->base.clz = &svg_tspan_class; + _set_render_attrs(LV_SVG_RENDER_OBJ(span), node, state); + return LV_SVG_RENDER_OBJ(span); + } + case LV_SVG_TAG_CONTENT: { + lv_svg_render_content_t * content = lv_zalloc(sizeof(lv_svg_render_content_t)); + LV_ASSERT_MALLOC(content); + content->base.clz = &svg_content_class; + _set_render_attrs(LV_SVG_RENDER_OBJ(content), node, state); + return LV_SVG_RENDER_OBJ(content); + } +#endif + case LV_SVG_TAG_IMAGE: { + lv_svg_render_image_t * image = lv_zalloc(sizeof(lv_svg_render_image_t)); + LV_ASSERT_MALLOC(image); + image->base.clz = &svg_image_class; + _set_render_attrs(LV_SVG_RENDER_OBJ(image), node, state); + return LV_SVG_RENDER_OBJ(image); + } + case LV_SVG_TAG_USE: { + lv_svg_render_use_t * use = lv_zalloc(sizeof(lv_svg_render_use_t)); + LV_ASSERT_MALLOC(use); + use->base.clz = &svg_use_class; + _set_render_attrs(LV_SVG_RENDER_OBJ(use), node, state); + return LV_SVG_RENDER_OBJ(use); + } + case LV_SVG_TAG_SOLID_COLOR: { + lv_svg_render_solid_t * solid = lv_zalloc(sizeof(lv_svg_render_solid_t)); + LV_ASSERT_MALLOC(solid); + solid->base.clz = &svg_solid_class; + _set_render_attrs(LV_SVG_RENDER_OBJ(solid), node, state); + return LV_SVG_RENDER_OBJ(solid); + } + case LV_SVG_TAG_RADIAL_GRADIENT: + case LV_SVG_TAG_LINEAR_GRADIENT: { + lv_svg_render_gradient_t * grad = lv_zalloc(sizeof(lv_svg_render_gradient_t)); + LV_ASSERT_MALLOC(grad); + grad->base.clz = &svg_grad_class; + if(node->type == LV_SVG_TAG_LINEAR_GRADIENT) { + grad->dsc.style = LV_VECTOR_GRADIENT_STYLE_LINEAR; + } + else { // radial gradient + grad->dsc.style = LV_VECTOR_GRADIENT_STYLE_RADIAL; + } + _set_render_attrs(LV_SVG_RENDER_OBJ(grad), node, state); + return LV_SVG_RENDER_OBJ(grad); + } + case LV_SVG_TAG_G: { + lv_svg_render_group_t * group = lv_zalloc(sizeof(lv_svg_render_group_t)); + LV_ASSERT_MALLOC(group); + group->base.clz = &svg_group_class; + _set_render_attrs(LV_SVG_RENDER_OBJ(group), node, state); + return LV_SVG_RENDER_OBJ(group); + } + default: + return NULL; + } +} + +static bool _lv_svg_doc_walk_cb(const lv_tree_node_t * node, void * data) +{ + struct _lv_svg_drawing_builder_state * state = (struct _lv_svg_drawing_builder_state *)data; + lv_svg_render_obj_t * obj = _lv_svg_render_create(LV_SVG_NODE(node), state); + if(!obj) { + return true; + } + + if(state->in_defs) { + obj->flags |= _RENDER_IN_DEFS; + } + if(state->in_group_deps > 0) { + obj->flags |= _RENDER_IN_GROUP; + } + + if(state->list == NULL) { + state->list = obj; + state->tail = obj; + } + else { + state->tail->next = obj; + state->tail = obj; + } + LV_SVG_NODE(node)->render_obj = obj; + return true; +} + +static bool _lv_svg_doc_walk_before_cb(const lv_tree_node_t * node, void * data) +{ + struct _lv_svg_drawing_builder_state * state = (struct _lv_svg_drawing_builder_state *)data; + lv_svg_node_t * svg_node = LV_SVG_NODE(node); +#if LV_USE_FREETYPE + if(svg_node->type == LV_SVG_TAG_TEXT) { + state->in_text = true; + state->cur_text = svg_node; + } +#endif + if(svg_node->type == LV_SVG_TAG_DEFS) { + state->in_defs = true; + } + + if(svg_node->type == LV_SVG_TAG_G) { + state->in_group_deps++; + } + state->draw_dsc = _lv_svg_draw_dsc_push(state->draw_dsc); + return true; +} + +static void _lv_svg_doc_walk_after_cb(const lv_tree_node_t * node, void * data) +{ + struct _lv_svg_drawing_builder_state * state = (struct _lv_svg_drawing_builder_state *)data; + lv_svg_node_t * svg_node = LV_SVG_NODE(node); + if(svg_node->render_obj) { + _copy_draw_dsc(&(LV_SVG_NODE(node)->render_obj->dsc), &(state->draw_dsc->dsc)); + } +#if LV_USE_FREETYPE + if(state->in_text) { + if(svg_node->type == LV_SVG_TAG_TSPAN || svg_node->type == LV_SVG_TAG_CONTENT) { + if(LV_TREE_NODE(svg_node)->parent == LV_TREE_NODE(state->cur_text)) { + lv_svg_render_text_t * text = (lv_svg_render_text_t *)state->cur_text->render_obj; + if((lv_array_size(&text->contents) + 1) > lv_array_capacity(&text->contents)) { + lv_array_resize(&text->contents, text->contents.capacity << 1); + } + lv_array_push_back(&text->contents, (uint8_t *)(&svg_node->render_obj)); + } + } + } + if(svg_node->type == LV_SVG_TAG_TEXT) { + state->in_text = false; + state->cur_text = NULL; + } +#endif + if(svg_node->type == LV_SVG_TAG_G) { + lv_svg_render_group_t * group = (lv_svg_render_group_t *)svg_node->render_obj; + uint32_t count = LV_TREE_NODE(node)->child_cnt; + for(uint32_t i = 0; i < count; i++) { + lv_svg_node_t * child = LV_SVG_NODE_CHILD(node, i); + if(child->render_obj) { // not defs + lv_array_push_back(&group->items, (uint8_t *)(&child->render_obj)); + } + } + + state->in_group_deps--; + if(state->in_group_deps == 0) { + group->base.flags &= ~_RENDER_IN_GROUP; + } + } + if(svg_node->type == LV_SVG_TAG_DEFS) { + state->in_defs = false; + } + state->draw_dsc = _lv_svg_draw_dsc_pop(state->draw_dsc); +} + +#if LV_USE_FREETYPE +static void _freetype_outline_cb(lv_event_t * e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_freetype_outline_event_param_t * param = lv_event_get_param(e); + switch(code) { + case LV_EVENT_CREATE: + param->outline = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM); + break; + case LV_EVENT_DELETE: + lv_vector_path_delete(param->outline); + break; + case LV_EVENT_INSERT: { + if(param->type == LV_FREETYPE_OUTLINE_MOVE_TO) { + lv_fpoint_t pt = {0}; + pt.x = LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.x); + pt.y = -LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.y); + lv_vector_path_move_to(param->outline, &pt); + } + else if(param->type == LV_FREETYPE_OUTLINE_LINE_TO) { + lv_fpoint_t pt = {0}; + pt.x = LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.x); + pt.y = -LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.y); + lv_vector_path_line_to(param->outline, &pt); + } + else if(param->type == LV_FREETYPE_OUTLINE_CUBIC_TO) { + lv_fpoint_t pt[3] = {0}; + pt[0].x = LV_FREETYPE_F26DOT6_TO_FLOAT(param->control1.x); + pt[0].y = -LV_FREETYPE_F26DOT6_TO_FLOAT(param->control1.y); + pt[1].x = LV_FREETYPE_F26DOT6_TO_FLOAT(param->control2.x); + pt[1].y = -LV_FREETYPE_F26DOT6_TO_FLOAT(param->control2.y); + pt[2].x = LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.x); + pt[2].y = -LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.y); + lv_vector_path_cubic_to(param->outline, &pt[0], &pt[1], &pt[2]); + } + else if(param->type == LV_FREETYPE_OUTLINE_CONIC_TO) { + lv_fpoint_t pt[2] = {0}; + pt[0].x = LV_FREETYPE_F26DOT6_TO_FLOAT(param->control1.x); + pt[0].y = -LV_FREETYPE_F26DOT6_TO_FLOAT(param->control1.y); + pt[1].x = LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.x); + pt[1].y = -LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.y); + lv_vector_path_quad_to(param->outline, &pt[0], &pt[1]); + } + else if(param->type == LV_FREETYPE_OUTLINE_END) { + lv_vector_path_close(param->outline); + } + } + break; + default: + LV_LOG_WARN("unknown event code: %d", code); + break; + } +} +#endif +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_svg_render_obj_t * lv_svg_render_create(const lv_svg_node_t * svg_doc) +{ + if(!svg_doc) { + return NULL; + } + + struct _lv_svg_draw_dsc * dsc = _lv_svg_draw_dsc_create(); + struct _lv_svg_drawing_builder_state state = { + .doc = svg_doc, + .draw_dsc = dsc, + .in_group_deps = 0, + .in_defs = false, +#if LV_USE_FREETYPE + .in_text = false, + .cur_text = NULL, +#endif + .list = NULL, .tail = NULL + }; + + lv_tree_walk(LV_TREE_NODE(svg_doc), LV_TREE_WALK_PRE_ORDER, _lv_svg_doc_walk_cb, _lv_svg_doc_walk_before_cb, + _lv_svg_doc_walk_after_cb, &state); + _lv_svg_draw_dsc_delete(dsc); + return state.list; +} + +void lv_svg_render_delete(lv_svg_render_obj_t * list) +{ + while(list) { + lv_svg_render_obj_t * obj = list; + list = list->next; + + _deinit_draw_dsc(&(obj->dsc)); + + if(obj->clz->destroy) { + obj->clz->destroy(obj); + } + if(obj->id) { + lv_free(obj->id); + } + if(obj->fill_ref) { + lv_free(obj->fill_ref); + } + if(obj->stroke_ref) { + lv_free(obj->stroke_ref); + } + lv_free(obj); + } +} + +uint32_t lv_svg_render_get_size(const lv_svg_render_obj_t * render) +{ + if(!render) { + return 0; + } + + uint32_t size = 0; + const lv_svg_render_obj_t * cur = render; + while(cur) { + if(cur->clz->get_size) { + cur->clz->get_size(cur, &size); + } + cur = cur->next; + } + return size; +} + +lv_result_t lv_svg_render_get_viewport_size(const lv_svg_render_obj_t * render, float * width, float * height) +{ + if(!render) { + LV_LOG_WARN("Invalid render object"); + return LV_RESULT_INVALID; + } + + if(render->clz != &svg_viewport_class) { + LV_LOG_WARN("Invalid render object type"); + return LV_RESULT_INVALID; + } + const lv_svg_render_viewport_t * cur = (const lv_svg_render_viewport_t *)render; + if(width) { + *width = cur->width; + } + if(height) { + *height = cur->height; + } + return LV_RESULT_OK; +} + +void lv_draw_svg_render(lv_vector_dsc_t * dsc, const lv_svg_render_obj_t * render) +{ + if(!render || !dsc) { + return; + } + + const lv_svg_render_obj_t * cur = render; + while(cur) { + if(cur->clz->render && ((cur->flags & 3) == _RENDER_NORMAL)) { + _prepare_render(cur, dsc); + cur->clz->render(cur, dsc, NULL); + } + cur = cur->next; + } +} + +void lv_draw_svg(lv_layer_t * layer, const lv_svg_node_t * svg_doc) +{ + if(!svg_doc) { + return; + } + + lv_vector_dsc_t * dsc = lv_vector_dsc_create(layer); + lv_svg_render_obj_t * list = lv_svg_render_create(svg_doc); + lv_draw_svg_render(dsc, list); + lv_draw_vector(dsc); + lv_svg_render_delete(list); + lv_vector_dsc_delete(dsc); +} + +/********************** + * STATIC FUNCTIONS + **********************/ +#endif /*LV_USE_SVG*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_render.h b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_render.h new file mode 100644 index 000000000..d2e87860c --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_render.h @@ -0,0 +1,125 @@ +/** + * @file lv_svg_render.h + * + */ + +#ifndef LV_SVG_RENDER_H +#define LV_SVG_RENDER_H + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" + +#if LV_USE_SVG +#if !LV_USE_VECTOR_GRAPHIC + #error "LV_USE_SVG requires LV_USE_VECTOR_GRAPHIC = 1" +#endif + +#include "lv_svg.h" +#include "../../misc/lv_types.h" +#include "../../draw/lv_draw_vector_private.h" + +/********************* + * DEFINES + *********************/ + +#define LV_SVG_RENDER_OBJ(n) ((lv_svg_render_obj_t*)(n)) + +/********************** + * TYPEDEFS + **********************/ +struct _lv_svg_render_class; + +typedef struct _lv_svg_render_obj { + struct _lv_svg_render_obj * next; + lv_svg_tag_t tag; + uint32_t flags; + char * id; + lv_vector_draw_dsc_t dsc; + lv_matrix_t matrix; + + /* for url(XXX) reference */ + struct _lv_svg_render_obj * head; + char * fill_ref; + char * stroke_ref; + struct _lv_svg_render_class * clz; +} lv_svg_render_obj_t; + +typedef struct _lv_svg_render_class { + void (*set_paint_ref)(struct _lv_svg_render_obj * obj, lv_vector_draw_dsc_t * dsc, + const struct _lv_svg_render_obj * target_obj, bool fill); + + void (*init)(struct _lv_svg_render_obj * obj, const lv_svg_node_t * node); + void (*render)(const struct _lv_svg_render_obj * obj, lv_vector_dsc_t * dsc, const lv_matrix_t * matrix); + void (*set_attr)(struct _lv_svg_render_obj * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr); + void (*get_bounds)(const struct _lv_svg_render_obj * obj, lv_area_t * area); + void (*get_size)(const struct _lv_svg_render_obj * obj, uint32_t * size); + void (*destroy)(struct _lv_svg_render_obj * obj); +} lv_svg_render_class; + +typedef struct _lv_svg_render_hal { + void (*load_image)(const char * image_url, lv_draw_image_dsc_t * img_dsc); + const char * (*get_font_path)(const char * font_family); +} lv_svg_render_hal_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * @brief Initialize the SVG render + * @param hal pointer to a structure with rendering functions + */ +void lv_svg_render_init(const lv_svg_render_hal_t * hal); + +/** + * @brief Create a new SVG render from an SVG document + * @param svg_doc pointer to the SVG document + * @return pointer to the new SVG render object + */ +lv_svg_render_obj_t * lv_svg_render_create(const lv_svg_node_t * svg_doc); + +/** + * @brief Delete an SVG render object + * @param render pointer to the SVG render object to delete + */ +void lv_svg_render_delete(lv_svg_render_obj_t * render); + +/** + * @brief Get size of render objects + * @param render pointer to the SVG render object + * @return the bytes of SVG render objects + */ +uint32_t lv_svg_render_get_size(const lv_svg_render_obj_t * render); + +/** + * @brief Get viewport's width and height of the render object + * @param render pointer to the SVG render object + * @param width pointer to save the width of the viewport of the SVG render object + * @param height pointer to save the height of the viewport of the SVG render object + * @return lv_result_t, LV_RESULT_OK if success, LV_RESULT_INVALID if fail + */ +lv_result_t lv_svg_render_get_viewport_size(const lv_svg_render_obj_t * render, float * width, float * height); + +/** + * @brief Render an SVG object to a vector graphics + * @param dsc pointer to the vector graphics descriptor + * @param render pointer to the SVG render object to render + */ +void lv_draw_svg_render(lv_vector_dsc_t * dsc, const lv_svg_render_obj_t * render); + +/** + * @brief Draw an SVG document to a layer + * @param layer pointer to the target layer + * @param svg_doc pointer to the SVG document to draw + */ +void lv_draw_svg(lv_layer_t * layer, const lv_svg_node_t * svg_doc); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_SVG*/ + +#endif /*LV_SVG_RENDER_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_token.c b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_token.c new file mode 100644 index 000000000..1c7643aed --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/svg/lv_svg_token.c @@ -0,0 +1,483 @@ +/** + * @file lv_svg_token.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_svg_token.h" +#if LV_USE_SVG + +#include "../../../lvgl.h" +#include +#include + +/********************* +* DEFINES +*********************/ + +/********************** +* TYPEDEFS +**********************/ + +/* + * tag mask quote mask tag search comment doc type xml inst + * | 0 0 0 | 0 0 | 0 | 0 | 0 | 0 | 0 | + */ +enum { + SVG_TAG_MASK = (1 << 3) - 1, + SVG_QUOTE_MASK = (1 << 5) - (1 << 3), + SVG_TAG = 1 << 5, + SVG_SEARCH = 1 << 6, + SVG_COMMENT = 1 << 7, + SVG_DOCTYPE = 1 << 8, + SVG_XMLINST = 1 << 9, +}; +typedef uint32_t _lv_svg_parser_bits_t; + +enum { + SVG_NO_QUOTE = 0, + SVG_SINGLE_QUOTE = 1, + SVG_DOUBLE_QUOTE = 2, +}; +typedef uint32_t _lv_svg_parser_quote_t; + +enum { + SVG_NO_TAG = 0, + SVG_TAG_NAME = 1, + SVG_ATTR_START = 2, + SVG_ATTR_NAME = 3, + SVG_SEARCH_EQUAL = 4, + SVG_SEARCH_VALUE = 5, + SVG_QUOTE_VALUE = 6, + SVG_VALUE = 7, +}; +typedef uint32_t _lv_svg_parser_tag_state_t; + +typedef struct { + uint32_t flags; + const char * cur; + const char * end; +} _lv_svg_parser_state_t; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void _set_state(_lv_svg_parser_state_t * state, uint32_t bit) +{ + state->flags |= bit; +} + +static void _clear_state(_lv_svg_parser_state_t * state, uint32_t bit) +{ + state->flags &= ~bit; +} + +static bool _is_state(_lv_svg_parser_state_t * state, uint32_t bit) +{ + return state->flags & bit; +} + +static void _set_tag_state(_lv_svg_parser_state_t * state, uint32_t bit) +{ + state->flags = (state->flags & ~SVG_TAG_MASK) | bit; +} + +static void _set_quote_state(_lv_svg_parser_state_t * state, uint32_t bit) +{ + state->flags = (state->flags & ~SVG_QUOTE_MASK) | (bit << 3); +} + +static bool _special_handle(_lv_svg_parser_state_t * state) +{ + return state->flags & (SVG_TAG | SVG_SEARCH | SVG_TAG_MASK | SVG_COMMENT | SVG_DOCTYPE | SVG_XMLINST); +} + +static void _lv_svg_token_init(_lv_svg_token_t * token) +{ + token->start = NULL; + token->end = NULL; + token->type = LV_SVG_TOKEN_CONTENT; + token->flat = false; + token->cur_attr = NULL; + lv_array_init(&token->attrs, LV_ARRAY_DEFAULT_CAPACITY, sizeof(_lv_svg_token_attr_t)); +} + +static void _lv_svg_token_reset(_lv_svg_token_t * token) +{ + token->start = NULL; + token->end = NULL; + token->type = LV_SVG_TOKEN_CONTENT; + token->flat = false; + token->cur_attr = NULL; + lv_array_clear(&token->attrs); +} + +static bool _lv_svg_token_process(_lv_svg_token_t * token, svg_token_process cb, void * data) +{ + if(!token->start || SVG_TOKEN_LEN(token) == 0) + return true; + + bool ret = cb(token, data); + _lv_svg_token_reset(token); + return ret; +} + +static _lv_svg_token_attr_t * _new_svg_attr(_lv_svg_token_t * token) +{ + if((lv_array_size(&token->attrs) + 1) > lv_array_capacity(&token->attrs)) { + lv_array_resize(&token->attrs, token->attrs.capacity << 1); + } + + token->attrs.size++; + _lv_svg_token_attr_t * attr = lv_array_at(&token->attrs, token->attrs.size - 1); + lv_memset(attr, 0, sizeof(_lv_svg_token_attr_t)); + return attr; +} + +static void _svg_parser_xml_inst(_lv_svg_parser_state_t * state, _lv_svg_token_t * token) +{ + LV_UNUSED(token); + + while(state->cur <= state->end) { + char ch = *(state->cur); + if(ch == '>' && (*(state->cur - 1)) == '?') { + _clear_state(state, SVG_XMLINST); + state->cur++; + break; + } + state->cur++; + } +} + +static void _svg_parser_comment(_lv_svg_parser_state_t * state, _lv_svg_token_t * token) +{ + LV_UNUSED(token); + + while(state->cur <= state->end) { + char ch = *(state->cur); + if(ch == '>' && (*(state->cur - 1)) == '-' && (*(state->cur - 2)) == '-') { + _clear_state(state, SVG_COMMENT); + state->cur++; + break; + } + state->cur++; + } +} + +static void _svg_parser_doctype(_lv_svg_parser_state_t * state, _lv_svg_token_t * token) +{ + LV_UNUSED(token); + + //TODO: processing DTD type + while(state->cur <= state->end) { + char ch = *(state->cur); + if(ch == '>') { + _clear_state(state, SVG_DOCTYPE); + state->cur++; + break; + } + state->cur++; + } +} + +static bool _svg_parser_tag(_lv_svg_parser_state_t * state, _lv_svg_token_t * token, svg_token_process cb, void * data) +{ + while(state->cur <= state->end) { + switch(state->flags & SVG_TAG_MASK) { + case SVG_NO_TAG: { + if(!_lv_svg_token_process(token, cb, data)) { + return false; + } + state->cur++; + } + return true; + case SVG_TAG_NAME: { + char ch = *(state->cur); + if(ch == '/') { + token->type = LV_SVG_TOKEN_END; + state->cur++; + if(!token->start) { + token->start = state->cur; + } + continue; + } + else if(ch == '>' || isspace(ch)) { + token->end = state->cur; + _set_tag_state(state, SVG_ATTR_START); + continue; + } + else { + if(!token->start) { + token->type = LV_SVG_TOKEN_BEGIN; + token->start = state->cur; + } + state->cur++; + continue; + } + } + break; + case SVG_ATTR_START: { + char ch = *(state->cur); + if(!isspace(ch) && ch != '\'' && ch != '\"') { + if(ch == '/') { + token->flat = true; + state->cur++; + continue; + } + if(ch == '>') { + _set_tag_state(state, SVG_NO_TAG); + } + else { + token->cur_attr = NULL; + _set_tag_state(state, SVG_ATTR_NAME); + } + continue; + } + } + break; + case SVG_ATTR_NAME: { + if(!token->cur_attr) { + token->cur_attr = _new_svg_attr(token); + } + char ch = *(state->cur); + if(isspace(ch) || ch == '=' || ch == '/' || ch == '>') { + token->cur_attr->name_end = state->cur; + _set_tag_state(state, SVG_SEARCH_EQUAL); + continue; + } + else { + if(!token->cur_attr->name_start) { + token->cur_attr->name_start = state->cur; + } + state->cur++; + continue; + } + } + break; + case SVG_SEARCH_EQUAL: { + char ch = *(state->cur); + if(!isspace(ch) && ch != '/' && ch != '\'' && ch != '\"') { + if(ch == '=') { + _set_tag_state(state, SVG_SEARCH_VALUE); + } + else { + // attr name has empty value + token->cur_attr = NULL; + _set_tag_state(state, SVG_ATTR_START); + continue; + } + } + } + break; + case SVG_SEARCH_VALUE: { + char ch = *(state->cur); + if(!isspace(ch)) { + if(ch == '\'' || ch == '\"') { + if(ch == '\'') { + _set_quote_state(state, SVG_SINGLE_QUOTE); + } + else { + _set_quote_state(state, SVG_DOUBLE_QUOTE); + } + _set_tag_state(state, SVG_QUOTE_VALUE); + } + else { + _set_tag_state(state, SVG_VALUE); + continue; + } + } + } + break; + case SVG_QUOTE_VALUE: { + char ch = *(state->cur); + if((ch == '\'' && ((state->flags & SVG_QUOTE_MASK) >> 3) == SVG_SINGLE_QUOTE) + || (ch == '\"' && ((state->flags & SVG_QUOTE_MASK) >> 3) == SVG_DOUBLE_QUOTE)) { + if(!token->cur_attr->value_start) { + token->cur_attr->value_start = state->cur; + } + token->cur_attr->value_end = state->cur; + _set_quote_state(state, SVG_NO_QUOTE); + _set_tag_state(state, SVG_ATTR_START); + continue; + } + else { + if(!token->cur_attr->value_start) { + token->cur_attr->value_start = state->cur; + } + state->cur++; + continue; + } + } + break; + case SVG_VALUE: { + char ch = *(state->cur); + if(isspace(ch) || ch == '>' || ch == '/') { + if(!token->cur_attr->value_start) { + token->cur_attr->value_start = state->cur; + } + token->cur_attr->value_end = state->cur; + _set_quote_state(state, SVG_NO_QUOTE); + _set_tag_state(state, SVG_ATTR_START); + continue; + } + else { + if(!token->cur_attr->value_start) { + token->cur_attr->value_start = state->cur; + } + state->cur++; + continue; + } + } + break; + } + state->cur++; + } + return true; +} + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +bool _lv_svg_tokenizer(const char * svg_data, uint32_t data_len, svg_token_process cb, void * data) +{ + LV_ASSERT_NULL(svg_data); + LV_ASSERT(data_len > 0); + LV_ASSERT_NULL(cb); + LV_ASSERT_NULL(data); + + _lv_svg_token_t token; + _lv_svg_token_init(&token); + _lv_svg_parser_state_t state = { + .flags = 0, + .cur = svg_data, + .end = svg_data + data_len, + }; + + while(state.cur < state.end) { + char ch = *(state.cur); + if(ch == '\r' || ch == '\n') { // skip LR character + state.cur++; + continue; + } + else if(_special_handle(&state)) { + if(_is_state(&state, SVG_TAG)) { + _clear_state(&state, SVG_TAG); + switch(ch) { + case '/': // end tag + _set_tag_state(&state, SVG_TAG_NAME); + break; + case '!': { + // bounds - // tvgSwRasterTexmap.h --> _rasterTexmapPolygonMesh - // - // TODO: Should we calculate the exact path(s) of the triangle mesh instead? - // i.e. copy tvgSwShape.capp -> _genOutline? - // - // TODO: Cntrs? - auto triangles = mesh->triangles; - auto min = triangles[0].vertex[0].pt; - auto max = triangles[0].vertex[0].pt; - - for (uint32_t i = 0; i < mesh->triangleCnt; ++i) { - if (triangles[i].vertex[0].pt.x < min.x) min.x = triangles[i].vertex[0].pt.x; - else if (triangles[i].vertex[0].pt.x > max.x) max.x = triangles[i].vertex[0].pt.x; - if (triangles[i].vertex[0].pt.y < min.y) min.y = triangles[i].vertex[0].pt.y; - else if (triangles[i].vertex[0].pt.y > max.y) max.y = triangles[i].vertex[0].pt.y; - - if (triangles[i].vertex[1].pt.x < min.x) min.x = triangles[i].vertex[1].pt.x; - else if (triangles[i].vertex[1].pt.x > max.x) max.x = triangles[i].vertex[1].pt.x; - if (triangles[i].vertex[1].pt.y < min.y) min.y = triangles[i].vertex[1].pt.y; - else if (triangles[i].vertex[1].pt.y > max.y) max.y = triangles[i].vertex[1].pt.y; - - if (triangles[i].vertex[2].pt.x < min.x) min.x = triangles[i].vertex[2].pt.x; - else if (triangles[i].vertex[2].pt.x > max.x) max.x = triangles[i].vertex[2].pt.x; - if (triangles[i].vertex[2].pt.y < min.y) min.y = triangles[i].vertex[2].pt.y; - else if (triangles[i].vertex[2].pt.y > max.y) max.y = triangles[i].vertex[2].pt.y; - } - to[0] = {min.x, min.y}; - to[1] = {max.x, min.y}; - to[2] = {max.x, max.y}; - to[3] = {min.x, max.y}; - } else { - auto w = static_cast(image->w); - auto h = static_cast(image->h); - to[0] = {0, 0}; - to[1] = {w, 0}; - to[2] = {w, h}; - to[3] = {0, h}; - } + auto w = static_cast(image->w); + auto h = static_cast(image->h); + to[0] = {0, 0}; + to[1] = {w, 0}; + to[2] = {w, h}; + to[3] = {0, h}; for (int i = 0; i < 4; i++) { outline->pts.push(mathTransform(&to[i], transform)); @@ -111,25 +75,25 @@ static bool _genOutline(SwImage* image, const RenderMesh* mesh, const Matrix* tr /* External Class Implementation */ /************************************************************************/ -bool imagePrepare(SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid) +bool imagePrepare(SwImage* image, const Matrix& transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid) { image->direct = _onlyShifted(transform); //Fast track: Non-transformed image but just shifted. if (image->direct) { - image->ox = -static_cast(round(transform->e13)); - image->oy = -static_cast(round(transform->e23)); + image->ox = -static_cast(nearbyint(transform.e13)); + image->oy = -static_cast(nearbyint(transform.e23)); //Figure out the scale factor by transform matrix } else { - auto scaleX = sqrtf((transform->e11 * transform->e11) + (transform->e21 * transform->e21)); - auto scaleY = sqrtf((transform->e22 * transform->e22) + (transform->e12 * transform->e12)); + auto scaleX = sqrtf((transform.e11 * transform.e11) + (transform.e21 * transform.e21)); + auto scaleY = sqrtf((transform.e22 * transform.e22) + (transform.e12 * transform.e12)); image->scale = (fabsf(scaleX - scaleY) > 0.01f) ? 1.0f : scaleX; - if (mathZero(transform->e12) && mathZero(transform->e21)) image->scaled = true; + if (tvg::zero(transform.e12) && tvg::zero(transform.e21)) image->scaled = true; else image->scaled = false; } - if (!_genOutline(image, mesh, transform, mpool, tid)) return false; + if (!_genOutline(image, transform, mpool, tid)) return false; return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion, image->direct); } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMath.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMath.cpp index 8b8d8a4ba..6161276e4 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMath.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMath.cpp @@ -47,7 +47,7 @@ SwFixed mathMean(SwFixed angle1, SwFixed angle2) } -bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut) +int mathCubicAngle(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut) { auto d1 = base[2] - base[3]; auto d2 = base[1] - base[2]; @@ -57,7 +57,7 @@ bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, Sw if (d2.small()) { if (d3.small()) { angleIn = angleMid = angleOut = 0; - return true; + return -1; //ignoreable } else { angleIn = angleMid = angleOut = mathAtan(d3); } @@ -93,8 +93,8 @@ bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, Sw auto theta1 = abs(mathDiff(angleIn, angleMid)); auto theta2 = abs(mathDiff(angleMid, angleOut)); - if ((theta1 < (SW_ANGLE_PI / 8)) && (theta2 < (SW_ANGLE_PI / 8))) return true; - return false; + if ((theta1 < (SW_ANGLE_PI / 8)) && (theta2 < (SW_ANGLE_PI / 8))) return 0; //small size + return 1; } @@ -167,8 +167,8 @@ void mathRotate(SwPoint& pt, SwFixed angle) auto cosv = cosf(radian); auto sinv = sinf(radian); - pt.x = SwCoord(roundf((v.x * cosv - v.y * sinv) * 64.0f)); - pt.y = SwCoord(roundf((v.x * sinv + v.y * cosv) * 64.0f)); + pt.x = SwCoord(nearbyint((v.x * cosv - v.y * sinv) * 64.0f)); + pt.y = SwCoord(nearbyint((v.x * sinv + v.y * cosv) * 64.0f)); } @@ -182,7 +182,7 @@ SwFixed mathTan(SwFixed angle) SwFixed mathAtan(const SwPoint& pt) { if (pt.zero()) return 0; - return SwFixed(atan2f(TO_FLOAT(pt.y), TO_FLOAT(pt.x)) * (180.0f / MATH_PI) * 65536.0f); + return SwFixed(tvg::atan2(TO_FLOAT(pt.y), TO_FLOAT(pt.x)) * (180.0f / MATH_PI) * 65536.0f); } @@ -245,6 +245,15 @@ void mathSplitCubic(SwPoint* base) } +void mathSplitLine(SwPoint* base) +{ + base[2] = base[1]; + + base[1].x = (base[0].x + base[1].x) >> 1; + base[1].y = (base[0].y + base[1].y) >> 1; +} + + SwFixed mathDiff(SwFixed angle1, SwFixed angle2) { auto delta = angle2 - angle1; @@ -257,30 +266,28 @@ SwFixed mathDiff(SwFixed angle1, SwFixed angle2) } -SwPoint mathTransform(const Point* to, const Matrix* transform) +SwPoint mathTransform(const Point* to, const Matrix& transform) { - if (!transform) return {TO_SWCOORD(to->x), TO_SWCOORD(to->y)}; - - auto tx = to->x * transform->e11 + to->y * transform->e12 + transform->e13; - auto ty = to->x * transform->e21 + to->y * transform->e22 + transform->e23; + auto tx = to->x * transform.e11 + to->y * transform.e12 + transform.e13; + auto ty = to->x * transform.e21 + to->y * transform.e22 + transform.e23; return {TO_SWCOORD(tx), TO_SWCOORD(ty)}; } -bool mathClipBBox(const SwBBox& clipper, SwBBox& clipee) +bool mathClipBBox(const SwBBox& clipper, SwBBox& clippee) { - clipee.max.x = (clipee.max.x < clipper.max.x) ? clipee.max.x : clipper.max.x; - clipee.max.y = (clipee.max.y < clipper.max.y) ? clipee.max.y : clipper.max.y; - clipee.min.x = (clipee.min.x > clipper.min.x) ? clipee.min.x : clipper.min.x; - clipee.min.y = (clipee.min.y > clipper.min.y) ? clipee.min.y : clipper.min.y; + clippee.max.x = (clippee.max.x < clipper.max.x) ? clippee.max.x : clipper.max.x; + clippee.max.y = (clippee.max.y < clipper.max.y) ? clippee.max.y : clipper.max.y; + clippee.min.x = (clippee.min.x > clipper.min.x) ? clippee.min.x : clipper.min.x; + clippee.min.y = (clippee.min.y > clipper.min.y) ? clippee.min.y : clipper.min.y; //Check valid region - if (clipee.max.x - clipee.min.x < 1 && clipee.max.y - clipee.min.y < 1) return false; + if (clippee.max.x - clippee.min.x < 1 && clippee.max.y - clippee.min.y < 1) return false; //Check boundary - if (clipee.min.x >= clipper.max.x || clipee.min.y >= clipper.max.y || - clipee.max.x <= clipper.min.x || clipee.max.y <= clipper.min.y) return false; + if (clippee.min.x >= clipper.max.x || clippee.min.y >= clipper.max.y || + clippee.max.x <= clipper.min.x || clippee.max.y <= clipper.min.y) return false; return true; } @@ -308,14 +315,12 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S if (yMin > pt->y) yMin = pt->y; if (yMax < pt->y) yMax = pt->y; } - //Since no antialiasing is applied in the Fast Track case, - //the rasterization region has to be rearranged. - //https://github.com/Samsung/thorvg/issues/916 + if (fastTrack) { - renderRegion.min.x = static_cast(round(xMin / 64.0f)); - renderRegion.max.x = static_cast(round(xMax / 64.0f)); - renderRegion.min.y = static_cast(round(yMin / 64.0f)); - renderRegion.max.y = static_cast(round(yMax / 64.0f)); + renderRegion.min.x = static_cast(nearbyint(xMin / 64.0f)); + renderRegion.max.x = static_cast(nearbyint(xMax / 64.0f)); + renderRegion.min.y = static_cast(nearbyint(yMin / 64.0f)); + renderRegion.max.y = static_cast(nearbyint(yMax / 64.0f)); } else { renderRegion.min.x = xMin >> 6; renderRegion.max.x = (xMax + 63) >> 6; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMemPool.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMemPool.cpp index 4a9d7f527..036690e20 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMemPool.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwMemPool.cpp @@ -84,10 +84,14 @@ SwMpool* mpoolInit(uint32_t threads) { auto allocSize = threads + 1; - auto mpool = static_cast(calloc(sizeof(SwMpool), 1)); - mpool->outline = static_cast(calloc(1, sizeof(SwOutline) * allocSize)); - mpool->strokeOutline = static_cast(calloc(1, sizeof(SwOutline) * allocSize)); - mpool->dashOutline = static_cast(calloc(1, sizeof(SwOutline) * allocSize)); + auto mpool = static_cast(lv_zalloc(sizeof(SwMpool))); + LV_ASSERT_MALLOC(mpool); + mpool->outline = static_cast(lv_zalloc(sizeof(SwOutline) * allocSize)); + LV_ASSERT_MALLOC(mpool->outline); + mpool->strokeOutline = static_cast(lv_zalloc(sizeof(SwOutline) * allocSize)); + LV_ASSERT_MALLOC(mpool->strokeOutline); + mpool->dashOutline = static_cast(lv_zalloc(sizeof(SwOutline) * allocSize)); + LV_ASSERT_MALLOC(mpool->dashOutline); mpool->allocSize = allocSize; return mpool; @@ -123,10 +127,10 @@ bool mpoolTerm(SwMpool* mpool) mpoolClear(mpool); - free(mpool->outline); - free(mpool->strokeOutline); - free(mpool->dashOutline); - free(mpool); + lv_free(mpool->outline); + lv_free(mpool->strokeOutline); + lv_free(mpool->dashOutline); + lv_free(mpool); return true; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwPostEffect.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwPostEffect.cpp new file mode 100644 index 000000000..386fd73a2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwPostEffect.cpp @@ -0,0 +1,215 @@ +/* + * 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 "tvgSwCommon.h" + +/************************************************************************/ +/* Gaussian Filter Implementation */ +/************************************************************************/ + +struct SwGaussianBlur +{ + static constexpr int MAX_LEVEL = 3; + int level; + int kernel[MAX_LEVEL]; +}; + + +static void _gaussianExtendRegion(RenderRegion& region, int extra, int8_t direction) +{ + //bbox region expansion for feathering + if (direction != 2) { + region.x = -extra; + region.w = extra * 2; + } + if (direction != 1) { + region.y = -extra; + region.h = extra * 2; + } +} + + +static int _gaussianRemap(int end, int idx, int border) +{ + //wrap + if (border == 1) return idx % end; + + //duplicate + if (idx < 0) return 0; + else if (idx >= end) return end - 1; + return idx; +} + + +//TODO: SIMD OPTIMIZATION? +static void _gaussianBlur(uint8_t* src, uint8_t* dst, int32_t stride, int32_t w, int32_t h, const SwBBox& bbox, int32_t dimension, int border, bool flipped) +{ + if (flipped) { + src += ((bbox.min.x * stride) + bbox.min.y) << 2; + dst += ((bbox.min.x * stride) + bbox.min.y) << 2; + } else { + src += ((bbox.min.y * stride) + bbox.min.x) << 2; + dst += ((bbox.min.y * stride) + bbox.min.x) << 2; + } + + auto iarr = 1.0f / (dimension + dimension + 1); + + for (int x = 0; x < h; x++) { + auto p = x * stride; + auto i = p * 4; //current index + auto l = -(dimension + 1); //left index + auto r = dimension; //right index + int acc[4] = {0, 0, 0, 0}; //sliding accumulator + + //initial acucmulation + for (int x2 = l; x2 < r; ++x2) { + auto id = (_gaussianRemap(w, x2, border) + p) * 4; + acc[0] += src[id++]; + acc[1] += src[id++]; + acc[2] += src[id++]; + acc[3] += src[id]; + } + //perform filtering + for (int x2 = 0; x2 < w; ++x2, ++r, ++l) { + auto rid = (_gaussianRemap(w, r, border) + p) * 4; + auto lid = (_gaussianRemap(w, l, border) + p) * 4; + acc[0] += src[rid++] - src[lid++]; + acc[1] += src[rid++] - src[lid++]; + acc[2] += src[rid++] - src[lid++]; + acc[3] += src[rid] - src[lid]; + dst[i++] = static_cast(acc[0] * iarr + 0.5f); + dst[i++] = static_cast(acc[1] * iarr + 0.5f); + dst[i++] = static_cast(acc[2] * iarr + 0.5f); + dst[i++] = static_cast(acc[3] * iarr + 0.5f); + } + } +} + + +static int _gaussianInit(int* kernel, float sigma, int level) +{ + const auto MAX_LEVEL = SwGaussianBlur::MAX_LEVEL; + + //compute the kernel + auto wl = (int) sqrt((12 * sigma / MAX_LEVEL) + 1); + if (wl % 2 == 0) --wl; + auto wu = wl + 2; + auto mi = (12 * sigma - MAX_LEVEL * wl * wl - 4 * MAX_LEVEL * wl - 3 * MAX_LEVEL) / (-4 * wl - 4); + auto m = int(mi + 0.5f); + auto extends = 0; + + for (int i = 0; i < level; i++) { + kernel[i] = ((i < m ? wl : wu) - 1) / 2; + extends += kernel[i]; + } + + return extends; +} + + +bool effectGaussianPrepare(RenderEffectGaussian* params) +{ + auto data = (SwGaussianBlur*)lv_malloc(sizeof(SwGaussianBlur)); + LV_ASSERT_MALLOC(data); + + //compute box kernel sizes + data->level = int(SwGaussianBlur::MAX_LEVEL * ((params->quality - 1) * 0.01f)) + 1; + auto extends = _gaussianInit(data->kernel, params->sigma * params->sigma, data->level); + + //skip, if the parameters are invalid. + if (extends == 0) { + params->invalid = true; + lv_free(data); + return false; + } + + _gaussianExtendRegion(params->extend, extends, params->direction); + + params->rd = data; + + return true; +} + + +/* It is best to take advantage of the Gaussian blur’s separable property + by dividing the process into two passes. horizontal and vertical. + We can expect fewer calculations. */ +bool effectGaussianBlur(SwImage& image, SwImage& buffer, const SwBBox& bbox, const RenderEffectGaussian* params) +{ + if (params->invalid) return false; + + if (image.channelSize != sizeof(uint32_t)) { + TVGERR("SW_ENGINE", "Not supported grayscale Gaussian Blur!"); + return false; + } + + auto data = static_cast(params->rd); + auto w = (bbox.max.x - bbox.min.x); + auto h = (bbox.max.y - bbox.min.y); + auto stride = image.stride; + auto front = image.buf8; + auto back = buffer.buf8; + auto swapped = false; + + //fine-tuning for low-quality (experimental) + auto threshold = (std::min(w, h) < 300) ? 2 : 1; + + TVGLOG("SW_ENGINE", "GaussianFilter region(%ld, %ld, %ld, %ld) params(%f %d %d), level(%d)", bbox.min.x, bbox.min.y, bbox.max.x, bbox.max.y, params->sigma, params->direction, params->border, data->level); + + //horizontal + if (params->direction == 0 || params->direction == 1) { + for (int i = 0; i < data->level; ++i) { + auto k = data->kernel[i] / threshold; + if (k == 0) continue; + _gaussianBlur(front, back, stride, w, h, bbox, k, params->border, false); + std::swap(front, back); + swapped = !swapped; + } + } + + //vertical. x/y flipping and horionztal access is pretty compatible with the memory architecture. + if (params->direction == 0 || params->direction == 2) { + rasterXYFlip(reinterpret_cast(front), reinterpret_cast(back), stride, w, h, bbox, false); + std::swap(front, back); + + for (int i = 0; i < data->level; ++i) { + auto k = data->kernel[i] / threshold; + if (k == 0) continue; + _gaussianBlur(front, back, stride, h, w, bbox, k, params->border, true); + std::swap(front, back); + swapped = !swapped; + } + + rasterXYFlip(reinterpret_cast(front), reinterpret_cast(back), stride, h, w, bbox, true); + std::swap(front, back); + } + + if (swapped) std::swap(image.buf8, buffer.buf8); + + return true; +} + +#endif /* LV_USE_THORVG_INTERNAL */ + diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRaster.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRaster.cpp index 237e30de7..635059792 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRaster.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRaster.cpp @@ -197,10 +197,21 @@ static inline uint8_t _opMaskDifference(uint8_t s, uint8_t d, uint8_t a) } +static inline uint8_t _opMaskLighten(uint8_t s, uint8_t d, uint8_t a) +{ + return (s > d) ? s : d; +} + + +static inline uint8_t _opMaskDarken(uint8_t s, uint8_t d, uint8_t a) +{ + return (s < d) ? s : d; +} + + static inline bool _direct(CompositeMethod method) { - //subtract & Intersect allows the direct composition - if (method == CompositeMethod::SubtractMask || method == CompositeMethod::IntersectMask) return true; + if (method == CompositeMethod::SubtractMask || method == CompositeMethod::IntersectMask || method == CompositeMethod::DarkenMask) return true; return false; } @@ -212,6 +223,8 @@ static inline SwMask _getMaskOp(CompositeMethod method) case CompositeMethod::SubtractMask: return _opMaskSubtract; case CompositeMethod::DifferenceMask: return _opMaskDifference; case CompositeMethod::IntersectMask: return _opMaskIntersect; + case CompositeMethod::LightenMask: return _opMaskLighten; + case CompositeMethod::DarkenMask: return _opMaskDarken; default: return nullptr; } } @@ -386,7 +399,8 @@ static bool _rasterMattedRect(SwSurface* surface, const SwBBox& region, uint8_t auto dst = &buffer[y * surface->stride]; auto cmp = &cbuffer[y * surface->compositor->image.stride * csize]; for (uint32_t x = 0; x < w; ++x, ++dst, cmp += csize) { - *dst = INTERPOLATE(color, *dst, alpha(cmp)); + auto tmp = ALPHA_BLEND(color, alpha(cmp)); + *dst = tmp + ALPHA_BLEND(*dst, IA(tmp)); } } //8bits grayscale @@ -412,12 +426,11 @@ static bool _rasterBlendingRect(SwSurface* surface, const SwBBox& region, uint8_ auto h = static_cast(region.max.y - region.min.y); auto color = surface->join(r, g, b, a); auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; - auto ialpha = 255 - a; for (uint32_t y = 0; y < h; ++y) { auto dst = &buffer[y * surface->stride]; for (uint32_t x = 0; x < w; ++x, ++dst) { - *dst = surface->blender(color, *dst, ialpha); + *dst = surface->blender(color, *dst, 255); } } return true; @@ -480,7 +493,7 @@ static bool _rasterRect(SwSurface* surface, const SwBBox& region, uint8_t r, uin /* Rle */ /************************************************************************/ -static bool _rasterCompositeMaskedRle(SwSurface* surface, SwRleData* rle, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterCompositeMaskedRle(SwSurface* surface, SwRle* rle, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { auto span = rle->spans; auto cbuffer = surface->compositor->image.buf8; @@ -500,7 +513,7 @@ static bool _rasterCompositeMaskedRle(SwSurface* surface, SwRleData* rle, SwMask } -static bool _rasterDirectMaskedRle(SwSurface* surface, SwRleData* rle, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterDirectMaskedRle(SwSurface* surface, SwRle* rle, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { auto span = rle->spans; auto cbuffer = surface->compositor->image.buf8; @@ -521,7 +534,7 @@ static bool _rasterDirectMaskedRle(SwSurface* surface, SwRleData* rle, SwMask ma } -static bool _rasterMaskedRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterMaskedRle(SwSurface* surface, SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { TVGLOG("SW_ENGINE", "Masked(%d) Rle", (int)surface->compositor->method); @@ -535,7 +548,7 @@ static bool _rasterMaskedRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint } -static bool _rasterMattedRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterMattedRle(SwSurface* surface, SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { TVGLOG("SW_ENGINE", "Matted(%d) Rle", (int)surface->compositor->method); @@ -558,10 +571,8 @@ static bool _rasterMattedRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint *dst = tmp + ALPHA_BLEND(*dst, IA(tmp)); } } - return true; - } //8bit grayscale - if (surface->channelSize == sizeof(uint8_t)) { + } else if (surface->channelSize == sizeof(uint8_t)) { uint8_t src; for (uint32_t i = 0; i < rle->size; ++i, ++span) { auto dst = &surface->buf8[span->y * surface->stride + span->x]; @@ -572,29 +583,27 @@ static bool _rasterMattedRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint *dst = INTERPOLATE8(src, *dst, alpha(cmp)); } } - return true; } - return false; + return true; } -static bool _rasterBlendingRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterBlendingRle(SwSurface* surface, const SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { if (surface->channelSize != sizeof(uint32_t)) return false; auto span = rle->spans; auto color = surface->join(r, g, b, a); - auto ialpha = 255 - a; for (uint32_t i = 0; i < rle->size; ++i, ++span) { auto dst = &surface->buf32[span->y * surface->stride + span->x]; if (span->coverage == 255) { for (uint32_t x = 0; x < span->len; ++x, ++dst) { - *dst = surface->blender(color, *dst, ialpha); + *dst = surface->blender(color, *dst, 255); } } else { for (uint32_t x = 0; x < span->len; ++x, ++dst) { - auto tmp = surface->blender(color, *dst, ialpha); + auto tmp = surface->blender(color, *dst, 255); *dst = INTERPOLATE(tmp, *dst, span->coverage); } } @@ -603,7 +612,7 @@ static bool _rasterBlendingRle(SwSurface* surface, const SwRleData* rle, uint8_t } -static bool _rasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterTranslucentRle(SwSurface* surface, const SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { #if defined(THORVG_AVX_VECTOR_SUPPORT) return avxRasterTranslucentRle(surface, rle, r, g, b, a); @@ -615,7 +624,7 @@ static bool _rasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint } -static bool _rasterSolidRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b) +static bool _rasterSolidRle(SwSurface* surface, const SwRle* rle, uint8_t r, uint8_t g, uint8_t b) { auto span = rle->spans; @@ -652,7 +661,7 @@ static bool _rasterSolidRle(SwSurface* surface, const SwRleData* rle, uint8_t r, } -static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterRle(SwSurface* surface, SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { if (!rle) return false; @@ -677,7 +686,7 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g, 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); \ + auto my = (int32_t)nearbyint(sy); \ miny = my - (int32_t)sampleSize; \ if (miny < 0) miny = 0; \ maxy = my + (int32_t)sampleSize; \ @@ -688,66 +697,9 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g, 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 -static bool _rasterCompositeScaledMaskedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwMask maskOp, uint8_t opacity) -{ - auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; - auto sampleSize = _sampleSize(image->scale); - auto span = image->rle->spans; - int32_t miny = 0, maxy = 0; - - 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 a = MULTIPLY(span->coverage, opacity); - for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++cmp) { - SCALED_IMAGE_RANGE_X - auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); - if (a < 255) src = MULTIPLY(src, a); - *cmp = maskOp(src, *cmp, ~src); - } - } - return true; -} - - -static bool _rasterDirectScaledMaskedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwMask maskOp, uint8_t opacity) -{ - auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; - auto sampleSize = _sampleSize(image->scale); - auto span = image->rle->spans; - int32_t miny = 0, maxy = 0; - - 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]; - auto a = MULTIPLY(span->coverage, opacity); - for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++cmp, ++dst) { - SCALED_IMAGE_RANGE_X - auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); - if (a < 255) src = MULTIPLY(src, a); - src = maskOp(src, *cmp, 0); //not use alpha - *dst = src + MULTIPLY(*dst, ~src); - } - } - return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); -} -#endif - static bool _rasterScaledMaskedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity) { -#if 0 //Enable it when GRAYSCALE image is supported - TVGLOG("SW_ENGINE", "Scaled Masked(%d) Rle Image", (int)surface->compositor->method); - - //8bit masking channels composition - if (surface->channelSize != sizeof(uint8_t)) return false; - - auto maskOp = _getMaskOp(surface->compositor->method); - if (_direct(surface->compositor->method)) return _rasterDirectScaledMaskedRleImage(surface, image, itransform, region, maskOp, opacity); - else return _rasterCompositeScaledMaskedRleImage(surface, image, itransform, region, maskOp, opacity); -#endif + TVGERR("SW_ENGINE", "Not Supported Scaled Masked(%d) Rle Image", (int)surface->compositor->method); return false; } @@ -775,7 +727,6 @@ static bool _rasterScaledMattedRleImage(SwSurface* surface, const SwImage* image *dst = src + ALPHA_BLEND(*dst, IA(src)); } } - return true; } @@ -802,9 +753,8 @@ static bool _rasterScaledBlendingRleImage(SwSurface* surface, const SwImage* ima for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst) { SCALED_IMAGE_RANGE_X auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); - if (opacity < 255) src = ALPHA_BLEND(src, opacity); auto tmp = surface->blender(src, *dst, 255); - *dst = INTERPOLATE(tmp, *dst, MULTIPLY(span->coverage, A(src))); + *dst = INTERPOLATE(tmp, *dst, MULTIPLY(alpha, A(src))); } } } @@ -834,7 +784,7 @@ static bool _rasterScaledRleImage(SwSurface* surface, const SwImage* image, cons } -static bool _scaledRleImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint8_t opacity) +static bool _scaledRleImage(SwSurface* surface, const SwImage* image, const Matrix& transform, const SwBBox& region, uint8_t opacity) { if (surface->channelSize == sizeof(uint8_t)) { TVGERR("SW_ENGINE", "Not supported scaled rle image!"); @@ -843,9 +793,7 @@ static bool _scaledRleImage(SwSurface* surface, const SwImage* image, const Matr Matrix itransform; - if (transform) { - if (!mathInverse(transform, &itransform)) return false; - } else mathIdentity(&itransform); + if (!inverse(&transform, &itransform)) return true; if (_compositing(surface)) { if (_matting(surface)) return _rasterScaledMattedRleImage(surface, image, &itransform, region, opacity); @@ -863,75 +811,6 @@ static bool _scaledRleImage(SwSurface* surface, const SwImage* image, const Matr /* RLE Direct Image */ /************************************************************************/ -#if 0 //Enable it when GRAYSCALE image is supported -static bool _rasterCompositeDirectMaskedRleImage(SwSurface* surface, const SwImage* image, SwMask maskOp, uint8_t opacity) -{ - auto span = image->rle->spans; - auto cbuffer = surface->compositor->image.buf8; - 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 * cstride + span->x]; - auto alpha = MULTIPLY(span->coverage, opacity); - if (alpha == 255) { - for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp) { - *cmp = maskOp(*src, *cmp, ~*src); - } - } else { - for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp) { - auto tmp = MULTIPLY(*src, alpha); - *cmp = maskOp(*src, *cmp, ~tmp); - } - } - } - return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); -} - - -static bool _rasterDirectDirectMaskedRleImage(SwSurface* surface, const SwImage* image, SwMask maskOp, uint8_t opacity) -{ - auto span = image->rle->spans; - auto cbuffer = surface->compositor->image.buf8; - 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 * cstride + span->x]; - auto dst = &surface->buf8[span->y * surface->stride + span->x]; - auto alpha = MULTIPLY(span->coverage, opacity); - if (alpha == 255) { - for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp, ++dst) { - auto tmp = maskOp(*src, *cmp, 0); //not use alpha - *dst = INTERPOLATE8(tmp, *dst, (255 - tmp)); - } - } else { - for (uint32_t x = 0; x < span->len; ++x, ++src, ++cmp, ++dst) { - auto tmp = maskOp(MULTIPLY(*src, alpha), *cmp, 0); //not use alpha - *dst = INTERPOLATE8(tmp, *dst, (255 - tmp)); - } - } - } - return true; -} -#endif - -static bool _rasterDirectMaskedRleImage(SwSurface* surface, const SwImage* image, uint8_t opacity) -{ -#if 0 //Enable it when GRAYSCALE image is supported - TVGLOG("SW_ENGINE", "Direct Masked(%d) Rle Image", (int)surface->compositor->method); - - //8bit masking channels composition - if (surface->channelSize != sizeof(uint8_t)) return false; - - auto maskOp = _getMaskOp(surface->compositor->method); - if (_direct(surface->compositor->method)) _rasterDirectDirectMaskedRleImage(surface, image, maskOp, opacity); - else return _rasterCompositeDirectMaskedRleImage(surface, image, maskOp, opacity); -#endif - return false; -} - - static bool _rasterDirectMattedRleImage(SwSurface* surface, const SwImage* image, uint8_t opacity) { TVGLOG("SW_ENGINE", "Direct Matted(%d) Rle Image", (int)surface->compositor->method); @@ -972,18 +851,12 @@ static bool _rasterDirectBlendingRleImage(SwSurface* surface, const SwImage* ima auto alpha = MULTIPLY(span->coverage, opacity); if (alpha == 255) { for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) { - *dst = surface->blender(*img, *dst, IA(*img)); - } - } else if (opacity == 255) { - for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) { - auto tmp = surface->blender(*img, *dst, 255); - *dst = INTERPOLATE(tmp, *dst, MULTIPLY(span->coverage, A(*img))); + *dst = surface->blender(*img, *dst, 255); } } else { for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) { - auto src = ALPHA_BLEND(*img, opacity); - auto tmp = surface->blender(src, *dst, IA(src)); - *dst = INTERPOLATE(tmp, *dst, MULTIPLY(span->coverage, A(src))); + auto tmp = surface->blender(*img, *dst, 255); + *dst = INTERPOLATE(tmp, *dst, MULTIPLY(alpha, A(*img))); } } } @@ -1014,6 +887,13 @@ static bool _rasterDirectRleImage(SwSurface* surface, const SwImage* image, uint } +static bool _rasterDirectMaskedRleImage(SwSurface* surface, const SwImage* image, uint8_t opacity) +{ + TVGERR("SW_ENGINE", "Not Supported Direct Masked(%d) Rle Image", (int)surface->compositor->method); + return false; +} + + static bool _directRleImage(SwSurface* surface, const SwImage* image, uint8_t opacity) { if (surface->channelSize == sizeof(uint8_t)) { @@ -1037,72 +917,20 @@ static bool _directRleImage(SwSurface* surface, const SwImage* image, uint8_t op /*Scaled Image */ /************************************************************************/ -#if 0 //Enable it when GRAYSCALE image is supported -static bool _rasterCompositeScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwMask maskOp, uint8_t opacity) -{ - auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; - auto sampleSize = _sampleSize(image->scale); - auto cstride = surface->compositor->image.stride; - auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x); - int32_t miny = 0, maxy = 0; - - for (auto y = region.min.y; y < region.max.y; ++y) { - SCALED_IMAGE_RANGE_Y(y) - auto cmp = cbuffer; - for (auto x = region.min.x; x < region.max.x; ++x, ++cmp) { - SCALED_IMAGE_RANGE_X - auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); - if (opacity < 255) src = MULTIPLY(src, opacity); - *cmp = maskOp(src, *cmp, ~src); - } - cbuffer += cstride; - } - return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); -} - - -static bool _rasterDirectScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, SwMask maskOp, uint8_t opacity) -{ - auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; - auto sampleSize = _sampleSize(image->scale); - auto cstride = surface->compositor->image.stride; - auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x); - auto dbuffer = surface->buf8 + (region.min.y * surface->stride + region.min.x); - int32_t miny = 0, maxy = 0; - - for (auto y = region.min.y; y < region.max.y; ++y) { - SCALED_IMAGE_RANGE_Y(y) - auto cmp = cbuffer; - auto dst = dbuffer; - for (auto x = region.min.x; x < region.max.x; ++x, ++cmp, ++dst) { - SCALED_IMAGE_RANGE_X - auto src = scaleMethod(image->buf8, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); - if (opacity < 255) src = MULTIPLY(src, opacity); - src = maskOp(src, *cmp, 0); //not use alpha - *dst = src + MULTIPLY(*dst, ~src); - } - cbuffer += cstride; - dbuffer += surface->stride; - } - return true; -} -#endif - static bool _rasterScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity) { -#if 0 //Enable it when GRAYSCALE image is supported - TVGLOG("SW_ENGINE", "Scaled Masked(%d) Image [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y); - - auto maskOp = _getMaskOp(surface->compositor->method); - if (_direct(surface->compositor->method)) return _rasterDirectScaledMaskedImage(surface, image, itransform, region, maskOp, opacity); - else return _rasterCompositeScaledMaskedImage(surface, image, itransform, region, maskOp, opacity); -#endif + TVGERR("SW_ENGINE", "Not Supported Scaled Masked Image!"); return false; } static bool _rasterScaledMattedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity) { + if (surface->channelSize == sizeof(uint8_t)) { + TVGERR("SW_ENGINE", "Not supported grayscale scaled matted image!"); + return false; + } + auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x); auto csize = surface->compositor->image.channelSize; auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize; @@ -1133,6 +961,11 @@ static bool _rasterScaledMattedImage(SwSurface* surface, const SwImage* image, c static bool _rasterScaledBlendingImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity) { + if (surface->channelSize == sizeof(uint8_t)) { + TVGERR("SW_ENGINE", "Not supported grayscale scaled blending image!"); + return false; + } + auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x); auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; auto sampleSize = _sampleSize(image->scale); @@ -1144,9 +977,8 @@ static bool _rasterScaledBlendingImage(SwSurface* surface, const SwImage* image, for (auto x = region.min.x; x < region.max.x; ++x, ++dst) { SCALED_IMAGE_RANGE_X auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); - if (opacity < 255) ALPHA_BLEND(src, opacity); auto tmp = surface->blender(src, *dst, 255); - *dst = INTERPOLATE(tmp, *dst, A(src)); + *dst = INTERPOLATE(tmp, *dst, MULTIPLY(opacity, A(src))); } } return true; @@ -1155,37 +987,44 @@ static bool _rasterScaledBlendingImage(SwSurface* surface, const SwImage* image, static bool _rasterScaledImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity) { - auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x); auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler; auto sampleSize = _sampleSize(image->scale); int32_t miny = 0, maxy = 0; - for (auto y = region.min.y; y < region.max.y; ++y, dbuffer += surface->stride) { - SCALED_IMAGE_RANGE_Y(y) - auto dst = dbuffer; - for (auto x = region.min.x; x < region.max.x; ++x, ++dst) { - SCALED_IMAGE_RANGE_X - auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); - if (opacity < 255) src = ALPHA_BLEND(src, opacity); - *dst = src + ALPHA_BLEND(*dst, IA(src)); + //32bits channels + if (surface->channelSize == sizeof(uint32_t)) { + auto buffer = surface->buf32 + (region.min.y * surface->stride + region.min.x); + for (auto y = region.min.y; y < region.max.y; ++y, buffer += surface->stride) { + SCALED_IMAGE_RANGE_Y(y) + auto dst = buffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++dst) { + SCALED_IMAGE_RANGE_X + auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); + if (opacity < 255) src = ALPHA_BLEND(src, opacity); + *dst = src + ALPHA_BLEND(*dst, IA(src)); + } + } + } else if (surface->channelSize == sizeof(uint8_t)) { + auto buffer = surface->buf8 + (region.min.y * surface->stride + region.min.x); + for (auto y = region.min.y; y < region.max.y; ++y, buffer += surface->stride) { + SCALED_IMAGE_RANGE_Y(y) + auto dst = buffer; + for (auto x = region.min.x; x < region.max.x; ++x, ++dst) { + SCALED_IMAGE_RANGE_X + auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize); + *dst = MULTIPLY(A(src), opacity); + } } } return true; } -static bool _scaledImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint8_t opacity) +static bool _scaledImage(SwSurface* surface, const SwImage* image, const Matrix& transform, const SwBBox& region, uint8_t opacity) { - if (surface->channelSize == sizeof(uint8_t)) { - TVGERR("SW_ENGINE", "Not supported grayscale Textmap polygon mesh!"); - return false; - } - Matrix itransform; - if (transform) { - if (!mathInverse(transform, &itransform)) return false; - } else mathIdentity(&itransform); + if (!inverse(&transform, &itransform)) return true; if (_compositing(surface)) { if (_matting(surface)) return _rasterScaledMattedImage(surface, image, &itransform, region, opacity); @@ -1203,78 +1042,9 @@ static bool _scaledImage(SwSurface* surface, const SwImage* image, const Matrix* /* Direct Image */ /************************************************************************/ -#if 0 //Enable it when GRAYSCALE image is supported -static bool _rasterCompositeDirectMaskedImage(SwSurface* surface, const SwImage* image, const SwBBox& region, SwMask maskOp, uint8_t opacity) -{ - auto h = static_cast(region.max.y - region.min.y); - auto w = static_cast(region.max.x - region.min.x); - auto cstride = surface->compositor->image.stride; - - auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x); //compositor buffer - auto sbuffer = image->buf8 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); - - for (uint32_t y = 0; y < h; ++y) { - auto cmp = cbuffer; - auto src = sbuffer; - if (opacity == 255) { - for (uint32_t x = 0; x < w; ++x, ++src, ++cmp) { - *cmp = maskOp(*src, *cmp, ~*src); - } - } else { - for (uint32_t x = 0; x < w; ++x, ++src, ++cmp) { - auto tmp = MULTIPLY(*src, opacity); - *cmp = maskOp(tmp, *cmp, ~tmp); - } - } - cbuffer += cstride; - sbuffer += image->stride; - } - return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); -} - - -static bool _rasterDirectDirectMaskedImage(SwSurface* surface, const SwImage* image, const SwBBox& region, SwMask maskOp, uint8_t opacity) -{ - auto h = static_cast(region.max.y - region.min.y); - auto w = static_cast(region.max.x - region.min.x); - auto cstride = surface->compositor->image.stride; - - auto cbuffer = surface->compositor->image.buf32 + (region.min.y * cstride + region.min.x); //compositor buffer - auto dbuffer = surface->buf8 + (region.min.y * surface->stride + region.min.x); //destination buffer - auto sbuffer = image->buf8 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); - - for (uint32_t y = 0; y < h; ++y) { - auto cmp = cbuffer; - auto dst = dbuffer; - auto src = sbuffer; - if (opacity == 255) { - for (uint32_t x = 0; x < w; ++x, ++src, ++cmp, ++dst) { - auto tmp = maskOp(*src, *cmp, 0); //not use alpha - *dst = tmp + MULTIPLY(*dst, ~tmp); - } - } else { - for (uint32_t x = 0; x < w; ++x, ++src, ++cmp, ++dst) { - auto tmp = maskOp(MULTIPLY(*src, opacity), *cmp, 0); //not use alpha - *dst = tmp + MULTIPLY(*dst, ~tmp); - } - } - cbuffer += cstride; - dbuffer += surface->stride; - sbuffer += image->stride; - } - return true; -} -#endif - static bool _rasterDirectMaskedImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity) { - TVGERR("SW_ENGINE", "Not Supported: Direct Masked(%d) Image [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y); - -#if 0 //Enable it when GRAYSCALE image is supported - auto maskOp = _getMaskOp(surface->compositor->method); - if (_direct(surface->compositor->method)) return _rasterDirectDirectMaskedImage(surface, image, region, maskOp, opacity); - else return _rasterCompositeDirectMaskedImage(surface, image, region, maskOp, opacity); -#endif + TVGERR("SW_ENGINE", "Not Supported: Direct Masked Image"); return false; } @@ -1321,11 +1091,13 @@ static bool _rasterDirectMattedImage(SwSurface* surface, const SwImage* image, c auto src = sbuffer; if (opacity == 255) { for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) { - *dst = MULTIPLY(A(*src), alpha(cmp)); + auto tmp = MULTIPLY(A(*src), alpha(cmp)); + *dst = tmp + MULTIPLY(*dst, 255 - tmp); } } else { for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) { - *dst = MULTIPLY(A(*src), MULTIPLY(opacity, alpha(cmp))); + auto tmp = MULTIPLY(A(*src), MULTIPLY(opacity, alpha(cmp))); + *dst = tmp + MULTIPLY(*dst, 255 - tmp); } } buffer += surface->stride; @@ -1356,10 +1128,9 @@ static bool _rasterDirectBlendingImage(SwSurface* surface, const SwImage* image, *dst = INTERPOLATE(tmp, *dst, A(*src)); } } else { - for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++src) { - auto tmp = ALPHA_BLEND(*src, opacity); - auto tmp2 = surface->blender(tmp, *dst, 255); - *dst = INTERPOLATE(tmp2, *dst, A(tmp)); + for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) { + auto tmp = surface->blender(*src, *dst, 255); + *dst = INTERPOLATE(tmp, *dst, MULTIPLY(opacity, A(*src))); } } dbuffer += surface->stride; @@ -1370,29 +1141,83 @@ static bool _rasterDirectBlendingImage(SwSurface* surface, const SwImage* image, static bool _rasterDirectImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity) +{ + auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + + //32bits channels + if (surface->channelSize == sizeof(uint32_t)) { + auto dbuffer = &surface->buf32[region.min.y * surface->stride + region.min.x]; + + for (auto y = region.min.y; y < region.max.y; ++y) { + auto dst = dbuffer; + auto src = sbuffer; + if (opacity == 255) { + for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) { + *dst = *src + ALPHA_BLEND(*dst, IA(*src)); + } + } else { + for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++src) { + auto tmp = ALPHA_BLEND(*src, opacity); + *dst = tmp + ALPHA_BLEND(*dst, IA(tmp)); + } + } + dbuffer += surface->stride; + sbuffer += image->stride; + } + //8bits grayscale + } else if (surface->channelSize == sizeof(uint8_t)) { + auto dbuffer = &surface->buf8[region.min.y * surface->stride + region.min.x]; + + for (auto y = region.min.y; y < region.max.y; ++y, dbuffer += surface->stride, sbuffer += image->stride) { + auto dst = dbuffer; + auto src = sbuffer; + if (opacity == 255) { + for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++src) { + *dst = *src + MULTIPLY(*dst, IA(*src)); + } + } else { + for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++src) { + *dst = INTERPOLATE8(A(*src), *dst, opacity); + } + } + } + } + return true; +} + + +static bool _rasterDirectMattedBlendingImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity) { if (surface->channelSize == sizeof(uint8_t)) { TVGERR("SW_ENGINE", "Not supported grayscale image!"); return false; } - auto dbuffer = &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); + auto csize = surface->compositor->image.channelSize; + auto alpha = surface->alpha(surface->compositor->method); auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize; //compositor buffer + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; - for (auto y = region.min.y; y < region.max.y; ++y) { - auto dst = dbuffer; + for (uint32_t y = 0; y < h; ++y) { + auto dst = buffer; + auto cmp = cbuffer; auto src = sbuffer; if (opacity == 255) { - for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) { - *dst = *src + ALPHA_BLEND(*dst, IA(*src)); + for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) { + auto tmp = ALPHA_BLEND(*src, alpha(cmp)); + *dst = INTERPOLATE(surface->blender(tmp, *dst, 255), *dst, A(tmp)); } } else { - for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++src) { - auto tmp = ALPHA_BLEND(*src, opacity); - *dst = tmp + ALPHA_BLEND(*dst, IA(tmp)); + for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) { + auto tmp = ALPHA_BLEND(*src, alpha(cmp)); + *dst = INTERPOLATE(surface->blender(tmp, *dst, 255), *dst, MULTIPLY(opacity, A(tmp))); } } - dbuffer += surface->stride; + buffer += surface->stride; + cbuffer += surface->compositor->image.stride * csize; sbuffer += image->stride; } return true; @@ -1403,8 +1228,10 @@ static bool _rasterDirectImage(SwSurface* surface, const SwImage* image, const S static bool _directImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity) { if (_compositing(surface)) { - if (_matting(surface)) return _rasterDirectMattedImage(surface, image, region, opacity); - else return _rasterDirectMaskedImage(surface, image, region, opacity); + if (_matting(surface)) { + if (_blending(surface)) return _rasterDirectMattedBlendingImage(surface, image, region, opacity); + else return _rasterDirectMattedImage(surface, image, region, opacity); + } else return _rasterDirectMaskedImage(surface, image, region, opacity); } else if (_blending(surface)) { return _rasterDirectBlendingImage(surface, image, region, opacity); } else { @@ -1415,7 +1242,7 @@ static bool _directImage(SwSurface* surface, const SwImage* image, const SwBBox& //Blenders for the following scenarios: [RLE / Whole] * [Direct / Scaled / Transformed] -static bool _rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, const SwBBox& region, uint8_t opacity) +static bool _rasterImage(SwSurface* surface, SwImage* image, const Matrix& transform, const SwBBox& region, uint8_t opacity) { //RLE Image if (image->rle) { @@ -1528,13 +1355,23 @@ static bool _rasterBlendingGradientRect(SwSurface* surface, const SwBBox& region template static bool _rasterTranslucentGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) { - 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); - for (uint32_t y = 0; y < h; ++y) { - fillMethod()(fill, buffer, region.min.y + y, region.min.x, w, opBlendPreNormal, 255); - buffer += surface->stride; + //32 bits + if (surface->channelSize == sizeof(uint32_t)) { + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; + for (uint32_t y = 0; y < h; ++y) { + fillMethod()(fill, buffer, region.min.y + y, region.min.x, w, opBlendPreNormal, 255); + buffer += surface->stride; + } + //8 bits + } else if (surface->channelSize == sizeof(uint8_t)) { + auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x; + for (uint32_t y = 0; y < h; ++y) { + fillMethod()(fill, buffer, region.min.y + y, region.min.x, w, _opMaskAdd, 255); + buffer += surface->stride; + } } return true; } @@ -1543,12 +1380,23 @@ static bool _rasterTranslucentGradientRect(SwSurface* surface, const SwBBox& reg template static bool _rasterSolidGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) { - auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; auto w = static_cast(region.max.x - region.min.x); auto h = static_cast(region.max.y - region.min.y); - for (uint32_t y = 0; y < h; ++y) { - fillMethod()(fill, buffer + y * surface->stride, region.min.y + y, region.min.x, w, opBlendSrcOver, 255); + //32 bits + if (surface->channelSize == sizeof(uint32_t)) { + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; + for (uint32_t y = 0; y < h; ++y) { + fillMethod()(fill, buffer, region.min.y + y, region.min.x, w, opBlendSrcOver, 255); + buffer += surface->stride; + } + //8 bits + } else if (surface->channelSize == sizeof(uint8_t)) { + auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x; + for (uint32_t y = 0; y < h; ++y) { + fillMethod()(fill, buffer, region.min.y + y, region.min.x, w, _opMaskNone, 255); + buffer += surface->stride; + } } return true; } @@ -1556,8 +1404,6 @@ static bool _rasterSolidGradientRect(SwSurface* surface, const SwBBox& region, c static bool _rasterLinearGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) { - if (fill->linear.len < FLOAT_EPSILON) return false; - if (_compositing(surface)) { if (_matting(surface)) return _rasterGradientMattedRect(surface, region, fill); else return _rasterGradientMaskedRect(surface, region, fill); @@ -1591,7 +1437,7 @@ static bool _rasterRadialGradientRect(SwSurface* surface, const SwBBox& region, /************************************************************************/ template -static bool _rasterCompositeGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, SwMask maskOp) +static bool _rasterCompositeGradientMaskedRle(SwSurface* surface, const SwRle* rle, const SwFill* fill, SwMask maskOp) { auto span = rle->spans; auto cstride = surface->compositor->image.stride; @@ -1606,7 +1452,7 @@ static bool _rasterCompositeGradientMaskedRle(SwSurface* surface, const SwRleDat template -static bool _rasterDirectGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, SwMask maskOp) +static bool _rasterDirectGradientMaskedRle(SwSurface* surface, const SwRle* rle, const SwFill* fill, SwMask maskOp) { auto span = rle->spans; auto cstride = surface->compositor->image.stride; @@ -1623,7 +1469,7 @@ static bool _rasterDirectGradientMaskedRle(SwSurface* surface, const SwRleData* template -static bool _rasterGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +static bool _rasterGradientMaskedRle(SwSurface* surface, const SwRle* rle, const SwFill* fill) { auto method = surface->compositor->method; @@ -1638,7 +1484,7 @@ static bool _rasterGradientMaskedRle(SwSurface* surface, const SwRleData* rle, c template -static bool _rasterGradientMattedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +static bool _rasterGradientMattedRle(SwSurface* surface, const SwRle* rle, const SwFill* fill) { TVGLOG("SW_ENGINE", "Matted(%d) Rle Linear Gradient", (int)surface->compositor->method); @@ -1657,7 +1503,7 @@ static bool _rasterGradientMattedRle(SwSurface* surface, const SwRleData* rle, c template -static bool _rasterBlendingGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +static bool _rasterBlendingGradientRle(SwSurface* surface, const SwRle* rle, const SwFill* fill) { auto span = rle->spans; @@ -1670,7 +1516,7 @@ static bool _rasterBlendingGradientRle(SwSurface* surface, const SwRleData* rle, template -static bool _rasterTranslucentGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +static bool _rasterTranslucentGradientRle(SwSurface* surface, const SwRle* rle, const SwFill* fill) { auto span = rle->spans; @@ -1685,7 +1531,7 @@ static bool _rasterTranslucentGradientRle(SwSurface* surface, const SwRleData* r } else if (surface->channelSize == sizeof(uint8_t)) { for (uint32_t i = 0; i < rle->size; ++i, ++span) { auto dst = &surface->buf8[span->y * surface->stride + span->x]; - fillMethod()(fill, dst, span->y, span->x, span->len, _opMaskAdd, 255); + fillMethod()(fill, dst, span->y, span->x, span->len, _opMaskAdd, span->coverage); } } return true; @@ -1693,7 +1539,7 @@ static bool _rasterTranslucentGradientRle(SwSurface* surface, const SwRleData* r template -static bool _rasterSolidGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +static bool _rasterSolidGradientRle(SwSurface* surface, const SwRle* rle, const SwFill* fill) { auto span = rle->spans; @@ -1717,7 +1563,7 @@ static bool _rasterSolidGradientRle(SwSurface* surface, const SwRleData* rle, co } -static bool _rasterLinearGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +static bool _rasterLinearGradientRle(SwSurface* surface, const SwRle* rle, const SwFill* fill) { if (!rle) return false; @@ -1734,7 +1580,7 @@ static bool _rasterLinearGradientRle(SwSurface* surface, const SwRleData* rle, c } -static bool _rasterRadialGradientRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill) +static bool _rasterRadialGradientRle(SwSurface* surface, const SwRle* rle, const SwFill* fill) { if (!rle) return false; @@ -1742,9 +1588,9 @@ static bool _rasterRadialGradientRle(SwSurface* surface, const SwRleData* rle, c if (_matting(surface)) return _rasterGradientMattedRle(surface, rle, fill); else return _rasterGradientMaskedRle(surface, rle, fill); } else if (_blending(surface)) { - _rasterBlendingGradientRle(surface, rle, fill); + return _rasterBlendingGradientRle(surface, rle, fill); } else { - if (fill->translucent) _rasterTranslucentGradientRle(surface, rle, fill); + if (fill->translucent) return _rasterTranslucentGradientRle(surface, rle, fill); else return _rasterSolidGradientRle(surface, rle, fill); } return false; @@ -1802,7 +1648,7 @@ bool rasterCompositor(SwSurface* surface) } -bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h) +bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h, pixel_t val) { if (!surface || !surface->buf32 || surface->stride == 0 || surface->w == 0 || surface->h == 0) return false; @@ -1810,11 +1656,11 @@ bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_ if (surface->channelSize == sizeof(uint32_t)) { //full clear if (w == surface->stride) { - rasterPixel32(surface->buf32, 0x00000000, surface->stride * y, w * h); + rasterPixel32(surface->buf32, val, surface->stride * y, w * h); //partial clear } else { for (uint32_t i = 0; i < h; i++) { - rasterPixel32(surface->buf32, 0x00000000, (surface->stride * y + x) + (surface->stride * i), w); + rasterPixel32(surface->buf32, val, (surface->stride * y + x) + (surface->stride * i), w); } } //8 bits @@ -1833,7 +1679,7 @@ bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_ } -void rasterUnpremultiply(Surface* surface) +void rasterUnpremultiply(RenderSurface* surface) { if (surface->channelSize != sizeof(uint32_t)) return; @@ -1863,7 +1709,7 @@ void rasterUnpremultiply(Surface* surface) } -void rasterPremultiply(Surface* surface) +void rasterPremultiply(RenderSurface* surface) { ScopedLock lock(surface->key); if (surface->premultiplied || (surface->channelSize != sizeof(uint32_t))) return; @@ -1884,27 +1730,39 @@ void rasterPremultiply(Surface* surface) } -bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id) +bool rasterGradientShape(SwSurface* surface, SwShape* shape, const Fill* fdata, uint8_t opacity) { if (!shape->fill) return false; + if (auto color = fillFetchSolid(shape->fill, fdata)) { + auto a = MULTIPLY(color->a, opacity); + return a > 0 ? rasterShape(surface, shape, color->r, color->g, color->b, a) : true; + } + + auto type = fdata->type(); if (shape->fastTrack) { - if (id == TVG_CLASS_ID_LINEAR) return _rasterLinearGradientRect(surface, shape->bbox, shape->fill); - else if (id == TVG_CLASS_ID_RADIAL)return _rasterRadialGradientRect(surface, shape->bbox, shape->fill); + if (type == Type::LinearGradient) return _rasterLinearGradientRect(surface, shape->bbox, shape->fill); + else if (type == Type::RadialGradient)return _rasterRadialGradientRect(surface, shape->bbox, shape->fill); } else { - if (id == TVG_CLASS_ID_LINEAR) return _rasterLinearGradientRle(surface, shape->rle, shape->fill); - else if (id == TVG_CLASS_ID_RADIAL) return _rasterRadialGradientRle(surface, shape->rle, shape->fill); + if (type == Type::LinearGradient) return _rasterLinearGradientRle(surface, shape->rle, shape->fill); + else if (type == Type::RadialGradient) return _rasterRadialGradientRle(surface, shape->rle, shape->fill); } return false; } -bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id) +bool rasterGradientStroke(SwSurface* surface, SwShape* shape, const Fill* fdata, uint8_t opacity) { if (!shape->stroke || !shape->stroke->fill || !shape->strokeRle) return false; - if (id == TVG_CLASS_ID_LINEAR) return _rasterLinearGradientRle(surface, shape->strokeRle, shape->stroke->fill); - else if (id == TVG_CLASS_ID_RADIAL) return _rasterRadialGradientRle(surface, shape->strokeRle, shape->stroke->fill); + if (auto color = fillFetchSolid(shape->stroke->fill, fdata)) { + auto a = MULTIPLY(color->a, opacity); + return a > 0 ? rasterStroke(surface, shape, color->r, color->g, color->b, a) : true; + } + + auto type = fdata->type(); + if (type == Type::LinearGradient) return _rasterLinearGradientRle(surface, shape->strokeRle, shape->stroke->fill); + else if (type == Type::RadialGradient) return _rasterRadialGradientRle(surface, shape->strokeRle, shape->stroke->fill); return false; } @@ -1934,17 +1792,16 @@ 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) +bool rasterImage(SwSurface* surface, SwImage* image, const Matrix& transform, const SwBBox& bbox, uint8_t opacity) { //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); + return _rasterImage(surface, image, transform, bbox, opacity); } -bool rasterConvertCS(Surface* surface, ColorSpace to) +bool rasterConvertCS(RenderSurface* surface, ColorSpace to) { ScopedLock lock(surface->key); if (surface->cs == to) return true; @@ -1963,5 +1820,40 @@ bool rasterConvertCS(Surface* surface, ColorSpace to) return false; } + +//TODO: SIMD OPTIMIZATION? +void rasterXYFlip(uint32_t* src, uint32_t* dst, int32_t stride, int32_t w, int32_t h, const SwBBox& bbox, bool flipped) +{ + constexpr int32_t BLOCK = 8; //experimental decision + + if (flipped) { + src += ((bbox.min.x * stride) + bbox.min.y); + dst += ((bbox.min.y * stride) + bbox.min.x); + } else { + src += ((bbox.min.y * stride) + bbox.min.x); + dst += ((bbox.min.x * stride) + bbox.min.y); + } + + for (int32_t x = 0; x < w; x += BLOCK) { + auto bx = std::min(w, x + BLOCK) - x; + auto in = &src[x]; + auto out = &dst[x * stride]; + for (int32_t y = 0; y < h; y += BLOCK) { + auto p = &in[y * stride]; + auto q = &out[y]; + auto by = std::min(h, y + BLOCK) - y; + for (int32_t xx = 0; xx < bx; ++xx) { + for (int32_t yy = 0; yy < by; ++yy) { + *q = *p; + p += stride; + ++q; + } + p += 1 - by * stride; + q += stride - by; + } + } + } +} + #endif /* LV_USE_THORVG_INTERNAL */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterAvx.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterAvx.h index 82c177ce3..5c1128c07 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterAvx.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterAvx.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2021 - 2024 the ThorVG project. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -104,105 +104,127 @@ static void avxRasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32 static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - if (surface->channelSize != sizeof(uint32_t)) { - TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize); - return false; - } - - 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); - uint32_t ialpha = 255 - a; + //32bits channels + if (surface->channelSize == sizeof(uint32_t)) { + auto color = surface->join(r, g, b, a); + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; - auto avxColor = _mm_set1_epi32(color); - auto avxIalpha = _mm_set1_epi8(ialpha); + uint32_t ialpha = 255 - a; - for (uint32_t y = 0; y < h; ++y) { - auto dst = &buffer[y * surface->stride]; + auto avxColor = _mm_set1_epi32(color); + auto avxIalpha = _mm_set1_epi8(ialpha); - //1. fill the not aligned memory (for 128-bit registers a 16-bytes alignment is required) - auto notAligned = ((uintptr_t)dst & 0xf) / 4; - if (notAligned) { - notAligned = (N_32BITS_IN_128REG - notAligned > w ? w : N_32BITS_IN_128REG - notAligned); - for (uint32_t x = 0; x < notAligned; ++x, ++dst) { + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + + //1. fill the not aligned memory (for 128-bit registers a 16-bytes alignment is required) + auto notAligned = ((uintptr_t)dst & 0xf) / 4; + if (notAligned) { + notAligned = (N_32BITS_IN_128REG - notAligned > w ? w : N_32BITS_IN_128REG - notAligned); + for (uint32_t x = 0; x < notAligned; ++x, ++dst) { + *dst = color + ALPHA_BLEND(*dst, ialpha); + } + } + + //2. fill the aligned memory - N_32BITS_IN_128REG pixels processed at once + uint32_t iterations = (w - notAligned) / N_32BITS_IN_128REG; + uint32_t avxFilled = iterations * N_32BITS_IN_128REG; + auto avxDst = (__m128i*)dst; + for (uint32_t x = 0; x < iterations; ++x, ++avxDst) { + *avxDst = _mm_add_epi32(avxColor, ALPHA_BLEND(*avxDst, avxIalpha)); + } + + //3. fill the remaining pixels + int32_t leftovers = w - notAligned - avxFilled; + dst += avxFilled; + while (leftovers--) { *dst = color + ALPHA_BLEND(*dst, ialpha); + dst++; } } - - //2. fill the aligned memory - N_32BITS_IN_128REG pixels processed at once - uint32_t iterations = (w - notAligned) / N_32BITS_IN_128REG; - uint32_t avxFilled = iterations * N_32BITS_IN_128REG; - auto avxDst = (__m128i*)dst; - for (uint32_t x = 0; x < iterations; ++x, ++avxDst) { - *avxDst = _mm_add_epi32(avxColor, ALPHA_BLEND(*avxDst, avxIalpha)); - } - - //3. fill the remaining pixels - int32_t leftovers = w - notAligned - avxFilled; - dst += avxFilled; - while (leftovers--) { - *dst = color + ALPHA_BLEND(*dst, ialpha); - dst++; + //8bit grayscale + } else if (surface->channelSize == sizeof(uint8_t)) { + TVGLOG("SW_ENGINE", "Require AVX Optimization, Channel Size = %d", surface->channelSize); + auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x; + auto ialpha = ~a; + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + for (uint32_t x = 0; x < w; ++x, ++dst) { + *dst = a + MULTIPLY(*dst, ialpha); + } } } return true; } -static bool avxRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool avxRasterTranslucentRle(SwSurface* surface, const SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - if (surface->channelSize != sizeof(uint32_t)) { - TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize); - return false; - } - - auto color = surface->join(r, g, b, a); auto span = rle->spans; - uint32_t src; - for (uint32_t i = 0; i < rle->size; ++i) { - auto dst = &surface->buf32[span->y * surface->stride + span->x]; + //32bit channels + if (surface->channelSize == sizeof(uint32_t)) { + auto color = surface->join(r, g, b, a); + uint32_t src; - if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage); - else src = color; + for (uint32_t i = 0; i < rle->size; ++i) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; - auto ialpha = IA(src); + if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage); + else src = color; - //1. fill the not aligned memory (for 128-bit registers a 16-bytes alignment is required) - auto notAligned = ((uintptr_t)dst & 0xf) / 4; - if (notAligned) { - notAligned = (N_32BITS_IN_128REG - notAligned > span->len ? span->len : N_32BITS_IN_128REG - notAligned); - for (uint32_t x = 0; x < notAligned; ++x, ++dst) { + auto ialpha = IA(src); + + //1. fill the not aligned memory (for 128-bit registers a 16-bytes alignment is required) + auto notAligned = ((uintptr_t)dst & 0xf) / 4; + if (notAligned) { + notAligned = (N_32BITS_IN_128REG - notAligned > span->len ? span->len : N_32BITS_IN_128REG - notAligned); + for (uint32_t x = 0; x < notAligned; ++x, ++dst) { + *dst = src + ALPHA_BLEND(*dst, ialpha); + } + } + + //2. fill the aligned memory using avx - N_32BITS_IN_128REG pixels processed at once + //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) { + auto avxSrc = _mm_set1_epi32(src); + auto avxIalpha = _mm_set1_epi8(ialpha); + + avxFilled = iterations * N_32BITS_IN_128REG; + auto avxDst = (__m128i*)dst; + for (uint32_t x = 0; x < iterations; ++x, ++avxDst) { + *avxDst = _mm_add_epi32(avxSrc, ALPHA_BLEND(*avxDst, avxIalpha)); + } + } + + //3. fill the remaining pixels + int32_t leftovers = span->len - notAligned - avxFilled; + dst += avxFilled; + while (leftovers--) { *dst = src + ALPHA_BLEND(*dst, ialpha); + dst++; + } + + ++span; + } + //8bit grayscale + } else if (surface->channelSize == sizeof(uint8_t)) { + TVGLOG("SW_ENGINE", "Require AVX Optimization, Channel Size = %d", surface->channelSize); + uint8_t src; + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf8[span->y * surface->stride + span->x]; + if (span->coverage < 255) src = MULTIPLY(span->coverage, a); + else src = a; + auto ialpha = ~a; + for (uint32_t x = 0; x < span->len; ++x, ++dst) { + *dst = src + MULTIPLY(*dst, ialpha); } } - - //2. fill the aligned memory using avx - N_32BITS_IN_128REG pixels processed at once - //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) { - auto avxSrc = _mm_set1_epi32(src); - auto avxIalpha = _mm_set1_epi8(ialpha); - - avxFilled = iterations * N_32BITS_IN_128REG; - auto avxDst = (__m128i*)dst; - for (uint32_t x = 0; x < iterations; ++x, ++avxDst) { - *avxDst = _mm_add_epi32(avxSrc, ALPHA_BLEND(*avxDst, avxIalpha)); - } - } - - //3. fill the remaining pixels - int32_t leftovers = span->len - notAligned - avxFilled; - dst += avxFilled; - while (leftovers--) { - *dst = src + ALPHA_BLEND(*dst, ialpha); - dst++; - } - - ++span; } return true; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterC.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterC.h index bc5211e5e..1e73aa455 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterC.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterC.h @@ -63,7 +63,7 @@ static void inline cRasterPixels(PIXEL_T* dst, PIXEL_T val, uint32_t offset, int } -static bool inline cRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool inline cRasterTranslucentRle(SwSurface* surface, const SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { auto span = rle->spans; @@ -128,7 +128,7 @@ static bool inline cRasterTranslucentRect(SwSurface* surface, const SwBBox& regi } -static bool inline cRasterABGRtoARGB(Surface* surface) +static bool inline cRasterABGRtoARGB(RenderSurface* surface) { TVGLOG("SW_ENGINE", "Convert ColorSpace ABGR - ARGB [Size: %d x %d]", surface->w, surface->h); @@ -159,7 +159,7 @@ static bool inline cRasterABGRtoARGB(Surface* surface) } -static bool inline cRasterARGBtoABGR(Surface* surface) +static bool inline cRasterARGBtoABGR(RenderSurface* surface) { //exactly same with ABGRtoARGB return cRasterABGRtoARGB(surface); diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterNeon.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterNeon.h index a84bfe87d..8e05dd98b 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterNeon.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterNeon.h @@ -92,46 +92,58 @@ static void neonRasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int3 } -static bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool neonRasterTranslucentRle(SwSurface* surface, const SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - if (surface->channelSize != sizeof(uint32_t)) { - TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize); - return false; - } - - auto color = surface->join(r, g, b, a); auto span = rle->spans; - uint32_t src; - uint8x8_t *vDst = nullptr; - uint16_t align; - for (uint32_t i = 0; i < rle->size; ++i) { - if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage); - else src = color; + //32bit channels + if (surface->channelSize == sizeof(uint32_t)) { + auto color = surface->join(r, g, b, a); + uint32_t src; + uint8x8_t *vDst = nullptr; + uint16_t align; - auto dst = &surface->buf32[span->y * surface->stride + span->x]; - auto ialpha = IA(src); + for (uint32_t i = 0; i < rle->size; ++i) { + if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage); + else src = color; - if ((((uintptr_t) dst) & 0x7) != 0) { - //fill not aligned byte - *dst = src + ALPHA_BLEND(*dst, ialpha); - vDst = (uint8x8_t*)(dst + 1); - align = 1; - } else { - vDst = (uint8x8_t*) dst; - align = 0; + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto ialpha = IA(src); + + if ((((uintptr_t) dst) & 0x7) != 0) { + //fill not aligned byte + *dst = src + ALPHA_BLEND(*dst, ialpha); + vDst = (uint8x8_t*)(dst + 1); + align = 1; + } else { + vDst = (uint8x8_t*) dst; + align = 0; + } + + uint8x8_t vSrc = (uint8x8_t) vdup_n_u32(src); + uint8x8_t vIalpha = vdup_n_u8((uint8_t) ialpha); + + for (uint32_t x = 0; x < (span->len - align) / 2; ++x) + vDst[x] = vadd_u8(vSrc, ALPHA_BLEND(vDst[x], vIalpha)); + + auto leftovers = (span->len - align) % 2; + if (leftovers > 0) dst[span->len - 1] = src + ALPHA_BLEND(dst[span->len - 1], ialpha); + + ++span; + } + //8bit grayscale + } else if (surface->channelSize == sizeof(uint8_t)) { + TVGLOG("SW_ENGINE", "Require Neon Optimization, Channel Size = %d", surface->channelSize); + uint8_t src; + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf8[span->y * surface->stride + span->x]; + if (span->coverage < 255) src = MULTIPLY(span->coverage, a); + else src = a; + auto ialpha = ~a; + for (uint32_t x = 0; x < span->len; ++x, ++dst) { + *dst = src + MULTIPLY(*dst, ialpha); + } } - - uint8x8_t vSrc = (uint8x8_t) vdup_n_u32(src); - uint8x8_t vIalpha = vdup_n_u8((uint8_t) ialpha); - - for (uint32_t x = 0; x < (span->len - align) / 2; ++x) - vDst[x] = vadd_u8(vSrc, ALPHA_BLEND(vDst[x], vIalpha)); - - auto leftovers = (span->len - align) % 2; - if (leftovers > 0) dst[span->len - 1] = src + ALPHA_BLEND(dst[span->len - 1], ialpha); - - ++span; } return true; } @@ -139,41 +151,51 @@ static bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, u static bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - if (surface->channelSize != sizeof(uint32_t)) { - TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize); - return false; - } - - 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); - auto ialpha = 255 - a; - auto vColor = vdup_n_u32(color); - auto vIalpha = vdup_n_u8((uint8_t) ialpha); + //32bits channels + if (surface->channelSize == sizeof(uint32_t)) { + auto color = surface->join(r, g, b, a); + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; + auto ialpha = 255 - a; - uint8x8_t* vDst = nullptr; - uint32_t align; + auto vColor = vdup_n_u32(color); + auto vIalpha = vdup_n_u8((uint8_t) ialpha); - for (uint32_t y = 0; y < h; ++y) { - auto dst = &buffer[y * surface->stride]; + uint8x8_t* vDst = nullptr; + uint32_t align; - if ((((uintptr_t) dst) & 0x7) != 0) { - //fill not aligned byte - *dst = color + ALPHA_BLEND(*dst, ialpha); - vDst = (uint8x8_t*) (dst + 1); - align = 1; - } else { - vDst = (uint8x8_t*) dst; - align = 0; + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + + if ((((uintptr_t) dst) & 0x7) != 0) { + //fill not aligned byte + *dst = color + ALPHA_BLEND(*dst, ialpha); + vDst = (uint8x8_t*) (dst + 1); + align = 1; + } else { + vDst = (uint8x8_t*) dst; + align = 0; + } + + for (uint32_t x = 0; x < (w - align) / 2; ++x) + vDst[x] = vadd_u8((uint8x8_t)vColor, ALPHA_BLEND(vDst[x], vIalpha)); + + auto leftovers = (w - align) % 2; + if (leftovers > 0) dst[w - 1] = color + ALPHA_BLEND(dst[w - 1], ialpha); + } + //8bit grayscale + } else if (surface->channelSize == sizeof(uint8_t)) { + TVGLOG("SW_ENGINE", "Require Neon Optimization, Channel Size = %d", surface->channelSize); + auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x; + auto ialpha = ~a; + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + for (uint32_t x = 0; x < w; ++x, ++dst) { + *dst = a + MULTIPLY(*dst, ialpha); + } } - - for (uint32_t x = 0; x < (w - align) / 2; ++x) - vDst[x] = vadd_u8((uint8x8_t)vColor, ALPHA_BLEND(vDst[x], vIalpha)); - - auto leftovers = (w - align) % 2; - if (leftovers > 0) dst[w - 1] = color + ALPHA_BLEND(dst[w - 1], ialpha); } return true; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterTexmap.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterTexmap.h index 6ef2e3204..59bebc172 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterTexmap.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRasterTexmap.h @@ -23,6 +23,17 @@ #include "../../lv_conf_internal.h" #if LV_USE_THORVG_INTERNAL +struct Vertex +{ + Point pt; + Point uv; +}; + +struct Polygon +{ + Vertex vertex[3]; +}; + struct AALine { int32_t x[2]; @@ -37,14 +48,6 @@ struct AASpans int32_t yEnd; }; -static inline void _swap(float& a, float& b, float& tmp) -{ - tmp = a; - a = b; - b = tmp; -} - - //Careful! Shared resource, No support threading static float dudx, dvdx; static float dxdya, dxdyb, dudya, dvdya; @@ -653,28 +656,27 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const float off_y; float dxdy[3] = {0.0f, 0.0f, 0.0f}; - float tmp; auto upper = false; //Sort the vertices in ascending Y order if (y[0] > y[1]) { - _swap(x[0], x[1], tmp); - _swap(y[0], y[1], tmp); - _swap(u[0], u[1], tmp); - _swap(v[0], v[1], tmp); + std::swap(x[0], x[1]); + std::swap(y[0], y[1]); + std::swap(u[0], u[1]); + std::swap(v[0], v[1]); } if (y[0] > y[2]) { - _swap(x[0], x[2], tmp); - _swap(y[0], y[2], tmp); - _swap(u[0], u[2], tmp); - _swap(v[0], v[2], tmp); + std::swap(x[0], x[2]); + std::swap(y[0], y[2]); + std::swap(u[0], u[2]); + std::swap(v[0], v[2]); } if (y[1] > y[2]) { - _swap(x[1], x[2], tmp); - _swap(y[1], y[2], tmp); - _swap(u[1], u[2], tmp); - _swap(v[1], v[2], tmp); + std::swap(x[1], x[2]); + std::swap(y[1], y[2]); + std::swap(u[1], u[2]); + std::swap(v[1], v[2]); } //Y indexes @@ -687,7 +689,7 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const auto denom = ((x[2] - x[0]) * (y[1] - y[0]) - (x[1] - x[0]) * (y[2] - y[0])); //Skip poly if it's an infinitely thin line - if (mathZero(denom)) return; + if (tvg::zero(denom)) return; denom = 1 / denom; //Reciprocal for speeding up dudx = ((u[2] - u[0]) * (y[1] - y[0]) - (u[1] - u[0]) * (y[2] - y[0])) * denom; @@ -703,8 +705,8 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const //Determine which side of the polygon the longer edge is on auto side = (dxdy[1] > dxdy[0]) ? true : false; - if (mathEqual(y[0], y[1])) side = x[0] > x[1]; - if (mathEqual(y[1], y[2])) side = x[2] > x[1]; + if (tvg::equal(y[0], y[1])) side = x[0] > x[1]; + if (tvg::equal(y[1], y[2])) side = x[2] > x[1]; auto regionTop = region ? region->min.y : image->rle->spans->y; //Normal Image or Rle Image? auto compositing = _compositing(surface); //Composition required @@ -829,14 +831,16 @@ static AASpans* _AASpans(float ymin, float ymax, const SwImage* image, const SwB if (!_arrange(image, region, yStart, yEnd)) return nullptr; - auto aaSpans = static_cast(malloc(sizeof(AASpans))); + auto aaSpans = static_cast(lv_malloc(sizeof(AASpans))); + LV_ASSERT_MALLOC(aaSpans); aaSpans->yStart = yStart; aaSpans->yEnd = yEnd; //Initialize X range auto height = yEnd - yStart; - aaSpans->lines = static_cast(malloc(height * sizeof(AALine))); + aaSpans->lines = static_cast(lv_malloc(height * sizeof(AALine))); + LV_ASSERT_MALLOC(aaSpans->lines); for (int32_t i = 0; i < height; i++) { aaSpans->lines[i].x[0] = INT32_MAX; @@ -880,17 +884,15 @@ static void _calcVertCoverage(AALine *lines, int32_t eidx, int32_t y, int32_t re static void _calcHorizCoverage(AALine *lines, int32_t eidx, int32_t y, int32_t x, int32_t x2) { - if (lines[y].length[eidx] < abs(x - x2)) { - lines[y].length[eidx] = abs(x - x2); - lines[y].coverage[eidx] = (255 / (lines[y].length[eidx] + 1)); - } + lines[y].length[eidx] = abs(x - x2); + lines[y].coverage[eidx] = (255 / (lines[y].length[eidx] + 1)); } /* * This Anti-Aliasing mechanism is originated from Hermet Park's idea. * To understand this AA logic, you can refer this page: - * www.hermet.pe.kr/122 (hermetpark@gmail.com) + * https://uigraphics.tistory.com/1 */ static void _calcAAEdge(AASpans *aaSpans, int32_t eidx) { @@ -909,9 +911,14 @@ static void _calcAAEdge(AASpans *aaSpans, int32_t eidx) ptx[1] = tx[1]; \ } while (0) + struct Point + { + int32_t x, y; + }; + int32_t y = 0; - SwPoint pEdge = {-1, -1}; //previous edge point - SwPoint edgeDiff = {0, 0}; //temporary used for point distance + Point pEdge = {-1, -1}; //previous edge point + Point edgeDiff = {0, 0}; //temporary used for point distance /* store bigger to tx[0] between prev and current edge's x positions. */ int32_t tx[2] = {0, 0}; @@ -936,6 +943,9 @@ static void _calcAAEdge(AASpans *aaSpans, int32_t eidx) //Calculates AA Edges for (y++; y < yEnd; y++) { + + if (lines[y].x[0] == INT32_MAX) continue; + //Ready tx if (eidx == 0) { tx[0] = pEdge.x; @@ -1033,6 +1043,7 @@ static void _calcAAEdge(AASpans *aaSpans, int32_t eidx) static bool _apply(SwSurface* surface, AASpans* aaSpans) { + auto end = surface->buf32 + surface->h * surface->stride; auto y = aaSpans->yStart; uint32_t pixel; uint32_t* dst; @@ -1053,8 +1064,13 @@ static bool _apply(SwSurface* surface, AASpans* aaSpans) dst = surface->buf32 + (offset + line->x[0]); if (line->x[0] > 1) pixel = *(dst - 1); else pixel = *dst; - pos = 1; + + //exceptional handling. out of memory bound. + if (dst + line->length[0] >= end) { + pos += (dst + line->length[0] - end); + } + while (pos <= line->length[0]) { *dst = INTERPOLATE(*dst, pixel, line->coverage[0] * pos); ++dst; @@ -1062,22 +1078,26 @@ static bool _apply(SwSurface* surface, AASpans* aaSpans) } //Right edge - dst = surface->buf32 + (offset + line->x[1] - 1); + dst = surface->buf32 + offset + line->x[1] - 1; + if (line->x[1] < (int32_t)(surface->w - 1)) pixel = *(dst + 1); else pixel = *dst; + pos = line->length[1]; - pos = width; - while ((int32_t)(width - line->length[1]) < pos) { - *dst = INTERPOLATE(*dst, pixel, 255 - (line->coverage[1] * (line->length[1] - (width - pos)))); + //exceptional handling. out of memory bound. + if (dst - pos < surface->buf32) --pos; + + while (pos > 0) { + *dst = INTERPOLATE(*dst, pixel, 255 - (line->coverage[1] * pos)); --dst; --pos; } - } + } y++; } - free(aaSpans->lines); - free(aaSpans); + lv_free(aaSpans->lines); + lv_free(aaSpans); return true; } @@ -1093,7 +1113,7 @@ static bool _apply(SwSurface* surface, AASpans* aaSpans) | / | 3 -- 2 */ -static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox* region, uint8_t opacity) +static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const Matrix& transform, const SwBBox* region, uint8_t opacity) { if (surface->channelSize == sizeof(uint8_t)) { TVGERR("SW_ENGINE", "Not supported grayscale Textmap polygon!"); @@ -1101,7 +1121,7 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const } //Exceptions: No dedicated drawing area? - if ((!image->rle && !region) || (image->rle && image->rle->size == 0)) return false; + if ((!image->rle && !region) || (image->rle && image->rle->size == 0)) return true; /* Prepare vertices. shift XY coordinates to match the sub-pixeling technique. */ @@ -1113,7 +1133,7 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const float ys = FLT_MAX, ye = -1.0f; for (int i = 0; i < 4; i++) { - if (transform) mathMultiply(&vertices[i].pt, transform); + 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; } @@ -1145,70 +1165,5 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const return _apply(surface, aaSpans); } - -/* - Provide any number of triangles to draw a mesh using the supplied image. - Indexes are not used, so each triangle (Polygon) vertex has to be defined, even if they copy the previous one. - Example: - - 0 -- 1 0 -- 1 0 - | / | --> | / / | - | / | | / / | - 2 -- 3 2 1 -- 2 - - Should provide two Polygons, one for each triangle. - // TODO: region? -*/ -static bool _rasterTexmapPolygonMesh(SwSurface* surface, const SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox* region, uint8_t opacity) -{ - if (surface->channelSize == sizeof(uint8_t)) { - TVGERR("SW_ENGINE", "Not supported grayscale Textmap polygon mesh!"); - return false; - } - - //Exceptions: No dedicated drawing area? - if ((!image->rle && !region) || (image->rle && image->rle->size == 0)) return false; - - // Step polygons once to transform - auto transformedTris = (Polygon*)malloc(sizeof(Polygon) * mesh->triangleCnt); - float ys = FLT_MAX, ye = -1.0f; - for (uint32_t i = 0; i < mesh->triangleCnt; i++) { - transformedTris[i] = mesh->triangles[i]; - mathMultiply(&transformedTris[i].vertex[0].pt, transform); - mathMultiply(&transformedTris[i].vertex[1].pt, transform); - mathMultiply(&transformedTris[i].vertex[2].pt, transform); - - if (transformedTris[i].vertex[0].pt.y < ys) ys = transformedTris[i].vertex[0].pt.y; - else if (transformedTris[i].vertex[0].pt.y > ye) ye = transformedTris[i].vertex[0].pt.y; - if (transformedTris[i].vertex[1].pt.y < ys) ys = transformedTris[i].vertex[1].pt.y; - else if (transformedTris[i].vertex[1].pt.y > ye) ye = transformedTris[i].vertex[1].pt.y; - if (transformedTris[i].vertex[2].pt.y < ys) ys = transformedTris[i].vertex[2].pt.y; - else if (transformedTris[i].vertex[2].pt.y > ye) ye = transformedTris[i].vertex[2].pt.y; - - // Convert normalized UV coordinates to image coordinates - transformedTris[i].vertex[0].uv.x *= (float)image->w; - transformedTris[i].vertex[0].uv.y *= (float)image->h; - transformedTris[i].vertex[1].uv.x *= (float)image->w; - transformedTris[i].vertex[1].uv.y *= (float)image->h; - transformedTris[i].vertex[2].uv.x *= (float)image->w; - transformedTris[i].vertex[2].uv.y *= (float)image->h; - } - - // Get AA spans and step polygons again to draw - if (auto aaSpans = _AASpans(ys, ye, image, region)) { - for (uint32_t i = 0; i < mesh->triangleCnt; i++) { - _rasterPolygonImage(surface, image, region, transformedTris[i], aaSpans, opacity); - } -#if 0 - if (_compositing(surface) && _masking(surface) && !_direct(surface->compositor->method)) { - _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); - } -#endif - _apply(surface, aaSpans); - } - free(transformedTris); - return true; -} - #endif /* LV_USE_THORVG_INTERNAL */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.cpp index 9a0965424..5b812d7f1 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.cpp @@ -23,6 +23,10 @@ #include "../../lv_conf_internal.h" #if LV_USE_THORVG_INTERNAL +#ifdef THORVG_SW_OPENMP_SUPPORT + #include +#endif +#include #include "tvgMath.h" #include "tvgSwCommon.h" #include "tvgTaskScheduler.h" @@ -40,8 +44,8 @@ struct SwTask : Task { SwSurface* surface = nullptr; SwMpool* mpool = nullptr; - SwBBox bbox = {{0, 0}, {0, 0}}; //Whole Rendering Region - Matrix* transform = nullptr; + SwBBox bbox; //Rendering Region + Matrix transform; Array clips; RenderUpdateFlag flags = RenderUpdateFlag::None; uint8_t opacity; @@ -67,13 +71,8 @@ struct SwTask : Task } virtual void dispose() = 0; - virtual bool clip(SwRleData* target) = 0; - virtual SwRleData* rle() = 0; - - virtual ~SwTask() - { - free(transform); - } + virtual bool clip(SwRle* target) = 0; + virtual ~SwTask() {} }; @@ -81,7 +80,6 @@ struct SwShapeTask : SwTask { SwShape shape; const RenderShape* rshape = nullptr; - bool cmpStroking = false; bool clipper = false; /* We assume that if the stroke width is greater than 2, @@ -90,7 +88,7 @@ struct SwShapeTask : SwTask Additionally, the stroke style should not be dashed. */ bool antialiasing(float strokeWidth) { - return strokeWidth < 2.0f || rshape->stroke->dashCnt > 0 || rshape->stroke->strokeFirst; + return strokeWidth < 2.0f || rshape->stroke->dashCnt > 0 || rshape->stroke->strokeFirst || rshape->strokeTrim() || rshape->stroke->color[3] < 255;; } float validStrokeWidth() @@ -98,40 +96,34 @@ struct SwShapeTask : SwTask if (!rshape->stroke) return 0.0f; auto width = rshape->stroke->width; - if (mathZero(width)) return 0.0f; + if (tvg::zero(width)) return 0.0f; if (!rshape->stroke->fill && (MULTIPLY(rshape->stroke->color[3], opacity) == 0)) return 0.0f; - if (mathZero(rshape->stroke->trim.begin - rshape->stroke->trim.end)) return 0.0f; + if (tvg::zero(rshape->stroke->trim.begin - rshape->stroke->trim.end)) return 0.0f; - if (transform) return (width * sqrt(transform->e11 * transform->e11 + transform->e12 * transform->e12)); - else return width; + return (width * sqrt(transform.e11 * transform.e11 + transform.e12 * transform.e12)); } - - bool clip(SwRleData* target) override + bool clip(SwRle* target) override { - if (shape.fastTrack) rleClipRect(target, &bbox); - else if (shape.rle) rleClipPath(target, shape.rle); + if (shape.fastTrack) rleClip(target, &bbox); + else if (shape.rle) rleClip(target, shape.rle); else return false; return true; } - SwRleData* rle() override - { - if (!shape.rle && shape.fastTrack) { - shape.rle = rleRender(&shape.bbox); - } - return shape.rle; - } - void run(unsigned tid) override { - if (opacity == 0 && !clipper) return; //Invisible + //Invisible + if (opacity == 0 && !clipper) { + bbox.reset(); + return; + } auto strokeWidth = validStrokeWidth(); - bool visibleFill = false; - auto clipRegion = bbox; + SwBBox renderRegion{}; + auto visibleFill = false; //This checks also for the case, if the invisible shape turned to visible by alpha. auto prepareShape = false; @@ -143,15 +135,16 @@ struct SwShapeTask : SwTask rshape->fillColor(nullptr, nullptr, nullptr, &alpha); alpha = MULTIPLY(alpha, opacity); visibleFill = (alpha > 0 || rshape->fill); + shapeReset(&shape); if (visibleFill || clipper) { - shapeReset(&shape); - if (!shapePrepare(&shape, rshape, transform, clipRegion, bbox, mpool, tid, clips.count > 0 ? true : false)) { + if (!shapePrepare(&shape, rshape, transform, bbox, renderRegion, mpool, tid, clips.count > 0 ? true : false)) { visibleFill = false; + renderRegion.reset(); } } } //Fill - if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) { + if (flags & (RenderUpdateFlag::Path |RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) { if (visibleFill || clipper) { if (!shapeGenRle(&shape, rshape, antialiasing(strokeWidth))) goto err; } @@ -164,11 +157,11 @@ struct SwShapeTask : SwTask } } //Stroke - if (flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) { + if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) { if (strokeWidth > 0.0f) { shapeResetStroke(&shape, rshape, transform); - if (!shapeGenStrokeRle(&shape, rshape, transform, clipRegion, bbox, mpool, tid)) goto err; + if (!shapeGenStrokeRle(&shape, rshape, transform, bbox, renderRegion, mpool, tid)) goto err; if (auto fill = rshape->strokeFill()) { auto ctable = (flags & RenderUpdateFlag::GradientStroke) ? true : false; if (ctable) shapeResetStrokeFill(&shape); @@ -192,9 +185,13 @@ struct SwShapeTask : SwTask //Clip stroke rle if (shape.strokeRle && !clipper->clip(shape.strokeRle)) goto err; } + + bbox = renderRegion; //sync + return; err: + bbox.reset(); shapeReset(&shape); shapeDelOutline(&shape, mpool, tid); } @@ -206,77 +203,17 @@ struct SwShapeTask : SwTask }; -struct SwSceneTask : SwTask -{ - Array scene; //list of paints render data (SwTask) - SwRleData* sceneRle = nullptr; - - bool clip(SwRleData* target) override - { - //Only one shape - if (scene.count == 1) { - return static_cast(*scene.data)->clip(target); - } - - //More than one shapes - if (sceneRle) rleClipPath(target, sceneRle); - else TVGLOG("SW_ENGINE", "No clippers in a scene?"); - - return true; - } - - SwRleData* rle() override - { - return sceneRle; - } - - void run(unsigned tid) override - { - //TODO: Skip the run if the scene hasn't changed. - if (!sceneRle) sceneRle = static_cast(calloc(1, sizeof(SwRleData))); - else rleReset(sceneRle); - - //Merge shapes if it has more than one shapes - if (scene.count > 1) { - //Merge first two clippers - auto clipper1 = static_cast(*scene.data); - auto clipper2 = static_cast(*(scene.data + 1)); - - rleMerge(sceneRle, clipper1->rle(), clipper2->rle()); - - //Unify the remained clippers - for (auto rd = scene.begin() + 2; rd < scene.end(); ++rd) { - auto clipper = static_cast(*rd); - rleMerge(sceneRle, sceneRle, clipper->rle()); - } - } - } - - void dispose() override - { - rleFree(sceneRle); - } -}; - - struct SwImageTask : SwTask { SwImage image; - Surface* source; //Image source - const RenderMesh* mesh = nullptr; //Should be valid ptr in action + RenderSurface* source; //Image source - bool clip(SwRleData* target) override + bool clip(SwRle* target) override { TVGERR("SW_ENGINE", "Image is used as ClipPath?"); return true; } - SwRleData* rle() override - { - TVGERR("SW_ENGINE", "Image is used as Scene ClipPath?"); - return nullptr; - } - void run(unsigned tid) override { auto clipRegion = bbox; @@ -296,10 +233,9 @@ struct SwImageTask : SwTask imageReset(&image); if (!image.data || image.w == 0 || image.h == 0) goto end; - if (!imagePrepare(&image, mesh, transform, clipRegion, bbox, mpool, tid)) goto end; + if (!imagePrepare(&image, transform, clipRegion, bbox, mpool, tid)) goto end; - // TODO: How do we clip the triangle mesh? Only clip non-meshed images for now - if (mesh->triangleCnt == 0 && clips.count > 0) { + if (clips.count > 0) { if (!imageGenRle(&image, bbox, false)) goto end; if (image.rle) { //Clear current task memorypool here if the clippers would use the same memory pool @@ -339,7 +275,7 @@ static void _renderFill(SwShapeTask* task, SwSurface* surface, uint8_t opacity) { uint8_t r, g, b, a; if (auto fill = task->rshape->fill) { - rasterGradientShape(surface, &task->shape, fill->identifier()); + rasterGradientShape(surface, &task->shape, fill, opacity); } else { task->rshape->fillColor(&r, &g, &b, &a); a = MULTIPLY(opacity, a); @@ -351,7 +287,7 @@ static void _renderStroke(SwShapeTask* task, SwSurface* surface, uint8_t opacity { uint8_t r, g, b, a; if (auto strokeFill = task->rshape->strokeFill()) { - rasterGradientStroke(surface, &task->shape, strokeFill->identifier()); + rasterGradientStroke(surface, &task->shape, strokeFill, opacity); } else { if (task->rshape->strokeColor(&r, &g, &b, &a)) { a = MULTIPLY(opacity, a); @@ -451,7 +387,7 @@ void SwRenderer::clearCompositors() { //Free Composite Caches for (auto comp = compositors.begin(); comp < compositors.end(); ++comp) { - free((*comp)->compositor->image.data); + lv_free((*comp)->compositor->image.data); delete((*comp)->compositor); delete(*comp); } @@ -483,7 +419,7 @@ bool SwRenderer::renderImage(RenderData data) if (task->opacity == 0) return true; - return rasterImage(surface, &task->image, task->mesh, task->transform, task->bbox, task->opacity); + return rasterImage(surface, &task->image, task->transform, task->bbox, task->opacity); } @@ -515,27 +451,18 @@ bool SwRenderer::blend(BlendMethod method) surface->blendMethod = method; switch (method) { - case BlendMethod::Add: - surface->blender = opBlendAdd; - break; - case BlendMethod::Screen: - surface->blender = opBlendScreen; + case BlendMethod::Normal: + surface->blender = nullptr; break; case BlendMethod::Multiply: surface->blender = opBlendMultiply; break; + case BlendMethod::Screen: + surface->blender = opBlendScreen; + break; case BlendMethod::Overlay: surface->blender = opBlendOverlay; break; - case BlendMethod::Difference: - surface->blender = opBlendDifference; - break; - case BlendMethod::Exclusion: - surface->blender = opBlendExclusion; - break; - case BlendMethod::SrcOver: - surface->blender = opBlendSrcOver; - break; case BlendMethod::Darken: surface->blender = opBlendDarken; break; @@ -554,7 +481,17 @@ bool SwRenderer::blend(BlendMethod method) case BlendMethod::SoftLight: surface->blender = opBlendSoftLight; break; + case BlendMethod::Difference: + surface->blender = opBlendDifference; + break; + case BlendMethod::Exclusion: + surface->blender = opBlendExclusion; + break; + case BlendMethod::Add: + surface->blender = opBlendAdd; + break; default: + TVGLOG("SW_ENGINE", "Non supported blending option = %d", (int) method); surface->blender = nullptr; break; } @@ -568,7 +505,7 @@ RenderRegion SwRenderer::region(RenderData data) } -bool SwRenderer::beginComposite(Compositor* cmp, CompositeMethod method, uint8_t opacity) +bool SwRenderer::beginComposite(RenderCompositor* cmp, CompositeMethod method, uint8_t opacity) { if (!cmp) return false; auto p = static_cast(cmp); @@ -606,13 +543,51 @@ bool SwRenderer::mempool(bool shared) } -const Surface* SwRenderer::mainSurface() +const RenderSurface* SwRenderer::mainSurface() { return surface; } -Compositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs) +SwSurface* SwRenderer::request(int channelSize) +{ + SwSurface* cmp = nullptr; + + //Use cached data + for (auto p = compositors.begin(); p < compositors.end(); ++p) { + if ((*p)->compositor->valid && (*p)->compositor->image.channelSize == channelSize) { + cmp = *p; + break; + } + } + + //New Composition + if (!cmp) { + //Inherits attributes from main surface + cmp = new SwSurface(surface); + cmp->compositor = new SwCompositor; + cmp->compositor->image.data = (pixel_t*)lv_malloc(channelSize * surface->stride * surface->h); + LV_ASSERT_MALLOC(cmp->compositor->image.data); + cmp->compositor->image.w = surface->w; + cmp->compositor->image.h = surface->h; + cmp->compositor->image.stride = surface->stride; + cmp->compositor->image.direct = true; + cmp->compositor->valid = true; + cmp->channelSize = cmp->compositor->image.channelSize = channelSize; + cmp->w = cmp->compositor->image.w; + cmp->h = cmp->compositor->image.h; + + compositors.push(cmp); + } + + //Sync. This may have been modified by post-processing. + cmp->data = cmp->compositor->image.data; + + return cmp; +} + + +RenderCompositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs) { auto x = region.x; auto y = region.y; @@ -624,32 +599,11 @@ Compositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs) //Out of boundary if (x >= sw || y >= sh || x + w < 0 || y + h < 0) return nullptr; - SwSurface* cmp = nullptr; - - auto reqChannelSize = CHANNEL_SIZE(cs); - - //Use cached data - for (auto p = compositors.begin(); p < compositors.end(); ++p) { - if ((*p)->compositor->valid && (*p)->compositor->image.channelSize == reqChannelSize) { - cmp = *p; - break; - } - } - - //New Composition - if (!cmp) { - //Inherits attributes from main 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) - cmp->compositor->image.data = (pixel_t*)malloc(reqChannelSize * surface->stride * surface->h); - cmp->channelSize = cmp->compositor->image.channelSize = reqChannelSize; - - compositors.push(cmp); - } + auto cmp = request(CHANNEL_SIZE(cs)); //Boundary Check + if (x < 0) x = 0; + if (y < 0) y = 0; if (x + w > sw) w = (sw - x); if (y + h > sh) h = (sh - y); @@ -660,16 +614,11 @@ Compositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs) cmp->compositor->bbox.min.y = y; cmp->compositor->bbox.max.x = x + w; cmp->compositor->bbox.max.y = y + h; - cmp->compositor->image.stride = surface->stride; - cmp->compositor->image.w = surface->w; - cmp->compositor->image.h = surface->h; - cmp->compositor->image.direct = true; - cmp->data = cmp->compositor->image.data; - cmp->w = cmp->compositor->image.w; - cmp->h = cmp->compositor->image.h; - - rasterClear(cmp, x, y, w, h); + /* TODO: Currently, only blending might work. + Blending and composition must be handled together. */ + auto color = (surface->blender && !surface->compositor) ? 0x00ffffff : 0x00000000; + rasterClear(cmp, x, y, w, h, color); //Switch render target surface = cmp; @@ -678,7 +627,7 @@ Compositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs) } -bool SwRenderer::endComposite(Compositor* cmp) +bool SwRenderer::endComposite(RenderCompositor* cmp) { if (!cmp) return false; @@ -691,13 +640,35 @@ bool SwRenderer::endComposite(Compositor* cmp) //Default is alpha blending if (p->method == CompositeMethod::None) { - return rasterImage(surface, &p->image, nullptr, nullptr, p->bbox, p->opacity); + Matrix m = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + return rasterImage(surface, &p->image, m, p->bbox, p->opacity); } return true; } +bool SwRenderer::prepare(RenderEffect* effect) +{ + switch (effect->type) { + case SceneEffect::GaussianBlur: return effectGaussianPrepare(static_cast(effect)); + default: return false; + } +} + + +bool SwRenderer::effect(RenderCompositor* cmp, const RenderEffect* effect) +{ + auto p = static_cast(cmp); + auto& buffer = request(surface->channelSize)->compositor->image; + + switch (effect->type) { + case SceneEffect::GaussianBlur: return effectGaussianBlur(p->image, buffer, p->bbox, static_cast(effect)); + default: return false; + } +} + + ColorSpace SwRenderer::colorSpace() { if (surface) return surface->cs; @@ -717,14 +688,11 @@ void SwRenderer::dispose(RenderData data) } -void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform, const Array& clips, uint8_t opacity, RenderUpdateFlag flags) +void* SwRenderer::prepareCommon(SwTask* task, const Matrix& transform, const Array& clips, uint8_t opacity, RenderUpdateFlag flags) { if (!surface) return task; if (flags == RenderUpdateFlag::None) return task; - //Finish previous task if it has duplicated request. - task->done(); - //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. @@ -733,29 +701,20 @@ void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform, } task->clips = clips; - - if (transform) { - if (!task->transform) task->transform = static_cast(malloc(sizeof(Matrix))); - *task->transform = transform->m; - } else { - if (task->transform) free(task->transform); - task->transform = nullptr; - } + task->transform = transform; //zero size? - if (task->transform) { - if (task->transform->e11 == 0.0f && task->transform->e12 == 0.0f) return task; //zero width - if (task->transform->e21 == 0.0f && task->transform->e22 == 0.0f) return task; //zero height - } + if (task->transform.e11 == 0.0f && task->transform.e12 == 0.0f) return task; //zero width + if (task->transform.e21 == 0.0f && task->transform.e22 == 0.0f) return task; //zero height task->opacity = opacity; task->surface = surface; task->mpool = mpool; task->flags = flags; - task->bbox.min.x = mathMax(static_cast(0), static_cast(vport.x)); - task->bbox.min.y = mathMax(static_cast(0), static_cast(vport.y)); - task->bbox.max.x = mathMin(static_cast(surface->w), static_cast(vport.x + vport.w)); - task->bbox.max.y = mathMin(static_cast(surface->h), static_cast(vport.y + vport.h)); + task->bbox.min.x = std::max(static_cast(0), static_cast(vport.x)); + task->bbox.min.y = std::max(static_cast(0), static_cast(vport.y)); + task->bbox.max.x = std::min(static_cast(surface->w), static_cast(vport.x + vport.w)); + task->bbox.max.y = std::min(static_cast(surface->h), static_cast(vport.y + vport.h)); if (!task->pushed) { task->pushed = true; @@ -768,42 +727,27 @@ void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform, } -RenderData SwRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) +RenderData SwRenderer::prepare(RenderSurface* surface, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) { //prepare task auto task = static_cast(data); if (!task) task = new SwImageTask; + else task->done(); + task->source = surface; - task->mesh = mesh; + return prepareCommon(task, transform, clips, opacity, flags); } -RenderData SwRenderer::prepare(const Array& scene, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) -{ - //prepare task - auto task = static_cast(data); - if (!task) task = new SwSceneTask; - task->scene = scene; - - //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.begin(); task < scene.end(); ++task) { - static_cast(*task)->done(); - } - return prepareCommon(task, transform, clips, opacity, flags); -} - - -RenderData SwRenderer::prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) +RenderData SwRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) { //prepare task auto task = static_cast(data); - if (!task) { - task = new SwShapeTask; - task->rshape = &rshape; - } + if (!task) task = new SwShapeTask; + else task->done(); + + task->rshape = &rshape; task->clipper = clipper; return prepareCommon(task, transform, clips, opacity, flags); @@ -834,6 +778,10 @@ bool SwRenderer::init(uint32_t threads) int32_t SwRenderer::init() { +#ifdef THORVG_SW_OPENMP_SUPPORT + omp_set_num_threads(TaskScheduler::threads()); +#endif + return initEngineCnt; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.h index 593ba52e4..45a54738c 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRenderer.h @@ -39,9 +39,8 @@ namespace tvg class SwRenderer : public RenderMethod { public: - RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override; - RenderData prepare(const Array& scene, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; - RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; + RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override; + RenderData prepare(RenderSurface* surface, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; bool preRender() override; bool renderShape(RenderData data) override; bool renderImage(RenderData data) override; @@ -52,18 +51,21 @@ public: bool viewport(const RenderRegion& vp) override; bool blend(BlendMethod method) override; ColorSpace colorSpace() override; - const Surface* mainSurface() override; + const RenderSurface* mainSurface() override; bool clear() override; bool sync() override; bool target(pixel_t* data, uint32_t stride, uint32_t w, uint32_t h, ColorSpace cs); bool mempool(bool shared); - Compositor* target(const RenderRegion& region, ColorSpace cs) override; - bool beginComposite(Compositor* cmp, CompositeMethod method, uint8_t opacity) override; - bool endComposite(Compositor* cmp) override; + RenderCompositor* target(const RenderRegion& region, ColorSpace cs) override; + bool beginComposite(RenderCompositor* cmp, CompositeMethod method, uint8_t opacity) override; + bool endComposite(RenderCompositor* cmp) override; void clearCompositors(); + bool prepare(RenderEffect* effect) override; + bool effect(RenderCompositor* cmp, const RenderEffect* effect) override; + static SwRenderer* gen(); static bool init(uint32_t threads); static int32_t init(); @@ -80,7 +82,8 @@ private: SwRenderer(); ~SwRenderer(); - RenderData prepareCommon(SwTask* task, const RenderTransform* transform, const Array& clips, uint8_t opacity, RenderUpdateFlag flags); + SwSurface* request(int channelSize); + RenderData prepareCommon(SwTask* task, const Matrix& transform, const Array& clips, uint8_t opacity, RenderUpdateFlag flags); }; } diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRle.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRle.cpp index 689f2fe1f..d70bac68c 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRle.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwRle.cpp @@ -200,7 +200,6 @@ /* Internal Class Implementation */ /************************************************************************/ -constexpr auto MAX_SPANS = 256; constexpr auto PIXEL_BITS = 8; //must be at least 6 bits! constexpr auto ONE_PIXEL = (1L << PIXEL_BITS); @@ -221,7 +220,7 @@ struct Cell struct RleWorker { - SwRleData* rle; + SwRle* rle; SwPoint cellPos; SwPoint cellMin; @@ -239,14 +238,11 @@ struct RleWorker SwPoint pos; SwPoint bezStack[32 * 3 + 1]; + SwPoint lineStack[32 + 1]; int levStack[32]; SwOutline* outline; - SwSpan spans[MAX_SPANS]; - int spansCnt; - int ySpan; - int bandSize; int bandShoot; @@ -304,26 +300,6 @@ static inline SwCoord HYPOT(SwPoint pt) return ((pt.x > pt.y) ? (pt.x + (3 * pt.y >> 3)) : (pt.y + (3 * pt.x >> 3))); } -static void _genSpan(SwRleData* rle, const SwSpan* spans, uint32_t count) -{ - auto newSize = rle->size + count; - - /* allocate enough memory for new spans */ - /* alloc is required to prevent free and reallocation */ - /* when the rle needs to be regenerated because of attribute change. */ - if (rle->alloc < newSize) { - rle->alloc = (newSize * 2); - //OPTIMIZE: use mempool! - rle->spans = static_cast(realloc(rle->spans, rle->alloc * sizeof(SwSpan))); - } - - //copy the new spans to the allocated memory - SwSpan* lastSpan = rle->spans + rle->size; - memcpy(lastSpan, spans, count * sizeof(SwSpan)); - - rle->size = newSize; -} - static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoord aCount) { @@ -347,25 +323,26 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor if (coverage > 255) coverage = 255; } + if (coverage == 0) return; + //span has ushort coordinates. check limit overflow if (x >= SHRT_MAX) { TVGERR("SW_ENGINE", "X-coordinate overflow!"); - x = SHRT_MAX; + return; } if (y >= SHRT_MAX) { - TVGERR("SW_ENGINE", "Y Coordinate overflow!"); - y = SHRT_MAX; + TVGERR("SW_ENGINE", "Y-coordinate overflow!"); + return; } - if (coverage > 0) { - if (!rw.antiAlias) coverage = 255; - auto count = rw.spansCnt; - auto span = rw.spans + count - 1; + auto rle = rw.rle; - //see whether we can add this span to the current list - if ((count > 0) && (rw.ySpan == y) && - (span->x + span->len == x) && (span->coverage == coverage)) { + if (!rw.antiAlias) coverage = 255; + //see whether we can add this span to the current list + if (rle->size > 0) { + auto span = rle->spans + rle->size - 1; + if ((span->coverage == coverage) && (span->y == y) && (span->x + span->len == x)) { //Clip x range SwCoord xOver = 0; if (x + aCount >= rw.cellMax.x) xOver -= (x + aCount - rw.cellMax.x); @@ -375,35 +352,36 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor span->len += (aCount + xOver); return; } - - if (count >= MAX_SPANS) { - _genSpan(rw.rle, rw.spans, count); - rw.spansCnt = 0; - rw.ySpan = 0; - span = rw.spans; - } else { - ++span; - } - - //Clip x range - SwCoord xOver = 0; - 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; - - //add a span to the current list - span->x = x; - span->y = y; - span->len = (aCount + xOver); - span->coverage = coverage; - ++rw.spansCnt; - rw.ySpan = y; } + + //span pool is full, grow it. + if (rle->size >= rle->alloc) { + auto newSize = (rle->size > 0) ? (rle->size * 2) : 256; + if (rle->alloc < newSize) { + rle->alloc = newSize; + rle->spans = static_cast(lv_realloc(rle->spans, rle->alloc * sizeof(SwSpan))); + LV_ASSERT_MALLOC(rle->spans); + } + } + + //Clip x range + SwCoord xOver = 0; + 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; + + //add a span to the current list + auto span = rle->spans + rle->size; + span->x = x; + span->y = y; + span->len = (aCount + xOver); + span->coverage = coverage; + rle->size++; } @@ -411,9 +389,6 @@ static void _sweep(RleWorker& rw) { if (rw.cellsCnt == 0) return; - rw.spansCnt = 0; - rw.ySpan = 0; - for (int y = 0; y < rw.yCnt; ++y) { auto cover = 0; auto x = 0; @@ -430,8 +405,6 @@ static void _sweep(RleWorker& rw) if (cover != 0) _horizLine(rw, x, y, cover * (ONE_PIXEL * 2), rw.cellXCnt - x); } - - if (rw.spansCnt > 0) _genSpan(rw.rle, rw.spans, rw.spansCnt); } @@ -545,98 +518,116 @@ static void _lineTo(RleWorker& rw, const SwPoint& to) return; } - auto diff = to - rw.pos; - auto f1 = rw.pos - SUBPIXELS(e1); - SwPoint f2; + auto line = rw.lineStack; + line[0] = to; + line[1] = rw.pos; - //inside one cell - if (e1 == e2) { - ; - //any horizontal line - } else if (diff.y == 0) { - e1.x = e2.x; - _setCell(rw, e1); - } else if (diff.x == 0) { - //vertical line up - if (diff.y > 0) { - do { - f2.y = ONE_PIXEL; - rw.cover += (f2.y - f1.y); - rw.area += (f2.y - f1.y) * f1.x * 2; - f1.y = 0; - ++e1.y; - _setCell(rw, e1); - } while(e1.y != e2.y); - //vertical line down - } else { - do { - f2.y = 0; - rw.cover += (f2.y - f1.y); - rw.area += (f2.y - f1.y) * f1.x * 2; - f1.y = ONE_PIXEL; - --e1.y; - _setCell(rw, e1); - } while(e1.y != e2.y); + while (true) { + auto diff = line[0] - line[1]; + auto L = HYPOT(diff); + + if (L > SHRT_MAX) { + mathSplitLine(line); + ++line; + continue; } - //any other line - } else { - Area prod = diff.x * f1.y - diff.y * f1.x; + e1 = TRUNC(line[1]); + e2 = TRUNC(line[0]); - /* These macros speed up repetitive divisions by replacing them - with multiplications and right shifts. */ - auto dx_r = static_cast(ULONG_MAX >> PIXEL_BITS) / (diff.x); - auto dy_r = static_cast(ULONG_MAX >> PIXEL_BITS) / (diff.y); - - /* The fundamental value `prod' determines which side and the */ - /* exact coordinate where the line exits current cell. It is */ - /* also easily updated when moving from one cell to the next. */ - do { - auto px = diff.x * ONE_PIXEL; - auto py = diff.y * ONE_PIXEL; - - //left - if (prod <= 0 && prod - px > 0) { - f2 = {0, SW_UDIV(-prod, -dx_r)}; - prod -= py; - rw.cover += (f2.y - f1.y); - rw.area += (f2.y - f1.y) * (f1.x + f2.x); - f1 = {ONE_PIXEL, f2.y}; - --e1.x; - //up - } else if (prod - px <= 0 && prod - px + py > 0) { - prod -= px; - f2 = {SW_UDIV(-prod, dy_r), ONE_PIXEL}; - rw.cover += (f2.y - f1.y); - rw.area += (f2.y - f1.y) * (f1.x + f2.x); - f1 = {f2.x, 0}; - ++e1.y; - //right - } else if (prod - px + py <= 0 && prod + py >= 0) { - prod += py; - f2 = {ONE_PIXEL, SW_UDIV(prod, dx_r)}; - rw.cover += (f2.y - f1.y); - rw.area += (f2.y - f1.y) * (f1.x + f2.x); - f1 = {0, f2.y}; - ++e1.x; - //down - } else { - f2 = {SW_UDIV(prod, -dy_r), 0}; - prod += px; - rw.cover += (f2.y - f1.y); - rw.area += (f2.y - f1.y) * (f1.x + f2.x); - f1 = {f2.x, ONE_PIXEL}; - --e1.y; - } + auto f1 = line[1] - SUBPIXELS(e1); + SwPoint f2; + //inside one cell + if (e1 == e2) { + ; + //any horizontal line + } else if (diff.y == 0) { + e1.x = e2.x; _setCell(rw, e1); + } else if (diff.x == 0) { + //vertical line up + if (diff.y > 0) { + do { + f2.y = ONE_PIXEL; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * f1.x * 2; + f1.y = 0; + ++e1.y; + _setCell(rw, e1); + } while(e1.y != e2.y); + //vertical line down + } else { + do { + f2.y = 0; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * f1.x * 2; + f1.y = ONE_PIXEL; + --e1.y; + _setCell(rw, e1); + } while(e1.y != e2.y); + } + //any other line + } else { + Area prod = diff.x * f1.y - diff.y * f1.x; - } while(e1 != e2); + /* These macros speed up repetitive divisions by replacing them + with multiplications and right shifts. */ + auto dx_r = static_cast(ULONG_MAX >> PIXEL_BITS) / (diff.x); + auto dy_r = static_cast(ULONG_MAX >> PIXEL_BITS) / (diff.y); + + /* The fundamental value `prod' determines which side and the */ + /* exact coordinate where the line exits current cell. It is */ + /* also easily updated when moving from one cell to the next. */ + do { + auto px = diff.x * ONE_PIXEL; + auto py = diff.y * ONE_PIXEL; + + //left + if (prod <= 0 && prod - px > 0) { + f2 = {0, SW_UDIV(-prod, -dx_r)}; + prod -= py; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * (f1.x + f2.x); + f1 = {ONE_PIXEL, f2.y}; + --e1.x; + //up + } else if (prod - px <= 0 && prod - px + py > 0) { + prod -= px; + f2 = {SW_UDIV(-prod, dy_r), ONE_PIXEL}; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * (f1.x + f2.x); + f1 = {f2.x, 0}; + ++e1.y; + //right + } else if (prod - px + py <= 0 && prod + py >= 0) { + prod += py; + f2 = {ONE_PIXEL, SW_UDIV(prod, dx_r)}; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * (f1.x + f2.x); + f1 = {0, f2.y}; + ++e1.x; + //down + } else { + f2 = {SW_UDIV(prod, -dy_r), 0}; + prod += px; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * (f1.x + f2.x); + f1 = {f2.x, ONE_PIXEL}; + --e1.y; + } + + _setCell(rw, e1); + + } while(e1 != e2); + } + + f2 = {line[0].x - SUBPIXELS(e2.x), line[0].y - SUBPIXELS(e2.y)}; + rw.cover += (f2.y - f1.y); + rw.area += (f2.y - f1.y) * (f1.x + f2.x); + rw.pos = line[0]; + + if (line-- == rw.lineStack) return; } - - f2 = {to.x - SUBPIXELS(e2.x), to.y - SUBPIXELS(e2.y)}; - rw.cover += (f2.y - f1.y); - rw.area += (f2.y - f1.y) * (f1.x + f2.x); - rw.pos = to; } @@ -722,31 +713,27 @@ static void _decomposeOutline(RleWorker& rw) auto start = UPSCALE(outline->pts[first]); auto pt = outline->pts.data + first; auto types = outline->types.data + first; + ++types; _moveTo(rw, UPSCALE(outline->pts[first])); while (pt < limit) { - ++pt; - ++types; - //emit a single line_to if (types[0] == SW_CURVE_TYPE_POINT) { + ++pt; + ++types; _lineTo(rw, UPSCALE(*pt)); //types cubic } else { - pt += 2; - types += 2; - - if (pt <= limit) { - _cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), UPSCALE(pt[0])); - continue; - } - _cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), start); - goto close; + pt += 3; + types += 3; + if (pt <= limit) _cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), UPSCALE(pt[0])); + else if (pt - 1 == limit) _cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), start); + else goto close; } } - _lineTo(rw, start); close: + _lineTo(rw, start); first = last + 1; } } @@ -763,7 +750,7 @@ static int _genRle(RleWorker& rw) } -static SwSpan* _intersectSpansRegion(const SwRleData *clip, const SwRleData *target, SwSpan *outSpans, uint32_t outSpansCnt) +static SwSpan* _intersectSpansRegion(const SwRle *clip, const SwRle *target, SwSpan *outSpans, uint32_t outSpansCnt) { auto out = outSpans; auto spans = target->spans; @@ -772,7 +759,7 @@ static SwSpan* _intersectSpansRegion(const SwRleData *clip, const SwRleData *tar auto clipEnd = clip->spans + clip->size; while (spans < end && clipSpans < clipEnd) { - //align y coordinates. + //align y-coordinates. if (clipSpans->y > spans->y) { ++spans; continue; @@ -782,7 +769,7 @@ static SwSpan* _intersectSpansRegion(const SwRleData *clip, const SwRleData *tar continue; } - //Try clipping with all clip spans which have a same y coordinate. + //Try clipping with all clip spans which have a same y-coordinate. auto temp = clipSpans; while(temp < clipEnd && outSpansCnt > 0 && temp->y == clipSpans->y) { auto sx1 = spans->x; @@ -815,7 +802,7 @@ static SwSpan* _intersectSpansRegion(const SwRleData *clip, const SwRleData *tar } -static SwSpan* _intersectSpansRect(const SwBBox *bbox, const SwRleData *targetRle, SwSpan *outSpans, uint32_t outSpansCnt) +static SwSpan* _intersectSpansRect(const SwBBox *bbox, const SwRle *targetRle, SwSpan *outSpans, uint32_t outSpansCnt) { auto out = outSpans; auto spans = targetRle->spans; @@ -854,49 +841,9 @@ static SwSpan* _intersectSpansRect(const SwBBox *bbox, const SwRleData *targetRl } -static SwSpan* _mergeSpansRegion(const SwRleData *clip1, const SwRleData *clip2, SwSpan *outSpans) +void _replaceClipSpan(SwRle *rle, SwSpan* clippedSpans, uint32_t size) { - auto out = outSpans; - auto spans1 = clip1->spans; - auto end1 = clip1->spans + clip1->size; - auto spans2 = clip2->spans; - auto end2 = clip2->spans + clip2->size; - - //list two spans up in y order - //TODO: Remove duplicated regions? - while (spans1 < end1 && spans2 < end2) { - while (spans1 < end1 && spans1->y <= spans2->y) { - *out = *spans1; - ++spans1; - ++out; - } - if (spans1 >= end1) break; - while (spans2 < end2 && spans2->y <= spans1->y) { - *out = *spans2; - ++spans2; - ++out; - } - } - - //Leftovers - while (spans1 < end1) { - *out = *spans1; - ++spans1; - ++out; - } - while (spans2 < end2) { - *out = *spans2; - ++spans2; - ++out; - } - - return out; -} - - -void _replaceClipSpan(SwRleData *rle, SwSpan* clippedSpans, uint32_t size) -{ - free(rle->spans); + lv_free(rle->spans); rle->spans = clippedSpans; rle->size = rle->alloc = size; } @@ -906,7 +853,7 @@ void _replaceClipSpan(SwRleData *rle, SwSpan* clippedSpans, uint32_t size) /* External Class Implementation */ /************************************************************************/ -SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias) +SwRle* rleRender(SwRle* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias) { constexpr auto RENDER_POOL_SIZE = 16384L; constexpr auto BAND_SIZE = 40; @@ -929,13 +876,15 @@ SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& ren rw.cellMax = renderRegion.max; rw.cellXCnt = rw.cellMax.x - rw.cellMin.x; rw.cellYCnt = rw.cellMax.y - rw.cellMin.y; - rw.ySpan = 0; rw.outline = const_cast(outline); - rw.bandSize = rw.bufferSize / (sizeof(Cell) * 8); //bandSize: 64 + rw.bandSize = rw.bufferSize / (sizeof(Cell) * 2); //bandSize: 256 rw.bandShoot = 0; rw.antiAlias = antiAlias; - if (!rle) rw.rle = reinterpret_cast(calloc(1, sizeof(SwRleData))); + if (!rle) { + rw.rle = reinterpret_cast(lv_zalloc(sizeof(SwRle))); + LV_ASSERT_MALLOC(rw.rle); + } else rw.rle = rle; //Generate RLE @@ -969,10 +918,7 @@ SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& ren if (cellMod > 0) cellStart += sizeof(Cell) - cellMod; - auto cellEnd = rw.bufferSize; - cellEnd -= cellEnd % sizeof(Cell); - - auto cellsMax = reinterpret_cast((char*)rw.buffer + cellEnd); + auto cellsMax = reinterpret_cast((char*)rw.buffer + rw.bufferSize); rw.cells = reinterpret_cast((char*)rw.buffer + cellStart); if (rw.cells >= cellsMax) goto reduce_bands; @@ -1024,19 +970,20 @@ SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& ren return rw.rle; error: - free(rw.rle); - rw.rle = nullptr; + lv_free(rw.rle); return nullptr; } -SwRleData* rleRender(const SwBBox* bbox) +SwRle* rleRender(const SwBBox* bbox) { auto width = static_cast(bbox->max.x - bbox->min.x); auto height = static_cast(bbox->max.y - bbox->min.y); - auto rle = static_cast(malloc(sizeof(SwRleData))); - rle->spans = static_cast(malloc(sizeof(SwSpan) * height)); + auto rle = static_cast(lv_malloc(sizeof(SwRle))); + LV_ASSERT_MALLOC(rle); + rle->spans = static_cast(lv_malloc(sizeof(SwSpan) * height)); + LV_ASSERT_MALLOC(rle->spans); rle->size = height; rle->alloc = height; @@ -1052,82 +999,45 @@ SwRleData* rleRender(const SwBBox* bbox) } -void rleReset(SwRleData* rle) +void rleReset(SwRle* rle) { if (!rle) return; rle->size = 0; } -void rleFree(SwRleData* rle) +void rleFree(SwRle* rle) { if (!rle) return; - if (rle->spans) free(rle->spans); - free(rle); + if (rle->spans) lv_free(rle->spans); + lv_free(rle); } -void rleMerge(SwRleData* rle, SwRleData* clip1, SwRleData* clip2) -{ - if (!rle || (!clip1 && !clip2)) return; - if (clip1 && clip1->size == 0 && clip2 && clip2->size == 0) return; - - TVGLOG("SW_ENGINE", "Unifying Rle!"); - - //clip1 is empty, just copy clip2 - if (!clip1 || clip1->size == 0) { - if (clip2) { - auto spans = static_cast(malloc(sizeof(SwSpan) * (clip2->size))); - memcpy(spans, clip2->spans, clip2->size); - _replaceClipSpan(rle, spans, clip2->size); - } else { - _replaceClipSpan(rle, nullptr, 0); - } - return; - } - - //clip2 is empty, just copy clip1 - if (!clip2 || clip2->size == 0) { - if (clip1) { - auto spans = static_cast(malloc(sizeof(SwSpan) * (clip1->size))); - memcpy(spans, clip1->spans, clip1->size); - _replaceClipSpan(rle, spans, clip1->size); - } else { - _replaceClipSpan(rle, nullptr, 0); - } - return; - } - - auto spanCnt = clip1->size + clip2->size; - auto spans = static_cast(malloc(sizeof(SwSpan) * spanCnt)); - auto spansEnd = _mergeSpansRegion(clip1, clip2, spans); - - _replaceClipSpan(rle, spans, spansEnd - spans); -} - - -void rleClipPath(SwRleData *rle, const SwRleData *clip) +void rleClip(SwRle *rle, const SwRle *clip) { if (rle->size == 0 || clip->size == 0) return; auto spanCnt = rle->size > clip->size ? rle->size : clip->size; - auto spans = static_cast(malloc(sizeof(SwSpan) * (spanCnt))); + auto spans = static_cast(lv_malloc(sizeof(SwSpan) * (spanCnt))); + LV_ASSERT_MALLOC(spans); auto spansEnd = _intersectSpansRegion(clip, rle, spans, spanCnt); _replaceClipSpan(rle, spans, spansEnd - spans); - TVGLOG("SW_ENGINE", "Using ClipPath!"); + TVGLOG("SW_ENGINE", "Using Path Clipping!"); } -void rleClipRect(SwRleData *rle, const SwBBox* clip) +void rleClip(SwRle *rle, const SwBBox* clip) { if (rle->size == 0) return; - auto spans = static_cast(malloc(sizeof(SwSpan) * (rle->size))); + auto spans = static_cast(lv_malloc(sizeof(SwSpan) * (rle->size))); + LV_ASSERT_MALLOC(spans); auto spansEnd = _intersectSpansRect(clip, rle, spans, rle->size); _replaceClipSpan(rle, spans, spansEnd - spans); - TVGLOG("SW_ENGINE", "Using ClipRect!"); + TVGLOG("SW_ENGINE", "Using Box Clipping!"); } #endif /* LV_USE_THORVG_INTERNAL */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwShape.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwShape.cpp index e2652c1ea..ca5805b31 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwShape.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwShape.cpp @@ -25,7 +25,6 @@ #include "tvgSwCommon.h" #include "tvgMath.h" -#include "tvgLines.h" /************************************************************************/ /* Internal Class Implementation */ @@ -52,7 +51,7 @@ static bool _outlineEnd(SwOutline& outline) } -static bool _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix* transform, bool closed = 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); @@ -63,20 +62,20 @@ static bool _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix* tr } -static void _outlineLineTo(SwOutline& outline, const Point* to, const Matrix* transform) +static void _outlineLineTo(SwOutline& outline, const Point* to, const Matrix& transform) { outline.pts.push(mathTransform(to, transform)); outline.types.push(SW_CURVE_TYPE_POINT); } -static void _outlineCubicTo(SwOutline& outline, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix* transform) +static void _outlineCubicTo(SwOutline& outline, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix& transform) { outline.pts.push(mathTransform(ctrl1, transform)); 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); @@ -102,15 +101,15 @@ static bool _outlineClose(SwOutline& outline) } -static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* transform) +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 = cur.length(); - if (mathZero(len)) { + if (tvg::zero(len)) { _outlineMoveTo(*dash.outline, &dash.ptCur, transform); //draw the current line fully - } else if (len < dash.curLen) { + } else if (len <= dash.curLen) { dash.curLen -= len; if (!dash.curOpGap) { if (dash.move) { @@ -125,7 +124,7 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans Line left, right; if (dash.curLen > 0) { len -= dash.curLen; - lineSplitAt(cur, dash.curLen, left, right); + cur.split(dash.curLen, left, right); if (!dash.curOpGap) { if (dash.move || dash.pattern[dash.curIdx] - dash.curLen < FLOAT_EPSILON) { _outlineMoveTo(*dash.outline, &left.pt1, transform); @@ -163,15 +162,15 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans } -static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix* transform) +static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix& transform) { Bezier cur = {dash.ptCur, *ctrl1, *ctrl2, *to}; - auto len = bezLength(cur); + auto len = cur.length(); //draw the current line fully - if (mathZero(len)) { + if (tvg::zero(len)) { _outlineMoveTo(*dash.outline, &dash.ptCur, transform); - } else if (len < dash.curLen) { + } else if (len <= dash.curLen) { dash.curLen -= len; if (!dash.curOpGap) { if (dash.move) { @@ -186,7 +185,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct Bezier left, right; if (dash.curLen > 0) { len -= dash.curLen; - bezSplitAt(cur, dash.curLen, left, right); + cur.split(dash.curLen, left, right); if (!dash.curOpGap) { if (dash.move || dash.pattern[dash.curIdx] - dash.curLen < FLOAT_EPSILON) { _outlineMoveTo(*dash.outline, &left.start, transform); @@ -213,7 +212,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct } _outlineCubicTo(*dash.outline, &cur.ctrl1, &cur.ctrl2, &cur.end, transform); } - if (dash.curLen < 1 && TO_SWCOORD(len) > 1) { + if (dash.curLen < 0.1f && TO_SWCOORD(len) > 1) { //move to next dash dash.curIdx = (dash.curIdx + 1) % dash.cnt; dash.curLen = dash.pattern[dash.curIdx]; @@ -224,7 +223,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct } -static void _dashClose(SwDashStroke& dash, const Matrix* transform) +static void _dashClose(SwDashStroke& dash, const Matrix& transform) { _dashLineTo(dash, &dash.ptStart, transform); } @@ -248,7 +247,86 @@ static void _dashMoveTo(SwDashStroke& dash, uint32_t offIdx, float offset, const } -static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* transform, float length, SwMpool* mpool, unsigned tid) +static void _trimPattern(SwDashStroke* dash, const RenderShape* rshape, float length, float trimBegin, float trimEnd) +{ + auto begin = length * trimBegin; + auto end = length * trimEnd; + + //default + if (end > begin) { + if (begin > 0.0f) dash->cnt = 4; + else dash->cnt = 2; + //looping + } else dash->cnt = 3; + + if (dash->cnt == 2) { + dash->pattern[0] = end - begin; + dash->pattern[1] = length - (end - begin); + } else if (dash->cnt == 3) { + dash->pattern[0] = end; + dash->pattern[1] = (begin - end); + dash->pattern[2] = length - begin; + } else { + 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; + } +} + + +static float _outlineLength(const RenderShape* rshape, uint32_t shiftPts, uint32_t shiftCmds, bool subpath) +{ + const PathCommand* cmds = rshape->path.cmds.data + shiftCmds; + auto cmdCnt = rshape->path.cmds.count - shiftCmds; + const Point* pts = rshape->path.pts.data + shiftPts; + auto ptsCnt = rshape->path.pts.count - shiftPts; + + //No actual shape data + if (cmdCnt <= 0 || ptsCnt <= 0) return 0.0f; + + const Point* close = nullptr; + auto len = 0.0f; + + //must begin with moveTo + if (cmds[0] == PathCommand::MoveTo) { + close = pts; + cmds++; + pts++; + cmdCnt--; + } + + while (cmdCnt-- > 0) { + switch (*cmds) { + case PathCommand::Close: { + len += length(pts - 1, close); + if (subpath) return len; + break; + } + case PathCommand::MoveTo: { + if (subpath) return len; + close = pts; + ++pts; + break; + } + case PathCommand::LineTo: { + len += length(pts - 1, pts); + ++pts; + break; + } + case PathCommand::CubicTo: { + len += Bezier{*(pts - 1), *pts, *(pts + 1), *(pts + 2)}.length(); + pts += 3; + break; + } + } + ++cmds; + } + return len; +} + + +static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix& transform, bool trimmed, SwMpool* mpool, unsigned tid) { const PathCommand* cmds = rshape->path.cmds.data; auto cmdCnt = rshape->path.cmds.count; @@ -258,52 +336,31 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans //No actual shape data if (cmdCnt == 0 || ptsCnt == 0) return nullptr; + auto startPts = pts; + auto startCmds = cmds; + SwDashStroke dash; auto offset = 0.0f; - auto trimmed = false; - dash.cnt = rshape->strokeDash((const float**)&dash.pattern, &offset); + auto simultaneous = rshape->stroke->trim.simultaneous; + float trimBegin = 0.0f, trimEnd = 1.0f; + if (trimmed) rshape->stroke->strokeTrim(trimBegin, trimEnd); - //dash by trimming. - if (length > 0.0f && dash.cnt == 0) { - auto begin = length * rshape->stroke->trim.begin; - auto end = length * rshape->stroke->trim.end; - - //TODO: mix trimming + dash style - - //default - if (end > begin) { - if (begin > 0.0f) dash.cnt += 4; - else dash.cnt += 2; - //looping - } else dash.cnt += 3; - - dash.pattern = (float*)malloc(sizeof(float) * dash.cnt); - - if (dash.cnt == 2) { - dash.pattern[0] = end - begin; - dash.pattern[1] = length - (end - begin); - } else if (dash.cnt == 3) { - dash.pattern[0] = end; - dash.pattern[1] = (begin - end); - dash.pattern[2] = length - begin; - } else { - 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; + if (dash.cnt == 0) { + if (trimmed) { + dash.pattern = (float*)lv_malloc(sizeof(float) * 4); + LV_ASSERT_MALLOC(dash.pattern); } - - trimmed = true; - //just a dash style. + else return nullptr; } else { - if (dash.cnt == 0) return nullptr; + //TODO: handle dash + trim - for now trimming ignoring is forced + trimmed = false; } - //offset? + //offset auto patternLength = 0.0f; uint32_t offIdx = 0; - if (!mathZero(offset)) { + if (!tvg::zero(offset)) { for (size_t i = 0; i < dash.cnt; ++i) patternLength += dash.pattern[i]; bool isOdd = dash.cnt % 2; if (isOdd) patternLength *= 2; @@ -322,6 +379,7 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans //must begin with moveTo if (cmds[0] == PathCommand::MoveTo) { + if (trimmed) _trimPattern(&dash, rshape, _outlineLength(rshape, 0, 0, simultaneous), trimBegin, trimEnd); _dashMoveTo(dash, offIdx, offset, pts); cmds++; pts++; @@ -334,8 +392,12 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans break; } case PathCommand::MoveTo: { - if (rshape->stroke->trim.individual) _dashMoveTo(dash, pts); - else _dashMoveTo(dash, offIdx, offset, pts); + if (trimmed) { + if (simultaneous) { + _trimPattern(&dash, rshape, _outlineLength(rshape, pts - startPts, cmds - startCmds, true), trimBegin, trimEnd); + _dashMoveTo(dash, offIdx, offset, pts); + } else _dashMoveTo(dash, pts); + } else _dashMoveTo(dash, offIdx, offset, pts); ++pts; break; } @@ -355,66 +417,17 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans _outlineEnd(*dash.outline); - if (trimmed) free(dash.pattern); + if (trimmed) lv_free(dash.pattern); return dash.outline; } -static float _outlineLength(const RenderShape* rshape) -{ - const PathCommand* cmds = rshape->path.cmds.data; - auto cmdCnt = rshape->path.cmds.count; - const Point* pts = rshape->path.pts.data; - auto ptsCnt = rshape->path.pts.count; - - //No actual shape data - if (cmdCnt == 0 || ptsCnt == 0) return 0.0f; - - 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); - //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: { - close = pts; - ++pts; - break; - } - case PathCommand::LineTo: { - length += mathLength(pts - 1, pts); - ++pts; - break; - } - case PathCommand::CubicTo: { - length += bezLength({*(pts - 1), *pts, *(pts + 1), *(pts + 2)}); - pts += 3; - break; - } - } - ++cmds; - } - if (simultaneous && slength > length) return slength; - else return length; -} - - static bool _axisAlignedRect(const SwOutline* outline) { //Fast Track: axis-aligned rectangle? if (outline->pts.count != 5) return false; + if (outline->types[2] == SW_CURVE_TYPE_CUBIC) return false; auto pt1 = outline->pts.data + 0; auto pt2 = outline->pts.data + 1; @@ -430,7 +443,7 @@ static bool _axisAlignedRect(const SwOutline* outline) } -static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix* transform, SwMpool* mpool, unsigned tid, bool hasComposite) +static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix& transform, SwMpool* mpool, unsigned tid, bool hasComposite) { const PathCommand* cmds = rshape->path.cmds.data; auto cmdCnt = rshape->path.cmds.count; @@ -486,12 +499,11 @@ static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix* /* External Class Implementation */ /************************************************************************/ -bool shapePrepare(SwShape* shape, const RenderShape* rshape, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite) +bool shapePrepare(SwShape* shape, const RenderShape* rshape, const Matrix& transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite) { if (!_genOutline(shape, rshape, transform, mpool, tid, hasComposite)) return false; if (!mathUpdateOutlineBBox(shape->outline, clipRegion, renderRegion, shape->fastTrack)) return false; - //Keep it for Rasterization Region shape->bbox = renderRegion; //Check valid region @@ -569,9 +581,12 @@ void shapeDelStroke(SwShape* shape) } -void shapeResetStroke(SwShape* shape, const RenderShape* rshape, const Matrix* transform) +void shapeResetStroke(SwShape* shape, const RenderShape* rshape, const Matrix& transform) { - if (!shape->stroke) shape->stroke = static_cast(calloc(1, sizeof(SwStroke))); + if (!shape->stroke) { + shape->stroke = static_cast(lv_zalloc(sizeof(SwStroke))); + LV_ASSERT_MALLOC(shape->stroke); + } auto stroke = shape->stroke; if (!stroke) return; @@ -580,18 +595,17 @@ void shapeResetStroke(SwShape* shape, const RenderShape* rshape, const Matrix* t } -bool shapeGenStrokeRle(SwShape* shape, const RenderShape* rshape, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid) +bool shapeGenStrokeRle(SwShape* shape, const RenderShape* rshape, const Matrix& transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid) { SwOutline* shapeOutline = nullptr; SwOutline* strokeOutline = nullptr; auto dashStroking = false; auto ret = true; - auto length = rshape->strokeTrim() ? _outlineLength(rshape) : 0.0f; - //Dash style (+trimming) - if (rshape->stroke->dashCnt > 0 || length > 0) { - shapeOutline = _genDashOutline(rshape, transform, length, mpool, tid); + auto trimmed = rshape->strokeTrim(); + if (rshape->stroke->dashCnt > 0 || trimmed) { + shapeOutline = _genDashOutline(rshape, transform, trimmed, mpool, tid); if (!shapeOutline) return false; dashStroking = true; //Normal style @@ -624,13 +638,13 @@ clear: } -bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable) +bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix& transform, SwSurface* surface, uint8_t opacity, bool ctable) { return fillGenColorTable(shape->fill, fill, transform, surface, opacity, ctable); } -bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable) +bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix& transform, SwSurface* surface, uint8_t opacity, bool ctable) { return fillGenColorTable(shape->stroke->fill, fill, transform, surface, opacity, ctable); } @@ -639,7 +653,8 @@ bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix* tr void shapeResetFill(SwShape* shape) { if (!shape->fill) { - shape->fill = static_cast(calloc(1, sizeof(SwFill))); + shape->fill = static_cast(lv_zalloc(sizeof(SwFill))); + LV_ASSERT_MALLOC(shape->fill); if (!shape->fill) return; } fillReset(shape->fill); @@ -649,7 +664,8 @@ void shapeResetFill(SwShape* shape) void shapeResetStrokeFill(SwShape* shape) { if (!shape->stroke->fill) { - shape->stroke->fill = static_cast(calloc(1, sizeof(SwFill))); + shape->stroke->fill = static_cast(lv_zalloc(sizeof(SwFill))); + LV_ASSERT_MALLOC(shape->stroke->fill); if (!shape->stroke->fill) return; } fillReset(shape->stroke->fill); diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwStroke.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwStroke.cpp index 954250c8c..527164a1a 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwStroke.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgSwStroke.cpp @@ -61,8 +61,10 @@ static void _growBorder(SwStrokeBorder* border, uint32_t newPts) while (maxCur < maxNew) maxCur += (maxCur >> 1) + 16; //OPTIMIZE: use mempool! - border->pts = static_cast(realloc(border->pts, maxCur * sizeof(SwPoint))); - border->tags = static_cast(realloc(border->tags, maxCur * sizeof(uint8_t))); + border->pts = static_cast(lv_realloc(border->pts, maxCur * sizeof(SwPoint))); + LV_ASSERT_MALLOC(border->pts); + border->tags = static_cast(lv_realloc(border->tags, maxCur * sizeof(uint8_t))); + LV_ASSERT_MALLOC(border->tags); border->maxPts = maxCur; } @@ -241,7 +243,7 @@ static void _outside(SwStroke& stroke, int32_t side, SwFixed lineLength) } else { //this is a mitered (pointed) or beveled (truncated) corner auto rotate = SIDE_TO_ROTATE(side); - auto bevel = (stroke.join == StrokeJoin::Bevel) ? true : false; + auto bevel = stroke.join == StrokeJoin::Bevel; SwFixed phi = 0; SwFixed thcos = 0; @@ -444,13 +446,23 @@ static void _cubicTo(SwStroke& stroke, const SwPoint& ctrl1, const SwPoint& ctrl //initialize with current direction angleIn = angleOut = angleMid = stroke.angleIn; - if (arc < limit && !mathSmallCubic(arc, angleIn, angleMid, angleOut)) { + auto valid = mathCubicAngle(arc, angleIn, angleMid, angleOut); + + //valid size + if (valid > 0 && arc < limit) { if (stroke.firstPt) stroke.angleIn = angleIn; mathSplitCubic(arc); arc += 3; continue; } + //ignoreable size + if (valid < 0 && arc == bezStack) { + stroke.center = to; + return; + } + + //small size if (firstArc) { firstArc = false; //process corner if necessary @@ -796,30 +808,25 @@ void strokeFree(SwStroke* stroke) if (!stroke) return; //free borders - if (stroke->borders[0].pts) free(stroke->borders[0].pts); - if (stroke->borders[0].tags) free(stroke->borders[0].tags); - if (stroke->borders[1].pts) free(stroke->borders[1].pts); - if (stroke->borders[1].tags) free(stroke->borders[1].tags); + if (stroke->borders[0].pts) lv_free(stroke->borders[0].pts); + if (stroke->borders[0].tags) lv_free(stroke->borders[0].tags); + if (stroke->borders[1].pts) lv_free(stroke->borders[1].pts); + if (stroke->borders[1].tags) lv_free(stroke->borders[1].tags); fillFree(stroke->fill); stroke->fill = nullptr; - free(stroke); + lv_free(stroke); } -void strokeReset(SwStroke* stroke, const RenderShape* rshape, const Matrix* transform) +void strokeReset(SwStroke* stroke, const RenderShape* rshape, const Matrix& transform) { - if (transform) { - stroke->sx = sqrtf(powf(transform->e11, 2.0f) + powf(transform->e21, 2.0f)); - stroke->sy = sqrtf(powf(transform->e12, 2.0f) + powf(transform->e22, 2.0f)); - } else { - stroke->sx = stroke->sy = 1.0f; - } - + stroke->sx = sqrtf(powf(transform.e11, 2.0f) + powf(transform.e21, 2.0f)); + stroke->sy = sqrtf(powf(transform.e12, 2.0f) + powf(transform.e22, 2.0f)); stroke->width = HALF_STROKE(rshape->strokeWidth()); stroke->cap = rshape->strokeCap(); - stroke->miterlimit = static_cast(rshape->strokeMiterlimit()) << 16; + stroke->miterlimit = static_cast(rshape->strokeMiterlimit() * 65536.0f); //Save line join: it can be temporarily changed when stroking curves... stroke->joinSaved = stroke->join = rshape->strokeJoin(); @@ -853,31 +860,25 @@ bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline) //A contour cannot start with a cubic control point if (type == SW_CURVE_TYPE_CUBIC) return false; + ++types; auto closed = outline.closed.data ? outline.closed.data[i]: false; _beginSubPath(*stroke, start, closed); while (pt < limit) { - ++pt; - ++types; - //emit a single line_to if (types[0] == SW_CURVE_TYPE_POINT) { + ++pt; + ++types; _lineTo(*stroke, *pt); //types cubic } else { - if (pt + 1 > limit || types[1] != SW_CURVE_TYPE_CUBIC) return false; - - pt += 2; - types += 2; - - if (pt <= limit) { - _cubicTo(*stroke, pt[-2], pt[-1], pt[0]); - continue; - } - _cubicTo(*stroke, pt[-2], pt[-1], start); - goto close; + pt += 3; + types += 3; + if (pt <= limit) _cubicTo(*stroke, pt[-2], pt[-1], pt[0]); + else if (pt - 1 == limit) _cubicTo(*stroke, pt[-2], pt[-1], start); + else goto close; } } close: diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgTaskScheduler.h b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgTaskScheduler.h index af1334b79..f4caa1c32 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgTaskScheduler.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgTaskScheduler.h @@ -28,10 +28,18 @@ #include #include +#include #include "tvgCommon.h" #include "tvgInlist.h" +using std::mutex; +using std::condition_variable; +using std::unique_lock; +using std::thread; +using std::atomic; +using std::try_to_lock; + namespace tvg { #ifdef THORVG_THREAD_SUPPORT @@ -112,6 +120,7 @@ struct TaskScheduler } //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 index 6cb2b4f74..8888a1bd6 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgText.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgText.cpp @@ -38,9 +38,8 @@ /************************************************************************/ -Text::Text() : pImpl(new Impl) +Text::Text() : pImpl(new Impl(this)) { - Paint::pImpl->id = TVG_CLASS_ID_TEXT; } @@ -74,6 +73,21 @@ Result Text::load(const std::string& path) noexcept } +Result Text::load(const char* name, const char* data, uint32_t size, const string& mimeType, bool copy) noexcept +{ + if (!name || (size == 0 && data)) return Result::InvalidArguments; + + //unload font + if (!data) { + if (LoaderMgr::retrieve(name)) return Result::Success; + return Result::InsufficientCondition; + } + + if (!LoaderMgr::loader(name, data, size, mimeType, copy)) return Result::NonSupport; + return Result::Success; +} + + Result Text::unload(const std::string& path) noexcept { if (LoaderMgr::retrieve(path)) return Result::Success; @@ -83,20 +97,13 @@ Result Text::unload(const std::string& path) noexcept 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); + return pImpl->shape->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); + return pImpl->shape->fill(std::move(f)); } @@ -106,9 +113,9 @@ unique_ptr Text::gen() noexcept } -uint32_t Text::identifier() noexcept +Type Text::type() const noexcept { - return TVG_CLASS_ID_TEXT; + return Type::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 index 89cef1879..42847360d 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgText.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgText.h @@ -29,43 +29,33 @@ #include #include "tvgShape.h" #include "tvgFill.h" - -#ifdef THORVG_TTF_LOADER_SUPPORT - #include "tvgTtfLoader.h" -#else - #include "tvgLoader.h" -#endif +#include "tvgLoader.h" struct Text::Impl { FontLoader* loader = nullptr; - Shape* paint = nullptr; + Text* paint; + Shape* shape; char* utf8 = nullptr; float fontSize; bool italic = false; bool changed = false; + Impl(Text* p) : paint(p), shape(Shape::gen().release()) + { + } + ~Impl() { - free(utf8); + lv_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)); + delete(shape); } Result text(const char* utf8) { - free(this->utf8); - if (utf8) this->utf8 = strdup(utf8); + lv_free(this->utf8); + if (utf8) this->utf8 = lv_strdup(utf8); else this->utf8 = nullptr; changed = true; @@ -77,6 +67,11 @@ struct Text::Impl auto loader = LoaderMgr::loader(name); if (!loader) return Result::InsufficientCondition; + if (style && strstr(style, "italic")) italic = true; + else italic = false; + + fontSize = size; + //Same resource has been loaded. if (this->loader == loader) { this->loader->sharing--; //make it sure the reference counting. @@ -86,52 +81,44 @@ struct Text::Impl } 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}; + return P(shape)->bounds(renderer); } bool render(RenderMethod* renderer) { - if (paint) return PP(paint)->render(renderer); - return false; + if (!loader) return true; + renderer->blend(PP(paint)->blendMethod); + return PP(shape)->render(renderer); } bool load() { if (!loader) return false; + loader->request(shape, utf8); //reload if (changed) { - loader->request(paint, utf8, italic); loader->read(); changed = false; } - if (paint) { - loader->resize(paint, fontSize, fontSize); - return true; - } - return false; + return loader->transform(shape, fontSize, italic); } - RenderData update(RenderMethod* renderer, const RenderTransform* transform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) + RenderData update(RenderMethod* renderer, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, TVG_UNUSED 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 fill = P(shape)->rs.fill; + if (fill && P(shape)->flag & RenderUpdateFlag::Gradient) { auto scale = 1.0f / loader->scale; - if (fill->identifier() == TVG_CLASS_ID_LINEAR) { + if (fill->type() == Type::LinearGradient) { P(static_cast(fill))->x1 *= scale; P(static_cast(fill))->y1 *= scale; P(static_cast(fill))->x2 *= scale; @@ -145,34 +132,36 @@ struct Text::Impl P(static_cast(fill))->fr *= scale; } } - return PP(paint)->update(renderer, transform, clips, opacity, pFlag, clipper); + return PP(shape)->update(renderer, transform, clips, opacity, pFlag, false); } 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); + if (!load()) return false; + PP(shape)->bounds(x, y, w, h, true, true, false); return true; } - Paint* duplicate() + Paint* duplicate(Paint* ret) { + if (ret) TVGERR("RENDERER", "TODO: duplicate()"); + load(); - auto ret = Text::gen().release(); - auto dup = ret->pImpl; - if (paint) dup->paint = static_cast(paint->duplicate()); + auto text = Text::gen().release(); + auto dup = text->pImpl; + P(shape)->duplicate(dup->shape); if (loader) { dup->loader = loader; ++dup->loader->sharing; } - dup->utf8 = strdup(utf8); + dup->utf8 = lv_strdup(utf8); dup->italic = italic; dup->fontSize = fontSize; - return ret; + return text; } Iterator* iterator() diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgWgCanvas.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgWgCanvas.cpp index 3bdaec9e4..591ec0b18 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgWgCanvas.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgWgCanvas.cpp @@ -43,40 +43,49 @@ struct WgCanvas::Impl /************************************************************************/ #ifdef THORVG_WG_RASTER_SUPPORT -WgCanvas::WgCanvas() : Canvas(WgRenderer::gen()), pImpl(new Impl) +WgCanvas::WgCanvas() : Canvas(WgRenderer::gen()), pImpl(nullptr) #else WgCanvas::WgCanvas() : Canvas(nullptr), pImpl(nullptr) #endif { } + WgCanvas::~WgCanvas() { - delete pImpl; +#ifdef THORVG_WG_RASTER_SUPPORT + auto renderer = static_cast(Canvas::pImpl->renderer); + renderer->target(nullptr, 0, 0); +#endif } -Result WgCanvas::target(void* window, uint32_t w, uint32_t h) noexcept + +Result WgCanvas::target(void* instance, void* surface, uint32_t w, uint32_t h, void* device) noexcept { #ifdef THORVG_WG_RASTER_SUPPORT - if (!window) return Result::InvalidArguments; - if ((w == 0) || (h == 0)) return Result::InvalidArguments; + if (Canvas::pImpl->status != Status::Damaged && Canvas::pImpl->status != Status::Synced) { + return Result::InsufficientCondition; + } + + if (!instance || !surface || (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; + if (!renderer->target((WGPUInstance)instance, (WGPUSurface)surface, w, h, (WGPUDevice)device)) 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(); + Canvas::pImpl->status = Status::Damaged; return Result::Success; #endif return Result::NonSupport; } + unique_ptr WgCanvas::gen() noexcept { #ifdef THORVG_WG_RASTER_SUPPORT diff --git a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgXmlParser.cpp b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgXmlParser.cpp index ffb9b5df4..89c359d37 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgXmlParser.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/thorvg/tvgXmlParser.cpp @@ -301,7 +301,8 @@ bool isIgnoreUnsupportedLogElements(TVG_UNUSED const char* tagName) bool simpleXmlParseAttributes(const char* buf, unsigned bufLength, simpleXMLAttributeCb func, const void* data) { const char *itr = buf, *itrEnd = buf + bufLength; - char* tmpBuf = (char*)malloc(bufLength + 1); + char* tmpBuf = (char*)lv_malloc(bufLength + 1); + LV_ASSERT_MALLOC(tmpBuf); if (!buf || !func || !tmpBuf) goto error; @@ -366,11 +367,11 @@ bool simpleXmlParseAttributes(const char* buf, unsigned bufLength, simpleXMLAttr } success: - free(tmpBuf); + lv_free(tmpBuf); return true; error: - free(tmpBuf); + lv_free(tmpBuf); return false; } @@ -495,13 +496,13 @@ bool simpleXmlParseW3CAttribute(const char* buf, unsigned bufLength, simpleXMLAt key[0] = '\0'; val[0] = '\0'; - if (next == nullptr && sep != nullptr) { + if (sep != nullptr && next == nullptr) { memcpy(key, buf, sep - buf); key[sep - buf] = '\0'; memcpy(val, sep + 1, end - sep - 1); val[end - sep - 1] = '\0'; - } else if (sep < next && sep != nullptr) { + } else if (sep != nullptr && sep < next) { memcpy(key, buf, sep - buf); key[sep - buf] = '\0'; @@ -525,8 +526,9 @@ bool simpleXmlParseW3CAttribute(const char* buf, unsigned bufLength, simpleXMLAt } } + if (!next) break; buf = next + 1; - } while (next != nullptr); + } while (true); return true; } @@ -563,7 +565,7 @@ const char* simpleXmlParseCSSAttribute(const char* buf, unsigned bufLength, char if (*p == '.') break; } - if (p == itr) *tag = strdup("all"); + if (p == itr) *tag = lv_strdup("all"); else *tag = strDuplicate(itr, p - itr); if (p == itrEnd) *name = nullptr; diff --git a/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/LICENSE.txt b/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/LICENSE.txt new file mode 100644 index 000000000..01239c16e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/tiny_ttf/LICENSE.txt @@ -0,0 +1,63 @@ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +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. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +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 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. + + +============================================================================== + + +MIT License + +Copyright (c) 2022 honey the codewitch + +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. 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 899432707..434584ea9 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 @@ -77,7 +77,7 @@ typedef struct _tiny_ttf_glyph_cache_data_t { lv_font_glyph_dsc_t glyph_dsc; } tiny_ttf_glyph_cache_data_t; -typedef struct lv_tiny_ttf_cache_data_t { +typedef struct _lv_tiny_ttf_cache_data_t { uint32_t glyph_index; uint32_t size; lv_draw_buf_t * draw_buf; @@ -104,10 +104,23 @@ static lv_cache_compare_res_t tiny_ttf_draw_data_cache_compare_cb(const tiny_ttf const tiny_ttf_cache_data_t * rhs); static void lv_tiny_ttf_cache_create(ttf_font_desc_t * dsc); + +static lv_font_t * tiny_ttf_font_create_cb(const lv_font_info_t * info, const void * src); +static void tiny_ttf_font_delete_cb(lv_font_t * font); +static void * tiny_ttf_font_dup_src_cb(const void * src); +static void tiny_ttf_font_free_src_cb(void * src); + /********************** * GLOBAL VARIABLES **********************/ +const lv_font_class_t lv_tiny_ttf_font_class = { + .create_cb = tiny_ttf_font_create_cb, + .delete_cb = tiny_ttf_font_delete_cb, + .dup_src_cb = tiny_ttf_font_dup_src_cb, + .free_src_cb = tiny_ttf_font_free_src_cb, +}; + /********************** * STATIC VARIABLES **********************/ @@ -530,6 +543,7 @@ static bool tiny_ttf_draw_data_cache_create_cb(tiny_ttf_cache_data_t * node, voi uint32_t stride = draw_buf->header.stride; stbtt_MakeGlyphBitmap(info, draw_buf->data, w, h, stride, dsc->scale, dsc->scale, g1); + lv_draw_buf_flush_cache(draw_buf, NULL); node->draw_buf = draw_buf; return true; } @@ -555,4 +569,59 @@ static lv_cache_compare_res_t tiny_ttf_draw_data_cache_compare_cb(const tiny_ttf return 0; } +static lv_font_t * tiny_ttf_font_create_cb(const lv_font_info_t * info, const void * src) +{ + const lv_tiny_ttf_font_src_t * font_src = src; + + if(font_src->path) { +#if LV_TINY_TTF_FILE_SUPPORT + if(font_src->cache_size) { + return lv_tiny_ttf_create_file_ex(font_src->path, info->size, info->kerning, font_src->cache_size); + } + + return lv_tiny_ttf_create_file(font_src->path, info->size); +#else + LV_LOG_WARN("LV_TINY_TTF_FILE_SUPPORT not enabled"); + return NULL; +#endif + } + + if(font_src->cache_size) { + return lv_tiny_ttf_create_data_ex(font_src->data, font_src->data_size, info->size, info->kerning, font_src->cache_size); + } + + return lv_tiny_ttf_create_data(font_src->data, font_src->data_size, info->size); +} + +static void tiny_ttf_font_delete_cb(lv_font_t * font) +{ + lv_tiny_ttf_destroy(font); +} + +static void * tiny_ttf_font_dup_src_cb(const void * src) +{ + const lv_tiny_ttf_font_src_t * font_src = src; + + lv_tiny_ttf_font_src_t * new_src = lv_malloc_zeroed(sizeof(lv_tiny_ttf_font_src_t)); + LV_ASSERT_MALLOC(new_src); + *new_src = *font_src; + + if(font_src->path) { + new_src->path = lv_strdup(font_src->path); + } + + return new_src; +} + +static void tiny_ttf_font_free_src_cb(void * src) +{ + lv_tiny_ttf_font_src_t * font_src = src; + if(font_src->path) { + lv_free((char *)font_src->path); + font_src->path = NULL; + } + + lv_free(font_src); +} + #endif 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 b6e7dc0a8..09910bca9 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 @@ -25,6 +25,15 @@ extern "C" { * TYPEDEFS **********************/ +typedef struct { + const char * path; /**< Path to the font file*/ + const void * data; /**< Pointer to the font data*/ + size_t data_size; /**< Size of the font data*/ + size_t cache_size; /**< Size of the font cache*/ +} lv_tiny_ttf_font_src_t; + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_font_class_t lv_tiny_ttf_font_class; + /********************** * GLOBAL PROTOTYPES **********************/ 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 1cd3e2abe..d2dc388be 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 @@ -2758,7 +2758,7 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo * info, i if(ttUSHORT(data, 2 + info->gpos) != 0) return 0; // Minor version 0 lookupListOffset = ttUSHORT(data, 8 + info->gpos); - lookupList = lookupListOffset; + lookupList = info->gpos + lookupListOffset; lookupCount = ttUSHORT(data, lookupList); for(i = 0; i < lookupCount; ++i) { @@ -2876,7 +2876,7 @@ STBTT_DEF int stbtt_KernTableCheck(const stbtt_fontinfo * info) if(ttUSHORT(data, 2 + info->gpos) != 0) return 0; // Minor version 0 lookupListOffset = ttUSHORT(data, 8 + info->gpos); - lookupList = lookupListOffset; + lookupList = info->gpos + lookupListOffset; lookupCount = ttUSHORT(data, lookupList); for(i = 0; i < lookupCount; ++i) { diff --git a/lib/libesp32_lvgl/lvgl/src/libs/tjpgd/LICENSE.txt b/lib/libesp32_lvgl/lvgl/src/libs/tjpgd/LICENSE.txt new file mode 100644 index 000000000..b910bf443 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/libs/tjpgd/LICENSE.txt @@ -0,0 +1,15 @@ +/*----------------------------------------------------------------------------/ +/ TJpgDec - Tiny JPEG Decompressor R0.03 (C)ChaN, 2021 +/-----------------------------------------------------------------------------/ +/ The TJpgDec is a generic JPEG decompressor module for tiny embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following terms. +/ +/ Copyright (C) 2021, ChaN, all right reserved. +/ +/ * The TJpgDec module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/-----------------------------------------------------------------------------/ 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 index 3264b9abe..162101365 100644 --- a/lib/libesp32_lvgl/lvgl/src/lv_api_map_v9_1.h +++ b/lib/libesp32_lvgl/lvgl/src/lv_api_map_v9_1.h @@ -36,15 +36,10 @@ extern "C" { **********************/ #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 @@ -78,21 +73,57 @@ extern "C" { #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_obj_get_child_by_id lv_obj_find_by_id +#define lv_obj_update_flag lv_obj_set_flag #define _lv_inv_area lv_inv_area +#define lv_chart_set_all_value lv_chart_set_all_values +#define lv_calendar_set_showed_date lv_calendar_set_month_shown +#define lv_chart_set_range lv_chart_set_axis_range +#define lv_chart_set_value_by_id lv_chart_set_series_value_by_id +#define lv_chart_get_x_array lv_chart_get_series_x_array +#define lv_chart_get_y_array lv_chart_get_series_y_array +#define lv_chart_set_ext_x_array lv_chart_set_series_ext_x_array +#define lv_chart_set_ext_y_array lv_chart_set_series_ext_y_array -/********************** - * DEPRECATED FUNCTIONS - **********************/ +#if defined(LV_FS_DEFAULT_DRIVE_LETTER) +#warning LV_FS_DEFAULT_DRIVE_LETTER is deprecated. Rename to LV_FS_DEFAULT_DRIVER_LETTER + +#if LV_FS_DEFAULT_DRIVER_LETTER == '\0' +#undef LV_FS_DEFAULT_DRIVER_LETTER +#define LV_FS_DEFAULT_DRIVER_LETTER LV_FS_DEFAULT_DRIVE_LETTER +#endif + +#endif /* defined(LV_FS_DEFAULT_DRIVE_LETTER) */ + +#define LV_LABEL_LONG_WRAP LV_LABEL_LONG_MODE_WRAP +#define LV_LABEL_LONG_DOT LV_LABEL_LONG_MODE_DOTS +#define LV_LABEL_LONG_SCROLL LV_LABEL_LONG_MODE_SCROLL +#define LV_LABEL_LONG_SCROLL_CIRCULAR LV_LABEL_LONG_MODE_SCROLL_CIRCULAR +#define LV_LABEL_LONG_CLIP LV_LABEL_LONG_MODE_CLIP + +#define lv_anim_set_time lv_anim_set_duration +#define lv_anim_set_playback_time lv_anim_set_reverse_duration +#define lv_anim_set_playback_delay lv_anim_set_reverse_delay +#define lv_anim_set_playback_duration lv_anim_set_reverse_duration + +#define lv_gradient_init_stops lv_grad_init_stops +#define lv_gradient_stop_t lv_grad_stop_t + +#define lv_spangroup_new_span lv_spangroup_add_span +#define lv_spangroup_refr_mode lv_spangroup_refresh + +#define lv_slider_set_left_value lv_slider_set_start_value + +#define lv_calendar_header_arrow_create lv_calendar_add_header_arrow +#define lv_calendar_header_dropdown_create lv_calendar_add_header_dropdown #ifdef __cplusplus } /*extern "C"*/ #endif -#endif /*LV_API_MAP_V9_0_H*/ +#endif /* LV_API_MAP_V9_1_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/lv_conf_internal.h b/lib/libesp32_lvgl/lvgl/src/lv_conf_internal.h index 0a66d949e..d5b30d873 100644 --- a/lib/libesp32_lvgl/lvgl/src/lv_conf_internal.h +++ b/lib/libesp32_lvgl/lvgl/src/lv_conf_internal.h @@ -1,14 +1,14 @@ /** * GENERATED FILE, DO NOT EDIT IT! * @file lv_conf_internal.h - * Make sure all the defines of lv_conf.h have a default value -**/ + * This file ensures all defines of lv_conf.h have a default value. + */ #ifndef LV_CONF_INTERNAL_H #define LV_CONF_INTERNAL_H /* clang-format off */ -/*Config options*/ +/* Config options */ #define LV_OS_NONE 0 #define LV_OS_PTHREAD 1 #define LV_OS_FREERTOS 2 @@ -16,6 +16,7 @@ #define LV_OS_RTTHREAD 4 #define LV_OS_WINDOWS 5 #define LV_OS_MQX 6 +#define LV_OS_SDL2 7 #define LV_OS_CUSTOM 255 #define LV_STDLIB_BUILTIN 0 @@ -29,15 +30,18 @@ #define LV_DRAW_SW_ASM_HELIUM 2 #define LV_DRAW_SW_ASM_CUSTOM 255 -/* Handle special Kconfig options */ +#define LV_NEMA_HAL_CUSTOM 0 +#define LV_NEMA_HAL_STM32 1 + +/** Handle special Kconfig options. */ #ifndef LV_KCONFIG_IGNORE #include "lv_conf_kconfig.h" - #ifdef CONFIG_LV_CONF_SKIP + #if defined(CONFIG_LV_CONF_SKIP) && !defined(LV_CONF_SKIP) #define LV_CONF_SKIP #endif #endif -/*If "lv_conf.h" is available from here try to use it later.*/ +/* If "lv_conf.h" is available from here try to use it later. */ #ifdef __has_include #if __has_include("lv_conf.h") #ifndef LV_CONF_INCLUDE_SIMPLE @@ -46,18 +50,14 @@ #endif #endif -/*If lv_conf.h is not skipped include it*/ +/* If lv_conf.h is not skipped, include it. */ #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) - #include __LV_TO_STR(LV_CONF_PATH) - #undef __LV_TO_STR_AUX - #undef __LV_TO_STR - #elif defined(LV_CONF_INCLUDE_SIMPLE) /*Or simply include lv_conf.h is enabled*/ + #ifdef LV_CONF_PATH /* If there is a path defined for lv_conf.h, use it */ + #include LV_CONF_PATH /* Note: Make sure to define custom CONF_PATH as a string */ + #elif defined(LV_CONF_INCLUDE_SIMPLE) /* Or simply include lv_conf.h is enabled. */ #include "lv_conf.h" #else - #include "../../lv_conf.h" /*Else assume lv_conf.h is next to the lvgl folder*/ + #include "../../lv_conf.h" /* Else assume lv_conf.h is next to the lvgl folder. */ #endif #if !defined(LV_CONF_H) && !defined(LV_CONF_SUPPRESS_DEFINE_CHECK) /* #include will sometimes silently fail when __has_include is used */ @@ -74,7 +74,7 @@ * Start parsing lv_conf_template.h -----------------------------------*/ -/*If you need to include anything here, do it inside the `__ASSEMBLY__` guard */ +/* If you need to include anything here, do it inside the `__ASSEMBLY__` guard */ #if 0 && defined(__ASSEMBLY__) #include "my_include.h" #endif @@ -83,7 +83,7 @@ COLOR SETTINGS *====================*/ -/*Color depth: 1 (I1), 8 (L8), 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 @@ -96,7 +96,7 @@ STDLIB WRAPPER SETTINGS *=========================*/ -/* Possible values +/** Possible values * - LV_STDLIB_BUILTIN: LVGL's built in implementation * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc * - LV_STDLIB_MICROPYTHON: MicroPython implementation @@ -110,6 +110,14 @@ #define LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN #endif #endif + +/** Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ #ifndef LV_USE_STDLIB_STRING #ifdef CONFIG_LV_USE_STDLIB_STRING #define LV_USE_STDLIB_STRING CONFIG_LV_USE_STDLIB_STRING @@ -117,6 +125,14 @@ #define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN #endif #endif + +/** Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ #ifndef LV_USE_STDLIB_SPRINTF #ifdef CONFIG_LV_USE_STDLIB_SPRINTF #define LV_USE_STDLIB_SPRINTF CONFIG_LV_USE_STDLIB_SPRINTF @@ -169,16 +185,16 @@ #endif #if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN - /*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/ + /** Size of memory available for `lv_malloc()` in bytes (>= 2kB) */ #ifndef LV_MEM_SIZE #ifdef CONFIG_LV_MEM_SIZE #define LV_MEM_SIZE CONFIG_LV_MEM_SIZE #else - #define LV_MEM_SIZE (64 * 1024U) /*[bytes]*/ + #define LV_MEM_SIZE (64 * 1024U) /**< [bytes] */ #endif #endif - /*Size of the memory expand for `lv_malloc()` in bytes*/ + /** Size of the memory expand for `lv_malloc()` in bytes */ #ifndef LV_MEM_POOL_EXPAND_SIZE #ifdef CONFIG_LV_MEM_POOL_EXPAND_SIZE #define LV_MEM_POOL_EXPAND_SIZE CONFIG_LV_MEM_POOL_EXPAND_SIZE @@ -187,15 +203,15 @@ #endif #endif - /*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/ + /** Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too. */ #ifndef LV_MEM_ADR #ifdef CONFIG_LV_MEM_ADR #define LV_MEM_ADR CONFIG_LV_MEM_ADR #else - #define LV_MEM_ADR 0 /*0: unused*/ + #define LV_MEM_ADR 0 /**< 0: unused*/ #endif #endif - /*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/ + /* Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc */ #if LV_MEM_ADR == 0 #ifndef LV_MEM_POOL_INCLUDE #ifdef CONFIG_LV_MEM_POOL_INCLUDE @@ -218,29 +234,29 @@ HAL SETTINGS *====================*/ -/*Default display refresh, input device read and animation step period.*/ +/** Default display refresh, input device read and animation step period. */ #ifndef LV_DEF_REFR_PERIOD #ifdef CONFIG_LV_DEF_REFR_PERIOD #define LV_DEF_REFR_PERIOD CONFIG_LV_DEF_REFR_PERIOD #else - #define LV_DEF_REFR_PERIOD 33 /*[ms]*/ + #define LV_DEF_REFR_PERIOD 33 /**< [ms] */ #endif #endif -/*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings. - *(Not so important, you can adjust it to modify default sizes and spaces)*/ +/** Default Dots Per Inch. Used to initialize default sizes such as widgets sized, style paddings. + * (Not so important, you can adjust it to modify default sizes and spaces.) */ #ifndef LV_DPI_DEF #ifdef CONFIG_LV_DPI_DEF #define LV_DPI_DEF CONFIG_LV_DPI_DEF #else - #define LV_DPI_DEF 130 /*[px/inch]*/ + #define LV_DPI_DEF 130 /**< [px/inch] */ #endif #endif /*================= * OPERATING SYSTEM *=================*/ -/*Select an operating system to use. Possible options: +/** Select operating system to use. Possible options: * - LV_OS_NONE * - LV_OS_PTHREAD * - LV_OS_FREERTOS @@ -248,6 +264,7 @@ * - LV_OS_RTTHREAD * - LV_OS_WINDOWS * - LV_OS_MQX + * - LV_OS_SDL2 * - LV_OS_CUSTOM */ #ifndef LV_USE_OS #ifdef CONFIG_LV_USE_OS @@ -267,29 +284,29 @@ #endif #endif #if LV_USE_OS == LV_OS_FREERTOS - /* - * Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM - * than unblocking a task using an intermediary object such as a binary semaphore. - * RTOS task notifications can only be used when there is only one task that can be the recipient of the event. - */ - #ifndef LV_USE_FREERTOS_TASK_NOTIFY - #ifdef LV_KCONFIG_PRESENT - #ifdef CONFIG_LV_USE_FREERTOS_TASK_NOTIFY - #define LV_USE_FREERTOS_TASK_NOTIFY CONFIG_LV_USE_FREERTOS_TASK_NOTIFY - #else - #define LV_USE_FREERTOS_TASK_NOTIFY 0 - #endif - #else - #define LV_USE_FREERTOS_TASK_NOTIFY 1 - #endif - #endif + /* + * Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM + * than unblocking a task using an intermediary object such as a binary semaphore. + * RTOS task notifications can only be used when there is only one task that can be the recipient of the event. + */ + #ifndef LV_USE_FREERTOS_TASK_NOTIFY + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_FREERTOS_TASK_NOTIFY + #define LV_USE_FREERTOS_TASK_NOTIFY CONFIG_LV_USE_FREERTOS_TASK_NOTIFY + #else + #define LV_USE_FREERTOS_TASK_NOTIFY 0 + #endif + #else + #define LV_USE_FREERTOS_TASK_NOTIFY 1 + #endif + #endif #endif /*======================== * RENDERING CONFIGURATION *========================*/ -/*Align the stride of all layers and images to this bytes*/ +/** Align stride of all layers and images to this bytes */ #ifndef LV_DRAW_BUF_STRIDE_ALIGN #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_DRAW_BUF_STRIDE_ALIGN @@ -302,7 +319,7 @@ #endif #endif -/*Align the start address of draw_buf addresses to this bytes*/ +/** Align start address of draw_buf addresses to this bytes*/ #ifndef LV_DRAW_BUF_ALIGN #ifdef CONFIG_LV_DRAW_BUF_ALIGN #define LV_DRAW_BUF_ALIGN CONFIG_LV_DRAW_BUF_ALIGN @@ -311,10 +328,10 @@ #endif #endif -/*Using matrix for transformations. - *Requirements: - `LV_USE_MATRIX = 1`. - The rendering engine needs to support 3x3 matrix transformations.*/ +/** Using matrix for transformations. + * Requirements: + * - `LV_USE_MATRIX = 1`. + * - 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 @@ -328,23 +345,50 @@ * "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers * and can't be drawn in chunks. */ -/*The target buffer size for simple layer chunks.*/ +/** The target buffer size for simple layer chunks. */ #ifndef LV_DRAW_LAYER_SIMPLE_BUF_SIZE #ifdef CONFIG_LV_DRAW_LAYER_SIMPLE_BUF_SIZE #define LV_DRAW_LAYER_SIMPLE_BUF_SIZE CONFIG_LV_DRAW_LAYER_SIMPLE_BUF_SIZE #else - #define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /*[bytes]*/ + #define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /**< [bytes]*/ #endif #endif -/* The stack size of the drawing thread. +/* Limit the max allocated memory for simple and transformed layers. + * It should be at least `LV_DRAW_LAYER_SIMPLE_BUF_SIZE` sized but if transformed layers are also used + * it should be enough to store the largest widget too (width x height x 4 area). + * Set it to 0 to have no limit. */ +#ifndef LV_DRAW_LAYER_MAX_MEMORY + #ifdef CONFIG_LV_DRAW_LAYER_MAX_MEMORY + #define LV_DRAW_LAYER_MAX_MEMORY CONFIG_LV_DRAW_LAYER_MAX_MEMORY + #else + #define LV_DRAW_LAYER_MAX_MEMORY 0 /**< No limit by default [bytes]*/ + #endif +#endif + +/** Stack size of 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]*/ + #define LV_DRAW_THREAD_STACK_SIZE (8 * 1024) /**< [bytes]*/ + #endif +#endif + +/** Thread priority of the drawing task. + * Higher values mean higher priority. + * Can use values from lv_thread_prio_t enum in lv_os.h: LV_THREAD_PRIO_LOWEST, + * LV_THREAD_PRIO_LOW, LV_THREAD_PRIO_MID, LV_THREAD_PRIO_HIGH, LV_THREAD_PRIO_HIGHEST + * Make sure the priority value aligns with the OS-specific priority levels. + * On systems with limited priority levels (e.g., FreeRTOS), a higher value can improve + * rendering performance but might cause other tasks to starve. */ +#ifndef LV_DRAW_THREAD_PRIO + #ifdef CONFIG_LV_DRAW_THREAD_PRIO + #define LV_DRAW_THREAD_PRIO CONFIG_LV_DRAW_THREAD_PRIO + #else + #define LV_DRAW_THREAD_PRIO LV_THREAD_PRIO_HIGH #endif #endif @@ -360,117 +404,147 @@ #endif #endif #if LV_USE_DRAW_SW == 1 + /* + * 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_RGB565_SWAPPED + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + #define LV_DRAW_SW_SUPPORT_RGB565_SWAPPED CONFIG_LV_DRAW_SW_SUPPORT_RGB565_SWAPPED + #else + #define LV_DRAW_SW_SUPPORT_RGB565_SWAPPED 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_RGB565_SWAPPED 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_ARGB8888_PREMULTIPLIED + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + #define LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED CONFIG_LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED + #else + #define LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED 0 + #endif + #else + #define LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED 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 - /* - * 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 - */ + /* The threshold of the luminance to consider a pixel as + * active in indexed color format */ + #ifndef LV_DRAW_SW_I1_LUM_THRESHOLD + #ifdef CONFIG_LV_DRAW_SW_I1_LUM_THRESHOLD + #define LV_DRAW_SW_I1_LUM_THRESHOLD CONFIG_LV_DRAW_SW_I1_LUM_THRESHOLD + #else + #define LV_DRAW_SW_I1_LUM_THRESHOLD 127 + #endif + #endif - #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 multiple threads will render the screen in parallel */ + /** Set number of draw units. + * - > 1 requires operating system to be enabled in `LV_USE_OS`. + * - > 1 means multiple threads will render the screen in parallel. */ #ifndef LV_DRAW_SW_DRAW_UNIT_CNT #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_DRAW_SW_DRAW_UNIT_CNT @@ -483,7 +557,7 @@ #endif #endif - /* Use Arm-2D to accelerate the sw render */ + /** Use Arm-2D to accelerate software (sw) rendering. */ #ifndef LV_USE_DRAW_ARM2D_SYNC #ifdef CONFIG_LV_USE_DRAW_ARM2D_SYNC #define LV_USE_DRAW_ARM2D_SYNC CONFIG_LV_USE_DRAW_ARM2D_SYNC @@ -492,7 +566,7 @@ #endif #endif - /* Enable native helium assembly to be compiled */ + /** Enable native helium assembly to be compiled. */ #ifndef LV_USE_NATIVE_HELIUM_ASM #ifdef CONFIG_LV_USE_NATIVE_HELIUM_ASM #define LV_USE_NATIVE_HELIUM_ASM CONFIG_LV_USE_NATIVE_HELIUM_ASM @@ -501,8 +575,9 @@ #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 */ + /** + * - 0: Use a simple renderer capable of drawing only simple rectangles with gradient, images, text, 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 CONFIG_LV_DRAW_SW_COMPLEX @@ -516,9 +591,9 @@ #endif #if LV_DRAW_SW_COMPLEX == 1 - /*Allow buffering some shadow calculation. - *LV_DRAW_SW_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius` - *Caching has LV_DRAW_SW_SHADOW_CACHE_SIZE^2 RAM cost*/ + /** Allow buffering some shadow calculation. + * LV_DRAW_SW_SHADOW_CACHE_SIZE is the maximum shadow size to buffer, where shadow size is + * `shadow_width + radius`. Caching has LV_DRAW_SW_SHADOW_CACHE_SIZE^2 RAM cost. */ #ifndef LV_DRAW_SW_SHADOW_CACHE_SIZE #ifdef CONFIG_LV_DRAW_SW_SHADOW_CACHE_SIZE #define LV_DRAW_SW_SHADOW_CACHE_SIZE CONFIG_LV_DRAW_SW_SHADOW_CACHE_SIZE @@ -527,10 +602,10 @@ #endif #endif - /* Set number of maximally cached circle data. - * The circumference of 1/4 circle are saved for anti-aliasing - * radius * 4 bytes are used per circle (the most often used radiuses are saved) - * 0: to disable caching */ + /** Set number of maximally-cached circle data. + * The circumference of 1/4 circle are saved for anti-aliasing. + * `radius * 4` bytes are used per circle (the most often used radiuses are saved). + * - 0: disables caching */ #ifndef LV_DRAW_SW_CIRCLE_CACHE_SIZE #ifdef CONFIG_LV_DRAW_SW_CIRCLE_CACHE_SIZE #define LV_DRAW_SW_CIRCLE_CACHE_SIZE CONFIG_LV_DRAW_SW_CIRCLE_CACHE_SIZE @@ -558,7 +633,7 @@ #endif #endif - /* Enable drawing complex gradients in software: linear at an angle, radial or conical */ + /** 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 @@ -566,9 +641,67 @@ #define LV_USE_DRAW_SW_COMPLEX_GRADIENTS 0 #endif #endif + #endif -/* Use NXP's VG-Lite GPU on iMX RTxxx platforms. */ +/*Use TSi's aka (Think Silicon) NemaGFX */ +#ifndef LV_USE_NEMA_GFX + #ifdef CONFIG_LV_USE_NEMA_GFX + #define LV_USE_NEMA_GFX CONFIG_LV_USE_NEMA_GFX + #else + #define LV_USE_NEMA_GFX 0 + #endif +#endif + +#if LV_USE_NEMA_GFX + /** Select which NemaGFX HAL to use. Possible options: + * - LV_NEMA_HAL_CUSTOM + * - LV_NEMA_HAL_STM32 */ + #ifndef LV_USE_NEMA_HAL + #ifdef CONFIG_LV_USE_NEMA_HAL + #define LV_USE_NEMA_HAL CONFIG_LV_USE_NEMA_HAL + #else + #define LV_USE_NEMA_HAL LV_NEMA_HAL_CUSTOM + #endif + #endif + #if LV_USE_NEMA_HAL == LV_NEMA_HAL_STM32 + #ifndef LV_NEMA_STM32_HAL_INCLUDE + #ifdef CONFIG_LV_NEMA_STM32_HAL_INCLUDE + #define LV_NEMA_STM32_HAL_INCLUDE CONFIG_LV_NEMA_STM32_HAL_INCLUDE + #else + #define LV_NEMA_STM32_HAL_INCLUDE + #endif + #endif + #endif + + /*Enable Vector Graphics Operations. Available only if NemaVG library is present*/ + #ifndef LV_USE_NEMA_VG + #ifdef CONFIG_LV_USE_NEMA_VG + #define LV_USE_NEMA_VG CONFIG_LV_USE_NEMA_VG + #else + #define LV_USE_NEMA_VG 0 + #endif + #endif + #if LV_USE_NEMA_VG + /*Define application's resolution used for VG related buffer allocation */ + #ifndef LV_NEMA_GFX_MAX_RESX + #ifdef CONFIG_LV_NEMA_GFX_MAX_RESX + #define LV_NEMA_GFX_MAX_RESX CONFIG_LV_NEMA_GFX_MAX_RESX + #else + #define LV_NEMA_GFX_MAX_RESX 800 + #endif + #endif + #ifndef LV_NEMA_GFX_MAX_RESY + #ifdef CONFIG_LV_NEMA_GFX_MAX_RESY + #define LV_NEMA_GFX_MAX_RESY CONFIG_LV_NEMA_GFX_MAX_RESY + #else + #define LV_NEMA_GFX_MAX_RESY 600 + #endif + #endif + #endif +#endif + +/** Use NXP's VG-Lite GPU on iMX RTxxx platforms. */ #ifndef LV_USE_DRAW_VGLITE #ifdef CONFIG_LV_USE_DRAW_VGLITE #define LV_USE_DRAW_VGLITE CONFIG_LV_USE_DRAW_VGLITE @@ -578,7 +711,7 @@ #endif #if LV_USE_DRAW_VGLITE - /* Enable blit quality degradation workaround recommended for screen's dimension > 352 pixels. */ + /** Enable blit quality degradation workaround recommended for screen's dimension > 352 pixels. */ #ifndef LV_USE_VGLITE_BLIT_SPLIT #ifdef CONFIG_LV_USE_VGLITE_BLIT_SPLIT #define LV_USE_VGLITE_BLIT_SPLIT CONFIG_LV_USE_VGLITE_BLIT_SPLIT @@ -588,7 +721,7 @@ #endif #if LV_USE_OS - /* Use additional draw thread for VG-Lite processing.*/ + /** 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 @@ -602,7 +735,7 @@ #endif #if LV_USE_VGLITE_DRAW_THREAD - /* Enable VGLite draw async. Queue multiple tasks and flash them once to the GPU. */ + /** 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 @@ -617,7 +750,7 @@ #endif #endif - /* Enable VGLite asserts. */ + /** Enable VGLite asserts. */ #ifndef LV_USE_VGLITE_ASSERT #ifdef CONFIG_LV_USE_VGLITE_ASSERT #define LV_USE_VGLITE_ASSERT CONFIG_LV_USE_VGLITE_ASSERT @@ -625,9 +758,18 @@ #define LV_USE_VGLITE_ASSERT 0 #endif #endif + + /** Enable VGLite error checks. */ + #ifndef LV_USE_VGLITE_CHECK_ERROR + #ifdef CONFIG_LV_USE_VGLITE_CHECK_ERROR + #define LV_USE_VGLITE_CHECK_ERROR CONFIG_LV_USE_VGLITE_CHECK_ERROR + #else + #define LV_USE_VGLITE_CHECK_ERROR 0 + #endif + #endif #endif -/* Use NXP's PXP on iMX RTxxx platforms. */ +/** Use NXP's PXP on iMX RTxxx platforms. */ #ifndef LV_USE_PXP #ifdef CONFIG_LV_USE_PXP #define LV_USE_PXP CONFIG_LV_USE_PXP @@ -637,7 +779,7 @@ #endif #if LV_USE_PXP - /* Use PXP for drawing.*/ + /** Use PXP for drawing.*/ #ifndef LV_USE_DRAW_PXP #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_DRAW_PXP @@ -650,7 +792,7 @@ #endif #endif - /* Use PXP to rotate display.*/ + /** Use PXP to rotate display.*/ #ifndef LV_USE_ROTATE_PXP #ifdef CONFIG_LV_USE_ROTATE_PXP #define LV_USE_ROTATE_PXP CONFIG_LV_USE_ROTATE_PXP @@ -660,7 +802,7 @@ #endif #if LV_USE_DRAW_PXP && LV_USE_OS - /* Use additional draw thread for PXP processing.*/ + /** Use additional draw thread for PXP processing.*/ #ifndef LV_USE_PXP_DRAW_THREAD #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_PXP_DRAW_THREAD @@ -674,7 +816,7 @@ #endif #endif - /* Enable PXP asserts. */ + /** Enable PXP asserts. */ #ifndef LV_USE_PXP_ASSERT #ifdef CONFIG_LV_USE_PXP_ASSERT #define LV_USE_PXP_ASSERT CONFIG_LV_USE_PXP_ASSERT @@ -684,7 +826,52 @@ #endif #endif -/* Use Renesas Dave2D on RA platforms. */ +/** Use NXP's G2D on MPU platforms. */ +#ifndef LV_USE_DRAW_G2D + #ifdef CONFIG_LV_USE_DRAW_G2D + #define LV_USE_DRAW_G2D CONFIG_LV_USE_DRAW_G2D + #else + #define LV_USE_DRAW_G2D 0 + #endif +#endif + +#if LV_USE_DRAW_G2D + /** Maximum number of buffers that can be stored for G2D draw unit. + * Includes the frame buffers and assets. */ + #ifndef LV_G2D_HASH_TABLE_SIZE + #ifdef CONFIG_LV_G2D_HASH_TABLE_SIZE + #define LV_G2D_HASH_TABLE_SIZE CONFIG_LV_G2D_HASH_TABLE_SIZE + #else + #define LV_G2D_HASH_TABLE_SIZE 50 + #endif + #endif + + #if LV_USE_OS + /** Use additional draw thread for G2D processing.*/ + #ifndef LV_USE_G2D_DRAW_THREAD + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_G2D_DRAW_THREAD + #define LV_USE_G2D_DRAW_THREAD CONFIG_LV_USE_G2D_DRAW_THREAD + #else + #define LV_USE_G2D_DRAW_THREAD 0 + #endif + #else + #define LV_USE_G2D_DRAW_THREAD 1 + #endif + #endif + #endif + + /** Enable G2D asserts. */ + #ifndef LV_USE_G2D_ASSERT + #ifdef CONFIG_LV_USE_G2D_ASSERT + #define LV_USE_G2D_ASSERT CONFIG_LV_USE_G2D_ASSERT + #else + #define LV_USE_G2D_ASSERT 0 + #endif + #endif +#endif + +/** Use Renesas Dave2D on RA platforms. */ #ifndef LV_USE_DRAW_DAVE2D #ifdef CONFIG_LV_USE_DRAW_DAVE2D #define LV_USE_DRAW_DAVE2D CONFIG_LV_USE_DRAW_DAVE2D @@ -693,7 +880,7 @@ #endif #endif -/* Draw using cached SDL textures*/ +/** Draw using cached SDL textures*/ #ifndef LV_USE_DRAW_SDL #ifdef CONFIG_LV_USE_DRAW_SDL #define LV_USE_DRAW_SDL CONFIG_LV_USE_DRAW_SDL @@ -702,7 +889,7 @@ #endif #endif -/* Use VG-Lite GPU. */ +/** Use VG-Lite GPU. */ #ifndef LV_USE_DRAW_VG_LITE #ifdef CONFIG_LV_USE_DRAW_VG_LITE #define LV_USE_DRAW_VG_LITE CONFIG_LV_USE_DRAW_VG_LITE @@ -712,7 +899,7 @@ #endif #if LV_USE_DRAW_VG_LITE - /* Enable VG-Lite custom external 'gpu_init()' function */ + /** 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 @@ -721,7 +908,7 @@ #endif #endif - /* Enable VG-Lite assert. */ + /** 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 @@ -730,7 +917,7 @@ #endif #endif - /* VG-Lite flush commit trigger threshold. GPU will try to batch these many draw tasks. */ + /** 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 @@ -739,20 +926,23 @@ #endif #endif - /* Enable border to simulate shadow - * NOTE: which usually improves performance, - * but does not guarantee the same rendering quality as the software. */ + /** 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 + #ifdef LV_KCONFIG_PRESENT + #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 #else - #define LV_VG_LITE_USE_BOX_SHADOW 0 + #define LV_VG_LITE_USE_BOX_SHADOW 1 #endif #endif - /* VG-Lite gradient maximum cache number. - * NOTE: The memory usage of a single gradient image is 4K bytes. - */ + /** 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 @@ -761,8 +951,7 @@ #endif #endif - /* VG-Lite stroke maximum cache number. - */ + /** 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 @@ -770,7 +959,45 @@ #define LV_VG_LITE_STROKE_CACHE_CNT 32 #endif #endif +#endif +/** Accelerate blends, fills, etc. with STM32 DMA2D */ +#ifndef LV_USE_DRAW_DMA2D + #ifdef CONFIG_LV_USE_DRAW_DMA2D + #define LV_USE_DRAW_DMA2D CONFIG_LV_USE_DRAW_DMA2D + #else + #define LV_USE_DRAW_DMA2D 0 + #endif +#endif + +#if LV_USE_DRAW_DMA2D + #ifndef LV_DRAW_DMA2D_HAL_INCLUDE + #ifdef CONFIG_LV_DRAW_DMA2D_HAL_INCLUDE + #define LV_DRAW_DMA2D_HAL_INCLUDE CONFIG_LV_DRAW_DMA2D_HAL_INCLUDE + #else + #define LV_DRAW_DMA2D_HAL_INCLUDE "stm32h7xx_hal.h" + #endif + #endif + + /* if enabled, the user is required to call `lv_draw_dma2d_transfer_complete_interrupt_handler` + * upon receiving the DMA2D global interrupt + */ + #ifndef LV_USE_DRAW_DMA2D_INTERRUPT + #ifdef CONFIG_LV_USE_DRAW_DMA2D_INTERRUPT + #define LV_USE_DRAW_DMA2D_INTERRUPT CONFIG_LV_USE_DRAW_DMA2D_INTERRUPT + #else + #define LV_USE_DRAW_DMA2D_INTERRUPT 0 + #endif + #endif +#endif + +/** Draw using cached OpenGLES textures */ +#ifndef LV_USE_DRAW_OPENGLES + #ifdef CONFIG_LV_USE_DRAW_OPENGLES + #define LV_USE_DRAW_OPENGLES CONFIG_LV_USE_DRAW_OPENGLES + #else + #define LV_USE_DRAW_OPENGLES 0 + #endif #endif /*======================= @@ -781,7 +1008,7 @@ * Logging *-----------*/ -/*Enable the log module*/ +/** Enable log module */ #ifndef LV_USE_LOG #ifdef CONFIG_LV_USE_LOG #define LV_USE_LOG CONFIG_LV_USE_LOG @@ -790,14 +1017,13 @@ #endif #endif #if LV_USE_LOG - - /*How important log should be added: - *LV_LOG_LEVEL_TRACE A lot of logs to give detailed information - *LV_LOG_LEVEL_INFO Log important events - *LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem - *LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail - *LV_LOG_LEVEL_USER Only logs added by the user - *LV_LOG_LEVEL_NONE Do not log anything*/ + /** Set value to one of the following levels of logging detail: + * - LV_LOG_LEVEL_TRACE Log detailed information. + * - LV_LOG_LEVEL_INFO Log important events. + * - LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem. + * - LV_LOG_LEVEL_ERROR Log only critical issues, when system may fail. + * - LV_LOG_LEVEL_USER Log only custom log messages added by the user. + * - LV_LOG_LEVEL_NONE Do not log anything. */ #ifndef LV_LOG_LEVEL #ifdef CONFIG_LV_LOG_LEVEL #define LV_LOG_LEVEL CONFIG_LV_LOG_LEVEL @@ -806,8 +1032,8 @@ #endif #endif - /*1: Print the log with 'printf'; - *0: User need to register a callback with `lv_log_register_print_cb()`*/ + /** - 1: Print log with 'printf'; + * - 0: User needs to register a callback with `lv_log_register_print_cb()`. */ #ifndef LV_LOG_PRINTF #ifdef CONFIG_LV_LOG_PRINTF #define LV_LOG_PRINTF CONFIG_LV_LOG_PRINTF @@ -816,13 +1042,13 @@ #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`*/ + /** Set callback to print 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*/ + /** - 1: Enable printing timestamp; + * - 0: Disable printing timestamp. */ #ifndef LV_LOG_USE_TIMESTAMP #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_LOG_USE_TIMESTAMP @@ -835,8 +1061,8 @@ #endif #endif - /*1: Print file and line number of the log; - *0: Do not print file and line number of the log*/ + /** - 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 CONFIG_LV_LOG_USE_FILE_LINE @@ -849,8 +1075,7 @@ #endif #endif - - /*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/ + /* Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs. */ #ifndef LV_LOG_TRACE_MEM #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_LOG_TRACE_MEM @@ -859,7 +1084,7 @@ #define LV_LOG_TRACE_MEM 0 #endif #else - #define LV_LOG_TRACE_MEM 1 + #define LV_LOG_TRACE_MEM 1 /**< Enable/disable trace logs in memory operations. */ #endif #endif #ifndef LV_LOG_TRACE_TIMER @@ -870,7 +1095,7 @@ #define LV_LOG_TRACE_TIMER 0 #endif #else - #define LV_LOG_TRACE_TIMER 1 + #define LV_LOG_TRACE_TIMER 1 /**< Enable/disable trace logs in timer operations. */ #endif #endif #ifndef LV_LOG_TRACE_INDEV @@ -881,7 +1106,7 @@ #define LV_LOG_TRACE_INDEV 0 #endif #else - #define LV_LOG_TRACE_INDEV 1 + #define LV_LOG_TRACE_INDEV 1 /**< Enable/disable trace logs in input device operations. */ #endif #endif #ifndef LV_LOG_TRACE_DISP_REFR @@ -892,7 +1117,7 @@ #define LV_LOG_TRACE_DISP_REFR 0 #endif #else - #define LV_LOG_TRACE_DISP_REFR 1 + #define LV_LOG_TRACE_DISP_REFR 1 /**< Enable/disable trace logs in display re-draw operations. */ #endif #endif #ifndef LV_LOG_TRACE_EVENT @@ -903,7 +1128,7 @@ #define LV_LOG_TRACE_EVENT 0 #endif #else - #define LV_LOG_TRACE_EVENT 1 + #define LV_LOG_TRACE_EVENT 1 /**< Enable/disable trace logs in event dispatch logic. */ #endif #endif #ifndef LV_LOG_TRACE_OBJ_CREATE @@ -914,7 +1139,7 @@ #define LV_LOG_TRACE_OBJ_CREATE 0 #endif #else - #define LV_LOG_TRACE_OBJ_CREATE 1 + #define LV_LOG_TRACE_OBJ_CREATE 1 /**< Enable/disable trace logs in object creation (core `obj` creation plus every widget). */ #endif #endif #ifndef LV_LOG_TRACE_LAYOUT @@ -925,7 +1150,7 @@ #define LV_LOG_TRACE_LAYOUT 0 #endif #else - #define LV_LOG_TRACE_LAYOUT 1 + #define LV_LOG_TRACE_LAYOUT 1 /**< Enable/disable trace logs in flex- and grid-layout operations. */ #endif #endif #ifndef LV_LOG_TRACE_ANIM @@ -936,7 +1161,7 @@ #define LV_LOG_TRACE_ANIM 0 #endif #else - #define LV_LOG_TRACE_ANIM 1 + #define LV_LOG_TRACE_ANIM 1 /**< Enable/disable trace logs in animation logic. */ #endif #endif #ifndef LV_LOG_TRACE_CACHE @@ -947,18 +1172,17 @@ #define LV_LOG_TRACE_CACHE 0 #endif #else - #define LV_LOG_TRACE_CACHE 1 + #define LV_LOG_TRACE_CACHE 1 /**< Enable/disable trace logs in cache operations. */ #endif #endif - #endif /*LV_USE_LOG*/ /*------------- * Asserts *-----------*/ -/*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*/ +/* Enable assertion failures if an operation fails or 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 CONFIG_LV_USE_ASSERT_NULL @@ -967,7 +1191,7 @@ #define LV_USE_ASSERT_NULL 0 #endif #else - #define LV_USE_ASSERT_NULL 1 /*Check if the parameter is NULL. (Very fast, recommended)*/ + #define LV_USE_ASSERT_NULL 1 /**< Check if the parameter is NULL. (Very fast, recommended) */ #endif #endif #ifndef LV_USE_ASSERT_MALLOC @@ -978,32 +1202,32 @@ #define LV_USE_ASSERT_MALLOC 0 #endif #else - #define LV_USE_ASSERT_MALLOC 1 /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/ + #define LV_USE_ASSERT_MALLOC 1 /**< Checks is the memory is successfully allocated or no. (Very fast, recommended) */ #endif #endif #ifndef LV_USE_ASSERT_STYLE #ifdef CONFIG_LV_USE_ASSERT_STYLE #define LV_USE_ASSERT_STYLE CONFIG_LV_USE_ASSERT_STYLE #else - #define LV_USE_ASSERT_STYLE 0 /*Check if the styles are properly initialized. (Very fast, recommended)*/ + #define LV_USE_ASSERT_STYLE 0 /**< Check if the styles are properly initialized. (Very fast, recommended) */ #endif #endif #ifndef LV_USE_ASSERT_MEM_INTEGRITY #ifdef CONFIG_LV_USE_ASSERT_MEM_INTEGRITY #define LV_USE_ASSERT_MEM_INTEGRITY CONFIG_LV_USE_ASSERT_MEM_INTEGRITY #else - #define LV_USE_ASSERT_MEM_INTEGRITY 0 /*Check the integrity of `lv_mem` after critical operations. (Slow)*/ + #define LV_USE_ASSERT_MEM_INTEGRITY 0 /**< Check the integrity of `lv_mem` after critical operations. (Slow) */ #endif #endif #ifndef LV_USE_ASSERT_OBJ #ifdef CONFIG_LV_USE_ASSERT_OBJ #define LV_USE_ASSERT_OBJ CONFIG_LV_USE_ASSERT_OBJ #else - #define LV_USE_ASSERT_OBJ 0 /*Check the object's type and existence (e.g. not deleted). (Slow)*/ + #define LV_USE_ASSERT_OBJ 0 /**< Check the object's type and existence (e.g. not deleted). (Slow) */ #endif #endif -/*Add a custom handler when assert happens e.g. to restart the MCU*/ +/** Add a custom handler when assert happens e.g. to restart MCU. */ #ifndef LV_ASSERT_HANDLER_INCLUDE #ifdef CONFIG_LV_ASSERT_HANDLER_INCLUDE #define LV_ASSERT_HANDLER_INCLUDE CONFIG_LV_ASSERT_HANDLER_INCLUDE @@ -1015,7 +1239,7 @@ #ifdef CONFIG_LV_ASSERT_HANDLER #define LV_ASSERT_HANDLER CONFIG_LV_ASSERT_HANDLER #else - #define LV_ASSERT_HANDLER while(1); /*Halt by default*/ + #define LV_ASSERT_HANDLER while(1); /**< Halt by default */ #endif #endif @@ -1023,7 +1247,7 @@ * Debug *-----------*/ -/*1: Draw random colored rectangles over the redrawn areas*/ +/** 1: Draw random colored rectangles over the redrawn areas. */ #ifndef LV_USE_REFR_DEBUG #ifdef CONFIG_LV_USE_REFR_DEBUG #define LV_USE_REFR_DEBUG CONFIG_LV_USE_REFR_DEBUG @@ -1032,7 +1256,7 @@ #endif #endif -/*1: Draw a red overlay for ARGB layers and a green overlay for RGB layers*/ +/** 1: Draw a red overlay for ARGB layers and a green overlay for RGB layers*/ #ifndef LV_USE_LAYER_DEBUG #ifdef CONFIG_LV_USE_LAYER_DEBUG #define LV_USE_LAYER_DEBUG CONFIG_LV_USE_LAYER_DEBUG @@ -1041,9 +1265,10 @@ #endif #endif -/*1: Draw overlays with different colors for each draw_unit's tasks. - *Also add the index number of the draw unit on white background. - *For layers add the index number of the draw unit on black background.*/ +/** 1: Adds the following behaviors for debugging: + * - Draw overlays with different colors for each draw_unit's tasks. + * - Draw index number of draw unit on white background. + * - For layers, draws index number of draw unit on black background. */ #ifndef LV_USE_PARALLEL_DRAW_DEBUG #ifdef CONFIG_LV_USE_PARALLEL_DRAW_DEBUG #define LV_USE_PARALLEL_DRAW_DEBUG CONFIG_LV_USE_PARALLEL_DRAW_DEBUG @@ -1064,7 +1289,7 @@ #endif #endif #if LV_ENABLE_GLOBAL_CUSTOM - /*Header to include for the custom 'lv_global' function"*/ + /** Header to include for custom 'lv_global' function" */ #ifndef LV_GLOBAL_CUSTOM_INCLUDE #ifdef CONFIG_LV_GLOBAL_CUSTOM_INCLUDE #define LV_GLOBAL_CUSTOM_INCLUDE CONFIG_LV_GLOBAL_CUSTOM_INCLUDE @@ -1074,10 +1299,11 @@ #endif #endif -/*Default cache size in bytes. - *Used by image decoders such as `lv_lodepng` to keep the decoded image in the memory. - *If size is not set to 0, the decoder will fail to decode when the cache is full. - *If size is 0, the cache function is not enabled and the decoded mem will be released immediately after use.*/ +/** Default cache size in bytes. + * Used by image decoders such as `lv_lodepng` to keep the decoded image in memory. + * If size is not set to 0, the decoder will fail to decode when the cache is full. + * If size is 0, the cache function is not enabled and the decoded memory will be + * released immediately after use. */ #ifndef LV_CACHE_DEF_SIZE #ifdef CONFIG_LV_CACHE_DEF_SIZE #define LV_CACHE_DEF_SIZE CONFIG_LV_CACHE_DEF_SIZE @@ -1086,8 +1312,8 @@ #endif #endif -/*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.*/ +/** 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. */ #ifndef LV_IMAGE_HEADER_CACHE_DEF_CNT #ifdef CONFIG_LV_IMAGE_HEADER_CACHE_DEF_CNT #define LV_IMAGE_HEADER_CACHE_DEF_CNT CONFIG_LV_IMAGE_HEADER_CACHE_DEF_CNT @@ -1096,8 +1322,8 @@ #endif #endif -/*Number of stops allowed per gradient. Increase this to allow more stops. - *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/ +/** Number of stops allowed per gradient. Increase this to allow more stops. + * This adds (sizeof(lv_color_t) + 1) bytes per additional stop. */ #ifndef LV_GRADIENT_MAX_STOPS #ifdef CONFIG_LV_GRADIENT_MAX_STOPS #define LV_GRADIENT_MAX_STOPS CONFIG_LV_GRADIENT_MAX_STOPS @@ -1106,8 +1332,12 @@ #endif #endif -/* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. - * 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */ +/** Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. + * - 0: round down, + * - 64: round up from x.75, + * - 128: round up from half, + * - 192: round up from x.25, + * - 254: round up */ #ifndef LV_COLOR_MIX_ROUND_OFS #ifdef CONFIG_LV_COLOR_MIX_ROUND_OFS #define LV_COLOR_MIX_ROUND_OFS CONFIG_LV_COLOR_MIX_ROUND_OFS @@ -1116,7 +1346,7 @@ #endif #endif -/* Add 2 x 32 bit variables to each lv_obj_t to speed up getting style properties */ +/** Add 2 x 32-bit variables to each `lv_obj_t` to speed up getting style properties */ #ifndef LV_OBJ_STYLE_CACHE #ifdef CONFIG_LV_OBJ_STYLE_CACHE #define LV_OBJ_STYLE_CACHE CONFIG_LV_OBJ_STYLE_CACHE @@ -1125,7 +1355,7 @@ #endif #endif -/* Add `id` field to `lv_obj_t` */ +/** Add `id` field to `lv_obj_t` */ #ifndef LV_USE_OBJ_ID #ifdef CONFIG_LV_USE_OBJ_ID #define LV_USE_OBJ_ID CONFIG_LV_USE_OBJ_ID @@ -1134,7 +1364,16 @@ #endif #endif -/* Automatically assign an ID when obj is created */ +/** Enable support widget names*/ +#ifndef LV_USE_OBJ_NAME + #ifdef CONFIG_LV_USE_OBJ_NAME + #define LV_USE_OBJ_NAME CONFIG_LV_USE_OBJ_NAME + #else + #define LV_USE_OBJ_NAME 0 + #endif +#endif + +/** 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 @@ -1143,11 +1382,11 @@ #endif #endif -/*Use the builtin obj ID handler functions: +/** Use 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. +* - lv_obj_stringify_id: Return string-ified identifier, 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 @@ -1161,7 +1400,7 @@ #endif #endif -/*Use obj property set/get API*/ +/** Use obj property set/get API. */ #ifndef LV_USE_OBJ_PROPERTY #ifdef CONFIG_LV_USE_OBJ_PROPERTY #define LV_USE_OBJ_PROPERTY CONFIG_LV_USE_OBJ_PROPERTY @@ -1170,7 +1409,7 @@ #endif #endif -/*Enable property name support*/ +/** Enable property name support. */ #ifndef LV_USE_OBJ_PROPERTY_NAME #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_OBJ_PROPERTY_NAME @@ -1183,8 +1422,8 @@ #endif #endif -/* VG-Lite Simulator */ -/*Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ +/* Use VG-Lite Simulator. + * - Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ #ifndef LV_USE_VG_LITE_THORVG #ifdef CONFIG_LV_USE_VG_LITE_THORVG #define LV_USE_VG_LITE_THORVG CONFIG_LV_USE_VG_LITE_THORVG @@ -1194,8 +1433,7 @@ #endif #if LV_USE_VG_LITE_THORVG - - /*Enable LVGL's blend mode support*/ + /** Enable LVGL's blend mode support */ #ifndef LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT #ifdef CONFIG_LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT #define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT CONFIG_LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT @@ -1204,7 +1442,7 @@ #endif #endif - /*Enable YUV color format support*/ + /** Enable YUV color format support */ #ifndef LV_VG_LITE_THORVG_YUV_SUPPORT #ifdef CONFIG_LV_VG_LITE_THORVG_YUV_SUPPORT #define LV_VG_LITE_THORVG_YUV_SUPPORT CONFIG_LV_VG_LITE_THORVG_YUV_SUPPORT @@ -1213,7 +1451,7 @@ #endif #endif - /*Enable Linear gradient extension support*/ + /** 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 @@ -1222,7 +1460,7 @@ #endif #endif - /*Enable 16 pixels alignment*/ + /** Enable alignment on 16 pixels */ #ifndef LV_VG_LITE_THORVG_16PIXELS_ALIGN #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_VG_LITE_THORVG_16PIXELS_ALIGN @@ -1235,7 +1473,7 @@ #endif #endif - /*Buffer address alignment*/ + /** Buffer address alignment */ #ifndef LV_VG_LITE_THORVG_BUF_ADDR_ALIGN #ifdef CONFIG_LV_VG_LITE_THORVG_BUF_ADDR_ALIGN #define LV_VG_LITE_THORVG_BUF_ADDR_ALIGN CONFIG_LV_VG_LITE_THORVG_BUF_ADDR_ALIGN @@ -1244,7 +1482,7 @@ #endif #endif - /*Enable multi-thread render*/ + /** Enable multi-thread render */ #ifndef LV_VG_LITE_THORVG_THREAD_RENDER #ifdef CONFIG_LV_VG_LITE_THORVG_THREAD_RENDER #define LV_VG_LITE_THORVG_THREAD_RENDER CONFIG_LV_VG_LITE_THORVG_THREAD_RENDER @@ -1252,14 +1490,23 @@ #define LV_VG_LITE_THORVG_THREAD_RENDER 0 #endif #endif +#endif +/* Enable the multi-touch gesture recognition feature */ +/* Gesture recognition requires the use of floats */ +#ifndef LV_USE_GESTURE_RECOGNITION + #ifdef CONFIG_LV_USE_GESTURE_RECOGNITION + #define LV_USE_GESTURE_RECOGNITION CONFIG_LV_USE_GESTURE_RECOGNITION + #else + #define LV_USE_GESTURE_RECOGNITION 0 + #endif #endif /*===================== * COMPILER SETTINGS *====================*/ -/*For big endian systems set to 1*/ +/** For big endian systems set to 1 */ #ifndef LV_BIG_ENDIAN_SYSTEM #ifdef CONFIG_LV_BIG_ENDIAN_SYSTEM #define LV_BIG_ENDIAN_SYSTEM CONFIG_LV_BIG_ENDIAN_SYSTEM @@ -1268,7 +1515,7 @@ #endif #endif -/*Define a custom attribute to `lv_tick_inc` function*/ +/** Define a custom attribute for `lv_tick_inc` function */ #ifndef LV_ATTRIBUTE_TICK_INC #ifdef CONFIG_LV_ATTRIBUTE_TICK_INC #define LV_ATTRIBUTE_TICK_INC CONFIG_LV_ATTRIBUTE_TICK_INC @@ -1277,7 +1524,7 @@ #endif #endif -/*Define a custom attribute to `lv_timer_handler` function*/ +/** Define a custom attribute for `lv_timer_handler` function */ #ifndef LV_ATTRIBUTE_TIMER_HANDLER #ifdef CONFIG_LV_ATTRIBUTE_TIMER_HANDLER #define LV_ATTRIBUTE_TIMER_HANDLER CONFIG_LV_ATTRIBUTE_TIMER_HANDLER @@ -1286,7 +1533,7 @@ #endif #endif -/*Define a custom attribute to `lv_display_flush_ready` function*/ +/** Define a custom attribute for `lv_display_flush_ready` function */ #ifndef LV_ATTRIBUTE_FLUSH_READY #ifdef CONFIG_LV_ATTRIBUTE_FLUSH_READY #define LV_ATTRIBUTE_FLUSH_READY CONFIG_LV_ATTRIBUTE_FLUSH_READY @@ -1295,7 +1542,8 @@ #endif #endif -/*Required alignment size for buffers*/ +/** Align VG_LITE buffers on this number of bytes. + * @note vglite_src_buf_aligned() uses this value to validate alignment of passed buffer pointers. */ #ifndef LV_ATTRIBUTE_MEM_ALIGN_SIZE #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_ATTRIBUTE_MEM_ALIGN_SIZE @@ -1308,8 +1556,8 @@ #endif #endif -/*Will be added where memories needs to be aligned (with -Os data might not be aligned to boundary by default). - * E.g. __attribute__((aligned(4)))*/ +/** Will be added where memory needs to be aligned (with -Os data might not be aligned to boundary by default). + * E.g. __attribute__((aligned(4)))*/ #ifndef LV_ATTRIBUTE_MEM_ALIGN #ifdef CONFIG_LV_ATTRIBUTE_MEM_ALIGN #define LV_ATTRIBUTE_MEM_ALIGN CONFIG_LV_ATTRIBUTE_MEM_ALIGN @@ -1318,7 +1566,7 @@ #endif #endif -/*Attribute to mark large constant arrays for example font's bitmaps*/ +/** Attribute to mark large constant arrays, for example for font bitmaps */ #ifndef LV_ATTRIBUTE_LARGE_CONST #ifdef CONFIG_LV_ATTRIBUTE_LARGE_CONST #define LV_ATTRIBUTE_LARGE_CONST CONFIG_LV_ATTRIBUTE_LARGE_CONST @@ -1327,7 +1575,7 @@ #endif #endif -/*Compiler prefix for a big array declaration in RAM*/ +/** Compiler prefix for a large array declaration in RAM */ #ifndef LV_ATTRIBUTE_LARGE_RAM_ARRAY #ifdef CONFIG_LV_ATTRIBUTE_LARGE_RAM_ARRAY #define LV_ATTRIBUTE_LARGE_RAM_ARRAY CONFIG_LV_ATTRIBUTE_LARGE_RAM_ARRAY @@ -1336,7 +1584,7 @@ #endif #endif -/*Place performance critical functions into a faster memory (e.g RAM)*/ +/** Place performance critical functions into a faster memory (e.g RAM) */ #ifndef LV_ATTRIBUTE_FAST_MEM #ifdef CONFIG_LV_ATTRIBUTE_FAST_MEM #define LV_ATTRIBUTE_FAST_MEM CONFIG_LV_ATTRIBUTE_FAST_MEM @@ -1345,17 +1593,17 @@ #endif #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.*/ +/** 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. */ #ifndef LV_EXPORT_CONST_INT #ifdef CONFIG_LV_EXPORT_CONST_INT #define LV_EXPORT_CONST_INT CONFIG_LV_EXPORT_CONST_INT #else - #define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/ + #define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /**< The default value just prevents GCC warning */ #endif #endif -/*Prefix all global extern data with this*/ +/** Prefix all global extern data with this */ #ifndef LV_ATTRIBUTE_EXTERN_DATA #ifdef CONFIG_LV_ATTRIBUTE_EXTERN_DATA #define LV_ATTRIBUTE_EXTERN_DATA CONFIG_LV_ATTRIBUTE_EXTERN_DATA @@ -1364,7 +1612,7 @@ #endif #endif -/* Use `float` as `lv_value_precise_t` */ +/** Use `float` as `lv_value_precise_t` */ #ifndef LV_USE_FLOAT #ifdef CONFIG_LV_USE_FLOAT #define LV_USE_FLOAT CONFIG_LV_USE_FLOAT @@ -1373,8 +1621,8 @@ #endif #endif -/*Enable matrix support - *Requires `LV_USE_FLOAT = 1`*/ +/** 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 @@ -1383,12 +1631,14 @@ #endif #endif -/*Include `lvgl_private.h` in `lvgl.h` to access internal data and functions by default*/ +/** 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 + #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 #endif @@ -1396,8 +1646,8 @@ * FONT USAGE *===================*/ -/*Montserrat fonts with ASCII range and some symbols using bpp = 4 - *https://fonts.google.com/specimen/Montserrat*/ +/* Montserrat fonts with ASCII range and some symbols using bpp = 4 + * https://fonts.google.com/specimen/Montserrat */ #ifndef LV_FONT_MONTSERRAT_8 #ifdef CONFIG_LV_FONT_MONTSERRAT_8 #define LV_FONT_MONTSERRAT_8 CONFIG_LV_FONT_MONTSERRAT_8 @@ -1550,37 +1800,51 @@ #endif #endif -/*Demonstrate special features*/ +/* Demonstrate special features */ #ifndef LV_FONT_MONTSERRAT_28_COMPRESSED #ifdef CONFIG_LV_FONT_MONTSERRAT_28_COMPRESSED #define LV_FONT_MONTSERRAT_28_COMPRESSED CONFIG_LV_FONT_MONTSERRAT_28_COMPRESSED #else - #define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/ + #define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /**< bpp = 3 */ #endif #endif #ifndef LV_FONT_DEJAVU_16_PERSIAN_HEBREW #ifdef CONFIG_LV_FONT_DEJAVU_16_PERSIAN_HEBREW #define LV_FONT_DEJAVU_16_PERSIAN_HEBREW CONFIG_LV_FONT_DEJAVU_16_PERSIAN_HEBREW #else - #define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, Persian letters and all their forms*/ + #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*/ + #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 #else - #define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/ + #define LV_FONT_SIMSUN_16_CJK 0 /**< 1000 most common CJK radicals */ + #endif +#endif +#ifndef LV_FONT_SOURCE_HAN_SANS_SC_14_CJK + #ifdef CONFIG_LV_FONT_SOURCE_HAN_SANS_SC_14_CJK + #define LV_FONT_SOURCE_HAN_SANS_SC_14_CJK CONFIG_LV_FONT_SOURCE_HAN_SANS_SC_14_CJK + #else + #define LV_FONT_SOURCE_HAN_SANS_SC_14_CJK 0 /**< 1338 most common CJK radicals */ + #endif +#endif +#ifndef LV_FONT_SOURCE_HAN_SANS_SC_16_CJK + #ifdef CONFIG_LV_FONT_SOURCE_HAN_SANS_SC_16_CJK + #define LV_FONT_SOURCE_HAN_SANS_SC_16_CJK CONFIG_LV_FONT_SOURCE_HAN_SANS_SC_16_CJK + #else + #define LV_FONT_SOURCE_HAN_SANS_SC_16_CJK 0 /**< 1338 most common CJK radicals */ #endif #endif -/*Pixel perfect monospace fonts*/ +/** Pixel perfect monospaced fonts */ #ifndef LV_FONT_UNSCII_8 #ifdef CONFIG_LV_FONT_UNSCII_8 #define LV_FONT_UNSCII_8 CONFIG_LV_FONT_UNSCII_8 @@ -1596,9 +1860,15 @@ #endif #endif -/*Optionally declare custom fonts here. - *You can use these fonts as default font too and they will be available globally. - *E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/ +/** Optionally declare custom fonts here. + * + * You can use any of these fonts as the default font too and they will be available + * globally. Example: + * + * @code + * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2) + * @endcode + */ #ifndef LV_FONT_CUSTOM_DECLARE #ifdef CONFIG_LV_FONT_CUSTOM_DECLARE #define LV_FONT_CUSTOM_DECLARE CONFIG_LV_FONT_CUSTOM_DECLARE @@ -1607,7 +1877,7 @@ #endif #endif -/*Always set a default font*/ +/** Always set a default font */ #ifndef LV_FONT_DEFAULT #ifdef CONFIG_LV_FONT_DEFAULT #define LV_FONT_DEFAULT CONFIG_LV_FONT_DEFAULT @@ -1616,9 +1886,9 @@ #endif #endif -/*Enable handling large font and/or fonts with a lot of characters. - *The limit depends on the font size, font face and bpp. - *Compiler error will be triggered if a font needs it.*/ +/** Enable handling large font and/or fonts with a lot of characters. + * The limit depends on the font size, font face and bpp. + * A compiler error will be triggered if a font needs it. */ #ifndef LV_FONT_FMT_TXT_LARGE #ifdef CONFIG_LV_FONT_FMT_TXT_LARGE #define LV_FONT_FMT_TXT_LARGE CONFIG_LV_FONT_FMT_TXT_LARGE @@ -1627,7 +1897,7 @@ #endif #endif -/*Enables/disables support for compressed fonts.*/ +/** Enables/disables support for compressed fonts. */ #ifndef LV_USE_FONT_COMPRESSED #ifdef CONFIG_LV_USE_FONT_COMPRESSED #define LV_USE_FONT_COMPRESSED CONFIG_LV_USE_FONT_COMPRESSED @@ -1636,7 +1906,7 @@ #endif #endif -/*Enable drawing placeholders when glyph dsc is not found*/ +/** Enable drawing placeholders when glyph dsc is not found. */ #ifndef LV_USE_FONT_PLACEHOLDER #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_FONT_PLACEHOLDER @@ -1655,7 +1925,7 @@ /** * Select a character encoding for strings. - * Your IDE or editor should have the same character encoding + * Your IDE or editor should have the same character encoding. * - LV_TXT_ENC_UTF8 * - LV_TXT_ENC_ASCII */ @@ -1667,7 +1937,7 @@ #endif #endif -/*Can break (wrap) texts on these chars*/ +/** While rendering text strings, break (wrap) text on these chars. */ #ifndef LV_TXT_BREAK_CHARS #ifdef CONFIG_LV_TXT_BREAK_CHARS #define LV_TXT_BREAK_CHARS CONFIG_LV_TXT_BREAK_CHARS @@ -1676,8 +1946,8 @@ #endif #endif -/*If a word is at least this long, will break wherever "prettiest" - *To disable, set to a value <= 0*/ +/** If a word is at least this long, will break wherever "prettiest". + * To disable, set to a value <= 0. */ #ifndef LV_TXT_LINE_BREAK_LONG_LEN #ifdef CONFIG_LV_TXT_LINE_BREAK_LONG_LEN #define LV_TXT_LINE_BREAK_LONG_LEN CONFIG_LV_TXT_LINE_BREAK_LONG_LEN @@ -1686,8 +1956,8 @@ #endif #endif -/*Minimum number of characters in a long word to put on a line before a break. - *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ +/** Minimum number of characters in a long word to put on a line before a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ #ifndef LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN #ifdef CONFIG_LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN #define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN CONFIG_LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN @@ -1696,8 +1966,8 @@ #endif #endif -/*Minimum number of characters in a long word to put on a line after a break. - *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ +/** Minimum number of characters in a long word to put on a line after a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ #ifndef LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN #ifdef CONFIG_LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN #define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN CONFIG_LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN @@ -1706,9 +1976,9 @@ #endif #endif -/*Support bidirectional texts. Allows mixing Left-to-Right and Right-to-Left texts. - *The direction will be processed according to the Unicode Bidirectional Algorithm: - *https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/ +/** Support bidirectional text. Allows mixing Left-to-Right and Right-to-Left text. + * The direction will be processed according to the Unicode Bidirectional Algorithm: + * https://www.w3.org/International/articles/inline-bidi-markup/uba-basics */ #ifndef LV_USE_BIDI #ifdef CONFIG_LV_USE_BIDI #define LV_USE_BIDI CONFIG_LV_USE_BIDI @@ -1720,7 +1990,7 @@ /*Set the default direction. Supported values: *`LV_BASE_DIR_LTR` Left-to-Right *`LV_BASE_DIR_RTL` Right-to-Left - *`LV_BASE_DIR_AUTO` detect texts base direction*/ + *`LV_BASE_DIR_AUTO` detect text base direction*/ #ifndef LV_BIDI_BASE_DIR_DEF #ifdef CONFIG_LV_BIDI_BASE_DIR_DEF #define LV_BIDI_BASE_DIR_DEF CONFIG_LV_BIDI_BASE_DIR_DEF @@ -1730,8 +2000,8 @@ #endif #endif -/*Enable Arabic/Persian processing - *In these languages characters should be replaced with another form based on their position in the text*/ +/** Enable Arabic/Persian processing + * 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 @@ -1740,12 +2010,27 @@ #endif #endif +/*The control character to use for signaling text recoloring*/ +#ifndef LV_TXT_COLOR_CMD + #ifdef CONFIG_LV_TXT_COLOR_CMD + #define LV_TXT_COLOR_CMD CONFIG_LV_TXT_COLOR_CMD + #else + #define LV_TXT_COLOR_CMD "#" + #endif +#endif + /*================== * WIDGETS *================*/ +/* Documentation for widgets can be found here: https://docs.lvgl.io/master/details/widgets/index.html . */ -/*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/ - +/** 1: Causes these widgets to be given default values at creation time. + * - lv_buttonmatrix_t: Get default maps: {"Btn1", "Btn2", "Btn3", "\n", "Btn4", "Btn5", ""}, else map not set. + * - lv_checkbox_t : String label set to "Check box", else set to empty string. + * - lv_dropdown_t : Options set to "Option 1", "Option 2", "Option 3", else no values are set. + * - lv_roller_t : Options set to "Option 1", "Option 2", "Option 3", "Option 4", "Option 5", else no values are set. + * - lv_label_t : Text set to "Text", else empty string. + * */ #ifndef LV_WIDGETS_HAS_DEFAULT_VALUE #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_WIDGETS_HAS_DEFAULT_VALUE @@ -1937,7 +2222,7 @@ #define LV_USE_DROPDOWN 0 #endif #else - #define LV_USE_DROPDOWN 1 /*Requires: lv_label*/ + #define LV_USE_DROPDOWN 1 /**< Requires: lv_label */ #endif #endif @@ -1949,7 +2234,7 @@ #define LV_USE_IMAGE 0 #endif #else - #define LV_USE_IMAGE 1 /*Requires: lv_label*/ + #define LV_USE_IMAGE 1 /**< Requires: lv_label */ #endif #endif @@ -1997,7 +2282,7 @@ #define LV_LABEL_TEXT_SELECTION 0 #endif #else - #define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/ + #define LV_LABEL_TEXT_SELECTION 1 /**< Enable selecting text of the label */ #endif #endif #ifndef LV_LABEL_LONG_TXT_HINT @@ -2008,14 +2293,14 @@ #define LV_LABEL_LONG_TXT_HINT 0 #endif #else - #define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/ + #define LV_LABEL_LONG_TXT_HINT 1 /**< Store some extra info in labels to speed up drawing of very long text */ #endif #endif #ifndef LV_LABEL_WAIT_CHAR_COUNT #ifdef CONFIG_LV_LABEL_WAIT_CHAR_COUNT #define LV_LABEL_WAIT_CHAR_COUNT CONFIG_LV_LABEL_WAIT_CHAR_COUNT #else - #define LV_LABEL_WAIT_CHAR_COUNT 3 /*The count of wait chart*/ + #define LV_LABEL_WAIT_CHAR_COUNT 3 /**< The count of wait chart */ #endif #endif #endif @@ -2060,7 +2345,7 @@ #ifdef CONFIG_LV_USE_LOTTIE #define LV_USE_LOTTIE CONFIG_LV_USE_LOTTIE #else - #define LV_USE_LOTTIE 0 /*Requires: lv_canvas, thorvg */ + #define LV_USE_LOTTIE 0 /**< Requires: lv_canvas, thorvg */ #endif #endif @@ -2096,7 +2381,7 @@ #define LV_USE_ROLLER 0 #endif #else - #define LV_USE_ROLLER 1 /*Requires: lv_label*/ + #define LV_USE_ROLLER 1 /**< Requires: lv_label */ #endif #endif @@ -2120,7 +2405,7 @@ #define LV_USE_SLIDER 0 #endif #else - #define LV_USE_SLIDER 1 /*Requires: lv_bar*/ + #define LV_USE_SLIDER 1 /**< Requires: lv_bar */ #endif #endif @@ -2136,7 +2421,7 @@ #endif #endif #if LV_USE_SPAN - /*A line text can contain maximum num of span descriptor */ + /** A line of text can contain this maximum number of span descriptors. */ #ifndef LV_SPAN_SNIPPET_STACK_SIZE #ifdef CONFIG_LV_SPAN_SNIPPET_STACK_SIZE #define LV_SPAN_SNIPPET_STACK_SIZE CONFIG_LV_SPAN_SNIPPET_STACK_SIZE @@ -2182,27 +2467,6 @@ #endif #endif -#ifndef LV_USE_TEXTAREA - #ifdef LV_KCONFIG_PRESENT - #ifdef CONFIG_LV_USE_TEXTAREA - #define LV_USE_TEXTAREA CONFIG_LV_USE_TEXTAREA - #else - #define LV_USE_TEXTAREA 0 - #endif - #else - #define LV_USE_TEXTAREA 1 /*Requires: lv_label*/ - #endif -#endif -#if LV_USE_TEXTAREA != 0 - #ifndef LV_TEXTAREA_DEF_PWD_SHOW_TIME - #ifdef CONFIG_LV_TEXTAREA_DEF_PWD_SHOW_TIME - #define LV_TEXTAREA_DEF_PWD_SHOW_TIME CONFIG_LV_TEXTAREA_DEF_PWD_SHOW_TIME - #else - #define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/ - #endif - #endif -#endif - #ifndef LV_USE_TABLE #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_TABLE @@ -2227,6 +2491,27 @@ #endif #endif +#ifndef LV_USE_TEXTAREA + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_TEXTAREA + #define LV_USE_TEXTAREA CONFIG_LV_USE_TEXTAREA + #else + #define LV_USE_TEXTAREA 0 + #endif + #else + #define LV_USE_TEXTAREA 1 /**< Requires: lv_label */ + #endif +#endif +#if LV_USE_TEXTAREA != 0 + #ifndef LV_TEXTAREA_DEF_PWD_SHOW_TIME + #ifdef CONFIG_LV_TEXTAREA_DEF_PWD_SHOW_TIME + #define LV_TEXTAREA_DEF_PWD_SHOW_TIME CONFIG_LV_TEXTAREA_DEF_PWD_SHOW_TIME + #else + #define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /**< [ms] */ + #endif + #endif +#endif + #ifndef LV_USE_TILEVIEW #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_TILEVIEW @@ -2251,11 +2536,20 @@ #endif #endif +#ifndef LV_USE_3DTEXTURE + #ifdef CONFIG_LV_USE_3DTEXTURE + #define LV_USE_3DTEXTURE CONFIG_LV_USE_3DTEXTURE + #else + #define LV_USE_3DTEXTURE 0 + #endif +#endif + /*================== * THEMES *==================*/ +/* Documentation for themes can be found here: https://docs.lvgl.io/master/details/common-widget-features/styles/style.html#themes . */ -/*A simple, impressive and very complete theme*/ +/** A simple, impressive and very complete theme */ #ifndef LV_USE_THEME_DEFAULT #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_THEME_DEFAULT @@ -2268,8 +2562,7 @@ #endif #endif #if LV_USE_THEME_DEFAULT - - /*0: Light mode; 1: Dark mode*/ + /** 0: Light mode; 1: Dark mode */ #ifndef LV_THEME_DEFAULT_DARK #ifdef CONFIG_LV_THEME_DEFAULT_DARK #define LV_THEME_DEFAULT_DARK CONFIG_LV_THEME_DEFAULT_DARK @@ -2278,7 +2571,7 @@ #endif #endif - /*1: Enable grow on press*/ + /** 1: Enable grow on press */ #ifndef LV_THEME_DEFAULT_GROW #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_THEME_DEFAULT_GROW @@ -2291,7 +2584,7 @@ #endif #endif - /*Default transition time in [ms]*/ + /** Default transition time in ms. */ #ifndef LV_THEME_DEFAULT_TRANSITION_TIME #ifdef CONFIG_LV_THEME_DEFAULT_TRANSITION_TIME #define LV_THEME_DEFAULT_TRANSITION_TIME CONFIG_LV_THEME_DEFAULT_TRANSITION_TIME @@ -2301,7 +2594,7 @@ #endif #endif /*LV_USE_THEME_DEFAULT*/ -/*A very simple theme that is a good starting point for a custom theme*/ +/** A very simple theme that is a good starting point for a custom theme */ #ifndef LV_USE_THEME_SIMPLE #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_THEME_SIMPLE @@ -2314,7 +2607,7 @@ #endif #endif -/*A theme designed for monochrome displays*/ +/** A theme designed for monochrome displays */ #ifndef LV_USE_THEME_MONO #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_THEME_MONO @@ -2330,8 +2623,9 @@ /*================== * LAYOUTS *==================*/ +/* Documentation for layouts can be found here: https://docs.lvgl.io/master/details/common-widget-features/layouts/index.html . */ -/*A layout similar to Flexbox in CSS.*/ +/** A layout similar to Flexbox in CSS. */ #ifndef LV_USE_FLEX #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_FLEX @@ -2344,7 +2638,7 @@ #endif #endif -/*A layout similar to Grid in CSS.*/ +/** A layout similar to Grid in CSS. */ #ifndef LV_USE_GRID #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_GRID @@ -2360,19 +2654,22 @@ /*==================== * 3RD PARTS LIBRARIES *====================*/ +/* Documentation for libraries can be found here: https://docs.lvgl.io/master/details/libs/index.html . */ -/*File system interfaces for common APIs */ +/* 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 +/** Setting a default driver letter allows skipping the driver prefix in filepaths. + * Documentation about how to use the below driver-identifier letters can be found at + * https://docs.lvgl.io/master/details/main-modules/fs.html#lv-fs-identifier-letters . */ +#ifndef LV_FS_DEFAULT_DRIVER_LETTER + #ifdef CONFIG_LV_FS_DEFAULT_DRIVER_LETTER + #define LV_FS_DEFAULT_DRIVER_LETTER CONFIG_LV_FS_DEFAULT_DRIVER_LETTER #else - #define LV_FS_DEFAULT_DRIVE_LETTER '\0' + #define LV_FS_DEFAULT_DRIVER_LETTER '\0' #endif #endif -/*API for fopen, fread, etc*/ +/** API for fopen, fread, etc. */ #ifndef LV_USE_FS_STDIO #ifdef CONFIG_LV_USE_FS_STDIO #define LV_USE_FS_STDIO CONFIG_LV_USE_FS_STDIO @@ -2385,26 +2682,26 @@ #ifdef CONFIG_LV_FS_STDIO_LETTER #define LV_FS_STDIO_LETTER CONFIG_LV_FS_STDIO_LETTER #else - #define LV_FS_STDIO_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_STDIO_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ #endif #endif #ifndef LV_FS_STDIO_PATH #ifdef CONFIG_LV_FS_STDIO_PATH #define LV_FS_STDIO_PATH CONFIG_LV_FS_STDIO_PATH #else - #define LV_FS_STDIO_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ + #define LV_FS_STDIO_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ #endif #endif #ifndef LV_FS_STDIO_CACHE_SIZE #ifdef CONFIG_LV_FS_STDIO_CACHE_SIZE #define LV_FS_STDIO_CACHE_SIZE CONFIG_LV_FS_STDIO_CACHE_SIZE #else - #define LV_FS_STDIO_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ + #define LV_FS_STDIO_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ #endif #endif #endif -/*API for open, read, etc*/ +/** API for open, read, etc. */ #ifndef LV_USE_FS_POSIX #ifdef CONFIG_LV_USE_FS_POSIX #define LV_USE_FS_POSIX CONFIG_LV_USE_FS_POSIX @@ -2417,26 +2714,26 @@ #ifdef CONFIG_LV_FS_POSIX_LETTER #define LV_FS_POSIX_LETTER CONFIG_LV_FS_POSIX_LETTER #else - #define LV_FS_POSIX_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_POSIX_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ #endif #endif #ifndef LV_FS_POSIX_PATH #ifdef CONFIG_LV_FS_POSIX_PATH #define LV_FS_POSIX_PATH CONFIG_LV_FS_POSIX_PATH #else - #define LV_FS_POSIX_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ + #define LV_FS_POSIX_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ #endif #endif #ifndef LV_FS_POSIX_CACHE_SIZE #ifdef CONFIG_LV_FS_POSIX_CACHE_SIZE #define LV_FS_POSIX_CACHE_SIZE CONFIG_LV_FS_POSIX_CACHE_SIZE #else - #define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ + #define LV_FS_POSIX_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ #endif #endif #endif -/*API for CreateFile, ReadFile, etc*/ +/** API for CreateFile, ReadFile, etc. */ #ifndef LV_USE_FS_WIN32 #ifdef CONFIG_LV_USE_FS_WIN32 #define LV_USE_FS_WIN32 CONFIG_LV_USE_FS_WIN32 @@ -2449,26 +2746,26 @@ #ifdef CONFIG_LV_FS_WIN32_LETTER #define LV_FS_WIN32_LETTER CONFIG_LV_FS_WIN32_LETTER #else - #define LV_FS_WIN32_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_WIN32_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ #endif #endif #ifndef LV_FS_WIN32_PATH #ifdef CONFIG_LV_FS_WIN32_PATH #define LV_FS_WIN32_PATH CONFIG_LV_FS_WIN32_PATH #else - #define LV_FS_WIN32_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ + #define LV_FS_WIN32_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ #endif #endif #ifndef LV_FS_WIN32_CACHE_SIZE #ifdef CONFIG_LV_FS_WIN32_CACHE_SIZE #define LV_FS_WIN32_CACHE_SIZE CONFIG_LV_FS_WIN32_CACHE_SIZE #else - #define LV_FS_WIN32_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ + #define LV_FS_WIN32_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ #endif #endif #endif -/*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/ +/** API for FATFS (needs to be added separately). Uses f_open, f_read, etc. */ #ifndef LV_USE_FS_FATFS #ifdef CONFIG_LV_USE_FS_FATFS #define LV_USE_FS_FATFS CONFIG_LV_USE_FS_FATFS @@ -2481,19 +2778,26 @@ #ifdef CONFIG_LV_FS_FATFS_LETTER #define LV_FS_FATFS_LETTER CONFIG_LV_FS_FATFS_LETTER #else - #define LV_FS_FATFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_FATFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #endif + #endif + #ifndef LV_FS_FATFS_PATH + #ifdef CONFIG_LV_FS_FATFS_PATH + #define LV_FS_FATFS_PATH CONFIG_LV_FS_FATFS_PATH + #else + #define LV_FS_FATFS_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ #endif #endif #ifndef LV_FS_FATFS_CACHE_SIZE #ifdef CONFIG_LV_FS_FATFS_CACHE_SIZE #define LV_FS_FATFS_CACHE_SIZE CONFIG_LV_FS_FATFS_CACHE_SIZE #else - #define LV_FS_FATFS_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ + #define LV_FS_FATFS_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ #endif #endif #endif -/*API for memory-mapped file access. */ +/** API for memory-mapped file access. */ #ifndef LV_USE_FS_MEMFS #ifdef CONFIG_LV_USE_FS_MEMFS #define LV_USE_FS_MEMFS CONFIG_LV_USE_FS_MEMFS @@ -2506,12 +2810,12 @@ #ifdef CONFIG_LV_FS_MEMFS_LETTER #define LV_FS_MEMFS_LETTER CONFIG_LV_FS_MEMFS_LETTER #else - #define LV_FS_MEMFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_MEMFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ #endif #endif #endif -/*API for LittleFs. */ +/** API for LittleFs. */ #ifndef LV_USE_FS_LITTLEFS #ifdef CONFIG_LV_USE_FS_LITTLEFS #define LV_USE_FS_LITTLEFS CONFIG_LV_USE_FS_LITTLEFS @@ -2524,12 +2828,19 @@ #ifdef CONFIG_LV_FS_LITTLEFS_LETTER #define LV_FS_LITTLEFS_LETTER CONFIG_LV_FS_LITTLEFS_LETTER #else - #define LV_FS_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_LITTLEFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #endif + #endif + #ifndef LV_FS_LITTLEFS_PATH + #ifdef CONFIG_LV_FS_LITTLEFS_PATH + #define LV_FS_LITTLEFS_PATH CONFIG_LV_FS_LITTLEFS_PATH + #else + #define LV_FS_LITTLEFS_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ #endif #endif #endif -/*API for Arduino LittleFs. */ +/** 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 @@ -2542,12 +2853,19 @@ #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')*/ + #define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #endif + #endif + #ifndef LV_FS_ARDUINO_ESP_LITTLEFS_PATH + #ifdef CONFIG_LV_FS_ARDUINO_ESP_LITTLEFS_PATH + #define LV_FS_ARDUINO_ESP_LITTLEFS_PATH CONFIG_LV_FS_ARDUINO_ESP_LITTLEFS_PATH + #else + #define LV_FS_ARDUINO_ESP_LITTLEFS_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ #endif #endif #endif -/*API for Arduino Sd. */ +/** 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 @@ -2560,12 +2878,37 @@ #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')*/ + #define LV_FS_ARDUINO_SD_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #endif + #endif + #ifndef LV_FS_ARDUINO_SD_PATH + #ifdef CONFIG_LV_FS_ARDUINO_SD_PATH + #define LV_FS_ARDUINO_SD_PATH CONFIG_LV_FS_ARDUINO_SD_PATH + #else + #define LV_FS_ARDUINO_SD_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ #endif #endif #endif -/*LODEPNG decoder library*/ +/** API for UEFI */ +#ifndef LV_USE_FS_UEFI + #ifdef CONFIG_LV_USE_FS_UEFI + #define LV_USE_FS_UEFI CONFIG_LV_USE_FS_UEFI + #else + #define LV_USE_FS_UEFI 0 + #endif +#endif +#if LV_USE_FS_UEFI + #ifndef LV_FS_UEFI_LETTER + #ifdef CONFIG_LV_FS_UEFI_LETTER + #define LV_FS_UEFI_LETTER CONFIG_LV_FS_UEFI_LETTER + #else + #define LV_FS_UEFI_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #endif + #endif +#endif + +/** LODEPNG decoder library */ #ifndef LV_USE_LODEPNG #ifdef CONFIG_LV_USE_LODEPNG #define LV_USE_LODEPNG CONFIG_LV_USE_LODEPNG @@ -2574,7 +2917,7 @@ #endif #endif -/*PNG decoder(libpng) library*/ +/** PNG decoder(libpng) library */ #ifndef LV_USE_LIBPNG #ifdef CONFIG_LV_USE_LIBPNG #define LV_USE_LIBPNG CONFIG_LV_USE_LIBPNG @@ -2583,7 +2926,7 @@ #endif #endif -/*BMP decoder library*/ +/** BMP decoder library */ #ifndef LV_USE_BMP #ifdef CONFIG_LV_USE_BMP #define LV_USE_BMP CONFIG_LV_USE_BMP @@ -2592,8 +2935,8 @@ #endif #endif -/* JPG + split JPG decoder library. - * Split JPG is a custom format optimized for embedded systems. */ +/** JPG + split JPG decoder library. + * Split JPG is a custom format optimized for embedded systems. */ #ifndef LV_USE_TJPGD #ifdef CONFIG_LV_USE_TJPGD #define LV_USE_TJPGD CONFIG_LV_USE_TJPGD @@ -2602,8 +2945,8 @@ #endif #endif -/* libjpeg-turbo decoder library. - * Supports complete JPEG specifications and high-performance JPEG decoding. */ +/** libjpeg-turbo decoder library. + * - Supports complete JPEG specifications and high-performance JPEG decoding. */ #ifndef LV_USE_LIBJPEG_TURBO #ifdef CONFIG_LV_USE_LIBJPEG_TURBO #define LV_USE_LIBJPEG_TURBO CONFIG_LV_USE_LIBJPEG_TURBO @@ -2612,7 +2955,7 @@ #endif #endif -/*GIF decoder library*/ +/** GIF decoder library */ #ifndef LV_USE_GIF #ifdef CONFIG_LV_USE_GIF #define LV_USE_GIF CONFIG_LV_USE_GIF @@ -2621,7 +2964,7 @@ #endif #endif #if LV_USE_GIF - /*GIF decoder accelerate*/ + /** 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 @@ -2632,7 +2975,7 @@ #endif -/*Decode bin images to RAM*/ +/** Decode bin images to RAM */ #ifndef LV_BIN_DECODER_RAM_LOAD #ifdef CONFIG_LV_BIN_DECODER_RAM_LOAD #define LV_BIN_DECODER_RAM_LOAD CONFIG_LV_BIN_DECODER_RAM_LOAD @@ -2641,7 +2984,7 @@ #endif #endif -/*RLE decompress library*/ +/** RLE decompress library */ #ifndef LV_USE_RLE #ifdef CONFIG_LV_USE_RLE #define LV_USE_RLE CONFIG_LV_USE_RLE @@ -2650,7 +2993,7 @@ #endif #endif -/*QR code library*/ +/** QR code library */ #ifndef LV_USE_QRCODE #ifdef CONFIG_LV_USE_QRCODE #define LV_USE_QRCODE CONFIG_LV_USE_QRCODE @@ -2659,7 +3002,7 @@ #endif #endif -/*Barcode code library*/ +/** Barcode code library */ #ifndef LV_USE_BARCODE #ifdef CONFIG_LV_USE_BARCODE #define LV_USE_BARCODE CONFIG_LV_USE_BARCODE @@ -2668,7 +3011,7 @@ #endif #endif -/*FreeType library*/ +/** FreeType library */ #ifndef LV_USE_FREETYPE #ifdef CONFIG_LV_USE_FREETYPE #define LV_USE_FREETYPE CONFIG_LV_USE_FREETYPE @@ -2677,7 +3020,7 @@ #endif #endif #if LV_USE_FREETYPE - /*Let FreeType to use LVGL memory and file porting*/ + /** Let FreeType use LVGL memory and file porting */ #ifndef LV_FREETYPE_USE_LVGL_PORT #ifdef CONFIG_LV_FREETYPE_USE_LVGL_PORT #define LV_FREETYPE_USE_LVGL_PORT CONFIG_LV_FREETYPE_USE_LVGL_PORT @@ -2686,8 +3029,8 @@ #endif #endif - /*Cache count of the glyphs in FreeType. It means the number of glyphs that can be cached. - *The higher the value, the more memory will be used.*/ + /** Cache count of glyphs in FreeType, i.e. number of glyphs that can be cached. + * The higher the value, the more memory will be used. */ #ifndef LV_FREETYPE_CACHE_FT_GLYPH_CNT #ifdef CONFIG_LV_FREETYPE_CACHE_FT_GLYPH_CNT #define LV_FREETYPE_CACHE_FT_GLYPH_CNT CONFIG_LV_FREETYPE_CACHE_FT_GLYPH_CNT @@ -2697,7 +3040,7 @@ #endif #endif -/* Built-in TTF decoder */ +/** Built-in TTF decoder */ #ifndef LV_USE_TINY_TTF #ifdef CONFIG_LV_USE_TINY_TTF #define LV_USE_TINY_TTF CONFIG_LV_USE_TINY_TTF @@ -2723,7 +3066,7 @@ #endif #endif -/*Rlottie library*/ +/** Rlottie library */ #ifndef LV_USE_RLOTTIE #ifdef CONFIG_LV_USE_RLOTTIE #define LV_USE_RLOTTIE CONFIG_LV_USE_RLOTTIE @@ -2732,8 +3075,8 @@ #endif #endif -/*Enable Vector Graphic APIs - *Requires `LV_USE_MATRIX = 1`*/ +/** 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 @@ -2742,7 +3085,7 @@ #endif #endif -/* Enable ThorVG (vector graphics library) from the src/libs folder */ +/** Enable ThorVG (vector graphics library) from the src/libs folder */ #ifndef LV_USE_THORVG_INTERNAL #ifdef CONFIG_LV_USE_THORVG_INTERNAL #define LV_USE_THORVG_INTERNAL CONFIG_LV_USE_THORVG_INTERNAL @@ -2751,7 +3094,7 @@ #endif #endif -/* Enable ThorVG by assuming that its installed and linked to the project */ +/** Enable ThorVG by assuming that its installed and linked to the project */ #ifndef LV_USE_THORVG_EXTERNAL #ifdef CONFIG_LV_USE_THORVG_EXTERNAL #define LV_USE_THORVG_EXTERNAL CONFIG_LV_USE_THORVG_EXTERNAL @@ -2760,7 +3103,7 @@ #endif #endif -/*Use lvgl built-in LZ4 lib*/ +/** Use lvgl built-in LZ4 lib */ #ifndef LV_USE_LZ4_INTERNAL #ifdef CONFIG_LV_USE_LZ4_INTERNAL #define LV_USE_LZ4_INTERNAL CONFIG_LV_USE_LZ4_INTERNAL @@ -2769,7 +3112,7 @@ #endif #endif -/*Use external LZ4 library*/ +/** Use external LZ4 library */ #ifndef LV_USE_LZ4_EXTERNAL #ifdef CONFIG_LV_USE_LZ4_EXTERNAL #define LV_USE_LZ4_EXTERNAL CONFIG_LV_USE_LZ4_EXTERNAL @@ -2778,8 +3121,32 @@ #endif #endif -/*FFmpeg library for image decoding and playing videos - *Supports all major image formats so do not enable other image decoder with it*/ +/*SVG library + * - Requires `LV_USE_VECTOR_GRAPHIC = 1` */ +#ifndef LV_USE_SVG + #ifdef CONFIG_LV_USE_SVG + #define LV_USE_SVG CONFIG_LV_USE_SVG + #else + #define LV_USE_SVG 0 + #endif +#endif +#ifndef LV_USE_SVG_ANIMATION + #ifdef CONFIG_LV_USE_SVG_ANIMATION + #define LV_USE_SVG_ANIMATION CONFIG_LV_USE_SVG_ANIMATION + #else + #define LV_USE_SVG_ANIMATION 0 + #endif +#endif +#ifndef LV_USE_SVG_DEBUG + #ifdef CONFIG_LV_USE_SVG_DEBUG + #define LV_USE_SVG_DEBUG CONFIG_LV_USE_SVG_DEBUG + #else + #define LV_USE_SVG_DEBUG 0 + #endif +#endif + +/** FFmpeg library for image decoding and playing videos. + * Supports all major image formats so do not enable other image decoder with it. */ #ifndef LV_USE_FFMPEG #ifdef CONFIG_LV_USE_FFMPEG #define LV_USE_FFMPEG CONFIG_LV_USE_FFMPEG @@ -2788,7 +3155,7 @@ #endif #endif #if LV_USE_FFMPEG - /*Dump input information to stderr*/ + /** Dump input information to stderr */ #ifndef LV_FFMPEG_DUMP_FORMAT #ifdef CONFIG_LV_FFMPEG_DUMP_FORMAT #define LV_FFMPEG_DUMP_FORMAT CONFIG_LV_FFMPEG_DUMP_FORMAT @@ -2796,13 +3163,24 @@ #define LV_FFMPEG_DUMP_FORMAT 0 #endif #endif + /** Use lvgl file path in FFmpeg Player widget + * You won't be able to open URLs after enabling this feature. + * Note that FFmpeg image decoder will always use lvgl file system. */ + #ifndef LV_FFMPEG_PLAYER_USE_LV_FS + #ifdef CONFIG_LV_FFMPEG_PLAYER_USE_LV_FS + #define LV_FFMPEG_PLAYER_USE_LV_FS CONFIG_LV_FFMPEG_PLAYER_USE_LV_FS + #else + #define LV_FFMPEG_PLAYER_USE_LV_FS 0 + #endif + #endif #endif /*================== * OTHERS *==================*/ +/* Documentation for several of the below items can be found here: https://docs.lvgl.io/master/details/auxiliary-modules/index.html . */ -/*1: Enable API to take snapshot for object*/ +/** 1: Enable API to take snapshot for object */ #ifndef LV_USE_SNAPSHOT #ifdef CONFIG_LV_USE_SNAPSHOT #define LV_USE_SNAPSHOT CONFIG_LV_USE_SNAPSHOT @@ -2811,7 +3189,7 @@ #endif #endif -/*1: Enable system monitor component*/ +/** 1: Enable system monitor component */ #ifndef LV_USE_SYSMON #ifdef CONFIG_LV_USE_SYSMON #define LV_USE_SYSMON CONFIG_LV_USE_SYSMON @@ -2820,17 +3198,17 @@ #endif #endif #if LV_USE_SYSMON - /*Get the idle percentage. E.g. uint32_t my_get_idle(void);*/ + /** Get the idle percentage. E.g. uint32_t my_get_idle(void); */ #ifndef LV_SYSMON_GET_IDLE #ifdef CONFIG_LV_SYSMON_GET_IDLE #define LV_SYSMON_GET_IDLE CONFIG_LV_SYSMON_GET_IDLE #else - #define LV_SYSMON_GET_IDLE lv_timer_get_idle + #define LV_SYSMON_GET_IDLE lv_os_get_idle_percent #endif #endif - /*1: Show CPU usage and FPS count - * Requires `LV_USE_SYSMON = 1`*/ + /** 1: Show CPU usage and FPS count. + * - Requires `LV_USE_SYSMON = 1` */ #ifndef LV_USE_PERF_MONITOR #ifdef CONFIG_LV_USE_PERF_MONITOR #define LV_USE_PERF_MONITOR CONFIG_LV_USE_PERF_MONITOR @@ -2847,7 +3225,7 @@ #endif #endif - /*0: Displays performance data on the screen, 1: Prints performance data using log.*/ + /** 0: Displays performance data on the screen; 1: Prints performance data using log. */ #ifndef LV_USE_PERF_MONITOR_LOG_MODE #ifdef CONFIG_LV_USE_PERF_MONITOR_LOG_MODE #define LV_USE_PERF_MONITOR_LOG_MODE CONFIG_LV_USE_PERF_MONITOR_LOG_MODE @@ -2857,9 +3235,9 @@ #endif #endif - /*1: Show the used memory and the memory fragmentation - * Requires `LV_USE_STDLIB_MALLOC = LV_STDLIB_BUILTIN` - * Requires `LV_USE_SYSMON = 1`*/ + /** 1: Show used memory and memory fragmentation. + * - Requires `LV_USE_STDLIB_MALLOC = LV_STDLIB_BUILTIN` + * - Requires `LV_USE_SYSMON = 1`*/ #ifndef LV_USE_MEM_MONITOR #ifdef CONFIG_LV_USE_MEM_MONITOR #define LV_USE_MEM_MONITOR CONFIG_LV_USE_MEM_MONITOR @@ -2876,10 +3254,9 @@ #endif #endif #endif - #endif /*LV_USE_SYSMON*/ -/*1: Enable the runtime performance profiler*/ +/** 1: Enable runtime performance profiler */ #ifndef LV_USE_PROFILER #ifdef CONFIG_LV_USE_PROFILER #define LV_USE_PROFILER CONFIG_LV_USE_PROFILER @@ -2888,7 +3265,7 @@ #endif #endif #if LV_USE_PROFILER - /*1: Enable the built-in profiler*/ + /** 1: Enable the built-in profiler */ #ifndef LV_USE_PROFILER_BUILTIN #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_PROFILER_BUILTIN @@ -2901,17 +3278,28 @@ #endif #endif #if LV_USE_PROFILER_BUILTIN - /*Default profiler trace buffer size*/ + /** Default profiler trace buffer size */ #ifndef LV_PROFILER_BUILTIN_BUF_SIZE #ifdef CONFIG_LV_PROFILER_BUILTIN_BUF_SIZE #define LV_PROFILER_BUILTIN_BUF_SIZE CONFIG_LV_PROFILER_BUILTIN_BUF_SIZE #else - #define LV_PROFILER_BUILTIN_BUF_SIZE (16 * 1024) /*[bytes]*/ + #define LV_PROFILER_BUILTIN_BUF_SIZE (16 * 1024) /**< [bytes] */ + #endif + #endif + #ifndef LV_PROFILER_BUILTIN_DEFAULT_ENABLE + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_BUILTIN_DEFAULT_ENABLE + #define LV_PROFILER_BUILTIN_DEFAULT_ENABLE CONFIG_LV_PROFILER_BUILTIN_DEFAULT_ENABLE + #else + #define LV_PROFILER_BUILTIN_DEFAULT_ENABLE 0 + #endif + #else + #define LV_PROFILER_BUILTIN_DEFAULT_ENABLE 1 #endif #endif #endif - /*Header to include for the profiler*/ + /** Header to include for profiler */ #ifndef LV_PROFILER_INCLUDE #ifdef CONFIG_LV_PROFILER_INCLUDE #define LV_PROFILER_INCLUDE CONFIG_LV_PROFILER_INCLUDE @@ -2920,7 +3308,7 @@ #endif #endif - /*Profiler start point function*/ + /** Profiler start point function */ #ifndef LV_PROFILER_BEGIN #ifdef CONFIG_LV_PROFILER_BEGIN #define LV_PROFILER_BEGIN CONFIG_LV_PROFILER_BEGIN @@ -2929,7 +3317,7 @@ #endif #endif - /*Profiler end point function*/ + /** Profiler end point function */ #ifndef LV_PROFILER_END #ifdef CONFIG_LV_PROFILER_END #define LV_PROFILER_END CONFIG_LV_PROFILER_END @@ -2938,7 +3326,7 @@ #endif #endif - /*Profiler start point function with custom tag*/ + /** Profiler start point function with custom tag */ #ifndef LV_PROFILER_BEGIN_TAG #ifdef CONFIG_LV_PROFILER_BEGIN_TAG #define LV_PROFILER_BEGIN_TAG CONFIG_LV_PROFILER_BEGIN_TAG @@ -2947,7 +3335,7 @@ #endif #endif - /*Profiler end point function with custom tag*/ + /** Profiler end point function with custom tag */ #ifndef LV_PROFILER_END_TAG #ifdef CONFIG_LV_PROFILER_END_TAG #define LV_PROFILER_END_TAG CONFIG_LV_PROFILER_END_TAG @@ -2955,9 +3343,148 @@ #define LV_PROFILER_END_TAG LV_PROFILER_BUILTIN_END_TAG #endif #endif + + /*Enable layout profiler*/ + #ifndef LV_PROFILER_LAYOUT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_LAYOUT + #define LV_PROFILER_LAYOUT CONFIG_LV_PROFILER_LAYOUT + #else + #define LV_PROFILER_LAYOUT 0 + #endif + #else + #define LV_PROFILER_LAYOUT 1 + #endif + #endif + + /*Enable disp refr profiler*/ + #ifndef LV_PROFILER_REFR + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_REFR + #define LV_PROFILER_REFR CONFIG_LV_PROFILER_REFR + #else + #define LV_PROFILER_REFR 0 + #endif + #else + #define LV_PROFILER_REFR 1 + #endif + #endif + + /*Enable draw profiler*/ + #ifndef LV_PROFILER_DRAW + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_DRAW + #define LV_PROFILER_DRAW CONFIG_LV_PROFILER_DRAW + #else + #define LV_PROFILER_DRAW 0 + #endif + #else + #define LV_PROFILER_DRAW 1 + #endif + #endif + + /*Enable indev profiler*/ + #ifndef LV_PROFILER_INDEV + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_INDEV + #define LV_PROFILER_INDEV CONFIG_LV_PROFILER_INDEV + #else + #define LV_PROFILER_INDEV 0 + #endif + #else + #define LV_PROFILER_INDEV 1 + #endif + #endif + + /*Enable decoder profiler*/ + #ifndef LV_PROFILER_DECODER + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_DECODER + #define LV_PROFILER_DECODER CONFIG_LV_PROFILER_DECODER + #else + #define LV_PROFILER_DECODER 0 + #endif + #else + #define LV_PROFILER_DECODER 1 + #endif + #endif + + /*Enable font profiler*/ + #ifndef LV_PROFILER_FONT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_FONT + #define LV_PROFILER_FONT CONFIG_LV_PROFILER_FONT + #else + #define LV_PROFILER_FONT 0 + #endif + #else + #define LV_PROFILER_FONT 1 + #endif + #endif + + /*Enable fs profiler*/ + #ifndef LV_PROFILER_FS + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_FS + #define LV_PROFILER_FS CONFIG_LV_PROFILER_FS + #else + #define LV_PROFILER_FS 0 + #endif + #else + #define LV_PROFILER_FS 1 + #endif + #endif + + /*Enable style profiler*/ + #ifndef LV_PROFILER_STYLE + #ifdef CONFIG_LV_PROFILER_STYLE + #define LV_PROFILER_STYLE CONFIG_LV_PROFILER_STYLE + #else + #define LV_PROFILER_STYLE 0 + #endif + #endif + + /*Enable timer profiler*/ + #ifndef LV_PROFILER_TIMER + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_TIMER + #define LV_PROFILER_TIMER CONFIG_LV_PROFILER_TIMER + #else + #define LV_PROFILER_TIMER 0 + #endif + #else + #define LV_PROFILER_TIMER 1 + #endif + #endif + + /*Enable cache profiler*/ + #ifndef LV_PROFILER_CACHE + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_CACHE + #define LV_PROFILER_CACHE CONFIG_LV_PROFILER_CACHE + #else + #define LV_PROFILER_CACHE 0 + #endif + #else + #define LV_PROFILER_CACHE 1 + #endif + #endif + + /*Enable event profiler*/ + #ifndef LV_PROFILER_EVENT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_PROFILER_EVENT + #define LV_PROFILER_EVENT CONFIG_LV_PROFILER_EVENT + #else + #define LV_PROFILER_EVENT 0 + #endif + #else + #define LV_PROFILER_EVENT 1 + #endif + #endif #endif -/*1: Enable Monkey test*/ +/** 1: Enable Monkey test */ #ifndef LV_USE_MONKEY #ifdef CONFIG_LV_USE_MONKEY #define LV_USE_MONKEY CONFIG_LV_USE_MONKEY @@ -2966,7 +3493,7 @@ #endif #endif -/*1: Enable grid navigation*/ +/** 1: Enable grid navigation */ #ifndef LV_USE_GRIDNAV #ifdef CONFIG_LV_USE_GRIDNAV #define LV_USE_GRIDNAV CONFIG_LV_USE_GRIDNAV @@ -2975,7 +3502,7 @@ #endif #endif -/*1: Enable lv_obj fragment*/ +/** 1: Enable `lv_obj` fragment logic */ #ifndef LV_USE_FRAGMENT #ifdef CONFIG_LV_USE_FRAGMENT #define LV_USE_FRAGMENT CONFIG_LV_USE_FRAGMENT @@ -2984,7 +3511,7 @@ #endif #endif -/*1: Support using images as font in label or span widgets */ +/** 1: Support using images as font in label or span widgets */ #ifndef LV_USE_IMGFONT #ifdef CONFIG_LV_USE_IMGFONT #define LV_USE_IMGFONT CONFIG_LV_USE_IMGFONT @@ -2993,7 +3520,7 @@ #endif #endif -/*1: Enable an observer pattern implementation*/ +/** 1: Enable an observer pattern implementation */ #ifndef LV_USE_OBSERVER #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_USE_OBSERVER @@ -3006,8 +3533,8 @@ #endif #endif -/*1: Enable Pinyin input method*/ -/*Requires: lv_keyboard*/ +/** 1: Enable Pinyin input method + * - Requires: lv_keyboard */ #ifndef LV_USE_IME_PINYIN #ifdef CONFIG_LV_USE_IME_PINYIN #define LV_USE_IME_PINYIN CONFIG_LV_USE_IME_PINYIN @@ -3016,8 +3543,8 @@ #endif #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 thesaurus*/ + /** 1: Use default thesaurus. + * @note 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 CONFIG_LV_IME_PINYIN_USE_DEFAULT_DICT @@ -3029,8 +3556,8 @@ #define LV_IME_PINYIN_USE_DEFAULT_DICT 1 #endif #endif - /*Set the maximum number of candidate panels that can be displayed*/ - /*This needs to be adjusted according to the size of the screen*/ + /** Set maximum number of candidate panels that can be displayed. + * @note This needs to be adjusted according to size of screen. */ #ifndef LV_IME_PINYIN_CAND_TEXT_NUM #ifdef CONFIG_LV_IME_PINYIN_CAND_TEXT_NUM #define LV_IME_PINYIN_CAND_TEXT_NUM CONFIG_LV_IME_PINYIN_CAND_TEXT_NUM @@ -3039,7 +3566,7 @@ #endif #endif - /*Use 9 key input(k9)*/ + /** Use 9-key input (k9). */ #ifndef LV_IME_PINYIN_USE_K9_MODE #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_IME_PINYIN_USE_K9_MODE @@ -3062,8 +3589,8 @@ #endif /*LV_IME_PINYIN_USE_K9_MODE*/ #endif -/*1: Enable file explorer*/ -/*Requires: lv_table*/ +/** 1: Enable file explorer. + * - Requires: lv_table */ #ifndef LV_USE_FILE_EXPLORER #ifdef CONFIG_LV_USE_FILE_EXPLORER #define LV_USE_FILE_EXPLORER CONFIG_LV_USE_FILE_EXPLORER @@ -3072,7 +3599,7 @@ #endif #endif #if LV_USE_FILE_EXPLORER - /*Maximum length of path*/ + /** Maximum length of path */ #ifndef LV_FILE_EXPLORER_PATH_MAX_LEN #ifdef CONFIG_LV_FILE_EXPLORER_PATH_MAX_LEN #define LV_FILE_EXPLORER_PATH_MAX_LEN CONFIG_LV_FILE_EXPLORER_PATH_MAX_LEN @@ -3080,8 +3607,8 @@ #define LV_FILE_EXPLORER_PATH_MAX_LEN (128) #endif #endif - /*Quick access bar, 1:use, 0:not use*/ - /*Requires: lv_list*/ + /** Quick access bar, 1:use, 0:do not use. + * - Requires: lv_list */ #ifndef LV_FILE_EXPLORER_QUICK_ACCESS #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_FILE_EXPLORER_QUICK_ACCESS @@ -3095,11 +3622,70 @@ #endif #endif +/** 1: Enable Font manager */ +#ifndef LV_USE_FONT_MANAGER + #ifdef CONFIG_LV_USE_FONT_MANAGER + #define LV_USE_FONT_MANAGER CONFIG_LV_USE_FONT_MANAGER + #else + #define LV_USE_FONT_MANAGER 0 + #endif +#endif +#if LV_USE_FONT_MANAGER + +/**Font manager name max length*/ +#ifndef LV_FONT_MANAGER_NAME_MAX_LEN + #ifdef CONFIG_LV_FONT_MANAGER_NAME_MAX_LEN + #define LV_FONT_MANAGER_NAME_MAX_LEN CONFIG_LV_FONT_MANAGER_NAME_MAX_LEN + #else + #define LV_FONT_MANAGER_NAME_MAX_LEN 32 + #endif +#endif + +#endif + +/** Enable emulated input devices, time emulation, and screenshot compares. */ +#ifndef LV_USE_TEST + #ifdef CONFIG_LV_USE_TEST + #define LV_USE_TEST CONFIG_LV_USE_TEST + #else + #define LV_USE_TEST 0 + #endif +#endif +#if LV_USE_TEST + +/** Enable `lv_test_screenshot_compare`. + * Requires libpng and a few MB of extra RAM. */ +#ifndef LV_USE_TEST_SCREENSHOT_COMPARE + #ifdef CONFIG_LV_USE_TEST_SCREENSHOT_COMPARE + #define LV_USE_TEST_SCREENSHOT_COMPARE CONFIG_LV_USE_TEST_SCREENSHOT_COMPARE + #else + #define LV_USE_TEST_SCREENSHOT_COMPARE 0 + #endif +#endif +#endif /*LV_USE_TEST*/ + +/** Enable loading XML UIs runtime */ +#ifndef LV_USE_XML + #ifdef CONFIG_LV_USE_XML + #define LV_USE_XML CONFIG_LV_USE_XML + #else + #define LV_USE_XML 0 + #endif +#endif + +/*1: Enable color filter style*/ +#ifndef LV_USE_COLOR_FILTER + #ifdef CONFIG_LV_USE_COLOR_FILTER + #define LV_USE_COLOR_FILTER CONFIG_LV_USE_COLOR_FILTER + #else + #define LV_USE_COLOR_FILTER 0 + #endif +#endif /*================== * DEVICES *==================*/ -/*Use SDL to open window on PC and handle mouse and keyboard*/ +/** Use SDL to open window on PC and handle mouse and keyboard. */ #ifndef LV_USE_SDL #ifdef CONFIG_LV_USE_SDL #define LV_USE_SDL CONFIG_LV_USE_SDL @@ -3119,7 +3705,7 @@ #ifdef CONFIG_LV_SDL_RENDER_MODE #define LV_SDL_RENDER_MODE CONFIG_LV_SDL_RENDER_MODE #else - #define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /*LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance*/ + #define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /**< LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance */ #endif #endif #ifndef LV_SDL_BUF_COUNT @@ -3130,7 +3716,7 @@ #define LV_SDL_BUF_COUNT 0 #endif #else - #define LV_SDL_BUF_COUNT 1 /*1 or 2*/ + #define LV_SDL_BUF_COUNT 1 /**< 1 or 2 */ #endif #endif #ifndef LV_SDL_ACCELERATED @@ -3141,14 +3727,14 @@ #define LV_SDL_ACCELERATED 0 #endif #else - #define LV_SDL_ACCELERATED 1 /*1: Use hardware acceleration*/ + #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 #else - #define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/ + #define LV_SDL_FULLSCREEN 0 /**< 1: Make the window full screen by default */ #endif #endif #ifndef LV_SDL_DIRECT_EXIT @@ -3159,7 +3745,7 @@ #define LV_SDL_DIRECT_EXIT 0 #endif #else - #define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL windows are closed*/ + #define LV_SDL_DIRECT_EXIT 1 /**< 1: Exit the application when all SDL windows are closed */ #endif #endif #ifndef LV_SDL_MOUSEWHEEL_MODE @@ -3171,7 +3757,7 @@ #endif #endif -/*Use X11 to open window on Linux desktop and handle mouse and keyboard*/ +/** Use X11 to open window on Linux desktop and handle mouse and keyboard */ #ifndef LV_USE_X11 #ifdef CONFIG_LV_USE_X11 #define LV_USE_X11 CONFIG_LV_USE_X11 @@ -3188,7 +3774,7 @@ #define LV_X11_DIRECT_EXIT 0 #endif #else - #define LV_X11_DIRECT_EXIT 1 /*Exit the application when all X11 windows have been closed*/ + #define LV_X11_DIRECT_EXIT 1 /**< Exit application when all X11 windows have been closed */ #endif #endif #ifndef LV_X11_DOUBLE_BUFFER @@ -3199,10 +3785,10 @@ #define LV_X11_DOUBLE_BUFFER 0 #endif #else - #define LV_X11_DOUBLE_BUFFER 1 /*Use double buffers for rendering*/ + #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!)*/ + /* 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 CONFIG_LV_X11_RENDER_MODE_PARTIAL @@ -3211,26 +3797,26 @@ #define LV_X11_RENDER_MODE_PARTIAL 0 #endif #else - #define LV_X11_RENDER_MODE_PARTIAL 1 /*Partial render mode (preferred)*/ + #define LV_X11_RENDER_MODE_PARTIAL 1 /**< Partial render mode (preferred) */ #endif #endif #ifndef LV_X11_RENDER_MODE_DIRECT #ifdef CONFIG_LV_X11_RENDER_MODE_DIRECT #define LV_X11_RENDER_MODE_DIRECT CONFIG_LV_X11_RENDER_MODE_DIRECT #else - #define LV_X11_RENDER_MODE_DIRECT 0 /*direct render mode*/ + #define LV_X11_RENDER_MODE_DIRECT 0 /**< Direct render mode */ #endif #endif #ifndef LV_X11_RENDER_MODE_FULL #ifdef CONFIG_LV_X11_RENDER_MODE_FULL #define LV_X11_RENDER_MODE_FULL CONFIG_LV_X11_RENDER_MODE_FULL #else - #define LV_X11_RENDER_MODE_FULL 0 /*Full render mode*/ + #define LV_X11_RENDER_MODE_FULL 0 /**< Full render mode */ #endif #endif #endif -/*Use Wayland to open a window and handle input on Linux or BSD desktops */ +/** 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 @@ -3239,23 +3825,49 @@ #endif #endif #if LV_USE_WAYLAND + #ifndef LV_WAYLAND_BUF_COUNT + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_WAYLAND_BUF_COUNT + #define LV_WAYLAND_BUF_COUNT CONFIG_LV_WAYLAND_BUF_COUNT + #else + #define LV_WAYLAND_BUF_COUNT 0 + #endif + #else + #define LV_WAYLAND_BUF_COUNT 1 /**< Use 1 for single buffer with partial render mode or 2 for double buffer with full render mode*/ + #endif + #endif + #ifndef LV_WAYLAND_USE_DMABUF + #ifdef CONFIG_LV_WAYLAND_USE_DMABUF + #define LV_WAYLAND_USE_DMABUF CONFIG_LV_WAYLAND_USE_DMABUF + #else + #define LV_WAYLAND_USE_DMABUF 0 /**< Use DMA buffers for frame buffers. Requires LV_DRAW_USE_G2D */ + #endif + #endif + #ifndef LV_WAYLAND_RENDER_MODE + #ifdef CONFIG_LV_WAYLAND_RENDER_MODE + #define LV_WAYLAND_RENDER_MODE CONFIG_LV_WAYLAND_RENDER_MODE + #else + #define LV_WAYLAND_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL /**< DMABUF supports LV_DISPLAY_RENDER_MODE_FULL and LV_DISPLAY_RENDER_MODE_DIRECT*/ + #endif + #endif + /**< When LV_WAYLAND_USE_DMABUF is disabled, only LV_DISPLAY_RENDER_MODE_PARTIAL is supported*/ #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*/ + #define LV_WAYLAND_WINDOW_DECORATIONS 0 /**< Draw client side window decorations only necessary on Mutter/GNOME. Not supported using DMABUF*/ #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*/ + #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*/ +/** Driver for /dev/fb */ #ifndef LV_USE_LINUX_FBDEV #ifdef CONFIG_LV_USE_LINUX_FBDEV #define LV_USE_LINUX_FBDEV CONFIG_LV_USE_LINUX_FBDEV @@ -3292,9 +3904,20 @@ #define LV_LINUX_FBDEV_BUFFER_SIZE 60 #endif #endif + #ifndef LV_LINUX_FBDEV_MMAP + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_LINUX_FBDEV_MMAP + #define LV_LINUX_FBDEV_MMAP CONFIG_LV_LINUX_FBDEV_MMAP + #else + #define LV_LINUX_FBDEV_MMAP 0 + #endif + #else + #define LV_LINUX_FBDEV_MMAP 1 + #endif + #endif #endif -/*Use Nuttx to open window and handle touchscreen*/ +/** Use Nuttx to open window and handle touchscreen */ #ifndef LV_USE_NUTTX #ifdef CONFIG_LV_USE_NUTTX #define LV_USE_NUTTX CONFIG_LV_USE_NUTTX @@ -3304,6 +3927,23 @@ #endif #if LV_USE_NUTTX + #ifndef LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP + #ifdef CONFIG_LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP + #define LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP CONFIG_LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP + #else + #define LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP 0 + #endif + #endif + + /** Use independent image heap for default draw buffer */ + #ifndef LV_NUTTX_DEFAULT_DRAW_BUF_USE_INDEPENDENT_IMAGE_HEAP + #ifdef CONFIG_LV_NUTTX_DEFAULT_DRAW_BUF_USE_INDEPENDENT_IMAGE_HEAP + #define LV_NUTTX_DEFAULT_DRAW_BUF_USE_INDEPENDENT_IMAGE_HEAP CONFIG_LV_NUTTX_DEFAULT_DRAW_BUF_USE_INDEPENDENT_IMAGE_HEAP + #else + #define LV_NUTTX_DEFAULT_DRAW_BUF_USE_INDEPENDENT_IMAGE_HEAP 0 + #endif + #endif + #ifndef LV_USE_NUTTX_LIBUV #ifdef CONFIG_LV_USE_NUTTX_LIBUV #define LV_USE_NUTTX_LIBUV CONFIG_LV_USE_NUTTX_LIBUV @@ -3312,7 +3952,7 @@ #endif #endif - /*Use Nuttx custom init API to open window and handle touchscreen*/ + /** Use Nuttx custom init API to open window and handle touchscreen */ #ifndef LV_USE_NUTTX_CUSTOM_INIT #ifdef CONFIG_LV_USE_NUTTX_CUSTOM_INIT #define LV_USE_NUTTX_CUSTOM_INIT CONFIG_LV_USE_NUTTX_CUSTOM_INIT @@ -3321,7 +3961,7 @@ #endif #endif - /*Driver for /dev/lcd*/ + /** Driver for /dev/lcd */ #ifndef LV_USE_NUTTX_LCD #ifdef CONFIG_LV_USE_NUTTX_LCD #define LV_USE_NUTTX_LCD CONFIG_LV_USE_NUTTX_LCD @@ -3346,7 +3986,7 @@ #endif #endif - /*Driver for /dev/input*/ + /** Driver for /dev/input */ #ifndef LV_USE_NUTTX_TOUCHSCREEN #ifdef CONFIG_LV_USE_NUTTX_TOUCHSCREEN #define LV_USE_NUTTX_TOUCHSCREEN CONFIG_LV_USE_NUTTX_TOUCHSCREEN @@ -3355,9 +3995,17 @@ #endif #endif + /*Touchscreen cursor size in pixels(<=0: disable cursor)*/ + #ifndef LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE + #ifdef CONFIG_LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE + #define LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE CONFIG_LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE + #else + #define LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE 0 + #endif + #endif #endif -/*Driver for /dev/dri/card*/ +/** Driver for /dev/dri/card */ #ifndef LV_USE_LINUX_DRM #ifdef CONFIG_LV_USE_LINUX_DRM #define LV_USE_LINUX_DRM CONFIG_LV_USE_LINUX_DRM @@ -3366,7 +4014,22 @@ #endif #endif -/*Interface for TFT_eSPI*/ +#if LV_USE_LINUX_DRM + + /* Use the MESA GBM library to allocate DMA buffers that can be + * shared across sub-systems and libraries using the Linux DMA-BUF API. + * The GBM library aims to provide a platform independent memory management system + * it supports the major GPU vendors - This option requires linking with libgbm */ + #ifndef LV_LINUX_DRM_GBM_BUFFERS + #ifdef CONFIG_LV_LINUX_DRM_GBM_BUFFERS + #define LV_LINUX_DRM_GBM_BUFFERS CONFIG_LV_LINUX_DRM_GBM_BUFFERS + #else + #define LV_LINUX_DRM_GBM_BUFFERS 0 + #endif + #endif +#endif + +/** Interface for TFT_eSPI */ #ifndef LV_USE_TFT_ESPI #ifdef CONFIG_LV_USE_TFT_ESPI #define LV_USE_TFT_ESPI CONFIG_LV_USE_TFT_ESPI @@ -3375,7 +4038,7 @@ #endif #endif -/*Driver for evdev input devices*/ +/** Driver for evdev input devices */ #ifndef LV_USE_EVDEV #ifdef CONFIG_LV_USE_EVDEV #define LV_USE_EVDEV CONFIG_LV_USE_EVDEV @@ -3384,7 +4047,7 @@ #endif #endif -/*Driver for libinput input devices*/ +/** Driver for libinput input devices */ #ifndef LV_USE_LIBINPUT #ifdef CONFIG_LV_USE_LIBINPUT #define LV_USE_LIBINPUT CONFIG_LV_USE_LIBINPUT @@ -3402,7 +4065,7 @@ #endif #endif - /*Full keyboard support*/ + /** Full keyboard support */ #ifndef LV_LIBINPUT_XKB #ifdef CONFIG_LV_LIBINPUT_XKB #define LV_LIBINPUT_XKB CONFIG_LV_LIBINPUT_XKB @@ -3411,7 +4074,7 @@ #endif #endif #if LV_LIBINPUT_XKB - /*"setxkbmap -query" can help find the right values for your keyboard*/ + /** "setxkbmap -query" can help find the right values for your keyboard */ #ifndef LV_LIBINPUT_XKB_KEY_MAP #ifdef CONFIG_LV_LIBINPUT_XKB_KEY_MAP #define LV_LIBINPUT_XKB_KEY_MAP CONFIG_LV_LIBINPUT_XKB_KEY_MAP @@ -3422,7 +4085,7 @@ #endif #endif -/*Drivers for LCD devices connected via SPI/parallel port*/ +/* Drivers for LCD devices connected via SPI/parallel port */ #ifndef LV_USE_ST7735 #ifdef CONFIG_LV_USE_ST7735 #define LV_USE_ST7735 CONFIG_LV_USE_ST7735 @@ -3451,16 +4114,37 @@ #define LV_USE_ILI9341 0 #endif #endif - -#ifndef LV_USE_GENERIC_MIPI - #ifdef CONFIG_LV_USE_GENERIC_MIPI - #define LV_USE_GENERIC_MIPI CONFIG_LV_USE_GENERIC_MIPI +#ifndef LV_USE_FT81X + #ifdef CONFIG_LV_USE_FT81X + #define LV_USE_FT81X CONFIG_LV_USE_FT81X #else - #define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) + #define LV_USE_FT81X 0 #endif #endif -/*Driver for Renesas GLCD*/ +#if (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) + #ifndef LV_USE_GENERIC_MIPI + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_USE_GENERIC_MIPI + #define LV_USE_GENERIC_MIPI CONFIG_LV_USE_GENERIC_MIPI + #else + #define LV_USE_GENERIC_MIPI 0 + #endif + #else + #define LV_USE_GENERIC_MIPI 1 + #endif + #endif +#else + #ifndef LV_USE_GENERIC_MIPI + #ifdef CONFIG_LV_USE_GENERIC_MIPI + #define LV_USE_GENERIC_MIPI CONFIG_LV_USE_GENERIC_MIPI + #else + #define LV_USE_GENERIC_MIPI 0 + #endif + #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 @@ -3469,7 +4153,26 @@ #endif #endif -/* LVGL Windows backend */ +/** Driver for ST LTDC */ +#ifndef LV_USE_ST_LTDC + #ifdef CONFIG_LV_USE_ST_LTDC + #define LV_USE_ST_LTDC CONFIG_LV_USE_ST_LTDC + #else + #define LV_USE_ST_LTDC 0 + #endif +#endif +#if LV_USE_ST_LTDC + /* Only used for partial. */ + #ifndef LV_ST_LTDC_USE_DMA2D_FLUSH + #ifdef CONFIG_LV_ST_LTDC_USE_DMA2D_FLUSH + #define LV_ST_LTDC_USE_DMA2D_FLUSH CONFIG_LV_ST_LTDC_USE_DMA2D_FLUSH + #else + #define LV_ST_LTDC_USE_DMA2D_FLUSH 0 + #endif + #endif +#endif + +/** LVGL Windows backend */ #ifndef LV_USE_WINDOWS #ifdef CONFIG_LV_USE_WINDOWS #define LV_USE_WINDOWS CONFIG_LV_USE_WINDOWS @@ -3478,7 +4181,32 @@ #endif #endif -/* Use OpenGL to open window on PC and handle mouse and keyboard */ +/** LVGL UEFI backend */ +#ifndef LV_USE_UEFI + #ifdef CONFIG_LV_USE_UEFI + #define LV_USE_UEFI CONFIG_LV_USE_UEFI + #else + #define LV_USE_UEFI 0 + #endif +#endif +#if LV_USE_UEFI + #ifndef LV_USE_UEFI_INCLUDE + #ifdef CONFIG_LV_USE_UEFI_INCLUDE + #define LV_USE_UEFI_INCLUDE CONFIG_LV_USE_UEFI_INCLUDE + #else + #define LV_USE_UEFI_INCLUDE "myefi.h" /**< Header that hides the actual framework (EDK2, gnu-efi, ...) */ + #endif + #endif + #ifndef LV_UEFI_USE_MEMORY_SERVICES + #ifdef CONFIG_LV_UEFI_USE_MEMORY_SERVICES + #define LV_UEFI_USE_MEMORY_SERVICES CONFIG_LV_UEFI_USE_MEMORY_SERVICES + #else + #define LV_UEFI_USE_MEMORY_SERVICES 0 /**< Use the memory functions from the boot services table */ + #endif + #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 @@ -3495,12 +4223,12 @@ #define LV_USE_OPENGLES_DEBUG 0 #endif #else - #define LV_USE_OPENGLES_DEBUG 1 /* Enable or disable debug for opengles */ + #define LV_USE_OPENGLES_DEBUG 1 /**< Enable or disable debug for opengles */ #endif #endif #endif -/* QNX Screen display and input drivers */ +/** QNX Screen display and input drivers */ #ifndef LV_USE_QNX #ifdef CONFIG_LV_USE_QNX #define LV_USE_QNX CONFIG_LV_USE_QNX @@ -3517,16 +4245,16 @@ #define LV_QNX_BUF_COUNT 0 #endif #else - #define LV_QNX_BUF_COUNT 1 /*1 or 2*/ + #define LV_QNX_BUF_COUNT 1 /**< 1 or 2 */ #endif #endif #endif -/*================== -* EXAMPLES -*==================*/ +/*===================== +* BUILD OPTIONS +*======================*/ -/*Enable the examples to be built with the library*/ +/** Enable examples to be built with the library. */ #ifndef LV_BUILD_EXAMPLES #ifdef LV_KCONFIG_PRESENT #ifdef CONFIG_LV_BUILD_EXAMPLES @@ -3539,145 +4267,212 @@ #endif #endif +/** Build the demos */ +#ifndef LV_BUILD_DEMOS + #ifdef LV_KCONFIG_PRESENT + #ifdef CONFIG_LV_BUILD_DEMOS + #define LV_BUILD_DEMOS CONFIG_LV_BUILD_DEMOS + #else + #define LV_BUILD_DEMOS 0 + #endif + #else + #define LV_BUILD_DEMOS 1 + #endif +#endif + /*=================== * DEMO USAGE ====================*/ -/*Show some widget. It might be required to increase `LV_MEM_SIZE` */ -#ifndef LV_USE_DEMO_WIDGETS - #ifdef CONFIG_LV_USE_DEMO_WIDGETS - #define LV_USE_DEMO_WIDGETS CONFIG_LV_USE_DEMO_WIDGETS - #else - #define LV_USE_DEMO_WIDGETS 0 - #endif -#endif - -/*Demonstrate the usage of encoder and keyboard*/ -#ifndef LV_USE_DEMO_KEYPAD_AND_ENCODER - #ifdef CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER - #define LV_USE_DEMO_KEYPAD_AND_ENCODER CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER - #else - #define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 - #endif -#endif - -/*Benchmark your system*/ -#ifndef LV_USE_DEMO_BENCHMARK - #ifdef CONFIG_LV_USE_DEMO_BENCHMARK - #define LV_USE_DEMO_BENCHMARK CONFIG_LV_USE_DEMO_BENCHMARK - #else - #define LV_USE_DEMO_BENCHMARK 0 - #endif -#endif - -/*Render test for each primitives. Requires at least 480x272 display*/ -#ifndef LV_USE_DEMO_RENDER - #ifdef CONFIG_LV_USE_DEMO_RENDER - #define LV_USE_DEMO_RENDER CONFIG_LV_USE_DEMO_RENDER - #else - #define LV_USE_DEMO_RENDER 0 - #endif -#endif - -/*Stress test for LVGL*/ -#ifndef LV_USE_DEMO_STRESS - #ifdef CONFIG_LV_USE_DEMO_STRESS - #define LV_USE_DEMO_STRESS CONFIG_LV_USE_DEMO_STRESS - #else - #define LV_USE_DEMO_STRESS 0 - #endif -#endif - -/*Music player demo*/ -#ifndef LV_USE_DEMO_MUSIC - #ifdef CONFIG_LV_USE_DEMO_MUSIC - #define LV_USE_DEMO_MUSIC CONFIG_LV_USE_DEMO_MUSIC - #else - #define LV_USE_DEMO_MUSIC 0 - #endif -#endif -#if LV_USE_DEMO_MUSIC - #ifndef LV_DEMO_MUSIC_SQUARE - #ifdef CONFIG_LV_DEMO_MUSIC_SQUARE - #define LV_DEMO_MUSIC_SQUARE CONFIG_LV_DEMO_MUSIC_SQUARE +#if LV_BUILD_DEMOS + /** Show some widgets. This might be required to increase `LV_MEM_SIZE`. */ + #ifndef LV_USE_DEMO_WIDGETS + #ifdef CONFIG_LV_USE_DEMO_WIDGETS + #define LV_USE_DEMO_WIDGETS CONFIG_LV_USE_DEMO_WIDGETS #else - #define LV_DEMO_MUSIC_SQUARE 0 + #define LV_USE_DEMO_WIDGETS 0 #endif #endif - #ifndef LV_DEMO_MUSIC_LANDSCAPE - #ifdef CONFIG_LV_DEMO_MUSIC_LANDSCAPE - #define LV_DEMO_MUSIC_LANDSCAPE CONFIG_LV_DEMO_MUSIC_LANDSCAPE + + /** Demonstrate usage of encoder and keyboard. */ + #ifndef LV_USE_DEMO_KEYPAD_AND_ENCODER + #ifdef CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER + #define LV_USE_DEMO_KEYPAD_AND_ENCODER CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER #else - #define LV_DEMO_MUSIC_LANDSCAPE 0 + #define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 #endif #endif - #ifndef LV_DEMO_MUSIC_ROUND - #ifdef CONFIG_LV_DEMO_MUSIC_ROUND - #define LV_DEMO_MUSIC_ROUND CONFIG_LV_DEMO_MUSIC_ROUND + + /** Benchmark your system */ + #ifndef LV_USE_DEMO_BENCHMARK + #ifdef CONFIG_LV_USE_DEMO_BENCHMARK + #define LV_USE_DEMO_BENCHMARK CONFIG_LV_USE_DEMO_BENCHMARK #else - #define LV_DEMO_MUSIC_ROUND 0 + #define LV_USE_DEMO_BENCHMARK 0 #endif #endif - #ifndef LV_DEMO_MUSIC_LARGE - #ifdef CONFIG_LV_DEMO_MUSIC_LARGE - #define LV_DEMO_MUSIC_LARGE CONFIG_LV_DEMO_MUSIC_LARGE - #else - #define LV_DEMO_MUSIC_LARGE 0 + + #if LV_USE_DEMO_BENCHMARK + /** Use fonts where bitmaps are aligned 16 byte and has Nx16 byte stride */ + #ifndef LV_DEMO_BENCHMARK_ALIGNED_FONTS + #ifdef CONFIG_LV_DEMO_BENCHMARK_ALIGNED_FONTS + #define LV_DEMO_BENCHMARK_ALIGNED_FONTS CONFIG_LV_DEMO_BENCHMARK_ALIGNED_FONTS + #else + #define LV_DEMO_BENCHMARK_ALIGNED_FONTS 0 + #endif #endif #endif - #ifndef LV_DEMO_MUSIC_AUTO_PLAY - #ifdef CONFIG_LV_DEMO_MUSIC_AUTO_PLAY - #define LV_DEMO_MUSIC_AUTO_PLAY CONFIG_LV_DEMO_MUSIC_AUTO_PLAY + + /** Render test for each primitive. + * - Requires at least 480x272 display. */ + #ifndef LV_USE_DEMO_RENDER + #ifdef CONFIG_LV_USE_DEMO_RENDER + #define LV_USE_DEMO_RENDER CONFIG_LV_USE_DEMO_RENDER #else - #define LV_DEMO_MUSIC_AUTO_PLAY 0 + #define LV_USE_DEMO_RENDER 0 #endif #endif -#endif - -/*Flex layout demo*/ -#ifndef LV_USE_DEMO_FLEX_LAYOUT - #ifdef CONFIG_LV_USE_DEMO_FLEX_LAYOUT - #define LV_USE_DEMO_FLEX_LAYOUT CONFIG_LV_USE_DEMO_FLEX_LAYOUT - #else - #define LV_USE_DEMO_FLEX_LAYOUT 0 + + /** Stress test for LVGL */ + #ifndef LV_USE_DEMO_STRESS + #ifdef CONFIG_LV_USE_DEMO_STRESS + #define LV_USE_DEMO_STRESS CONFIG_LV_USE_DEMO_STRESS + #else + #define LV_USE_DEMO_STRESS 0 + #endif #endif -#endif - -/*Smart-phone like multi-language demo*/ -#ifndef LV_USE_DEMO_MULTILANG - #ifdef CONFIG_LV_USE_DEMO_MULTILANG - #define LV_USE_DEMO_MULTILANG CONFIG_LV_USE_DEMO_MULTILANG - #else - #define LV_USE_DEMO_MULTILANG 0 + + /** Music player demo */ + #ifndef LV_USE_DEMO_MUSIC + #ifdef CONFIG_LV_USE_DEMO_MUSIC + #define LV_USE_DEMO_MUSIC CONFIG_LV_USE_DEMO_MUSIC + #else + #define LV_USE_DEMO_MUSIC 0 + #endif #endif -#endif - -/*Widget transformation demo*/ -#ifndef LV_USE_DEMO_TRANSFORM - #ifdef CONFIG_LV_USE_DEMO_TRANSFORM - #define LV_USE_DEMO_TRANSFORM CONFIG_LV_USE_DEMO_TRANSFORM - #else - #define LV_USE_DEMO_TRANSFORM 0 + #if LV_USE_DEMO_MUSIC + #ifndef LV_DEMO_MUSIC_SQUARE + #ifdef CONFIG_LV_DEMO_MUSIC_SQUARE + #define LV_DEMO_MUSIC_SQUARE CONFIG_LV_DEMO_MUSIC_SQUARE + #else + #define LV_DEMO_MUSIC_SQUARE 0 + #endif + #endif + #ifndef LV_DEMO_MUSIC_LANDSCAPE + #ifdef CONFIG_LV_DEMO_MUSIC_LANDSCAPE + #define LV_DEMO_MUSIC_LANDSCAPE CONFIG_LV_DEMO_MUSIC_LANDSCAPE + #else + #define LV_DEMO_MUSIC_LANDSCAPE 0 + #endif + #endif + #ifndef LV_DEMO_MUSIC_ROUND + #ifdef CONFIG_LV_DEMO_MUSIC_ROUND + #define LV_DEMO_MUSIC_ROUND CONFIG_LV_DEMO_MUSIC_ROUND + #else + #define LV_DEMO_MUSIC_ROUND 0 + #endif + #endif + #ifndef LV_DEMO_MUSIC_LARGE + #ifdef CONFIG_LV_DEMO_MUSIC_LARGE + #define LV_DEMO_MUSIC_LARGE CONFIG_LV_DEMO_MUSIC_LARGE + #else + #define LV_DEMO_MUSIC_LARGE 0 + #endif + #endif + #ifndef LV_DEMO_MUSIC_AUTO_PLAY + #ifdef CONFIG_LV_DEMO_MUSIC_AUTO_PLAY + #define LV_DEMO_MUSIC_AUTO_PLAY CONFIG_LV_DEMO_MUSIC_AUTO_PLAY + #else + #define LV_DEMO_MUSIC_AUTO_PLAY 0 + #endif + #endif #endif -#endif - -/*Demonstrate scroll settings*/ -#ifndef LV_USE_DEMO_SCROLL - #ifdef CONFIG_LV_USE_DEMO_SCROLL - #define LV_USE_DEMO_SCROLL CONFIG_LV_USE_DEMO_SCROLL - #else - #define LV_USE_DEMO_SCROLL 0 + + /** Vector graphic demo */ + #ifndef LV_USE_DEMO_VECTOR_GRAPHIC + #ifdef CONFIG_LV_USE_DEMO_VECTOR_GRAPHIC + #define LV_USE_DEMO_VECTOR_GRAPHIC CONFIG_LV_USE_DEMO_VECTOR_GRAPHIC + #else + #define LV_USE_DEMO_VECTOR_GRAPHIC 0 + #endif #endif -#endif - -/*Vector graphic demo*/ -#ifndef LV_USE_DEMO_VECTOR_GRAPHIC - #ifdef CONFIG_LV_USE_DEMO_VECTOR_GRAPHIC - #define LV_USE_DEMO_VECTOR_GRAPHIC CONFIG_LV_USE_DEMO_VECTOR_GRAPHIC - #else - #define LV_USE_DEMO_VECTOR_GRAPHIC 0 + + /*--------------------------- + * Demos from lvgl/lv_demos + ---------------------------*/ + + /** Flex layout demo */ + #ifndef LV_USE_DEMO_FLEX_LAYOUT + #ifdef CONFIG_LV_USE_DEMO_FLEX_LAYOUT + #define LV_USE_DEMO_FLEX_LAYOUT CONFIG_LV_USE_DEMO_FLEX_LAYOUT + #else + #define LV_USE_DEMO_FLEX_LAYOUT 0 + #endif #endif -#endif + + /** Smart-phone like multi-language demo */ + #ifndef LV_USE_DEMO_MULTILANG + #ifdef CONFIG_LV_USE_DEMO_MULTILANG + #define LV_USE_DEMO_MULTILANG CONFIG_LV_USE_DEMO_MULTILANG + #else + #define LV_USE_DEMO_MULTILANG 0 + #endif + #endif + + /** Widget transformation demo */ + #ifndef LV_USE_DEMO_TRANSFORM + #ifdef CONFIG_LV_USE_DEMO_TRANSFORM + #define LV_USE_DEMO_TRANSFORM CONFIG_LV_USE_DEMO_TRANSFORM + #else + #define LV_USE_DEMO_TRANSFORM 0 + #endif + #endif + + /** Demonstrate scroll settings */ + #ifndef LV_USE_DEMO_SCROLL + #ifdef CONFIG_LV_USE_DEMO_SCROLL + #define LV_USE_DEMO_SCROLL CONFIG_LV_USE_DEMO_SCROLL + #else + #define LV_USE_DEMO_SCROLL 0 + #endif + #endif + + /*E-bike demo with Lottie animations (if LV_USE_LOTTIE is enabled)*/ + #ifndef LV_USE_DEMO_EBIKE + #ifdef CONFIG_LV_USE_DEMO_EBIKE + #define LV_USE_DEMO_EBIKE CONFIG_LV_USE_DEMO_EBIKE + #else + #define LV_USE_DEMO_EBIKE 0 + #endif + #endif + #if LV_USE_DEMO_EBIKE + #ifndef LV_DEMO_EBIKE_PORTRAIT + #ifdef CONFIG_LV_DEMO_EBIKE_PORTRAIT + #define LV_DEMO_EBIKE_PORTRAIT CONFIG_LV_DEMO_EBIKE_PORTRAIT + #else + #define LV_DEMO_EBIKE_PORTRAIT 0 /*0: for 480x270..480x320, 1: for 480x800..720x1280*/ + #endif + #endif + #endif + + /** High-resolution demo */ + #ifndef LV_USE_DEMO_HIGH_RES + #ifdef CONFIG_LV_USE_DEMO_HIGH_RES + #define LV_USE_DEMO_HIGH_RES CONFIG_LV_USE_DEMO_HIGH_RES + #else + #define LV_USE_DEMO_HIGH_RES 0 + #endif + #endif + + /* Smart watch demo */ + #ifndef LV_USE_DEMO_SMARTWATCH + #ifdef CONFIG_LV_USE_DEMO_SMARTWATCH + #define LV_USE_DEMO_SMARTWATCH CONFIG_LV_USE_DEMO_SMARTWATCH + #else + #define LV_USE_DEMO_SMARTWATCH 0 + #endif + #endif +#endif /* LV_BUILD_DEMOS */ @@ -3685,6 +4480,9 @@ * End of parsing lv_conf_template.h -----------------------------------*/ +/*Fix inconsistent name*/ +#define LV_USE_ANIMIMAGE LV_USE_ANIMIMG + #ifndef __ASSEMBLY__ LV_EXPORT_CONST_INT(LV_DPI_DEF); LV_EXPORT_CONST_INT(LV_DRAW_BUF_STRIDE_ALIGN); @@ -3693,7 +4491,7 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN); #undef LV_KCONFIG_PRESENT -/*Set some defines if a dependency is disabled*/ +/* Set some defines if a dependency is disabled. */ #if LV_USE_LOG == 0 #define LV_LOG_LEVEL LV_LOG_LEVEL_NONE #define LV_LOG_TRACE_MEM 0 @@ -3706,17 +4504,52 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN); #define LV_LOG_TRACE_ANIM 0 #endif /*LV_USE_LOG*/ +#if LV_USE_WAYLAND == 0 + #define LV_WAYLAND_USE_DMABUF 0 + #define LV_WAYLAND_WINDOW_DECORATIONS 0 + #define LV_WAYLAND_WL_SHELL 0 +#endif /* LV_USE_WAYLAND */ + #if LV_USE_SYSMON == 0 #define LV_USE_PERF_MONITOR 0 #define LV_USE_MEM_MONITOR 0 #endif /*LV_USE_SYSMON*/ +#if LV_USE_PERF_MONITOR == 0 + #define LV_USE_PERF_MONITOR_LOG_MODE 0 +#endif /*LV_USE_PERF_MONITOR*/ + +#if LV_BUILD_DEMOS == 0 + #define LV_USE_DEMO_WIDGETS 0 + #define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 + #define LV_USE_DEMO_BENCHMARK 0 + #define LV_USE_DEMO_RENDER 0 + #define LV_USE_DEMO_STRESS 0 + #define LV_USE_DEMO_MUSIC 0 + #define LV_USE_DEMO_VECTOR_GRAPHIC 0 + #define LV_USE_DEMO_FLEX_LAYOUT 0 + #define LV_USE_DEMO_MULTILANG 0 + #define LV_USE_DEMO_TRANSFORM 0 + #define LV_USE_DEMO_SCROLL 0 + #define LV_USE_DEMO_EBIKE 0 + #define LV_USE_DEMO_HIGH_RES 0 + #define LV_USE_DEMO_SMARTWATCH 0 +#endif /* LV_BUILD_DEMOS */ + #ifndef LV_USE_LZ4 - #define LV_USE_LZ4 (LV_USE_LZ4_INTERNAL || LV_USE_LZ4_EXTERNAL) + #if (LV_USE_LZ4_INTERNAL || LV_USE_LZ4_EXTERNAL) + #define LV_USE_LZ4 1 + #else + #define LV_USE_LZ4 0 + #endif #endif #ifndef LV_USE_THORVG - #define LV_USE_THORVG (LV_USE_THORVG_INTERNAL || LV_USE_THORVG_EXTERNAL) + #if (LV_USE_THORVG_INTERNAL || LV_USE_THORVG_EXTERNAL) + #define LV_USE_THORVG 1 + #else + #define LV_USE_THORVG 0 + #endif #endif #if LV_USE_OS @@ -3730,7 +4563,10 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN); #endif #endif -/*If running without lv_conf.h add typedefs with default value*/ +/*Allow only upper case letters and '/' ('/' is a special case for backward compatibility)*/ +#define LV_FS_IS_VALID_LETTER(l) ((l) == '/' || ((l) >= 'A' && (l) <= 'Z')) + +/* 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*/ #define _CRT_SECURE_NO_WARNINGS diff --git a/lib/libesp32_lvgl/lvgl/src/lv_conf_kconfig.h b/lib/libesp32_lvgl/lvgl/src/lv_conf_kconfig.h index 7796e0fb9..78f959687 100644 --- a/lib/libesp32_lvgl/lvgl/src/lv_conf_kconfig.h +++ b/lib/libesp32_lvgl/lvgl/src/lv_conf_kconfig.h @@ -83,6 +83,30 @@ extern "C" { # define CONFIG_LV_USE_STDLIB_SPRINTF LV_STDLIB_CUSTOM #endif +/******************* + * LV_USE_OS + *******************/ + +#ifdef CONFIG_LV_OS_NONE +# define CONFIG_LV_USE_OS LV_OS_NONE +#elif defined(CONFIG_LV_OS_PTHREAD) +# define CONFIG_LV_USE_OS LV_OS_PTHREAD +#elif defined(CONFIG_LV_OS_FREERTOS) +# define CONFIG_LV_USE_OS LV_OS_FREERTOS +#elif defined(CONFIG_LV_OS_CMSIS_RTOS2) +# define CONFIG_LV_USE_OS LV_OS_CMSIS_RTOS2 +#elif defined (CONFIG_LV_OS_RTTHREAD) +# define CONFIG_LV_USE_OS LV_OS_RTTHREAD +#elif defined (CONFIG_LV_OS_WINDOWS) +# define CONFIG_LV_USE_OS LV_OS_WINDOWS +#elif defined (CONFIG_LV_OS_MQX) +# define CONFIG_LV_USE_OS LV_OS_MQX +#elif defined (CONFIG_LV_OS_SDL2) +# define CONFIG_LV_USE_OS LV_OS_SDL2 +#elif defined (CONFIG_LV_OS_CUSTOM) +# define CONFIG_LV_USE_OS LV_OS_CUSTOM +#endif + /******************* * LV_MEM_SIZE *******************/ @@ -204,10 +228,10 @@ 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_SOURCE_HAN_SANS_SC_14_CJK) +# define CONFIG_LV_FONT_DEFAULT &lv_font_source_han_sans_sc_14_cjk +#elif defined(CONFIG_LV_FONT_SOURCE_HAN_SANS_SC_16_CJK) +# define CONFIG_LV_FONT_DEFAULT &lv_font_source_han_sans_sc_16_cjk #elif defined(CONFIG_LV_FONT_DEFAULT_UNSCII_8) # define CONFIG_LV_FONT_DEFAULT &lv_font_unscii_8 #elif defined(CONFIG_LV_FONT_DEFAULT_UNSCII_16) @@ -247,6 +271,18 @@ extern "C" { # define CONFIG_LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_FULL #endif +/*------------------ + * WAYLAND + *-----------------*/ + +#ifdef CONFIG_LV_WAYLAND_RENDER_MODE_PARTIAL +# define CONFIG_LV_WAYLAND_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL +#elif defined(CONFIG_LV_WAYLAND_RENDER_MODE_DIRECT) +# define CONFIG_LV_WAYLAND_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT +#elif defined(CONFIG_LV_WAYLAND_RENDER_MODE_FULL) +# define CONFIG_LV_WAYLAND_RENDER_MODE_FULL LV_DISPLAY_RENDER_MODE_FULL +#endif + /*------------------ * LINUX FBDEV *-----------------*/ @@ -259,6 +295,15 @@ extern "C" { # define CONFIG_LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_FULL #endif + +#ifdef CONFIG_LV_USE_CALENDAR +# ifdef CONFIG_LV_CALENDAR_WEEK_STARTS_MONDAY +# define CONFIG_LV_CALENDAR_DEFAULT_DAY_NAMES { CONFIG_LV_MONDAY_STR , CONFIG_LV_TUESDAY_STR, CONFIG_LV_WEDNESDAY_STR, CONFIG_LV_THURSDAY_STR, CONFIG_LV_FRIDAY_STR, CONFIG_LV_SATURDAY_STR, CONFIG_LV_SUNDAY_STR } +# else +# define CONFIG_LV_CALENDAR_DEFAULT_DAY_NAMES { CONFIG_LV_SUNDAY_STR, CONFIG_LV_MONDAY_STR , CONFIG_LV_TUESDAY_STR, CONFIG_LV_WEDNESDAY_STR, CONFIG_LV_THURSDAY_STR, CONFIG_LV_FRIDAY_STR, CONFIG_LV_SATURDAY_STR } +# endif +#endif + #ifdef __cplusplus } /*extern "C"*/ #endif diff --git a/lib/libesp32_lvgl/lvgl/src/lv_init.c b/lib/libesp32_lvgl/lvgl/src/lv_init.c index a019d6e57..7192f72d9 100644 --- a/lib/libesp32_lvgl/lvgl/src/lv_init.c +++ b/lib/libesp32_lvgl/lvgl/src/lv_init.c @@ -6,7 +6,6 @@ /********************* * 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" @@ -39,7 +38,16 @@ #include "themes/simple/lv_theme_simple.h" #include "misc/lv_fs.h" #include "osal/lv_os_private.h" +#include "others/sysmon/lv_sysmon_private.h" +#include "others/xml/lv_xml.h" +#if LV_USE_SVG + #include "libs/svg/lv_svg_decoder.h" +#endif + +#if LV_USE_NEMA_GFX + #include "draw/nema_gfx/lv_draw_nema_gfx.h" +#endif #if LV_USE_DRAW_VGLITE #include "draw/nxp/vglite/lv_draw_vglite.h" #endif @@ -48,6 +56,9 @@ #include "draw/nxp/pxp/lv_draw_pxp.h" #endif #endif +#if LV_USE_DRAW_G2D + #include "draw/nxp/g2d/lv_draw_g2d.h" +#endif #if LV_USE_DRAW_DAVE2D #include "draw/renesas/dave2d/lv_draw_dave2d.h" #endif @@ -57,9 +68,21 @@ #if LV_USE_DRAW_VG_LITE #include "draw/vg_lite/lv_draw_vg_lite.h" #endif +#if LV_USE_DRAW_DMA2D + #include "draw/dma2d/lv_draw_dma2d.h" +#endif +#if LV_USE_DRAW_OPENGLES + #include "draw/opengles/lv_draw_opengles.h" +#endif #if LV_USE_WINDOWS #include "drivers/windows/lv_windows_context.h" #endif +#if LV_USE_UEFI + #include "drivers/uefi/lv_uefi_context.h" +#endif +#if LV_USE_EVDEV + #include "drivers/evdev/lv_evdev_private.h" +#endif /********************* * DEFINES @@ -190,12 +213,23 @@ void lv_init(void) lv_group_init(); +#if LV_USE_FREETYPE + /* Since the drawing unit needs to register the freetype event, + * initialize the freetype module first + */ + lv_freetype_init(LV_FREETYPE_CACHE_FT_GLYPH_CNT); +#endif + lv_draw_init(); #if LV_USE_DRAW_SW lv_draw_sw_init(); #endif +#if LV_USE_NEMA_GFX + lv_draw_nema_gfx_init(); +#endif + #if LV_USE_DRAW_VGLITE lv_draw_vglite_init(); #endif @@ -206,6 +240,10 @@ void lv_init(void) #endif #endif +#if LV_USE_DRAW_G2D + lv_draw_g2d_init(); +#endif + #if LV_USE_DRAW_DAVE2D lv_draw_dave2d_init(); #endif @@ -214,10 +252,22 @@ void lv_init(void) lv_draw_sdl_init(); #endif +#if LV_USE_DRAW_DMA2D + lv_draw_dma2d_init(); +#endif + +#if LV_USE_DRAW_OPENGLES + lv_draw_opengles_init(); +#endif + #if LV_USE_WINDOWS lv_windows_platform_init(); #endif +#if LV_USE_UEFI + lv_uefi_platform_init(); +#endif + lv_obj_style_init(); /*Initialize the screen refresh system*/ @@ -303,6 +353,15 @@ void lv_init(void) lv_fs_arduino_sd_init(); #endif +#if LV_USE_FS_UEFI + lv_fs_uefi_init(); +#endif + + /*Use the earlier initialized position of FFmpeg decoder as a fallback decoder*/ +#if LV_USE_FFMPEG + lv_ffmpeg_init(); +#endif + #if LV_USE_LODEPNG lv_lodepng_init(); #endif @@ -323,15 +382,12 @@ void lv_init(void) lv_bmp_init(); #endif - /*Make FFMPEG last because the last converter will be checked first and - *it's superior to any other */ -#if LV_USE_FFMPEG - lv_ffmpeg_init(); +#if LV_USE_SVG + lv_svg_decoder_init(); #endif -#if LV_USE_FREETYPE - /*Init freetype library*/ - lv_freetype_init(LV_FREETYPE_CACHE_FT_GLYPH_CNT); +#if LV_USE_XML + lv_xml_init(); #endif lv_initialized = true; @@ -359,12 +415,12 @@ void lv_deinit(void) lv_cleanup_devices(LV_GLOBAL_DEFAULT()); -#if LV_USE_SPAN != 0 - lv_span_stack_deinit(); +#if LV_USE_EVDEV + lv_evdev_deinit(); #endif -#if LV_USE_DRAW_SW - lv_draw_sw_deinit(); +#if LV_USE_SPAN != 0 + lv_span_stack_deinit(); #endif #if LV_USE_FREETYPE @@ -389,6 +445,10 @@ void lv_deinit(void) lv_obj_style_deinit(); +#if LV_USE_UEFI + lv_uefi_platform_deinit(); +#endif + #if LV_USE_PXP #if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP lv_draw_pxp_deinit(); @@ -399,10 +459,22 @@ void lv_deinit(void) lv_draw_vglite_deinit(); #endif +#if LV_USE_DRAW_G2D + lv_draw_g2d_deinit(); +#endif + #if LV_USE_DRAW_VG_LITE lv_draw_vg_lite_deinit(); #endif +#if LV_USE_DRAW_DMA2D + lv_draw_dma2d_deinit(); +#endif + +#if LV_USE_DRAW_OPENGLES + lv_draw_opengles_deinit(); +#endif + #if LV_USE_DRAW_SW lv_draw_sw_deinit(); #endif @@ -437,6 +509,10 @@ void lv_deinit(void) lv_log_register_print_cb(NULL); #endif +#ifdef LV_GC_DEINIT + LV_GC_DEINIT(); +#endif + } /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/lvgl_private.h b/lib/libesp32_lvgl/lvgl/src/lvgl_private.h index 8ab64e973..325290c22 100644 --- a/lib/libesp32_lvgl/lvgl/src/lvgl_private.h +++ b/lib/libesp32_lvgl/lvgl/src/lvgl_private.h @@ -1,10 +1,10 @@ /** * @file lvgl_private.h - * + * This file exists only to be compatible with Arduino's library structure */ -#ifndef LVGL_PRIVATE_H -#define LVGL_PRIVATE_H +#ifndef LVGL_PRIVATE_SRC_H +#define LVGL_PRIVATE_SRC_H #ifdef __cplusplus extern "C" { @@ -13,94 +13,7 @@ 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_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" +#include "../lvgl_private.h" /********************* * DEFINES @@ -122,4 +35,4 @@ extern "C" { } /*extern "C"*/ #endif -#endif /*LVGL_PRIVATE_H*/ +#endif /* LVGL_PRIVATE_SRC_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_class.h b/lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_class.h new file mode 100644 index 000000000..89b23c3f5 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_class.h @@ -0,0 +1,17 @@ +/** + * @file lv_cache_clazz.h + * + */ + +#ifndef LV_CACHE_CLAZZ_H +#define LV_CACHE_CLAZZ_H + + +/********************* + * INCLUDES + *********************/ + +#include "lv_cache_lru_rb.h" +#include "lv_cache_lru_ll.h" + +#endif //LV_CACHE_CLAZZ_H diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_lru_ll.c b/lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_lru_ll.c new file mode 100644 index 000000000..593194f89 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_lru_ll.c @@ -0,0 +1,443 @@ +/** +* @file lv_cache_lru_ll.c +* +*/ + +/*********************************\ +* * +* ┏ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ┓ * +* ┌ ─ ─ ─ ┐ * +* ┃ Cache insert ┃ * +* │Hitting│ head * +* ┃ ─ ─ ─ ─ ┃ * +* ┌─────┐ * +* ┃ │ B │ ┃ * +* └──▲──┘ * +* ┃ │ ┃ * +* ┌──┴──┐ * +* ┃ │ E │ ┃ * +* └──▲──┘ * +* ┃ │ ┃ * +* ┌──┴──┐ * +* ┃ │ A │ ┌ ─ ─ ─ ─ ─ ┐ ┃ * +* └──▲──┘ LRU * +* ┃ │ │ Cache │ ┃ * +* ┌──┴──┐ ─ ─ ─ ─ ─ ─ * +* ┃ │ D │ ┃ * +* └──▲──┘ * +* ┃ │ ┃ * +* ┌──┴──┐ * +* ┃ │ C │ ┃ * +* └──▲──┘ * +* ┃ ┌ ─ ─│─ ─ ┐ ┃ * +* ┌──┴──┐ * +* ┃ │ │ F │ │ ┃ * +* └─────┘ * +* ┃ └ ─ ─ ─ ─ ┘ ┃ * +* remove * +* ┃ tail ┃ * +* ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ * +* * +\*********************************/ + +/********************* + * INCLUDES + *********************/ + +#include "lv_cache_lru_ll.h" +#include "../lv_cache_entry.h" +#include "../../../stdlib/lv_sprintf.h" +#include "../../../stdlib/lv_string.h" +#include "../../lv_ll.h" + +#include "../../lv_iter.h" +#include "../../lv_assert.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef uint32_t (get_data_size_cb_t)(const void * data); + +struct _lv_cache_lru_ll_t { + lv_cache_t cache; + lv_ll_t ll; + get_data_size_cb_t * get_data_size_cb; +}; + +typedef struct _lv_cache_lru_ll_t lv_cache_lru_ll_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void * alloc_cb(void); +static bool init_cnt_cb(lv_cache_t * cache); +static bool init_size_cb(lv_cache_t * cache); +static void destroy_cb(lv_cache_t * cache, void * user_data); + +static lv_cache_entry_t * get_cb(lv_cache_t * cache, const void * key, void * user_data); +static lv_cache_entry_t * add_cb(lv_cache_t * cache, const void * key, void * user_data); +static void remove_cb(lv_cache_t * cache, lv_cache_entry_t * entry, void * user_data); +static void drop_cb(lv_cache_t * cache, const void * key, void * user_data); +static void drop_all_cb(lv_cache_t * cache, void * user_data); +static lv_cache_entry_t * get_victim_cb(lv_cache_t * cache, void * user_data); +static lv_cache_reserve_cond_res_t reserve_cond_cb(lv_cache_t * cache, const void * key, size_t reserved_size, + void * user_data); + +static void * alloc_new_node(lv_cache_lru_ll_t * lru, void * key, void * user_data); + +static uint32_t cnt_get_data_size_cb(const void * data); +static uint32_t size_get_data_size_cb(const void * data); + +static lv_iter_t * cache_iter_create_cb(lv_cache_t * cache); +static lv_result_t cache_iter_next_cb(void * instance, void * context, void * elem); + +/********************** + * GLOBAL VARIABLES + **********************/ +const lv_cache_class_t lv_cache_class_lru_ll_count = { + .alloc_cb = alloc_cb, + .init_cb = init_cnt_cb, + .destroy_cb = destroy_cb, + + .get_cb = get_cb, + .add_cb = add_cb, + .remove_cb = remove_cb, + .drop_cb = drop_cb, + .drop_all_cb = drop_all_cb, + .get_victim_cb = get_victim_cb, + .reserve_cond_cb = reserve_cond_cb, + .iter_create_cb = cache_iter_create_cb, +}; + +const lv_cache_class_t lv_cache_class_lru_ll_size = { + .alloc_cb = alloc_cb, + .init_cb = init_size_cb, + .destroy_cb = destroy_cb, + + .get_cb = get_cb, + .add_cb = add_cb, + .remove_cb = remove_cb, + .drop_cb = drop_cb, + .drop_all_cb = drop_all_cb, + .get_victim_cb = get_victim_cb, + .reserve_cond_cb = reserve_cond_cb, + .iter_create_cb = cache_iter_create_cb, +}; + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void * alloc_new_node(lv_cache_lru_ll_t * lru, void * key, void * user_data) +{ + LV_UNUSED(user_data); + + LV_ASSERT_NULL(lru); + LV_ASSERT_NULL(key); + + if(lru == NULL || key == NULL) { + return NULL; + } + + void * new_node = lv_ll_ins_head(&lru->ll); + if(new_node == NULL) { + return NULL; + } + + lv_memcpy(new_node, key, lru->cache.node_size); + lv_cache_entry_t * entry = lv_cache_entry_get_entry(new_node, lru->cache.node_size); + lv_cache_entry_init(entry, &lru->cache, lru->cache.node_size); + return entry; +} + +static void * alloc_cb(void) +{ + void * res = lv_malloc(sizeof(lv_cache_lru_ll_t)); + LV_ASSERT_MALLOC(res); + if(res == NULL) { + LV_LOG_ERROR("malloc failed"); + return NULL; + } + + lv_memzero(res, sizeof(lv_cache_lru_ll_t)); + return res; +} + +static bool init_cnt_cb(lv_cache_t * cache) +{ + lv_cache_lru_ll_t * lru = (lv_cache_lru_ll_t *)cache; + + LV_ASSERT_NULL(lru->cache.ops.compare_cb); + LV_ASSERT_NULL(lru->cache.ops.free_cb); + LV_ASSERT(lru->cache.node_size > 0); + + if(lru->cache.node_size <= 0 || lru->cache.ops.compare_cb == NULL || lru->cache.ops.free_cb == NULL) { + return false; + } + + lv_ll_init(&lru->ll, lv_cache_entry_get_size(lru->cache.node_size)); + lru->get_data_size_cb = cnt_get_data_size_cb; + + return true; +} + +static bool init_size_cb(lv_cache_t * cache) +{ + lv_cache_lru_ll_t * lru = (lv_cache_lru_ll_t *)cache; + + LV_ASSERT_NULL(lru->cache.ops.compare_cb); + LV_ASSERT_NULL(lru->cache.ops.free_cb); + LV_ASSERT(lru->cache.node_size > 0); + + if(lru->cache.node_size <= 0 || lru->cache.ops.compare_cb == NULL || lru->cache.ops.free_cb == NULL) { + return false; + } + + lv_ll_init(&lru->ll, lv_cache_entry_get_size(lru->cache.node_size)); + lru->get_data_size_cb = size_get_data_size_cb; + + return true; +} + +static void destroy_cb(lv_cache_t * cache, void * user_data) +{ + LV_UNUSED(user_data); + + lv_cache_lru_ll_t * lru = (lv_cache_lru_ll_t *)cache; + + LV_ASSERT_NULL(lru); + + if(lru == NULL) { + return; + } + + cache->clz->drop_all_cb(cache, user_data); + cache->size = 0; +} + +static lv_cache_entry_t * get_cb(lv_cache_t * cache, const void * key, void * user_data) +{ + LV_UNUSED(user_data); + + lv_cache_lru_ll_t * lru = (lv_cache_lru_ll_t *)cache; + + LV_ASSERT_NULL(lru); + LV_ASSERT_NULL(key); + + if(lru == NULL || key == NULL) { + return NULL; + } + + /* Linear search */ + void * node = NULL; + LV_LL_READ(&lru->ll, node) { + if(lru->cache.ops.compare_cb(node, key) == 0) { + break; + } + } + /*cache hit*/ + if(node) { + void * head = lv_ll_get_head(&lru->ll); + lv_ll_move_before(&lru->ll, node, head); + + lv_cache_entry_t * entry = lv_cache_entry_get_entry(node, cache->node_size); + return entry; + } + return NULL; +} + +static lv_cache_entry_t * add_cb(lv_cache_t * cache, const void * key, void * user_data) +{ + LV_UNUSED(user_data); + + lv_cache_lru_ll_t * lru = (lv_cache_lru_ll_t *)cache; + + LV_ASSERT_NULL(lru); + LV_ASSERT_NULL(key); + + if(lru == NULL || key == NULL) { + return NULL; + } + + lv_cache_entry_t * entry = alloc_new_node(lru, (void *)key, user_data); + if(entry == NULL) { + return NULL; + } + + cache->size += lru->get_data_size_cb(key); + + return entry; +} + +static void remove_cb(lv_cache_t * cache, lv_cache_entry_t * entry, void * user_data) +{ + LV_UNUSED(user_data); + + lv_cache_lru_ll_t * lru = (lv_cache_lru_ll_t *)cache; + + LV_ASSERT_NULL(lru); + LV_ASSERT_NULL(entry); + + if(lru == NULL || entry == NULL) { + return; + } + + void * node = lv_cache_entry_get_data(entry); + + lv_ll_remove(&lru->ll, node); + + cache->size -= lru->get_data_size_cb(node); +} + +static void drop_cb(lv_cache_t * cache, const void * key, void * user_data) +{ + lv_cache_lru_ll_t * lru = (lv_cache_lru_ll_t *)cache; + + LV_ASSERT_NULL(lru); + LV_ASSERT_NULL(key); + + if(lru == NULL || key == NULL) { + return; + } + + void * node = cache->clz->get_cb(cache, key, user_data); + if(node == NULL) { + return; + } + lv_ll_remove(&lru->ll, node); + + lru->cache.ops.free_cb(node, user_data); + cache->size -= lru->get_data_size_cb(node); + + lv_cache_entry_t * entry = lv_cache_entry_get_entry(node, cache->node_size); + lv_cache_entry_delete(entry); +} + +static void drop_all_cb(lv_cache_t * cache, void * user_data) +{ + lv_cache_lru_ll_t * lru = (lv_cache_lru_ll_t *)cache; + + LV_ASSERT_NULL(lru); + + if(lru == NULL) { + return; + } + + uint32_t used_cnt = 0; + void * node; + LV_LL_READ(&lru->ll, node) { + /*free user handled data and do other clean up*/ + lv_cache_entry_t * entry = lv_cache_entry_get_entry(node, cache->node_size); + if(lv_cache_entry_get_ref(entry) == 0) { + lru->cache.ops.free_cb(node, user_data); + } + else { + LV_LOG_WARN("entry (%p) is still referenced (%" LV_PRId32 ")", (void *)entry, lv_cache_entry_get_ref(entry)); + used_cnt++; + } + } + if(used_cnt > 0) { + LV_LOG_WARN("%" LV_PRId32 " entries are still referenced", used_cnt); + } + + lv_ll_clear(&lru->ll); + + cache->size = 0; +} + +static lv_cache_entry_t * get_victim_cb(lv_cache_t * cache, void * user_data) +{ + LV_UNUSED(user_data); + + lv_cache_lru_ll_t * lru = (lv_cache_lru_ll_t *)cache; + + LV_ASSERT_NULL(lru); + + void * tail; + LV_LL_READ_BACK(&lru->ll, tail) { + lv_cache_entry_t * entry = lv_cache_entry_get_entry(tail, cache->node_size); + if(lv_cache_entry_get_ref(entry) == 0) { + return entry; + } + } + + return NULL; +} + +static lv_cache_reserve_cond_res_t reserve_cond_cb(lv_cache_t * cache, const void * key, size_t reserved_size, + void * user_data) +{ + LV_UNUSED(user_data); + + lv_cache_lru_ll_t * lru = (lv_cache_lru_ll_t *)cache; + + LV_ASSERT_NULL(lru); + + if(lru == NULL) { + return LV_CACHE_RESERVE_COND_ERROR; + } + + uint32_t data_size = key ? lru->get_data_size_cb(key) : 0; + if(data_size > lru->cache.max_size) { + LV_LOG_ERROR("data size (%" LV_PRIu32 ") is larger than max size (%" LV_PRIu32 ")", data_size, lru->cache.max_size); + return LV_CACHE_RESERVE_COND_TOO_LARGE; + } + + return cache->size + reserved_size + data_size > lru->cache.max_size + ? LV_CACHE_RESERVE_COND_NEED_VICTIM + : LV_CACHE_RESERVE_COND_OK; +} + +static uint32_t cnt_get_data_size_cb(const void * data) +{ + LV_UNUSED(data); + return 1; +} + +static uint32_t size_get_data_size_cb(const void * data) +{ + lv_cache_slot_size_t * slot = (lv_cache_slot_size_t *)data; + return slot->size; +} + +static lv_iter_t * cache_iter_create_cb(lv_cache_t * cache) +{ + return lv_iter_create(cache, lv_cache_entry_get_size(cache->node_size), 0, cache_iter_next_cb); +} + +static lv_result_t cache_iter_next_cb(void * instance, void * context, void * elem) +{ + lv_cache_lru_ll_t * lru = (lv_cache_lru_ll_t *)instance; + void ** ll_node = context; + + LV_ASSERT_NULL(ll_node); + + if(*ll_node == NULL) *ll_node = lv_ll_get_head(&lru->ll); + else *ll_node = lv_ll_get_next(&lru->ll, *ll_node); + + void * node = *ll_node; + + if(node == NULL) return LV_RESULT_INVALID; + + lv_memcpy(elem, node, lv_cache_entry_get_size(lru->cache.node_size)); + + return LV_RESULT_OK; +} diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_lru_ll.h b/lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_lru_ll.h new file mode 100644 index 000000000..8c0352b4a --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_lru_ll.h @@ -0,0 +1,44 @@ +/** +* @file lv_cache_lru_ll.h +* +*/ + +#ifndef LV_CACHE_LRU_LL_H +#define LV_CACHE_LRU_LL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../lv_cache_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/************************* + * GLOBAL VARIABLES + *************************/ +LV_ATTRIBUTE_EXTERN_DATA extern const lv_cache_class_t lv_cache_class_lru_ll_count; +LV_ATTRIBUTE_EXTERN_DATA extern const lv_cache_class_t lv_cache_class_lru_ll_size; +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CACHE_LRU_LL_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_lru_rb.c b/lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_lru_rb.c similarity index 91% rename from lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_lru_rb.c rename to lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_lru_rb.c index 0a73102d1..79b64b188 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_lru_rb.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_lru_rb.c @@ -43,11 +43,15 @@ /********************* * INCLUDES *********************/ + #include "lv_cache_lru_rb.h" -#include "../../stdlib/lv_sprintf.h" -#include "../../stdlib/lv_string.h" -#include "../lv_ll.h" -#include "../lv_rb_private.h" +#include "../lv_cache_entry.h" +#include "../../../stdlib/lv_sprintf.h" +#include "../../../stdlib/lv_string.h" +#include "../../lv_ll.h" +#include "../../lv_rb_private.h" +#include "../../lv_rb.h" +#include "../../lv_iter.h" /********************* * DEFINES @@ -58,7 +62,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 +70,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 **********************/ @@ -91,6 +95,9 @@ inline static void ** get_lru_node(lv_lru_rb_t_ * lru, lv_rb_node_t * node); static uint32_t cnt_get_data_size_cb(const void * data); static uint32_t size_get_data_size_cb(const void * data); +static lv_iter_t * cache_iter_create_cb(lv_cache_t * cache); +static lv_result_t cache_iter_next_cb(void * instance, void * context, void * elem); + /********************** * GLOBAL VARIABLES **********************/ @@ -105,7 +112,8 @@ const lv_cache_class_t lv_cache_class_lru_rb_count = { .drop_cb = drop_cb, .drop_all_cb = drop_all_cb, .get_victim_cb = get_victim_cb, - .reserve_cond_cb = reserve_cond_cb + .reserve_cond_cb = reserve_cond_cb, + .iter_create_cb = cache_iter_create_cb, }; const lv_cache_class_t lv_cache_class_lru_rb_size = { @@ -119,7 +127,8 @@ const lv_cache_class_t lv_cache_class_lru_rb_size = { .drop_cb = drop_cb, .drop_all_cb = drop_all_cb, .get_victim_cb = get_victim_cb, - .reserve_cond_cb = reserve_cond_cb + .reserve_cond_cb = reserve_cond_cb, + .iter_create_cb = cache_iter_create_cb, }; /********************** * STATIC VARIABLES @@ -460,3 +469,29 @@ static uint32_t size_get_data_size_cb(const void * data) lv_cache_slot_size_t * slot = (lv_cache_slot_size_t *)data; return slot->size; } + +static lv_iter_t * cache_iter_create_cb(lv_cache_t * cache) +{ + return lv_iter_create(cache, lv_cache_entry_get_size(cache->node_size), sizeof(void *), cache_iter_next_cb); +} + +static lv_result_t cache_iter_next_cb(void * instance, void * context, void * elem) +{ + lv_lru_rb_t_ * lru = (lv_lru_rb_t_ *)instance; + lv_rb_node_t *** ll_node = context; + + LV_ASSERT_NULL(ll_node); + + if(*ll_node == NULL) *ll_node = lv_ll_get_head(&lru->ll); + else *ll_node = lv_ll_get_next(&lru->ll, *ll_node); + + lv_rb_node_t ** node = *ll_node; + + if(node == NULL) return LV_RESULT_INVALID; + + uint32_t node_size = lru->cache.node_size; + void * search_key = (*node)->data; + lv_memcpy(elem, search_key, lv_cache_entry_get_size(node_size)); + + return LV_RESULT_OK; +} diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_lru_rb.h b/lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_lru_rb.h similarity index 93% rename from lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_lru_rb.h rename to lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_lru_rb.h index c0f44f396..a7dbdc099 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache_lru_rb.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/class/lv_cache_lru_rb.h @@ -13,8 +13,8 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "lv_cache_entry.h" -#include "lv_cache_private.h" + +#include "../lv_cache_private.h" /********************* * DEFINES diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/instance/lv_cache_instance.h b/lib/libesp32_lvgl/lvgl/src/misc/cache/instance/lv_cache_instance.h new file mode 100644 index 000000000..2dc696857 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/instance/lv_cache_instance.h @@ -0,0 +1,16 @@ +/** + * @file lv_cache_instance.h + * + */ + +#ifndef LV_CACHE_INSTANCE_H +#define LV_CACHE_INSTANCE_H + +/********************* + * INCLUDES + *********************/ + +#include "lv_image_header_cache.h" +#include "lv_image_cache.h" + +#endif //LV_CACHE_INSTANCE_H diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_cache.c b/lib/libesp32_lvgl/lvgl/src/misc/cache/instance/lv_image_cache.c similarity index 66% rename from lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_cache.c rename to lib/libesp32_lvgl/lvgl/src/misc/cache/instance/lv_image_cache.c index c2ca4354e..6313d85c7 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_cache.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/instance/lv_image_cache.c @@ -7,12 +7,12 @@ * INCLUDES *********************/ -#include "../../draw/lv_image_decoder_private.h" -#include "../lv_assert.h" -#include "../../core/lv_global.h" +#include "../../../draw/lv_image_decoder_private.h" +#include "../../lv_assert.h" +#include "../../../core/lv_global.h" +#include "../../../misc/lv_iter.h" #include "lv_image_cache.h" -#include "lv_image_header_cache.h" /********************* * DEFINES @@ -34,6 +34,7 @@ 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); +static void iter_inspect_cb(void * elem); /********************** * GLOBAL VARIABLES @@ -99,6 +100,21 @@ bool lv_image_cache_is_enabled(void) return lv_cache_is_enabled(img_cache_p); } +lv_iter_t * lv_image_cache_iter_create(void) +{ + return lv_cache_iter_create(img_cache_p); +} + +void lv_image_cache_dump(void) +{ + lv_iter_t * iter = lv_image_cache_iter_create(); + if(iter == NULL) return; + + LV_LOG_USER("Image cache dump:"); + LV_LOG_USER("\tsize\tdata_size\tcf\trc\ttype\tdecoded\t\t\tsrc"); + lv_iter_inspect(iter, iter_inspect_cb); +} + /********************** * STATIC FUNCTIONS **********************/ @@ -143,3 +159,32 @@ static void image_cache_free_cb(lv_image_cache_data_t * entry, void * user_data) /*Free the duplicated file name*/ if(entry->src_type == LV_IMAGE_SRC_FILE) lv_free((void *)entry->src); } + +static void iter_inspect_cb(void * elem) +{ + lv_image_cache_data_t * data = (lv_image_cache_data_t *)elem; + lv_draw_buf_t * decoded = (lv_draw_buf_t *)data->decoded; + lv_image_header_t * header = &decoded->header; + lv_cache_entry_t * entry = lv_cache_entry_get_entry(data, img_cache_p->node_size); + + LV_UNUSED(decoded); + LV_UNUSED(header); + LV_UNUSED(entry); + + /* size data_size cf rc type decoded src*/ +#define IMAGE_CACHE_DUMP_FORMAT " %4dx%-4d %9"LV_PRIu32" %d %"LV_PRId32" " + switch(data->src_type) { + case LV_IMAGE_SRC_FILE: + LV_LOG_USER(IMAGE_CACHE_DUMP_FORMAT "file\t%-12p\t%s", header->w, header->h, decoded->data_size, header->cf, + lv_cache_entry_get_ref(entry), (void *)data->decoded, (char *)data->src); + break; + case LV_IMAGE_SRC_VARIABLE: + LV_LOG_USER(IMAGE_CACHE_DUMP_FORMAT "var \t%-12p\t%p", header->w, header->h, decoded->data_size, header->cf, + lv_cache_entry_get_ref(entry), (void *)data->decoded, data->src); + break; + default: + LV_LOG_USER(IMAGE_CACHE_DUMP_FORMAT "unkn\t%-12p\t%p", header->w, header->h, decoded->data_size, header->cf, + lv_cache_entry_get_ref(entry), (void *)data->decoded, data->src); + break; + } +} diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_cache.h b/lib/libesp32_lvgl/lvgl/src/misc/cache/instance/lv_image_cache.h similarity index 81% rename from lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_cache.h rename to lib/libesp32_lvgl/lvgl/src/misc/cache/instance/lv_image_cache.h index 1900b98e0..2d1e827f2 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_cache.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/instance/lv_image_cache.h @@ -14,8 +14,7 @@ extern "C" { * INCLUDES *********************/ -#include "../../lv_conf_internal.h" -#include "../lv_types.h" +#include "../../lv_types.h" /********************* * DEFINES @@ -56,6 +55,17 @@ void lv_image_cache_drop(const void * src); */ bool lv_image_cache_is_enabled(void); +/** + * Create an iterator to iterate over the image cache. + * @return an iterator to iterate over the image cache. + */ +lv_iter_t * lv_image_cache_iter_create(void); + +/** + * Dump the content of the image cache in a human-readable format with cache order. + */ +void lv_image_cache_dump(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/instance/lv_image_header_cache.c similarity index 64% rename from lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_header_cache.c rename to lib/libesp32_lvgl/lvgl/src/misc/cache/instance/lv_image_header_cache.c index ef124fb0a..21b76e225 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_header_cache.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/instance/lv_image_header_cache.c @@ -7,11 +7,12 @@ * INCLUDES *********************/ -#include "../../draw/lv_image_decoder_private.h" -#include "../lv_assert.h" -#include "../../core/lv_global.h" +#include "../../../draw/lv_image_decoder_private.h" +#include "../../lv_assert.h" +#include "../../../core/lv_global.h" #include "lv_image_header_cache.h" +#include "../../lv_iter.h" /********************* * DEFINES @@ -32,6 +33,7 @@ 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); +static void iter_inspect_cb(void * elem); /********************** * GLOBAL VARIABLES @@ -94,6 +96,21 @@ bool lv_image_header_cache_is_enabled(void) return lv_cache_is_enabled(img_header_cache_p); } +lv_iter_t * lv_image_header_cache_iter_create(void) +{ + return lv_cache_iter_create(img_header_cache_p); +} + +void lv_image_header_cache_dump(void) +{ + lv_iter_t * iter = lv_image_cache_iter_create(); + if(iter == NULL) return; + + LV_LOG_USER("Image cache dump:"); + LV_LOG_USER("\tsize\tdata_size\tcf\trc\ttype\tdecoded\t\t\tsrc"); + lv_iter_inspect(iter, iter_inspect_cb); +} + /********************** * STATIC FUNCTIONS **********************/ @@ -131,3 +148,32 @@ static void image_header_cache_free_cb(lv_image_header_cache_data_t * entry, voi if(entry->src_type == LV_IMAGE_SRC_FILE) lv_free((void *)entry->src); } + +static void iter_inspect_cb(void * elem) +{ + lv_image_cache_data_t * data = (lv_image_cache_data_t *)elem; + lv_draw_buf_t * decoded = (lv_draw_buf_t *)data->decoded; + lv_image_header_t * header = &decoded->header; + lv_cache_entry_t * entry = lv_cache_entry_get_entry(data, img_header_cache_p->node_size); + + LV_UNUSED(decoded); + LV_UNUSED(header); + LV_UNUSED(entry); + + /* size data_size cf rc type decoded src*/ +#define IMAGE_CACHE_DUMP_FORMAT " %4dx%-4d %9"LV_PRIu32" %d %" LV_PRId32 " " + switch(data->src_type) { + case LV_IMAGE_SRC_FILE: + LV_LOG_USER(IMAGE_CACHE_DUMP_FORMAT "file\t%-12p\t%s", header->w, header->h, decoded->data_size, header->cf, + lv_cache_entry_get_ref(entry), (void *)data->decoded, (char *)data->src); + break; + case LV_IMAGE_SRC_VARIABLE: + LV_LOG_USER(IMAGE_CACHE_DUMP_FORMAT "var \t%-12p\t%p", header->w, header->h, decoded->data_size, header->cf, + lv_cache_entry_get_ref(entry), (void *)data->decoded, data->src); + break; + default: + LV_LOG_USER(IMAGE_CACHE_DUMP_FORMAT "unkn\t%-12p\t%p", header->w, header->h, decoded->data_size, header->cf, + lv_cache_entry_get_ref(entry), (void *)data->decoded, data->src); + break; + } +} diff --git a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_header_cache.h b/lib/libesp32_lvgl/lvgl/src/misc/cache/instance/lv_image_header_cache.h similarity index 81% rename from lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_header_cache.h rename to lib/libesp32_lvgl/lvgl/src/misc/cache/instance/lv_image_header_cache.h index bcecfaf6e..44179812a 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_image_header_cache.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/instance/lv_image_header_cache.h @@ -14,8 +14,7 @@ extern "C" { * INCLUDES *********************/ -#include "../../lv_conf_internal.h" -#include "../lv_types.h" +#include "../../lv_types.h" /********************* * DEFINES @@ -57,6 +56,17 @@ void lv_image_header_cache_drop(const void * src); */ bool lv_image_header_cache_is_enabled(void); +/** + * Create an iterator to iterate over the image header cache. + * @return an iterator to iterate over the image header cache. + */ +lv_iter_t * lv_image_header_cache_iter_create(void); + +/** + * Dump the content of the image header cache in a human-readable format with cache order. + */ +void lv_image_header_cache_dump(void); + /************************* * GLOBAL VARIABLES *************************/ 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 0518ab5e1..33a72196f 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache.c @@ -10,6 +10,7 @@ #include "../../stdlib/lv_sprintf.h" #include "../lv_assert.h" #include "lv_cache_entry_private.h" +#include "lv_cache_private.h" /********************* * DEFINES @@ -25,6 +26,7 @@ static void cache_drop_internal_no_lock(lv_cache_t * cache, const void * key, void * user_data); static bool cache_evict_one_internal_no_lock(lv_cache_t * cache, void * user_data); static lv_cache_entry_t * cache_add_internal_no_lock(lv_cache_t * cache, const void * key, void * user_data); + /********************** * GLOBAL VARIABLES **********************/ @@ -81,14 +83,14 @@ 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_PROFILER_CACHE_BEGIN; lv_mutex_lock(&cache->lock); if(cache->size == 0) { lv_mutex_unlock(&cache->lock); - LV_PROFILER_END; + LV_PROFILER_CACHE_END; return NULL; } @@ -98,14 +100,14 @@ lv_cache_entry_t * lv_cache_acquire(lv_cache_t * cache, const void * key, void * } lv_mutex_unlock(&cache->lock); - LV_PROFILER_END; + LV_PROFILER_CACHE_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_PROFILER_CACHE_BEGIN; lv_mutex_lock(&cache->lock); lv_cache_entry_release_data(entry, user_data); @@ -116,20 +118,20 @@ void lv_cache_release(lv_cache_t * cache, lv_cache_entry_t * entry, void * user_ } lv_mutex_unlock(&cache->lock); - LV_PROFILER_END; + LV_PROFILER_CACHE_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_PROFILER_CACHE_BEGIN; lv_mutex_lock(&cache->lock); if(cache->max_size == 0) { lv_mutex_unlock(&cache->lock); - LV_PROFILER_END; + LV_PROFILER_CACHE_END; return NULL; } @@ -139,7 +141,7 @@ lv_cache_entry_t * lv_cache_add(lv_cache_t * cache, const void * key, void * use } lv_mutex_unlock(&cache->lock); - LV_PROFILER_END; + LV_PROFILER_CACHE_END; return entry; } lv_cache_entry_t * lv_cache_acquire_or_create(lv_cache_t * cache, const void * key, void * user_data) @@ -147,7 +149,7 @@ 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_PROFILER_CACHE_BEGIN; lv_mutex_lock(&cache->lock); lv_cache_entry_t * entry = NULL; @@ -158,7 +160,7 @@ 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; + LV_PROFILER_CACHE_END; return entry; } } @@ -166,7 +168,7 @@ lv_cache_entry_t * lv_cache_acquire_or_create(lv_cache_t * cache, const void * k if(cache->max_size == 0) { lv_mutex_unlock(&cache->lock); - LV_PROFILER_END; + LV_PROFILER_CACHE_END; return NULL; } @@ -174,12 +176,13 @@ lv_cache_entry_t * lv_cache_acquire_or_create(lv_cache_t * cache, const void * k if(entry == NULL) { lv_mutex_unlock(&cache->lock); - LV_PROFILER_END; + LV_PROFILER_CACHE_END; return NULL; } bool create_res = cache->ops.create_cb(lv_cache_entry_get_data(entry), user_data); if(create_res == false) { cache->clz->remove_cb(cache, entry, user_data); + cache->ops.free_cb(lv_cache_entry_get_data(entry), user_data); lv_cache_entry_delete(entry); entry = NULL; } @@ -188,59 +191,59 @@ lv_cache_entry_t * lv_cache_acquire_or_create(lv_cache_t * cache, const void * k } lv_mutex_unlock(&cache->lock); - LV_PROFILER_END; + LV_PROFILER_CACHE_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; + LV_PROFILER_CACHE_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; + LV_PROFILER_CACHE_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_PROFILER_CACHE_BEGIN; lv_mutex_lock(&cache->lock); cache_drop_internal_no_lock(cache, key, user_data); lv_mutex_unlock(&cache->lock); - LV_PROFILER_END; + LV_PROFILER_CACHE_END; } bool lv_cache_evict_one(lv_cache_t * cache, void * user_data) { LV_ASSERT_NULL(cache); - LV_PROFILER_BEGIN; + LV_PROFILER_CACHE_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; + LV_PROFILER_CACHE_END; return res; } void lv_cache_drop_all(lv_cache_t * cache, void * user_data) { LV_ASSERT_NULL(cache); - LV_PROFILER_BEGIN; + LV_PROFILER_CACHE_BEGIN; lv_mutex_lock(&cache->lock); cache->clz->drop_all_cb(cache, user_data); lv_mutex_unlock(&cache->lock); - LV_PROFILER_END; + LV_PROFILER_CACHE_END; } void lv_cache_set_max_size(lv_cache_t * cache, size_t max_size, void * user_data) @@ -292,6 +295,13 @@ const char * lv_cache_get_name(lv_cache_t * cache) return cache->name; } +lv_iter_t * lv_cache_iter_create(lv_cache_t * cache) +{ + LV_ASSERT_NULL(cache); + if(cache == NULL || cache->clz->iter_create_cb == NULL) return NULL; + return cache->clz->iter_create_cb(cache); +} + /********************** * 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 ab488bec6..3e393e873 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/cache/lv_cache.h @@ -13,14 +13,14 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "lv_cache_entry.h" -#include "lv_cache_private.h" + #include "../lv_types.h" -#include "lv_cache_lru_rb.h" +#include "lv_cache_entry.h" + +#include "class/lv_cache_class.h" +#include "instance/lv_cache_instance.h" -#include "lv_image_cache.h" -#include "lv_image_header_cache.h" /********************* * DEFINES *********************/ @@ -215,6 +215,13 @@ void lv_cache_set_name(lv_cache_t * cache, const char * name); */ const char * lv_cache_get_name(lv_cache_t * cache); +/** + * Create an iterator for the cache object. The iterator is used to iterate over all cache entries. + * @param cache The cache object pointer to create the iterator. + * @return Returns a pointer to the created iterator on success, `NULL` on error. + */ +lv_iter_t * lv_cache_iter_create(lv_cache_t * cache); + /************************* * GLOBAL VARIABLES *************************/ 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 e0cc66434..4f280e66e 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 @@ -12,6 +12,7 @@ #include "lv_cache.h" #include "lv_cache_entry_private.h" #include "lv_cache_private.h" + /********************* * DEFINES *********************/ @@ -19,7 +20,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; @@ -51,11 +52,13 @@ void lv_cache_entry_reset_ref(lv_cache_entry_t * entry) LV_ASSERT_NULL(entry); entry->ref_cnt = 0; } + void lv_cache_entry_inc_ref(lv_cache_entry_t * entry) { LV_ASSERT_NULL(entry); entry->ref_cnt++; } + void lv_cache_entry_dec_ref(lv_cache_entry_t * entry) { LV_ASSERT_NULL(entry); @@ -65,35 +68,42 @@ void lv_cache_entry_dec_ref(lv_cache_entry_t * entry) entry->ref_cnt = 0; } } + int32_t lv_cache_entry_get_ref(lv_cache_entry_t * entry) { LV_ASSERT_NULL(entry); return entry->ref_cnt; } + uint32_t lv_cache_entry_get_node_size(lv_cache_entry_t * entry) { return entry->node_size; } + void lv_cache_entry_set_node_size(lv_cache_entry_t * entry, uint32_t node_size) { LV_ASSERT_NULL(entry); entry->node_size = node_size; } + void lv_cache_entry_set_invalid(lv_cache_entry_t * entry, bool is_invalid) { LV_ASSERT_NULL(entry); entry->is_invalid = is_invalid; } + bool lv_cache_entry_is_invalid(lv_cache_entry_t * entry) { LV_ASSERT_NULL(entry); return entry->is_invalid; } + void * lv_cache_entry_get_data(lv_cache_entry_t * entry) { LV_ASSERT_NULL(entry); return (uint8_t *)entry - entry->node_size; } + void * lv_cache_entry_acquire_data(lv_cache_entry_t * entry) { LV_ASSERT_NULL(entry); @@ -101,6 +111,7 @@ void * lv_cache_entry_acquire_data(lv_cache_entry_t * entry) lv_cache_entry_inc_ref(entry); return lv_cache_entry_get_data(entry); } + void lv_cache_entry_release_data(lv_cache_entry_t * entry, void * user_data) { LV_UNUSED(user_data); @@ -113,16 +124,19 @@ void lv_cache_entry_release_data(lv_cache_entry_t * entry, void * user_data) lv_cache_entry_dec_ref(entry); } + lv_cache_entry_t * lv_cache_entry_get_entry(void * data, const uint32_t node_size) { LV_ASSERT_NULL(data); return (lv_cache_entry_t *)((uint8_t *)data + node_size); } + void lv_cache_entry_set_cache(lv_cache_entry_t * entry, const lv_cache_t * cache) { LV_ASSERT_NULL(entry); entry->cache = cache; } + const lv_cache_t * lv_cache_entry_get_cache(const lv_cache_entry_t * entry) { LV_ASSERT_NULL(entry); @@ -133,6 +147,7 @@ uint32_t lv_cache_entry_get_size(const uint32_t node_size) { return node_size + sizeof(lv_cache_entry_t); } + lv_cache_entry_t * lv_cache_entry_alloc(const uint32_t node_size, const lv_cache_t * cache) { void * res = lv_malloc_zeroed(lv_cache_entry_get_size(node_size)); @@ -145,6 +160,7 @@ lv_cache_entry_t * lv_cache_entry_alloc(const uint32_t node_size, const lv_cache lv_cache_entry_init(entry, cache, node_size); return (lv_cache_entry_t *)((uint8_t *)entry + node_size); } + void lv_cache_entry_init(lv_cache_entry_t * entry, const lv_cache_t * cache, const uint32_t node_size) { LV_ASSERT_NULL(entry); @@ -155,6 +171,7 @@ void lv_cache_entry_init(lv_cache_entry_t * entry, const lv_cache_t * cache, con entry->ref_cnt = 0; entry->is_invalid = false; } + void lv_cache_entry_delete(lv_cache_entry_t * entry) { LV_ASSERT_NULL(entry); @@ -162,6 +179,7 @@ void lv_cache_entry_delete(lv_cache_entry_t * entry) void * data = lv_cache_entry_get_data(entry); lv_free(data); } + /********************** * STATIC FUNCTIONS **********************/ 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 947f71d72..3c28f2d92 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 @@ -13,9 +13,8 @@ extern "C" { /********************* * INCLUDES *********************/ -#include "../../osal/lv_os.h" #include "../lv_types.h" -#include "lv_cache_private.h" + /********************* * DEFINES *********************/ 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 f8d41bb9f..7fc2794cb 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 @@ -16,6 +16,7 @@ extern "C" { #include "../lv_types.h" #include "../../osal/lv_os.h" #include "../lv_profiler.h" + /********************* * DEFINES *********************/ @@ -35,6 +36,7 @@ void lv_cache_entry_set_invalid(lv_cache_entry_t * entry, bool is_invalid); void lv_cache_entry_set_cache(lv_cache_entry_t * entry, const lv_cache_t * cache); void * lv_cache_entry_acquire_data(lv_cache_entry_t * entry); void lv_cache_entry_release_data(lv_cache_entry_t * entry, void * user_data); + /************************* * GLOBAL VARIABLES *************************/ 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 c8ac24993..80bd0b989 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 @@ -34,15 +34,13 @@ 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_class_t lv_cache_class_t; typedef int8_t lv_cache_compare_res_t; typedef bool (*lv_cache_create_cb_t)(void * node, void * user_data); @@ -107,10 +105,16 @@ typedef lv_cache_entry_t * (*lv_cache_get_victim_cb)(lv_cache_t * cache, void * 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); +/** + * The cache iterator creation function, used by the cache class to create an iterator for the cache. + * @return A pointer to the created iterator, or NULL if the iterator cannot be created. + */ +typedef lv_iter_t * (*lv_cache_iter_create_cb)(lv_cache_t * cache); + /** * 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 */ @@ -119,7 +123,7 @@ struct lv_cache_ops_t { /** * The cache entry struct */ -struct lv_cache_t { +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. */ @@ -129,7 +133,7 @@ struct lv_cache_t { uint32_t max_size; /**< Maximum size of the cache */ uint32_t size; /**< Current size of the cache */ - lv_cache_ops_t ops; /**< Cache operations struct lv_cache_ops_t */ + lv_cache_ops_t ops; /**< Cache operations struct _lv_cache_ops_t */ lv_mutex_t lock; /**< Cache lock used to protect the cache in multithreading environments */ @@ -143,7 +147,7 @@ struct lv_cache_t { * - 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 */ @@ -155,15 +159,17 @@ struct lv_cache_class_t { 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 */ + + lv_cache_iter_create_cb iter_create_cb; /**< The iterator creation function for cache entries */ }; /*----------------- * 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; /** * Cache entry slot struct @@ -171,7 +177,7 @@ typedef struct lv_cache_slot_size_t lv_cache_slot_size_t; * 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/lv_anim.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.c index 8fc986764..7eab8fbfa 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.c @@ -19,8 +19,16 @@ /********************* * DEFINES *********************/ + +/**Perform linear animations in max 1024 steps. Used in `path_cb`s*/ #define LV_ANIM_RESOLUTION 1024 + +/**log2(LV_ANIM_RESOLUTION)*/ #define LV_ANIM_RES_SHIFT 10 + +/**In an anim. time this bit indicates that the value is speed, and not time*/ +#define LV_ANIM_SPEED_MASK 0x80000000 + #define state LV_GLOBAL_DEFAULT()->anim_state #define anim_ll_p &(state.anim_ll) @@ -36,9 +44,9 @@ static void anim_mark_list_change(void); static void anim_completed_handler(lv_anim_t * a); static int32_t lv_anim_path_cubic_bezier(const lv_anim_t * a, int32_t x1, int32_t y1, int32_t x2, int32_t y2); -static uint32_t convert_speed_to_time(uint32_t speed, int32_t start, int32_t end); +static void lv_anim_pause_for_internal(lv_anim_t * a, uint32_t ms); static void resolve_time(lv_anim_t * a); -static bool remove_concurrent_anims(lv_anim_t * a_current); +static bool remove_concurrent_anims(const lv_anim_t * a_current); static void remove_anim(void * a); /********************** @@ -87,6 +95,11 @@ lv_anim_t * lv_anim_start(const lv_anim_t * a) { LV_TRACE_ANIM("begin"); + /*Do not let two animations for the same 'var' with the same 'exec_cb'*/ + if(a->early_apply && (a->exec_cb || a->custom_exec_cb)) { + remove_concurrent_anims(a); + } + /*Add the new animation to the animation linked list*/ lv_anim_t * new_anim = lv_ll_ins_head(anim_ll_p); LV_ASSERT_MALLOC(new_anim); @@ -97,6 +110,7 @@ lv_anim_t * lv_anim_start(const lv_anim_t * a) if(a->var == a) new_anim->var = new_anim; new_anim->run_round = state.anim_run_round; new_anim->last_timer_run = lv_tick_get(); + new_anim->is_paused = false; /*Set the start value*/ if(new_anim->early_apply) { @@ -109,14 +123,12 @@ lv_anim_t * lv_anim_start(const lv_anim_t * a) resolve_time(new_anim); - /*Do not let two animations for the same 'var' with the same 'exec_cb'*/ - if(a->exec_cb || a->custom_exec_cb) remove_concurrent_anims(new_anim); - + new_anim->current_value = new_anim->path_cb(new_anim); if(new_anim->exec_cb) { - new_anim->exec_cb(new_anim->var, new_anim->start_value); + new_anim->exec_cb(new_anim->var, new_anim->current_value); } if(new_anim->custom_exec_cb) { - new_anim->custom_exec_cb(new_anim, new_anim->start_value); + new_anim->custom_exec_cb(new_anim, new_anim->current_value); } } @@ -137,7 +149,7 @@ uint32_t lv_anim_get_playtime(const lv_anim_t * a) 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; + uint32_t playtime = a->repeat_delay + a->duration + a->reverse_delay + a->reverse_duration; playtime = playtime * repeat_cnt; return playtime; } @@ -218,7 +230,7 @@ uint32_t lv_anim_speed_clamped(uint32_t speed, uint32_t min_time, uint32_t max_t min_time = (min_time + 5) / 10; max_time = (max_time + 5) / 10; - return 0x80000000 + (max_time << 20) + (min_time << 10) + speed; + return LV_ANIM_SPEED_MASK + (max_time << 20) + (min_time << 10) + speed; } @@ -361,11 +373,6 @@ 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); @@ -408,19 +415,19 @@ 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) +void lv_anim_set_reverse_duration(lv_anim_t * a, uint32_t duration) { - a->playback_duration = duration; + a->reverse_duration = duration; } -void lv_anim_set_playback_time(lv_anim_t * a, uint32_t duration) +void lv_anim_set_reverse_time(lv_anim_t * a, uint32_t duration) { - lv_anim_set_playback_duration(a, duration); + lv_anim_set_reverse_duration(a, duration); } -void lv_anim_set_playback_delay(lv_anim_t * a, uint32_t delay) +void lv_anim_set_reverse_delay(lv_anim_t * a, uint32_t delay) { - a->playback_delay = delay; + a->reverse_delay = delay; } void lv_anim_set_repeat_count(lv_anim_t * a, uint32_t cnt) @@ -483,9 +490,50 @@ 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); } +uint32_t lv_anim_resolve_speed(uint32_t speed_or_time, int32_t start, int32_t end) +{ + /*It was a simple time*/ + if((speed_or_time & LV_ANIM_SPEED_MASK) == 0) return speed_or_time; + + uint32_t d = LV_ABS(start - end); + uint32_t speed = speed_or_time & 0x3FF; + uint32_t time = (d * 100) / speed; /*Speed is in 10 units per sec*/ + uint32_t max_time = (speed_or_time >> 20) & 0x3FF; + uint32_t min_time = (speed_or_time >> 10) & 0x3FF; + + return LV_CLAMP(min_time * 10, time, max_time * 10); +} + +bool lv_anim_is_paused(lv_anim_t * a) +{ + LV_ASSERT_NULL(a); + return a->is_paused; +} + +void lv_anim_pause(lv_anim_t * a) +{ + LV_ASSERT_NULL(a); + lv_anim_pause_for_internal(a, LV_ANIM_PAUSE_FOREVER); +} + +void lv_anim_pause_for(lv_anim_t * a, uint32_t ms) +{ + LV_ASSERT_NULL(a); + lv_anim_pause_for_internal(a, ms); +} + +void lv_anim_resume(lv_anim_t * a) +{ + LV_ASSERT_NULL(a); + a->is_paused = false; + a->pause_duration = 0; + a->run_round = state.anim_run_round; +} + /********************** * STATIC FUNCTIONS **********************/ + /** * Periodically handle the animations. * @param param unused @@ -498,11 +546,23 @@ static void anim_timer(lv_timer_t * param) state.anim_run_round = state.anim_run_round ? false : true; lv_anim_t * a = lv_ll_get_head(anim_ll_p); - while(a != NULL) { uint32_t elaps = lv_tick_elaps(a->last_timer_run); - a->act_time += elaps; + if(a->is_paused) { + const uint32_t time_paused = lv_tick_elaps(a->pause_time); + const bool is_pause_over = a->pause_duration != LV_ANIM_PAUSE_FOREVER && time_paused >= a->pause_duration; + + if(is_pause_over) { + const uint32_t pause_overrun = time_paused - a->pause_duration; + a->is_paused = false; + a->act_time += pause_overrun; + a->run_round = !state.anim_run_round; + } + } + else { + a->act_time += elaps; + } a->last_timer_run = lv_tick_get(); /*It can be set by `lv_anim_delete()` typically in `end_cb`. If set then an animation delete @@ -511,9 +571,8 @@ static void anim_timer(lv_timer_t * param) */ state.anim_list_changed = false; - if(a->run_round != state.anim_run_round) { + if(!a->is_paused && a->run_round != state.anim_run_round) { a->run_round = state.anim_run_round; /*The list readying might be reset so need to know which anim has run already*/ - /*The animation will run now for the first time. Call `start_cb`*/ if(!a->start_cb_called && a->act_time >= 0) { @@ -533,8 +592,10 @@ static void anim_timer(lv_timer_t * param) } if(a->act_time >= 0) { + int32_t act_time_original = a->act_time; /*The unclipped version is used later to correctly repeat the animation*/ if(a->act_time > a->duration) a->act_time = a->duration; + int32_t act_time_before_exec = a->act_time; int32_t new_value; new_value = a->path_cb(a); @@ -545,9 +606,15 @@ static void anim_timer(lv_timer_t * param) if(!state.anim_list_changed && a->custom_exec_cb) a->custom_exec_cb(a, new_value); } - /*If the time is elapsed the animation is ready*/ - if(!state.anim_list_changed && a->act_time >= a->duration) { - anim_completed_handler(a); + if(!state.anim_list_changed) { + /*Restore the original time to see is there is over time. + *Restore only if it wasn't changed in the `exec_cb` for some special reasons.*/ + if(a->act_time == act_time_before_exec) a->act_time = act_time_original; + + /*If the time is elapsed the animation is ready*/ + if(a->act_time >= a->duration) { + anim_completed_handler(a); + } } } } @@ -564,20 +631,20 @@ static void anim_timer(lv_timer_t * param) /** * Called when an animation is completed to do the necessary things - * e.g. repeat, play back, delete etc. + * e.g. repeat, play in reverse, delete etc. * @param a pointer to an animation descriptor */ static void anim_completed_handler(lv_anim_t * a) { /*In the end of a forward anim decrement repeat cnt.*/ - if(a->playback_now == 0 && a->repeat_cnt > 0 && a->repeat_cnt != LV_ANIM_REPEAT_INFINITE) { + if(a->reverse_play_in_progress == 0 && a->repeat_cnt > 0 && a->repeat_cnt != LV_ANIM_REPEAT_INFINITE) { a->repeat_cnt--; } - /*Delete the animation if - * - no repeat left and no play back (simple one shot animation) - * - no repeat, play back is enabled and play back is ready*/ - if(a->repeat_cnt == 0 && (a->playback_duration == 0 || a->playback_now == 1)) { + /*Delete animation if + * - no repeat left and no reverse play scheduled (simple one shot animation); or + * - no repeat, reverse play enabled (reverse_duration != 0) and reverse play is completed. */ + if(a->repeat_cnt == 0 && (a->reverse_duration == 0 || a->reverse_play_in_progress == 1)) { /*Delete the animation from the list. * This way the `completed_cb` will see the animations like it's animation is already deleted*/ @@ -592,22 +659,25 @@ static void anim_completed_handler(lv_anim_t * a) } /*If the animation is not deleted then restart it*/ else { - a->act_time = -(int32_t)(a->repeat_delay); /*Restart the animation*/ - /*Swap the start and end values in play back mode*/ - if(a->playback_duration != 0) { - /*If now turning back use the 'playback_pause*/ - if(a->playback_now == 0) a->act_time = -(int32_t)(a->playback_delay); + /*Restart the animation. If the time is over a little compensate it.*/ + int32_t over_time = 0; + if(a->act_time > a->duration) over_time = a->act_time - a->duration; + a->act_time = over_time - (int32_t)(a->repeat_delay); + /*Swap start and end values in reverse-play mode*/ + if(a->reverse_duration != 0) { + /*If now now playing in reverse, use the 'reverse_delay'.*/ + if(a->reverse_play_in_progress == 0) a->act_time = -(int32_t)(a->reverse_delay); - /*Toggle the play back state*/ - a->playback_now = a->playback_now == 0 ? 1 : 0; + /*Toggle reverse-play state*/ + a->reverse_play_in_progress = a->reverse_play_in_progress == 0 ? 1 : 0; /*Swap the start and end values*/ int32_t tmp = a->start_value; a->start_value = a->end_value; a->end_value = tmp; - /*Swap the time and playback_duration*/ + /*Swap the time and reverse_duration*/ tmp = a->duration; - a->duration = a->playback_duration; - a->playback_duration = tmp; + a->duration = a->reverse_duration; + a->reverse_duration = tmp; } } } @@ -635,26 +705,20 @@ static int32_t lv_anim_path_cubic_bezier(const lv_anim_t * a, int32_t x1, int32_ return new_value; } -static uint32_t convert_speed_to_time(uint32_t speed_or_time, int32_t start, int32_t end) +static void lv_anim_pause_for_internal(lv_anim_t * a, uint32_t ms) { - /*It was a simple time*/ - if((speed_or_time & 0x80000000) == 0) return speed_or_time; - uint32_t d = LV_ABS(start - end); - uint32_t speed = speed_or_time & 0x3FF; - uint32_t time = (d * 100) / speed; /*Speed is in 10 units per sec*/ - uint32_t max_time = (speed_or_time >> 20) & 0x3FF; - uint32_t min_time = (speed_or_time >> 10) & 0x3FF; - - return LV_CLAMP(min_time * 10, time, max_time * 10); + a->is_paused = true; + a->pause_time = lv_tick_get(); + a->pause_duration = ms; } static void resolve_time(lv_anim_t * a) { - a->duration = convert_speed_to_time(a->duration, a->start_value, a->end_value); - a->playback_duration = convert_speed_to_time(a->playback_duration, a->start_value, a->end_value); - a->playback_delay = convert_speed_to_time(a->playback_delay, a->start_value, a->end_value); - a->repeat_delay = convert_speed_to_time(a->repeat_delay, a->start_value, a->end_value); + a->duration = lv_anim_resolve_speed(a->duration, a->start_value, a->end_value); + a->reverse_duration = lv_anim_resolve_speed(a->reverse_duration, a->start_value, a->end_value); + a->reverse_delay = lv_anim_resolve_speed(a->reverse_delay, a->start_value, a->end_value); + a->repeat_delay = lv_anim_resolve_speed(a->repeat_delay, a->start_value, a->end_value); } /** @@ -663,7 +727,7 @@ static void resolve_time(lv_anim_t * a) * @param a_current the current animation, use its var and exec_cb as reference to know what to remove * @return true: at least one animation was delete */ -static bool remove_concurrent_anims(lv_anim_t * a_current) +static bool remove_concurrent_anims(const lv_anim_t * a_current) { if(a_current->exec_cb == NULL && a_current->custom_exec_cb == NULL) return false; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.h index 0d626c89b..9cd977106 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_anim.h @@ -25,6 +25,7 @@ extern "C" { #define LV_ANIM_REPEAT_INFINITE 0xFFFFFFFF #define LV_ANIM_PLAYTIME_INFINITE 0xFFFFFFFF +#define LV_ANIM_PAUSE_FOREVER 0xFFFFFFFF /* * Macros used to set cubic-bezier anim parameter. @@ -80,10 +81,9 @@ LV_EXPORT_CONST_INT(LV_ANIM_PLAYTIME_INFINITE); **********************/ /** Can be used to indicate if animations are enabled or disabled in a case*/ -typedef enum { - LV_ANIM_OFF, - LV_ANIM_ON, -} lv_anim_enable_t; +#define LV_ANIM_OFF false +#define LV_ANIM_ON true +typedef bool lv_anim_enable_t; /** Get the current value during an animation*/ typedef int32_t (*lv_anim_path_cb_t)(const lv_anim_t *); @@ -121,36 +121,40 @@ typedef struct { } lv_anim_bezier3_para_t; /** Describes an animation*/ -struct lv_anim_t { - void * var; /**< Variable to animate*/ - lv_anim_exec_xcb_t exec_cb; /**< Function to execute to animate*/ +struct _lv_anim_t { + void * var; /**< Variable (Widget or other user-provided object) to animate */ + lv_anim_exec_xcb_t exec_cb; /**< Function to execute to animate */ lv_anim_custom_exec_cb_t custom_exec_cb; /**< Function to execute to animate, - * same purpose as exec_cb but different parameters*/ - lv_anim_start_cb_t start_cb; /**< Call it when the animation is starts (considering `delay`)*/ - lv_anim_completed_cb_t completed_cb; /**< Call it when the animation is fully completed*/ - lv_anim_deleted_cb_t deleted_cb; /**< Call it when the animation is deleted*/ - lv_anim_get_value_cb_t get_value_cb; /**< Get the current value in relative mode*/ - void * user_data; /**< Custom user data*/ - lv_anim_path_cb_t path_cb; /**< Describe the path (curve) of animations*/ - int32_t start_value; /**< Start value*/ - int32_t current_value; /**< Current value*/ - int32_t end_value; /**< End value*/ - int32_t duration; /**< Animation time in ms*/ - int32_t act_time; /**< Current time in animation. Set to negative to make delay.*/ - uint32_t playback_delay; /**< Wait before play back*/ - uint32_t playback_duration; /**< Duration of playback animation*/ - uint32_t repeat_delay; /**< Wait before repeat*/ - uint32_t repeat_cnt; /**< Repeat count for the animation*/ - union lv_anim_path_para_t { - lv_anim_bezier3_para_t bezier3; /**< Parameter used when path is custom_bezier*/ + * same purpose as exec_cb but different parameters */ + lv_anim_start_cb_t start_cb; /**< Call it when animation is starts (considering `delay`) */ + lv_anim_completed_cb_t completed_cb; /**< Call it when animation is fully completed */ + lv_anim_deleted_cb_t deleted_cb; /**< Call it when animation is deleted */ + lv_anim_get_value_cb_t get_value_cb; /**< Get current value in relative mode */ + void * user_data; /**< Custom user data */ + lv_anim_path_cb_t path_cb; /**< Provides path (curve) of animation */ + int32_t start_value; /**< Start value */ + int32_t current_value; /**< Current value */ + int32_t end_value; /**< End value */ + int32_t duration; /**< Animation duration in ms */ + int32_t act_time; /**< Ms elapsed since animation started. Set to negative to make delay. */ + uint32_t reverse_delay; /**< Wait (in ms) after forward play ends and before reverse play begins. */ + uint32_t reverse_duration; /**< Reverse animation duration in ms */ + uint32_t repeat_delay; /**< Wait before repeating */ + uint32_t repeat_cnt; /**< Repeat count for animation */ + union _lv_anim_path_para_t { + lv_anim_bezier3_para_t bezier3; /**< Parameter used when path is custom_bezier */ } parameter; /* Animation system use these - user shouldn't set */ uint32_t last_timer_run; - uint8_t playback_now : 1; /**< Play back is in progress*/ - uint8_t run_round : 1; /**< Indicates the animation has run in this round*/ - uint8_t start_cb_called : 1; /**< Indicates that the `start_cb` was already called*/ - uint8_t early_apply : 1; /**< 1: Apply start value immediately even is there is `delay`*/ + uint32_t pause_time; /**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 = anim_dsc->start_time; int32_t value = 0; 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 e8fd8be73..0e9651d53 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 diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_area.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_area.c index 4410076d6..34743e8e5 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_area.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_area.c @@ -130,7 +130,7 @@ int8_t lv_area_diff(lv_area_t res_p[], const lv_area_t * a1_p, const lv_area_t * n.x1 = a1_p->x1; n.y1 = a1_p->y1; n.x2 = a1_p->x2; - n.y2 = a1_p->y1 + th; + n.y2 = a1_p->y1 + th - 1; res_p[res_c++] = n; } @@ -138,7 +138,7 @@ int8_t lv_area_diff(lv_area_t res_p[], const lv_area_t * a1_p, const lv_area_t * int32_t bh = a1_h - (a2_p->y2 - a1_p->y1); if(bh > 0 && a2_p->y2 < a1_p->y2) { n.x1 = a1_p->x1; - n.y1 = a2_p->y2; + n.y1 = a2_p->y2 + 1; n.x2 = a1_p->x2; n.y2 = a2_p->y2 + bh; res_p[res_c++] = n; @@ -151,18 +151,18 @@ int8_t lv_area_diff(lv_area_t res_p[], const lv_area_t * a1_p, const lv_area_t * /*Compute the left rectangle*/ int32_t lw = a2_p->x1 - a1_p->x1; - if(lw > 0 && sh > 0) { + if(lw > 0 && sh >= 0) { n.x1 = a1_p->x1; n.y1 = y1; - n.x2 = a1_p->x1 + lw; + n.x2 = a1_p->x1 + lw - 1; n.y2 = y1 + sh; res_p[res_c++] = n; } /*Compute the right rectangle*/ int32_t rw = a1_w - (a2_p->x2 - a1_p->x1); - if(rw > 0) { - n.x1 = a2_p->x2; + if(rw > 0 && sh >= 0) { + n.x1 = a2_p->x2 + 1; n.y1 = y1; n.x2 = a2_p->x2 + rw; n.y2 = y1 + sh; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_array.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_array.c index 39382bcbf..4f7b97a34 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_array.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_array.c @@ -42,13 +42,25 @@ void lv_array_init(lv_array_t * array, uint32_t capacity, uint32_t element_size) array->element_size = element_size; array->data = lv_malloc(capacity * element_size); + array->inner_alloc = true; LV_ASSERT_MALLOC(array->data); } +void lv_array_init_from_buf(lv_array_t * array, void * buf, uint32_t capacity, uint32_t element_size) +{ + LV_ASSERT_NULL(buf); + array->size = 0; + array->capacity = capacity; + array->element_size = element_size; + + array->data = buf; + array->inner_alloc = false; +} + void lv_array_deinit(lv_array_t * array) { if(array->data) { - lv_free(array->data); + if(array->inner_alloc) lv_free(array->data); array->data = NULL; } @@ -122,15 +134,24 @@ lv_result_t lv_array_erase(lv_array_t * array, uint32_t start, uint32_t end) return LV_RESULT_OK; } -void lv_array_resize(lv_array_t * array, uint32_t new_capacity) +bool lv_array_resize(lv_array_t * array, uint32_t new_capacity) { + if(array->inner_alloc == false) { + LV_LOG_WARN("Cannot resize array with external buffer"); + return false; + } + uint8_t * data = lv_realloc(array->data, new_capacity * array->element_size); LV_ASSERT_NULL(data); + + if(data == NULL) return false; + array->data = data; array->capacity = new_capacity; if(array->size > new_capacity) { array->size = new_capacity; } + return true; } lv_result_t lv_array_concat(lv_array_t * array, const lv_array_t * other) @@ -139,7 +160,9 @@ lv_result_t lv_array_concat(lv_array_t * array, const lv_array_t * other) uint32_t size = other->size; if(array->size + size > array->capacity) { /*array is full*/ - lv_array_resize(array, array->size + size); + if(lv_array_resize(array, array->size + size) == false) { + return LV_RESULT_INVALID; + } } uint8_t * data = array->data + array->size * array->element_size; @@ -154,11 +177,18 @@ 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 + LV_ARRAY_DEFAULT_CAPACITY); + if(lv_array_resize(array, array->capacity + LV_ARRAY_DEFAULT_CAPACITY) == false) { + return LV_RESULT_INVALID; + } } + /** + * When the element is NULL, it means that the user wants to add an empty element. + */ uint8_t * data = array->data + array->size * array->element_size; - lv_memcpy(data, element, array->element_size); + if(element) lv_memcpy(data, element, array->element_size); + else lv_memzero(data, array->element_size); + array->size++; return LV_RESULT_OK; } @@ -182,41 +212,6 @@ lv_result_t lv_array_assign(lv_array_t * array, uint32_t index, const void * val 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 e63f56318..c8a159081 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_array.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_array.h @@ -32,12 +32,14 @@ extern "C" { **********************/ /** Description of a array*/ -typedef struct { +struct _lv_array_t { uint8_t * data; uint32_t size; uint32_t capacity; uint32_t element_size; -} lv_array_t; + + bool inner_alloc; /* true: data is allocated by the array; false: data is allocated by the user */ +}; /********************** * GLOBAL PROTOTYPES @@ -51,13 +53,24 @@ typedef struct { */ void lv_array_init(lv_array_t * array, uint32_t capacity, uint32_t element_size); +/** + * Init an array from a buffer. + * @note The buffer must be large enough to store `capacity` elements. The array will not release the buffer and reallocate it. + * The user must ensure that the buffer is valid during the lifetime of the array. And release the buffer when the array is no longer needed. + * @param array pointer to an `lv_array_t` variable to initialize + * @param buf pointer to a buffer to use as the array's data + * @param capacity the initial capacity of the array + * @param element_size the size of an element in bytes + */ +void lv_array_init_from_buf(lv_array_t * array, void * buf, uint32_t capacity, uint32_t element_size); + /** * Resize the array to the given capacity. * @note if the new capacity is smaller than the current size, the array will be truncated. * @param array pointer to an `lv_array_t` variable * @param new_capacity the new capacity of the array */ -void lv_array_resize(lv_array_t * array, uint32_t new_capacity); +bool lv_array_resize(lv_array_t * array, uint32_t new_capacity); /** * Deinit the array, and free the allocated memory @@ -70,28 +83,40 @@ 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 */ -uint32_t lv_array_size(const lv_array_t * array); +static inline uint32_t lv_array_size(const lv_array_t * array) +{ + return array->size; +} /** * 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 */ -uint32_t lv_array_capacity(const lv_array_t * array); +static inline uint32_t lv_array_capacity(const lv_array_t * array) +{ + return array->capacity; +} /** * 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 */ -bool lv_array_is_empty(const lv_array_t * array); +static inline bool lv_array_is_empty(const lv_array_t * array) +{ + return array->size == 0; +} /** * 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 */ -bool lv_array_is_full(const lv_array_t * array); +static inline bool lv_array_is_full(const lv_array_t * array) +{ + return array->size == array->capacity; +} /** * Copy an array to another. @@ -105,7 +130,10 @@ 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 */ -void lv_array_clear(lv_array_t * array); +static inline void lv_array_clear(lv_array_t * array) +{ + array->size = 0; +} /** * Shrink the memory capacity of array if necessary. @@ -144,8 +172,9 @@ lv_result_t lv_array_concat(lv_array_t * array, const lv_array_t * other); /** * Push back element. Adds a new element to the end of the array. * If the array capacity is not enough for the new element, the array will be resized automatically. + * @note If the element is NULL, it will be added as an empty element. * @param array pointer to an `lv_array_t` variable - * @param element pointer to the element to add + * @param element pointer to the element to add. NULL to push an empty element. * @return LV_RESULT_OK: success, otherwise: error */ lv_result_t lv_array_push_back(lv_array_t * array, const void * element); @@ -172,13 +201,19 @@ 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 */ -void * lv_array_front(const lv_array_t * array); +static inline void * lv_array_front(const lv_array_t * array) +{ + return lv_array_at(array, 0); +} /** * Returns a pointer to the last element in the array. * @param array pointer to an `lv_array_t` variable */ -void * lv_array_back(const lv_array_t * array); +static inline void * lv_array_back(const lv_array_t * array) +{ + return lv_array_at(array, lv_array_size(array) - 1); +} /********************** * MACROS diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_async.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_async.c index e1657aeb4..b2e718dd3 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_async.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_async.c @@ -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_circle_buf.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_circle_buf.c new file mode 100644 index 000000000..455435c8d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_circle_buf.c @@ -0,0 +1,295 @@ +/** + * @file lv_circle_buf.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_assert.h" + +#include "lv_circle_buf.h" +#include "lv_array.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_circle_buf_t { + lv_array_t array; + uint32_t head; + uint32_t tail; /**< The next write position */ + + bool inner_alloc; /**< true: the array is allocated by the buffer, false: the array is created from an external buffer */ +}; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void circle_buf_prepare_empty(lv_circle_buf_t * circle_buf); + +/********************** + * GLOBAL VARIABLES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_circle_buf_t * lv_circle_buf_create(const uint32_t capacity, const uint32_t element_size) +{ + lv_circle_buf_t * circle_buf = lv_malloc(sizeof(lv_circle_buf_t)); + LV_ASSERT_MALLOC(circle_buf); + + if(circle_buf == NULL) { + return NULL; + } + + lv_array_init(&circle_buf->array, capacity, element_size); + circle_buf->head = 0; + circle_buf->tail = 0; + circle_buf->inner_alloc = true; + + circle_buf_prepare_empty(circle_buf); + + return circle_buf; +} + +lv_circle_buf_t * lv_circle_buf_create_from_buf(void * buf, const uint32_t capacity, const uint32_t element_size) +{ + LV_ASSERT_NULL(buf); + + lv_circle_buf_t * circle_buf = lv_malloc(sizeof(lv_circle_buf_t)); + LV_ASSERT_MALLOC(circle_buf); + + if(circle_buf == NULL) { + return NULL; + } + + lv_array_init_from_buf(&circle_buf->array, buf, capacity, element_size); + circle_buf->head = 0; + circle_buf->tail = 0; + circle_buf->inner_alloc = false; + + circle_buf_prepare_empty(circle_buf); + + return circle_buf; +} + +lv_circle_buf_t * lv_circle_buf_create_from_array(const lv_array_t * array) +{ + LV_ASSERT_NULL(array); + if(array == NULL) { + return NULL; + } + + lv_circle_buf_t * circle_buf = lv_malloc(sizeof(lv_circle_buf_t)); + LV_ASSERT_MALLOC(circle_buf); + + if(circle_buf == NULL) { + return NULL; + } + + circle_buf->array = *array; + circle_buf->head = 0; + circle_buf->tail = 0; + circle_buf->inner_alloc = false; + + circle_buf_prepare_empty(circle_buf); + + return circle_buf; +} + +lv_result_t lv_circle_buf_resize(lv_circle_buf_t * circle_buf, const uint32_t capacity) +{ + LV_ASSERT_NULL(circle_buf); + + if(lv_array_resize(&circle_buf->array, capacity) == false) { + return LV_RESULT_INVALID; + } + + circle_buf->head = 0; + circle_buf->tail = 0; + + circle_buf_prepare_empty(circle_buf); + + return LV_RESULT_OK; +} + +void lv_circle_buf_destroy(lv_circle_buf_t * circle_buf) +{ + LV_ASSERT_NULL(circle_buf); + + lv_array_deinit(&circle_buf->array); + + lv_free(circle_buf); +} + +uint32_t lv_circle_buf_size(const lv_circle_buf_t * circle_buf) +{ + LV_ASSERT_NULL(circle_buf); + + return circle_buf->tail - circle_buf->head; +} + +uint32_t lv_circle_buf_capacity(const lv_circle_buf_t * circle_buf) +{ + LV_ASSERT_NULL(circle_buf); + + return lv_array_capacity(&circle_buf->array); +} + +uint32_t lv_circle_buf_remain(const lv_circle_buf_t * circle_buf) +{ + LV_ASSERT_NULL(circle_buf); + + return lv_circle_buf_capacity(circle_buf) - lv_circle_buf_size(circle_buf); +} + +bool lv_circle_buf_is_empty(const lv_circle_buf_t * circle_buf) +{ + LV_ASSERT_NULL(circle_buf); + + return !lv_circle_buf_size(circle_buf); +} + +bool lv_circle_buf_is_full(const lv_circle_buf_t * circle_buf) +{ + LV_ASSERT_NULL(circle_buf); + + return !lv_circle_buf_remain(circle_buf); +} + +void lv_circle_buf_reset(lv_circle_buf_t * circle_buf) +{ + LV_ASSERT_NULL(circle_buf); + + circle_buf->head = 0; + circle_buf->tail = 0; +} + +void * lv_circle_buf_head(const lv_circle_buf_t * circle_buf) +{ + LV_ASSERT_NULL(circle_buf); + + return lv_array_at(&circle_buf->array, + circle_buf->head % lv_circle_buf_capacity(circle_buf)); +} + +void * lv_circle_buf_tail(const lv_circle_buf_t * circle_buf) +{ + LV_ASSERT_NULL(circle_buf); + + return lv_array_at(&circle_buf->array, + circle_buf->tail % lv_circle_buf_capacity(circle_buf)); +} + +lv_result_t lv_circle_buf_read(lv_circle_buf_t * circle_buf, void * data) +{ + LV_ASSERT_NULL(circle_buf); + + if(lv_circle_buf_is_empty(circle_buf)) { + circle_buf->head = 0; + circle_buf->tail = 0; + return LV_RESULT_INVALID; + } + + lv_circle_buf_peek_at(circle_buf, 0, data); + circle_buf->head++; + + return LV_RESULT_OK; +} + +lv_result_t lv_circle_buf_write(lv_circle_buf_t * circle_buf, const void * data) +{ + LV_ASSERT_NULL(circle_buf); + + if(lv_circle_buf_is_full(circle_buf)) { + return LV_RESULT_INVALID; + } + + lv_array_assign(&circle_buf->array, circle_buf->tail % lv_circle_buf_capacity(circle_buf), data); + circle_buf->tail++; + + return LV_RESULT_OK; +} + +uint32_t lv_circle_buf_fill(lv_circle_buf_t * circle_buf, uint32_t count, lv_circle_buf_fill_cb_t fill_cb, + void * user_data) +{ + LV_ASSERT_NULL(circle_buf); + LV_ASSERT_NULL(fill_cb); + + uint32_t filled = 0; + while(count > 0 && !lv_circle_buf_is_full(circle_buf)) { + void * data = lv_circle_buf_tail(circle_buf); + if(fill_cb(data, circle_buf->array.element_size, (int32_t)filled, user_data) == LV_RESULT_OK) { + circle_buf->tail++; + filled++; + } + else break; + + count--; + } + + return filled; +} + +lv_result_t lv_circle_buf_skip(lv_circle_buf_t * circle_buf) +{ + LV_ASSERT_NULL(circle_buf); + + if(lv_circle_buf_is_empty(circle_buf)) { + circle_buf->head = 0; + circle_buf->tail = 0; + return LV_RESULT_INVALID; + } + + circle_buf->head++; + + return LV_RESULT_OK; +} + +lv_result_t lv_circle_buf_peek(const lv_circle_buf_t * circle_buf, void * data) +{ + LV_ASSERT_NULL(circle_buf); + LV_ASSERT_NULL(data); + + return lv_circle_buf_peek_at(circle_buf, 0, data); +} + +lv_result_t lv_circle_buf_peek_at(const lv_circle_buf_t * circle_buf, const uint32_t index, void * data) +{ + LV_ASSERT_NULL(circle_buf); + LV_ASSERT_NULL(data); + + const uint32_t real_index = (index % lv_circle_buf_size(circle_buf) + circle_buf->head) % lv_circle_buf_capacity( + circle_buf); + lv_memcpy(data, lv_array_at(&circle_buf->array, real_index), circle_buf->array.element_size); + + return LV_RESULT_OK; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void circle_buf_prepare_empty(lv_circle_buf_t * circle_buf) +{ + const uint32_t required = lv_array_capacity(&circle_buf->array) - lv_array_size(&circle_buf->array); + for(uint32_t i = 0; i < required; i++) lv_array_push_back(&circle_buf->array, NULL); +} diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_circle_buf.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_circle_buf.h new file mode 100644 index 000000000..2b4f27bf8 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_circle_buf.h @@ -0,0 +1,191 @@ +/** +* @file lv_circle_buf.h +* + */ + + +#ifndef LV_CIRCLE_BUF_H +#define LV_CIRCLE_BUF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef bool (*lv_circle_buf_fill_cb_t)(void * buf, uint32_t buff_len, int32_t index, void * user_data); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a circle buffer + * @param capacity the maximum number of elements in the buffer + * @param element_size the size of an element in bytes + * @return pointer to the created buffer + */ +lv_circle_buf_t * lv_circle_buf_create(uint32_t capacity, uint32_t element_size); + +/** + * Create a circle buffer from an existing buffer + * @param buf pointer to a buffer + * @param capacity the maximum number of elements in the buffer + * @param element_size the size of an element in bytes + * @return pointer to the created buffer + */ +lv_circle_buf_t * lv_circle_buf_create_from_buf(void * buf, uint32_t capacity, uint32_t element_size); + +/** + * Create a circle buffer from an existing array + * @param array pointer to an array + * @return pointer to the created buffer + */ +lv_circle_buf_t * lv_circle_buf_create_from_array(const lv_array_t * array); + +/** + * Resize the buffer + * @param circle_buf pointer to a buffer + * @param capacity the new capacity of the buffer + * @return LV_RESULT_OK: the buffer is resized; LV_RESULT_INVALID: the buffer is not resized + */ +lv_result_t lv_circle_buf_resize(lv_circle_buf_t * circle_buf, uint32_t capacity); + +/** + * Destroy a circle buffer + * @param circle_buf pointer to buffer + */ +void lv_circle_buf_destroy(lv_circle_buf_t * circle_buf); + +/** + * Get the size of the buffer + * @param circle_buf pointer to buffer + * @return the number of elements in the buffer + */ +uint32_t lv_circle_buf_size(const lv_circle_buf_t * circle_buf); + +/** + * Get the capacity of the buffer + * @param circle_buf pointer to buffer + * @return the maximum number of elements in the buffer + */ +uint32_t lv_circle_buf_capacity(const lv_circle_buf_t * circle_buf); + +/** + * Get the remaining space in the buffer + * @param circle_buf pointer to buffer + * @return the number of elements that can be written to the buffer + */ +uint32_t lv_circle_buf_remain(const lv_circle_buf_t * circle_buf); + +/** + * Check if the buffer is empty + * @param circle_buf pointer to buffer + * @return true: the buffer is empty; false: the buffer is not empty + */ +bool lv_circle_buf_is_empty(const lv_circle_buf_t * circle_buf); + +/** + * Check if the buffer is full + * @param circle_buf pointer to buffer + * @return true: the buffer is full; false: the buffer is not full + */ +bool lv_circle_buf_is_full(const lv_circle_buf_t * circle_buf); + +/** + * Reset the buffer + * @param circle_buf pointer to buffer + * @return LV_RESULT_OK: the buffer is reset; LV_RESULT_INVALID: the buffer is not reset + */ +void lv_circle_buf_reset(lv_circle_buf_t * circle_buf); + +/** + * Get the head of the buffer + * @param circle_buf pointer to buffer + * @return pointer to the head of the buffer + */ +void * lv_circle_buf_head(const lv_circle_buf_t * circle_buf); + +/** + * Get the tail of the buffer + * @param circle_buf pointer to buffer + * @return pointer to the tail of the buffer + */ +void * lv_circle_buf_tail(const lv_circle_buf_t * circle_buf); + +/** + * Read a value + * @param circle_buf pointer to buffer + * @param data pointer to a variable to store the read value + * @return LV_RESULT_OK: the value is read; LV_RESULT_INVALID: the value is not read + */ +lv_result_t lv_circle_buf_read(lv_circle_buf_t * circle_buf, void * data); + +/** + * Write a value + * @param circle_buf pointer to buffer + * @param data pointer to the value to write + * @return LV_RESULT_OK: the value is written; LV_RESULT_INVALID: the value is not written + */ +lv_result_t lv_circle_buf_write(lv_circle_buf_t * circle_buf, const void * data); + +/** + * Fill the buffer with values + * @param circle_buf pointer to buffer + * @param count the number of values to fill + * @param fill_cb the callback function to fill the buffer + * @param user_data + * @return the number of values filled + */ +uint32_t lv_circle_buf_fill(lv_circle_buf_t * circle_buf, uint32_t count, lv_circle_buf_fill_cb_t fill_cb, + void * user_data); + +/** + * Skip a value + * @param circle_buf pointer to buffer + * @return LV_RESULT_OK: the value is skipped; LV_RESULT_INVALID: the value is not skipped + */ +lv_result_t lv_circle_buf_skip(lv_circle_buf_t * circle_buf); + +/** + * Peek a value + * @param circle_buf pointer to buffer + * @param data pointer to a variable to store the peeked value + * @return LV_RESULT_OK: the value is peeked; LV_RESULT_INVALID: the value is not peeked + */ +lv_result_t lv_circle_buf_peek(const lv_circle_buf_t * circle_buf, void * data); + +/** + * Peek a value at an index + * @param circle_buf pointer to buffer + * @param index the index of the value to peek, if the index is greater than the size of the buffer, it will return looply. + * @param data pointer to a variable to store the peeked value + * @return LV_RESULT_OK: the value is peeked; LV_RESULT_INVALID: the value is not peeked + */ +lv_result_t lv_circle_buf_peek_at(const lv_circle_buf_t * circle_buf, uint32_t index, void * data); + +/************************* + * GLOBAL VARIABLES + *************************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CIRCLE_BUF_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_color.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_color.c index d62f280b1..fa8d3e726 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 * */ @@ -51,21 +51,34 @@ uint8_t lv_color_format_get_bpp(lv_color_format_t cf) return 2; case LV_COLOR_FORMAT_I4: case LV_COLOR_FORMAT_A4: + case LV_COLOR_FORMAT_NEMA_TSC4: return 4; + case LV_COLOR_FORMAT_NEMA_TSC6: + case LV_COLOR_FORMAT_NEMA_TSC6A: + case LV_COLOR_FORMAT_NEMA_TSC6AP: + return 6; case LV_COLOR_FORMAT_L8: case LV_COLOR_FORMAT_A8: case LV_COLOR_FORMAT_I8: + case LV_COLOR_FORMAT_ARGB2222: return 8; - + case LV_COLOR_FORMAT_NEMA_TSC12: + case LV_COLOR_FORMAT_NEMA_TSC12A: + return 12; case LV_COLOR_FORMAT_RGB565A8: case LV_COLOR_FORMAT_RGB565: + case LV_COLOR_FORMAT_RGB565_SWAPPED: + case LV_COLOR_FORMAT_YUY2: case LV_COLOR_FORMAT_AL88: + case LV_COLOR_FORMAT_ARGB1555: + case LV_COLOR_FORMAT_ARGB4444: return 16; case LV_COLOR_FORMAT_ARGB8565: case LV_COLOR_FORMAT_RGB888: return 24; case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED: case LV_COLOR_FORMAT_XRGB8888: return 32; @@ -89,7 +102,11 @@ bool lv_color_format_has_alpha(lv_color_format_t cf) case LV_COLOR_FORMAT_RGB565A8: case LV_COLOR_FORMAT_ARGB8565: case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED: case LV_COLOR_FORMAT_AL88: + case LV_COLOR_FORMAT_ARGB2222: + case LV_COLOR_FORMAT_ARGB1555: + case LV_COLOR_FORMAT_ARGB4444: return true; default: return false; @@ -378,6 +395,7 @@ 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 6328c0d2c..0116de1e1 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 * */ @@ -53,8 +53,8 @@ enum { LV_OPA_COVER = 255, }; -#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 /**< Fully transparent if opa <= LV_OPA_MIN */ +#define LV_OPA_MAX 253 /**< Fully cover if opa >= LV_OPA_MAX */ /** * Get the pixel size of a color format in bits, bpp @@ -69,15 +69,27 @@ enum { (cf) == LV_COLOR_FORMAT_A2 ? 2 : \ (cf) == LV_COLOR_FORMAT_I4 ? 4 : \ (cf) == LV_COLOR_FORMAT_A4 ? 4 : \ + (cf) == LV_COLOR_FORMAT_NEMA_TSC4 ? 4 : \ + (cf) == LV_COLOR_FORMAT_NEMA_TSC6 ? 6 : \ + (cf) == LV_COLOR_FORMAT_NEMA_TSC6A ? 6 : \ + (cf) == LV_COLOR_FORMAT_NEMA_TSC6AP ? 6 : \ (cf) == LV_COLOR_FORMAT_L8 ? 8 : \ (cf) == LV_COLOR_FORMAT_A8 ? 8 : \ (cf) == LV_COLOR_FORMAT_I8 ? 8 : \ + (cf) == LV_COLOR_FORMAT_ARGB2222 ? 8 : \ + (cf) == LV_COLOR_FORMAT_NEMA_TSC12 ? 12 : \ + (cf) == LV_COLOR_FORMAT_NEMA_TSC12A ? 12 : \ (cf) == LV_COLOR_FORMAT_AL88 ? 16 : \ (cf) == LV_COLOR_FORMAT_RGB565 ? 16 : \ + (cf) == LV_COLOR_FORMAT_RGB565_SWAPPED ? 16 : \ (cf) == LV_COLOR_FORMAT_RGB565A8 ? 16 : \ + (cf) == LV_COLOR_FORMAT_YUY2 ? 16 : \ + (cf) == LV_COLOR_FORMAT_ARGB1555 ? 16 : \ + (cf) == LV_COLOR_FORMAT_ARGB4444 ? 16 : \ (cf) == LV_COLOR_FORMAT_ARGB8565 ? 24 : \ (cf) == LV_COLOR_FORMAT_RGB888 ? 24 : \ (cf) == LV_COLOR_FORMAT_ARGB8888 ? 32 : \ + (cf) == LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED ? 32 : \ (cf) == LV_COLOR_FORMAT_XRGB8888 ? 32 : \ 0 \ ) @@ -143,16 +155,21 @@ typedef enum { 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_AL88 = 0x15, /**< L8 with alpha >*/ + LV_COLOR_FORMAT_RGB565_SWAPPED = 0x1B, /*3 byte (+alpha) formats*/ LV_COLOR_FORMAT_RGB888 = 0x0F, LV_COLOR_FORMAT_ARGB8888 = 0x10, LV_COLOR_FORMAT_XRGB8888 = 0x11, + LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED = 0x1A, /*Formats not supported by software renderer but kept here so GPU can use it*/ LV_COLOR_FORMAT_A1 = 0x0B, LV_COLOR_FORMAT_A2 = 0x0C, LV_COLOR_FORMAT_A4 = 0x0D, + LV_COLOR_FORMAT_ARGB1555 = 0x16, + LV_COLOR_FORMAT_ARGB4444 = 0x17, + LV_COLOR_FORMAT_ARGB2222 = 0X18, /* reference to https://wiki.videolan.org/YUV/ */ /*YUV planar formats*/ @@ -170,6 +187,17 @@ typedef enum { LV_COLOR_FORMAT_YUV_END = LV_COLOR_FORMAT_UYVY, + LV_COLOR_FORMAT_PROPRIETARY_START = 0x30, + + LV_COLOR_FORMAT_NEMA_TSC_START = LV_COLOR_FORMAT_PROPRIETARY_START, + LV_COLOR_FORMAT_NEMA_TSC4 = LV_COLOR_FORMAT_NEMA_TSC_START, + LV_COLOR_FORMAT_NEMA_TSC6 = 0x31, + LV_COLOR_FORMAT_NEMA_TSC6A = 0x32, + LV_COLOR_FORMAT_NEMA_TSC6AP = 0x33, + LV_COLOR_FORMAT_NEMA_TSC12 = 0x34, + LV_COLOR_FORMAT_NEMA_TSC12A = 0x35, + LV_COLOR_FORMAT_NEMA_TSC_END = LV_COLOR_FORMAT_NEMA_TSC12A, + /*Color formats in which LVGL can render*/ #if LV_COLOR_DEPTH == 1 LV_COLOR_FORMAT_NATIVE = LV_COLOR_FORMAT_I1, @@ -206,8 +234,8 @@ typedef enum { #define LV_COLOR_MAKE(r8, g8, b8) {b8, g8, r8} -#define LV_OPA_MIX2(a1, a2) (((int32_t)(a1) * (a2)) >> 8) -#define LV_OPA_MIX3(a1, a2, a3) (((int32_t)(a1) * (a2) * (a3)) >> 16) +#define LV_OPA_MIX2(a1, a2) ((lv_opa_t)(((int32_t)(a1) * (a2)) >> 8)) +#define LV_OPA_MIX3(a1, a2, a3) ((lv_opa_t)(((int32_t)(a1) * (a2) * (a3)) >> 16)) /********************** * GLOBAL PROTOTYPES @@ -412,6 +440,17 @@ uint8_t lv_color24_luminance(const uint8_t * c); */ uint8_t lv_color32_luminance(lv_color32_t c); + +/** + * Swap the endianness of an rgb565 color + * @param c a color + * @return the swapped color + */ +static inline uint16_t LV_ATTRIBUTE_FAST_MEM lv_color_swap_16(uint16_t c) +{ + return (c >> 8) | (c << 8); +} + /********************** * 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 a26f2b453..b9d281115 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.c @@ -52,9 +52,28 @@ lv_color32_t lv_color_mix32(lv_color32_t fg, lv_color32_t bg) 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; + bg.red = LV_UDIV255((uint32_t)((uint32_t)fg.red * fg.alpha + (uint32_t)bg.red * (255 - fg.alpha))); + bg.green = LV_UDIV255((uint32_t)((uint32_t)fg.green * fg.alpha + (uint32_t)bg.green * (255 - fg.alpha))); + bg.blue = LV_UDIV255((uint32_t)((uint32_t)fg.blue * fg.alpha + (uint32_t)bg.blue * (255 - fg.alpha))); + return bg; +} + +lv_color32_t lv_color_mix32_premultiplied(lv_color32_t fg, lv_color32_t bg) +{ + if(fg.alpha >= LV_OPA_MAX) { + return fg; /* Fully opaque foreground replaces background */ + } + if(fg.alpha <= LV_OPA_MIN) { + return bg; /* Fully transparent foreground, return background */ + } + + uint32_t inv_fg_alpha = LV_OPA_MAX - fg.alpha; + + /* Premultiplied blending */ + bg.red = fg.red + ((bg.red * inv_fg_alpha) >> 8); + bg.green = fg.green + ((bg.green * inv_fg_alpha) >> 8); + bg.blue = fg.blue + ((bg.blue * inv_fg_alpha) >> 8); + return bg; } @@ -69,6 +88,27 @@ void lv_color_filter_dsc_init(lv_color_filter_dsc_t * dsc, lv_color_filter_cb_t dsc->filter_cb = cb; } +lv_color32_t lv_color_over32(lv_color32_t fg, lv_color32_t bg) +{ + if(fg.alpha >= LV_OPA_MAX || bg.alpha <= LV_OPA_MIN) { + return fg; + } + else if(fg.alpha <= LV_OPA_MIN) { + return bg; + } + else if(bg.alpha == 255) { + return lv_color_mix32(fg, bg); + } + + lv_opa_t res_alpha = 255 - LV_OPA_MIX2(255 - fg.alpha, 255 - bg.alpha); + lv_opa_t ratio = (uint32_t)((uint32_t)fg.alpha * 255) / res_alpha; + fg.alpha = ratio; + lv_color32_t res = lv_color_mix32(fg, bg); + res.alpha = res_alpha; + + return res; +} + /********************** * 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 0a59de35d..6905d1ab8 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_color_op.h @@ -26,11 +26,11 @@ 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); -struct lv_color_filter_dsc_t { +struct _lv_color_filter_dsc_t { lv_color_filter_cb_t filter_cb; void * user_data; }; @@ -58,6 +58,21 @@ lv_color_t LV_ATTRIBUTE_FAST_MEM lv_color_mix(lv_color_t c1, lv_color_t c2, uint */ lv_color32_t lv_color_mix32(lv_color32_t fg, lv_color32_t bg); +/** + * @brief Blends two premultiplied ARGB8888 colors while maintaining correct alpha compositing. + * + * This function correctly blends the foreground (fg) and background (bg) colors, + * ensuring that the output remains in a premultiplied alpha format. + * + * @param fg The foreground color in premultiplied ARGB8888 format. + * @param bg The background color in premultiplied ARGB8888 format. + * @return The resulting blended color in premultiplied ARGB8888 format. + * + * @note If the foreground is fully opaque, it is returned as is. + * @note If the foreground is fully transparent, the background is returned. + */ +lv_color32_t lv_color_mix32_premultiplied(lv_color32_t fg, lv_color32_t bg); + /** * Get the brightness of a color * @param c a color @@ -67,6 +82,14 @@ 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); +/** + * Blend two colors that have not been pre-multiplied using their alpha values + * @param fg the foreground color + * @param bg the background color + * @return result color + */ +lv_color32_t lv_color_over32(lv_color32_t fg, lv_color32_t bg); + /********************** * PREDEFINED COLORS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_event.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_event.c index ec985ed25..81a0e9603 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_event.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_event.c @@ -27,6 +27,15 @@ * STATIC PROTOTYPES **********************/ +/* Traverse the list to delete the objects marked for deletion */ +static void cleanup_event_list(lv_event_list_t * list); +static void cleanup_event_list_core(lv_array_t * array); + +static void event_mark_deleting(lv_event_list_t * list, lv_event_dsc_t * dsc); +static bool event_is_marked_deleting(lv_event_dsc_t * dsc); +static uint32_t event_array_size(lv_event_list_t * list); +static lv_event_dsc_t ** event_array_at(lv_event_list_t * list, uint32_t index); + /********************** * STATIC VARIABLES **********************/ @@ -63,26 +72,49 @@ 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) { if(list == NULL) return LV_RESULT_OK; + if(e->deleted) return LV_RESULT_INVALID; - uint32_t i = 0; - lv_event_dsc_t ** dsc = lv_array_front(list); - uint32_t size = lv_array_size(list); - for(i = 0; i < size; i++) { - if(dsc[i]->cb == NULL) continue; - bool is_preprocessed = (dsc[i]->filter & LV_EVENT_PREPROCESS) != 0; + /* When obj is deleted in its own event, it will cause the `list->array` header to be released, + * but the content still exists, which leads to memory leakage. + * Therefore, back up the header in advance, + * which can strive to release the memory and prevent used-after-free. */ + lv_array_t back_array_head = list->array; + + /* Dealing with the problem of nested event deletion event */ + const bool is_traversing = list->is_traversing; + list->is_traversing = true; + + lv_result_t res = LV_RESULT_OK; + const uint32_t size = event_array_size(list); + for(uint32_t i = 0; i < size && !e->deleted; i++) { + lv_event_dsc_t * dsc = *event_array_at(list, i); + if(dsc->cb == NULL) continue; + if(event_is_marked_deleting(dsc)) continue; + const bool is_preprocessed = (dsc->filter & LV_EVENT_PREPROCESS) != 0; if(is_preprocessed != preprocess) continue; - lv_event_code_t filter = dsc[i]->filter & ~LV_EVENT_PREPROCESS; + lv_event_code_t filter = dsc->filter & ~LV_EVENT_PREPROCESS; if(filter == LV_EVENT_ALL || filter == e->code) { - e->user_data = dsc[i]->user_data; - dsc[i]->cb(e); - if(e->stop_processing) return LV_RESULT_OK; + e->user_data = dsc->user_data; + dsc->cb(e); + if(e->stop_processing) break; /*Stop if the object is deleted*/ - if(e->deleted) return LV_RESULT_INVALID; - + if(e->deleted) { + res = LV_RESULT_INVALID; + break; + } } } - return LV_RESULT_OK; + + if(is_traversing) return res; + + if(e->deleted) cleanup_event_list_core(&back_array_head); + else { + list->is_traversing = false; + cleanup_event_list(list); + } + + return res; } lv_event_dsc_t * lv_event_add(lv_event_list_t * list, lv_event_cb_t cb, lv_event_code_t filter, @@ -95,12 +127,12 @@ lv_event_dsc_t * lv_event_add(lv_event_list_t * list, lv_event_cb_t cb, lv_event dsc->filter = filter; dsc->user_data = user_data; - if(lv_array_size(list) == 0) { + if(event_array_size(list) == 0) { /*event list hasn't been initialized.*/ - lv_array_init(list, 1, sizeof(lv_event_dsc_t *)); + lv_array_init(&list->array, 1, sizeof(lv_event_dsc_t *)); } - lv_array_push_back(list, &dsc); + lv_array_push_back(&list->array, &dsc); return dsc; } @@ -109,12 +141,12 @@ bool lv_event_remove_dsc(lv_event_list_t * list, lv_event_dsc_t * dsc) LV_ASSERT_NULL(list); LV_ASSERT_NULL(dsc); - int size = lv_array_size(list); - lv_event_dsc_t ** events = lv_array_front(list); - for(int i = 0; i < size; i++) { - if(events[i] == dsc) { - lv_free(dsc); - lv_array_remove(list, i); + const uint32_t size = event_array_size(list); + for(uint32_t i = 0; i < size; i++) { + lv_event_dsc_t * event = *event_array_at(list, i); + if(event == dsc) { + event_mark_deleting(list, event); + cleanup_event_list(list); return true; } } @@ -125,14 +157,13 @@ bool lv_event_remove_dsc(lv_event_list_t * list, lv_event_dsc_t * dsc) uint32_t lv_event_get_count(lv_event_list_t * list) { LV_ASSERT_NULL(list); - return lv_array_size(list); + return event_array_size(list); } lv_event_dsc_t * lv_event_get_dsc(lv_event_list_t * list, uint32_t index) { LV_ASSERT_NULL(list); - lv_event_dsc_t ** dsc; - dsc = lv_array_at(list, index); + lv_event_dsc_t ** dsc = event_array_at(list, index); return dsc ? *dsc : NULL; } @@ -153,19 +184,19 @@ bool lv_event_remove(lv_event_list_t * list, uint32_t index) { LV_ASSERT_NULL(list); lv_event_dsc_t * dsc = lv_event_get_dsc(list, index); - lv_free(dsc); - return lv_array_remove(list, index); + if(dsc == NULL) return false; + event_mark_deleting(list, dsc); + cleanup_event_list(list); + return true; } void lv_event_remove_all(lv_event_list_t * list) { LV_ASSERT_NULL(list); - int size = lv_array_size(list); - lv_event_dsc_t ** dsc = lv_array_front(list); - for(int i = 0; i < size; i++) { - lv_free(dsc[i]); - } - lv_array_deinit(list); + const uint32_t size = event_array_size(list); + for(uint32_t i = 0; i < size; i++) + event_mark_deleting(list, *event_array_at(list, i)); + cleanup_event_list(list); } void * lv_event_get_current_target(lv_event_t * e) @@ -219,6 +250,155 @@ void lv_event_mark_deleted(void * target) } } +const char * lv_event_code_get_name(lv_event_code_t code) +{ + /*Remove the preprocess flag*/ + code &= ~LV_EVENT_PREPROCESS; + +#define ENUM_CASE(x) case LV_##x: return #x + + switch(code) { + ENUM_CASE(EVENT_ALL); + + /** Input device events*/ + ENUM_CASE(EVENT_PRESSED); + ENUM_CASE(EVENT_PRESSING); + ENUM_CASE(EVENT_PRESS_LOST); + ENUM_CASE(EVENT_SHORT_CLICKED); + ENUM_CASE(EVENT_SINGLE_CLICKED); + ENUM_CASE(EVENT_DOUBLE_CLICKED); + ENUM_CASE(EVENT_TRIPLE_CLICKED); + ENUM_CASE(EVENT_LONG_PRESSED); + ENUM_CASE(EVENT_LONG_PRESSED_REPEAT); + ENUM_CASE(EVENT_CLICKED); + ENUM_CASE(EVENT_RELEASED); + ENUM_CASE(EVENT_SCROLL_BEGIN); + ENUM_CASE(EVENT_SCROLL_THROW_BEGIN); + ENUM_CASE(EVENT_SCROLL_END); + ENUM_CASE(EVENT_SCROLL); + ENUM_CASE(EVENT_GESTURE); + ENUM_CASE(EVENT_KEY); + ENUM_CASE(EVENT_ROTARY); + ENUM_CASE(EVENT_FOCUSED); + ENUM_CASE(EVENT_DEFOCUSED); + ENUM_CASE(EVENT_LEAVE); + ENUM_CASE(EVENT_HIT_TEST); + ENUM_CASE(EVENT_INDEV_RESET); + ENUM_CASE(EVENT_HOVER_OVER); + ENUM_CASE(EVENT_HOVER_LEAVE); + + /** Drawing events*/ + ENUM_CASE(EVENT_COVER_CHECK); + ENUM_CASE(EVENT_REFR_EXT_DRAW_SIZE); + ENUM_CASE(EVENT_DRAW_MAIN_BEGIN); + ENUM_CASE(EVENT_DRAW_MAIN); + ENUM_CASE(EVENT_DRAW_MAIN_END); + ENUM_CASE(EVENT_DRAW_POST_BEGIN); + ENUM_CASE(EVENT_DRAW_POST); + ENUM_CASE(EVENT_DRAW_POST_END); + ENUM_CASE(EVENT_DRAW_TASK_ADDED); + + /** Special events*/ + ENUM_CASE(EVENT_VALUE_CHANGED); + ENUM_CASE(EVENT_INSERT); + ENUM_CASE(EVENT_REFRESH); + ENUM_CASE(EVENT_READY); + ENUM_CASE(EVENT_CANCEL); + + /** Other events*/ + ENUM_CASE(EVENT_CREATE); + ENUM_CASE(EVENT_DELETE); + ENUM_CASE(EVENT_CHILD_CHANGED); + ENUM_CASE(EVENT_CHILD_CREATED); + ENUM_CASE(EVENT_CHILD_DELETED); + ENUM_CASE(EVENT_SCREEN_UNLOAD_START); + ENUM_CASE(EVENT_SCREEN_LOAD_START); + ENUM_CASE(EVENT_SCREEN_LOADED); + ENUM_CASE(EVENT_SCREEN_UNLOADED); + ENUM_CASE(EVENT_SIZE_CHANGED); + ENUM_CASE(EVENT_STYLE_CHANGED); + ENUM_CASE(EVENT_LAYOUT_CHANGED); + ENUM_CASE(EVENT_GET_SELF_SIZE); + + /** Events of optional LVGL components*/ + ENUM_CASE(EVENT_INVALIDATE_AREA); + ENUM_CASE(EVENT_RESOLUTION_CHANGED); + ENUM_CASE(EVENT_COLOR_FORMAT_CHANGED); + ENUM_CASE(EVENT_REFR_REQUEST); + ENUM_CASE(EVENT_REFR_START); + ENUM_CASE(EVENT_REFR_READY); + ENUM_CASE(EVENT_RENDER_START); + ENUM_CASE(EVENT_RENDER_READY); + ENUM_CASE(EVENT_FLUSH_START); + ENUM_CASE(EVENT_FLUSH_FINISH); + ENUM_CASE(EVENT_FLUSH_WAIT_START); + ENUM_CASE(EVENT_FLUSH_WAIT_FINISH); + + ENUM_CASE(EVENT_VSYNC); + ENUM_CASE(EVENT_VSYNC_REQUEST); + + /* Special event flags */ + case LV_EVENT_LAST: + case LV_EVENT_PREPROCESS: + case LV_EVENT_MARKED_DELETING: + break; + + /* Note that default is not added here because when adding new event code, + * if forget to add case, the compiler will automatically report a warning. + */ + } + +#undef ENUM_CASE + + return "EVENT_UNKNOWN"; +} + /********************** * STATIC FUNCTIONS **********************/ + +static void cleanup_event_list_core(lv_array_t * array) +{ + const uint32_t size = lv_array_size(array); + uint32_t kept_count = 0; + for(uint32_t i = 0; i < size; i++) { + lv_event_dsc_t ** dsc_i = lv_array_at(array, i); + lv_event_dsc_t ** dsc_kept = lv_array_at(array, kept_count); + if(event_is_marked_deleting(*dsc_i)) lv_free(*dsc_i); + else { + *dsc_kept = *dsc_i; + kept_count++; + } + } + + if(kept_count == 0) lv_array_deinit(array); + else lv_array_resize(array, kept_count); +} + +static void cleanup_event_list(lv_event_list_t * list) +{ + if(list->is_traversing) return; + if(list->has_marked_deleting == false) return; + + cleanup_event_list_core(&list->array); + + list->has_marked_deleting = false; +} + +static void event_mark_deleting(lv_event_list_t * list, lv_event_dsc_t * dsc) +{ + list->has_marked_deleting = true; + dsc->filter |= LV_EVENT_MARKED_DELETING; +} +static bool event_is_marked_deleting(lv_event_dsc_t * dsc) +{ + return (dsc->filter & LV_EVENT_MARKED_DELETING) != 0; +} +static uint32_t event_array_size(lv_event_list_t * list) +{ + return lv_array_size(&list->array); +} +static lv_event_dsc_t ** event_array_at(lv_event_list_t * list, uint32_t index) +{ + return lv_array_at(&list->array, index); +} diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_event.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_event.h index 61518e96a..a51def981 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_event.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_event.h @@ -29,95 +29,109 @@ extern "C" { typedef void (*lv_event_cb_t)(lv_event_t * e); /** - * Type of event being sent to the object. + * Type of event being sent to Widget */ typedef enum { LV_EVENT_ALL = 0, /** Input device events*/ - LV_EVENT_PRESSED, /**< The object has been pressed*/ - LV_EVENT_PRESSING, /**< The object is being pressed (called continuously while pressing)*/ - LV_EVENT_PRESS_LOST, /**< The object is still being pressed but slid cursor/finger off of the object */ - LV_EVENT_SHORT_CLICKED, /**< The object was pressed for a short period of time, then released it. Not called if scrolled.*/ - LV_EVENT_LONG_PRESSED, /**< Object has been pressed for at least `long_press_time`. Not called if scrolled.*/ - LV_EVENT_LONG_PRESSED_REPEAT, /**< Called after `long_press_time` in every `long_press_repeat_time` ms. Not called if scrolled.*/ - LV_EVENT_CLICKED, /**< Called on release if not scrolled (regardless to long press)*/ - LV_EVENT_RELEASED, /**< Called in every cases when the object has been released*/ - LV_EVENT_SCROLL_BEGIN, /**< Scrolling begins. The event parameter is a pointer to the animation of the scroll. Can be modified*/ + LV_EVENT_PRESSED, /**< Widget has been pressed */ + LV_EVENT_PRESSING, /**< Widget is being pressed (sent continuously while pressing)*/ + LV_EVENT_PRESS_LOST, /**< Widget is still being pressed but slid cursor/finger off Widget */ + LV_EVENT_SHORT_CLICKED, /**< Widget was pressed for a short period of time, then released. Not sent if scrolled. */ + LV_EVENT_SINGLE_CLICKED, /**< Sent for first short click within a small distance and short time */ + LV_EVENT_DOUBLE_CLICKED, /**< Sent for second short click within small distance and short time */ + LV_EVENT_TRIPLE_CLICKED, /**< Sent for third short click within small distance and short time */ + LV_EVENT_LONG_PRESSED, /**< Object has been pressed for at least `long_press_time`. Not sent if scrolled. */ + LV_EVENT_LONG_PRESSED_REPEAT, /**< Sent after `long_press_time` in every `long_press_repeat_time` ms. Not sent if scrolled. */ + LV_EVENT_CLICKED, /**< Sent on release if not scrolled (regardless to long press)*/ + LV_EVENT_RELEASED, /**< Sent in every cases when Widget has been released */ + LV_EVENT_SCROLL_BEGIN, /**< Scrolling begins. The event parameter is a pointer to the animation of the scroll. Can be modified */ LV_EVENT_SCROLL_THROW_BEGIN, - LV_EVENT_SCROLL_END, /**< Scrolling ends*/ - LV_EVENT_SCROLL, /**< Scrolling*/ - LV_EVENT_GESTURE, /**< A gesture is detected. Get the gesture with `lv_indev_get_gesture_dir(lv_indev_active());` */ - LV_EVENT_KEY, /**< A key is sent to the object. Get the key with `lv_indev_get_key(lv_indev_active());`*/ - LV_EVENT_ROTARY, /**< An encoder or wheel was rotated. Get the rotation count with `lv_event_get_rotary_diff(e);`*/ - LV_EVENT_FOCUSED, /**< The object is focused*/ - LV_EVENT_DEFOCUSED, /**< The object is defocused*/ - 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*/ + LV_EVENT_SCROLL_END, /**< Scrolling ends */ + LV_EVENT_SCROLL, /**< Scrolling */ + LV_EVENT_GESTURE, /**< A gesture is detected. Get gesture with `lv_indev_get_gesture_dir(lv_indev_active());` */ + LV_EVENT_KEY, /**< A key is sent to Widget. Get key with `lv_indev_get_key(lv_indev_active());`*/ + LV_EVENT_ROTARY, /**< An encoder or wheel was rotated. Get rotation count with `lv_event_get_rotary_diff(e);`*/ + LV_EVENT_FOCUSED, /**< Widget received focus */ + LV_EVENT_DEFOCUSED, /**< Widget's focus has been lost */ + LV_EVENT_LEAVE, /**< Widget's focus has been lost but is 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 *`.*/ - LV_EVENT_REFR_EXT_DRAW_SIZE, /**< Get the required extra draw area around the object (e.g. for shadow). The event parameter is `int32_t *` to store the size.*/ - LV_EVENT_DRAW_MAIN_BEGIN, /**< Starting the main drawing phase*/ - LV_EVENT_DRAW_MAIN, /**< Perform the main drawing*/ - LV_EVENT_DRAW_MAIN_END, /**< Finishing the main drawing phase*/ - LV_EVENT_DRAW_POST_BEGIN, /**< Starting the post draw phase (when all children are drawn)*/ - LV_EVENT_DRAW_POST, /**< Perform the post draw phase (when all children are drawn)*/ - LV_EVENT_DRAW_POST_END, /**< Finishing the post draw phase (when all children are drawn)*/ - LV_EVENT_DRAW_TASK_ADDED, /**< Adding a draw task */ + /** Drawing events */ + LV_EVENT_COVER_CHECK, /**< Check if Widget fully covers an area. The event parameter is `lv_cover_check_info_t *`. */ + LV_EVENT_REFR_EXT_DRAW_SIZE, /**< Get required extra draw area around Widget (e.g. for shadow). The event parameter is `int32_t *` to store the size. */ + LV_EVENT_DRAW_MAIN_BEGIN, /**< Starting the main drawing phase */ + LV_EVENT_DRAW_MAIN, /**< Perform the main drawing */ + LV_EVENT_DRAW_MAIN_END, /**< Finishing the main drawing phase */ + LV_EVENT_DRAW_POST_BEGIN, /**< Starting the post draw phase (when all children are drawn)*/ + LV_EVENT_DRAW_POST, /**< Perform the post draw phase (when all children are drawn)*/ + LV_EVENT_DRAW_POST_END, /**< Finishing the post draw phase (when all children are drawn)*/ + LV_EVENT_DRAW_TASK_ADDED, /**< Adding a draw task. The `LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS` flag needs to be set */ - /** Special events*/ - LV_EVENT_VALUE_CHANGED, /**< The object's value has changed (i.e. slider moved)*/ - LV_EVENT_INSERT, /**< A text is inserted to the object. The event data is `char *` being inserted.*/ - LV_EVENT_REFRESH, /**< Notify the object to refresh something on it (for the user)*/ - LV_EVENT_READY, /**< A process has finished*/ + /** Special events */ + LV_EVENT_VALUE_CHANGED, /**< Widget's value has changed (i.e. slider moved)*/ + LV_EVENT_INSERT, /**< Text has been inserted into Widget. The event data is `char *` being inserted. */ + LV_EVENT_REFRESH, /**< Notify Widget to refresh something on it (for user)*/ + LV_EVENT_READY, /**< A process has finished */ LV_EVENT_CANCEL, /**< A process has been cancelled */ - /** Other events*/ - LV_EVENT_CREATE, /**< Object is being created*/ - LV_EVENT_DELETE, /**< Object is being deleted*/ + /** Other events */ + LV_EVENT_CREATE, /**< Object is being created */ + LV_EVENT_DELETE, /**< Object is being deleted */ LV_EVENT_CHILD_CHANGED, /**< Child was removed, added, or its size, position were changed */ - LV_EVENT_CHILD_CREATED, /**< Child was created, always bubbles up to all parents*/ - LV_EVENT_CHILD_DELETED, /**< Child was deleted, always bubbles up to all parents*/ - LV_EVENT_SCREEN_UNLOAD_START, /**< A screen unload started, fired immediately when scr_load is called*/ - LV_EVENT_SCREEN_LOAD_START, /**< A screen load started, fired when the screen change delay is expired*/ - LV_EVENT_SCREEN_LOADED, /**< A screen was loaded*/ - LV_EVENT_SCREEN_UNLOADED, /**< A screen was unloaded*/ - LV_EVENT_SIZE_CHANGED, /**< Object coordinates/size have changed*/ - LV_EVENT_STYLE_CHANGED, /**< Object's style has changed*/ - LV_EVENT_LAYOUT_CHANGED, /**< The children position has changed due to a layout recalculation*/ - LV_EVENT_GET_SELF_SIZE, /**< Get the internal size of a widget*/ + LV_EVENT_CHILD_CREATED, /**< Child was created, always bubbles up to all parents */ + LV_EVENT_CHILD_DELETED, /**< Child was deleted, always bubbles up to all parents */ + LV_EVENT_SCREEN_UNLOAD_START, /**< A screen unload started, fired immediately when scr_load is called */ + LV_EVENT_SCREEN_LOAD_START, /**< A screen load started, fired when the screen change delay is expired */ + LV_EVENT_SCREEN_LOADED, /**< A screen was loaded */ + LV_EVENT_SCREEN_UNLOADED, /**< A screen was unloaded */ + LV_EVENT_SIZE_CHANGED, /**< Object coordinates/size have changed */ + LV_EVENT_STYLE_CHANGED, /**< Object's style has changed */ + LV_EVENT_LAYOUT_CHANGED, /**< A child's position position has changed due to a layout recalculation */ + LV_EVENT_GET_SELF_SIZE, /**< Get internal size of a widget */ - /** Events of optional LVGL components*/ - LV_EVENT_INVALIDATE_AREA, - LV_EVENT_RESOLUTION_CHANGED, - LV_EVENT_COLOR_FORMAT_CHANGED, - LV_EVENT_REFR_REQUEST, - LV_EVENT_REFR_START, - LV_EVENT_REFR_READY, - LV_EVENT_RENDER_START, - LV_EVENT_RENDER_READY, - LV_EVENT_FLUSH_START, - LV_EVENT_FLUSH_FINISH, - LV_EVENT_FLUSH_WAIT_START, - LV_EVENT_FLUSH_WAIT_FINISH, + /** Events of optional LVGL components */ + LV_EVENT_INVALIDATE_AREA, /**< An area is invalidated (marked for redraw). `lv_event_get_param(e)` + * returns a pointer to an `lv_area_t` object with the coordinates of the + * area to be invalidated. The area can be freely modified if needed to + * adapt it a special requirement of the display. Usually needed with + * monochrome displays to invalidate `N x 8` rows or columns in one pass. */ + LV_EVENT_RESOLUTION_CHANGED, /**< Sent when the resolution changes due to `lv_display_set_resolution()` or `lv_display_set_rotation()`. */ + LV_EVENT_COLOR_FORMAT_CHANGED,/**< Sent as a result of any call to `lv_display_set_color_format()`. */ + LV_EVENT_REFR_REQUEST, /**< Sent when something happened that requires redraw. */ + LV_EVENT_REFR_START, /**< Sent before a refreshing cycle starts. Sent even if there is nothing to redraw. */ + LV_EVENT_REFR_READY, /**< Sent when refreshing has been completed (after rendering and calling flush callback). Sent even if no redraw happened. */ + LV_EVENT_RENDER_START, /**< Sent just before rendering begins. */ + LV_EVENT_RENDER_READY, /**< Sent after rendering has been completed (before calling flush callback) */ + LV_EVENT_FLUSH_START, /**< Sent before flush callback is called. */ + LV_EVENT_FLUSH_FINISH, /**< Sent after flush callback call has returned. */ + LV_EVENT_FLUSH_WAIT_START, /**< Sent before flush wait callback is called. */ + LV_EVENT_FLUSH_WAIT_FINISH, /**< Sent after flush wait callback call has returned. */ LV_EVENT_VSYNC, + LV_EVENT_VSYNC_REQUEST, - 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 */ + LV_EVENT_MARKED_DELETING = 0x10000, } lv_event_code_t; -typedef lv_array_t lv_event_list_t; +typedef struct { + lv_array_t array; + uint8_t is_traversing: 1; /**< True: the list is being nested traversed */ + uint8_t has_marked_deleting: 1; /**< True: the list has marked deleting objects + when some of events are marked as deleting */ +} lv_event_list_t; /** * @brief Event callback. - * Events are used to notify the user of some action being taken on the object. + * Events are used to notify the user of some action being taken on Widget. * For details, see ::lv_event_t. */ @@ -139,14 +153,14 @@ bool lv_event_remove(lv_event_list_t * list, uint32_t index); void lv_event_remove_all(lv_event_list_t * list); /** - * Get the object originally targeted by the event. It's the same even if the event is bubbled. + * Get Widget originally targeted by the event. It's the same even if event was bubbled. * @param e pointer to the event descriptor * @return the target of the event_code */ void * lv_event_get_target(lv_event_t * e); /** - * Get the current target of the event. It's the object which event handler being called. + * Get current target of the event. It's the Widget for which the event handler being called. * If the event is not bubbled it's the same as "normal" target. * @param e pointer to the event descriptor * @return pointer to the current target of the event_code @@ -154,28 +168,28 @@ void * lv_event_get_target(lv_event_t * e); void * lv_event_get_current_target(lv_event_t * e); /** - * Get the event code of an event + * Get event code of an event. * @param e pointer to the event descriptor * @return the event code. (E.g. `LV_EVENT_CLICKED`, `LV_EVENT_FOCUSED`, etc) */ lv_event_code_t lv_event_get_code(lv_event_t * e); /** - * Get the parameter passed when the event was sent + * Get parameter passed when event was sent. * @param e pointer to the event descriptor * @return pointer to the parameter */ void * lv_event_get_param(lv_event_t * e); /** - * Get the user_data passed when the event was registered on the object + * Get user_data passed when event was registered on Widget. * @param e pointer to the event descriptor * @return pointer to the user_data */ void * lv_event_get_user_data(lv_event_t * e); /** - * Stop the event from bubbling. + * Stop event from bubbling. * This is only valid when called in the middle of an event processing chain. * @param e pointer to the event descriptor */ @@ -204,6 +218,13 @@ void lv_event_stop_processing(lv_event_t * e); */ uint32_t lv_event_register_id(void); +/** + * Get the name of an event code. + * @param code the event code + * @return the name of the event code as a string + */ +const char * lv_event_code_get_name(lv_event_code_t code); + /********************** * MACROS **********************/ @@ -212,4 +233,4 @@ uint32_t lv_event_register_id(void); } /*extern "C"*/ #endif -#endif /*LV_EVENT_H*/ +#endif /* LV_EVENT_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_event_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_event_private.h index b31ca81b8..5ba0e5a53 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_event_private.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_event_private.h @@ -24,13 +24,13 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_event_dsc_t { +struct _lv_event_dsc_t { lv_event_cb_t cb; void * user_data; uint32_t filter; }; -struct lv_event_t { +struct _lv_event_t { void * current_target; void * original_target; lv_event_code_t code; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.c index f71369880..e90d00c7f 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.c @@ -18,8 +18,8 @@ * 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)" +#if LV_FS_DEFAULT_DRIVER_LETTER != '\0' && (LV_FS_DEFAULT_DRIVER_LETTER < 'A' || 'Z' < LV_FS_DEFAULT_DRIVER_LETTER) + #error "When enabled, LV_FS_DEFAULT_DRIVER_LETTER needs to be a capital ASCII letter (A-Z)" #endif #define fsdrv_ll_p &(LV_GLOBAL_DEFAULT()->fsdrv_ll) @@ -28,7 +28,7 @@ * TYPEDEFS **********************/ typedef struct { - char drive_letter; + char driver_letter; const char * real_path; } resolved_path_t; @@ -82,7 +82,7 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo resolved_path_t resolved_path = lv_fs_resolve_path(path); - lv_fs_drv_t * drv = lv_fs_get_drv(resolved_path.drive_letter); + lv_fs_drv_t * drv = lv_fs_get_drv(resolved_path.driver_letter); if(drv == NULL) { LV_LOG_WARN("Can't open file (%s): unknown driver letter", path); @@ -101,7 +101,7 @@ 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; + LV_PROFILER_FS_BEGIN; file_p->drv = drv; @@ -112,7 +112,7 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo else { void * file_d = drv->open_cb(drv, resolved_path.real_path, mode); if(file_d == NULL || file_d == (void *)(-1)) { - LV_PROFILER_END; + LV_PROFILER_FS_END; return LV_FS_RES_UNKNOWN; } file_p->file_d = file_d; @@ -137,7 +137,7 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo } } - LV_PROFILER_END; + LV_PROFILER_FS_END; return LV_FS_RES_OK; } @@ -161,7 +161,7 @@ lv_fs_res_t lv_fs_close(lv_fs_file_t * file_p) return LV_FS_RES_NOT_IMP; } - LV_PROFILER_BEGIN; + LV_PROFILER_FS_BEGIN; lv_fs_res_t res = file_p->drv->close_cb(file_p->drv, file_p->file_d); @@ -178,7 +178,7 @@ lv_fs_res_t lv_fs_close(lv_fs_file_t * file_p) file_p->drv = NULL; file_p->cache = NULL; - LV_PROFILER_END; + LV_PROFILER_FS_END; return res; } @@ -195,7 +195,7 @@ lv_fs_res_t lv_fs_read(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t if(file_p->drv->read_cb == NULL) return LV_FS_RES_NOT_IMP; } - LV_PROFILER_BEGIN; + LV_PROFILER_FS_BEGIN; uint32_t br_tmp = 0; lv_fs_res_t res; @@ -209,7 +209,7 @@ 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; + LV_PROFILER_FS_END; return res; } @@ -229,7 +229,7 @@ lv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, u if(file_p->drv->write_cb == NULL) return LV_FS_RES_NOT_IMP; } - LV_PROFILER_BEGIN; + LV_PROFILER_FS_BEGIN; lv_fs_res_t res; uint32_t bw_tmp = 0; @@ -241,8 +241,7 @@ lv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, u } if(bw != NULL) *bw = bw_tmp; - LV_PROFILER_END; - + LV_PROFILER_FS_END; return res; } @@ -259,7 +258,7 @@ lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whenc if(file_p->drv->seek_cb == NULL) return LV_FS_RES_NOT_IMP; } - LV_PROFILER_BEGIN; + LV_PROFILER_FS_BEGIN; lv_fs_res_t res; if(file_p->drv->cache_size) { @@ -269,7 +268,7 @@ lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whenc res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, pos, whence); } - LV_PROFILER_END; + LV_PROFILER_FS_END; return res; } @@ -286,7 +285,7 @@ lv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos) return LV_FS_RES_NOT_IMP; } - LV_PROFILER_BEGIN; + LV_PROFILER_FS_BEGIN; lv_fs_res_t res; if(file_p->drv->cache_size) { @@ -297,7 +296,7 @@ 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; + LV_PROFILER_FS_END; return res; } @@ -308,7 +307,7 @@ lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path) resolved_path_t resolved_path = lv_fs_resolve_path(path); - lv_fs_drv_t * drv = lv_fs_get_drv(resolved_path.drive_letter); + lv_fs_drv_t * drv = lv_fs_get_drv(resolved_path.driver_letter); if(drv == NULL) { return LV_FS_RES_NOT_EX; @@ -324,19 +323,19 @@ lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path) return LV_FS_RES_NOT_IMP; } - LV_PROFILER_BEGIN; + LV_PROFILER_FS_BEGIN; void * dir_d = drv->dir_open_cb(drv, resolved_path.real_path); if(dir_d == NULL || dir_d == (void *)(-1)) { - LV_PROFILER_END; + LV_PROFILER_FS_END; return LV_FS_RES_UNKNOWN; } rddir_p->drv = drv; rddir_p->dir_d = dir_d; - LV_PROFILER_END; + LV_PROFILER_FS_END; return LV_FS_RES_OK; } @@ -357,11 +356,11 @@ 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_PROFILER_FS_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; + LV_PROFILER_FS_END; return res; } @@ -376,14 +375,14 @@ lv_fs_res_t lv_fs_dir_close(lv_fs_dir_t * rddir_p) return LV_FS_RES_NOT_IMP; } - LV_PROFILER_BEGIN; + LV_PROFILER_FS_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; + LV_PROFILER_FS_END; return res; } @@ -510,19 +509,19 @@ static resolved_path_t lv_fs_resolve_path(const char * path) { resolved_path_t resolved; -#if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/ +#if LV_FS_DEFAULT_DRIVER_LETTER != '\0' /* When using default driver-identifier 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.driver_letter = path[0]; resolved.real_path = path + 2; } else { - resolved.drive_letter = LV_FS_DEFAULT_DRIVE_LETTER; + resolved.driver_letter = LV_FS_DEFAULT_DRIVER_LETTER; resolved.real_path = path; } # else /*Lean rules for backward compatibility*/ - resolved.drive_letter = path[0]; + resolved.driver_letter = path[0]; if(*path != '\0') { path++; /*Ignore the driver letter*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.h index c6f938b7d..cefbf9633 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs.h @@ -64,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); @@ -119,7 +119,7 @@ void lv_fs_drv_register(lv_fs_drv_t * drv); /** * Give a pointer to a driver from its letter - * @param letter the driver letter + * @param letter the driver-identifier letter * @return pointer to a driver or NULL if not found */ lv_fs_drv_t * lv_fs_get_drv(char letter); @@ -144,7 +144,7 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo /** * Make a path object for the memory-mapped file compatible with the file system interface * @param path path to a lv_fs_path_ex object - * @param letter the letter of the driver. E.g. `LV_FS_MEMFS_LETTER` + * @param letter the identifier letter of the driver. E.g. `LV_FS_MEMFS_LETTER` * @param buf address of the memory buffer * @param size size of the memory buffer in bytes */ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_fs_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs_private.h index f8bb4bbd3..c6b213741 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_fs_private.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_fs_private.h @@ -24,7 +24,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_fs_file_cache_t { +struct _lv_fs_file_cache_t { uint32_t start; uint32_t end; uint32_t file_position; @@ -32,7 +32,7 @@ struct lv_fs_file_cache_t { }; /** Extended path object to specify buffer for memory-mapped files */ -struct lv_fs_path_ex_t { +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; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_grad.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_grad.c new file mode 100644 index 000000000..f3a73613d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_grad.c @@ -0,0 +1,120 @@ +/** + * @file lv_grad.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_grad.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ +void lv_grad_init_stops(lv_grad_dsc_t * dsc, 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); + LV_ASSERT(num_stops > 1); + LV_ASSERT_NULL(dsc); + LV_ASSERT_NULL(colors); + + dsc->stops_count = num_stops; + for(int i = 0; i < num_stops; i++) { + dsc->stops[i].color = colors[i]; + dsc->stops[i].opa = opa != NULL ? opa[i] : LV_OPA_COVER; + dsc->stops[i].frac = fracs != NULL ? fracs[i] : 255 * i / (num_stops - 1); + } +} + +void lv_grad_horizontal_init(lv_grad_dsc_t * dsc) +{ + LV_ASSERT_NULL(dsc); + + dsc->dir = LV_GRAD_DIR_HOR; +} + +void lv_grad_vertical_init(lv_grad_dsc_t * dsc) +{ + LV_ASSERT_NULL(dsc); + + dsc->dir = LV_GRAD_DIR_VER; +} + + +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + +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) +{ + LV_ASSERT_NULL(dsc); + 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) +{ + LV_ASSERT_NULL(dsc); + 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) +{ + LV_ASSERT_NULL(dsc); + 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) +{ + LV_ASSERT_NULL(dsc); + 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 */ + +/********************** + * STATIC FUNCTIONS + **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_grad.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_grad.h new file mode 100644 index 000000000..3ddeb724d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_grad.h @@ -0,0 +1,182 @@ +/** + * @file lv_grad.h + * + */ + +#ifndef LV_GRAD_H +#define LV_GRAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "lv_color.h" +#include "lv_area.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * The direction of the 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; + +/** + * 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. + */ +typedef struct { + lv_color_t color; /**< The stop color */ + lv_opa_t opa; /**< The opacity of the color*/ + uint8_t frac; /**< The stop position in 1/255 unit */ +} lv_grad_stop_t; + +/** A descriptor of a gradient. */ +typedef struct { + lv_grad_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 : 4; /**< 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 : 3; /**< 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; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * 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_grad_init_stops(lv_grad_dsc_t * grad, const lv_color_t colors[], const lv_opa_t opa[], + const uint8_t fracs[], int num_stops); + +/** + * Helper function to initialize a horizontal gradient. + * @param dsc gradient descriptor + */ +void lv_grad_horizontal_init(lv_grad_dsc_t * dsc); + +/** + * Helper function to initialize a vertical gradient. + * @param dsc gradient descriptor + */ +void lv_grad_vertical_init(lv_grad_dsc_t * dsc); + +#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); + +#endif /*LV_USE_DRAW_SW_COMPLEX_GRADIENTS*/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GRAD_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_iter.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_iter.c new file mode 100644 index 000000000..cb6377c0b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_iter.c @@ -0,0 +1,213 @@ +/** + * @file lv_iter.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_assert.h" + +#include "lv_iter.h" + +#include "lv_circle_buf.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_iter_t { + /* Iterator state */ + void * instance; /**< Pointer to the object to iterate over */ + uint32_t elem_size; /**< Size of one element in bytes */ + void * context; /**< Custom context for the iteration */ + uint32_t context_size; /**< Size of the custom context in bytes */ + + /* Peeking */ + lv_circle_buf_t * peek_buf; /**< Circular buffer for peeking */ + uint32_t peek_offset; /**< Offset in the peek buffer */ + + /* Callbacks */ + lv_iter_next_cb next_cb; /**< Callback to get the next element */ +}; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static bool peek_fill_cb(void * buf, uint32_t buf_len, int32_t index, void * user_data); + +/********************** + * GLOBAL VARIABLES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_iter_t * lv_iter_create(void * instance, const uint32_t elem_size, const uint32_t context_size, + lv_iter_next_cb next_cb) +{ + lv_iter_t * iter = lv_malloc_zeroed(sizeof(lv_iter_t)); + LV_ASSERT_MALLOC(iter); + + if(iter == NULL) { + LV_LOG_ERROR("Could not allocate memory for iterator"); + return NULL; + } + + iter->instance = instance; + iter->elem_size = elem_size; + iter->context_size = context_size; + iter->next_cb = next_cb; + + if(context_size > 0) { + iter->context = lv_malloc_zeroed(context_size); + LV_ASSERT_MALLOC(iter->context); + } + + return iter; +} + +void * lv_iter_get_context(const lv_iter_t * iter) +{ + LV_ASSERT_NULL(iter); + + return iter ? iter->context : NULL; +} + +void lv_iter_destroy(lv_iter_t * iter) +{ + LV_ASSERT_NULL(iter); + if(iter == NULL) return; + + if(iter->context_size > 0) lv_free(iter->context); + if(iter->peek_buf != NULL) lv_circle_buf_destroy(iter->peek_buf); + + iter->context = NULL; + iter->peek_buf = NULL; + + lv_free(iter); +} + +void lv_iter_make_peekable(lv_iter_t * iter, const uint32_t capacity) +{ + LV_ASSERT_NULL(iter); + if(iter == NULL) return; + + if(capacity == 0 || iter->peek_buf != NULL) return; + iter->peek_buf = lv_circle_buf_create(capacity, iter->elem_size); + LV_ASSERT_NULL(iter->peek_buf); +} + +lv_result_t lv_iter_next(lv_iter_t * iter, void * elem) +{ + LV_ASSERT_NULL(iter); + if(iter == NULL) return LV_RESULT_INVALID; + + lv_circle_buf_t * c_buf = iter->peek_buf; + if(c_buf != NULL && !lv_circle_buf_is_empty(c_buf)) { + if(elem) lv_circle_buf_read(c_buf, elem); + else lv_circle_buf_skip(c_buf); + iter->peek_offset = 0; + return LV_RESULT_OK; + } + + const lv_result_t iter_res = iter->next_cb(iter->instance, iter->context, elem); + if(iter_res == LV_RESULT_INVALID) return LV_RESULT_INVALID; + + if(c_buf != NULL) iter->peek_offset = 0; + + return iter_res; +} + +lv_result_t lv_iter_peek(lv_iter_t * iter, void * elem) +{ + LV_ASSERT_NULL(iter); + if(iter == NULL) return LV_RESULT_INVALID; + + lv_circle_buf_t * c_buf = iter->peek_buf; + if(c_buf == NULL) return LV_RESULT_INVALID; + + const uint32_t peek_count = lv_circle_buf_size(c_buf); + if(iter->peek_offset >= peek_count) { + const uint32_t required = iter->peek_offset + 1 - peek_count; + const uint32_t filled = lv_circle_buf_fill(c_buf, required, peek_fill_cb, iter); + if(filled != required) return LV_RESULT_INVALID; + } + + lv_circle_buf_peek_at(c_buf, iter->peek_offset, elem); + + return LV_RESULT_OK; +} + +lv_result_t lv_iter_peek_advance(lv_iter_t * iter) +{ + LV_ASSERT_NULL(iter); + if(iter == NULL) return LV_RESULT_INVALID; + + if(iter->peek_buf == NULL || iter->peek_offset + 1 >= lv_circle_buf_capacity(iter->peek_buf)) + return LV_RESULT_INVALID; + iter->peek_offset++; + return LV_RESULT_OK; +} + +lv_result_t lv_iter_peek_reset(lv_iter_t * iter) +{ + LV_ASSERT_NULL(iter); + if(iter == NULL) return LV_RESULT_INVALID; + + if(iter->peek_buf == NULL) return LV_RESULT_INVALID; + + iter->peek_offset = 0; + return LV_RESULT_OK; +} + +void lv_iter_inspect(lv_iter_t * iter, const lv_iter_inspect_cb inspect_cb) +{ + LV_ASSERT_NULL(iter); + if(iter == NULL) return; + + void * elem = lv_malloc_zeroed(iter->elem_size); + LV_ASSERT_MALLOC(elem); + + if(elem == NULL) { + LV_LOG_ERROR("Could not allocate memory for element"); + return; + } + + while(lv_iter_next(iter, elem) == LV_RESULT_OK) { + inspect_cb(elem); + } + + lv_free(elem); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static bool peek_fill_cb(void * buf, const uint32_t buf_len, const int32_t index, void * user_data) +{ + LV_UNUSED(buf_len); + LV_UNUSED(index); + + const lv_iter_t * iter = user_data; + const lv_result_t iter_res = iter->next_cb(iter->instance, iter->context, buf); + if(iter_res == LV_RESULT_INVALID) return false; + + return true; +} diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_iter.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_iter.h new file mode 100644 index 000000000..469d441e7 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_iter.h @@ -0,0 +1,120 @@ +/** +* @file lv_iter.h +* + */ + + +#ifndef LV_ITER_H +#define LV_ITER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef lv_result_t (*lv_iter_next_cb)(void * instance, void * context, void * elem); +typedef void (*lv_iter_inspect_cb)(void * elem); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create an iterator based on an instance, and then the next element of the iterator can be obtained through lv_iter_next, + * In order to obtain the next operation in a unified and abstract way. + * @param instance The instance to be iterated + * @param elem_size The size of the element to be iterated in bytes + * @param context_size The size of the context to be passed to the next_cb in bytes + * @param next_cb The callback function to get the next element + * @return The iterator object + */ +lv_iter_t * lv_iter_create(void * instance, uint32_t elem_size, uint32_t context_size, lv_iter_next_cb next_cb); + +/** + * Get the context of the iterator. You can use it to store some temporary variables associated with current iterator.. + * @param iter `lv_iter_t` object create before + * @return the iter context + */ +void * lv_iter_get_context(const lv_iter_t * iter); + +/** + * Destroy the iterator object, and release the context. Other resources allocated by the user are not released. + * The user needs to release it by itself. + * @param iter `lv_iter_t` object create before + */ +void lv_iter_destroy(lv_iter_t * iter); + +/** + * Get the next element of the iterator. + * @param iter `lv_iter_t` object create before + * @param elem The pointer to store the next element + * @return LV_RESULT_OK: Get the next element successfully + * LV_RESULT_INVALID: The next element is invalid + */ +lv_result_t lv_iter_next(lv_iter_t * iter, void * elem); + +/** + * Make the iterator peekable, which means that the user can peek the next element without advancing the iterator. + * @param iter `lv_iter_t` object create before + * @param capacity The capacity of the peek buffer + */ +void lv_iter_make_peekable(lv_iter_t * iter, uint32_t capacity); + +/** + * Peek the next element of the iterator without advancing the iterator. + * @param iter `lv_iter_t` object create before + * @param elem The pointer to store the next element + * @return LV_RESULT_OK: Peek the next element successfully + * LV_RESULT_INVALID: The next element is invalid + */ +lv_result_t lv_iter_peek(lv_iter_t * iter, void * elem); + +/** + * Only advance the iterator without getting the next element. + * @param iter `lv_iter_t` object create before + * @return LV_RESULT_OK: Peek the next element successfully + * LV_RESULT_INVALID: The next element is invalid + */ +lv_result_t lv_iter_peek_advance(lv_iter_t * iter); + +/** + * Reset the peek cursor to the `next` cursor. + * @param iter `lv_iter_t` object create before + * @return LV_RESULT_OK: Reset the peek buffer successfully + * LV_RESULT_INVALID: The peek buffer is invalid + */ +lv_result_t lv_iter_peek_reset(lv_iter_t * iter); + +/** + * Inspect the element of the iterator. The callback function will be called for each element of the iterator. + * @param iter `lv_iter_t` object create before + * @param inspect_cb The callback function to inspect the element + */ +void lv_iter_inspect(lv_iter_t * iter, lv_iter_inspect_cb inspect_cb); + +/************************* + * GLOBAL VARIABLES + *************************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ITER_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_ll.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_ll.c index ca1339ec5..9d86f1daa 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_ll.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_ll.c @@ -129,7 +129,7 @@ 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) { - /*The new head will be the node after 'n_act'*/ + /*The new head will be the node after 'node_p'*/ ll_p->head = lv_ll_get_next(ll_p, node_p); if(ll_p->head == NULL) { ll_p->tail = NULL; @@ -139,7 +139,7 @@ void lv_ll_remove(lv_ll_t * ll_p, void * node_p) } } else if(lv_ll_get_tail(ll_p) == node_p) { - /*The new tail will be the node before 'n_act'*/ + /*The new tail will be the node before 'node_p'*/ ll_p->tail = lv_ll_get_prev(ll_p, node_p); if(ll_p->tail == NULL) { ll_p->head = NULL; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_log.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_log.c index 3f3caec8d..4dd197587 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_log.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_log.c @@ -96,13 +96,6 @@ void lv_log_add(lv_log_level_t level, const char * file, int line, const char * #endif static const char * lvl_prefix[] = {"Trace", "Info", "Warn", "Error", "User"}; -#if LV_LOG_PRINTF - printf("[%s]" LOG_TIMESTAMP_FMT " %s: ", - lvl_prefix[level], LOG_TIMESTAMP_EXPR func); - vprintf(format, args); - printf(LOG_FILE_LINE_FMT "\n" LOG_FILE_LINE_EXPR); - fflush(stdout); -#endif if(custom_print_cb) { char buf[512]; char msg[256]; @@ -111,6 +104,15 @@ 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); } +#if LV_LOG_PRINTF + else { + printf("[%s]" LOG_TIMESTAMP_FMT " %s: ", + lvl_prefix[level], LOG_TIMESTAMP_EXPR func); + vprintf(format, args); + printf(LOG_FILE_LINE_FMT "\n" LOG_FILE_LINE_EXPR); + fflush(stdout); + } +#endif #if LV_LOG_USE_TIMESTAMP last_log_time = t; @@ -126,14 +128,15 @@ void lv_log(const char * format, ...) va_list args; va_start(args, format); -#if LV_LOG_PRINTF - vprintf(format, args); -#else if(custom_print_cb) { char buf[512]; lv_vsnprintf(buf, sizeof(buf), format, args); custom_print_cb(LV_LOG_LEVEL_USER, buf); } +#if LV_LOG_PRINTF + else { + vprintf(format, args); + } #endif va_end(args); diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_log.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_log.h index 7774ba6fc..305d309f5 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_log.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_log.h @@ -29,7 +29,7 @@ extern "C" { #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 */ +#define LV_LOG_LEVEL_NUM 5 /**< Number of log levels */ LV_EXPORT_CONST_INT(LV_LOG_LEVEL_TRACE); LV_EXPORT_CONST_INT(LV_LOG_LEVEL_INFO); diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_lru.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_lru.c index f8d4c0682..006584153 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; }; /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_lru.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_lru.h index 1bb25861f..fe41322dc 100755 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_lru.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_lru.h @@ -37,9 +37,9 @@ 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 { +typedef struct _lv_lru_t { lv_lru_item_t ** items; uint64_t access_count; size_t free_memory; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_math.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_math.c index bd728fbcf..a6d51a055 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 * */ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_math.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_math.h index 05e159f13..4395994fa 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 * */ @@ -45,7 +45,6 @@ typedef struct { * GLOBAL PROTOTYPES **********************/ -//! @cond Doxygen_Suppress /** * Return with sinus of an angle * @param angle @@ -55,8 +54,6 @@ int32_t /* LV_ATTRIBUTE_FAST_MEM */ lv_trigo_sin(int16_t angle); int32_t LV_ATTRIBUTE_FAST_MEM lv_trigo_cos(int16_t angle); -//! @endcond - /** * Calculate the y value of cubic-bezier(x1, y1, x2, y2) function as specified x. * @param x time in range of [0..LV_BEZIER_VAL_MAX] @@ -88,8 +85,6 @@ int32_t lv_bezier3(int32_t t, int32_t u0, uint32_t u1, int32_t u2, int32_t u3); */ uint16_t lv_atan2(int x, int y); -//! @cond Doxygen_Suppress - /** * Get the square root of a number * @param x integer which square root should be calculated @@ -102,8 +97,6 @@ uint16_t lv_atan2(int x, int y); */ void /* LV_ATTRIBUTE_FAST_MEM */ lv_sqrt(uint32_t x, lv_sqrt_res_t * q, uint32_t mask); -//! @endcond - /** * Alternative (fast, approximate) implementation for getting the square root of an integer. * @param x integer which square root should be calculated diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.c index 4a6bb6374..62a958481 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.c @@ -14,6 +14,8 @@ #include "../stdlib/lv_string.h" #include "lv_math.h" #include +#include +#include "../misc/lv_log.h" /********************* * DEFINES *********************/ @@ -180,8 +182,17 @@ bool lv_matrix_inverse(lv_matrix_t * matrix, const lv_matrix_t * m) 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]); + lv_value_precise_t w = point->x * matrix->m[2][0] + point->y * matrix->m[2][1] + matrix->m[2][2]; + if(LV_ABS(w) < FLT_EPSILON) { + LV_LOG_ERROR("matrix is invalid"); + p.x = 0; + p.y = 0; + } + else { + lv_value_precise_t inv_w = 1.0f / w; + p.x = (lv_value_precise_t)roundf((point->x * matrix->m[0][0] + point->y * matrix->m[0][1] + matrix->m[0][2]) * inv_w); + p.y = (lv_value_precise_t)roundf((point->x * matrix->m[1][0] + point->y * matrix->m[1][1] + matrix->m[1][2]) * inv_w); + } return p; } @@ -207,6 +218,11 @@ lv_area_t lv_matrix_transform_area(const lv_matrix_t * matrix, const lv_area_t * return res; } +bool lv_matrix_is_identity(const lv_matrix_t * matrix) +{ + return (matrix->m[0][2] == 0.0f && matrix->m[1][2] == 0.0f && lv_matrix_is_identity_or_translation(matrix)); +} + bool lv_matrix_is_identity_or_translation(const lv_matrix_t * matrix) { return (matrix->m[0][0] == 1.0f && diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.h index 9583fa9af..435ee9586 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_matrix.h @@ -33,7 +33,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_matrix_t { +struct _lv_matrix_t { float m[3][3]; }; @@ -109,6 +109,13 @@ lv_point_precise_t lv_matrix_transform_precise_point(const lv_matrix_t * matrix, */ lv_area_t lv_matrix_transform_area(const lv_matrix_t * matrix, const lv_area_t * area); +/** + * Check if the matrix is identity + * @param matrix pointer to a matrix + * @return true: the matrix is identity , false: the matrix is not identity + */ +bool lv_matrix_is_identity(const lv_matrix_t * matrix); + /** * Check if the matrix is identity or translation matrix * @param matrix pointer to a matrix diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler.h index 47d5bd243..840ee9a5a 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler.h @@ -45,6 +45,138 @@ extern "C" { #endif /*LV_USE_PROFILER*/ +#if LV_USE_PROFILER && LV_PROFILER_LAYOUT +#define LV_PROFILER_LAYOUT_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_LAYOUT_END LV_PROFILER_END +#define LV_PROFILER_LAYOUT_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_LAYOUT_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_LAYOUT_BEGIN +#define LV_PROFILER_LAYOUT_END +#define LV_PROFILER_LAYOUT_BEGIN_TAG(tag) +#define LV_PROFILER_LAYOUT_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_STYLE +#define LV_PROFILER_STYLE_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_STYLE_END LV_PROFILER_END +#define LV_PROFILER_STYLE_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_STYLE_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_STYLE_BEGIN +#define LV_PROFILER_STYLE_END +#define LV_PROFILER_STYLE_BEGIN_TAG(tag) +#define LV_PROFILER_STYLE_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_DRAW +#define LV_PROFILER_DRAW_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_DRAW_END LV_PROFILER_END +#define LV_PROFILER_DRAW_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_DRAW_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_DRAW_BEGIN +#define LV_PROFILER_DRAW_END +#define LV_PROFILER_DRAW_BEGIN_TAG(tag) +#define LV_PROFILER_DRAW_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_DECODER +#define LV_PROFILER_DECODER_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_DECODER_END LV_PROFILER_END +#define LV_PROFILER_DECODER_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_DECODER_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_DECODER_BEGIN +#define LV_PROFILER_DECODER_END +#define LV_PROFILER_DECODER_BEGIN_TAG(tag) +#define LV_PROFILER_DECODER_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_REFR +#define LV_PROFILER_REFR_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_REFR_END LV_PROFILER_END +#define LV_PROFILER_REFR_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_REFR_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_REFR_BEGIN +#define LV_PROFILER_REFR_END +#define LV_PROFILER_REFR_BEGIN_TAG(tag) +#define LV_PROFILER_REFR_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_INDEV +#define LV_PROFILER_INDEV_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_INDEV_END LV_PROFILER_END +#define LV_PROFILER_INDEV_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_INDEV_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_INDEV_BEGIN +#define LV_PROFILER_INDEV_END +#define LV_PROFILER_INDEV_BEGIN_TAG(tag) +#define LV_PROFILER_INDEV_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_FONT +#define LV_PROFILER_FONT_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_FONT_END LV_PROFILER_END +#define LV_PROFILER_FONT_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_FONT_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_FONT_BEGIN +#define LV_PROFILER_FONT_END +#define LV_PROFILER_FONT_BEGIN_TAG(tag) +#define LV_PROFILER_FONT_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_CACHE +#define LV_PROFILER_CACHE_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_CACHE_END LV_PROFILER_END +#define LV_PROFILER_CACHE_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_CACHE_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_CACHE_BEGIN +#define LV_PROFILER_CACHE_END +#define LV_PROFILER_CACHE_BEGIN_TAG(tag) +#define LV_PROFILER_CACHE_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_FS +#define LV_PROFILER_FS_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_FS_END LV_PROFILER_END +#define LV_PROFILER_FS_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_FS_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_FS_BEGIN +#define LV_PROFILER_FS_END +#define LV_PROFILER_FS_BEGIN_TAG(tag) +#define LV_PROFILER_FS_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_TIMER +#define LV_PROFILER_TIMER_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_TIMER_END LV_PROFILER_END +#define LV_PROFILER_TIMER_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_TIMER_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_TIMER_BEGIN +#define LV_PROFILER_TIMER_END +#define LV_PROFILER_TIMER_BEGIN_TAG(tag) +#define LV_PROFILER_TIMER_END_TAG(tag) +#endif + +#if LV_USE_PROFILER && LV_PROFILER_EVENT +#define LV_PROFILER_EVENT_BEGIN LV_PROFILER_BEGIN +#define LV_PROFILER_EVENT_END LV_PROFILER_END +#define LV_PROFILER_EVENT_BEGIN_TAG(tag) LV_PROFILER_BEGIN_TAG(tag) +#define LV_PROFILER_EVENT_END_TAG(tag) LV_PROFILER_END_TAG(tag) +#else +#define LV_PROFILER_EVENT_BEGIN +#define LV_PROFILER_EVENT_END +#define LV_PROFILER_EVENT_BEGIN_TAG(tag) +#define LV_PROFILER_EVENT_END_TAG(tag) +#endif + #ifdef __cplusplus } /*extern "C"*/ #endif 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 b6b6fd435..cb1483f55 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin.c @@ -20,7 +20,7 @@ #define profiler_ctx LV_GLOBAL_DEFAULT()->profiler_context #define LV_PROFILER_STR_MAX_LEN 128 -#define LV_PROFILER_TICK_PER_SEC_MAX 1000000 +#define LV_PROFILER_TICK_PER_SEC_MAX 1000000000 /* Maximum accuracy: 1 nanosecond */ #if LV_USE_OS #define LV_PROFILER_MULTEX_INIT lv_mutex_init(&profiler_ctx->mutex) @@ -42,8 +42,8 @@ * @brief Structure representing a built-in profiler item in LVGL */ typedef struct { + uint64_t tick; /**< The tick value of the profiler item */ char tag; /**< The tag of the profiler item */ - uint32_t tick; /**< The tick value of the profiler item */ const char * func; /**< A pointer to the function associated with the profiler item */ #if LV_USE_OS int tid; /**< The thread ID of the profiler item */ @@ -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 */ @@ -69,6 +69,7 @@ typedef struct lv_profiler_builtin_ctx_t { * STATIC PROTOTYPES **********************/ +static uint64_t default_tick_get_cb(void); static void default_flush_cb(const char * buf); static int default_tid_get_cb(void); static int default_cpu_get_cb(void); @@ -92,7 +93,7 @@ void lv_profiler_builtin_config_init(lv_profiler_builtin_config_t * config) lv_memzero(config, sizeof(lv_profiler_builtin_config_t)); config->buf_size = LV_PROFILER_BUILTIN_BUF_SIZE; config->tick_per_sec = 1000; - config->tick_get_cb = lv_tick_get; + config->tick_get_cb = default_tick_get_cb; config->flush_cb = default_flush_cb; config->tid_get_cb = default_tid_get_cb; config->cpu_get_cb = default_cpu_get_cb; @@ -141,7 +142,7 @@ void lv_profiler_builtin_init(const lv_profiler_builtin_config_t * config) profiler_ctx->config.flush_cb("#\n"); } - lv_profiler_builtin_set_enable(true); + lv_profiler_builtin_set_enable(LV_PROFILER_BUILTIN_DEFAULT_ENABLE); LV_LOG_INFO("init OK, item_num = %d", (int)num); } @@ -208,6 +209,11 @@ void lv_profiler_builtin_write(const char * func, char tag) * STATIC FUNCTIONS **********************/ +static uint64_t default_tick_get_cb(void) +{ + return lv_tick_get(); +} + static void default_flush_cb(const char * buf) { LV_LOG("%s", buf); @@ -235,23 +241,23 @@ static void flush_no_lock(void) uint32_t tick_per_sec = profiler_ctx->config.tick_per_sec; while(cur < profiler_ctx->cur_index) { lv_profiler_builtin_item_t * item = &profiler_ctx->item_arr[cur++]; - uint32_t sec = item->tick / tick_per_sec; - uint32_t usec = (item->tick % tick_per_sec) * (LV_PROFILER_TICK_PER_SEC_MAX / tick_per_sec); + uint64_t sec = item->tick / tick_per_sec; + uint64_t nsec = (item->tick % tick_per_sec) * (LV_PROFILER_TICK_PER_SEC_MAX / tick_per_sec); #if LV_USE_OS lv_snprintf(buf, sizeof(buf), - " LVGL-%d [%d] %" LV_PRIu32 ".%06" LV_PRIu32 ": tracing_mark_write: %c|1|%s\n", + " LVGL-%d [%d] %" LV_PRIu64 ".%09" LV_PRIu64 ": tracing_mark_write: %c|1|%s\n", item->tid, item->cpu, sec, - usec, + nsec, item->tag, item->func); #else lv_snprintf(buf, sizeof(buf), - " LVGL-1 [0] %" LV_PRIu32 ".%06" LV_PRIu32 ": tracing_mark_write: %c|1|%s\n", + " LVGL-1 [0] %" LV_PRIu64 ".%09" LV_PRIu64 ": tracing_mark_write: %c|1|%s\n", sec, - usec, + nsec, item->tag, item->func); #endif 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 index 3fb9938a2..48bfc39da 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin_private.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_profiler_builtin_private.h @@ -29,10 +29,10 @@ extern "C" { /** * @brief LVGL profiler built-in configuration structure */ -struct lv_profiler_builtin_config_t { +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 */ + uint64_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 */ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_rb_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_rb_private.h index 327b7b0be..492ca2e23 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_rb_private.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_rb_private.h @@ -24,15 +24,15 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_rb_node_t { - struct lv_rb_node_t * parent; - struct lv_rb_node_t * left; - struct lv_rb_node_t * right; +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 { +struct _lv_rb_t { lv_rb_node_t * root; lv_rb_compare_t compare; size_t size; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_style.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_style.c index d137d67eb..fa77b026f 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_style.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_style.c @@ -137,6 +137,8 @@ const uint8_t lv_style_builtin_prop_flag_lookup_table[LV_STYLE_NUM_BUILT_IN_PROP [LV_STYLE_LAYOUT] = LV_STYLE_PROP_FLAG_LAYOUT_UPDATE, [LV_STYLE_BASE_DIR] = LV_STYLE_PROP_FLAG_INHERITABLE | LV_STYLE_PROP_FLAG_LAYOUT_UPDATE, [LV_STYLE_BITMAP_MASK_SRC] = LV_STYLE_PROP_FLAG_LAYER_UPDATE, + [LV_STYLE_RECOLOR] = 0, + [LV_STYLE_RECOLOR_OPA] = 0, #if LV_USE_FLEX [LV_STYLE_FLEX_FLOW] = LV_STYLE_PROP_FLAG_LAYOUT_UPDATE, @@ -198,6 +200,36 @@ void lv_style_reset(lv_style_t * style) #endif } + +void lv_style_copy(lv_style_t * dst, const lv_style_t * src) +{ + if(lv_style_is_const(dst)) { + LV_LOG_WARN("The destination can not be a constant style"); + return; + } + + lv_style_reset(dst); + + /*Source is empty*/ + if(src->values_and_props == NULL) return; + if(src->prop_cnt == 0) return; + + int32_t i; + if(lv_style_is_const(src)) { + lv_style_const_prop_t * props_and_values = (lv_style_const_prop_t *)src->values_and_props; + for(i = 0; props_and_values[i].prop != LV_STYLE_PROP_INV; i++) { + lv_style_set_prop(dst, props_and_values[i].prop, props_and_values[i].value); + } + } + else { + lv_style_prop_t * props = (lv_style_prop_t *)src->values_and_props + src->prop_cnt * sizeof(lv_style_value_t); + lv_style_value_t * values = (lv_style_value_t *)src->values_and_props; + for(i = 0; i < src->prop_cnt; i++) { + lv_style_set_prop(dst, props[i], values[i]); + } + } +} + lv_style_prop_t lv_style_register_prop(uint8_t flag) { if(lv_style_custom_prop_flag_lookup_table == NULL) { @@ -250,6 +282,8 @@ bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop) if(style->prop_cnt == 0) return false; + LV_PROFILER_STYLE_BEGIN; + uint8_t * tmp = (lv_style_prop_t *)style->values_and_props + style->prop_cnt * sizeof(lv_style_value_t); uint8_t * old_props = (uint8_t *)tmp; uint32_t i; @@ -259,7 +293,11 @@ bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop) size_t size = (style->prop_cnt - 1) * (sizeof(lv_style_value_t) + sizeof(lv_style_prop_t)); uint8_t * new_values_and_props = lv_malloc(size); - if(new_values_and_props == NULL) return false; + if(new_values_and_props == NULL) { + LV_PROFILER_STYLE_END; + return false; + } + style->values_and_props = new_values_and_props; style->prop_cnt--; @@ -277,10 +315,12 @@ bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop) } lv_free(old_values); + LV_PROFILER_STYLE_END; return true; } } + LV_PROFILER_STYLE_END; return false; } @@ -294,7 +334,7 @@ void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_ } LV_ASSERT(prop != LV_STYLE_PROP_INV); - + LV_PROFILER_STYLE_BEGIN; lv_style_prop_t * props; int32_t i; @@ -304,6 +344,7 @@ void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_ if(props[i] == prop) { lv_style_value_t * values = (lv_style_value_t *)style->values_and_props; values[i] = value; + LV_PROFILER_STYLE_END; return; } } @@ -311,7 +352,11 @@ void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_ size_t size = (style->prop_cnt + 1) * (sizeof(lv_style_value_t) + sizeof(lv_style_prop_t)); uint8_t * values_and_props = lv_realloc(style->values_and_props, size); - if(values_and_props == NULL) return; + if(values_and_props == NULL) { + LV_PROFILER_STYLE_END; + return; + } + style->values_and_props = values_and_props; props = values_and_props + style->prop_cnt * sizeof(lv_style_value_t); @@ -331,6 +376,7 @@ void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_ uint32_t group = lv_style_get_prop_group(prop); style->has_group |= (uint32_t)1 << group; + LV_PROFILER_STYLE_END; } lv_style_res_t lv_style_get_prop(const lv_style_t * style, lv_style_prop_t prop, lv_style_value_t * value) @@ -371,6 +417,7 @@ lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop) case LV_STYLE_LINE_COLOR: case LV_STYLE_TEXT_COLOR: case LV_STYLE_IMAGE_RECOLOR: + case LV_STYLE_RECOLOR: return (lv_style_value_t) { .color = black }; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_style.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_style.h index dcce7dcd6..2da6cd1f8 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 * */ @@ -21,6 +21,7 @@ extern "C" { #include "lv_types.h" #include "lv_assert.h" #include "lv_bidi.h" +#include "lv_grad.h" #include "../layouts/lv_layout.h" /********************* @@ -59,7 +60,7 @@ LV_EXPORT_CONST_INT(LV_SCALE_NONE); #else #define LV_STYLE_CONST_INIT(var_name, prop_array) \ const lv_style_t var_name = { \ - .values_and_props = prop_array, \ + .values_and_props = (void*)prop_array, \ .has_group = 0xFFFFFFFF, \ .prop_cnt = 255, \ } @@ -68,6 +69,16 @@ LV_EXPORT_CONST_INT(LV_SCALE_NONE); #define LV_STYLE_CONST_PROPS_END { .prop = LV_STYLE_PROP_INV, .value = { .num = 0 } } +#if LV_GRADIENT_MAX_STOPS < 2 +#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 **********************/ @@ -80,6 +91,7 @@ typedef enum { 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*/ + LV_BLEND_MODE_DIFFERENCE, /**< Absolute difference between foreground and background*/ } lv_blend_mode_t; /** @@ -106,71 +118,6 @@ typedef enum { LV_BORDER_SIDE_INTERNAL = 0x10, /**< FOR matrix-like objects (e.g. Button matrix)*/ } lv_border_side_t; -/** - * The direction of the 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; - -/** - * 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. - */ -typedef struct { - lv_color_t color; /**< The stop color */ - lv_opa_t opa; /**< The opacity of the color*/ - uint8_t frac; /**< The stop position in 1/255 unit */ -} lv_gradient_stop_t; - -/** 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_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; - /** * A common type to handle all the property types in the same way. */ @@ -203,6 +150,8 @@ enum { LV_STYLE_ALIGN = 10, LV_STYLE_RADIUS = 12, + LV_STYLE_RADIAL_OFFSET = 13, + LV_STYLE_PAD_RADIAL = 14, /*Group 1*/ LV_STYLE_PAD_TOP = 16, @@ -289,47 +238,53 @@ enum { LV_STYLE_TEXT_LINE_SPACE = 92, LV_STYLE_TEXT_DECOR = 93, LV_STYLE_TEXT_ALIGN = 94, + LV_STYLE_TEXT_OUTLINE_STROKE_WIDTH = 95, + LV_STYLE_TEXT_OUTLINE_STROKE_OPA = 96, + LV_STYLE_TEXT_OUTLINE_STROKE_COLOR = 97, - LV_STYLE_OPA = 95, - LV_STYLE_OPA_LAYERED = 96, - LV_STYLE_COLOR_FILTER_DSC = 97, - LV_STYLE_COLOR_FILTER_OPA = 98, - LV_STYLE_ANIM = 99, - LV_STYLE_ANIM_DURATION = 100, - LV_STYLE_TRANSITION = 102, - LV_STYLE_BLEND_MODE = 103, - LV_STYLE_TRANSFORM_WIDTH = 104, - LV_STYLE_TRANSFORM_HEIGHT = 105, - LV_STYLE_TRANSLATE_X = 106, - LV_STYLE_TRANSLATE_Y = 107, - LV_STYLE_TRANSFORM_SCALE_X = 108, - LV_STYLE_TRANSFORM_SCALE_Y = 109, - LV_STYLE_TRANSFORM_ROTATION = 110, - LV_STYLE_TRANSFORM_PIVOT_X = 111, - LV_STYLE_TRANSFORM_PIVOT_Y = 112, - LV_STYLE_TRANSFORM_SKEW_X = 113, - LV_STYLE_TRANSFORM_SKEW_Y = 114, - LV_STYLE_BITMAP_MASK_SRC = 115, - LV_STYLE_ROTARY_SENSITIVITY = 116, + LV_STYLE_OPA = 98, + LV_STYLE_OPA_LAYERED = 99, + LV_STYLE_COLOR_FILTER_DSC = 100, + LV_STYLE_COLOR_FILTER_OPA = 101, + LV_STYLE_ANIM = 102, + LV_STYLE_ANIM_DURATION = 103, + LV_STYLE_TRANSITION = 104, + LV_STYLE_BLEND_MODE = 105, + LV_STYLE_TRANSFORM_WIDTH = 106, + LV_STYLE_TRANSFORM_HEIGHT = 107, + LV_STYLE_TRANSLATE_X = 108, + LV_STYLE_TRANSLATE_Y = 109, + LV_STYLE_TRANSFORM_SCALE_X = 110, + LV_STYLE_TRANSFORM_SCALE_Y = 111, + LV_STYLE_TRANSFORM_ROTATION = 112, + LV_STYLE_TRANSFORM_PIVOT_X = 113, + LV_STYLE_TRANSFORM_PIVOT_Y = 114, + LV_STYLE_TRANSFORM_SKEW_X = 115, + LV_STYLE_TRANSFORM_SKEW_Y = 116, + LV_STYLE_BITMAP_MASK_SRC = 117, + LV_STYLE_ROTARY_SENSITIVITY = 118, + LV_STYLE_TRANSLATE_RADIAL = 119, + LV_STYLE_RECOLOR = 120, + LV_STYLE_RECOLOR_OPA = 121, - 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, + LV_STYLE_FLEX_FLOW = 122, + LV_STYLE_FLEX_MAIN_PLACE = 123, + LV_STYLE_FLEX_CROSS_PLACE = 124, + LV_STYLE_FLEX_TRACK_PLACE = 125, + LV_STYLE_FLEX_GROW = 126, - LV_STYLE_GRID_COLUMN_ALIGN = 130, - LV_STYLE_GRID_ROW_ALIGN = 131, - LV_STYLE_GRID_ROW_DSC_ARRAY = 132, - LV_STYLE_GRID_COLUMN_DSC_ARRAY = 133, - LV_STYLE_GRID_CELL_COLUMN_POS = 134, - LV_STYLE_GRID_CELL_COLUMN_SPAN = 135, - LV_STYLE_GRID_CELL_X_ALIGN = 136, - LV_STYLE_GRID_CELL_ROW_POS = 137, - LV_STYLE_GRID_CELL_ROW_SPAN = 138, - LV_STYLE_GRID_CELL_Y_ALIGN = 139, + LV_STYLE_GRID_COLUMN_ALIGN = 127, + LV_STYLE_GRID_ROW_ALIGN = 128, + LV_STYLE_GRID_ROW_DSC_ARRAY = 129, + LV_STYLE_GRID_COLUMN_DSC_ARRAY = 130, + LV_STYLE_GRID_CELL_COLUMN_POS = 131, + LV_STYLE_GRID_CELL_COLUMN_SPAN = 132, + LV_STYLE_GRID_CELL_X_ALIGN = 133, + LV_STYLE_GRID_CELL_ROW_POS = 134, + LV_STYLE_GRID_CELL_ROW_SPAN = 135, + LV_STYLE_GRID_CELL_Y_ALIGN = 136, - LV_STYLE_LAST_BUILT_IN_PROP = 140, + LV_STYLE_LAST_BUILT_IN_PROP = 137, LV_STYLE_NUM_BUILT_IN_PROPS = LV_STYLE_LAST_BUILT_IN_PROP + 1, @@ -395,6 +350,20 @@ void lv_style_init(lv_style_t * style); */ void lv_style_reset(lv_style_t * style); +/** + * Copy all properties of a style to an other. + * It has the same affect callying the same `lv_set_style_...` + * functions on both styles. + * It means new memory will be allocated to store the properties in + * the destination style. + * After the copy the destination style is fully independent of the source + * and source can removed without affecting the destination style. + * @param dst the destination to copy into (can not the a constant style) + * @param src the source style to copy from. + */ +void lv_style_copy(lv_style_t * dst, const lv_style_t * src); + + /** * Check if a style is constant * @param style pointer to a style @@ -406,6 +375,7 @@ static inline bool lv_style_is_const(const lv_style_t * style) return false; } + /** * Register a new style property for custom usage * @return a new property ID, or LV_STYLE_PROP_INV if there are no more available. @@ -584,6 +554,26 @@ static inline void lv_style_set_pad_gap(lv_style_t * style, int32_t value) lv_style_set_pad_column(style, value); } +static inline void lv_style_set_margin_hor(lv_style_t * style, int32_t value) +{ + lv_style_set_margin_left(style, value); + lv_style_set_margin_right(style, value); +} + +static inline void lv_style_set_margin_ver(lv_style_t * style, int32_t value) +{ + lv_style_set_margin_top(style, value); + lv_style_set_margin_bottom(style, value); +} + +static inline void lv_style_set_margin_all(lv_style_t * style, int32_t value) +{ + lv_style_set_margin_left(style, value); + lv_style_set_margin_right(style, value); + lv_style_set_margin_top(style, value); + lv_style_set_margin_bottom(style, value); +} + static inline void lv_style_set_transform_scale(lv_style_t * style, int32_t value) { lv_style_set_transform_scale_x(style, value); 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 233cf7b94..cd7fe4f47 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_style_gen.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_style_gen.c @@ -122,6 +122,14 @@ void lv_style_set_translate_y(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_TRANSLATE_Y, v); } +void lv_style_set_translate_radial(lv_style_t * style, int32_t value) +{ + lv_style_value_t v = { + .num = (int32_t)value + }; + lv_style_set_prop(style, LV_STYLE_TRANSLATE_RADIAL, v); +} + void lv_style_set_transform_scale_x(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -226,6 +234,14 @@ void lv_style_set_pad_column(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_PAD_COLUMN, v); } +void lv_style_set_pad_radial(lv_style_t * style, int32_t value) +{ + lv_style_value_t v = { + .num = (int32_t)value + }; + lv_style_set_prop(style, LV_STYLE_PAD_RADIAL, v); +} + void lv_style_set_margin_top(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -658,6 +674,30 @@ 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); } +void lv_style_set_text_outline_stroke_color(lv_style_t * style, lv_color_t value) +{ + lv_style_value_t v = { + .color = value + }; + lv_style_set_prop(style, LV_STYLE_TEXT_OUTLINE_STROKE_COLOR, v); +} + +void lv_style_set_text_outline_stroke_width(lv_style_t * style, int32_t value) +{ + lv_style_value_t v = { + .num = (int32_t)value + }; + lv_style_set_prop(style, LV_STYLE_TEXT_OUTLINE_STROKE_WIDTH, v); +} + +void lv_style_set_text_outline_stroke_opa(lv_style_t * style, lv_opa_t value) +{ + lv_style_value_t v = { + .num = (int32_t)value + }; + lv_style_set_prop(style, LV_STYLE_TEXT_OUTLINE_STROKE_OPA, v); +} + void lv_style_set_radius(lv_style_t * style, int32_t value) { lv_style_value_t v = { @@ -666,6 +706,14 @@ void lv_style_set_radius(lv_style_t * style, int32_t value) lv_style_set_prop(style, LV_STYLE_RADIUS, v); } +void lv_style_set_radial_offset(lv_style_t * style, int32_t value) +{ + lv_style_value_t v = { + .num = (int32_t)value + }; + lv_style_set_prop(style, LV_STYLE_RADIAL_OFFSET, v); +} + void lv_style_set_clip_corner(lv_style_t * style, bool value) { lv_style_value_t v = { @@ -706,6 +754,22 @@ 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); } +void lv_style_set_recolor(lv_style_t * style, lv_color_t value) +{ + lv_style_value_t v = { + .color = value + }; + lv_style_set_prop(style, LV_STYLE_RECOLOR, v); +} + +void lv_style_set_recolor_opa(lv_style_t * style, lv_opa_t value) +{ + lv_style_value_t v = { + .num = (int32_t)value + }; + lv_style_set_prop(style, LV_STYLE_RECOLOR_OPA, v); +} + void lv_style_set_anim(lv_style_t * style, const lv_anim_t * value) { lv_style_value_t v = { 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 5714e74d9..b5c030dcb 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_style_gen.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_style_gen.h @@ -28,6 +28,7 @@ void lv_style_set_transform_width(lv_style_t * style, int32_t value); void lv_style_set_transform_height(lv_style_t * style, int32_t value); void lv_style_set_translate_x(lv_style_t * style, int32_t value); void lv_style_set_translate_y(lv_style_t * style, int32_t value); +void lv_style_set_translate_radial(lv_style_t * style, int32_t value); void lv_style_set_transform_scale_x(lv_style_t * style, int32_t value); void lv_style_set_transform_scale_y(lv_style_t * style, int32_t value); void lv_style_set_transform_rotation(lv_style_t * style, int32_t value); @@ -41,6 +42,7 @@ void lv_style_set_pad_left(lv_style_t * style, int32_t value); void lv_style_set_pad_right(lv_style_t * style, int32_t value); void lv_style_set_pad_row(lv_style_t * style, int32_t value); void lv_style_set_pad_column(lv_style_t * style, int32_t value); +void lv_style_set_pad_radial(lv_style_t * style, int32_t value); void lv_style_set_margin_top(lv_style_t * style, int32_t value); void lv_style_set_margin_bottom(lv_style_t * style, int32_t value); void lv_style_set_margin_left(lv_style_t * style, int32_t value); @@ -95,12 +97,18 @@ void lv_style_set_text_letter_space(lv_style_t * style, int32_t value); void lv_style_set_text_line_space(lv_style_t * style, int32_t value); void lv_style_set_text_decor(lv_style_t * style, lv_text_decor_t value); void lv_style_set_text_align(lv_style_t * style, lv_text_align_t value); +void lv_style_set_text_outline_stroke_color(lv_style_t * style, lv_color_t value); +void lv_style_set_text_outline_stroke_width(lv_style_t * style, int32_t value); +void lv_style_set_text_outline_stroke_opa(lv_style_t * style, lv_opa_t value); void lv_style_set_radius(lv_style_t * style, int32_t value); +void lv_style_set_radial_offset(lv_style_t * style, int32_t value); void lv_style_set_clip_corner(lv_style_t * style, bool value); void lv_style_set_opa(lv_style_t * style, lv_opa_t value); void lv_style_set_opa_layered(lv_style_t * style, lv_opa_t value); void lv_style_set_color_filter_dsc(lv_style_t * style, const lv_color_filter_dsc_t * value); void lv_style_set_color_filter_opa(lv_style_t * style, lv_opa_t value); +void lv_style_set_recolor(lv_style_t * style, lv_color_t value); +void lv_style_set_recolor_opa(lv_style_t * style, lv_opa_t value); void lv_style_set_anim(lv_style_t * style, const lv_anim_t * value); void lv_style_set_anim_duration(lv_style_t * style, uint32_t value); void lv_style_set_transition(lv_style_t * style, const lv_style_transition_dsc_t * value); @@ -201,6 +209,11 @@ void lv_style_set_grid_cell_row_span(lv_style_t * style, int32_t value); .prop = LV_STYLE_TRANSLATE_Y, .value = { .num = (int32_t)val } \ } +#define LV_STYLE_CONST_TRANSLATE_RADIAL(val) \ + { \ + .prop = LV_STYLE_TRANSLATE_RADIAL, .value = { .num = (int32_t)val } \ + } + #define LV_STYLE_CONST_TRANSFORM_SCALE_X(val) \ { \ .prop = LV_STYLE_TRANSFORM_SCALE_X, .value = { .num = (int32_t)val } \ @@ -266,6 +279,11 @@ void lv_style_set_grid_cell_row_span(lv_style_t * style, int32_t value); .prop = LV_STYLE_PAD_COLUMN, .value = { .num = (int32_t)val } \ } +#define LV_STYLE_CONST_PAD_RADIAL(val) \ + { \ + .prop = LV_STYLE_PAD_RADIAL, .value = { .num = (int32_t)val } \ + } + #define LV_STYLE_CONST_MARGIN_TOP(val) \ { \ .prop = LV_STYLE_MARGIN_TOP, .value = { .num = (int32_t)val } \ @@ -536,11 +554,31 @@ void lv_style_set_grid_cell_row_span(lv_style_t * style, int32_t value); .prop = LV_STYLE_TEXT_ALIGN, .value = { .num = (int32_t)val } \ } +#define LV_STYLE_CONST_TEXT_OUTLINE_STROKE_COLOR(val) \ + { \ + .prop = LV_STYLE_TEXT_OUTLINE_STROKE_COLOR, .value = { .color = val } \ + } + +#define LV_STYLE_CONST_TEXT_OUTLINE_STROKE_WIDTH(val) \ + { \ + .prop = LV_STYLE_TEXT_OUTLINE_STROKE_WIDTH, .value = { .num = (int32_t)val } \ + } + +#define LV_STYLE_CONST_TEXT_OUTLINE_STROKE_OPA(val) \ + { \ + .prop = LV_STYLE_TEXT_OUTLINE_STROKE_OPA, .value = { .num = (int32_t)val } \ + } + #define LV_STYLE_CONST_RADIUS(val) \ { \ .prop = LV_STYLE_RADIUS, .value = { .num = (int32_t)val } \ } +#define LV_STYLE_CONST_RADIAL_OFFSET(val) \ + { \ + .prop = LV_STYLE_RADIAL_OFFSET, .value = { .num = (int32_t)val } \ + } + #define LV_STYLE_CONST_CLIP_CORNER(val) \ { \ .prop = LV_STYLE_CLIP_CORNER, .value = { .num = (int32_t)val } \ @@ -566,6 +604,16 @@ void lv_style_set_grid_cell_row_span(lv_style_t * style, int32_t value); .prop = LV_STYLE_COLOR_FILTER_OPA, .value = { .num = (int32_t)val } \ } +#define LV_STYLE_CONST_RECOLOR(val) \ + { \ + .prop = LV_STYLE_RECOLOR, .value = { .color = val } \ + } + +#define LV_STYLE_CONST_RECOLOR_OPA(val) \ + { \ + .prop = LV_STYLE_RECOLOR_OPA, .value = { .num = (int32_t)val } \ + } + #define LV_STYLE_CONST_ANIM(val) \ { \ .prop = LV_STYLE_ANIM, .value = { .ptr = val } \ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_text.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_text.c index 11081f959..de182033b 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_text.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_text.c @@ -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], LV_TEXT_LEN_MAX, 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"); @@ -118,7 +118,8 @@ void lv_text_get_size(lv_point_t * size_res, const char * text, const lv_font_t } /*Calculate the longest line*/ - int32_t act_line_length = lv_text_get_width(&text[line_start], new_line_start - line_start, font, letter_space); + int32_t act_line_length = lv_text_get_width_with_flags(&text[line_start], new_line_start - line_start, font, + letter_space, flag); size_res->x = LV_MAX(act_line_length, size_res->x); line_start = new_line_start; @@ -136,6 +137,37 @@ void lv_text_get_size(lv_point_t * size_res, const char * text, const lv_font_t size_res->y -= line_space; } +bool lv_text_is_cmd(lv_text_cmd_state_t * state, uint32_t c) +{ + bool ret = false; + + if(c == (uint32_t)LV_TXT_COLOR_CMD[0]) { + if(*state == LV_TEXT_CMD_STATE_WAIT) { /*Start char*/ + *state = LV_TEXT_CMD_STATE_PAR; + ret = true; + } + /*Other start char in parameter is escaped cmd. char*/ + else if(*state == LV_TEXT_CMD_STATE_WAIT) { + *state = LV_TEXT_CMD_STATE_WAIT; + } + /*Command end*/ + else if(*state == LV_TEXT_CMD_STATE_IN) { + *state = LV_TEXT_CMD_STATE_WAIT; + ret = true; + } + } + + /*Skip the color parameter and wait the space after it*/ + if(*state == LV_TEXT_CMD_STATE_PAR) { + if(c == ' ') { + *state = LV_TEXT_CMD_STATE_IN; /*After the parameter the text is in the command*/ + } + ret = true; + } + + return ret; +} + /** * Get the next word of text. A word is delimited by break characters. * @@ -164,11 +196,13 @@ 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 cmd_state Pointer to a lv_text_cmd_state_t variable which stored the current state of command processing * @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) + lv_text_flag_t flag, uint32_t * word_w_ptr, + lv_text_cmd_state_t * cmd_state) { if(txt == NULL || txt[0] == '\0') return 0; if(font == NULL) return 0; @@ -192,6 +226,16 @@ static uint32_t lv_text_get_next_word(const char * txt, const lv_font_t * font, letter_next = lv_text_encoded_next(txt, &i_next_next); word_len++; + /*Handle the recolor command*/ + if((flag & LV_TEXT_FLAG_RECOLOR) != 0) { + if(lv_text_is_cmd(cmd_state, letter)) { + i = i_next; + i_next = i_next_next; + letter = letter_next; + continue; /*Skip the letter if it is part of a command*/ + } + } + letter_w = lv_font_get_glyph_width(font, letter, letter_next); cur_w += letter_w; @@ -203,6 +247,9 @@ static uint32_t lv_text_get_next_word(const char * txt, const lv_font_t * font, if(break_index == NO_BREAK_FOUND && (cur_w - letter_space) > max_width) { break_index = i; break_letter_count = word_len - 1; + if(flag & LV_TEXT_FLAG_BREAK_ALL) { + break; + } /*break_index is now pointing at the character that doesn't fit*/ } @@ -272,9 +319,9 @@ static uint32_t lv_text_get_next_word(const char * txt, const lv_font_t * font, #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, uint32_t len, + 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; @@ -288,23 +335,25 @@ uint32_t lv_text_get_next_line(const char * txt, const lv_font_t * font, *without thinking about word wrapping*/ if((flag & LV_TEXT_FLAG_EXPAND) || (flag & LV_TEXT_FLAG_FIT)) { uint32_t i; - for(i = 0; txt[i] != '\n' && txt[i] != '\r' && txt[i] != '\0'; i++) { + for(i = 0; i < len && txt[i] != '\n' && txt[i] != '\r' && txt[i] != '\0'; i++) { /*Just find the new line chars or string ends by incrementing `i`*/ } - if(txt[i] != '\0') i++; /*To go beyond `\n`*/ + if(i < len && txt[i] != '\0') i++; /*To go beyond `\n`*/ if(used_width) *used_width = -1; return i; } if(flag & LV_TEXT_FLAG_EXPAND) max_width = LV_COORD_MAX; + lv_text_cmd_state_t cmd_state = LV_TEXT_CMD_STATE_WAIT; + uint32_t i = 0; /*Iterating index into txt*/ - while(txt[i] != '\0' && max_width > 0) { + while(i < len && 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, word_flag, &word_w); + uint32_t advance = lv_text_get_next_word(&txt[i], font, letter_space, max_width, word_flag, &word_w, &cmd_state); max_width -= word_w; line_w += word_w; @@ -369,6 +418,45 @@ int32_t lv_text_get_width(const char * txt, uint32_t length, const lv_font_t * f return width; } +int32_t lv_text_get_width_with_flags(const char * txt, uint32_t length, const lv_font_t * font, int32_t letter_space, + lv_text_flag_t flags) +{ + if(txt == NULL) return 0; + if(font == NULL) return 0; + if(txt[0] == '\0') return 0; + + uint32_t i = 0; + int32_t width = 0; + lv_text_cmd_state_t cmd_state = LV_TEXT_CMD_STATE_WAIT; + + if(length != 0) { + while(txt[i] != '\0' && i < length) { + uint32_t letter; + uint32_t letter_next; + lv_text_encoded_letter_next_2(txt, &letter, &letter_next, &i); + + if((flags & LV_TEXT_FLAG_RECOLOR) != 0) { + if(lv_text_is_cmd(&cmd_state, letter) != false) { + continue; + } + } + + int32_t char_width = lv_font_get_glyph_width(font, letter, letter_next); + if(char_width > 0) { + width += char_width; + width += letter_space; + } + } + + if(width > 0) { + width -= letter_space; /*Trim the last letter space. Important if the text is center + aligned*/ + } + } + + return width; +} + void lv_text_ins(char * txt_buf, uint32_t pos, const char * ins_txt) { if(txt_buf == NULL || ins_txt == NULL) return; @@ -562,6 +650,11 @@ static uint32_t lv_text_utf8_next(const char * txt, uint32_t * i) uint32_t i_tmp = 0; if(i == NULL) i = &i_tmp; + /* Ensure the string is not null */ + if(txt == NULL || txt[*i] == '\0') { + return result; + } + /*Normal ASCII*/ if(LV_IS_ASCII(txt[*i])) { result = txt[*i]; diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_text.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_text.h index f2407dd8e..77b176d3e 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_text.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_text.h @@ -23,10 +23,15 @@ extern "C" { /********************* * DEFINES *********************/ +#ifndef LV_TXT_COLOR_CMD +#define LV_TXT_COLOR_CMD "#" +#endif #define LV_TXT_ENC_UTF8 1 #define LV_TXT_ENC_ASCII 2 +#define LV_TEXT_LEN_MAX UINT32_MAX + /********************** * TYPEDEFS **********************/ @@ -43,6 +48,7 @@ typedef enum { 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_RECOLOR = 0x08, /**< Enable parsing of recolor command*/ } lv_text_flag_t; /** Label align policy*/ @@ -53,6 +59,13 @@ typedef enum { LV_TEXT_ALIGN_RIGHT, /**< Align text to right*/ } lv_text_align_t; +/** State machine for text renderer. */ +typedef enum { + LV_TEXT_CMD_STATE_WAIT, /**< Waiting for command*/ + LV_TEXT_CMD_STATE_PAR, /**< Processing the parameter*/ + LV_TEXT_CMD_STATE_IN, /**< Processing the command*/ +} lv_text_cmd_state_t; + /********************** * GLOBAL PROTOTYPES **********************/ @@ -83,6 +96,26 @@ void lv_text_get_size(lv_point_t * size_res, const char * text, const lv_font_t */ int32_t lv_text_get_width(const char * txt, uint32_t length, const lv_font_t * font, int32_t letter_space); +/** + * Give the length of a text with a given font with text flags + * @param txt a '\0' terminate string + * @param length length of 'txt' in byte count and not characters (Á is 1 character but 2 bytes in + * UTF-8) + * @param font pointer to a font + * @param letter_space letter space + * @param flags settings for the text from ::lv_text_flag_t + * @return length of a char_num long text + */ +int32_t lv_text_get_width_with_flags(const char * txt, uint32_t length, const lv_font_t * font, int32_t letter_space, + lv_text_flag_t flags); + +/** + * Check if c is command state + * @param state + * @param c + * @return True if c is state + */ +bool lv_text_is_cmd(lv_text_cmd_state_t * state, uint32_t c); /********************** * 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 320debd0f..e6dcb4ddb 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_text_ap.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_text_ap.c @@ -46,6 +46,7 @@ static bool lv_text_is_arabic_vowel(uint16_t c); const ap_chars_map_t ap_chars_map[] = { /*{Key Offset, End, Beginning, Middle, Isolated, {conjunction}}*/ + {0, 0xFE81, 0, 0, 0, {0, 0}}, // أ {1, 0xFE84, -1, 0, -1, {1, 0}}, // أ {2, 0xFE86, -1, 0, -1, {1, 0}}, // ؤ {3, 0xFE88, -1, 0, -1, {1, 0}}, // ﺇ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_text_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_text_private.h index 858f59383..3814d8a14 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_text_private.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_text_private.h @@ -31,6 +31,7 @@ extern "C" { /** * Get the next line of text. Check line length and break chars too. * @param txt a '\0' terminated string + * @param len length of 'txt' in bytes * @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 @@ -41,7 +42,7 @@ extern "C" { * @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, +uint32_t lv_text_get_next_line(const char * txt, uint32_t len, const lv_font_t * font, int32_t letter_space, int32_t max_width, int32_t * used_width, lv_text_flag_t flag); /** diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.c index 959ce53b9..55f3319c4 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.c @@ -77,7 +77,7 @@ LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void) return 1; } - LV_PROFILER_BEGIN; + LV_PROFILER_TIMER_BEGIN; lv_lock(); uint32_t handler_start = lv_tick_get(); @@ -143,8 +143,7 @@ LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void) LV_TRACE_TIMER("finished (%" LV_PRIu32 " ms until the next timer call)", time_until_next); lv_unlock(); - LV_PROFILER_END; - + LV_PROFILER_TIMER_END; return time_until_next; } @@ -323,7 +322,11 @@ static bool lv_timer_exec(lv_timer_t * timer) timer->last_run = lv_tick_get(); LV_TRACE_TIMER("calling timer callback: %p", *((void **)&timer->timer_cb)); - if(timer->timer_cb && original_repeat_count != 0) timer->timer_cb(timer); + if(timer->timer_cb && original_repeat_count != 0) { + LV_PROFILER_TIMER_BEGIN_TAG("timer_cb"); + timer->timer_cb(timer); + LV_PROFILER_TIMER_END_TAG("timer_cb"); + } if(!state.timer_deleted) { LV_TRACE_TIMER("timer callback %p finished", *((void **)&timer->timer_cb)); diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.h index be2500333..063b283ef 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_timer.h @@ -44,16 +44,12 @@ typedef void (*lv_timer_handler_resume_cb_t)(void * data); * GLOBAL PROTOTYPES **********************/ -//! @cond Doxygen_Suppress - /** * Call it periodically to handle lv_timers. * @return time till it needs to be run next (in ms) */ LV_ATTRIBUTE_TIMER_HANDLER uint32_t lv_timer_handler(void); -//! @endcond - /** * Call it in the super-loop of main() or threads. It will run lv_timer_handler() * with a given period in ms. You can use it with sleep or delay in OS environment. diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_timer_private.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_timer_private.h index b7f42b0a1..9f7269f58 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_timer_private.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_timer_private.h @@ -27,7 +27,7 @@ extern "C" { /** * Descriptor of a lv_timer */ -struct lv_timer_t { +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 */ diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_tree.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_tree.c new file mode 100644 index 000000000..93fcff972 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_tree.c @@ -0,0 +1,189 @@ +/** + * @file lv_tree.c + * Tree. + * The nodes are dynamically allocated by the 'lv_mem' module, + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_tree.h" +#include "../stdlib/lv_mem.h" +#include "../stdlib/lv_string.h" + +#include "lv_assert.h" + +/********************* + * DEFINES + *********************/ +#define INIT_CHILDREN_CAP 4 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +const lv_tree_class_t lv_tree_node_class = { + .base_class = NULL, + .instance_size = sizeof(lv_tree_node_t), + .constructor_cb = NULL, + .destructor_cb = NULL, +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +static void _lv_tree_node_construct(const lv_tree_class_t * class_p, lv_tree_node_t * node) +{ + if(node->class_p->base_class) { + const lv_tree_class_t * original_class_p = node->class_p; + + node->class_p = node->class_p->base_class; + + _lv_tree_node_construct(class_p, node); + + node->class_p = original_class_p; + } + + if(node->class_p->constructor_cb) node->class_p->constructor_cb(class_p, node); +} + +static void _lv_tree_node_destruct(lv_tree_node_t * node) +{ + if(node->class_p->destructor_cb) node->class_p->destructor_cb(node->class_p, node); + + if(node->class_p->base_class) { + node->class_p = node->class_p->base_class; + + _lv_tree_node_destruct(node); + } +} + +static uint32_t get_instance_size(const lv_tree_class_t * class_p) +{ + const lv_tree_class_t * base = class_p; + while(base && base->instance_size == 0) + base = base->base_class; + + LV_ASSERT_NULL(base); + + return base->instance_size; +} + +static lv_tree_node_t * _lv_tree_class_create_node(const lv_tree_class_t * class_p, lv_tree_node_t * parent) +{ + uint32_t s = get_instance_size(class_p); + lv_tree_node_t * node = lv_malloc(s); + if(node == NULL) return NULL; + lv_memzero(node, s); + node->class_p = class_p; + node->parent = parent; + node->child_cap = INIT_CHILDREN_CAP; + node->children = lv_malloc(sizeof(lv_tree_node_t *) * node->child_cap); + if(parent != NULL) { + parent->child_cnt++; + if(parent->child_cnt == parent->child_cap) { + parent->child_cap <<= 1; + parent->children = lv_realloc(parent->children, sizeof(lv_tree_node_t *) * parent->child_cap); + } + parent->children[parent->child_cnt - 1] = node; + } + return node; +} + +lv_tree_node_t * lv_tree_node_create(const lv_tree_class_t * class_p, lv_tree_node_t * parent) +{ + LV_ASSERT_NULL(class_p); + lv_tree_node_t * node = _lv_tree_class_create_node(class_p, parent); + LV_ASSERT_NULL(node); + _lv_tree_node_construct(node->class_p, node); + return node; +} + +static bool _lv_tree_node_destructor_cb(const lv_tree_node_t * n, void * user_data) +{ + LV_UNUSED(user_data); + if(n) { + lv_tree_node_t * node = (lv_tree_node_t *)n; + _lv_tree_node_destruct(node); + lv_free(node->children); + lv_free(node); + } + return true; +} + +void lv_tree_node_delete(lv_tree_node_t * node) +{ + if(node) { + if(node->parent) { + /* Remove from parent */ + lv_tree_node_t * parent = node->parent; + for(uint32_t i = 0; i < parent->child_cnt; i++) { + if(parent->children[i] == node) { + parent->children[i] = NULL; + } + } + } + lv_tree_walk(node, LV_TREE_WALK_POST_ORDER, _lv_tree_node_destructor_cb, NULL, NULL, NULL); + } +} + +bool lv_tree_walk(const lv_tree_node_t * node, + lv_tree_walk_mode_t mode, + lv_tree_traverse_cb_t cb, + lv_tree_before_cb_t bcb, + lv_tree_after_cb_t acb, + void * user_data) +{ + if(node && cb) { + if(mode == LV_TREE_WALK_PRE_ORDER) { + if(bcb && !bcb(node, user_data)) { + return false; + } + if(!cb(node, user_data)) { + return false; + } + } + for(uint32_t i = 0; i < node->child_cnt; i++) { + if(!lv_tree_walk(node->children[i], mode, cb, bcb, acb, user_data)) { + return false; + } + } + if(mode == LV_TREE_WALK_PRE_ORDER) { + if(acb) { + acb(node, user_data); + } + } + + if(mode == LV_TREE_WALK_POST_ORDER) { + if(bcb && !bcb(node, user_data)) { + return false; + } + if(!cb(node, user_data)) { + return false; + } + if(acb) { + acb(node, user_data); + } + return true; + } + else { + return true; + } + } + else { + return true; + } +} diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_tree.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_tree.h new file mode 100644 index 000000000..cb1fda7ad --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_tree.h @@ -0,0 +1,105 @@ +/** + * @file lv_tree.h + * Tree. The tree nodes are dynamically allocated by the 'lv_mem' module. + */ + +#ifndef LV_TREE_H +#define LV_TREE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_types.h" + +/********************* + * DEFINES + *********************/ + +#define LV_TREE_NODE(n) ((lv_tree_node_t*)(n)) + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_tree_node_t; + +/** + * Describe the common methods of every object. + * Similar to a C++ class. + */ +typedef struct _lv_tree_class_t { + const struct _lv_tree_class_t * base_class; + uint32_t instance_size; + void (*constructor_cb)(const struct _lv_tree_class_t * class_p, struct _lv_tree_node_t * node); + void (*destructor_cb)(const struct _lv_tree_class_t * class_p, struct _lv_tree_node_t * node); +} lv_tree_class_t; + +/** Description of a tree node*/ +typedef struct _lv_tree_node_t { + struct _lv_tree_node_t * parent; + struct _lv_tree_node_t ** children; + uint32_t child_cnt; + uint32_t child_cap; + const struct _lv_tree_class_t * class_p; +} lv_tree_node_t; + +enum { + LV_TREE_WALK_PRE_ORDER = 0, + LV_TREE_WALK_POST_ORDER, +}; +typedef uint8_t lv_tree_walk_mode_t; + +typedef bool (*lv_tree_traverse_cb_t)(const lv_tree_node_t * node, void * user_data); +typedef bool (*lv_tree_before_cb_t)(const lv_tree_node_t * node, void * user_data); +typedef void (*lv_tree_after_cb_t)(const lv_tree_node_t * node, void * user_data); + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +extern const lv_tree_class_t lv_tree_node_class; + +/** + * @brief Create a tree node + * @param class_p pointer to a class of the node + * @param parent pointer to the parent node (or NULL if it's the root node) + * @return pointer to the new node + */ +lv_tree_node_t * lv_tree_node_create(const lv_tree_class_t * class_p, lv_tree_node_t * parent); + +/** + * @brief Delete a tree node and all its children recursively + * @param node pointer to the node to delete + */ +void lv_tree_node_delete(lv_tree_node_t * node); + +/** + * @brief Walk the tree recursively and call a callback function on each node + * @param node pointer to the root node of the tree + * @param mode LV_TREE_WALK_PRE_ORDER or LV_TREE_WALK_POST_ORDER + * @param cb callback function to call on each node + * @param bcb callback function to call before visiting a node + * @param acb callback function to call after visiting a node + * @param user_data user data to pass to the callback functions + * @return true: traversal is finished; false: traversal broken + */ +bool lv_tree_walk(const lv_tree_node_t * node, + lv_tree_walk_mode_t mode, + lv_tree_traverse_cb_t cb, + lv_tree_before_cb_t bcb, + lv_tree_after_cb_t acb, + void * user_data); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_types.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_types.h index b362e7ad0..47bf31626 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_types.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_types.h @@ -41,6 +41,16 @@ extern "C" { #endif +#if LV_USE_3DTEXTURE +#if LV_USE_OPENGLES +#define LV_3DTEXTURE_ID_NULL 0u +#endif + +#ifndef LV_3DTEXTURE_ID_NULL +#error enable LV_USE_OPENGLES to use LV_USE_3DTEXTURE +#endif +#endif /*LV_USE_3DTEXTURE*/ + /********************** * TYPEDEFS **********************/ @@ -81,12 +91,18 @@ typedef float lv_value_precise_t; typedef int32_t lv_value_precise_t; #endif +#if LV_USE_3DTEXTURE +#if LV_USE_OPENGLES +typedef unsigned int lv_3dtexture_id_t; +#endif +#endif + /** * Typedefs from various lvgl modules. * They are defined here to avoid circular dependencies. */ -typedef struct lv_obj_t lv_obj_t; +typedef struct _lv_obj_t lv_obj_t; typedef uint16_t lv_state_t; typedef uint32_t lv_part_t; @@ -95,249 +111,274 @@ typedef uint8_t lv_opa_t; typedef uint8_t lv_style_prop_t; -typedef struct lv_obj_class_t lv_obj_class_t; +typedef struct _lv_obj_class_t lv_obj_class_t; -typedef struct lv_group_t lv_group_t; +typedef struct _lv_group_t lv_group_t; -typedef struct lv_display_t lv_display_t; +typedef struct _lv_display_t lv_display_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; +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; -typedef struct lv_indev_t lv_indev_t; +typedef struct _lv_indev_t lv_indev_t; -typedef struct lv_event_t lv_event_t; +typedef struct _lv_event_t lv_event_t; -typedef struct lv_timer_t lv_timer_t; +typedef struct _lv_timer_t lv_timer_t; -typedef struct lv_theme_t lv_theme_t; +typedef struct _lv_theme_t lv_theme_t; -typedef struct lv_anim_t lv_anim_t; +typedef struct _lv_anim_t lv_anim_t; -typedef struct lv_font_t lv_font_t; +typedef struct _lv_font_t lv_font_t; +typedef struct _lv_font_class_t lv_font_class_t; +typedef struct _lv_font_info_t lv_font_info_t; -typedef struct lv_image_decoder_t lv_image_decoder_t; +typedef struct _lv_font_manager_t lv_font_manager_t; -typedef struct lv_image_decoder_dsc_t lv_image_decoder_dsc_t; +typedef struct _lv_image_decoder_t lv_image_decoder_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_image_decoder_dsc_t lv_image_decoder_dsc_t; -typedef struct lv_profiler_builtin_config_t lv_profiler_builtin_config_t; +typedef struct _lv_draw_image_dsc_t lv_draw_image_dsc_t; -typedef struct lv_rb_node_t lv_rb_node_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_rb_t lv_rb_t; +typedef struct _lv_profiler_builtin_config_t lv_profiler_builtin_config_t; -typedef struct lv_color_filter_dsc_t lv_color_filter_dsc_t; +typedef struct _lv_rb_node_t lv_rb_node_t; -typedef struct lv_event_dsc_t lv_event_dsc_t; +typedef struct _lv_rb_t lv_rb_t; -typedef struct lv_fs_file_cache_t lv_fs_file_cache_t; +typedef struct _lv_color_filter_dsc_t lv_color_filter_dsc_t; -typedef struct lv_fs_path_ex_t lv_fs_path_ex_t; +typedef struct _lv_event_dsc_t lv_event_dsc_t; -typedef struct lv_image_decoder_args_t lv_image_decoder_args_t; +typedef struct _lv_cache_t lv_cache_t; -typedef struct lv_image_cache_data_t lv_image_cache_data_t; +typedef struct _lv_cache_entry_t lv_cache_entry_t; -typedef struct lv_image_header_cache_data_t lv_image_header_cache_data_t; +typedef struct _lv_fs_file_cache_t lv_fs_file_cache_t; -typedef struct lv_draw_mask_t lv_draw_mask_t; +typedef struct _lv_fs_path_ex_t lv_fs_path_ex_t; -typedef struct lv_grad_t lv_grad_t; +typedef struct _lv_image_decoder_args_t lv_image_decoder_args_t; -typedef struct lv_draw_label_hint_t lv_draw_label_hint_t; +typedef struct _lv_image_cache_data_t lv_image_cache_data_t; -typedef struct lv_draw_glyph_dsc_t lv_draw_glyph_dsc_t; +typedef struct _lv_image_header_cache_data_t lv_image_header_cache_data_t; -typedef struct lv_draw_image_sup_t lv_draw_image_sup_t; +typedef struct _lv_draw_mask_t lv_draw_mask_t; -typedef struct lv_draw_mask_rect_dsc_t lv_draw_mask_rect_dsc_t; +typedef struct _lv_draw_label_hint_t lv_draw_label_hint_t; -typedef struct lv_obj_style_t lv_obj_style_t; +typedef struct _lv_draw_glyph_dsc_t lv_draw_glyph_dsc_t; -typedef struct lv_obj_style_transition_dsc_t lv_obj_style_transition_dsc_t; +typedef struct _lv_draw_image_sup_t lv_draw_image_sup_t; -typedef struct lv_hit_test_info_t lv_hit_test_info_t; +typedef struct _lv_draw_mask_rect_dsc_t lv_draw_mask_rect_dsc_t; -typedef struct lv_cover_check_info_t lv_cover_check_info_t; +typedef struct _lv_obj_style_t lv_obj_style_t; -typedef struct lv_obj_spec_attr_t lv_obj_spec_attr_t; +typedef struct _lv_obj_style_transition_dsc_t lv_obj_style_transition_dsc_t; -typedef struct lv_image_t lv_image_t; +typedef struct _lv_hit_test_info_t lv_hit_test_info_t; -typedef struct lv_animimg_t lv_animimg_t; +typedef struct _lv_cover_check_info_t lv_cover_check_info_t; -typedef struct lv_arc_t lv_arc_t; +typedef struct _lv_obj_spec_attr_t lv_obj_spec_attr_t; -typedef struct lv_label_t lv_label_t; +typedef struct _lv_image_t lv_image_t; -typedef struct lv_bar_anim_t lv_bar_anim_t; +typedef struct _lv_animimg_t lv_animimg_t; -typedef struct lv_bar_t lv_bar_t; +typedef struct _lv_arc_t lv_arc_t; -typedef struct lv_button_t lv_button_t; +typedef struct _lv_label_t lv_label_t; -typedef struct lv_buttonmatrix_t lv_buttonmatrix_t; +typedef struct _lv_bar_anim_t lv_bar_anim_t; -typedef struct lv_calendar_t lv_calendar_t; +typedef struct _lv_bar_t lv_bar_t; -typedef struct lv_canvas_t lv_canvas_t; +typedef struct _lv_button_t lv_button_t; -typedef struct lv_chart_series_t lv_chart_series_t; +typedef struct _lv_buttonmatrix_t lv_buttonmatrix_t; -typedef struct lv_chart_cursor_t lv_chart_cursor_t; +typedef struct _lv_calendar_t lv_calendar_t; -typedef struct lv_chart_t lv_chart_t; +typedef struct _lv_canvas_t lv_canvas_t; -typedef struct lv_checkbox_t lv_checkbox_t; +typedef struct _lv_chart_series_t lv_chart_series_t; -typedef struct lv_dropdown_t lv_dropdown_t; +typedef struct _lv_chart_cursor_t lv_chart_cursor_t; -typedef struct lv_dropdown_list_t lv_dropdown_list_t; +typedef struct _lv_chart_t lv_chart_t; -typedef struct lv_imagebutton_src_info_t lv_imagebutton_src_info_t; +typedef struct _lv_checkbox_t lv_checkbox_t; -typedef struct lv_imagebutton_t lv_imagebutton_t; +typedef struct _lv_dropdown_t lv_dropdown_t; -typedef struct lv_keyboard_t lv_keyboard_t; +typedef struct _lv_dropdown_list_t lv_dropdown_list_t; -typedef struct lv_led_t lv_led_t; +typedef struct _lv_imagebutton_src_info_t lv_imagebutton_src_info_t; -typedef struct lv_line_t lv_line_t; +typedef struct _lv_imagebutton_t lv_imagebutton_t; -typedef struct lv_menu_load_page_event_data_t lv_menu_load_page_event_data_t; +typedef struct _lv_keyboard_t lv_keyboard_t; -typedef struct lv_menu_history_t lv_menu_history_t; +typedef struct _lv_led_t lv_led_t; -typedef struct lv_menu_t lv_menu_t; +typedef struct _lv_line_t lv_line_t; -typedef struct lv_menu_page_t lv_menu_page_t; +typedef struct _lv_menu_load_page_event_data_t lv_menu_load_page_event_data_t; -typedef struct lv_msgbox_t lv_msgbox_t; +typedef struct _lv_menu_history_t lv_menu_history_t; -typedef struct lv_roller_t lv_roller_t; +typedef struct _lv_menu_t lv_menu_t; -typedef struct lv_scale_section_t lv_scale_section_t; +typedef struct _lv_menu_page_t lv_menu_page_t; -typedef struct lv_scale_t lv_scale_t; +typedef struct _lv_msgbox_t lv_msgbox_t; -typedef struct lv_slider_t lv_slider_t; +typedef struct _lv_roller_t lv_roller_t; -typedef struct lv_span_t lv_span_t; +typedef struct _lv_scale_section_t lv_scale_section_t; -typedef struct lv_spangroup_t lv_spangroup_t; +typedef struct _lv_scale_t lv_scale_t; -typedef struct lv_textarea_t lv_textarea_t; +typedef struct _lv_slider_t lv_slider_t; -typedef struct lv_spinbox_t lv_spinbox_t; +typedef struct _lv_span_t lv_span_t; -typedef struct lv_switch_t lv_switch_t; +typedef struct _lv_spangroup_t lv_spangroup_t; -typedef struct lv_table_cell_t lv_table_cell_t; +typedef struct _lv_textarea_t lv_textarea_t; -typedef struct lv_table_t lv_table_t; +typedef struct _lv_spinbox_t lv_spinbox_t; -typedef struct lv_tabview_t lv_tabview_t; +typedef struct _lv_switch_t lv_switch_t; -typedef struct lv_tileview_t lv_tileview_t; +typedef struct _lv_table_cell_t lv_table_cell_t; -typedef struct lv_tileview_tile_t lv_tileview_tile_t; +typedef struct _lv_table_t lv_table_t; -typedef struct lv_win_t lv_win_t; +typedef struct _lv_tabview_t lv_tabview_t; -typedef struct lv_observer_t lv_observer_t; +typedef struct _lv_tileview_t lv_tileview_t; -typedef struct lv_monkey_config_t lv_monkey_config_t; +typedef struct _lv_tileview_tile_t lv_tileview_tile_t; -typedef struct lv_ime_pinyin_t lv_ime_pinyin_t; +typedef struct _lv_win_t lv_win_t; -typedef struct lv_file_explorer_t lv_file_explorer_t; +typedef struct _lv_3dtexture_t lv_3dtexture_t; -typedef struct lv_barcode_t lv_barcode_t; +typedef struct _lv_observer_t lv_observer_t; -typedef struct lv_gif_t lv_gif_t; +typedef struct _lv_monkey_config_t lv_monkey_config_t; -typedef struct lv_qrcode_t lv_qrcode_t; +typedef struct _lv_ime_pinyin_t lv_ime_pinyin_t; -typedef struct lv_freetype_outline_vector_t lv_freetype_outline_vector_t; +typedef struct _lv_file_explorer_t lv_file_explorer_t; -typedef struct lv_freetype_outline_event_param_t lv_freetype_outline_event_param_t; +typedef struct _lv_barcode_t lv_barcode_t; -typedef struct lv_fpoint_t lv_fpoint_t; +typedef struct _lv_gif_t lv_gif_t; -typedef struct lv_matrix_t lv_matrix_t; +typedef struct _lv_qrcode_t lv_qrcode_t; -typedef struct lv_vector_path_t lv_vector_path_t; +typedef struct _lv_freetype_outline_vector_t lv_freetype_outline_vector_t; -typedef struct lv_vector_gradient_t lv_vector_gradient_t; +typedef struct _lv_freetype_outline_event_param_t lv_freetype_outline_event_param_t; -typedef struct lv_vector_fill_dsc_t lv_vector_fill_dsc_t; +typedef struct _lv_fpoint_t lv_fpoint_t; -typedef struct lv_vector_stroke_dsc_t lv_vector_stroke_dsc_t; +typedef struct _lv_matrix_t lv_matrix_t; -typedef struct lv_vector_draw_dsc_t lv_vector_draw_dsc_t; +typedef struct _lv_vector_path_t lv_vector_path_t; -typedef struct lv_draw_vector_task_dsc_t lv_draw_vector_task_dsc_t; +typedef struct _lv_vector_gradient_t lv_vector_gradient_t; -typedef struct lv_vector_dsc_t lv_vector_dsc_t; +typedef struct _lv_vector_fill_dsc_t lv_vector_fill_dsc_t; -typedef struct lv_xkb_t lv_xkb_t; +typedef struct _lv_vector_stroke_dsc_t lv_vector_stroke_dsc_t; -typedef struct lv_libinput_event_t lv_libinput_event_t; +typedef struct _lv_vector_draw_dsc_t lv_vector_draw_dsc_t; -typedef struct lv_libinput_t lv_libinput_t; +typedef struct _lv_draw_vector_task_dsc_t lv_draw_vector_task_dsc_t; -typedef struct lv_draw_sw_unit_t lv_draw_sw_unit_t; +typedef struct _lv_vector_dsc_t lv_vector_dsc_t; -typedef struct lv_draw_sw_mask_common_dsc_t lv_draw_sw_mask_common_dsc_t; +typedef struct _lv_xkb_t lv_xkb_t; -typedef struct lv_draw_sw_mask_line_param_t lv_draw_sw_mask_line_param_t; +typedef struct _lv_libinput_event_t lv_libinput_event_t; -typedef struct lv_draw_sw_mask_angle_param_t lv_draw_sw_mask_angle_param_t; +typedef struct _lv_libinput_t lv_libinput_t; -typedef struct lv_draw_sw_mask_radius_param_t lv_draw_sw_mask_radius_param_t; +typedef struct _lv_draw_sw_unit_t lv_draw_sw_unit_t; -typedef struct lv_draw_sw_mask_fade_param_t lv_draw_sw_mask_fade_param_t; +typedef struct _lv_draw_sw_mask_common_dsc_t lv_draw_sw_mask_common_dsc_t; -typedef struct lv_draw_sw_mask_map_param_t lv_draw_sw_mask_map_param_t; +typedef struct _lv_draw_sw_mask_line_param_t lv_draw_sw_mask_line_param_t; -typedef struct lv_draw_sw_blend_dsc_t lv_draw_sw_blend_dsc_t; +typedef struct _lv_draw_sw_mask_angle_param_t lv_draw_sw_mask_angle_param_t; -typedef struct lv_draw_sw_blend_fill_dsc_t lv_draw_sw_blend_fill_dsc_t; +typedef struct _lv_draw_sw_mask_radius_param_t lv_draw_sw_mask_radius_param_t; -typedef struct lv_draw_sw_blend_image_dsc_t lv_draw_sw_blend_image_dsc_t; +typedef struct _lv_draw_sw_mask_fade_param_t lv_draw_sw_mask_fade_param_t; -typedef struct lv_draw_buf_handlers_t lv_draw_buf_handlers_t; +typedef struct _lv_draw_sw_mask_map_param_t lv_draw_sw_mask_map_param_t; -typedef struct lv_rlottie_t lv_rlottie_t; +typedef struct _lv_draw_sw_blend_dsc_t lv_draw_sw_blend_dsc_t; -typedef struct lv_ffmpeg_player_t lv_ffmpeg_player_t; +typedef struct _lv_draw_sw_blend_fill_dsc_t lv_draw_sw_blend_fill_dsc_t; -typedef struct lv_glfw_window_t lv_glfw_window_t; -typedef struct lv_glfw_texture_t lv_glfw_texture_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; +typedef struct _lv_array_t lv_array_t; + +typedef struct _lv_iter_t lv_iter_t; + +typedef struct _lv_circle_buf_t lv_circle_buf_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; +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; +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; +typedef struct _lv_sysmon_perf_info_t lv_sysmon_perf_info_t; #endif /*LV_USE_PERF_MONITOR*/ #endif /*LV_USE_SYSMON*/ + +typedef struct _lv_xml_component_scope_t lv_xml_component_scope_t; + +typedef struct _lv_xml_parser_state_t lv_xml_parser_state_t; + +#if LV_USE_EVDEV +typedef struct _lv_evdev_discovery_t lv_evdev_discovery_t; +#endif + #endif /*__ASSEMBLY__*/ /********************** diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.c b/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.c index 868692170..0a4e626a2 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.c +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.c @@ -9,7 +9,7 @@ #include "lv_utils.h" #include "lv_fs.h" #include "lv_types.h" -#include "cache/lv_image_cache.h" +#include "cache/lv_cache.h" /********************* * DEFINES diff --git a/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.h b/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.h index 7a8d61014..9f30251a6 100644 --- a/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.h +++ b/lib/libesp32_lvgl/lvgl/src/misc/lv_utils.h @@ -57,6 +57,29 @@ void * lv_utils_bsearch(const void * key, const void * base, size_t n, size_t si */ lv_result_t lv_draw_buf_save_to_file(const lv_draw_buf_t * draw_buf, const char * path); +/** + * Reverse the order of the bytes in a 32-bit value. + * @param x a 32-bit value. + * @return the value `x` with reversed byte-order. + */ +static inline uint32_t lv_swap_bytes_32(uint32_t x) +{ + return (x << 24) + | ((x & 0x0000ff00U) << 8) + | ((x & 0x00ff0000U) >> 8) + | (x >> 24); +} + +/** + * Reverse the order of the bytes in a 16-bit value. + * @param x a 16-bit value. + * @return the value `x` with reversed byte-order. + */ +static inline uint16_t lv_swap_bytes_16(uint16_t x) +{ + return (x << 8) | (x >> 8); +} + /********************** * MACROS **********************/ 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 ed414c8da..d2f89430b 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_cmsis_rtos2.c +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_cmsis_rtos2.c @@ -17,6 +17,7 @@ #if LV_USE_OS == LV_OS_CMSIS_RTOS2 #include "../misc/lv_log.h" +#include "../misc/lv_timer.h" /********************* * DEFINES @@ -42,9 +43,11 @@ * GLOBAL FUNCTIONS **********************/ -lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size, +lv_result_t lv_thread_init(lv_thread_t * thread, const char * const name, lv_thread_prio_t prio, + void (*callback)(void *), size_t stack_size, void * user_data) { + LV_UNUSED(name); static const osPriority_t prio_map[] = { [LV_THREAD_PRIO_LOWEST] = osPriorityLow, [LV_THREAD_PRIO_LOW] = osPriorityBelowNormal, @@ -188,6 +191,11 @@ lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) return LV_RESULT_OK; } +uint32_t lv_os_get_idle_percent(void) +{ + return lv_timer_get_idle(); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.c index f65a299aa..c1eeccdf0 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.c +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.c @@ -26,9 +26,6 @@ *********************/ #define ulMAX_COUNT 10U -#ifndef pcTASK_NAME - #define pcTASK_NAME "lvglDraw" -#endif #define globals LV_GLOBAL_DEFAULT() @@ -61,7 +58,7 @@ static void prvTestAndDecrement(lv_thread_sync_t * pxCond, * STATIC VARIABLES **********************/ -#if (ESP_PLATFORM) +#ifdef ESP_PLATFORM static portMUX_TYPE critSectionMux = portMUX_INITIALIZER_UNLOCKED; #endif @@ -69,7 +66,7 @@ static void prvTestAndDecrement(lv_thread_sync_t * pxCond, * MACROS **********************/ -#if (ESP_PLATFORM) +#ifdef ESP_PLATFORM #define _enter_critical() taskENTER_CRITICAL(&critSectionMux); #define _exit_critical() taskEXIT_CRITICAL(&critSectionMux); #define _enter_critical_isr() taskENTER_CRITICAL_FROM_ISR(); @@ -85,7 +82,8 @@ static void prvTestAndDecrement(lv_thread_sync_t * pxCond, * GLOBAL FUNCTIONS **********************/ -lv_result_t lv_thread_init(lv_thread_t * pxThread, lv_thread_prio_t xSchedPriority, +lv_result_t lv_thread_init(lv_thread_t * pxThread, const char * const name, + lv_thread_prio_t xSchedPriority, void (*pvStartRoutine)(void *), size_t usStackSize, void * xAttr) { @@ -94,7 +92,7 @@ lv_result_t lv_thread_init(lv_thread_t * pxThread, lv_thread_prio_t xSchedPriori BaseType_t xTaskCreateStatus = xTaskCreate( prvRunThread, - pcTASK_NAME, + name, (configSTACK_DEPTH_TYPE)(usStackSize / sizeof(StackType_t)), (void *)pxThread, tskIDLE_PRIORITY + xSchedPriority, @@ -129,7 +127,7 @@ lv_result_t lv_mutex_lock(lv_mutex_t * pxMutex) /* If mutex in uninitialized, perform initialization. */ prvCheckMutexInit(pxMutex); - BaseType_t xMutexTakeStatus = xSemaphoreTake(pxMutex->xMutex, portMAX_DELAY); + BaseType_t xMutexTakeStatus = xSemaphoreTakeRecursive(pxMutex->xMutex, portMAX_DELAY); if(xMutexTakeStatus != pdTRUE) { LV_LOG_ERROR("xSemaphoreTake failed!"); return LV_RESULT_INVALID; @@ -165,7 +163,7 @@ lv_result_t lv_mutex_unlock(lv_mutex_t * pxMutex) /* If mutex in uninitialized, perform initialization. */ prvCheckMutexInit(pxMutex); - BaseType_t xMutexGiveStatus = xSemaphoreGive(pxMutex->xMutex); + BaseType_t xMutexGiveStatus = xSemaphoreGiveRecursive(pxMutex->xMutex); if(xMutexGiveStatus != pdTRUE) { LV_LOG_ERROR("xSemaphoreGive failed!"); return LV_RESULT_INVALID; @@ -176,6 +174,8 @@ lv_result_t lv_mutex_unlock(lv_mutex_t * pxMutex) lv_result_t lv_mutex_delete(lv_mutex_t * pxMutex) { + if(pxMutex->xIsInitialized == pdFALSE) + return LV_RESULT_INVALID; vSemaphoreDelete(pxMutex->xMutex); pxMutex->xIsInitialized = pdFALSE; diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.h b/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.h index 67a5a1e7f..a3bafca74 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.h +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_freertos.h @@ -23,7 +23,7 @@ extern "C" { #if LV_USE_OS == LV_OS_FREERTOS -#if (ESP_PLATFORM) +#ifdef ESP_PLATFORM #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" @@ -84,13 +84,6 @@ void lv_freertos_task_switch_in(const char * name); */ 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_linux.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_linux.c new file mode 100644 index 000000000..baec0aa54 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_linux.c @@ -0,0 +1,122 @@ +/** + * @file lv_linux.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_os.h" + +#if LV_USE_OS != LV_OS_NONE && defined(__linux__) + +#include "../core/lv_global.h" +#include "../misc/lv_log.h" +#include "lv_linux_private.h" +#include + +/********************* + * DEFINES + *********************/ + +#define LV_UPTIME_MONITOR_FILE "/proc/stat" + +#define LV_PROC_STAT_VAR_FORMAT " %" PRIu32 +#define LV_PROC_STAT_IGNORE_VAR_FORMAT " %*" PRIu32 + +#define last_proc_stat LV_GLOBAL_DEFAULT()->linux_last_proc_stat + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static lv_result_t lv_read_proc_stat(lv_proc_stat_t * result); +static uint32_t lv_proc_stat_get_total(const lv_proc_stat_t * p); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +uint32_t lv_os_get_idle_percent(void) +{ + lv_proc_stat_t proc_stat; + { + lv_result_t err = lv_read_proc_stat(&proc_stat); + + if(err == LV_RESULT_INVALID) { + return UINT32_MAX; + } + + for(size_t i = 0; i < LV_PROC_STAT_PARAMS_LEN; ++i) { + uint32_t delta = + proc_stat.buffer[i] - last_proc_stat.buffer[i]; + /* Update old for next call*/ + last_proc_stat.buffer[i] = proc_stat.buffer[i]; + /* Store delta in new */ + proc_stat.buffer[i] = delta; + } + } + + /* From here onwards, there's no risk of overflowing as long as we call this function regularly */ + const uint32_t total = lv_proc_stat_get_total(&proc_stat); + + if(total == 0) { + return 0; + } + + return (proc_stat.fields.idle * 100) / total; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_result_t lv_read_proc_stat(lv_proc_stat_t * result) +{ + FILE * fp = fopen(LV_UPTIME_MONITOR_FILE, "r"); + + if(!fp) { + LV_LOG_ERROR("Failed to open " LV_UPTIME_MONITOR_FILE); + return LV_RESULT_INVALID; + } + const char * fmt = "cpu " LV_PROC_STAT_VAR_FORMAT LV_PROC_STAT_VAR_FORMAT + LV_PROC_STAT_VAR_FORMAT LV_PROC_STAT_VAR_FORMAT + LV_PROC_STAT_IGNORE_VAR_FORMAT LV_PROC_STAT_VAR_FORMAT + LV_PROC_STAT_VAR_FORMAT LV_PROC_STAT_VAR_FORMAT; + + int err = fscanf(fp, fmt, &result->fields.user, &result->fields.nice, + &result->fields.system, &result->fields.idle, + &result->fields.irq, &result->fields.softirq, + &result->fields.steal); + + fclose(fp); + + if(err != LV_PROC_STAT_PARAMS_LEN) { + LV_LOG_ERROR("Failed to parse " LV_UPTIME_MONITOR_FILE); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; +} +static uint32_t lv_proc_stat_get_total(const lv_proc_stat_t * p) +{ + uint32_t sum = 0; + for(size_t i = 0; i < LV_PROC_STAT_PARAMS_LEN; ++i) { + sum += p->buffer[i]; + } + return sum; +} + +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_linux_private.h b/lib/libesp32_lvgl/lvgl/src/osal/lv_linux_private.h new file mode 100644 index 000000000..d6e43cbf7 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_linux_private.h @@ -0,0 +1,56 @@ + +/** + * @file lv_linux_private.h + * + */ + +#ifndef LV_LINUX_PRIVATE_H +#define LV_LINUX_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +#define LV_PROC_STAT_PARAMS_LEN 7 + +/********************** + * TYPEDEFS + **********************/ + + +typedef union { + struct { + /* + * We ignore the iowait column as it's not reliable + * We ignore the guest and guest_nice columns because they're accounted + * for in user and nice respectively + */ + uint32_t user, nice, system, idle, /*iowait,*/ irq, softirq, + steal /*, guest, guest_nice*/; + } fields; + uint32_t buffer[LV_PROC_STAT_PARAMS_LEN]; +} lv_proc_stat_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LINUX_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_mqx.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_mqx.c index fed82f428..ffcf16332 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_mqx.c +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_mqx.c @@ -11,6 +11,7 @@ #if LV_USE_OS == LV_OS_MQX #include "../misc/lv_log.h" +#include "../misc/lv_timer.h" #include "../stdlib/lv_string.h" /********************* @@ -37,7 +38,8 @@ * GLOBAL FUNCTIONS **********************/ -lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size, +lv_result_t lv_thread_init(lv_thread_t * thread, const char * const name, lv_thread_prio_t prio, + void (*callback)(void *), size_t stack_size, void * user_data) { TASK_TEMPLATE_STRUCT task_template; @@ -47,7 +49,7 @@ lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*c 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.TASK_NAME = name; task_template.CREATION_PARAMETER = (uint32_t)user_data; *thread = _task_create(0, 0, (uint32_t)&task_template); @@ -162,6 +164,11 @@ lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) return LV_RESULT_INVALID; } +uint32_t lv_os_get_idle_percent(void) +{ + return lv_timer_get_idle(); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_os.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_os.c index 7b775f034..64ef4b5d1 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_os.c +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_os.c @@ -42,30 +42,26 @@ void lv_os_init(void) #endif /*LV_USE_OS != LV_OS_NONE*/ } +#if 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 **********************/ + +#endif /*LV_USE_OS != LV_OS_NONE*/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_os.h b/lib/libesp32_lvgl/lvgl/src/osal/lv_os.h index d0a4e02f5..47fd80108 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_os.h +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_os.h @@ -35,6 +35,8 @@ extern "C" { #include "lv_windows.h" #elif LV_USE_OS == LV_OS_MQX #include "lv_mqx.h" +#elif LV_USE_OS == LV_OS_SDL2 +#include "lv_sdl2.h" #elif LV_USE_OS == LV_OS_CUSTOM #include LV_OS_CUSTOM_INCLUDE #endif @@ -58,6 +60,14 @@ typedef enum { * GLOBAL PROTOTYPES **********************/ +/** + * Set it for `LV_SYSMON_GET_IDLE` to show the CPU usage + * @return the idle percentage since the last call + */ +uint32_t lv_os_get_idle_percent(void); + +#if LV_USE_OS != LV_OS_NONE + /*---------------------------------------- * These functions needs to be implemented * for specific operating systems @@ -66,13 +76,15 @@ typedef enum { /** * Create a new thread * @param thread a variable in which the thread will be stored + * @param name the name of the thread * @param prio priority of the thread * @param callback function of the thread * @param stack_size stack size in bytes * @param user_data arbitrary data, will be available in the callback * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure */ -lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size, +lv_result_t lv_thread_init(lv_thread_t * thread, const char * const name, + lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size, void * user_data); /** @@ -175,6 +187,109 @@ lv_result_t lv_lock_isr(void); */ void lv_unlock(void); +#else + +/* Since compilation does not necessarily optimize cross-file empty functions well + * (-O3 optimization alone is not enough unless LTO optimization is enabled), + * In the absence of an operating system, use inline functions to help compile + * optimizations and avoid the call overhead of the OS API to ensure no performance penalty. + */ + +static inline lv_result_t lv_thread_init(lv_thread_t * thread, const char * const name, lv_thread_prio_t prio, + void (*callback)(void *), size_t stack_size, void * user_data) +{ + LV_UNUSED(thread); + LV_UNUSED(name); + LV_UNUSED(callback); + LV_UNUSED(prio); + LV_UNUSED(stack_size); + LV_UNUSED(user_data); + return LV_RESULT_INVALID; +} + +static inline lv_result_t lv_thread_delete(lv_thread_t * thread) +{ + LV_UNUSED(thread); + return LV_RESULT_INVALID; +} + +static inline lv_result_t lv_mutex_init(lv_mutex_t * mutex) +{ + LV_UNUSED(mutex); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_mutex_lock(lv_mutex_t * mutex) +{ + LV_UNUSED(mutex); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex) +{ + LV_UNUSED(mutex); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_mutex_unlock(lv_mutex_t * mutex) +{ + LV_UNUSED(mutex); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_mutex_delete(lv_mutex_t * mutex) +{ + LV_UNUSED(mutex); + return LV_RESULT_OK; +} + +static inline lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + +static inline lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + +static inline lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + +static inline lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + +static inline lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + +static inline void lv_lock(void) +{ + /*Do nothing*/ +} + +static inline lv_result_t lv_lock_isr(void) +{ + return LV_RESULT_OK; +} + +static inline void lv_unlock(void) +{ + /*Do nothing*/ +} + +#endif /*LV_USE_OS != LV_OS_NONE*/ + /********************** * 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 547810db7..9fe3cac63 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_os_none.c +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_os_none.c @@ -6,11 +6,12 @@ /********************* * INCLUDES *********************/ -#include "lv_os.h" +#include "../lv_conf_internal.h" #if LV_USE_OS == LV_OS_NONE -#include "../misc/lv_types.h" -#include "../misc/lv_assert.h" + +#include "lv_os.h" +#include "../misc/lv_timer.h" /********************* * DEFINES @@ -36,92 +37,14 @@ * 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) +uint32_t lv_os_get_idle_percent(void) { - LV_UNUSED(thread); - LV_UNUSED(callback); - LV_UNUSED(prio); - LV_UNUSED(stack_size); - LV_UNUSED(user_data); - LV_ASSERT(0); - return LV_RESULT_INVALID; -} - -lv_result_t lv_thread_delete(lv_thread_t * thread) -{ - LV_UNUSED(thread); - LV_ASSERT(0); - return LV_RESULT_INVALID; -} - -lv_result_t lv_mutex_init(lv_mutex_t * mutex) -{ - LV_UNUSED(mutex); - return LV_RESULT_OK; -} - -lv_result_t lv_mutex_lock(lv_mutex_t * mutex) -{ - LV_UNUSED(mutex); - return LV_RESULT_OK; -} - -lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex) -{ - LV_UNUSED(mutex); - return LV_RESULT_OK; -} - -lv_result_t lv_mutex_unlock(lv_mutex_t * mutex) -{ - LV_UNUSED(mutex); - return LV_RESULT_OK; -} - -lv_result_t lv_mutex_delete(lv_mutex_t * mutex) -{ - LV_UNUSED(mutex); - return LV_RESULT_OK; -} - -lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync) -{ - LV_UNUSED(sync); - LV_ASSERT(0); - return LV_RESULT_INVALID; -} - -lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync) -{ - LV_UNUSED(sync); - LV_ASSERT(0); - return LV_RESULT_INVALID; -} - -lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync) -{ - LV_UNUSED(sync); - LV_ASSERT(0); - 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); - LV_ASSERT(0); - return LV_RESULT_INVALID; + return lv_timer_get_idle(); } /********************** * STATIC FUNCTIONS **********************/ -#endif /*LV_USE_OS == LV_OS_NONE*/ + +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_pthread.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_pthread.c index 268f055c2..52bd236de 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_pthread.c +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_pthread.c @@ -10,9 +10,12 @@ #if LV_USE_OS == LV_OS_PTHREAD -#include #include "../misc/lv_log.h" +#ifndef __linux__ + #include "../misc/lv_timer.h" +#endif + /********************* * DEFINES *********************/ @@ -26,6 +29,7 @@ **********************/ static void * generic_callback(void * user_data); + /********************** * STATIC VARIABLES **********************/ @@ -38,9 +42,11 @@ static void * generic_callback(void * user_data); * 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) +lv_result_t lv_thread_init(lv_thread_t * thread, const char * const name, + lv_thread_prio_t prio, void (*callback)(void *), + size_t stack_size, void * user_data) { + LV_UNUSED(name); LV_UNUSED(prio); pthread_attr_t attr; pthread_attr_init(&attr); @@ -48,6 +54,7 @@ lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*c thread->callback = callback; thread->user_data = user_data; pthread_create(&thread->thread, &attr, generic_callback, thread); + pthread_attr_destroy(&attr); return LV_RESULT_OK; } @@ -164,6 +171,14 @@ lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) return LV_RESULT_INVALID; } +#ifndef __linux__ +uint32_t lv_os_get_idle_percent(void) +{ + return lv_timer_get_idle(); +} +#endif + + /********************** * STATIC FUNCTIONS **********************/ @@ -175,4 +190,5 @@ static void * generic_callback(void * user_data) return NULL; } + #endif /*LV_USE_OS == LV_OS_PTHREAD*/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_rtthread.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_rtthread.c index e781634e1..1f2f9d80e 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_rtthread.c +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_rtthread.c @@ -11,6 +11,7 @@ #if LV_USE_OS == LV_OS_RTTHREAD #include "../misc/lv_log.h" +#include "../misc/lv_timer.h" /********************* * DEFINES @@ -38,10 +39,11 @@ * GLOBAL FUNCTIONS **********************/ -lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size, +lv_result_t lv_thread_init(lv_thread_t * thread, const char * const name, lv_thread_prio_t prio, + void (*callback)(void *), size_t stack_size, void * user_data) { - thread->thread = rt_thread_create("thread", + thread->thread = rt_thread_create(name, callback, user_data, stack_size, @@ -183,6 +185,11 @@ lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) return LV_RESULT_INVALID; } +uint32_t lv_os_get_idle_percent(void) +{ + return lv_timer_get_idle(); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_sdl2.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_sdl2.c new file mode 100644 index 000000000..50a589a01 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_sdl2.c @@ -0,0 +1,194 @@ +/** + * @file lv_sdl2.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_os.h" + +#if LV_USE_OS == LV_OS_SDL2 + +#include +#include "../misc/lv_log.h" + +#ifndef __linux__ + #include "../misc/lv_timer.h" +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static int generic_callback(void * user_data); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_result_t lv_thread_init(lv_thread_t * thread, const char * const name, lv_thread_prio_t prio, + void (*callback)(void *), size_t stack_size, void * user_data) +{ + LV_UNUSED(prio); + thread->callback = callback; + thread->user_data = user_data; + thread->thread = SDL_CreateThreadWithStackSize(generic_callback, name, stack_size, thread); + if(thread->thread == NULL) { + LV_LOG_ERROR("Error: %s", SDL_GetError()); + return LV_RESULT_INVALID; + } + return LV_RESULT_OK; +} + +lv_result_t lv_thread_delete(lv_thread_t * thread) +{ + int ret; + SDL_WaitThread(thread->thread, &ret); + if(ret != 0) { + LV_LOG_ERROR("Error: %d", ret); + return LV_RESULT_INVALID; + } + + return LV_RESULT_OK; +} + +lv_result_t lv_mutex_init(lv_mutex_t * mutex) +{ + *mutex = SDL_CreateMutex(); + + if(*mutex == NULL) { + LV_LOG_ERROR("Error: %s", SDL_GetError()); + return LV_RESULT_INVALID; + } + else { + return LV_RESULT_OK; + } +} + +lv_result_t lv_mutex_lock(lv_mutex_t * mutex) +{ + int ret = SDL_LockMutex(*mutex); + if(ret) { + LV_LOG_ERROR("Error: %d", ret); + return LV_RESULT_INVALID; + } + else { + return LV_RESULT_OK; + } +} + +lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex) +{ + int ret = SDL_LockMutex(*mutex); + if(ret) { + LV_LOG_ERROR("Error: %d", ret); + return LV_RESULT_INVALID; + } + else { + return LV_RESULT_OK; + } +} + +lv_result_t lv_mutex_unlock(lv_mutex_t * mutex) +{ + int ret = SDL_UnlockMutex(*mutex); + if(ret) { + LV_LOG_ERROR("Error: %d", ret); + return LV_RESULT_INVALID; + } + else { + return LV_RESULT_OK; + } +} + +lv_result_t lv_mutex_delete(lv_mutex_t * mutex) +{ + SDL_DestroyMutex(*mutex); + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync) +{ + sync->mutex = SDL_CreateMutex(); + if(sync->mutex == NULL) { + LV_LOG_ERROR("Error: %s", SDL_GetError()); + return LV_RESULT_INVALID; + } + sync->cond = SDL_CreateCond(); + if(sync->cond == NULL) { + LV_LOG_ERROR("Error: %s", SDL_GetError()); + return LV_RESULT_INVALID; + } + sync->v = false; + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync) +{ + SDL_LockMutex(sync->mutex); + while(!sync->v) { + SDL_CondWait(sync->cond, sync->mutex); + } + sync->v = false; + SDL_UnlockMutex(sync->mutex); + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync) +{ + SDL_LockMutex(sync->mutex); + sync->v = true; + SDL_CondSignal(sync->cond); + SDL_UnlockMutex(sync->mutex); + + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) +{ + SDL_DestroyMutex(sync->mutex); + SDL_DestroyCond(sync->cond); + return LV_RESULT_OK; +} + +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + +#ifndef __linux__ +uint32_t lv_os_get_idle_percent(void) +{ + return lv_timer_get_idle(); +} +#endif + +/********************** + * STATIC FUNCTIONS + **********************/ + +static int generic_callback(void * user_data) +{ + lv_thread_t * thread = user_data; + thread->callback(thread->user_data); + return 0; +} + +#endif /*LV_USE_OS == LV_OS_SDL2*/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_sdl2.h b/lib/libesp32_lvgl/lvgl/src/osal/lv_sdl2.h new file mode 100644 index 000000000..69eff5851 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_sdl2.h @@ -0,0 +1,55 @@ +/** + * @file lv_sdl2.h + * + */ + +#ifndef LV_SDL2_H +#define LV_SDL2_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#if LV_USE_OS == LV_OS_SDL2 +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + SDL_Thread * thread; + void (*callback)(void *); + void * user_data; +} lv_thread_t; + +typedef SDL_mutex * lv_mutex_t; + +typedef struct { + SDL_mutex * mutex; + SDL_cond * cond; + bool v; +} lv_thread_sync_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OS == LV_OS_SDL2*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SDL2_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_windows.c b/lib/libesp32_lvgl/lvgl/src/osal/lv_windows.c index 78ac29353..8b28ab18a 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_windows.c +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_windows.c @@ -1,4 +1,4 @@ -/** +/** * @file lv_windows.c * */ @@ -12,6 +12,7 @@ #if LV_USE_OS == LV_OS_WINDOWS #include +#include "../misc/lv_timer.h" /********************* * DEFINES @@ -46,11 +47,13 @@ static unsigned __stdcall thread_start_routine(void * parameter); lv_result_t lv_thread_init( lv_thread_t * thread, + const char * const name, lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size, void * user_data) { + LV_UNUSED(name); if(!thread) { return LV_RESULT_INVALID; } @@ -204,6 +207,11 @@ lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) return LV_RESULT_INVALID; } +uint32_t lv_os_get_idle_percent(void) +{ + return lv_timer_get_idle(); +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/osal/lv_windows.h b/lib/libesp32_lvgl/lvgl/src/osal/lv_windows.h index fd930e872..9d864535d 100644 --- a/lib/libesp32_lvgl/lvgl/src/osal/lv_windows.h +++ b/lib/libesp32_lvgl/lvgl/src/osal/lv_windows.h @@ -1,4 +1,4 @@ -/** +/** * @file lv_windows.h * */ 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 bb0220c89..0563aaeef 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 @@ -24,6 +24,9 @@ #define quick_access_list_button_style (LV_GLOBAL_DEFAULT()->fe_list_button_style) +#define LV_FILE_NAVIGATION_CURRENT_DIR "." +#define LV_FILE_NAVIGATION_PARENT_DIR "Back" + /********************** * TYPEDEFS **********************/ @@ -32,19 +35,19 @@ * STATIC PROTOTYPES **********************/ static void lv_file_explorer_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); +static void init_style(lv_obj_t * obj); -static void browser_file_event_handler(lv_event_t * e); #if LV_FILE_EXPLORER_QUICK_ACCESS static void quick_access_event_handler(lv_event_t * e); static void quick_access_area_event_handler(lv_event_t * e); #endif -static void init_style(lv_obj_t * obj); +static void browser_file_event_handler(lv_event_t * e); static void show_dir(lv_obj_t * obj, const char * path); static void strip_ext(char * dir); +static void exch_table_item(lv_obj_t * tb, int16_t i, int16_t j); static void file_explorer_sort(lv_obj_t * obj); static void sort_by_file_kind(lv_obj_t * tb, int16_t lo, int16_t hi); -static void exch_table_item(lv_obj_t * tb, int16_t i, int16_t j); static bool is_end_with(const char * str1, const char * str2); /********************** @@ -57,7 +60,7 @@ const lv_obj_class_t lv_file_explorer_class = { .height_def = LV_SIZE_CONTENT, .instance_size = sizeof(lv_file_explorer_t), .base_class = &lv_obj_class, - .name = "file-explorer", + .name = "lv_file_explorer", }; /********************** @@ -403,11 +406,15 @@ static void init_style(lv_obj_t * obj) lv_style_set_border_width(&quick_access_list_button_style, 0); lv_style_set_bg_color(&quick_access_list_button_style, lv_color_hex(0xf2f1f6)); - uint32_t i, j; - for(i = 0; i < lv_obj_get_child_count(explorer->quick_access_area); i++) { + uint32_t ch_cnt = lv_obj_get_child_count(explorer->quick_access_area); + + for(uint32_t i = 0; i < ch_cnt; i++) { lv_obj_t * child = lv_obj_get_child(explorer->quick_access_area, i); + if(lv_obj_check_type(child, &lv_list_class)) { - for(j = 0; j < lv_obj_get_child_count(child); j++) { + uint32_t list_ch_cnt = lv_obj_get_child_count(child); + + for(uint32_t j = 0; j < list_ch_cnt; j++) { lv_obj_t * list_child = lv_obj_get_child(child, j); if(lv_obj_check_type(list_child, &lv_list_button_class)) { lv_obj_add_style(list_child, &quick_access_list_button_style, 0); @@ -481,39 +488,72 @@ static void browser_file_event_handler(lv_event_t * e) lv_file_explorer_t * explorer = (lv_file_explorer_t *)obj; - if(code == LV_EVENT_VALUE_CHANGED) { + lv_indev_type_t type = lv_indev_get_type(lv_indev_active()); + lv_event_code_t active_code = type == LV_INDEV_TYPE_POINTER || + type == LV_INDEV_TYPE_BUTTON ? LV_EVENT_VALUE_CHANGED : LV_EVENT_CLICKED; + + if(code == active_code) { char file_name[LV_FILE_EXPLORER_PATH_MAX_LEN]; - const char * str_fn = NULL; + const char * selected_text = NULL; + const lv_file_explorer_file_table_entry_data_t * file_entry_user_data = NULL; uint32_t row; uint32_t col; + uint8_t navigate_to_parent_dir = 0; + uint8_t navigate_to_child = 0; lv_memzero(file_name, sizeof(file_name)); lv_table_get_selected_cell(explorer->file_table, &row, &col); - str_fn = lv_table_get_cell_value(explorer->file_table, row, col); + selected_text = lv_table_get_cell_value(explorer->file_table, row, col); + file_entry_user_data = lv_table_get_cell_user_data(explorer->file_table, row, col); - str_fn = str_fn + 5; - if((lv_strcmp(str_fn, ".") == 0)) return; + selected_text = selected_text + 5; /* skip table cell format */ - if((lv_strcmp(str_fn, "..") == 0) && (lv_strlen(explorer->current_path) > 3)) { - strip_ext(explorer->current_path); + /* Three navigation modes are supported: + * - Navigate to current directory + * - Navigate to parent directory + * - Navigate to (current directory) child */ + navigate_to_parent_dir = (lv_strcmp(selected_text, LV_FILE_NAVIGATION_PARENT_DIR) == 0); + navigate_to_child = !navigate_to_parent_dir; + + + if((navigate_to_parent_dir) && (lv_strlen(explorer->current_path) > 3)) { + lv_strlcpy(file_name, explorer->current_path, sizeof(file_name)); + strip_ext(file_name); /*Remove the last '/' character*/ - strip_ext(explorer->current_path); - lv_snprintf((char *)file_name, sizeof(file_name), "%s", explorer->current_path); - } - else { - if(lv_strcmp(str_fn, "..") != 0) { - lv_snprintf((char *)file_name, sizeof(file_name), "%s%s", explorer->current_path, str_fn); + strip_ext(file_name); + + /* Append / at the end */ + size_t stripped_file_name_length = lv_strlen(file_name); + *(file_name + stripped_file_name_length) = '/'; + if(stripped_file_name_length + 1 < LV_FILE_EXPLORER_PATH_MAX_LEN) { + *(file_name + stripped_file_name_length + 1) = '\0'; } } + else { + if(navigate_to_child) { + lv_snprintf((char *)file_name, sizeof(file_name), "%s%s", explorer->current_path, selected_text); + } + else if(navigate_to_parent_dir) { /* We are most likely in the drive letter directory, doesn't have parent directory */ + return; + } + else { /* Nothing to do*/ } + } - lv_fs_dir_t dir; - if(lv_fs_dir_open(&dir, file_name) == LV_FS_RES_OK) { - lv_fs_dir_close(&dir); - show_dir(obj, (char *)file_name); + /* Navigate to the file path if this is a directory */ + if(file_entry_user_data->file_kind == LV_FILE_EXPLORER_FILE_KIND_DIR) { + lv_fs_dir_t dir; + lv_fs_res_t res = lv_fs_dir_open(&dir, file_name); + if(res == LV_FS_RES_OK) { + lv_fs_dir_close(&dir); + show_dir(obj, (char *)file_name); + } + else { + LV_LOG_USER("Could not navigate to %s (error: %d)", file_name, res); + } } else { - if(lv_strcmp(str_fn, "..") != 0) { - explorer->sel_fn = str_fn; + if(navigate_to_child) { + explorer->sel_fn = selected_text; lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL); } } @@ -521,9 +561,6 @@ static void browser_file_event_handler(lv_event_t * e) else if(code == LV_EVENT_SIZE_CHANGED) { lv_table_set_column_width(explorer->file_table, 0, lv_obj_get_width(explorer->file_table)); } - else if((code == LV_EVENT_CLICKED) || (code == LV_EVENT_RELEASED)) { - lv_obj_send_event(obj, LV_EVENT_CLICKED, NULL); - } } static void show_dir(lv_obj_t * obj, const char * path) @@ -534,6 +571,7 @@ static void show_dir(lv_obj_t * obj, const char * path) uint16_t index = 0; lv_fs_dir_t dir; lv_fs_res_t res; + lv_file_explorer_file_table_entry_data_t * file_entry_user_data; res = lv_fs_dir_open(&dir, path); if(res != LV_FS_RES_OK) { @@ -541,39 +579,43 @@ static void show_dir(lv_obj_t * obj, const char * path) return; } - lv_table_set_cell_value_fmt(explorer->file_table, index++, 0, LV_SYMBOL_DIRECTORY " %s", "."); - lv_table_set_cell_value_fmt(explorer->file_table, index++, 0, LV_SYMBOL_DIRECTORY " %s", ".."); - lv_table_set_cell_value(explorer->file_table, 0, 1, "0"); - lv_table_set_cell_value(explorer->file_table, 1, 1, "0"); + lv_table_set_cell_value(explorer->file_table, index++, 0, LV_SYMBOL_LEFT " " LV_FILE_NAVIGATION_PARENT_DIR); + file_entry_user_data = lv_malloc(sizeof(lv_file_explorer_file_table_entry_data_t)); + LV_ASSERT_MALLOC(file_entry_user_data); + file_entry_user_data->file_kind = LV_FILE_EXPLORER_FILE_KIND_DIR; + lv_table_set_cell_user_data(explorer->file_table, 0, 0, file_entry_user_data); while(1) { res = lv_fs_dir_read(&dir, fn, sizeof(fn)); if(res != LV_FS_RES_OK) { - LV_LOG_USER("Driver, file or directory is not exists %d!", res); + LV_LOG_USER("Driver, file or directory does not exist %d!", res); break; } /*fn is empty, if not more files to read*/ if(lv_strlen(fn) == 0) { - LV_LOG_USER("Not more files to read!"); + LV_LOG_USER("No more files to read!"); break; } + file_entry_user_data = lv_malloc(sizeof(lv_file_explorer_file_table_entry_data_t)); + LV_ASSERT_MALLOC(file_entry_user_data); + if((is_end_with(fn, ".png") == true) || (is_end_with(fn, ".PNG") == true) || \ (is_end_with(fn, ".jpg") == true) || (is_end_with(fn, ".JPG") == true) || \ (is_end_with(fn, ".bmp") == true) || (is_end_with(fn, ".BMP") == true) || \ (is_end_with(fn, ".gif") == true) || (is_end_with(fn, ".GIF") == true)) { lv_table_set_cell_value_fmt(explorer->file_table, index, 0, LV_SYMBOL_IMAGE " %s", fn); - lv_table_set_cell_value(explorer->file_table, index, 1, "1"); + file_entry_user_data->file_kind = LV_FILE_EXPLORER_FILE_KIND_IMAGE; } else if((is_end_with(fn, ".mp3") == true) || (is_end_with(fn, ".MP3") == true) || \ (is_end_with(fn, ".wav") == true) || (is_end_with(fn, ".WAV") == true)) { lv_table_set_cell_value_fmt(explorer->file_table, index, 0, LV_SYMBOL_AUDIO " %s", fn); - lv_table_set_cell_value(explorer->file_table, index, 1, "2"); + file_entry_user_data->file_kind = LV_FILE_EXPLORER_FILE_KIND_AUDIO; } else if((is_end_with(fn, ".mp4") == true) || (is_end_with(fn, ".MP4") == true)) { lv_table_set_cell_value_fmt(explorer->file_table, index, 0, LV_SYMBOL_VIDEO " %s", fn); - lv_table_set_cell_value(explorer->file_table, index, 1, "3"); + file_entry_user_data->file_kind = LV_FILE_EXPLORER_FILE_KIND_VIDEO; } else if((is_end_with(fn, ".") == true) || (is_end_with(fn, "..") == true)) { /*is dir*/ @@ -581,13 +623,15 @@ static void show_dir(lv_obj_t * obj, const char * path) } else if(fn[0] == '/') {/*is dir*/ lv_table_set_cell_value_fmt(explorer->file_table, index, 0, LV_SYMBOL_DIRECTORY " %s", fn + 1); - lv_table_set_cell_value(explorer->file_table, index, 1, "0"); + file_entry_user_data->file_kind = LV_FILE_EXPLORER_FILE_KIND_DIR; } else { lv_table_set_cell_value_fmt(explorer->file_table, index, 0, LV_SYMBOL_FILE " %s", fn); - lv_table_set_cell_value(explorer->file_table, index, 1, "4"); + file_entry_user_data->file_kind = LV_FILE_EXPLORER_FILE_KIND_FILE; } + lv_table_set_cell_user_data(explorer->file_table, index, 0, file_entry_user_data); + index++; } @@ -600,11 +644,11 @@ 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_strlcpy(explorer->current_path, path, sizeof(explorer->current_path)); + lv_strncpy(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); - if((*((explorer->current_path) + current_path_len) != '/') && (current_path_len < LV_FILE_EXPLORER_PATH_MAX_LEN)) { + if((explorer->current_path[current_path_len - 1] != '/') && (current_path_len < LV_FILE_EXPLORER_PATH_MAX_LEN)) { *((explorer->current_path) + current_path_len) = '/'; } } @@ -628,16 +672,31 @@ static void strip_ext(char * dir) static void exch_table_item(lv_obj_t * tb, int16_t i, int16_t j) { - const char * tmp; - tmp = lv_table_get_cell_value(tb, i, 0); - lv_table_set_cell_value(tb, 0, 2, tmp); - lv_table_set_cell_value(tb, i, 0, lv_table_get_cell_value(tb, j, 0)); - lv_table_set_cell_value(tb, j, 0, lv_table_get_cell_value(tb, 0, 2)); + if(i == j) return; + const char * i_value = lv_table_get_cell_value(tb, i, 0); - tmp = lv_table_get_cell_value(tb, i, 1); - lv_table_set_cell_value(tb, 0, 2, tmp); - lv_table_set_cell_value(tb, i, 1, lv_table_get_cell_value(tb, j, 1)); - lv_table_set_cell_value(tb, j, 1, lv_table_get_cell_value(tb, 0, 2)); + char * tmp_i_value = lv_malloc(lv_strlen(i_value) + 1); + LV_ASSERT_MALLOC(tmp_i_value); + lv_strcpy(tmp_i_value, i_value); + + //*Will be freed when the table is freed. The previous user data is freed when the new one is set*/ + lv_file_explorer_file_table_entry_data_t * tmp_i_user_data = lv_malloc(sizeof( + lv_file_explorer_file_table_entry_data_t)); + LV_ASSERT_MALLOC(tmp_i_user_data); + lv_memcpy(tmp_i_user_data, lv_table_get_cell_user_data(tb, i, 0), sizeof(lv_file_explorer_file_table_entry_data_t)); + + lv_file_explorer_file_table_entry_data_t * tmp_j_user_data = lv_malloc(sizeof( + lv_file_explorer_file_table_entry_data_t)); + LV_ASSERT_MALLOC(tmp_j_user_data); + lv_memcpy(tmp_j_user_data, lv_table_get_cell_user_data(tb, j, 0), sizeof(lv_file_explorer_file_table_entry_data_t)); + + lv_table_set_cell_value(tb, i, 0, lv_table_get_cell_value(tb, j, 0)); + lv_table_set_cell_user_data(tb, i, 0, tmp_j_user_data); + + lv_table_set_cell_value(tb, j, 0, tmp_i_value); + lv_table_set_cell_user_data(tb, j, 0, tmp_i_user_data); + + lv_free(tmp_i_value); } static void file_explorer_sort(lv_obj_t * obj) @@ -669,11 +728,12 @@ static void sort_by_file_kind(lv_obj_t * tb, int16_t lo, int16_t hi) int16_t lt = lo; int16_t i = lo + 1; int16_t gt = hi; - const char * v = lv_table_get_cell_value(tb, lo, 1); + lv_file_explorer_file_table_entry_data_t * v = lv_table_get_cell_user_data(tb, lo, 0); while(i <= gt) { - if(lv_strcmp(lv_table_get_cell_value(tb, i, 1), v) < 0) + lv_file_explorer_file_table_entry_data_t * x = lv_table_get_cell_user_data(tb, i, 0); + if(x->file_kind < v->file_kind) exch_table_item(tb, lt++, i++); - else if(lv_strcmp(lv_table_get_cell_value(tb, i, 1), v) > 0) + else if(x->file_kind > v->file_kind) exch_table_item(tb, i, gt--); else i++; @@ -688,8 +748,8 @@ static bool is_end_with(const char * str1, const char * str2) if(str1 == NULL || str2 == NULL) return false; - uint16_t len1 = lv_strlen(str1); - uint16_t len2 = lv_strlen(str2); + size_t len1 = lv_strlen(str1); + size_t len2 = lv_strlen(str2); if((len1 < len2) || (len1 == 0 || len2 == 0)) return false; 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 8dd7762f5..818b8d85e 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 @@ -93,6 +93,13 @@ const char * lv_file_explorer_get_selected_file_name(const lv_obj_t * obj); */ const char * lv_file_explorer_get_current_path(const lv_obj_t * obj); +/** + * Get file explorer file list obj(lv_table) + * @param obj pointer to a file explorer object + * @return pointer to the file explorer file table obj(lv_table) + */ +lv_obj_t * lv_file_explorer_get_file_table(lv_obj_t * obj); + /** * Get file explorer head area obj * @param obj pointer to a file explorer object @@ -100,13 +107,6 @@ const char * lv_file_explorer_get_current_path(const lv_obj_t * obj); */ lv_obj_t * lv_file_explorer_get_header(lv_obj_t * obj); -/** - * Get file explorer head area obj - * @param obj pointer to a file explorer object - * @return pointer to the file explorer quick access area obj(lv_obj) - */ -lv_obj_t * lv_file_explorer_get_quick_access_area(lv_obj_t * obj); - /** * Get file explorer path obj(label) * @param obj pointer to a file explorer object @@ -115,6 +115,13 @@ lv_obj_t * lv_file_explorer_get_quick_access_area(lv_obj_t * obj); lv_obj_t * lv_file_explorer_get_path_label(lv_obj_t * obj); #if LV_FILE_EXPLORER_QUICK_ACCESS +/** + * Get file explorer head area obj + * @param obj pointer to a file explorer object + * @return pointer to the file explorer quick access area obj(lv_obj) + */ +lv_obj_t * lv_file_explorer_get_quick_access_area(lv_obj_t * obj); + /** * Get file explorer places list obj(lv_list) * @param obj pointer to a file explorer object @@ -130,13 +137,6 @@ lv_obj_t * lv_file_explorer_get_places_list(lv_obj_t * obj); lv_obj_t * lv_file_explorer_get_device_list(lv_obj_t * obj); #endif -/** - * Get file explorer file list obj(lv_table) - * @param obj pointer to a file explorer object - * @return pointer to the file explorer file table obj(lv_table) - */ -lv_obj_t * lv_file_explorer_get_file_table(lv_obj_t * obj); - /** * Set file_explorer sort * @param obj pointer to a file explorer object 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 index 1b7eca1dd..ea35dd288 100644 --- 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 @@ -28,7 +28,7 @@ extern "C" { **********************/ /*Data of canvas*/ -struct lv_file_explorer_t { +struct _lv_file_explorer_t { lv_obj_t obj; lv_obj_t * cont; lv_obj_t * head_area; @@ -51,6 +51,18 @@ struct lv_file_explorer_t { lv_file_explorer_sort_t sort; }; +typedef enum { + LV_FILE_EXPLORER_FILE_KIND_DIR, + LV_FILE_EXPLORER_FILE_KIND_IMAGE, + LV_FILE_EXPLORER_FILE_KIND_AUDIO, + LV_FILE_EXPLORER_FILE_KIND_VIDEO, + LV_FILE_EXPLORER_FILE_KIND_FILE +} lv_file_explorer_file_kind_t; + +typedef struct { + lv_file_explorer_file_kind_t file_kind; +} lv_file_explorer_file_table_entry_data_t; + /********************** * GLOBAL PROTOTYPES diff --git a/lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager.c b/lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager.c new file mode 100644 index 000000000..525b5a09b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager.c @@ -0,0 +1,619 @@ +/** + * @file lv_font_manager.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_font_manager.h" + +#if LV_USE_FONT_MANAGER + +#include "lv_font_manager_recycle.h" +#include "../../misc/lv_ll.h" +#include "../../stdlib/lv_sprintf.h" + +/********************* + * DEFINES + *********************/ + +#define IS_FONT_FAMILY_NAME(name) (lv_strchr((name), ',') != NULL) +#define IS_FONT_HAS_FALLBACK(font) ((font)->fallback != NULL) + +/********************** + * TYPEDEFS + **********************/ + +/* font manager object */ +struct _lv_font_manager_t { + lv_ll_t refer_ll; /* font reference list */ + lv_ll_t rec_ll; /* lvgl font record list */ + lv_ll_t src_ll; /* font src record list */ + lv_font_manager_recycle_t * recycle_manager; +}; + +/* font reference node */ +typedef struct _lv_font_refer_node_t { + lv_font_t * font_p; + lv_font_info_t ft_info; + char name[LV_FONT_MANAGER_NAME_MAX_LEN]; /* name buffer */ + int ref_cnt; /* reference count */ +} lv_font_refer_node_t; + +/* lvgl font record node */ +typedef struct _lv_font_rec_node_t { + lv_font_t font; /* lvgl font info */ + const lv_font_refer_node_t * refer_node_p; /* referenced font resource */ +} lv_font_rec_node_t; + +typedef struct _lv_font_src_t { + char * name; + void * src; + bool is_static; + const lv_font_class_t * class_p; +} lv_font_src_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static lv_font_src_t * lv_font_manager_get_src(lv_font_manager_t * manager, const char * name); + +static bool lv_font_manager_check_resource(lv_font_manager_t * manager); +static lv_font_rec_node_t * lv_font_manager_search_rec_node(lv_font_manager_t * manager, lv_font_t * font); + +static const lv_font_refer_node_t * lv_font_manager_get_font(lv_font_manager_t * manager, + const lv_font_info_t * ft_info); +static bool lv_font_manager_drop_font(lv_font_manager_t * manager, const lv_font_refer_node_t * node); + +static lv_font_t * lv_font_manager_create_font_single(lv_font_manager_t * manager, const lv_font_info_t * ft_info); +static bool lv_font_manager_delete_font_single(lv_font_manager_t * manager, lv_font_t * font); + +static lv_font_t * lv_font_manager_create_font_family(lv_font_manager_t * manager, const lv_font_info_t * ft_info); +static void lv_font_manager_delete_font_family(lv_font_manager_t * manager, lv_font_t * font); + +static bool lv_font_manager_add_src_core(lv_font_manager_t * manager, const char * name, const char * path, + const lv_font_class_t * class_p, bool is_static); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_font_manager_t * lv_font_manager_create(uint32_t recycle_cache_size) +{ + LV_ASSERT_MSG(recycle_cache_size > 0, "recycle_cache_size should be greater than 0"); + lv_font_manager_t * manager = lv_malloc_zeroed(sizeof(lv_font_manager_t)); + LV_ASSERT_MALLOC(manager); + if(!manager) { + LV_LOG_ERROR("malloc failed for lv_font_manager_t"); + return NULL; + } + + lv_ll_init(&manager->refer_ll, sizeof(lv_font_refer_node_t)); + lv_ll_init(&manager->rec_ll, sizeof(lv_font_rec_node_t)); + lv_ll_init(&manager->src_ll, sizeof(lv_font_src_t)); + + manager->recycle_manager = lv_font_manager_recycle_create(recycle_cache_size); + + LV_LOG_INFO("success"); + return manager; +} + +bool lv_font_manager_delete(lv_font_manager_t * manager) +{ + LV_ASSERT_NULL(manager); + + /* Resource leak check */ + if(lv_font_manager_check_resource(manager)) { + LV_LOG_ERROR("unfreed resource detected, delete failed!"); + return false; + } + + /* clean recycle_manager */ + lv_font_manager_recycle_delete(manager->recycle_manager); + + /* clean path map */ + lv_font_src_t * font_src; + LV_LL_READ(&manager->src_ll, font_src) { + LV_LOG_INFO("remove src: %s", font_src->name); + if(!font_src->is_static) { + lv_free(font_src->name); + font_src->class_p->free_src_cb(font_src->src); + } + + font_src->name = NULL; + font_src->src = NULL; + } + lv_ll_clear(&manager->src_ll); + + lv_free(manager); + + LV_LOG_INFO("success"); + return true; +} + +bool lv_font_manager_add_src(lv_font_manager_t * manager, + const char * name, + const void * src, + const lv_font_class_t * class_p) +{ + return lv_font_manager_add_src_core(manager, name, src, class_p, false); +} + +bool lv_font_manager_add_src_static(lv_font_manager_t * manager, + const char * name, + const void * src, + const lv_font_class_t * class_p) +{ + return lv_font_manager_add_src_core(manager, name, src, class_p, true); +} + +bool lv_font_manager_remove_src(lv_font_manager_t * manager, const char * name) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(name); + + lv_font_src_t * font_src = lv_font_manager_get_src(manager, name); + if(!font_src) { + LV_LOG_WARN("src: %s not found", name); + return false; + } + + lv_ll_remove(&manager->src_ll, font_src); + + if(!font_src->is_static) { + lv_free(font_src->name); + font_src->class_p->free_src_cb(font_src->src); + } + + font_src->name = NULL; + font_src->src = NULL; + + lv_free(font_src); + + LV_LOG_WARN("src: %s remove success", name); + return true; +} + +lv_font_t * lv_font_manager_create_font(lv_font_manager_t * manager, + const char * font_family, + uint32_t render_mode, + uint32_t size, + uint32_t style, + lv_font_kerning_t kerning) +{ + + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(font_family); + + lv_font_info_t ft_info; + lv_memzero(&ft_info, sizeof(ft_info)); + ft_info.name = font_family; + ft_info.render_mode = render_mode; + ft_info.size = size; + ft_info.style = style; + ft_info.kerning = kerning; + + lv_font_t * ret_font; + + if(IS_FONT_FAMILY_NAME(ft_info.name)) { + ret_font = lv_font_manager_create_font_family(manager, &ft_info); + } + else { + ret_font = lv_font_manager_create_font_single(manager, &ft_info); + } + + /* Append fallback font to make LV_SYMBOL displayable */ + lv_font_t * cur_font = ret_font; + while(cur_font) { + if(cur_font->fallback == NULL) { + cur_font->fallback = LV_FONT_DEFAULT; + break; + } + cur_font = (lv_font_t *)cur_font->fallback; + } + + return ret_font; +} + +void lv_font_manager_delete_font(lv_font_manager_t * manager, lv_font_t * font) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(font); + + if(IS_FONT_HAS_FALLBACK(font)) { + lv_font_manager_delete_font_family(manager, font); + return; + } + + lv_font_manager_delete_font_single(manager, font); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_font_t * lv_font_manager_create_font_single(lv_font_manager_t * manager, const lv_font_info_t * ft_info) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(ft_info); + + const lv_font_refer_node_t * refer_node = lv_font_manager_get_font(manager, ft_info); + if(!refer_node) { + return NULL; + } + + /* add font record node */ + lv_font_rec_node_t * rec_node = lv_ll_ins_head(&manager->rec_ll); + LV_ASSERT_MALLOC(rec_node); + lv_memzero(rec_node, sizeof(lv_font_rec_node_t)); + + /* copy font data */ + rec_node->font = *refer_node->font_p; + + /* record reference font */ + rec_node->refer_node_p = refer_node; + + LV_LOG_INFO("success"); + return &rec_node->font; +} + +static bool lv_font_manager_delete_font_single(lv_font_manager_t * manager, lv_font_t * font) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(font); + + if(font == LV_FONT_DEFAULT) { + LV_LOG_INFO("LV_FONT_DEFAULT can not be deleted"); + return false; + } + + /* check font is created by font manager */ + lv_font_rec_node_t * rec_node = lv_font_manager_search_rec_node(manager, font); + if(!rec_node) { + LV_LOG_WARN("NO record found for font: %p(%d)," + " it was not created by font manager", + (void *)font, (int)font->line_height); + return false; + } + + bool retval = lv_font_manager_drop_font(manager, rec_node->refer_node_p); + LV_ASSERT(retval); + + /* free rec_node */ + lv_ll_remove(&manager->rec_ll, rec_node); + lv_free(rec_node); + + LV_LOG_INFO("success"); + return retval; +} + +static const char * strncpy_until(char * dest, const char * src, size_t n, char c) +{ + LV_ASSERT_NULL(dest); + LV_ASSERT_NULL(src); + + size_t i = 0; + while(i < n && *src != '\0' && *src != c) { + *dest++ = *src++; + i++; + } + + if(i < n) { + *dest = '\0'; + } + + return src; +} + +static lv_font_t * lv_font_manager_create_font_family(lv_font_manager_t * manager, const lv_font_info_t * ft_info) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(ft_info); + + lv_font_t * first_font = NULL; + lv_font_t * pre_font = NULL; + + const char * family_str = ft_info->name; + LV_LOG_INFO("font-family: %s", family_str); + + char tmp_name[LV_FONT_MANAGER_NAME_MAX_LEN] = { 0 }; + lv_font_info_t tmp_ft_info = *ft_info; + tmp_ft_info.name = tmp_name; + + while(1) { + family_str = strncpy_until(tmp_name, family_str, sizeof(tmp_name) - 1, ','); + + lv_font_t * cur_font = lv_font_manager_create_font_single(manager, &tmp_ft_info); + + if(cur_font) { + /* save first font pointer */ + if(!first_font) { + first_font = cur_font; + } + + /* append font fallback */ + if(pre_font) { + pre_font->fallback = cur_font; + } + + pre_font = cur_font; + } + + /* stop */ + if(*family_str == '\0') { + break; + } + + if(*family_str != ',') { + LV_LOG_ERROR("font name buffer is too small, please increase LV_FONT_MANAGER_NAME_MAX_LEN"); + break; + } + + /* skip ',' */ + family_str++; + } + + return first_font; +} + +static void lv_font_manager_delete_font_family(lv_font_manager_t * manager, lv_font_t * font) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(font); + + lv_font_t * f = font; + while(f) { + lv_font_t * fallback = (lv_font_t *)f->fallback; + lv_font_manager_delete_font_single(manager, f); + f = fallback; + } +} + +static bool lv_font_manager_add_src_core(lv_font_manager_t * manager, + const char * name, + const char * src, + const lv_font_class_t * class_p, + bool is_static) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(name); + LV_ASSERT_NULL(src); + LV_ASSERT_NULL(class_p); + + if(lv_font_manager_get_src(manager, name)) { + LV_LOG_WARN("name: %s already exists", name); + return false; + } + + lv_font_src_t * font_src = lv_ll_ins_tail(&manager->src_ll); + LV_ASSERT_MALLOC(font_src); + lv_memzero(font_src, sizeof(lv_font_src_t)); + font_src->is_static = is_static; + font_src->class_p = class_p; + + if(is_static) { + font_src->name = (char *)name; + font_src->src = (void *)src; + } + else { + font_src->name = lv_strdup(name); + LV_ASSERT_MALLOC(font_src->name); + + font_src->src = font_src->class_p->dup_src_cb(src); + LV_ASSERT_NULL(font_src->src); + } + + LV_LOG_INFO("name: %s, src: %p add success", name, src); + return true; +} + +static lv_font_src_t * lv_font_manager_get_src(lv_font_manager_t * manager, const char * name) +{ + lv_font_src_t * font_src; + LV_LL_READ(&manager->src_ll, font_src) { + if(lv_strcmp(name, font_src->name) == 0) { + return font_src; + } + } + + return NULL; +} + +static bool lv_font_manager_check_resource(lv_font_manager_t * manager) +{ + LV_ASSERT_NULL(manager); + + /* Check the recorded font */ + lv_ll_t * rec_ll = &manager->rec_ll; + uint32_t rec_ll_len = lv_ll_get_len(rec_ll); + if(rec_ll_len) { + LV_LOG_WARN("lvgl font resource[%" LV_PRIu32 "]:", rec_ll_len); + + lv_font_rec_node_t * node; + LV_LL_READ(rec_ll, node) { + LV_LOG_WARN("font: %p(%d) -> ref: %s(%d)", + (void *)node, + (int)node->font.line_height, + node->refer_node_p->ft_info.name, + node->refer_node_p->ft_info.size); + } + } + + /* Check the recorded font resources created by font creater */ + lv_ll_t * refer_ll = &manager->refer_ll; + uint32_t refer_ll_len = lv_ll_get_len(refer_ll); + if(refer_ll_len) { + LV_LOG_WARN("font resource[%" LV_PRIu32 "]:", refer_ll_len); + + lv_font_refer_node_t * node; + LV_LL_READ(refer_ll, node) { + LV_LOG_WARN("font: %s(%d), ref_cnt = %d", + node->ft_info.name, + node->ft_info.size, + node->ref_cnt); + } + } + + /* Check resource leak */ + bool has_resource = (rec_ll_len || refer_ll_len); + + return has_resource; +} + +static lv_font_rec_node_t * lv_font_manager_search_rec_node(lv_font_manager_t * manager, lv_font_t * font) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(font); + + lv_font_rec_node_t * rec_node; + LV_LL_READ(&manager->rec_ll, rec_node) { + if(font == &rec_node->font) { + LV_LOG_INFO("font: %p(%d) matched", (void *)font, (int)font->line_height); + return rec_node; + } + } + + return NULL; +} + +static lv_font_refer_node_t * lv_font_manager_search_refer_node(lv_font_manager_t * manager, + const lv_font_info_t * ft_info) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(ft_info); + + lv_font_refer_node_t * refer_node; + LV_LL_READ(&manager->refer_ll, refer_node) { + if(lv_font_info_is_equal(ft_info, &refer_node->ft_info)) { + LV_LOG_INFO("font: %s(%d) matched", ft_info->name, ft_info->size); + return refer_node; + } + } + + return NULL; +} + +static lv_font_t * lv_font_manager_create_font_wrapper(lv_font_manager_t * manager, const lv_font_info_t * ft_info) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(ft_info); + + lv_font_t * font; + + /* create font */ + font = lv_font_manager_recycle_get_reuse(manager->recycle_manager, ft_info); + + /* get reuse font from recycle */ + if(font) { + return font; + } + + /* cache miss */ + + const lv_font_src_t * font_src = lv_font_manager_get_src(manager, ft_info->name); + if(!font_src) { + LV_LOG_ERROR("name: %s not found src", ft_info->name); + return NULL; + } + + font = font_src->class_p->create_cb(ft_info, font_src->src); + if(!font) { + LV_LOG_ERROR("font create failed, name: %s, render_mode: %d, size: %d, style: %d", + ft_info->name, ft_info->render_mode, ft_info->size, ft_info->style); + return NULL; + } + + return font; +} + +static void lv_font_manager_delete_font_warpper(lv_font_manager_t * manager, lv_font_refer_node_t * refer_node) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(refer_node); + lv_font_manager_recycle_set_reuse(manager->recycle_manager, refer_node->font_p, &refer_node->ft_info); +} + +static const lv_font_refer_node_t * lv_font_manager_get_font(lv_font_manager_t * manager, + const lv_font_info_t * ft_info) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(ft_info); + + /* check refer_node is existed */ + lv_font_refer_node_t * refer_node = lv_font_manager_search_refer_node(manager, ft_info); + if(refer_node) { + refer_node->ref_cnt++; + LV_LOG_INFO("refer_node existed, ref_cnt++ = %d", refer_node->ref_cnt); + return refer_node; + } + + /* not found refer_node, start to create font */ + + lv_font_t * font = lv_font_manager_create_font_wrapper(manager, ft_info); + + if(!font) { + return NULL; + } + + /* add refer_node to refer_ll */ + refer_node = lv_ll_ins_head(&manager->refer_ll); + LV_ASSERT_MALLOC(refer_node); + lv_memzero(refer_node, sizeof(lv_font_refer_node_t)); + + lv_strncpy(refer_node->name, ft_info->name, sizeof(refer_node->name) - 1); + + const lv_font_src_t * font_src = lv_font_manager_get_src(manager, ft_info->name); + LV_ASSERT_NULL(font_src); + + /* copy font data */ + refer_node->font_p = font; + refer_node->ft_info = *ft_info; + refer_node->ft_info.name = refer_node->name; + refer_node->ft_info.class_p = font_src->class_p; + refer_node->ref_cnt = 1; + + LV_LOG_INFO("success"); + return refer_node; +} + +static bool lv_font_manager_drop_font(lv_font_manager_t * manager, const lv_font_refer_node_t * node) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(node); + + /* Check refer_node is existed */ + lv_font_refer_node_t * refer_node = lv_font_manager_search_refer_node(manager, &node->ft_info); + if(!refer_node) { + LV_LOG_WARN("NO record found for font: %s(%d)," + " it was not created by font manager", + node->ft_info.name, node->ft_info.size); + return false; + } + + refer_node->ref_cnt--; + + /* If ref_cnt is > 0, no need to delete font */ + if(refer_node->ref_cnt > 0) { + LV_LOG_INFO("refer_node existed, ref_cnt-- = %d", refer_node->ref_cnt); + return true; + } + + /* if ref_cnt is about to be 0, free font resource */ + lv_font_manager_delete_font_warpper(manager, refer_node); + + /* free refer_node */ + lv_ll_remove(&manager->refer_ll, refer_node); + lv_free(refer_node); + + LV_LOG_INFO("success"); + return true; +} + +#endif /* LV_USE_FONT_MANAGER */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager.h b/lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager.h new file mode 100644 index 000000000..5ba4ccc3e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager.h @@ -0,0 +1,115 @@ +/** + * @file lv_font_manager.h + * + */ +#ifndef LV_FONT_MANAGER_H +#define LV_FONT_MANAGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../font/lv_font.h" + +#if LV_USE_FONT_MANAGER + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create main font manager. + * @param recycle_cache_size number of fonts that were recently deleted from the cache. + * @return pointer to main font manager. + */ +lv_font_manager_t * lv_font_manager_create(uint32_t recycle_cache_size); + +/** + * Delete main font manager. + * @param manager pointer to main font manager. + * @return return true if the deletion was successful. + */ +bool lv_font_manager_delete(lv_font_manager_t * manager); + +/** + * Add font resource. + * @param manager pointer to main font manager. + * @param name font name. + * @param src font source. Need to strictly correspond to the font class. + * @param class_p font class. eg. lv_freetype_font_class, lv_builtin_font_class. + * @return return true if the add was successful. + */ +bool lv_font_manager_add_src(lv_font_manager_t * manager, + const char * name, + const void * src, + const lv_font_class_t * class_p); + +/** + * Add font resource with static memory. + * @param manager pointer to main font manager. + * @param name font name. It cannot be a local variable. + * @param src font source. Need to strictly correspond to the font class. And it cannot be a local variable. + * @param class_p font class. E.g. lv_freetype_font_class, lv_builtin_font_class. + * @return return true if the add was successful. + */ +bool lv_font_manager_add_src_static(lv_font_manager_t * manager, + const char * name, + const void * src, + const lv_font_class_t * class_p); + +/** + * Remove font resource. + * @param manager pointer to main font manager. + * @param name font name. + * @return return true if the remove was successful. + */ +bool lv_font_manager_remove_src(lv_font_manager_t * manager, const char * name); + +/** + * Create font. + * @param manager pointer to main font manager. + * @param font_family font family name. Matches the font resource name, using commas to separate different names. E.g. "my_font_1,my_font_2". + * @param render_mode font render mode. see `lv_freetype_font_render_mode_t`. + * @param size font size in pixel. + * @param style font style. see `lv_freetype_font_style_t`. + * @param kerning kerning mode. see `lv_font_kerning_t`. + * @return point to the created font. + */ +lv_font_t * lv_font_manager_create_font(lv_font_manager_t * manager, + const char * font_family, + uint32_t render_mode, + uint32_t size, + uint32_t style, + lv_font_kerning_t kerning); + +/** + * Delete font. + * @param manager pointer to main font manager. + * @param font point to the font. + * @return return true if the deletion was successful. + */ +void lv_font_manager_delete_font(lv_font_manager_t * manager, lv_font_t * font); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_FONT_MANAGER */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* FONT_MANAGER_MANAGER_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager_recycle.c b/lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager_recycle.c new file mode 100644 index 000000000..87bafd90d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager_recycle.c @@ -0,0 +1,172 @@ +/** + * @file lv_font_manager_recycle.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_font_manager_recycle.h" + +#if LV_USE_FONT_MANAGER + +#include "../../font/lv_font.h" +#include "../../misc/lv_ll.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +struct _lv_font_manager_recycle_t { + lv_ll_t recycle_ll; + uint32_t max_size; +}; + +typedef struct { + lv_font_info_t ft_info; + char name[LV_FONT_MANAGER_NAME_MAX_LEN]; + lv_font_t * font; +} lv_font_recycle_t; + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void lv_font_recycle_close(lv_font_manager_recycle_t * manager, lv_font_recycle_t * recycle); +static void lv_font_manager_recycle_remove_tail(lv_font_manager_recycle_t * manager); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_font_manager_recycle_t * lv_font_manager_recycle_create(uint32_t max_size) +{ + lv_font_manager_recycle_t * manager = lv_malloc_zeroed(sizeof(lv_font_manager_recycle_t)); + LV_ASSERT_MALLOC(manager); + if(!manager) { + LV_LOG_ERROR("malloc failed for lv_font_manager_recycle_t"); + return NULL; + } + + lv_ll_init(&manager->recycle_ll, sizeof(lv_font_recycle_t)); + manager->max_size = max_size; + + LV_LOG_INFO("success"); + return manager; +} + +void lv_font_manager_recycle_delete(lv_font_manager_recycle_t * manager) +{ + LV_ASSERT_NULL(manager); + + lv_ll_t * recycle_ll = &manager->recycle_ll; + + lv_font_recycle_t * recycle = lv_ll_get_head(recycle_ll); + + /* clear all recycle */ + while(recycle != NULL) { + lv_font_recycle_t * recycle_next = lv_ll_get_next(recycle_ll, recycle); + lv_font_recycle_close(manager, recycle); + recycle = recycle_next; + } + + lv_free(manager); + + LV_LOG_INFO("success"); +} + +lv_font_t * lv_font_manager_recycle_get_reuse(lv_font_manager_recycle_t * manager, const lv_font_info_t * ft_info) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(ft_info); + + lv_ll_t * recycle_ll = &manager->recycle_ll; + + LV_LOG_INFO("font: %s(%d) searching...", ft_info->name, ft_info->size); + + lv_font_recycle_t * recycle; + LV_LL_READ(recycle_ll, recycle) { + /* match font */ + if(lv_font_info_is_equal(ft_info, &recycle->ft_info)) { + lv_font_t * font = recycle->font; + LV_LOG_INFO("found font: %p", (void *)font); + + /* remove reused font */ + lv_ll_remove(recycle_ll, recycle); + lv_free(recycle); + return font; + } + } + + LV_LOG_INFO("NOT found"); + + return false; +} + +void lv_font_manager_recycle_set_reuse(lv_font_manager_recycle_t * manager, lv_font_t * font, + const lv_font_info_t * ft_info) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(ft_info); + + lv_ll_t * recycle_ll = &manager->recycle_ll; + + /* check recycled size */ + if(lv_ll_get_len(recycle_ll) >= manager->max_size) { + LV_LOG_INFO("recycle full, remove tail font..."); + lv_font_manager_recycle_remove_tail(manager); + } + + /* record reuse font */ + lv_font_recycle_t * recycle = lv_ll_ins_head(recycle_ll); + LV_ASSERT_MALLOC(recycle); + lv_memzero(recycle, sizeof(lv_font_recycle_t)); + + lv_strncpy(recycle->name, ft_info->name, sizeof(recycle->name)); + recycle->name[sizeof(recycle->name) - 1] = '\0'; + + recycle->font = font; + recycle->ft_info = *ft_info; + recycle->ft_info.name = recycle->name; + + LV_LOG_INFO("insert font: %s(%d) to reuse list", ft_info->name, ft_info->size); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_font_recycle_close(lv_font_manager_recycle_t * manager, lv_font_recycle_t * recycle) +{ + LV_ASSERT_NULL(manager); + LV_ASSERT_NULL(recycle); + + LV_LOG_INFO("font: %s(%d) close", recycle->ft_info.name, recycle->ft_info.size); + recycle->ft_info.class_p->delete_cb(recycle->font); + recycle->font = NULL; + + lv_ll_remove(&manager->recycle_ll, recycle); + lv_free(recycle); +} + +static void lv_font_manager_recycle_remove_tail(lv_font_manager_recycle_t * manager) +{ + lv_font_recycle_t * tail = lv_ll_get_tail(&manager->recycle_ll); + LV_ASSERT_NULL(tail); + lv_font_recycle_close(manager, tail); +} + +#endif /* LV_USE_FONT_MANAGER */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager_recycle.h b/lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager_recycle.h new file mode 100644 index 000000000..58eb89474 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/font_manager/lv_font_manager_recycle.h @@ -0,0 +1,78 @@ +/** + * @file lv_font_manager_recycle.h + * + */ + +#ifndef LV_FONT_MANAGER_RECYCLE_H +#define LV_FONT_MANAGER_RECYCLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../misc/lv_types.h" + +#if LV_USE_FONT_MANAGER + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct _lv_font_manager_recycle_t lv_font_manager_recycle_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create font recycle manager. + * @param max_size recycle size. + * @return pointer to font recycle manager. + */ +lv_font_manager_recycle_t * lv_font_manager_recycle_create(uint32_t max_size); + +/** + * Delete font recycle manager. + * @param manager pointer to font recycle manager. + */ +void lv_font_manager_recycle_delete(lv_font_manager_recycle_t * manager); + +/** + * Get a reusable font. + * @param manager pointer to font recycle manager. + * @param ft_info font info. + * @return returns true on success. + */ +lv_font_t * lv_font_manager_recycle_get_reuse(lv_font_manager_recycle_t * manager, const lv_font_info_t * ft_info); + +/** + * Set fonts to be reused. + * @param manager pointer to font recycle manager. + * @param ft_info font info. + */ +void lv_font_manager_recycle_set_reuse(lv_font_manager_recycle_t * manager, lv_font_t * font, + const lv_font_info_t * ft_info); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_FONT_MANAGER */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /* LV_FONT_MANAGER_RECYCLE_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 f93473757..1e7d29fcf 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment.h +++ b/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment.h @@ -25,9 +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; -struct lv_fragment_t { +struct _lv_fragment_t { /** * Class of this fragment */ @@ -49,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 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 a8565185b..5782a1652 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 @@ -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 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 index 3af36ddbc..bf0d23f4c 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment_private.h +++ b/lib/libesp32_lvgl/lvgl/src/others/fragment/lv_fragment_private.h @@ -29,7 +29,7 @@ extern "C" { /** * Fragment states */ -struct lv_fragment_managed_states_t { +struct _lv_fragment_managed_states_t { /** * Class of the fragment */ 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 8382269b7..cc8240f90 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 @@ -58,7 +58,7 @@ const lv_obj_class_t lv_ime_pinyin_class = { .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, .instance_size = sizeof(lv_ime_pinyin_t), .base_class = &lv_obj_class, - .name = "ime-pinyin", + .name = "lv_ime_pinyin", }; #if LV_IME_PINYIN_USE_K9_MODE @@ -798,6 +798,7 @@ static void pinyin_input_proc(lv_obj_t * obj) } lv_obj_remove_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN); + lv_obj_invalidate(pinyin_ime->cand_panel); } static void pinyin_page_proc(lv_obj_t * obj, uint16_t dir) 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 index 6ec42fc09..f422438e5 100644 --- 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 @@ -28,7 +28,7 @@ extern "C" { **********************/ /*Data of lv_ime_pinyin*/ -struct lv_ime_pinyin_t { +struct _lv_ime_pinyin_t { lv_obj_t obj; lv_obj_t * kb; lv_obj_t * cand_panel; 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 97ba10a51..824eba15c 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey.c +++ b/lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey.c @@ -24,7 +24,7 @@ /********************** * TYPEDEFS **********************/ -struct lv_monkey_t { +struct _lv_monkey_t { lv_monkey_config_t config; lv_indev_data_t indev_data; lv_indev_t * 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 6cbe0ec56..f86f991b9 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey.h +++ b/lib/libesp32_lvgl/lvgl/src/others/monkey/lv_monkey.h @@ -25,21 +25,19 @@ extern "C" { * TYPEDEFS **********************/ -typedef struct lv_monkey_t lv_monkey_t; +typedef struct _lv_monkey_t lv_monkey_t; -struct lv_monkey_config_t { - /**< Input device type*/ +struct _lv_monkey_config_t { + /** Input device type */ lv_indev_type_t type; - /**< Monkey execution period*/ + /** Monkey execution period */ struct { - //! @cond Doxygen_Suppress uint32_t min; uint32_t max; - //! @endcond } period_range; - /**< The range of input value*/ + /** The range of input value */ struct { int32_t min; int32_t max; 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 8d43f52de..2603561a9 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer.c +++ b/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer.c @@ -21,10 +21,17 @@ /********************** * TYPEDEFS **********************/ +typedef enum { + FLAG_COND_EQ = 0, + FLAG_COND_GT = 1, + FLAG_COND_GE = 2 +} flag_cond_t; + typedef struct { uint32_t flag; lv_subject_value_t value; - uint32_t inv : 1; + uint32_t inv : 1; + flag_cond_t cond : 3; } flag_and_cond_t; /********************** @@ -33,11 +40,13 @@ typedef struct { static void unsubscribe_on_delete_cb(lv_event_t * e); static void group_notify_cb(lv_observer_t * observer, lv_subject_t * subject); static lv_observer_t * bind_to_bitfield(lv_subject_t * subject, lv_obj_t * obj, lv_observer_cb_t cb, uint32_t flag, - int32_t ref_value, bool inv); + int32_t ref_value, bool inv, flag_cond_t cond); 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); static void obj_value_changed_event_cb(lv_event_t * e); +static void lv_subject_notify_if_changed(lv_subject_t * subject); + #if LV_USE_LABEL static void label_text_observer_cb(lv_observer_t * observer, lv_subject_t * subject); #endif @@ -92,7 +101,7 @@ void lv_subject_set_int(lv_subject_t * subject, int32_t value) subject->prev_value.num = subject->value.num; subject->value.num = value; - lv_subject_notify(subject); + lv_subject_notify_if_changed(subject); } int32_t lv_subject_get_int(lv_subject_t * subject) @@ -122,7 +131,7 @@ void lv_subject_init_string(lv_subject_t * subject, char * buf, char * prev_buf, if(prev_buf) lv_strlcpy(prev_buf, value, size); subject->type = LV_SUBJECT_TYPE_STRING; - subject->size = size; + subject->size = (uint32_t)size; subject->value.pointer = buf; subject->prev_value.pointer = prev_buf; @@ -132,7 +141,7 @@ void lv_subject_init_string(lv_subject_t * subject, char * buf, char * prev_buf, void lv_subject_copy_string(lv_subject_t * subject, const char * buf) { if(subject->type != LV_SUBJECT_TYPE_STRING) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_INT"); + LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_STRING"); return; } @@ -143,8 +152,29 @@ void lv_subject_copy_string(lv_subject_t * subject, const char * buf) lv_strlcpy((char *)subject->value.pointer, buf, subject->size); - lv_subject_notify(subject); + lv_subject_notify_if_changed(subject); +} +void lv_subject_snprintf(lv_subject_t * subject, const char * format, ...) +{ + if(subject->type != LV_SUBJECT_TYPE_STRING) { + LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_STRING"); + return; + } + + if(subject->size < 1U) return; + + if(subject->prev_value.pointer) { + lv_strlcpy((char *)subject->prev_value.pointer, subject->value.pointer, subject->size); + } + + va_list va; + va_start(va, format); + const int ret = lv_vsnprintf((char *)subject->value.pointer, subject->size, format, va); + LV_UNUSED(ret); + va_end(va); + + lv_subject_notify_if_changed(subject); } const char * lv_subject_get_string(lv_subject_t * subject) @@ -185,7 +215,7 @@ void lv_subject_set_pointer(lv_subject_t * subject, void * ptr) subject->prev_value.pointer = subject->value.pointer; subject->value.pointer = ptr; - lv_subject_notify(subject); + lv_subject_notify_if_changed(subject); } const void * lv_subject_get_pointer(lv_subject_t * subject) @@ -226,7 +256,7 @@ void lv_subject_set_color(lv_subject_t * subject, lv_color_t color) subject->prev_value.color = subject->value.color; subject->value.color = color; - lv_subject_notify(subject); + lv_subject_notify_if_changed(subject); } lv_color_t lv_subject_get_color(lv_subject_t * subject) @@ -249,18 +279,18 @@ lv_color_t lv_subject_get_previous_color(lv_subject_t * subject) return subject->prev_value.color; } -void lv_subject_init_group(lv_subject_t * subject, lv_subject_t * list[], uint32_t list_len) +void lv_subject_init_group(lv_subject_t * group_subject, lv_subject_t * list[], uint32_t list_len) { - subject->type = LV_SUBJECT_TYPE_GROUP; - subject->size = list_len; - lv_ll_init(&(subject->subs_ll), sizeof(lv_observer_t)); - subject->value.pointer = list; + group_subject->type = LV_SUBJECT_TYPE_GROUP; + group_subject->size = list_len; + lv_ll_init(&(group_subject->subs_ll), sizeof(lv_observer_t)); + group_subject->value.pointer = list; - /* bind all subjects to this subject */ + /* Bind all list[] subjects to `group_subject`. */ uint32_t i; for(i = 0; i < list_len; i++) { - /*If a subject in the group changes notify the group itself*/ - lv_subject_add_observer(list[i], group_notify_cb, subject); + /* If a subject in `list[]` changes, notify `group_subject`. */ + lv_subject_add_observer(list[i], group_notify_cb, group_subject); } } @@ -270,11 +300,6 @@ void lv_subject_deinit(lv_subject_t * subject) 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; } @@ -289,7 +314,8 @@ lv_subject_t * lv_subject_get_group_element(lv_subject_t * subject, int32_t inde return NULL; } - if(index >= subject->size) return NULL; + if(index >= (int32_t)subject->size) return NULL; + if(index < 0) return NULL; return ((lv_subject_t **)(subject->value.pointer))[index]; } @@ -327,7 +353,7 @@ lv_observer_t * lv_subject_add_observer_obj(lv_subject_t * subject, lv_observer_ lv_obj_add_event_cb(obj, unsubscribe_on_delete_cb, LV_EVENT_DELETE, observer); } - /* update object immediately */ + /* Update Observer immediately. */ if(observer->cb) observer->cb(observer, subject); return observer; @@ -352,7 +378,7 @@ lv_observer_t * lv_subject_add_observer_with_target(lv_subject_t * subject, lv_o observer->user_data = user_data; observer->target = target; - /* update object immediately */ + /* Update Observer immediately. */ if(observer->cb) observer->cb(observer, subject); return observer; @@ -363,6 +389,11 @@ void lv_observer_remove(lv_observer_t * observer) { LV_ASSERT_NULL(observer); + if(observer->for_obj && observer->target) { + lv_obj_remove_event_cb_with_user_data(observer->target, unsubscribe_on_delete_cb, observer); + lv_obj_remove_event_cb_with_user_data(observer->target, NULL, observer->subject); + } + observer->subject->notify_restart_query = 1; lv_ll_remove(&(observer->subject->subs_ll), observer); @@ -375,18 +406,31 @@ void lv_observer_remove(lv_observer_t * observer) void lv_obj_remove_from_subject(lv_obj_t * obj, lv_subject_t * subject) { + LV_ASSERT_NULL(obj); + /* + * Look for the `observer` that connects `obj` and `subject` + * Since the obj is associated with the subject, + * the `obj` will have an LV_EVENT_REMOVE event with the `unsubscribe_on_delete_cb` callback + * associated. + * From the event we can then find the observer in the event's `user_data` field + */ int32_t i; - int32_t event_cnt = (int32_t)(obj->spec_attr ? lv_array_size(&obj->spec_attr->event_list) : 0); + int32_t event_cnt = (int32_t)(obj->spec_attr ? lv_event_get_count(&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 handles the deletion of all possible event callbacks */ lv_observer_remove(observer); - lv_obj_remove_event(obj, i); } } } + /* Gracefully de-couple `subject` from Widget by deleting any existing + * `LV_EVENT_VALUE_CHANGED` event associated with `subject` in case + * one of the `..._bind_value()` functions was used. */ + lv_obj_remove_event_cb_with_user_data(obj, NULL, subject); + } void * lv_observer_get_target(lv_observer_t * observer) @@ -419,32 +463,97 @@ void lv_subject_notify(lv_subject_t * subject) 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) { - lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, false); + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, false, FLAG_COND_EQ); return observable; } lv_observer_t * lv_obj_bind_flag_if_not_eq(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value) { - lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, true); + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, true, FLAG_COND_EQ); return observable; } +lv_observer_t * lv_obj_bind_flag_if_gt(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value) +{ + + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, false, FLAG_COND_GT); + return observable; +} + +lv_observer_t * lv_obj_bind_flag_if_ge(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value) +{ + + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, false, FLAG_COND_GE); + return observable; +} + +lv_observer_t * lv_obj_bind_flag_if_lt(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value) +{ + /* a < b == !(a >= b) */ + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, true, FLAG_COND_GE); + return observable; +} + +lv_observer_t * lv_obj_bind_flag_if_le(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value) +{ + /* a <= b == !(a > b) */ + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, true, FLAG_COND_GT); + return observable; + +} 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) { - lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, false); + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, false, + FLAG_COND_EQ); return observable; } 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) { - lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, true); + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, true, + FLAG_COND_EQ); return observable; } +lv_observer_t * lv_obj_bind_state_if_gt(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value) +{ + + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, false, + FLAG_COND_GT); + return observable; +} + +lv_observer_t * lv_obj_bind_state_if_ge(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value) +{ + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, false, + FLAG_COND_GE); + return observable; +} + +lv_observer_t * lv_obj_bind_state_if_lt(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value) +{ + /* a < b == !(a >= b) */ + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, true, + FLAG_COND_GE); + return observable; + +} + +lv_observer_t * lv_obj_bind_state_if_le(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value) +{ + + /* a <= b == !(a > b) */ + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, true, + FLAG_COND_GT); + return observable; +} + + 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_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, LV_STATE_CHECKED, 0, true, + FLAG_COND_EQ); lv_obj_add_event_cb(obj, obj_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, subject); return observable; } @@ -452,8 +561,14 @@ lv_observer_t * lv_obj_bind_checked(lv_obj_t * obj, lv_subject_t * subject) #if LV_USE_LABEL lv_observer_t * lv_label_bind_text(lv_obj_t * obj, lv_subject_t * subject, const char * fmt) { + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + if(fmt == NULL) { - if(subject->type != LV_SUBJECT_TYPE_STRING && subject->type != LV_SUBJECT_TYPE_POINTER) { + if(subject->type == LV_SUBJECT_TYPE_INT) { + fmt = "%d"; + } + else if(subject->type != LV_SUBJECT_TYPE_STRING && subject->type != LV_SUBJECT_TYPE_POINTER) { LV_LOG_WARN("Incompatible subject type: %d", subject->type); return NULL; } @@ -474,6 +589,9 @@ lv_observer_t * lv_label_bind_text(lv_obj_t * obj, lv_subject_t * subject, const #if LV_USE_ARC lv_observer_t * lv_arc_bind_value(lv_obj_t * obj, lv_subject_t * subject) { + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + if(subject->type != LV_SUBJECT_TYPE_INT) { LV_LOG_WARN("Incompatible subject type: %d", subject->type); return NULL; @@ -489,6 +607,9 @@ lv_observer_t * lv_arc_bind_value(lv_obj_t * obj, lv_subject_t * subject) #if LV_USE_SLIDER lv_observer_t * lv_slider_bind_value(lv_obj_t * obj, lv_subject_t * subject) { + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + if(subject->type != LV_SUBJECT_TYPE_INT) { LV_LOG_WARN("Incompatible subject type: %d", subject->type); return NULL; @@ -502,9 +623,11 @@ lv_observer_t * lv_slider_bind_value(lv_obj_t * obj, lv_subject_t * subject) #endif /*LV_USE_SLIDER*/ #if LV_USE_ROLLER - lv_observer_t * lv_roller_bind_value(lv_obj_t * obj, lv_subject_t * subject) { + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + if(subject->type != LV_SUBJECT_TYPE_INT) { LV_LOG_WARN("Incompatible subject type: %d", subject->type); return NULL; @@ -514,14 +637,15 @@ lv_observer_t * lv_roller_bind_value(lv_obj_t * obj, lv_subject_t * subject) lv_observer_t * observer = lv_subject_add_observer_obj(subject, roller_value_observer_cb, obj, NULL); return observer; - } #endif /*LV_USE_ROLLER*/ #if LV_USE_DROPDOWN - lv_observer_t * lv_dropdown_bind_value(lv_obj_t * obj, lv_subject_t * subject) { + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + if(subject->type != LV_SUBJECT_TYPE_INT) { LV_LOG_WARN("Incompatible subject type: %d", subject->type); return NULL; @@ -531,9 +655,7 @@ lv_observer_t * lv_dropdown_bind_value(lv_obj_t * obj, lv_subject_t * subject) lv_observer_t * observer = lv_subject_add_observer_obj(subject, dropdown_value_observer_cb, obj, NULL); return observer; - } - #endif /*LV_USE_DROPDOWN*/ lv_obj_t * lv_observer_get_target_obj(lv_observer_t * observer) @@ -566,8 +688,11 @@ static void unsubscribe_on_delete_cb(lv_event_t * e) } static lv_observer_t * bind_to_bitfield(lv_subject_t * subject, lv_obj_t * obj, lv_observer_cb_t cb, uint32_t flag, - int32_t ref_value, bool inv) + int32_t ref_value, bool inv, flag_cond_t cond) { + LV_ASSERT_NULL(subject); + LV_ASSERT_NULL(obj); + if(subject->type != LV_SUBJECT_TYPE_INT) { LV_LOG_WARN("Incompatible subject type: %d", subject->type); return NULL; @@ -582,6 +707,7 @@ static lv_observer_t * bind_to_bitfield(lv_subject_t * subject, lv_obj_t * obj, p->flag = flag; p->value.num = ref_value; p->inv = inv; + p->cond = cond; lv_observer_t * observable = lv_subject_add_observer_obj(subject, cb, obj, p); observable->auto_free_user_data = 1; @@ -592,7 +718,19 @@ static void obj_flag_observer_cb(lv_observer_t * observer, lv_subject_t * subjec { flag_and_cond_t * p = observer->user_data; - bool res = subject->value.num == p->value.num; + /* Initializing this keeps some compilers happy */ + bool res = false; + switch(p->cond) { + case FLAG_COND_EQ: + res = subject->value.num == p->value.num; + break; + case FLAG_COND_GT: + res = subject->value.num > p->value.num; + break; + case FLAG_COND_GE: + res = subject->value.num >= p->value.num; + break; + } if(p->inv) res = !res; if(res) { @@ -607,7 +745,19 @@ static void obj_state_observer_cb(lv_observer_t * observer, lv_subject_t * subje { flag_and_cond_t * p = observer->user_data; - bool res = subject->value.num == p->value.num; + /* Initializing this keeps some compilers happy */ + bool res = false; + switch(p->cond) { + case FLAG_COND_EQ: + res = subject->value.num == p->value.num; + break; + case FLAG_COND_GT: + res = subject->value.num > p->value.num; + break; + case FLAG_COND_GE: + res = subject->value.num >= p->value.num; + break; + } if(p->inv) res = !res; if(res) { @@ -626,6 +776,37 @@ static void obj_value_changed_event_cb(lv_event_t * e) lv_subject_set_int(subject, lv_obj_has_state(obj, LV_STATE_CHECKED)); } +static void lv_subject_notify_if_changed(lv_subject_t * subject) +{ + + switch(subject->type) { + case LV_SUBJECT_TYPE_INVALID : + case LV_SUBJECT_TYPE_NONE : + return; + case LV_SUBJECT_TYPE_INT : + if(subject->value.num != subject->prev_value.num) { + lv_subject_notify(subject); + } + break; + case LV_SUBJECT_TYPE_GROUP : + case LV_SUBJECT_TYPE_POINTER : + /* Always notify as we don't know how to compare this */ + lv_subject_notify(subject); + break; + case LV_SUBJECT_TYPE_COLOR : + if(!lv_color_eq(subject->value.color, subject->prev_value.color)) { + lv_subject_notify(subject); + } + break; + case LV_SUBJECT_TYPE_STRING: + if(!subject->prev_value.pointer || + lv_strcmp(subject->value.pointer, subject->prev_value.pointer)) { + lv_subject_notify(subject); + } + break; + } +} + #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 cec77feed..fa4b305b6 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer.h +++ b/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer.h @@ -26,44 +26,45 @@ extern "C" { **********************/ /** - * Values for lv_submect_t's `type` field. + * Values for lv_subject_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*/ - LV_SUBJECT_TYPE_INT = 2, /**< an int32_t*/ - LV_SUBJECT_TYPE_POINTER = 3, /**< a void pointer*/ - LV_SUBJECT_TYPE_COLOR = 4, /**< an lv_color_t*/ - LV_SUBJECT_TYPE_GROUP = 5, /**< an array of subjects*/ - LV_SUBJECT_TYPE_STRING = 6, /**< a char pointer*/ + LV_SUBJECT_TYPE_INVALID = 0, /**< indicates Subject not initialized yet */ + LV_SUBJECT_TYPE_NONE = 1, /**< a null value like None or NILt */ + LV_SUBJECT_TYPE_INT = 2, /**< an int32_t */ + LV_SUBJECT_TYPE_POINTER = 3, /**< a void pointer */ + LV_SUBJECT_TYPE_COLOR = 4, /**< an lv_color_t */ + LV_SUBJECT_TYPE_GROUP = 5, /**< an array of Subjects */ + LV_SUBJECT_TYPE_STRING = 6, /**< a char pointer */ } lv_subject_type_t; /** * A common type to handle all the various observable types in the same way */ typedef union { - int32_t num; /**< Integer number (opacity, enums, booleans or "normal" numbers)*/ - const void * pointer; /**< Constant pointer (string buffer, format string, font, cone text, etc)*/ - lv_color_t color; /**< Color */ + int32_t num; /**< Integer number (opacity, enums, booleans or "normal" numbers) */ + const void * pointer; /**< Constant pointer (string buffer, format string, font, cone text, etc.) */ + lv_color_t color; /**< Color */ } lv_subject_value_t; /** - * The subject (an observable value) + * The Subject (an observable value) */ typedef struct { - lv_ll_t subs_ll; /**< Subscribers*/ - uint32_t type : 4; - uint32_t size : 28; /**< Might be used to store a size related to `type`*/ - lv_subject_value_t value; /**< Actual value*/ - lv_subject_value_t prev_value; /**< Previous value*/ - uint32_t notify_restart_query : 1; /**< If an observer deleted start notifying from the beginning. */ - void * user_data; /**< Additional parameter, can be used freely by the user*/ + lv_ll_t subs_ll; /**< Subscribers */ + lv_subject_value_t value; /**< Current value */ + lv_subject_value_t prev_value; /**< Previous value */ + void * user_data; /**< Additional parameter, can be used freely by user */ + uint32_t type : 4; /**< One of the LV_SUBJECT_TYPE_... values */ + uint32_t size : 24; /**< String buffer size or group length */ + uint32_t notify_restart_query : 1; /**< If an Observer was deleted during notifcation, + * start notifying from the beginning. */ } lv_subject_t; /** - * Callback called when the observed value changes - * @param observer pointer to the observer of the callback - * @param subject pointer to the subject of the observer + * Callback called to notify Observer that Subject's value has changed + * @param observer pointer to Observer + * @param subject pointer to Subject being observed */ typedef void (*lv_observer_cb_t)(lv_observer_t * observer, lv_subject_t * subject); @@ -72,323 +73,423 @@ typedef void (*lv_observer_cb_t)(lv_observer_t * observer, lv_subject_t * subjec **********************/ /** - * Initialize an integer type subject - * @param subject pointer to the subject + * Initialize an integer-type Subject. + * @param subject pointer to Subject * @param value initial value */ void lv_subject_init_int(lv_subject_t * subject, int32_t value); /** - * Set the value of an integer subject. It will notify all the observers as well. - * @param subject pointer to the subject - * @param value the new value + * Set value of an integer Subject and notify Observers. + * @param subject pointer to Subject + * @param value new value */ void lv_subject_set_int(lv_subject_t * subject, int32_t value); /** - * Get the current value of an integer subject - * @param subject pointer to the subject - * @return the current value + * Get current value of an integer Subject. + * @param subject pointer to Subject + * @return current value */ int32_t lv_subject_get_int(lv_subject_t * subject); /** - * Get the previous value of an integer subject - * @param subject pointer to the subject - * @return the current value + * Get previous value of an integer Subject. + * @param subject pointer to Subject + * @return current value */ int32_t lv_subject_get_previous_int(lv_subject_t * subject); /** - * Initialize a string type subject - * @param subject pointer to the subject - * @param buf pointer to a buffer to store the string - * @param prev_buf pointer to a buffer to store the previous string, can be NULL if not used - * @param size size of the buffer - * @param value initial value as a string, e.g. "hello" - * @note the string subject stores the whole string, not only a pointer + * Initialize a string-type Subject. + * @param subject pointer to Subject + * @param buf pointer to buffer to store string + * @param prev_buf pointer to buffer to store previous string; can be NULL if not used + * @param size size of buffer(s) + * @param value initial value of string, e.g. "hello" + * @note A string Subject stores its own copy of the string, not just the pointer. */ void lv_subject_init_string(lv_subject_t * subject, char * buf, char * prev_buf, size_t size, const char * value); /** - * Copy a string to a subject. It will notify all the observers as well. - * @param subject pointer to the subject - * @param buf the new string + * Copy a string to a Subject and notify Observers if it changed. + * @param subject pointer to Subject + * @param buf new string */ void lv_subject_copy_string(lv_subject_t * subject, const char * buf); /** - * Get the current value of an string subject - * @param subject pointer to the subject - * @return pointer to the buffer containing the current value + * Format a new string, updating Subject, and notify Observers if it changed. + * @param subject pointer to Subject + * @param format format string + */ +void lv_subject_snprintf(lv_subject_t * subject, const char * format, ...) LV_FORMAT_ATTRIBUTE(2, 3); + +/** + * Get current value of a string Subject. + * @param subject pointer to Subject + * @return pointer to buffer containing current value */ const char * lv_subject_get_string(lv_subject_t * subject); /** - * Get the previous value of an string subject - * @param subject pointer to the subject - * @return pointer to the buffer containing the current value + * Get previous value of a string Subject. + * @param subject pointer to Subject + * @return pointer to buffer containing previous value * @note NULL will be returned if NULL was passed in `lv_subject_init_string()` - * as `prev_buf` + * as `prev_buf`. */ const char * lv_subject_get_previous_string(lv_subject_t * subject); /** - * Initialize an pointer type subject - * @param subject pointer to the subject + * Initialize a pointer-type Subject. + * @param subject pointer to Subject * @param value initial value */ 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 + * Set value of a pointer Subject and notify Observers (regardless of whether it changed). + * @param subject pointer to Subject * @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 + * Get current value of a pointer Subject. + * @param subject pointer to Subject * @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 current value + * Get previous value of a pointer Subject. + * @param subject pointer to Subject + * @return previous value */ const void * lv_subject_get_previous_pointer(lv_subject_t * subject); /** - * Initialize an color type subject - * @param subject pointer to the subject + * Initialize a color-type Subject. + * @param subject pointer to Subject * @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 + * Set value of a color Subject and notify Observers if it changed. + * @param subject pointer to Subject * @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 + * Get current value of a color Subject. + * @param subject pointer to Subject * @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 current value + * Get previous value of a color Subject. + * @param subject pointer to Subject + * @return previous value */ lv_color_t lv_subject_get_previous_color(lv_subject_t * subject); /** - * Initialize a subject group - * @param subject pointer to the subject - * @param list list of other subject addresses, any of these changes `subject` will be notified - * @param list_len number of elements in `list` + * Initialize a Group-type Subject. + * @param group_subject pointer to Group-type Subject + * @param list list of other Subject addresses; when any of these have values + updated, Observers of `group_subject` will be notified. + * @param list_len number of elements in `list[]` */ -void lv_subject_init_group(lv_subject_t * subject, lv_subject_t * list[], uint32_t list_len); +void lv_subject_init_group(lv_subject_t * group_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. + * Remove all Observers from a Subject and free allocated memory, and delete + * any associated Widget-Binding events. This leaves `subject` "disconnected" from + * all Observers and all associated Widget events established through Widget Binding. + * @param subject pointer to Subject + * @note This can safely be called regardless of whether any Observers + * added with `lv_subject_add_observer_obj()` or bound to a Widget Property + * with one of the `..._bind_...()` functions. */ void lv_subject_deinit(lv_subject_t * subject); /** - * Get an element from the subject group's list - * @param subject pointer to the subject - * @param index index of the element to get - * @return pointer a subject from the list, or NULL if the index is out of bounds + * Get an element from Subject Group's list. + * @param subject pointer to Group-type Subject + * @param index index of element to get + * @return pointer to indexed Subject from list, or NULL if index is out of bounds */ lv_subject_t * lv_subject_get_group_element(lv_subject_t * subject, int32_t index); /** - * Add an observer to a subject. When the subject changes `observer_cb` will be called. - * @param subject pointer to the subject - * @param observer_cb callback to call + * Add Observer to Subject. When Subject's value changes `observer_cb` will be called. + * @param subject pointer to Subject + * @param observer_cb notification callback * @param user_data optional user data - * @return pointer to the created observer + * @return pointer to newly-created Observer */ lv_observer_t * lv_subject_add_observer(lv_subject_t * subject, lv_observer_cb_t observer_cb, void * user_data); /** - * 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 callback to call - * @param obj pointer to an object + * Add Observer to Subject for a Widget. + * When the Widget is deleted, Observer will be unsubscribed from Subject automatically. + * @param subject pointer to Subject + * @param observer_cb notification callback + * @param obj pinter to Widget * @param user_data optional user data - * @return pointer to the created observer + * @return pointer to newly-created Observer + * @note Do not call `lv_observer_remove()` on Observers created this way. + * Only clean up such Observers by either: + * - deleting the Widget, or + * - calling `lv_subject_deinit()` to gracefully de-couple and + * remove all Observers. */ lv_observer_t * lv_subject_add_observer_obj(lv_subject_t * subject, lv_observer_cb_t observer_cb, lv_obj_t * obj, void * user_data); /** - * Add an observer to a subject and also save a target. - * @param subject pointer to the subject - * @param observer_cb callback to call - * @param target pointer to any data + * Add an Observer to a Subject and also save a target pointer. + * @param subject pointer to Subject + * @param observer_cb notification callback + * @param target any pointer (NULL is okay) * @param user_data optional user data - * @return pointer to the created observer + * @return pointer to newly-created Observer */ 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 - * @param observer pointer to an observer + * Remove Observer from its Subject. + * @param observer pointer to Observer */ void lv_observer_remove(lv_observer_t * observer); /** - * 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) + * Remove Observers associated with Widget `obj` from specified `subject` or all Subjects. + * @param obj pointer to Widget whose Observers should be removed + * @param subject Subject to remove Widget from, or NULL to remove from all Subjects + * @note This function can be used e.g. when a Widget's Subject(s) needs to + * be replaced by other Subject(s) */ void lv_obj_remove_from_subject(lv_obj_t * obj, lv_subject_t * subject); /** - * Get the target of an observer - * @param observer pointer to an observer - * @return pointer to the saved target + * Get target of an Observer. + * @param observer pointer to Observer + * @return pointer to saved target */ void * lv_observer_get_target(lv_observer_t * observer); /** - * Get the target object of the observer. - * It's the same as `lv_observer_get_target` and added only - * for semantic reasons - * @param observer pointer to an observer - * @return pointer to the saved object target + * Get target Widget of Observer. + * This is the same as `lv_observer_get_target()`, except it returns `target` + * as an `lv_obj_t *`. + * @param observer pointer to Observer + * @return pointer to saved Widget target */ 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 + * Get Observer's user data. + * @param observer pointer to Observer + * @return void pointer to saved user data */ void * lv_observer_get_user_data(const lv_observer_t * observer); /** - * Notify all observers of subject - * @param subject pointer to a subject + * Notify all Observers of Subject. + * @param subject pointer to Subject */ 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 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 + * Set Widget's flag(s) if an integer Subject's value is equal to a reference value, clear flag otherwise. + * @param obj pointer to Widget + * @param subject pointer to Subject + * @param flag flag(s) (can be bit-wise OR-ed) to set or clear (e.g. `LV_OBJ_FLAG_HIDDEN`) + * @param ref_value reference value to compare Subject's value with + * @return pointer to newly-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); /** - * 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 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 + * Set Widget's flag(s) if an integer Subject's value is not equal to a reference value, clear flag otherwise. + * @param obj pointer to Widget + * @param subject pointer to Subject + * @param flag flag(s) (can be bit-wise OR-ed) to set or clear (e.g. `LV_OBJ_FLAG_HIDDEN`) + * @param ref_value reference value to compare Subject's value with + * @return pointer to newly-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, int32_t ref_value); /** - * 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 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 + * Set Widget's flag(s) if an integer Subject's value is greater than a reference value, clear flag otherwise. + * @param obj pointer to Widget + * @param subject pointer to Subject + * @param flag flag(s) (can be bit-wise OR-ed) to set or clear (e.g. `LV_OBJ_FLAG_HIDDEN`) + * @param ref_value reference value to compare Subject's value with + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_obj_bind_flag_if_gt(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value); + +/** + * Set Widget's flag(s) if an integer Subject's value is greater than or equal to a reference value, clear flag otherwise. + * @param obj pointer to Widget + * @param subject pointer to Subject + * @param flag flag(s) (can be bit-wise OR-ed) to set or clear (e.g. `LV_OBJ_FLAG_HIDDEN`) + * @param ref_value reference value to compare Subject's value with + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_obj_bind_flag_if_ge(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value); + +/** + * Set Widget's flag(s) if an integer Subject's value is less than a reference value, clear flag otherwise. + * @param obj pointer to Widget + * @param subject pointer to Subject + * @param flag flag(s) (can be bit-wise OR-ed) to set or clear (e.g. `LV_OBJ_FLAG_HIDDEN`) + * @param ref_value reference value to compare Subject's value with + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_obj_bind_flag_if_lt(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value); + +/** + * Set Widget's flag(s) if an integer Subject's value is less than or equal to a reference value, clear flag otherwise. + * @param obj pointer to Widget + * @param subject pointer to Subject + * @param flag flag(s) (can be bit-wise OR-ed) to set or clear (e.g. `LV_OBJ_FLAG_HIDDEN`) + * @param ref_value reference value to compare Subject's value with + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_obj_bind_flag_if_le(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value); + + +/** + * Set Widget's state(s) if an integer Subject's value is equal to a reference value, clear flag otherwise. + * @param obj pointer to Widget + * @param subject pointer to Subject + * @param state state(s) (can be bit-wise OR-ed) to set or clear (e.g. `LV_STATE_CHECKED`) + * @param ref_value reference value to compare Subject's value with + * @return pointer to newly-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); /** - * 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 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 + * Set a Widget's state(s) if an integer Subject's value is not equal to a reference value, clear flag otherwise + * @param obj pointer to Widget + * @param subject pointer to Subject + * @param state state(s) (can be bit-wise OR-ed) to set or clear (e.g. `LV_STATE_CHECKED`) + * @param ref_value reference value to compare Subject's value with + * @return pointer to newly-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); /** - * 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 + * Set Widget's state(s) if an integer Subject's value is greater than a reference value, clear flag otherwise. + * @param obj pointer to Widget + * @param subject pointer to Subject + * @param state state(s) (can be bit-wise OR-ed) to set or clear (e.g. `LV_STATE_CHECKED`) + * @param ref_value reference value to compare Subject's value with + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_obj_bind_state_if_gt(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value); + +/** + * Set Widget's state(s) if an integer Subject's value is greater than or equal to a reference value, clear flag otherwise. + * @param obj pointer to Widget + * @param subject pointer to Subject + * @param state state(s) (can be bit-wise OR-ed) to set or clear (e.g. `LV_STATE_CHECKED`) + * @param ref_value reference value to compare Subject's value with + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_obj_bind_state_if_ge(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value); + +/** + * Set Widget's state(s) if an integer Subject's value is less than a reference value, clear flag otherwise. + * @param obj pointer to Widget + * @param subject pointer to Subject + * @param state state(s) (can be bit-wise OR-ed) to set or clear (e.g. `LV_STATE_CHECKED`) + * @param ref_value reference value to compare Subject's value with + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_obj_bind_state_if_lt(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value); + +/** + * Set Widget's state(s) if an integer Subject's value is less than or equal to a reference value, clear flag otherwise. + * @param obj pointer to Widget + * @param subject pointer to Subject + * @param state state(s) (can be bit-wise OR-ed) to set or clear (e.g. `LV_STATE_CHECKED`) + * @param ref_value reference value to compare Subject's value with + * @return pointer to newly-created Observer + */ +lv_observer_t * lv_obj_bind_state_if_le(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value); + +/** + * Set an integer Subject to 1 when a Widget is checked and set it 0 when unchecked, and + * clear Widget's checked state when Subject's value changes to 0 and set it when non-zero. + * @param obj pointer to Widget + * @param subject pointer to a Subject + * @return pointer to newly-created Observer + * @note Ensure Widget's `LV_OBJ_FLAG_CHECKABLE` flag is set. */ 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 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. - * @note if the subject is a pointer must point to a `\0` terminated string. + * Bind an integer, string, or pointer Subject to a Label. + * @param obj pointer to Label + * @param subject pointer to Subject + * @param fmt optional printf-like format string with 1 format specifier (e.g. "%d °C") + * or NULL to bind to the value directly. + * @return pointer to newly-created Observer + * @note `fmt == NULL` can be used only with string and pointer Subjects. + * @note If Subject is a pointer and `fmt == NULL`, pointer must point + * to a `\0` terminated string. */ lv_observer_t * lv_label_bind_text(lv_obj_t * obj, lv_subject_t * subject, const char * fmt); #endif #if LV_USE_ARC /** - * Bind an integer subject to an arc's value - * @param obj pointer to an arc - * @param subject pointer to a subject - * @return pointer to the created observer + * Bind an integer subject to an Arc's value. + * @param obj pointer to Arc + * @param subject pointer to Subject + * @return pointer to newly-created Observer */ lv_observer_t * lv_arc_bind_value(lv_obj_t * obj, lv_subject_t * subject); #endif #if LV_USE_SLIDER /** - * Bind an integer subject to a slider's value - * @param obj pointer to a slider - * @param subject pointer to a subject - * @return pointer to the created observer + * Bind an integer Subject to a Slider's value. + * @param obj pointer to Slider + * @param subject pointer to Subject + * @return pointer to newly-created Observer */ lv_observer_t * lv_slider_bind_value(lv_obj_t * obj, lv_subject_t * subject); #endif #if LV_USE_ROLLER /** - * Bind an integer subject to a roller's value - * @param obj pointer to a roller - * @param subject pointer to a subject - * @return pointer to the created observer + * Bind an integer Subject to a Roller's value. + * @param obj pointer to Roller + * @param subject pointer to Subject + * @return pointer to newly-created Observer */ lv_observer_t * lv_roller_bind_value(lv_obj_t * obj, lv_subject_t * subject); #endif #if LV_USE_DROPDOWN /** - * Bind an integer subject to a dropdown's value - * @param obj pointer to a drop down - * @param subject pointer to a subject - * @return pointer to the created observer + * Bind an integer Subject to a Dropdown's value. + * @param obj pointer to Dropdown + * @param subject pointer to Subject + * @return pointer to newly-created Observer */ lv_observer_t * lv_dropdown_bind_value(lv_obj_t * obj, lv_subject_t * subject); #endif 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 index 04a7992eb..d62d1f663 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer_private.h +++ b/lib/libesp32_lvgl/lvgl/src/others/observer/lv_observer_private.h @@ -29,14 +29,14 @@ extern "C" { /** * 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 *`*/ +struct _lv_observer_t { + lv_subject_t * subject; /**< Observed subject */ + lv_observer_cb_t cb; /**< Callback that notifies when value changes */ + void * target; /**< A target for the observer, e.g. a widget or any pointer */ + void * user_data; /**< Additional parameter supplied when subscribing */ + uint32_t auto_free_user_data : 1; /**< Automatically free user data when observer is removed */ + uint32_t notified : 1; /**< Was observer already notified? */ + uint32_t for_obj : 1; /**< Is `target` a pointer to a Widget (`lv_obj_t *`)? */ }; 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 f3f182b8d..376d3b2af 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/snapshot/lv_snapshot.c +++ b/lib/libesp32_lvgl/lvgl/src/others/snapshot/lv_snapshot.c @@ -79,11 +79,16 @@ lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, l switch(cf) { case LV_COLOR_FORMAT_RGB565: + case LV_COLOR_FORMAT_ARGB8565: case LV_COLOR_FORMAT_RGB888: case LV_COLOR_FORMAT_XRGB8888: case LV_COLOR_FORMAT_ARGB8888: + case LV_COLOR_FORMAT_A8: case LV_COLOR_FORMAT_L8: case LV_COLOR_FORMAT_I1: + case LV_COLOR_FORMAT_ARGB2222: + case LV_COLOR_FORMAT_ARGB4444: + case LV_COLOR_FORMAT_ARGB1555: break; default: LV_LOG_WARN("Not supported color format"); @@ -104,7 +109,7 @@ lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, l lv_area_increase(&snapshot_area, ext_size, ext_size); lv_layer_t layer; - lv_memzero(&layer, sizeof(layer)); + lv_layer_init(&layer); layer.draw_buf = draw_buf; layer.buf_area.x1 = snapshot_area.x1; @@ -114,9 +119,6 @@ lv_result_t lv_snapshot_take_to_draw_buf(lv_obj_t * obj, lv_color_format_t cf, l 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_new = lv_obj_get_display(obj); 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 803ce8c5e..e8f5c6c88 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon.c +++ b/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon.c @@ -105,17 +105,19 @@ void lv_sysmon_show_performance(lv_display_t * disp) return; } - disp->perf_label = lv_sysmon_create(disp); if(disp->perf_label == NULL) { - LV_LOG_WARN("Couldn't create sysmon"); - 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); + 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); @@ -147,14 +149,16 @@ void lv_sysmon_show_memory(lv_display_t * disp) return; } - disp->mem_label = lv_sysmon_create(disp); if(disp->mem_label == NULL) { - LV_LOG_WARN("Couldn't create sysmon"); - 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_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); } @@ -240,7 +244,7 @@ static void perf_update_timer_cb(lv_timer_t * t) uint32_t time_since_last_report = lv_tick_elaps(info->measured.last_report_timestamp); lv_timer_t * disp_refr_timer = lv_display_get_refr_timer(NULL); - uint32_t disp_refr_period = disp_refr_timer->period; + uint32_t disp_refr_period = disp_refr_timer ? disp_refr_timer->period : LV_DEF_REFR_PERIOD; info->calculated.fps = info->measured.refr_interval_sum ? (1000 * info->measured.refr_cnt / time_since_last_report) : 0; info->calculated.fps = LV_MIN(info->calculated.fps, 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 index 08d6156d3..b4fa3877e 100644 --- a/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon_private.h +++ b/lib/libesp32_lvgl/lvgl/src/others/sysmon/lv_sysmon_private.h @@ -26,13 +26,13 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_sysmon_backend_data_t { +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 _lv_sysmon_perf_info_t { struct { bool inited; uint32_t refr_start; diff --git a/lib/libesp32_lvgl/lvgl/src/others/test/lv_test.h b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test.h new file mode 100644 index 000000000..5496c1005 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test.h @@ -0,0 +1,46 @@ +/** + * @file lv_test.h + * + */ + +#ifndef LV_TEST_H +#define LV_TEST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_TEST + +/********************* + * DEFINES + *********************/ +#include "lv_test_indev.h" +#include "lv_test_display.h" +#include "lv_test_helpers.h" +#include "lv_test_screenshot_compare.h" +#include "lv_test_indev_gesture.h" + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE TEST*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEST_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_display.c b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_display.c new file mode 100644 index 000000000..b6c00708f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_display.c @@ -0,0 +1,108 @@ +/** + * @file lv_test_display.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_test_display.h" +#if LV_USE_TEST + +#include "../../core/lv_global.h" +#include "../../lvgl_private.h" +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void dummy_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p); + +static void buf_changed_event_cb(lv_event_t * e); +static void delete_event_cb(lv_event_t * e); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ +#define _state LV_GLOBAL_DEFAULT()->test_state + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_display_t * lv_test_display_create(int32_t hor_res, int32_t ver_res) +{ + + lv_display_t * disp = lv_display_create(hor_res, ver_res); + lv_display_set_color_format(disp, LV_COLOR_FORMAT_XRGB8888); + + size_t buf_size = 4 * (hor_res + LV_DRAW_BUF_STRIDE_ALIGN - 1) * ver_res + LV_DRAW_BUF_ALIGN; + uint8_t * buf = malloc(buf_size); + LV_ASSERT_MALLOC(buf); + + lv_draw_buf_init(&_state.draw_buf, hor_res, ver_res, LV_COLOR_FORMAT_XRGB8888, LV_STRIDE_AUTO, lv_draw_buf_align(buf, + LV_COLOR_FORMAT_XRGB8888), buf_size); + _state.draw_buf.unaligned_data = buf; + lv_display_set_draw_buffers(disp, &_state.draw_buf, NULL); + lv_display_set_render_mode(disp, LV_DISPLAY_RENDER_MODE_DIRECT); + + lv_display_set_flush_cb(disp, dummy_flush_cb); + + lv_display_add_event_cb(disp, buf_changed_event_cb, LV_EVENT_COLOR_FORMAT_CHANGED, NULL); + lv_display_add_event_cb(disp, buf_changed_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL); + lv_display_add_event_cb(disp, delete_event_cb, LV_EVENT_DELETE, NULL); + + return disp; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void buf_changed_event_cb(lv_event_t * e) +{ + lv_display_t * disp = lv_event_get_target(e); + lv_color_format_t cf = lv_display_get_color_format(disp); + int32_t hor_res = lv_display_get_original_horizontal_resolution(disp); + int32_t ver_res = lv_display_get_original_vertical_resolution(disp); + + free(_state.draw_buf.unaligned_data); + + size_t buf_size = 4 * (hor_res + LV_DRAW_BUF_STRIDE_ALIGN - 1) * ver_res + LV_DRAW_BUF_ALIGN; + uint8_t * buf = malloc(buf_size); + LV_ASSERT_MALLOC(buf); + + lv_draw_buf_init(&_state.draw_buf, hor_res, ver_res, cf, LV_STRIDE_AUTO, lv_draw_buf_align(buf, cf), buf_size); + _state.draw_buf.unaligned_data = buf; + lv_display_set_draw_buffers(disp, &_state.draw_buf, NULL); +} + +static void delete_event_cb(lv_event_t * e) +{ + LV_UNUSED(e); + lv_display_t * disp = lv_event_get_target(e); + lv_draw_buf_t * draw_buf = lv_display_get_buf_active(disp); + free(draw_buf->unaligned_data); + +} + +static void dummy_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p) +{ + LV_UNUSED(area); + LV_UNUSED(color_p); + lv_display_flush_ready(disp); +} + +#endif /*LV_USE_TEST*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_display.h b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_display.h new file mode 100644 index 000000000..ea39da2da --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_display.h @@ -0,0 +1,55 @@ +/** + * @file lv_test_display.h + * + */ + +#ifndef LV_TEST_DISPLAY_H +#define LV_TEST_DISPLAY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_TEST + +#include "../../misc/lv_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/*** + * Create a dummy display for for the tests + * @param hor_res the maximal horizontal resolution + * @param ver_res the maximal vertical resolution + * @return the created display + * + * @note The resolution can be changed to any smaller values later + * using `lv_display_set_resolution` + * The color format can be freely changed later using `lv_display_set_color_format` + */ +lv_display_t * lv_test_display_create(int32_t hor_res, int32_t ver_res); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_TEST*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEST_DISPLAY_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_helpers.c b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_helpers.c new file mode 100644 index 000000000..cbaadca7d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_helpers.c @@ -0,0 +1,60 @@ +/** + * @file lv_test_helpers.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_test_helpers.h" + +#if LV_USE_TEST +#include "../../lvgl.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_test_wait(uint32_t ms) +{ + while(ms) { + lv_tick_inc(1); + lv_timer_handler(); + ms--; + } + lv_refr_now(NULL); +} + +void lv_test_fast_forward(uint32_t ms) +{ + lv_tick_inc(ms); + lv_timer_handler(); + lv_refr_now(NULL); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_TEST*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_helpers.h b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_helpers.h new file mode 100644 index 000000000..0c9048b8d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_helpers.h @@ -0,0 +1,80 @@ +/** + * @file lv_test_helpers.h + * + */ + +#ifndef LV_TEST_HELPERS_H +#define LV_TEST_HELPERS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_TEST + +#include "../../misc/lv_types.h" +#include "../../stdlib/lv_mem.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Emulate a delay. It's not real delay, but it tricks LVGL to think that the + * required time has been elapsed. + * `lv_timer_handler` is called after each millisecond, meaning all the events + * will be fired inside this function. + * At the end the animations and display will be also updated. + * @param ms the number of milliseconds to pass + */ +void lv_test_wait(uint32_t ms); + +/** + * Emulates some time passing. + * Update the animations and the display only once at the end. + * @param ms the number of milliseconds to pass + */ +void lv_test_fast_forward(uint32_t ms); + +#if LV_USE_STDLIB_MALLOC != LV_STDLIB_BUILTIN +/* Skip checking heap as we don't have the info available */ +#define LV_HEAP_CHECK(x) do {} while(0) +/* Pick a non-zero value */ +#define lv_test_get_free_mem() (65536) +#else +#define LV_HEAP_CHECK(x) x + +static inline size_t lv_test_get_free_mem(void) +{ + lv_mem_monitor_t m1; + lv_mem_monitor(&m1); + return m1.free_size; +} +#endif /* LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN */ + +/********************** + * MACROS + **********************/ + +#define LV_TEST_WIDTH_TO_STRIDE(w, px_size) ((((w) * (px_size) + (LV_DRAW_BUF_STRIDE_ALIGN - 1)) / LV_DRAW_BUF_STRIDE_ALIGN) * LV_DRAW_BUF_STRIDE_ALIGN) + +#endif /*LV_USE_TEST*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEST_HELPERS_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev.c b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev.c new file mode 100644 index 000000000..11bdb14b2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev.c @@ -0,0 +1,194 @@ +/** + * @file lv_test_indev.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_test.h" +#if LV_USE_TEST + +#include "../../core/lv_global.h" +#include "../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void lv_test_mouse_read_cb(lv_indev_t * indev, lv_indev_data_t * data); +static void lv_test_keypad_read_cb(lv_indev_t * indev, lv_indev_data_t * data); +static void lv_test_encoder_read_cb(lv_indev_t * indev, lv_indev_data_t * data); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ +#define _state LV_GLOBAL_DEFAULT()->test_state + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_test_indev_create_all(void) +{ + _state.mouse_indev = lv_indev_create(); + lv_indev_set_type(_state.mouse_indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(_state.mouse_indev, lv_test_mouse_read_cb); + + _state.keypad_indev = lv_indev_create(); + lv_indev_set_type(_state.keypad_indev, LV_INDEV_TYPE_KEYPAD); + lv_indev_set_read_cb(_state.keypad_indev, lv_test_keypad_read_cb); + + _state.encoder_indev = lv_indev_create(); + lv_indev_set_type(_state.encoder_indev, LV_INDEV_TYPE_ENCODER); + lv_indev_set_read_cb(_state.encoder_indev, lv_test_encoder_read_cb); +} + +lv_indev_t * lv_test_indev_get_indev(lv_indev_type_t type) +{ + switch(type) { + case LV_INDEV_TYPE_POINTER: + return _state.mouse_indev; + case LV_INDEV_TYPE_KEYPAD: + return _state.keypad_indev; + case LV_INDEV_TYPE_ENCODER: + return _state.encoder_indev; + default: + return NULL; + + } +} + +void lv_test_mouse_move_to(int32_t x, int32_t y) +{ + _state.x_act = x; + _state.y_act = y; +} + + +void lv_test_mouse_move_to_obj(lv_obj_t * obj) +{ + int32_t x = obj->coords.x1 + lv_obj_get_width(obj) / 2; + int32_t y = obj->coords.y1 + lv_obj_get_height(obj) / 2; + lv_test_mouse_move_to(x, y); +} + +void lv_test_mouse_move_by(int32_t x, int32_t y) +{ + _state.x_act += x; + _state.y_act += y; +} + +void lv_test_mouse_press(void) +{ + _state.mouse_pressed = true; +} + +void lv_test_mouse_release(void) +{ + _state.mouse_pressed = false; +} + +void lv_test_mouse_click_at(int32_t x, int32_t y) +{ + lv_test_mouse_release(); + lv_test_wait(50); + lv_test_mouse_move_to(x, y); + lv_test_mouse_press(); + lv_test_wait(50); + lv_test_mouse_release(); + lv_test_wait(50); +} + +void lv_test_key_press(uint32_t k) +{ + _state.key_act = k; + _state.key_pressed = true; +} + +void lv_test_key_release(void) +{ + _state.key_pressed = false; +} + +void lv_test_key_hit(uint32_t k) +{ + lv_test_key_release(); + lv_test_wait(50); + lv_test_key_press(k); + lv_test_wait(50); + lv_test_key_release(); + lv_test_wait(50); +} + +void lv_test_encoder_add_diff(int32_t d) +{ + _state.diff_act += d; +} + +void lv_test_encoder_turn(int32_t d) +{ + _state.diff_act += d; + lv_test_wait(50); +} + +void lv_test_encoder_press(void) +{ + _state.enc_pressed = true; +} + +void lv_test_encoder_release(void) +{ + _state.enc_pressed = false; +} + +void lv_test_encoder_click(void) +{ + lv_test_encoder_release(); + lv_test_wait(50); + lv_test_encoder_press(); + lv_test_wait(50); + lv_test_encoder_release(); + lv_test_wait(50); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_test_mouse_read_cb(lv_indev_t * indev, lv_indev_data_t * data) +{ + LV_UNUSED(indev); + lv_point_set(&data->point, _state.x_act, _state.y_act); + data->state = _state.mouse_pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; +} + + +static void lv_test_keypad_read_cb(lv_indev_t * indev, lv_indev_data_t * data) +{ + LV_UNUSED(indev); + data->key = _state.key_act; + data->state = _state.key_pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; +} + + +static void lv_test_encoder_read_cb(lv_indev_t * indev, lv_indev_data_t * data) +{ + LV_UNUSED(indev); + data->enc_diff = _state.diff_act; + data->state = _state.enc_pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; + _state.diff_act = 0; +} + +#endif /*LV_USE_TEST*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev.h b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev.h new file mode 100644 index 000000000..7d833fff4 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev.h @@ -0,0 +1,166 @@ +/** + * @file lv_test_indev.h + * + */ + +#ifndef LV_TEST_INDEV_H +#define LV_TEST_INDEV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_TEST + +#include "../../misc/lv_types.h" +#include "../../indev/lv_indev.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a mouse (pointer), keypad, and encoder indevs. + * They can be controlled via function calls during the test + */ +void lv_test_indev_create_all(void); + +/** + * Get one of the indev created in `lv_test_indev_create_all` + * @param type type of the indev to get + * @return the indev + */ +lv_indev_t * lv_test_indev_get_indev(lv_indev_type_t type); + +/** + * Move the mouse to the given coordinates. + * This function doesn't wait, but just changes the state and returns immediately. + * @param x the target absolute X coordinate + * @param y the target absolute Y coordinate + */ +void lv_test_mouse_move_to(int32_t x, int32_t y); + +/** + * Move the mouse to the center of a widget + * This function doesn't wait, but just changes the state and returns immediately. + * @param obj pointer to an widget + */ +void lv_test_mouse_move_to_obj(lv_obj_t * obj); + +/** + * Move the mouse cursor. Keep the pressed or released state + * This function doesn't wait, but just changes the state and returns immediately. + * @param x the difference in X to move + * @param y the difference in Y to move + */ +void lv_test_mouse_move_by(int32_t x, int32_t y); + +/** + * Make the mouse button pressed. + * This function doesn't wait, but just changes the state and returns immediately. + */ +void lv_test_mouse_press(void); + +/** + * Make the mouse button released. + * This function doesn't wait, but just changes the state and returns immediately. + */ +void lv_test_mouse_release(void); + +/** + * Emulate a click on a given point. + * First set the released state, wait a little, press, wait, and release again. + * The wait time is 50ms. + * Internally `lv_timer_handler` is called, meaning all the events will be fired inside this function. + * @param x the target absolute X coordinate + * @param y the target absolute Y coordinate + */ +void lv_test_mouse_click_at(int32_t x, int32_t y); + +/** + * Emulate a key press. + * This function doesn't wait, but just changes the state and returns immediately. + * @param k the key to press + */ +void lv_test_key_press(uint32_t k); + +/** + * Release the previously press key. + * This function doesn't wait, but just changes the state and returns immediately. + * @param k the key to press + */ +void lv_test_key_release(void); + +/** + * Emulate a key hit. + * First set the released state, wait a little, press, wait, and release again. + * The wait time is 50ms. + * Internally `lv_timer_handler` is called, meaning all the events will be fired inside this function. + * @param k the key to hit + */ +void lv_test_key_hit(uint32_t k); + + +/** + * Emulate encoder rotation, use positive parameter to rotate to the right + * and negative to rotate to the left. + * This function doesn't wait, but just changes the state and returns immediately. + * @param d number of encoder ticks to emulate + */ +void lv_test_encoder_add_diff(int32_t d); + +/** + * Emulate an encoder turn a wait 50ms. Use positive parameter to rotate to the right + * and negative to rotate to the left. + * Internally `lv_timer_handler` is called, meaning all the events will be fired inside this function. + * @param d number of encoder ticks to emulate + */ +void lv_test_encoder_turn(int32_t d); + +/** + * Emulate an encoder press. + * This function doesn't wait, but just changes the state and returns immediately. + */ +void lv_test_encoder_press(void); + +/** + * Emulate an encoder release. + * This function doesn't wait, but just changes the state and returns immediately. + */ +void lv_test_encoder_release(void); + +/** + * Emulate am encoder click. + * First set the released state, wait a little, press, wait, and release again. + * The wait time is 50ms. + * Internally `lv_timer_handler` is called, meaning all the events will be fired inside this function. + */ +void lv_test_encoder_click(void); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_TEST*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEST_INDEV_H*/ + + + + diff --git a/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev_gesture.c b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev_gesture.c new file mode 100644 index 000000000..ad0148195 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev_gesture.c @@ -0,0 +1,117 @@ +/** + * @file lv_test_indev_gesture.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_test.h" +#if LV_USE_TEST && LV_USE_GESTURE_RECOGNITION + +#include "../../core/lv_global.h" +#include "../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +#define MAX_TOUCH_CNT 2 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void lv_test_gesture_read_cb(lv_indev_t * indev, lv_indev_data_t * data); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ +#define _state LV_GLOBAL_DEFAULT()->test_state + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_test_indev_gesture_create(void) +{ + _state.max_touch_cnt = MAX_TOUCH_CNT; + _state.touch_data = + lv_malloc_zeroed(sizeof(lv_indev_touch_data_t) * _state.max_touch_cnt); + if(_state.touch_data == NULL) { + LV_LOG_ERROR("lv_indev_touch_data_t malloc failed"); + } + + _state.gesture_indev = lv_indev_create(); + lv_indev_set_type(_state.gesture_indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(_state.gesture_indev, lv_test_gesture_read_cb); +} + +lv_indev_t * lv_test_indev_get_gesture_indev(lv_indev_type_t type) +{ + switch(type) { + case LV_INDEV_TYPE_POINTER: + return _state.gesture_indev; + default: + return NULL; + } +} + +void lv_test_gesture_set_pinch_data(lv_point_t point_0, lv_point_t point_1) +{ + _state.touch_data[0].id = 0; + _state.touch_data[0].point = point_0; + _state.touch_data[1].id = 1; + _state.touch_data[1].point = point_1; +} + +void lv_test_gesture_pinch_press(void) +{ + _state.touch_data[0].state = LV_INDEV_STATE_PRESSED; + _state.touch_data[1].state = LV_INDEV_STATE_PRESSED; +} + +void lv_test_gesture_pinch_release(void) +{ + _state.touch_data[0].state = LV_INDEV_STATE_RELEASED; + _state.touch_data[1].state = LV_INDEV_STATE_RELEASED; +} + +void lv_test_gesture_pinch(lv_point_t point_begin_0, lv_point_t point_begin_1, + lv_point_t point_end_0, lv_point_t point_end_1) +{ + lv_test_gesture_pinch_release(); + lv_test_wait(50); + lv_test_gesture_set_pinch_data(point_begin_0, point_begin_1); + lv_test_gesture_pinch_press(); + lv_test_wait(50); + lv_test_gesture_set_pinch_data(point_end_0, point_end_1); + lv_test_wait(80); + lv_test_gesture_set_pinch_data(point_end_0, point_end_1); + lv_test_wait(80); + lv_test_gesture_pinch_release(); + lv_test_wait(50); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_test_gesture_read_cb(lv_indev_t * indev, lv_indev_data_t * data) +{ + LV_UNUSED(indev); + + lv_indev_gesture_recognizers_update(indev, + _state.touch_data, + _state.max_touch_cnt); + lv_indev_gesture_recognizers_set_data(indev, data); +} + +#endif /*LV_USE_TEST*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev_gesture.h b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev_gesture.h new file mode 100644 index 000000000..8973478d8 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_indev_gesture.h @@ -0,0 +1,88 @@ +/** + * @file lv_test_indev_gesture.h + * + */ + +#ifndef LV_TEST_INDEV_GESTURE_H +#define LV_TEST_INDEV_GESTURE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_TEST && LV_USE_GESTURE_RECOGNITION + +#include "../../misc/lv_types.h" +#include "../../indev/lv_indev.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a touch (pointer) indevs. + * They can be controlled via function calls during the test + */ +void lv_test_indev_gesture_create(void); + +/** + * Get one of the indev created in `lv_test_indev_gesture_create` + * @param type type of the indev to get + * @return the indev + */ +lv_indev_t * lv_test_indev_get_gesture_indev(lv_indev_type_t type); + +/** + * Set two touch points data for pinch gesture + * @param point_0 First touch point coordinates + * @param point_1 Second touch point coordinates + */ +void lv_test_gesture_set_pinch_data(lv_point_t point_0, lv_point_t point_1); + +/** + * Trigger press state of pinch gesture (both touch points pressed) + */ +void lv_test_gesture_pinch_press(void); + +/** + * Trigger release state of pinch gesture (both touch points released) + */ +void lv_test_gesture_pinch_release(void); + +/** + * Simulate a complete pinch gesture operation + * @param point_begin_0 Starting coordinates of first touch point + * @param point_begin_1 Starting coordinates of second touch point + * @param point_end_0 Ending coordinates of first touch point + * @param point_end_1 Ending coordinates of second touch point + */ +void lv_test_gesture_pinch(lv_point_t point_begin_0, lv_point_t point_begin_1, + lv_point_t point_end_0, lv_point_t point_end_1); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_TEST && LV_USE_GESTURE_RECOGNITION*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEST_INDEV_GESTURE_H*/ + + + + diff --git a/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_private.h b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_private.h new file mode 100644 index 000000000..b19f5b674 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_private.h @@ -0,0 +1,67 @@ +/** + * @file lv_test_private.h + * + */ + +#ifndef LV_TEST_PRIVATE_H +#define LV_TEST_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_TEST + +#include "../../misc/lv_types.h" +#include "../../indev/lv_indev_gesture.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_indev_t * mouse_indev; + lv_indev_t * keypad_indev; + lv_indev_t * encoder_indev; + + lv_draw_buf_t draw_buf; + + int32_t x_act; + int32_t y_act; + uint32_t key_act; + int32_t diff_act; + bool mouse_pressed; + bool key_pressed; + bool enc_pressed; + +#if LV_USE_GESTURE_RECOGNITION + lv_indev_t * gesture_indev; + lv_indev_touch_data_t * touch_data; + uint8_t max_touch_cnt; +#endif +} lv_test_state_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_TEST*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + + +#endif /*LV_TEST_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_screenshot_compare.c b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_screenshot_compare.c new file mode 100644 index 000000000..db73d18a1 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_screenshot_compare.c @@ -0,0 +1,328 @@ +/** + * @file lv_test_assert.c + * + * Copyright 2002-2010 Guillaume Cottenceau. + * + * This software may be freely redistributed under the terms + * of the X11 license. + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_TEST && defined(LV_USE_TEST_SCREENSHOT_COMPARE) && LV_USE_TEST_SCREENSHOT_COMPARE + +#if LV_USE_LODEPNG == 0 + #error "lodepng is required for screenshot compare. Enable it in lv_conf.h (LV_USE_LODEPNG 1)" +#endif + +#include "../../lvgl.h" +#include +#include +#include +#include +#include +#include "../../libs/lodepng/lodepng.h" + +#ifdef _WIN32 + #include + #define mkdir(pathname, mode) _mkdir(pathname) + #define strtok_r strtok_s +#else + #include +#endif + +/********************* + * DEFINES + *********************/ + +#ifndef REF_IMGS_PATH + #define REF_IMGS_PATH "" +#endif + +#ifndef REF_IMG_TOLERANCE + #define REF_IMG_TOLERANCE 0 +#endif + +#define ERR_FILE_NOT_FOUND -1 +#define ERR_PNG -2 + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static bool screenshot_compare(const char * fn_ref, uint8_t tolerance); +static unsigned read_png_file(lv_draw_buf_t ** refr_draw_buf, unsigned * width, unsigned * height, + const char * file_name); +static unsigned write_png_file(void * raw_img, uint32_t width, uint32_t height, char * file_name); +static void buf_to_xrgb8888(const lv_draw_buf_t * draw_buf, uint8_t * buf_out); +static void create_folders_if_needed(const char * path) ; + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +bool lv_test_screenshot_compare(const char * fn_ref) +{ + bool pass; + + lv_obj_t * scr = lv_screen_active(); + lv_obj_invalidate(scr); + + pass = screenshot_compare(fn_ref, REF_IMG_TOLERANCE); + if(!pass) return false; + + return true; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * Compare the content of the frame buffer with a reference image + * @param fn_ref reference image path + * @return true: test passed; false: test failed + */ +static bool screenshot_compare(const char * fn_ref, uint8_t tolerance) +{ + char fn_ref_full[256]; + lv_snprintf(fn_ref_full, sizeof(fn_ref_full), "%s%s", REF_IMGS_PATH, fn_ref); + + create_folders_if_needed(fn_ref_full); + + lv_refr_now(NULL); + + lv_draw_buf_t * draw_buf = lv_display_get_buf_active(NULL); + uint8_t * screen_buf_xrgb8888 = lv_malloc(draw_buf->header.w * draw_buf->header.h * 4); + buf_to_xrgb8888(draw_buf, screen_buf_xrgb8888); + + lv_draw_buf_t * ref_draw_buf; + unsigned ref_img_width = 0; + unsigned ref_img_height = 0; + unsigned res = read_png_file(&ref_draw_buf, &ref_img_width, &ref_img_height, fn_ref_full); + if(res) { + LV_LOG_ERROR("%s%s", fn_ref_full, " was not found, creating is now from the rendered screen"); + write_png_file(screen_buf_xrgb8888, draw_buf->header.w, draw_buf->header.h, fn_ref_full); + lv_free(screen_buf_xrgb8888); + return true; + } + + unsigned x, y; + bool err = false; + for(y = 0; y < ref_img_height; y++) { + uint8_t * screen_buf_tmp = screen_buf_xrgb8888 + draw_buf->header.w * 4 * y; + uint8_t * ref_row = (uint8_t *)ref_draw_buf->data + y * ref_draw_buf->header.stride; + for(x = 0; x < ref_img_width; x++) { + uint8_t * ptr_ref = &(ref_row[x * 4]); + uint8_t * ptr_act = &screen_buf_tmp[x * 4]; + + if(LV_ABS((int32_t) ptr_act[0] - (int32_t) ptr_ref[0]) > tolerance || + LV_ABS((int32_t) ptr_act[1] - (int32_t) ptr_ref[1]) > tolerance || + LV_ABS((int32_t) ptr_act[2] - (int32_t) ptr_ref[2]) > tolerance) { + uint32_t act_px = (ptr_act[2] << 16) + (ptr_act[1] << 8) + (ptr_act[0] << 0); + uint32_t ref_px = 0; + memcpy(&ref_px, ptr_ref, 3); + LV_LOG("\nScreenshot compare error\n" + " - File: %s\n" + " - At x:%d, y:%d.\n" + " - Expected: %X\n" + " - Actual: %X\n" + " - Tolerance: %d\n", + fn_ref_full, x, y, ref_px, act_px, tolerance); + err = true; + break; + } + } + if(err) break; + } + + if(err) { + char fn_ref_no_ext[128]; + lv_strlcpy(fn_ref_no_ext, fn_ref, sizeof(fn_ref_no_ext)); + fn_ref_no_ext[strlen(fn_ref_no_ext) - 4] = '\0'; + + char fn_err_full[256]; + lv_snprintf(fn_err_full, sizeof(fn_err_full), "%s%s_err.png", REF_IMGS_PATH, fn_ref_no_ext); + + write_png_file(screen_buf_xrgb8888, draw_buf->header.w, draw_buf->header.h, fn_err_full); + } + + fflush(stdout); + lv_free(screen_buf_xrgb8888); + lv_draw_buf_destroy(ref_draw_buf); + return !err; + +} + +static unsigned read_png_file(lv_draw_buf_t ** refr_draw_buf, unsigned * width, unsigned * height, + const char * file_name) +{ + unsigned error = lodepng_decode32_file((void *)refr_draw_buf, width, height, file_name); + if(error) LV_LOG_WARN("error %u: %s\n", error, lodepng_error_text(error)); + return error; +} + +static unsigned write_png_file(void * raw_img, uint32_t width, uint32_t height, char * file_name) +{ + unsigned error = lodepng_encode32_file(file_name, raw_img, width, height); + if(error) LV_LOG_WARN("error %u: %s\n", error, lodepng_error_text(error)); + return error; +} + +static void buf_to_xrgb8888(const lv_draw_buf_t * draw_buf, uint8_t * buf_out) +{ + uint32_t stride = draw_buf->header.stride; + lv_color_format_t cf_in = draw_buf->header.cf; + const uint8_t * buf_in = draw_buf->data; + + if(cf_in == LV_COLOR_FORMAT_RGB565 || cf_in == LV_COLOR_FORMAT_RGB565_SWAPPED) { + if(cf_in == LV_COLOR_FORMAT_RGB565_SWAPPED) { + lv_draw_sw_rgb565_swap(draw_buf->data, draw_buf->header.w * draw_buf->header.h); + } + uint32_t y; + for(y = 0; y < draw_buf->header.h; y++) { + + uint32_t x; + for(x = 0; x < draw_buf->header.w; x++) { + const lv_color16_t * c16 = (const lv_color16_t *)&buf_in[x * 2]; + + buf_out[x * 4 + 3] = 0xff; + buf_out[x * 4 + 2] = (c16->blue * 2106) >> 8; /*To make it rounded*/ + buf_out[x * 4 + 1] = (c16->green * 1037) >> 8; + buf_out[x * 4 + 0] = (c16->red * 2106) >> 8; + } + + buf_in += stride; + buf_out += draw_buf->header.w * 4; + } + } + else if(cf_in == LV_COLOR_FORMAT_ARGB8888 || cf_in == LV_COLOR_FORMAT_XRGB8888 || + cf_in == LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED) { + uint32_t y; + for(y = 0; y < draw_buf->header.h; y++) { + uint32_t x; + for(x = 0; x < draw_buf->header.w; x++) { + buf_out[x * 4 + 3] = buf_in[x * 4 + 3]; + buf_out[x * 4 + 2] = buf_in[x * 4 + 0]; + buf_out[x * 4 + 1] = buf_in[x * 4 + 1]; + buf_out[x * 4 + 0] = buf_in[x * 4 + 2]; + } + + buf_in += stride; + buf_out += draw_buf->header.w * 4; + } + } + else if(cf_in == LV_COLOR_FORMAT_RGB888) { + uint32_t y; + for(y = 0; y < draw_buf->header.h; y++) { + uint32_t x; + for(x = 0; x < draw_buf->header.w; x++) { + buf_out[x * 4 + 3] = 0xff; + buf_out[x * 4 + 2] = buf_in[x * 3 + 0]; + buf_out[x * 4 + 1] = buf_in[x * 3 + 1]; + buf_out[x * 4 + 0] = buf_in[x * 3 + 2]; + } + + buf_in += stride; + buf_out += draw_buf->header.w * 4; + } + } + else if(cf_in == LV_COLOR_FORMAT_L8) { + uint32_t y; + for(y = 0; y < draw_buf->header.h; y++) { + uint32_t x; + for(x = 0; x < draw_buf->header.w; x++) { + buf_out[x * 4 + 3] = 0xff; + buf_out[x * 4 + 2] = buf_in[x]; + buf_out[x * 4 + 1] = buf_in[x]; + buf_out[x * 4 + 0] = buf_in[x]; + } + + buf_in += stride; + buf_out += draw_buf->header.w * 4; + } + } + else if(cf_in == LV_COLOR_FORMAT_AL88) { + uint32_t y; + for(y = 0; y < draw_buf->header.h; y++) { + uint32_t x; + for(x = 0; x < draw_buf->header.w; x++) { + buf_out[x * 4 + 3] = buf_in[x * 2 + 1]; + buf_out[x * 4 + 2] = buf_in[x * 2 + 0]; + buf_out[x * 4 + 1] = buf_in[x * 2 + 0]; + buf_out[x * 4 + 0] = buf_in[x * 2 + 0]; + } + + buf_in += stride; + buf_out += draw_buf->header.w * 4; + } + } + else if(cf_in == LV_COLOR_FORMAT_I1) { + buf_in += 8; + uint32_t y; + for(y = 0; y < draw_buf->header.h; y++) { + uint32_t x; + for(x = 0; x < draw_buf->header.w; x++) { + const uint8_t byte = buf_in[x / 8] ; + const uint8_t bit_pos = x % 8; + const uint8_t pixel = (byte >> (7 - bit_pos)) & 0x01; + + buf_out[x * 4 + 3] = 0xff; + buf_out[x * 4 + 2] = pixel ? 0xff : 0x00; + buf_out[x * 4 + 1] = pixel ? 0xff : 0x00; + buf_out[x * 4 + 0] = pixel ? 0xff : 0x00; + } + + buf_in += stride; + buf_out += draw_buf->header.w * 4; + } + } +} + +static void create_folders_if_needed(const char * path) +{ + char * ptr; + char * path_copy = lv_strdup(path); + if(path_copy == NULL) { + LV_LOG_ERROR("Error duplicating path"); + exit(EXIT_FAILURE); + } + + char * token = strtok_r(path_copy, "/", &ptr); + char current_path[1024] = {'\0'}; /* Adjust the size as needed */ + + while(token && ptr && *ptr != '\0') { + lv_strcat(current_path, token); + lv_strcat(current_path, "/"); + + int mkdir_retval = mkdir(current_path, 0777); + if(mkdir_retval == 0) { + LV_LOG_INFO("Created folder: %s\n", current_path); + } + else if(errno != EEXIST) { + perror("Error creating folder"); + lv_free(path_copy); + exit(EXIT_FAILURE); + } + + token = strtok_r(NULL, "/", &ptr); + } + + lv_free(path_copy); +} + +#endif diff --git a/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_screenshot_compare.h b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_screenshot_compare.h new file mode 100644 index 000000000..b962becef --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/test/lv_test_screenshot_compare.h @@ -0,0 +1,53 @@ +/** + * @file lv_test_screenshot_compare.h + * + */ + +#ifndef LV_TEST_SCREENSHOT_COMPARE_H +#define LV_TEST_SCREENSHOT_COMPARE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_TEST && defined(LV_USE_TEST_SCREENSHOT_COMPARE) && LV_USE_TEST_SCREENSHOT_COMPARE + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Compare the current content of the test screen with a reference PNG image + * - If the reference image is not found it will be created automatically from the rendered screen. + * - If the compare fails an `_err.png` file will be created with the rendered content next to the reference image. + * + * It requires libPNG. + * + * @param fn_ref path to the reference image. Will be appended toREF_IMGS_PATH if set. + * @return true: the reference image and the display are the same; false: they are different (`_err.png` is created). + */ +bool lv_test_screenshot_compare(const char * fn_ref); + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_TEST_SCREENSHOT_COMPARE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TEST_SCREENSHOT_COMPARE_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 abbd6e86a..25c332819 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 @@ -168,7 +168,7 @@ typedef unsigned int vg_lite_color_t; VG_LITE_SUCCESS = 0, /*! Success. */ VG_LITE_INVALID_ARGUMENT, /*! An invalid argument was specified. */ VG_LITE_OUT_OF_MEMORY, /*! Out of memory. */ - VG_LITE_NO_CONTEXT, /*! No context or an unintialized context specified. */ + VG_LITE_NO_CONTEXT, /*! No context or an uninitialized context specified. */ VG_LITE_TIMEOUT, /*! A timeout has occurred during a wait. */ VG_LITE_OUT_OF_RESOURCES, /*! Out of system resources. */ VG_LITE_GENERIC_IO, /*! Cannot communicate with the kernel driver. */ @@ -996,7 +996,7 @@ typedef unsigned int vg_lite_color_t; /* Get the value of register from register's address. */ vg_lite_error_t vg_lite_get_register(vg_lite_uint32_t address, vg_lite_uint32_t* result); - /* Generate a 3x3 homogenous matrix to transform 4 source coordinates to 4 target coordinates. */ + /* Generate a 3x3 homogeneous matrix to transform 4 source coordinates to 4 target coordinates. */ vg_lite_error_t vg_lite_get_transform_matrix(vg_lite_point4_t src, vg_lite_point4_t dst, vg_lite_matrix_t *mat); /* Allocate a buffer from GPU hardware accessible memory. */ 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 28338be96..8e2f4f42a 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 @@ -119,6 +119,27 @@ typedef struct { uint8_t alpha; } vg_color32_t; +typedef struct { + uint8_t blue : 4; + uint8_t green : 4; + uint8_t red : 4; + uint8_t alpha : 4; +} vg_color_bgra4444_t; + +typedef struct { + uint8_t blue : 2; + uint8_t green : 2; + uint8_t red : 2; + uint8_t alpha : 2; +} vg_color_bgra2222_t; + +typedef struct { + uint8_t blue : 5; + uint8_t green : 5; + uint8_t red : 5; + uint8_t alpha : 1; +} vg_color_bgra5551_t; + typedef struct { vg_lite_float_t x; vg_lite_float_t y; @@ -131,14 +152,20 @@ class vg_lite_ctx public: std::unique_ptr canvas; void * target_buffer; + void * tvg_target_buffer; vg_lite_uint32_t target_px_size; vg_lite_buffer_format_t target_format; + vg_lite_rectangle_t scissor_rect; + bool scissor_is_set; public: vg_lite_ctx() : target_buffer { nullptr } + , tvg_target_buffer { nullptr } , target_px_size { 0 } , target_format { VG_LITE_BGRA8888 } + , scissor_rect { 0, 0, 0, 0 } + , scissor_is_set { false } , clut_2colors { 0 } , clut_4colors { 0 } , clut_16colors { 0 } @@ -422,6 +449,58 @@ static vg_lite_converter conv_alpha4_to_bgra8888( } }); +static vg_lite_converter conv_l8_to_bgra8888( + [](vg_color32_t * dest, const uint8_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) +{ + while(px_size--) { + dest->alpha = 0xFF; + dest->red = *src; + dest->green = *src; + dest->blue = *src; + dest++; + src++; + } +}); + +static vg_lite_converter conv_bgra5551_to_bgra8888( + [](vg_color32_t * dest, const vg_color_bgra5551_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) +{ + while(px_size--) { + dest->red = src->red * 0xFF / 0x1F; + dest->green = src->green * 0xFF / 0x1F; + dest->blue = src->blue * 0xFF / 0x1F; + dest->alpha = src->alpha ? 0xFF : 0; + src++; + dest++; + } +}); + +static vg_lite_converter conv_bgra4444_to_bgra8888( + [](vg_color32_t * dest, const vg_color_bgra4444_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) +{ + while(px_size--) { + dest->red = src->red * 0xFF / 0xF; + dest->green = src->green * 0xFF / 0xF; + dest->blue = src->blue * 0xFF / 0xF; + dest->alpha = src->alpha * 0xFF / 0xF; + src++; + dest++; + } +}); + +static vg_lite_converter conv_bgra2222_to_bgra8888( + [](vg_color32_t * dest, const vg_color_bgra2222_t * src, vg_lite_uint32_t px_size, vg_lite_uint32_t /* color */) +{ + while(px_size--) { + dest->red = src->red * 0xFF / 0x3; + dest->green = src->green * 0xFF / 0x3; + dest->blue = src->blue * 0xFF / 0x3; + dest->alpha = src->alpha * 0xFF / 0x3; + src++; + dest++; + } +}); + /********************** * MACROS **********************/ @@ -649,6 +728,61 @@ extern "C" { } } + static void picture_bgra8888_to_l8(uint8_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size) + { + while(px_size--) { + *dest = (src->red * 19595 + src->green * 38469 + src->blue * 7472) >> 16; + src++; + dest++; + } + } + + static void picture_bgra8888_to_alpha8(uint8_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size) + { + while(px_size--) { + *dest = src->alpha; + src++; + dest++; + } + } + + static void picture_bgra8888_to_bgra5551(vg_color_bgra5551_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size) + { + while(px_size--) { + dest->red = src->red * 0x1F / 0xFF; + dest->green = src->green * 0x1F / 0xFF; + dest->blue = src->blue * 0x1F / 0xFF; + dest->alpha = src->alpha > (0xFF / 2) ? 1 : 0; + src++; + dest++; + } + } + + static void picture_bgra8888_to_bgra4444(vg_color_bgra4444_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size) + { + while(px_size--) { + dest->red = src->red * 0xF / 0xFF; + dest->green = src->green * 0xF / 0xFF; + dest->blue = src->blue * 0xF / 0xFF; + dest->alpha = src->alpha * 0xF / 0xFF; + src++; + dest++; + } + } + + static void picture_bgra8888_to_bgra2222(vg_color_bgra2222_t * dest, const vg_color32_t * src, vg_lite_uint32_t px_size) + { + while(px_size--) { + dest->red = src->red * 0x3 / 0xFF; + dest->green = src->green * 0x3 / 0xFF; + dest->blue = src->blue * 0x3 / 0xFF; + dest->alpha = src->alpha * 0x3 / 0xFF; + src++; + dest++; + } + } + + vg_lite_error_t vg_lite_finish(void) { vg_lite_ctx * ctx = vg_lite_ctx::get_instance(); @@ -683,6 +817,33 @@ extern "C" { (const vg_color32_t *)ctx->get_temp_target_buffer(), ctx->target_px_size); break; + case VG_LITE_L8: + picture_bgra8888_to_l8( + (uint8_t *)ctx->target_buffer, + (const vg_color32_t *)ctx->get_temp_target_buffer(), + ctx->target_px_size); + break; + case VG_LITE_A8: + picture_bgra8888_to_alpha8( + (uint8_t *)ctx->target_buffer, + (const vg_color32_t *)ctx->get_temp_target_buffer(), + ctx->target_px_size); + break; + case VG_LITE_BGRA5551: + picture_bgra8888_to_bgra5551((vg_color_bgra5551_t *)ctx->target_buffer, + (const vg_color32_t *)ctx->get_temp_target_buffer(), + ctx->target_px_size); + break; + case VG_LITE_BGRA4444: + picture_bgra8888_to_bgra4444((vg_color_bgra4444_t *)ctx->target_buffer, + (const vg_color32_t *)ctx->get_temp_target_buffer(), + ctx->target_px_size); + break; + case VG_LITE_BGRA2222: + picture_bgra8888_to_bgra2222((vg_color_bgra2222_t *)ctx->target_buffer, + (const vg_color32_t *)ctx->get_temp_target_buffer(), + ctx->target_px_size); + break; case VG_LITE_BGRA8888: case VG_LITE_BGRX8888: /* No conversion required. */ @@ -695,6 +856,7 @@ extern "C" { /* finish convert, clean target buffer info */ ctx->target_buffer = nullptr; + ctx->tvg_target_buffer = nullptr; ctx->target_px_size = 0; return VG_LITE_SUCCESS; @@ -823,6 +985,7 @@ extern "C" { case gcFEATURE_BIT_VG_USE_DST: case gcFEATURE_BIT_VG_RADIAL_GRADIENT: case gcFEATURE_BIT_VG_IM_REPEAT_REFLECT: + case gcFEATURE_BIT_VG_SCISSOR: #if LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT case gcFEATURE_BIT_VG_LVGL_SUPPORT: @@ -1839,29 +2002,47 @@ Empty_sequence_handler: return VG_LITE_NOT_SUPPORT; } - vg_lite_error_t vg_lite_set_scissor(int32_t x, int32_t y, int32_t right, int32_t bottom) + vg_lite_error_t vg_lite_set_scissor(vg_lite_int32_t x, vg_lite_int32_t y, vg_lite_int32_t right, vg_lite_int32_t bottom) { - LV_UNUSED(x); - LV_UNUSED(y); - LV_UNUSED(right); - LV_UNUSED(bottom); - return VG_LITE_NOT_SUPPORT; + auto ctx = vg_lite_ctx::get_instance(); + vg_lite_int32_t width = right - x; + vg_lite_int32_t height = bottom - y; + + if(width <= 0 || height <= 0) { + return VG_LITE_INVALID_ARGUMENT; + } + + if(ctx->scissor_rect.x == x && ctx->scissor_rect.y == y && + ctx->scissor_rect.width == width && ctx->scissor_rect.height == height) { + return VG_LITE_SUCCESS; + } + + /*Finish the previous rendering before setting the new scissor*/ + vg_lite_error_t error; + VG_LITE_RETURN_ERROR(vg_lite_finish()); + + ctx->scissor_rect.x = x; + ctx->scissor_rect.y = y; + ctx->scissor_rect.width = width; + ctx->scissor_rect.height = height; + ctx->scissor_is_set = true; + return VG_LITE_SUCCESS; } vg_lite_error_t vg_lite_enable_scissor(void) { - return VG_LITE_NOT_SUPPORT; + return VG_LITE_SUCCESS; } vg_lite_error_t vg_lite_disable_scissor(void) { - return VG_LITE_NOT_SUPPORT; + return VG_LITE_SUCCESS; } vg_lite_error_t vg_lite_get_mem_size(vg_lite_uint32_t * size) { *size = 0; - return VG_LITE_NOT_SUPPORT; + return VG_LITE_SUCCESS; } vg_lite_error_t vg_lite_source_global_alpha(vg_lite_global_alpha_t alpha_mode, uint8_t alpha_value) @@ -1960,6 +2141,13 @@ Empty_sequence_handler: return VG_LITE_NOT_SUPPORT; } + + vg_lite_error_t vg_lite_dump_command_buffer(void) + { + LV_LOG_USER("command:"); + LV_LOG_USER("@[commit]"); + return VG_LITE_SUCCESS; + } } /* extern "C" */ /********************** @@ -2255,6 +2443,8 @@ static Result shape_append_path(std::unique_ptr & shape, vg_lite_path_t * cur += arg_len * fmt_len; } + TVG_CHECK_RETURN_RESULT(shape_set_stroke(shape, path)); + float x_min = path->bounding_box[0]; float y_min = path->bounding_box[1]; float x_max = path->bounding_box[2]; @@ -2265,8 +2455,6 @@ static Result shape_append_path(std::unique_ptr & shape, vg_lite_path_t * return Result::Success; } - TVG_CHECK_RETURN_RESULT(shape_set_stroke(shape, path)); - auto cilp = Shape::gen(); TVG_CHECK_RETURN_RESULT(cilp->appendRect(x_min, y_min, x_max - x_min, y_max - y_min, 0, 0)); TVG_CHECK_RETURN_RESULT(cilp->transform(matrix_conv(matrix))); @@ -2293,8 +2481,6 @@ static Result shape_append_rect(std::unique_ptr & shape, const vg_lite_bu static Result canvas_set_target(vg_lite_ctx * ctx, vg_lite_buffer_t * target) { - void * tvg_target_buffer = nullptr; - /* if target_buffer needs to be changed, finish current drawing */ if(ctx->target_buffer && ctx->target_buffer != target->memory) { vg_lite_finish(); @@ -2304,23 +2490,38 @@ static Result canvas_set_target(vg_lite_ctx * ctx, vg_lite_buffer_t * target) ctx->target_format = target->format; ctx->target_px_size = target->width * target->height; + void * canvas_target_buffer; if(TVG_IS_VG_FMT_SUPPORT(target->format)) { /* if target format is supported by VG, use target buffer directly */ - tvg_target_buffer = target->memory; + canvas_target_buffer = target->memory; } else { /* if target format is not supported by VG, use internal buffer */ - tvg_target_buffer = ctx->get_temp_target_buffer(target->width, target->height); + canvas_target_buffer = ctx->get_temp_target_buffer(target->width, target->height); } - Result res = ctx->canvas->target( - (uint32_t *)tvg_target_buffer, - target->width, - target->width, - target->height, - SwCanvas::ARGB8888); + /* Prevent repeated target setting */ + if(ctx->tvg_target_buffer == canvas_target_buffer) { + return Result::Success; + } - return res; + ctx->tvg_target_buffer = canvas_target_buffer; + + TVG_CHECK_RETURN_RESULT(ctx->canvas->target( + (uint32_t *)ctx->tvg_target_buffer, + target->width, + target->width, + target->height, + SwCanvas::ARGB8888)); + + if(ctx->scissor_is_set) { + TVG_CHECK_RETURN_RESULT( + ctx->canvas->viewport( + ctx->scissor_rect.x, ctx->scissor_rect.y, + ctx->scissor_rect.width, ctx->scissor_rect.height)); + } + + return Result::Success; } static vg_lite_uint32_t width_to_stride(vg_lite_uint32_t w, vg_lite_buffer_format_t color_format) @@ -2440,6 +2641,11 @@ static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr & picture } break; + case VG_LITE_L8: { + conv_l8_to_bgra8888.convert(&target, source); + } + break; + case VG_LITE_BGRX8888: { conv_bgrx8888_to_bgra8888.convert(&target, source); } @@ -2460,6 +2666,21 @@ static Result picture_load(vg_lite_ctx * ctx, std::unique_ptr & picture } break; + case VG_LITE_BGRA5551: { + conv_bgra5551_to_bgra8888.convert(&target, source); + } + break; + + case VG_LITE_BGRA4444: { + conv_bgra4444_to_bgra8888.convert(&target, source); + } + break; + + case VG_LITE_BGRA2222: { + conv_bgra2222_to_bgra8888.convert(&target, source); + } + break; + #if LV_VG_LITE_THORVG_YUV_SUPPORT case VG_LITE_NV12: { libyuv::NV12ToARGB((const uint8_t *)source->memory, source->stride, (const uint8_t *)source->yuv.uv_memory, diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml.c b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml.c new file mode 100644 index 000000000..87a0cdf4d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml.c @@ -0,0 +1,642 @@ +/** + * @file lv_xml.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_xml.h" +#if LV_USE_XML + +#include "lv_xml_base_types.h" +#include "lv_xml_parser.h" +#include "lv_xml_component.h" +#include "lv_xml_component_private.h" +#include "lv_xml_widget.h" +#include "lv_xml_style.h" +#include "lv_xml.h" +#include "lv_xml_utils.h" +#include "lv_xml_private.h" +#include "parsers/lv_xml_obj_parser.h" +#include "parsers/lv_xml_button_parser.h" +#include "parsers/lv_xml_label_parser.h" +#include "parsers/lv_xml_image_parser.h" +#include "parsers/lv_xml_bar_parser.h" +#include "parsers/lv_xml_slider_parser.h" +#include "parsers/lv_xml_tabview_parser.h" +#include "parsers/lv_xml_chart_parser.h" +#include "parsers/lv_xml_table_parser.h" +#include "parsers/lv_xml_dropdown_parser.h" +#include "parsers/lv_xml_roller_parser.h" +#include "parsers/lv_xml_scale_parser.h" +#include "parsers/lv_xml_buttonmatrix_parser.h" +#include "parsers/lv_xml_spangroup_parser.h" +#include "parsers/lv_xml_textarea_parser.h" +#include "parsers/lv_xml_keyboard_parser.h" +#include "parsers/lv_xml_arc_parser.h" +#include "parsers/lv_xml_checkbox_parser.h" +#include "parsers/lv_xml_canvas_parser.h" +#include "parsers/lv_xml_calendar_parser.h" +#include "parsers/lv_xml_event_parser.h" +#include "../../libs/expat/expat.h" +#include "../../draw/lv_draw_image.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void view_start_element_handler(void * user_data, const char * name, const char ** attrs); +static void view_end_element_handler(void * user_data, const char * name); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_xml_init(void) +{ + lv_xml_component_init(); + + lv_xml_register_font(NULL, "lv_font_default", lv_font_get_default()); + + lv_xml_widget_register("lv_obj", lv_xml_obj_create, lv_xml_obj_apply); + lv_xml_widget_register("lv_button", lv_xml_button_create, lv_xml_button_apply); + lv_xml_widget_register("lv_label", lv_xml_label_create, lv_xml_label_apply); + lv_xml_widget_register("lv_image", lv_xml_image_create, lv_xml_image_apply); + lv_xml_widget_register("lv_bar", lv_xml_bar_create, lv_xml_bar_apply); + lv_xml_widget_register("lv_slider", lv_xml_slider_create, lv_xml_slider_apply); + lv_xml_widget_register("lv_tabview", lv_xml_tabview_create, lv_xml_tabview_apply); + lv_xml_widget_register("lv_tabview-tab_bar", lv_xml_tabview_tab_bar_create, lv_xml_tabview_tab_bar_apply); + lv_xml_widget_register("lv_tabview-tab", lv_xml_tabview_tab_create, lv_xml_tabview_tab_apply); + lv_xml_widget_register("lv_chart", lv_xml_chart_create, lv_xml_chart_apply); + lv_xml_widget_register("lv_chart-cursor", lv_xml_chart_cursor_create, lv_xml_chart_cursor_apply); + lv_xml_widget_register("lv_chart-series", lv_xml_chart_series_create, lv_xml_chart_series_apply); + lv_xml_widget_register("lv_chart-axis", lv_xml_chart_axis_create, lv_xml_chart_axis_apply); + lv_xml_widget_register("lv_table", lv_xml_table_create, lv_xml_table_apply); + lv_xml_widget_register("lv_table-column", lv_xml_table_column_create, lv_xml_table_column_apply); + lv_xml_widget_register("lv_table-cell", lv_xml_table_cell_create, lv_xml_table_cell_apply); + lv_xml_widget_register("lv_dropdown", lv_xml_dropdown_create, lv_xml_dropdown_apply); + lv_xml_widget_register("lv_dropdown-list", lv_xml_dropdown_list_create, lv_xml_dropdown_list_apply); + lv_xml_widget_register("lv_roller", lv_xml_roller_create, lv_xml_roller_apply); + lv_xml_widget_register("lv_scale", lv_xml_scale_create, lv_xml_scale_apply); + lv_xml_widget_register("lv_scale-section", lv_xml_scale_section_create, lv_xml_scale_section_apply); + lv_xml_widget_register("lv_spangroup", lv_xml_spangroup_create, lv_xml_spangroup_apply); + lv_xml_widget_register("lv_spangroup-span", lv_xml_spangroup_span_create, lv_xml_spangroup_span_apply); + lv_xml_widget_register("lv_buttonmatrix", lv_xml_buttonmatrix_create, lv_xml_buttonmatrix_apply); + lv_xml_widget_register("lv_textarea", lv_xml_textarea_create, lv_xml_textarea_apply); + lv_xml_widget_register("lv_keyboard", lv_xml_keyboard_create, lv_xml_keyboard_apply); + lv_xml_widget_register("lv_arc", lv_xml_arc_create, lv_xml_arc_apply); + lv_xml_widget_register("lv_checkbox", lv_xml_checkbox_create, lv_xml_checkbox_apply); + lv_xml_widget_register("lv_canvas", lv_xml_canvas_create, lv_xml_canvas_apply); + lv_xml_widget_register("lv_calendar", lv_xml_calendar_create, lv_xml_calendar_apply); + lv_xml_widget_register("lv_calendar-header_arrow", lv_xml_calendar_header_arrow_create, + lv_xml_calendar_header_arrow_apply); + lv_xml_widget_register("lv_calendar-header_dropdown", lv_xml_calendar_header_dropdown_create, + lv_xml_calendar_header_dropdown_apply); + + lv_xml_widget_register("lv_event-call_function", lv_xml_event_call_function_create, lv_xml_event_call_function_apply); +} + +void * lv_xml_create_in_scope(lv_obj_t * parent, lv_xml_component_scope_t * parent_scope, + lv_xml_component_scope_t * scope, + const char ** attrs) +{ + /* Initialize the parser state */ + lv_xml_parser_state_t state; + lv_xml_parser_state_init(&state); + state.scope = *scope; /*Scope won't be modified here, so it's safe to copy it by value*/ + state.parent = parent; + state.parent_attrs = attrs; + state.parent_scope = parent_scope; + + lv_obj_t ** parent_node = lv_ll_ins_head(&state.parent_ll); + *parent_node = parent; + + /* Create an XML parser and set handlers */ + XML_Memory_Handling_Suite mem_handlers; + mem_handlers.malloc_fcn = lv_malloc; + mem_handlers.realloc_fcn = lv_realloc; + mem_handlers.free_fcn = lv_free; + XML_Parser parser = XML_ParserCreate_MM(NULL, &mem_handlers, NULL); + XML_SetUserData(parser, &state); + XML_SetElementHandler(parser, view_start_element_handler, view_end_element_handler); + + /* Parse the XML */ + if(XML_Parse(parser, scope->view_def, lv_strlen(scope->view_def), XML_TRUE) == XML_STATUS_ERROR) { + LV_LOG_WARN("XML parsing error: %s on line %lu", XML_ErrorString(XML_GetErrorCode(parser)), + XML_GetCurrentLineNumber(parser)); + XML_ParserFree(parser); + return NULL; + } + + state.item = state.view; + +#if LV_USE_OBJ_NAME + /*Set a default indexed name*/ + if(state.item && lv_obj_get_name(state.item) == NULL) { + char name_buf[128]; + lv_snprintf(name_buf, sizeof(name_buf), "%s_#", scope->name); + lv_obj_set_name(state.item, name_buf); + } +#endif + + lv_ll_clear(&state.parent_ll); + XML_ParserFree(parser); + + return state.view; +} + +void * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs) +{ + lv_obj_t * item = NULL; + + /* Select the widget specific parser type based on the name */ + lv_widget_processor_t * p = lv_xml_widget_get_processor(name); + if(p) { + lv_xml_parser_state_t state; + lv_xml_parser_state_init(&state); + state.parent = parent; + + /* When a component is just created there is no scope where + * its styles, constants, etc are stored. + * So leave state.scope = NULL which means the global context.*/ + + state.item = p->create_cb(&state, attrs); + if(attrs) { + p->apply_cb(&state, attrs); + } + return state.item; + } + + lv_xml_component_scope_t * scope = lv_xml_component_get_scope(name); + if(scope) { + item = lv_xml_create_in_scope(parent, NULL, scope, attrs); + + if(attrs) { + lv_xml_parser_state_t state; + lv_xml_parser_state_init(&state); + state.parent = parent; + state.item = item; + + /* When a component is just created there is no scope where + * its styles, constants, etc are stored. + * So leave state.scope = NULL which means the global context.*/ + + p = lv_xml_widget_get_extended_widget_processor(scope->extends); + p->apply_cb(&state, attrs); + } + + return item; + } + + /* If it isn't a component either then it is unknown */ + LV_LOG_WARN("'%s' is not a known widget, element, or component", name); + return NULL; +} + +lv_result_t lv_xml_register_font(lv_xml_component_scope_t * scope, const char * name, const lv_font_t * font) +{ + + if(scope == NULL) scope = lv_xml_component_get_scope("globals"); + if(scope == NULL) { + LV_LOG_WARN("No component found to register font `%s`", name); + return LV_RESULT_INVALID; + } + + lv_xml_font_t * f; + LV_LL_READ(&scope->font_ll, f) { + if(lv_streq(f->name, name)) { + LV_LOG_INFO("Font %s is already registered. Don't register it again.", name); + return LV_RESULT_OK; + } + } + + f = lv_ll_ins_head(&scope->font_ll); + f->name = lv_strdup(name); + f->font = font; + + return LV_RESULT_OK; +} + +const lv_font_t * lv_xml_get_font(lv_xml_component_scope_t * scope, const char * name) +{ + lv_xml_font_t * f; + if(scope) { + LV_LL_READ(&scope->font_ll, f) { + if(lv_streq(f->name, name)) return f->font; + } + } + + /*If not found in the component check the global space*/ + if((scope == NULL || scope->name == NULL) || !lv_streq(scope->name, "globals")) { + scope = lv_xml_component_get_scope("globals"); + if(scope) { + LV_LL_READ(&scope->font_ll, f) { + if(lv_streq(f->name, name)) return f->font; + } + } + } + + LV_LOG_WARN("No font was found with name \"%s\". Using LV_FONT_DEFAULT instead.", name); + return lv_font_get_default(); +} + +lv_result_t lv_xml_register_subject(lv_xml_component_scope_t * scope, const char * name, lv_subject_t * subject) +{ + if(scope == NULL) scope = lv_xml_component_get_scope("globals"); + if(scope == NULL) { + LV_LOG_WARN("No component found to register subject `%s`", name); + return LV_RESULT_INVALID; + } + + + lv_xml_subject_t * s; + LV_LL_READ(&scope->subjects_ll, s) { + if(lv_streq(s->name, name)) { + LV_LOG_INFO("Subject %s is already registered. Don't register it again.", name); + return LV_RESULT_OK; + } + } + + s = lv_ll_ins_head(&scope->subjects_ll); + s->name = lv_strdup(name); + s->subject = subject; + + return LV_RESULT_OK; +} + +lv_subject_t * lv_xml_get_subject(lv_xml_component_scope_t * scope, const char * name) +{ + lv_xml_subject_t * s; + if(scope) { + LV_LL_READ(&scope->subjects_ll, s) { + if(lv_streq(s->name, name)) return s->subject; + } + } + + /*If not found in the component check the global space*/ + if((scope == NULL || scope->name == NULL) || !lv_streq(scope->name, "globals")) { + scope = lv_xml_component_get_scope("globals"); + if(scope) { + LV_LL_READ(&scope->subjects_ll, s) { + if(lv_streq(s->name, name)) return s->subject; + } + } + } + + LV_LOG_WARN("No subject was found with name \"%s\".", name); + return NULL; +} + +lv_result_t lv_xml_register_const(lv_xml_component_scope_t * scope, const char * name, const char * value) +{ + if(scope == NULL) scope = lv_xml_component_get_scope("globals"); + if(scope == NULL) { + LV_LOG_WARN("No component found to register constant `%s`", name); + return LV_RESULT_INVALID; + } + + lv_xml_const_t * cnst; + LV_LL_READ(&scope->const_ll, cnst) { + if(lv_streq(cnst->name, name)) { + LV_LOG_INFO("Const %s is already registered. Don't register it again.", name); + return LV_RESULT_OK; + } + } + + cnst = lv_ll_ins_head(&scope->const_ll); + + cnst->name = lv_strdup(name); + cnst->value = lv_strdup(value); + + return LV_RESULT_OK; +} + +const char * lv_xml_get_const(lv_xml_component_scope_t * scope, const char * name) +{ + + if(scope == NULL) scope = lv_xml_component_get_scope("globals"); + if(scope == NULL) return NULL; + + lv_xml_const_t * cnst; + if(scope) { + LV_LL_READ(&scope->const_ll, cnst) { + if(lv_streq(cnst->name, name)) return cnst->value; + } + } + + /*If not found in the component check the global space*/ + if((scope == NULL || scope->name == NULL) || !lv_streq(scope->name, "globals")) { + scope = lv_xml_component_get_scope("globals"); + if(scope) { + LV_LL_READ(&scope->const_ll, cnst) { + if(lv_streq(cnst->name, name)) return cnst->value; + } + } + } + + LV_LOG_WARN("No constant was found with name \"%s\".", name); + return NULL; +} + + +lv_result_t lv_xml_register_image(lv_xml_component_scope_t * scope, const char * name, const void * src) +{ + if(scope == NULL) scope = lv_xml_component_get_scope("globals"); + if(scope == NULL) { + LV_LOG_WARN("No component found to register image `%s`", name); + return LV_RESULT_INVALID; + } + + lv_xml_image_t * img; + LV_LL_READ(&scope->image_ll, img) { + if(lv_streq(img->name, name)) { + LV_LOG_INFO("Image %s is already registered. Don't register it again.", name); + return LV_RESULT_OK; + } + } + + img = lv_ll_ins_head(&scope->image_ll); + img->name = lv_strdup(name); + if(lv_image_src_get_type(src) == LV_IMAGE_SRC_FILE) { + img->src = lv_strdup(src); + } + else { + img->src = src; + } + + return LV_RESULT_OK; +} + +const void * lv_xml_get_image(lv_xml_component_scope_t * scope, const char * name) +{ + if(scope == NULL) scope = lv_xml_component_get_scope("globals"); + if(scope == NULL) return NULL; + + lv_xml_image_t * img; + if(scope) { + LV_LL_READ(&scope->image_ll, img) { + if(lv_streq(img->name, name)) return img->src; + } + } + + /*If not found in the component check the global space*/ + if((scope == NULL || scope->name == NULL) || !lv_streq(scope->name, "globals")) { + scope = lv_xml_component_get_scope("globals"); + if(scope) { + LV_LL_READ(&scope->image_ll, img) { + if(lv_streq(img->name, name)) return img->src; + } + } + } + + LV_LOG_WARN("No image was found with name \"%s\"", name); + return NULL; +} + +lv_result_t lv_xml_register_event_cb(lv_xml_component_scope_t * scope, const char * name, lv_event_cb_t cb) +{ + if(scope == NULL) scope = lv_xml_component_get_scope("globals"); + if(scope == NULL) { + LV_LOG_WARN("No component found to register event `%s`", name); + return LV_RESULT_INVALID; + } + + lv_xml_event_cb_t * e; + LV_LL_READ(&scope->event_ll, e) { + if(lv_streq(e->name, name)) { + LV_LOG_INFO("Event_cb %s is already registered. Don't register it again.", name); + return LV_RESULT_OK; + } + } + + e = lv_ll_ins_head(&scope->event_ll); + e->name = lv_strdup(name); + e->cb = cb; + + return LV_RESULT_OK; +} + + +lv_event_cb_t lv_xml_get_event_cb(lv_xml_component_scope_t * scope, const char * name) +{ + if(scope == NULL) scope = lv_xml_component_get_scope("globals"); + if(scope == NULL) return NULL; + + lv_xml_event_cb_t * e; + if(scope) { + LV_LL_READ(&scope->event_ll, e) { + if(lv_streq(e->name, name)) return e->cb; + } + } + + /*If not found in the component check the global space*/ + if((scope == NULL || scope->name == NULL) || !lv_streq(scope->name, "globals")) { + scope = lv_xml_component_get_scope("globals"); + if(scope) { + LV_LL_READ(&scope->event_ll, e) { + if(lv_streq(e->name, name)) return e->cb; + } + } + } + + LV_LOG_WARN("No event was found with name \"%s\"", name); + return NULL; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static const char * get_param_type(lv_xml_component_scope_t * scope, const char * name) +{ + lv_xml_param_t * p; + LV_LL_READ(&scope->param_ll, p) { + if(lv_streq(p->name, name)) return p->type; + } + return NULL; +} + +static const char * get_param_default(lv_xml_component_scope_t * scope, const char * name) +{ + lv_xml_param_t * p; + LV_LL_READ(&scope->param_ll, p) { + if(lv_streq(p->name, name)) return p->def; + } + return NULL; +} + +static void resolve_params(lv_xml_component_scope_t * item_scope, lv_xml_component_scope_t * parent_scope, + const char ** item_attrs, const char ** parent_attrs) +{ + uint32_t i; + for(i = 0; item_attrs[i]; i += 2) { + const char * name = item_attrs[i]; + const char * value = item_attrs[i + 1]; + if(lv_streq(name, "styles")) continue; /*Styles will handle it themselves*/ + if(value[0] == '$') { + /*E.g. the ${my_color} value is the my_color attribute name on the parent*/ + const char * name_clean = &value[1]; /*skips `$`*/ + + const char * type = get_param_type(item_scope, name_clean); + if(type == NULL) { + LV_LOG_WARN("'%s' parameter is not defined on '%s'", name_clean, item_scope->name); + } + const char * ext_value = lv_xml_get_value_of(parent_attrs, name_clean); + if(ext_value) { + /*If the value is not resolved earlier (e.g. it's a top level element created manually) + * use the default value*/ + if(ext_value[0] == '#' || ext_value[0] == '$') { + ext_value = get_param_default(item_scope, name_clean); + } + else if(lv_streq(type, "style")) { + lv_xml_style_t * s = lv_xml_get_style_by_name(parent_scope, ext_value); + ext_value = s->long_name; + } + } + else { + /*If the API attribute is not provide don't set it*/ + ext_value = get_param_default(item_scope, name_clean); + } + if(ext_value) { + item_attrs[i + 1] = ext_value; + } + else { + /*Not set and no default value either + *Don't set this property*/ + item_attrs[i] = ""; + item_attrs[i + 1] = ""; + } + } + } +} + +static void resolve_consts(const char ** item_attrs, lv_xml_component_scope_t * scope) +{ + uint32_t i; + for(i = 0; item_attrs[i]; i += 2) { + const char * name = item_attrs[i]; + const char * value = item_attrs[i + 1]; + if(lv_streq(name, "styles")) continue; /*Styles will handle it themselves*/ + if(value[0] == '#') { + const char * value_clean = &value[1]; + + const char * const_value = lv_xml_get_const(scope, value_clean); + if(const_value) { + item_attrs[i + 1] = const_value; + } + /*If the const attribute is not provide don't set it*/ + else { + item_attrs[i] = ""; + item_attrs[i + 1] = ""; + } + } + } +} + +static void view_start_element_handler(void * user_data, const char * name, const char ** attrs) +{ + lv_xml_parser_state_t * state = (lv_xml_parser_state_t *)user_data; + bool is_view = false; + + if(lv_streq(name, "view")) { + const char * extends = lv_xml_get_value_of(attrs, "extends"); + name = extends ? extends : "lv_obj"; + is_view = true; + } + + lv_obj_t ** current_parent_p = lv_ll_get_tail(&state->parent_ll); + if(current_parent_p == NULL) { + if(state->parent == NULL) { + LV_LOG_ERROR("There is no parent object available for %s. This also should never happen.", name); + return; + } + else { + current_parent_p = &state->parent; + } + } + else { + state->parent = *current_parent_p; + } + + /*In `state->attrs` we have parameters of the component creation + *E.g. + *In `attrs` we have the attributes of child of the view. + *E.g. in `my_button` ` "text", "Hello" */ + resolve_params(&state->scope, state->parent_scope, attrs, state->parent_attrs); + + resolve_consts(attrs, &state->scope); + + void * item = NULL; + /* Select the widget specific parser type based on the name */ + lv_widget_processor_t * p = lv_xml_widget_get_processor(name); + if(p) { + item = p->create_cb(state, attrs); + state->item = item; + + + /*If it's a widget remove all styles. E.g. if it extends an `lv_button` + *now it has the button theme styles. However if it were a real widget + *it had e.g. `my_widget_class` so the button's theme wouldn't apply on it. + *Removing the style will ensure a better preview*/ + if(state->scope.is_widget && is_view) lv_obj_remove_style_all(item); + + /*Apply the attributes from e.g. ``*/ + if(item) { + p->apply_cb(state, attrs); + } + } + + /* If not a widget, check if it is a component */ + if(item == NULL) { + item = lv_xml_component_process(state, name, attrs); + state->item = item; + } + + /* If it isn't a component either then it is unknown */ + if(item == NULL) { + LV_LOG_WARN("'%s' is not a known widget, element, or component", name); + return; + } + + void ** new_parent = lv_ll_ins_tail(&state->parent_ll); + *new_parent = item; + + if(is_view) { + state->view = item; + } +} + +static void view_end_element_handler(void * user_data, const char * name) +{ + LV_UNUSED(name); + + lv_xml_parser_state_t * state = (lv_xml_parser_state_t *)user_data; + + lv_obj_t ** current_parent = lv_ll_get_tail(&state->parent_ll); + if(current_parent) { + lv_ll_remove(&state->parent_ll, current_parent); + lv_free(current_parent); + } +} + + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml.h b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml.h new file mode 100644 index 000000000..a26e3055a --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml.h @@ -0,0 +1,86 @@ +/** + * @file lv_xml.h + * + */ + +#ifndef LV_XML_H +#define LV_XML_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_types.h" +#include "../../misc/lv_event.h" +#include "../../others/observer/lv_observer.h" + +#if LV_USE_XML + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_xml_init(void); + +void * lv_xml_create(lv_obj_t * parent, const char * name, const char ** attrs); + +void * lv_xml_create_in_scope(lv_obj_t * parent, lv_xml_component_scope_t * parent_ctx, + lv_xml_component_scope_t * scope, + const char ** attrs); + +lv_result_t lv_xml_register_font(lv_xml_component_scope_t * scope, const char * name, const lv_font_t * font); + +const lv_font_t * lv_xml_get_font(lv_xml_component_scope_t * scope, const char * name); + +lv_result_t lv_xml_register_image(lv_xml_component_scope_t * scope, const char * name, const void * src); + +const void * lv_xml_get_image(lv_xml_component_scope_t * scope, const char * name); + +/** + * Map globally available subject name to an actual subject variable + * @param name name of the subject + * @param subject pointer to a subject + * @return `LV_RESULT_OK`: success + */ +lv_result_t lv_xml_register_subject(lv_xml_component_scope_t * scope, const char * name, lv_subject_t * subject); + +/** + * Get a subject by name. + * @param scope If specified start searching in that component's subject list, + * and if not found search in the global space. + * If `NULL` search in global space immediately. + * @param name Name of the subject to find. + * @return Pointer to the subject or NULL if not found. + */ +lv_subject_t * lv_xml_get_subject(lv_xml_component_scope_t * scope, const char * name); + +lv_result_t lv_xml_register_const(lv_xml_component_scope_t * scope, const char * name, const char * value); + +const char * lv_xml_get_const(lv_xml_component_scope_t * scope, const char * name); + +lv_result_t lv_xml_register_event_cb(lv_xml_component_scope_t * scope, const char * name, lv_event_cb_t cb); + +lv_event_cb_t lv_xml_get_event_cb(lv_xml_component_scope_t * scope, const char * name); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_base_types.c b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_base_types.c new file mode 100644 index 000000000..389a01e47 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_base_types.c @@ -0,0 +1,226 @@ +/** + * @file lv_xml_base_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../lvgl.h" +#if LV_USE_XML + +#include "lv_xml_base_types.h" +#include "lv_xml_private.h" +#include "lv_xml_parser.h" +#include "lv_xml_style.h" +#include "lv_xml_component_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_state_t lv_xml_state_to_enum(const char * txt) +{ + if(lv_streq("default", txt)) return LV_STATE_DEFAULT; + if(lv_streq("pressed", txt)) return LV_STATE_PRESSED; + if(lv_streq("checked", txt)) return LV_STATE_CHECKED; + if(lv_streq("hovered", txt)) return LV_STATE_HOVERED; + if(lv_streq("scrolled", txt)) return LV_STATE_SCROLLED; + if(lv_streq("disabled", txt)) return LV_STATE_DISABLED; + if(lv_streq("focused", txt)) return LV_STATE_FOCUSED; + if(lv_streq("focus_key", txt)) return LV_STATE_FOCUS_KEY; + if(lv_streq("edited", txt)) return LV_STATE_EDITED; + if(lv_streq("user_1", txt)) return LV_STATE_USER_1; + if(lv_streq("user_2", txt)) return LV_STATE_USER_2; + if(lv_streq("user_3", txt)) return LV_STATE_USER_3; + if(lv_streq("user_4", txt)) return LV_STATE_USER_4; + + LV_LOG_WARN("%s is an unknown value for state", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +int32_t lv_xml_to_size(const char * txt) +{ + if(lv_streq(txt, "content")) return LV_SIZE_CONTENT; + + int32_t v = lv_xml_atoi(txt); + if(txt[lv_strlen(txt) - 1] == '%') return lv_pct(v); + else return v; +} + +lv_align_t lv_xml_align_to_enum(const char * txt) +{ + if(lv_streq("top_left", txt)) return LV_ALIGN_TOP_LEFT; + if(lv_streq("top_mid", txt)) return LV_ALIGN_TOP_MID; + if(lv_streq("top_right", txt)) return LV_ALIGN_TOP_RIGHT; + if(lv_streq("bottom_left", txt)) return LV_ALIGN_BOTTOM_LEFT; + if(lv_streq("bottom_mid", txt)) return LV_ALIGN_BOTTOM_MID; + if(lv_streq("bottom_right", txt)) return LV_ALIGN_BOTTOM_RIGHT; + if(lv_streq("right_mid", txt)) return LV_ALIGN_RIGHT_MID; + if(lv_streq("left_mid", txt)) return LV_ALIGN_LEFT_MID; + if(lv_streq("center", txt)) return LV_ALIGN_CENTER; + + LV_LOG_WARN("%s is an unknown value for align", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_dir_t lv_xml_dir_to_enum(const char * txt) +{ + if(lv_streq("none", txt)) return LV_DIR_NONE; + if(lv_streq("top", txt)) return LV_DIR_TOP; + if(lv_streq("bottom", txt)) return LV_DIR_BOTTOM; + if(lv_streq("left", txt)) return LV_DIR_LEFT; + if(lv_streq("right", txt)) return LV_DIR_RIGHT; + if(lv_streq("hor", txt)) return LV_DIR_HOR; + if(lv_streq("ver", txt)) return LV_DIR_VER; + if(lv_streq("all", txt)) return LV_DIR_ALL; + + LV_LOG_WARN("%s is an unknown value for dir", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_border_side_t lv_xml_border_side_to_enum(const char * txt) +{ + if(lv_streq("none", txt)) return LV_BORDER_SIDE_NONE; + if(lv_streq("top", txt)) return LV_BORDER_SIDE_TOP; + if(lv_streq("bottom", txt)) return LV_BORDER_SIDE_BOTTOM; + if(lv_streq("left", txt)) return LV_BORDER_SIDE_LEFT; + if(lv_streq("right", txt)) return LV_BORDER_SIDE_RIGHT; + if(lv_streq("full", txt)) return LV_BORDER_SIDE_FULL; + + LV_LOG_WARN("%s is an unknown value for border_side", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_grad_dir_t lv_xml_grad_dir_to_enum(const char * txt) +{ + if(lv_streq("none", txt)) return LV_GRAD_DIR_NONE; + if(lv_streq("hor", txt)) return LV_GRAD_DIR_HOR; + if(lv_streq("ver", txt)) return LV_GRAD_DIR_VER; + + LV_LOG_WARN("%s is an unknown value for grad_dir", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_base_dir_t lv_xml_base_dir_to_enum(const char * txt) +{ + if(lv_streq("auto", txt)) return LV_BASE_DIR_AUTO; + if(lv_streq("ltr", txt)) return LV_BASE_DIR_LTR; + if(lv_streq("rtl", txt)) return LV_BASE_DIR_RTL; + + LV_LOG_WARN("%s is an unknown value for base_dir", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_text_align_t lv_xml_text_align_to_enum(const char * txt) +{ + if(lv_streq("left", txt)) return LV_TEXT_ALIGN_LEFT; + if(lv_streq("right", txt)) return LV_TEXT_ALIGN_RIGHT; + if(lv_streq("center", txt)) return LV_TEXT_ALIGN_CENTER; + if(lv_streq("auto", txt)) return LV_TEXT_ALIGN_AUTO; + + LV_LOG_WARN("%s is an unknown value for text_align", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_text_decor_t lv_xml_text_decor_to_enum(const char * txt) +{ + if(lv_streq("none", txt)) return LV_TEXT_DECOR_NONE; + if(lv_streq("underline", txt)) return LV_TEXT_DECOR_UNDERLINE; + if(lv_streq("strikethrough", txt)) return LV_TEXT_DECOR_STRIKETHROUGH; + + LV_LOG_WARN("%s is an unknown value for text_decor", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_flex_flow_t lv_xml_flex_flow_to_enum(const char * txt) +{ + if(lv_streq("column", txt)) return LV_FLEX_FLOW_COLUMN; + if(lv_streq("column_reverse", txt)) return LV_FLEX_FLOW_COLUMN_REVERSE; + if(lv_streq("column_wrap", txt)) return LV_FLEX_FLOW_COLUMN_WRAP; + if(lv_streq("column_wrap_reverse", txt)) return LV_FLEX_FLOW_COLUMN_WRAP_REVERSE; + if(lv_streq("row", txt)) return LV_FLEX_FLOW_ROW; + if(lv_streq("row_reverse", txt)) return LV_FLEX_FLOW_ROW_REVERSE; + if(lv_streq("row_wrap", txt)) return LV_FLEX_FLOW_ROW_WRAP; + if(lv_streq("row_wrap_reverse", txt)) return LV_FLEX_FLOW_ROW_WRAP_REVERSE; + + LV_LOG_WARN("%s is an unknown value for flex_flow", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_flex_align_t lv_xml_flex_align_to_enum(const char * txt) +{ + if(lv_streq("center", txt)) return LV_FLEX_ALIGN_CENTER; + if(lv_streq("end", txt)) return LV_FLEX_ALIGN_END; + if(lv_streq("start", txt)) return LV_FLEX_ALIGN_START; + if(lv_streq("space_around", txt)) return LV_FLEX_ALIGN_SPACE_AROUND; + if(lv_streq("space_between", txt)) return LV_FLEX_ALIGN_SPACE_BETWEEN; + if(lv_streq("space_evenly", txt)) return LV_FLEX_ALIGN_SPACE_EVENLY; + + LV_LOG_WARN("%s is an unknown value for flex_align", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_grid_align_t lv_xml_grid_align_to_enum(const char * txt) +{ + if(lv_streq("center", txt)) return LV_GRID_ALIGN_CENTER; + if(lv_streq("end", txt)) return LV_GRID_ALIGN_END; + if(lv_streq("start", txt)) return LV_GRID_ALIGN_START; + if(lv_streq("stretch", txt)) return LV_GRID_ALIGN_STRETCH; + if(lv_streq("space_around", txt)) return LV_GRID_ALIGN_SPACE_AROUND; + if(lv_streq("space_between", txt)) return LV_GRID_ALIGN_SPACE_BETWEEN; + if(lv_streq("space_evenly", txt)) return LV_GRID_ALIGN_SPACE_EVENLY; + + LV_LOG_WARN("%s is an unknown value for grid_align", txt); + return 0; /*Return 0 in lack of a better option. */ +} + + +lv_layout_t lv_xml_layout_to_enum(const char * txt) +{ + if(lv_streq("none", txt)) return LV_LAYOUT_NONE; + if(lv_streq("flex", txt)) return LV_LAYOUT_FLEX; + if(lv_streq("grid", txt)) return LV_LAYOUT_GRID; + + LV_LOG_WARN("%s is an unknown value for layout", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +lv_blend_mode_t lv_xml_blend_mode_to_enum(const char * txt) +{ + if(lv_streq("normal", txt)) return LV_BLEND_MODE_NORMAL; + if(lv_streq("additive", txt)) return LV_BLEND_MODE_ADDITIVE; + if(lv_streq("subtractive", txt)) return LV_BLEND_MODE_SUBTRACTIVE; + if(lv_streq("multiply", txt)) return LV_BLEND_MODE_MULTIPLY; + if(lv_streq("difference", txt)) return LV_BLEND_MODE_DIFFERENCE; + + LV_LOG_WARN("%s is an unknown value for blend_mode", txt); + return 0; /*Return 0 in lack of a better option. */ +} + + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_base_types.h b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_base_types.h new file mode 100644 index 000000000..184d0eeec --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_base_types.h @@ -0,0 +1,138 @@ +/** + * @file lv_xml_base_types.h + * + */ + +#ifndef LV_XML_BASE_TYPES_H +#define LV_XML_BASE_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_types.h" +#include "../../misc/lv_style.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Convert an state string to enum + * @param txt e.g. "pressed" + * @return the related enum, e.g. `LV_STATE_PRESSED` + */ +lv_state_t lv_xml_state_to_enum(const char * txt); + +/** + * Process inputs "content", "32", "32px", or "25%" + * and convert them to integer + * @param txt the input string + * @return the integer size + */ +int32_t lv_xml_to_size(const char * txt); + + +/** + * Convert an align string to enum + * @param txt e.g. "center" + * @return the related enum, e.g. `LV_ALIGN_CENTER` + */ +lv_align_t lv_xml_align_to_enum(const char * txt); + +/** + * Convert a direction string to enum + * @param txt e.g. "top" + * @return the related enum, e.g. `LV_DIR_TOP` + */ +lv_dir_t lv_xml_dir_to_enum(const char * txt); + +/** + * Convert a direction string to enum + * @param txt e.g. "top" + * @return the related enum, e.g. `LV_BORDER_SIDE_TOP` + */ +lv_border_side_t lv_xml_border_side_to_enum(const char * txt); + +/** + * Convert a base dir string to enum + * @param txt e.g. "rtl" + * @return the related enum, e.g. `LV_BASE_DIR_RTL` + */ +lv_base_dir_t lv_xml_base_dir_to_enum(const char * txt); + +/** + * Convert a grad dir string to enum + * @param txt e.g. "hor" + * @return the related enum, e.g. `LV_GRAD_DIR_HOR` + */ +lv_grad_dir_t lv_xml_grad_dir_to_enum(const char * txt); + +/** + * Convert a text align string to enum + * @param txt e.g. "left" + * @return the related enum, e.g. `LV_TEXT_ALIGN_LEFT` + */ +lv_text_align_t lv_xml_text_align_to_enum(const char * txt); + +/** + * Convert a text decor string to enum + * @param txt e.g. "underline" + * @return the related enum, e.g. `LV_TEXT_DECOR_UNDERLINE` + */ +lv_text_decor_t lv_xml_text_decor_to_enum(const char * txt); + +/** + * Convert a flex flow string to enum + * @param txt e.g. "row_wrap" + * @return the related enum, e.g. `LV_FLEX_FLOW_ROW_WRAP` + */ +lv_flex_flow_t lv_xml_flex_flow_to_enum(const char * txt); + +/** + * Convert a flex align string to enum + * @param txt e.g. "space_between" + * @return the related enum, e.g. `LV_FLEX_ALIGN_SPACE_BETWEEN` + */ +lv_flex_align_t lv_xml_flex_align_to_enum(const char * txt); + +/** + * Convert a grid align string to enum + * @param txt e.g. "space_between" + * @return the related enum, e.g. `LV_GRID_ALIGN_SPACE_BETWEEN` + */ +lv_grid_align_t lv_xml_grid_align_to_enum(const char * txt); + +/** + * Convert a layout string to enum + * @param txt e.g. "flex" + * @return the related enum, e.g. `LV_LAYOUT_FLEX` + */ +lv_layout_t lv_xml_layout_to_enum(const char * txt); + +/** + * Convert a blend mode string to enum + * @param txt e.g. "additive" + * @return the related enum, e.g. `LV_BLEND_MODE_ADDITIVE` + */ +lv_blend_mode_t lv_xml_blend_mode_to_enum(const char * txt); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_BASE_TYPES_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_component.c b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_component.c new file mode 100644 index 000000000..9344fe428 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_component.c @@ -0,0 +1,740 @@ +/** + * @file lv_xml_component.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_component.h" +#if LV_USE_XML + +#include "../../lvgl.h" +#include "lv_xml_component_private.h" +#include "lv_xml_private.h" +#include "lv_xml_parser.h" +#include "lv_xml_style.h" +#include "lv_xml_base_types.h" +#include "lv_xml_widget.h" +#include "parsers/lv_xml_obj_parser.h" +#include "../../libs/expat/expat.h" +#include "../../misc/lv_fs.h" +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void start_metadata_handler(void * user_data, const char * name, const char ** attrs); +static void end_metadata_handler(void * user_data, const char * name); +static void process_const_element(lv_xml_parser_state_t * state, const char ** attrs); +static void process_font_element(lv_xml_parser_state_t * state, const char * type, const char ** attrs); +static void process_image_element(lv_xml_parser_state_t * state, const char * type, const char ** attrs); +static void process_prop_element(lv_xml_parser_state_t * state, const char ** attrs); +static char * extract_view_content(const char * xml_definition); + +/********************** + * STATIC VARIABLES + **********************/ + +static lv_ll_t component_scope_ll; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_xml_component_init(void) +{ + lv_ll_init(&component_scope_ll, sizeof(lv_xml_component_scope_t)); + + lv_xml_component_scope_t * global_scope = lv_ll_ins_head(&component_scope_ll); + lv_memzero(global_scope, sizeof(lv_xml_component_scope_t)); + lv_xml_component_scope_init(global_scope); + global_scope->name = lv_strdup("globals"); + +} + +void lv_xml_component_scope_init(lv_xml_component_scope_t * scope) +{ + lv_ll_init(&scope->style_ll, sizeof(lv_xml_style_t)); + lv_ll_init(&scope->const_ll, sizeof(lv_xml_const_t)); + lv_ll_init(&scope->param_ll, sizeof(lv_xml_param_t)); + lv_ll_init(&scope->gradient_ll, sizeof(lv_xml_grad_t)); + lv_ll_init(&scope->subjects_ll, sizeof(lv_xml_subject_t)); + lv_ll_init(&scope->event_ll, sizeof(lv_xml_event_cb_t)); + lv_ll_init(&scope->image_ll, sizeof(lv_xml_image_t)); + lv_ll_init(&scope->font_ll, sizeof(lv_xml_font_t)); +} + + +lv_obj_t * lv_xml_component_process(lv_xml_parser_state_t * state, const char * name, const char ** attrs) +{ + lv_xml_component_scope_t * scope = lv_xml_component_get_scope(name); + if(scope == NULL) return NULL; + lv_obj_t * item = lv_xml_create_in_scope(state->parent, &state->scope, scope, attrs); + if(item == NULL) { + LV_LOG_WARN("Couldn't create component '%s'", name); + return NULL; + } + + /* Apply the properties of the component, e.g. */ + state->item = item; + lv_widget_processor_t * extended_proc = lv_xml_widget_get_extended_widget_processor(scope->extends); + extended_proc->apply_cb(state, attrs); + + +#if LV_USE_OBJ_NAME + /*Set a default indexed name*/ + if(state->item) { + const char * value_of_name = lv_xml_get_value_of(attrs, "name"); + if(value_of_name) lv_obj_set_name(item, value_of_name); + else { + char name_buf[128]; + lv_snprintf(name_buf, sizeof(name_buf), "%s_#", scope->name); + lv_obj_set_name(state->item, name_buf); + } + } +#endif + return item; +} + +lv_xml_component_scope_t * lv_xml_component_get_scope(const char * component_name) +{ + lv_xml_component_scope_t * scope; + LV_LL_READ(&component_scope_ll, scope) { + if(lv_streq(scope->name, component_name)) return scope; + } + + return NULL; +} + +lv_result_t lv_xml_component_register_from_data(const char * name, const char * xml_def) +{ + bool globals = false; + if(lv_streq(name, "globals")) globals = true; + + /* Create a temporary parser state to extract styles/params/consts */ + lv_xml_parser_state_t state; + if(globals) { + lv_xml_component_scope_t * global_scope = lv_xml_component_get_scope("globals"); + state.scope = *global_scope; + } + else { + lv_xml_parser_state_init(&state); + state.scope.name = name; + } + + /* Parse the XML to extract metadata */ + XML_Memory_Handling_Suite mem_handlers; + mem_handlers.malloc_fcn = lv_malloc; + mem_handlers.realloc_fcn = lv_realloc; + mem_handlers.free_fcn = lv_free; + XML_Parser parser = XML_ParserCreate_MM(NULL, &mem_handlers, NULL); + XML_SetUserData(parser, &state); + XML_SetElementHandler(parser, start_metadata_handler, end_metadata_handler); + + if(XML_Parse(parser, xml_def, lv_strlen(xml_def), XML_TRUE) == XML_STATUS_ERROR) { + LV_LOG_ERROR("XML parsing error: %s on line %lu", + XML_ErrorString(XML_GetErrorCode(parser)), + (unsigned long)XML_GetCurrentLineNumber(parser)); + XML_ParserFree(parser); + lv_free((char *)state.scope.extends); + return LV_RESULT_INVALID; + } + + XML_ParserFree(parser); + + + /* Copy extracted metadata to component processor */ + if(globals) { + lv_xml_component_scope_t * global_scope = lv_xml_component_get_scope("globals"); + lv_memcpy(global_scope, &state.scope, sizeof(lv_xml_component_scope_t)); + } + else { + lv_xml_component_scope_t * scope = lv_ll_ins_head(&component_scope_ll); + lv_memzero(scope, sizeof(lv_xml_component_scope_t)); + lv_memcpy(scope, &state.scope, sizeof(lv_xml_component_scope_t)); + + /* Extract view content directly instead of using XML parser */ + scope->view_def = extract_view_content(xml_def); + scope->name = lv_strdup(name); + if(!scope->view_def) { + LV_LOG_WARN("Failed to extract view content"); + /* Clean up and return error */ + lv_free(scope); + return LV_RESULT_INVALID; + } + } + + return LV_RESULT_OK; +} + + +lv_result_t lv_xml_component_register_from_file(const char * path) +{ + /* Extract component name from path */ + /* Create a copy of the filename to modify */ + char * filename = lv_strdup(lv_fs_get_last(path)); + const char * ext = lv_fs_get_ext(filename); + filename[lv_strlen(filename) - lv_strlen(ext) - 1] = '\0'; /*Trim the extension*/ + + lv_fs_res_t fs_res; + lv_fs_file_t f; + fs_res = lv_fs_open(&f, path, LV_FS_MODE_RD); + if(fs_res != LV_FS_RES_OK) { + LV_LOG_WARN("Couldn't open %s", path); + lv_free(filename); + return LV_RESULT_INVALID; + } + + /* Determine file size */ + lv_fs_seek(&f, 0, LV_FS_SEEK_END); + uint32_t file_size = 0; + lv_fs_tell(&f, &file_size); + lv_fs_seek(&f, 0, LV_FS_SEEK_SET); + + /* Create the buffer */ + char * xml_buf = lv_malloc(file_size + 1); + if(xml_buf == NULL) { + LV_LOG_WARN("Memory allocation failed for file %s (%d bytes)", path, file_size + 1); + lv_free(filename); + lv_fs_close(&f); + return LV_RESULT_INVALID; + } + + /* Read the file content */ + uint32_t rn; + lv_fs_read(&f, xml_buf, file_size, &rn); + if(rn != file_size) { + LV_LOG_WARN("Couldn't read %s fully", path); + lv_free(filename); + lv_free(xml_buf); + lv_fs_close(&f); + return LV_RESULT_INVALID; + } + + /* Null-terminate the buffer */ + xml_buf[rn] = '\0'; + + /* Register the component */ + lv_result_t res = lv_xml_component_register_from_data(filename, xml_buf); + + /* Housekeeping */ + lv_free(filename); + lv_free(xml_buf); + lv_fs_close(&f); + + return res; +} + +lv_result_t lv_xml_component_unregister(const char * name) +{ + lv_xml_component_scope_t * scope = lv_xml_component_get_scope(name); + if(scope == NULL) return LV_RESULT_INVALID; + + lv_ll_remove(&component_scope_ll, scope); + + lv_free((char *)scope->name); + lv_free((char *)scope->view_def); + lv_free((char *)scope->extends); + + lv_xml_const_t * cnst; + LV_LL_READ(&scope->const_ll, cnst) { + lv_free((char *)cnst->name); + lv_free((char *)cnst->value); + } + lv_ll_clear(&scope->const_ll); + + lv_xml_param_t * param; + LV_LL_READ(&scope->param_ll, param) { + lv_free((char *)param->name); + lv_free((char *)param->def); + lv_free((char *)param->type); + } + lv_ll_clear(&scope->param_ll); + + + lv_xml_font_t * font; + LV_LL_READ(&scope->font_ll, font) { + lv_free((char *)font->name); + } + lv_ll_clear(&scope->font_ll); + + lv_xml_image_t * image; + LV_LL_READ(&scope->image_ll, image) { + lv_free((char *)image->name); + lv_free((char *)image->src); + } + lv_ll_clear(&scope->image_ll); + + lv_xml_style_t * style; + LV_LL_READ(&scope->style_ll, style) { + lv_free((char *)style->name); + lv_free((char *)style->long_name); + lv_style_reset(&style->style); + } + lv_ll_clear(&scope->style_ll); + + + lv_xml_grad_t * grad; + LV_LL_READ(&scope->gradient_ll, grad) { + lv_free((char *)grad->name); + } + lv_ll_clear(&scope->gradient_ll); + + lv_xml_subject_t * subject; + LV_LL_READ(&scope->subjects_ll, subject) { + lv_free((char *)subject->name); + if(subject->subject->type == LV_SUBJECT_TYPE_STRING) { + lv_free((char *)subject->subject->prev_value.pointer); + lv_free((char *)subject->subject->value.pointer); + } + lv_free(subject->subject); + } + lv_ll_clear(&scope->subjects_ll); + + lv_free(scope); + + return LV_RESULT_OK; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void process_const_element(lv_xml_parser_state_t * state, const char ** attrs) +{ + const char * name = lv_xml_get_value_of(attrs, "name"); + const char * value = lv_xml_get_value_of(attrs, "value"); + + if(name == NULL) { + LV_LOG_WARN("'name' is missing from a constant"); + return; + } + if(value == NULL) { + LV_LOG_WARN("'value' is missing from a constant"); + return; + } + + lv_xml_register_const(&state->scope, name, value); +} + +static void process_font_element(lv_xml_parser_state_t * state, const char * type, const char ** attrs) +{ + const char * name = lv_xml_get_value_of(attrs, "name"); + if(name == NULL) { + LV_LOG_WARN("'name' is missing from a font"); + return; + } + + const char * src_path = lv_xml_get_value_of(attrs, "src_path"); + if(src_path == NULL) { + LV_LOG_WARN("'src_path' is missing from a `%s` font", name); + return; + } + + const char * as_file = lv_xml_get_value_of(attrs, "as_file"); + if(as_file == NULL || lv_streq(as_file, "false")) { + LV_LOG_INFO("Ignore non-file based font `%s`", name); + return; + } + + lv_xml_font_t * f; + LV_LL_READ(&state->scope.font_ll, f) { + if(lv_streq(f->name, name)) { + LV_LOG_INFO("Font %s is already registered. Don't register it again.", name); + return; + } + } + + /*E.g. */ + if(lv_streq(type, "tiny_ttf")) { + const char * size = lv_xml_get_value_of(attrs, "size"); + if(size == NULL) { + LV_LOG_WARN("'size' is missing from a `%s` tiny_ttf font", name); + return; + } +#if LV_TINY_TTF_FILE_SUPPORT + lv_font_t * font = lv_tiny_ttf_create_file(src_path, lv_xml_atoi(size)); + if(font == NULL) { + LV_LOG_WARN("Couldn't load `%s` tiny_ttf font", name); + return; + } + lv_result_t res = lv_xml_register_font(&state->scope, name, font); + if(res == LV_RESULT_INVALID) { + LV_LOG_WARN("Failed to register `%s` tiny_ttf font", name); + lv_tiny_ttf_destroy(font); + return; + } + + /*Get the font which was just created and add a destroy_cb*/ + lv_xml_font_t * new_font; + LV_LL_READ(&state->scope.font_ll, new_font) { + if(lv_streq(new_font->name, name)) { + new_font->font_destroy_cb = lv_tiny_ttf_destroy; + break; + } + } + +#else + LV_LOG_WARN("LV_TINY_TTF_FILE_SUPPORT is not enabled for `%s` font", name); + +#endif + } + else if(lv_streq(type, "bin")) { + lv_font_t * font = lv_binfont_create(src_path); + if(font == NULL) { + LV_LOG_WARN("Couldn't load `%s` bin font", name); + return; + } + + lv_result_t res = lv_xml_register_font(&state->scope, name, font); + if(res == LV_RESULT_INVALID) { + LV_LOG_WARN("Failed to register `%s` bin font", name); + lv_binfont_destroy(font); + return; + } + + lv_xml_font_t * new_font; + LV_LL_READ(&state->scope.font_ll, new_font) { + if(lv_streq(new_font->name, name)) { + new_font->font_destroy_cb = lv_binfont_destroy; + break; + } + } + } + else { + LV_LOG_WARN("`%s` is a not supported font type", type); + } +} + +static void process_image_element(lv_xml_parser_state_t * state, const char * type, const char ** attrs) +{ + const char * name = lv_xml_get_value_of(attrs, "name"); + if(name == NULL) { + LV_LOG_WARN("'name' is missing from a font"); + return; + } + + const char * src_path = lv_xml_get_value_of(attrs, "src_path"); + if(src_path == NULL) { + LV_LOG_WARN("'src_path' is missing from a `%s` font", name); + return; + } + + /* E.g. */ + if(lv_streq(type, "file")) { + lv_xml_register_image(&state->scope, name, src_path); + } + else { + LV_LOG_INFO("Ignore non-file image `%s`", name); + } +} + +static void process_subject_element(lv_xml_parser_state_t * state, const char * type, const char ** attrs) +{ + const char * name = lv_xml_get_value_of(attrs, "name"); + const char * value = lv_xml_get_value_of(attrs, "value"); + + if(name == NULL) { + LV_LOG_WARN("'name' is missing from a subject"); + return; + } + if(value == NULL) { + LV_LOG_WARN("'value' is missing from a subject"); + return; + } + + lv_subject_t * subject = lv_malloc(sizeof(lv_subject_t)); + + if(lv_streq(type, "int")) lv_subject_init_int(subject, lv_xml_atoi(value)); + else if(lv_streq(type, "color")) lv_subject_init_color(subject, lv_xml_to_color(value)); + else if(lv_streq(type, "string")) { + /*Simple solution for now. Will be improved later*/ + char * buf_prev = lv_malloc(256); + char * buf_act = lv_malloc(256); + lv_subject_init_string(subject, buf_act, buf_prev, 256, value); + } + + lv_xml_register_subject(&state->scope, name, subject); +} + +static void process_grad_element(lv_xml_parser_state_t * state, const char * tag_name, const char ** attrs) +{ + lv_xml_grad_t * grad = lv_ll_ins_tail(&state->scope.gradient_ll); + grad->name = lv_strdup(lv_xml_get_value_of(attrs, "name")); + lv_grad_dsc_t * dsc = &grad->grad_dsc; + lv_memzero(dsc, sizeof(lv_grad_dsc_t)); + dsc->extend = LV_GRAD_EXTEND_PAD; + + if(lv_streq(tag_name, "linear")) { + dsc->dir = LV_GRAD_DIR_LINEAR; + char buf[64]; + char * buf_p = buf; + const char * start = lv_xml_get_value_of(attrs, "start"); + lv_strlcpy(buf, start, sizeof(buf)); + dsc->params.linear.start.x = lv_xml_to_size(lv_xml_split_str(&buf_p, ' ')); + dsc->params.linear.start.y = lv_xml_to_size(buf_p); + + buf_p = buf; + const char * end = lv_xml_get_value_of(attrs, "end"); + lv_strlcpy(buf, end, sizeof(buf)); + dsc->params.linear.end.x = lv_xml_to_size(lv_xml_split_str(&buf_p, ' ')); + dsc->params.linear.end.y = lv_xml_to_size(buf_p); + } + else if(lv_streq(tag_name, "radial")) { + dsc->dir = LV_GRAD_DIR_RADIAL; + char buf[64]; + char * buf_p = buf; + const char * center = lv_xml_get_value_of(attrs, "center"); + if(center) { + lv_strlcpy(buf, center, sizeof(buf)); + dsc->params.radial.end.x = lv_xml_to_size(lv_xml_split_str(&buf_p, ' ')); + dsc->params.radial.end.y = lv_xml_to_size(buf_p); + } + else { + dsc->params.radial.end.x = lv_pct(50); + dsc->params.radial.end.y = lv_pct(50); + } + buf_p = buf; + const char * center_edge = lv_xml_get_value_of(attrs, "edge"); + if(center_edge) { + lv_strlcpy(buf, center_edge, sizeof(buf)); + dsc->params.radial.end_extent.x = lv_xml_to_size(lv_xml_split_str(&buf_p, ' ')); + dsc->params.radial.end_extent.y = lv_xml_to_size(buf_p); + } + else { + dsc->params.radial.end_extent.x = lv_pct(100); + dsc->params.radial.end_extent.y = lv_pct(100); + } + + buf_p = buf; + const char * center_radius = lv_xml_get_value_of(attrs, "radius"); + if(center_radius) { + int32_t r = lv_xml_atoi(center_radius); + lv_strlcpy(buf, center_edge, sizeof(buf)); + dsc->params.radial.end_extent.x = dsc->params.radial.end.x + r; + dsc->params.radial.end_extent.y = dsc->params.radial.end.y; + } + + buf_p = buf; + const char * focal = lv_xml_get_value_of(attrs, "focal_center"); + if(focal) { + lv_strlcpy(buf, focal, sizeof(buf)); + dsc->params.radial.focal.x = lv_xml_to_size(lv_xml_split_str(&buf_p, ' ')); + dsc->params.radial.focal.y = lv_xml_to_size(buf_p); + } + else { + dsc->params.radial.focal.x = dsc->params.radial.end.x; + dsc->params.radial.focal.y = dsc->params.radial.end.y; + } + + buf_p = buf; + const char * focal_edge = lv_xml_get_value_of(attrs, "focal_edge"); + if(focal_edge) { + lv_strlcpy(buf, focal_edge, sizeof(buf)); + dsc->params.radial.focal_extent.x = lv_xml_to_size(lv_xml_split_str(&buf_p, ' ')); + dsc->params.radial.focal_extent.y = lv_xml_to_size(buf_p); + } + else { + dsc->params.radial.focal_extent.x = dsc->params.radial.focal.x; + dsc->params.radial.focal_extent.y = dsc->params.radial.focal.y; + } + + buf_p = buf; + const char * focal_radius = lv_xml_get_value_of(attrs, "focal_radius"); + if(focal_radius) { + int32_t r = lv_xml_atoi(center_radius); + lv_strlcpy(buf, center_edge, sizeof(buf)); + dsc->params.radial.focal_extent.x = dsc->params.radial.focal.x + r; + dsc->params.radial.focal_extent.y = dsc->params.radial.focal.y; + } + + } + + else if(lv_streq(tag_name, "conical")) { + dsc->dir = LV_GRAD_DIR_CONICAL; + char buf[64]; + char * buf_p = buf; + const char * center = lv_xml_get_value_of(attrs, "center"); + if(center) { + lv_strlcpy(buf, center, sizeof(buf)); + dsc->params.conical.center.x = lv_xml_to_size(lv_xml_split_str(&buf_p, ' ')); + dsc->params.conical.center.y = lv_xml_to_size(buf_p); + } + else { + dsc->params.conical.center.x = lv_pct(50); + dsc->params.conical.center.y = lv_pct(50); + } + buf_p = buf; + const char * angle = lv_xml_get_value_of(attrs, "angle"); + if(angle) { + lv_strlcpy(buf, angle, sizeof(buf)); + dsc->params.conical.start_angle = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); + dsc->params.conical.end_angle = lv_xml_atoi(buf_p); + } + else { + dsc->params.conical.start_angle = 0; + dsc->params.conical.end_angle = 360; + } + } + else if(lv_streq(tag_name, "horizontal")) { + dsc->dir = LV_GRAD_DIR_HOR; + } + else if(lv_streq(tag_name, "vertical")) { + dsc->dir = LV_GRAD_DIR_VER; + } + else { + LV_LOG_WARN("Unknown gradient type: %s", tag_name); + } +} + + +static void process_grad_stop_element(lv_xml_parser_state_t * state, const char ** attrs) +{ + /*Add the stop to the last gradient*/ + lv_xml_grad_t * grad = lv_ll_get_tail(&state->scope.gradient_ll); + lv_grad_dsc_t * dsc = &grad->grad_dsc; + + uint32_t idx = dsc->stops_count; + if(idx == LV_GRADIENT_MAX_STOPS) { + LV_LOG_WARN("Too many gradient stops. Incresase LV_GRADIENT_MAX_STOPS"); + return; + } + const char * color_value = lv_xml_get_value_of(attrs, "color"); + const char * opa_value = lv_xml_get_value_of(attrs, "opa"); + const char * offset_value = lv_xml_get_value_of(attrs, "offset"); + + dsc->stops[idx].color = color_value ? lv_xml_to_color(color_value) : lv_color_black(); + dsc->stops[idx].opa = opa_value ? lv_xml_to_opa(opa_value) : LV_OPA_COVER; + dsc->stops[idx].frac = offset_value ? lv_xml_to_opa(offset_value) : (uint8_t)((int32_t)idx * 255 / + (LV_GRADIENT_MAX_STOPS - 1)); + + dsc->stops_count++; +} + +static void process_prop_element(lv_xml_parser_state_t * state, const char ** attrs) +{ + lv_xml_param_t * prop = lv_ll_ins_tail(&state->scope.param_ll); + prop->name = lv_strdup(lv_xml_get_value_of(attrs, "name")); + const char * def = lv_xml_get_value_of(attrs, "default"); + if(def) prop->def = lv_strdup(def); + else prop->def = NULL; + + const char * type = lv_xml_get_value_of(attrs, "type"); + if(type == NULL) type = "compound"; /*If there in no type it means there are s*/ + prop->type = lv_strdup(type); +} + + +static void start_metadata_handler(void * user_data, const char * name, const char ** attrs) +{ + lv_xml_parser_state_t * state = (lv_xml_parser_state_t *)user_data; + + lv_xml_parser_section_t old_section = state->section; + lv_xml_parser_start_section(state, name); + if(lv_streq(name, "view")) { + const char * extends = lv_xml_get_value_of(attrs, "extends"); + if(extends == NULL) extends = "lv_obj"; + + state->scope.extends = lv_strdup(extends); + } + + if(lv_streq(name, "widget")) state->scope.is_widget = 1; + + /* Process elements based on current context */ + switch(state->section) { + case LV_XML_PARSER_SECTION_API: + if(old_section != state->section) return; /*Ignore the section opening, e.g. */ + process_prop_element(state, attrs); + break; + + case LV_XML_PARSER_SECTION_CONSTS: + if(old_section != state->section) return; /*Ignore the section opening, e.g. */ + process_const_element(state, attrs); + break; + + case LV_XML_PARSER_SECTION_GRAD: + if(old_section != state->section) return; /*Ignore the section opening, e.g. */ + process_grad_element(state, name, attrs); + break; + + case LV_XML_PARSER_SECTION_GRAD_STOP: + process_grad_stop_element(state, attrs); + break; + + case LV_XML_PARSER_SECTION_STYLES: + if(old_section != state->section) return; /*Ignore the section opening, e.g. */ + lv_xml_style_register(&state->scope, attrs); + break; + + case LV_XML_PARSER_SECTION_FONTS: + if(old_section != state->section) return; /*Ignore the section opening, e.g. */ + process_font_element(state, name, attrs); + break; + + case LV_XML_PARSER_SECTION_IMAGES: + if(old_section != state->section) return; /*Ignore the section opening, e.g. */ + process_image_element(state, name, attrs); + break; + + case LV_XML_PARSER_SECTION_SUBJECTS: + if(old_section != state->section) return; /*Ignore the section opening, e.g. */ + process_subject_element(state, name, attrs); + break; + + default: + break; + } +} + +static void end_metadata_handler(void * user_data, const char * name) +{ + lv_xml_parser_state_t * state = (lv_xml_parser_state_t *)user_data; + lv_xml_parser_end_section(state, name); +} + +static char * extract_view_content(const char * xml_definition) +{ + if(!xml_definition) return NULL; + + /* Find start of view tag */ + const char * start = strstr(xml_definition, ""); + if(end) { + end += 7; /* Include "" in result */ + } + else { + /*If there is no " maybe it's like "*/ + end = strstr(start, "/>"); + if(!end) return NULL; + end += 2; /* Include "/>" in result */ + } + + /* Calculate and allocate length */ + size_t len = end - start; + char * view_content = lv_malloc(len + 1); + if(!view_content) return NULL; + + /* Copy content and null terminate */ + lv_memcpy(view_content, start, len); + view_content[len] = '\0'; + + return view_content; +} + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_component.h b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_component.h new file mode 100644 index 000000000..31837edee --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_component.h @@ -0,0 +1,78 @@ +/** + * @file lv_xml_component.h + * + */ + +#ifndef LV_LABEL_XML_COMPONENT_H +#define LV_LABEL_XML_COMPONENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_types.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Process a component during parsing an XML. It create a widget and apply all the attributes + * @param state the current parsing state + * @param name name of the component + * @param attrs attributes of the widget + * @return + */ +lv_obj_t * lv_xml_component_process(lv_xml_parser_state_t * state, const char * name, const char ** attrs); + +/** + * Load the styles, constants, another data of the component. It needs to be called only once for each component. + * @param name the name as the component will be referenced later in other components + * @param xml_def the XML definition of the component as a NULL terminated string + * @return LV_RES_OK: loaded successfully, LV_RES_INVALID: otherwise + */ +lv_result_t lv_xml_component_register_from_data(const char * name, const char * xml_def); + +/** + * Load the styles, constants, another data of the component. It needs to be called only once for each component. + * @param path path to an XML file + * @return LV_RES_OK: loaded successfully, LV_RES_INVALID: otherwise + */ +lv_result_t lv_xml_component_register_from_file(const char * path); + +/** + * Get the scope of a component which was registered by + * `lv_xml_component_register_from_data` or `lv_xml_component_register_from_file` + * @param component_name name of the component + * @return pointer the scope or NULL if not found + */ +lv_xml_component_scope_t * lv_xml_component_get_scope(const char * component_name); + +/** + * Remove a component from from the list. + * @param name the name of the component (used during registration) + * @return LV_RESULT_OK on successful unregistration, LV_RESULT_INVALID otherwise. + */ +lv_result_t lv_xml_component_unregister(const char * name); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_COMPONENT_H*/ + + diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_component_private.h b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_component_private.h new file mode 100644 index 000000000..9b84eb4ee --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_component_private.h @@ -0,0 +1,92 @@ +/** + * @file lv_xml_component_private.h + * + */ + +#ifndef LV_XML_COMPONENT_PRIVATE_H +#define LV_XML_COMPONENT_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_xml.h" +#if LV_USE_XML + +#include "lv_xml_utils.h" +#include "../../misc/lv_ll.h" +#include "../../misc/lv_style.h" +#include "../../others/observer/lv_observer.h" + +/********************** + * TYPEDEFS + **********************/ + +typedef void * (*lv_xml_component_process_cb_t)(lv_obj_t * parent, const char * data, const char ** attrs); + +struct _lv_xml_component_scope_t { + const char * name; + lv_ll_t style_ll; + lv_ll_t const_ll; + lv_ll_t param_ll; + lv_ll_t gradient_ll; + lv_ll_t subjects_ll; + lv_ll_t font_ll; + lv_ll_t image_ll; + lv_ll_t event_ll; + const char * view_def; + const char * extends; + uint32_t is_widget : 1; /*1: not component but widget registered as a component for preview*/ + struct _lv_xml_component_scope_t * next; +}; + +typedef struct { + const char * name; + const char * value; +} lv_xml_const_t; + +typedef struct { + const char * name; + lv_subject_t * subject; +} lv_xml_subject_t; + +typedef struct { + const char * name; + const char * def; + const char * type; +} lv_xml_param_t; + +typedef struct { + const char * name; + lv_grad_dsc_t grad_dsc; +} lv_xml_grad_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize the components system. + */ +void lv_xml_component_init(void); + +/** + * Initialize the linked lists of a component context + * @param scope pointer to a component contexts + */ +void lv_xml_component_scope_init(lv_xml_component_scope_t * scope); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_COMPONENT_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_parser.c new file mode 100644 index 000000000..9cf4d6d88 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_parser.c @@ -0,0 +1,123 @@ +/** + * @file lv_xml.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml.h" +#if LV_USE_XML + +#include "lv_xml_private.h" +#include "lv_xml_parser.h" +#include "lv_xml_style.h" +#include "lv_xml_component_private.h" +#include "lv_xml_base_types.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_xml_parser_state_init(lv_xml_parser_state_t * state) +{ + lv_memzero(state, sizeof(lv_xml_parser_state_t)); + lv_ll_init(&state->parent_ll, sizeof(lv_obj_t *)); + lv_xml_component_scope_init(&state->scope); +} + +void lv_xml_parser_start_section(lv_xml_parser_state_t * state, const char * name) +{ + /* Check for context changes */ + if(lv_streq(name, "api")) { + state->section = LV_XML_PARSER_SECTION_API; + return; + } + if(lv_streq(name, "gradients")) { + state->section = LV_XML_PARSER_SECTION_GRAD; + return; + } + if(state->section == LV_XML_PARSER_SECTION_GRAD && lv_streq(name, "stop")) { + state->section = LV_XML_PARSER_SECTION_GRAD_STOP; + return; + } + else if(lv_streq(name, "consts")) { + state->section = LV_XML_PARSER_SECTION_CONSTS; + return; + } + else if(lv_streq(name, "styles")) { + state->section = LV_XML_PARSER_SECTION_STYLES; + return; + } + else if(lv_streq(name, "images")) { + state->section = LV_XML_PARSER_SECTION_IMAGES; + return; + } + else if(lv_streq(name, "fonts")) { + state->section = LV_XML_PARSER_SECTION_FONTS; + return; + } + else if(lv_streq(name, "subjects")) { + state->section = LV_XML_PARSER_SECTION_SUBJECTS; + return; + } + else if(lv_streq(name, "view")) { + state->section = LV_XML_PARSER_SECTION_VIEW; + return; + } +} + +void lv_xml_parser_end_section(lv_xml_parser_state_t * state, const char * name) +{ + + /* Reset context when leaving a block */ + if(lv_streq(name, "params") || + lv_streq(name, "consts") || + lv_streq(name, "gradients") || + lv_streq(name, "styles") || + lv_streq(name, "view")) { + state->section = LV_XML_PARSER_SECTION_NONE; + } + + /*When processing gradient stops, but not a stop was closed got bacg to gradient processing + * E.g. */ + if(state->section == LV_XML_PARSER_SECTION_GRAD_STOP && !lv_streq(name, "stop")) { + state->section = LV_XML_PARSER_SECTION_GRAD; + } +} + +void * lv_xml_state_get_parent(lv_xml_parser_state_t * state) +{ + return state->parent; +} + +void * lv_xml_state_get_item(lv_xml_parser_state_t * state) +{ + return state->item; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_parser.h new file mode 100644 index 000000000..531748a77 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_parser.h @@ -0,0 +1,79 @@ +/** + * @file lv_xml_parser.h + * + */ + +#ifndef LV_XML_PARSER_H +#define LV_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_types.h" +#include "../../misc/lv_style.h" +#if LV_USE_XML + +#include "lv_xml_component.h" +#include "lv_xml_component_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_XML_PARSER_SECTION_NONE, + LV_XML_PARSER_SECTION_API, + LV_XML_PARSER_SECTION_CONSTS, + LV_XML_PARSER_SECTION_GRAD, + LV_XML_PARSER_SECTION_GRAD_STOP, + LV_XML_PARSER_SECTION_STYLES, + LV_XML_PARSER_SECTION_FONTS, + LV_XML_PARSER_SECTION_IMAGES, + LV_XML_PARSER_SECTION_SUBJECTS, + LV_XML_PARSER_SECTION_VIEW +} lv_xml_parser_section_t; + +struct _lv_xml_parser_state_t { + lv_xml_component_scope_t scope; + lv_ll_t parent_ll; + lv_obj_t * parent; + lv_obj_t * item; + lv_obj_t * view; /*Pointer to the created view during component creation*/ + const char ** parent_attrs; + lv_xml_component_scope_t * parent_scope; + lv_xml_parser_section_t section; +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void lv_xml_parser_state_init(lv_xml_parser_state_t * state); + +void lv_xml_parser_start_section(lv_xml_parser_state_t * state, const char * name); + +void lv_xml_parser_end_section(lv_xml_parser_state_t * state, const char * name); + +void * lv_xml_state_get_parent(lv_xml_parser_state_t * state); + +void * lv_xml_state_get_item(lv_xml_parser_state_t * state); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_PARSER_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_private.h b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_private.h new file mode 100644 index 000000000..71abee3da --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_private.h @@ -0,0 +1,64 @@ +/** + * @file lv_xml_ptivate.h + * + */ + +#ifndef LV_XML_PRIVATE_H +#define LV_XML_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "lv_xml.h" +#if LV_USE_XML + +#include "parsers/lv_xml_obj_parser.h" +#include "lv_xml_parser.h" +#include "lv_xml_base_types.h" +#include "lv_xml_utils.h" +#include "lv_xml_style.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + const char * name; + const lv_font_t * font; + void (*font_destroy_cb)(lv_font_t *); +} lv_xml_font_t; + +typedef struct { + const char * name; + const void * src; +} lv_xml_image_t; + +typedef struct { + const char * name; + lv_event_cb_t cb; +} lv_xml_event_cb_t; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_PRIVATE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_style.c b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_style.c new file mode 100644 index 000000000..3706ba139 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_style.c @@ -0,0 +1,541 @@ +/** + * @file lv_xml_style.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "../../lvgl.h" +#if LV_USE_XML + +#include "lv_xml_base_types.h" +#include "lv_xml_parser.h" +#include "lv_xml_style.h" +#include "lv_xml_utils.h" +#include "lv_xml_component_private.h" +#include + +/********************* + * DEFINES + *********************/ +#ifdef _MSC_VER + #define strtok_r strtok_s // Use strtok_s as an equivalent to strtok_r in Visual Studio +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_style_prop_t style_prop_text_to_enum(const char * txt); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/*Expands to e.g. + if(lv_streq(name, "height")) lv_style_set_height(style, lv_xml_to_size(value)); + */ +#define SET_STYLE_IF(prop, value) if(lv_streq(name, #prop)) lv_style_set_##prop(style, value) + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_state_t lv_xml_style_state_to_enum(const char * txt) +{ + if(lv_streq("default", txt)) return LV_STATE_DEFAULT; + else if(lv_streq("pressed", txt)) return LV_STATE_PRESSED; + else if(lv_streq("checked", txt)) return LV_STATE_CHECKED; + else if(lv_streq("scrolled", txt)) return LV_STATE_SCROLLED; + else if(lv_streq("focused", txt)) return LV_STATE_FOCUSED; + else if(lv_streq("focus_key", txt)) return LV_STATE_FOCUS_KEY; + else if(lv_streq("edited", txt)) return LV_STATE_EDITED; + else if(lv_streq("hovered", txt)) return LV_STATE_HOVERED; + else if(lv_streq("disabled", txt)) return LV_STATE_DISABLED; + + return 0; /*Return 0 in lack of a better option. */ +} + +lv_part_t lv_xml_style_part_to_enum(const char * txt) +{ + if(lv_streq("main", txt)) return LV_PART_MAIN; + else if(lv_streq("scrollbar", txt)) return LV_PART_SCROLLBAR; + else if(lv_streq("indicator", txt)) return LV_PART_INDICATOR; + else if(lv_streq("knob", txt)) return LV_PART_KNOB; + else if(lv_streq("selected", txt)) return LV_PART_SELECTED; + else if(lv_streq("items", txt)) return LV_PART_ITEMS; + else if(lv_streq("cursor", txt)) return LV_PART_CURSOR; + + return 0; /*Return 0 in lack of a better option. */ +} + +lv_result_t lv_xml_style_register(lv_xml_component_scope_t * scope, const char ** attrs) +{ + const char * style_name = lv_xml_get_value_of(attrs, "name"); + if(style_name == NULL) { + LV_LOG_WARN("'name' is missing from a style"); + return LV_RESULT_INVALID; + } + + if(scope == NULL) scope = lv_xml_component_get_scope("globals"); + if(scope == NULL) return LV_RESULT_INVALID; + + + lv_xml_style_t * xml_style; + /*If a style with the same name is already created, use it */ + bool found = false; + LV_LL_READ(&scope->style_ll, xml_style) { + if(lv_streq(xml_style->name, style_name)) { + found = true; + LV_LOG_INFO("Style %s is already registered. Extending it with new properties.", style_name); + break; + } + } + + if(!found) { + xml_style = lv_ll_ins_tail(&scope->style_ll); + xml_style->name = lv_strdup(style_name); + lv_style_init(&xml_style->style); + size_t long_name_len = lv_strlen(scope->name) + 1 + lv_strlen(style_name) + 1; + xml_style->long_name = lv_malloc(long_name_len); + lv_snprintf((char *)xml_style->long_name, long_name_len, "%s.%s", scope->name, style_name); /*E.g. my_button.style1*/ + } + + lv_style_t * style = &xml_style->style; + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + if(lv_streq(name, "name")) continue; + if(lv_streq(name, "help")) continue; + if(lv_streq(name, "figma_node_id")) continue; + + if(value[0] == '#') { + const char * value_clean = &value[1]; + lv_xml_const_t * c; + LV_LL_READ(&scope->const_ll, c) { + if(lv_streq(c->name, value_clean)) { + value = c->value; + break; + } + } + } + + if(lv_streq(value, "remove")) { + lv_style_prop_t prop = style_prop_text_to_enum(name); + if(prop != LV_STYLE_PROP_INV) lv_style_remove_prop(style, prop); + else if(lv_streq(name, "pad_all")) { + lv_style_remove_prop(style, LV_STYLE_PAD_TOP); + lv_style_remove_prop(style, LV_STYLE_PAD_BOTTOM); + lv_style_remove_prop(style, LV_STYLE_PAD_LEFT); + lv_style_remove_prop(style, LV_STYLE_PAD_RIGHT); + } + else if(lv_streq(name, "pad_hor")) { + lv_style_remove_prop(style, LV_STYLE_PAD_LEFT); + lv_style_remove_prop(style, LV_STYLE_PAD_RIGHT); + } + else if(lv_streq(name, "pad_ver")) { + lv_style_remove_prop(style, LV_STYLE_PAD_TOP); + lv_style_remove_prop(style, LV_STYLE_PAD_BOTTOM); + } + else if(lv_streq(name, "pad_gap")) { + lv_style_remove_prop(style, LV_STYLE_PAD_COLUMN); + lv_style_remove_prop(style, LV_STYLE_PAD_ROW); + } + else if(lv_streq(name, "margin_all")) { + lv_style_remove_prop(style, LV_STYLE_MARGIN_TOP); + lv_style_remove_prop(style, LV_STYLE_MARGIN_BOTTOM); + lv_style_remove_prop(style, LV_STYLE_MARGIN_LEFT); + lv_style_remove_prop(style, LV_STYLE_MARGIN_RIGHT); + } + else if(lv_streq(name, "margin_hor")) { + lv_style_remove_prop(style, LV_STYLE_MARGIN_LEFT); + lv_style_remove_prop(style, LV_STYLE_MARGIN_RIGHT); + } + else if(lv_streq(name, "margin_ver")) { + lv_style_remove_prop(style, LV_STYLE_MARGIN_TOP); + lv_style_remove_prop(style, LV_STYLE_MARGIN_BOTTOM); + } + } + else SET_STYLE_IF(width, lv_xml_to_size(value)); + else SET_STYLE_IF(min_width, lv_xml_to_size(value)); + else SET_STYLE_IF(max_width, lv_xml_to_size(value)); + else SET_STYLE_IF(height, lv_xml_to_size(value)); + else SET_STYLE_IF(min_height, lv_xml_to_size(value)); + else SET_STYLE_IF(max_height, lv_xml_to_size(value)); + else SET_STYLE_IF(length, lv_xml_to_size(value)); + else SET_STYLE_IF(radius, lv_xml_to_size(value)); + + else SET_STYLE_IF(pad_left, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_right, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_top, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_bottom, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_hor, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_ver, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_all, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_row, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_column, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_gap, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_radial, lv_xml_atoi(value)); + + else SET_STYLE_IF(margin_left, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_right, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_top, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_bottom, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_hor, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_ver, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_all, lv_xml_atoi(value)); + + else SET_STYLE_IF(base_dir, lv_xml_base_dir_to_enum(value)); + else SET_STYLE_IF(clip_corner, lv_xml_to_bool(value)); + + else SET_STYLE_IF(bg_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(bg_color, lv_xml_to_color(value)); + else SET_STYLE_IF(bg_grad_dir, lv_xml_grad_dir_to_enum(value)); + else SET_STYLE_IF(bg_grad_color, lv_xml_to_color(value)); + else SET_STYLE_IF(bg_main_stop, lv_xml_atoi(value)); + else SET_STYLE_IF(bg_grad_stop, lv_xml_atoi(value)); + else SET_STYLE_IF(bg_grad, lv_xml_component_get_grad(scope, value)); + + else SET_STYLE_IF(bg_image_src, lv_xml_get_image(scope, value)); + else SET_STYLE_IF(bg_image_tiled, lv_xml_to_bool(value)); + else SET_STYLE_IF(bg_image_recolor, lv_xml_to_color(value)); + else SET_STYLE_IF(bg_image_recolor_opa, lv_xml_to_opa(value)); + + else SET_STYLE_IF(border_color, lv_xml_to_color(value)); + else SET_STYLE_IF(border_width, lv_xml_atoi(value)); + else SET_STYLE_IF(border_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(border_side, lv_xml_border_side_to_enum(value)); + else SET_STYLE_IF(border_post, lv_xml_to_bool(value)); + + else SET_STYLE_IF(outline_color, lv_xml_to_color(value)); + else SET_STYLE_IF(outline_width, lv_xml_atoi(value)); + else SET_STYLE_IF(outline_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(outline_pad, lv_xml_atoi(value)); + + else SET_STYLE_IF(shadow_width, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_color, lv_xml_to_color(value)); + else SET_STYLE_IF(shadow_offset_x, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_offset_y, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_spread, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_opa, lv_xml_to_opa(value)); + + else SET_STYLE_IF(text_color, lv_xml_to_color(value)); + else SET_STYLE_IF(text_font, lv_xml_get_font(scope, value)); + else SET_STYLE_IF(text_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(text_align, lv_xml_text_align_to_enum(value)); + else SET_STYLE_IF(text_letter_space, lv_xml_atoi(value)); + else SET_STYLE_IF(text_line_space, lv_xml_atoi(value)); + else SET_STYLE_IF(text_decor, lv_xml_text_decor_to_enum(value)); + + else SET_STYLE_IF(image_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(image_recolor, lv_xml_to_color(value)); + else SET_STYLE_IF(image_recolor_opa, lv_xml_to_opa(value)); + + else SET_STYLE_IF(line_color, lv_xml_to_color(value)); + else SET_STYLE_IF(line_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(line_width, lv_xml_atoi(value)); + else SET_STYLE_IF(line_dash_width, lv_xml_atoi(value)); + else SET_STYLE_IF(line_dash_gap, lv_xml_atoi(value)); + else SET_STYLE_IF(line_rounded, lv_xml_to_bool(value)); + + else SET_STYLE_IF(arc_color, lv_xml_to_color(value)); + else SET_STYLE_IF(arc_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(arc_width, lv_xml_atoi(value)); + else SET_STYLE_IF(arc_rounded, lv_xml_to_bool(value)); + else SET_STYLE_IF(arc_image_src, lv_xml_get_image(scope, value)); + + else SET_STYLE_IF(opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(opa_layered, lv_xml_to_opa(value)); + else SET_STYLE_IF(color_filter_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(anim_duration, lv_xml_atoi(value)); + else SET_STYLE_IF(blend_mode, lv_xml_blend_mode_to_enum(value)); + else SET_STYLE_IF(transform_width, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_height, lv_xml_atoi(value)); + else SET_STYLE_IF(translate_x, lv_xml_atoi(value)); + else SET_STYLE_IF(translate_y, lv_xml_atoi(value)); + else SET_STYLE_IF(translate_radial, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_scale_x, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_scale_y, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_rotation, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_pivot_x, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_pivot_y, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_skew_x, lv_xml_atoi(value)); + else SET_STYLE_IF(bitmap_mask_src, lv_xml_get_image(scope, value)); + else SET_STYLE_IF(rotary_sensitivity, lv_xml_atoi(value)); + else SET_STYLE_IF(recolor, lv_xml_to_color(value)); + else SET_STYLE_IF(recolor_opa, lv_xml_to_opa(value)); + + else SET_STYLE_IF(layout, lv_xml_layout_to_enum(value)); + + else SET_STYLE_IF(flex_flow, lv_xml_flex_flow_to_enum(value)); + else SET_STYLE_IF(flex_grow, lv_xml_atoi(value)); + else SET_STYLE_IF(flex_main_place, lv_xml_flex_align_to_enum(value)); + else SET_STYLE_IF(flex_cross_place, lv_xml_flex_align_to_enum(value)); + else SET_STYLE_IF(flex_track_place, lv_xml_flex_align_to_enum(value)); + + else SET_STYLE_IF(grid_column_align, lv_xml_grid_align_to_enum(value)); + else SET_STYLE_IF(grid_row_align, lv_xml_grid_align_to_enum(value)); + else SET_STYLE_IF(grid_cell_column_pos, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_column_span, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_x_align, lv_xml_grid_align_to_enum(value)); + else SET_STYLE_IF(grid_cell_row_pos, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_row_span, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_y_align, lv_xml_grid_align_to_enum(value)); + + + else { + LV_LOG_WARN("%s style property is not supported", name); + } + } + + return LV_RESULT_OK; +} + +const char * lv_xml_style_string_process(char * txt, lv_style_selector_t * selector) +{ + *selector = 0; + + char * style_name = lv_xml_split_str(&txt, ':'); + char * selector_str = lv_xml_split_str(&txt, ':'); + while(selector_str != NULL) { + /* Handle different states and parts */ + *selector |= lv_xml_style_state_to_enum(selector_str); + *selector |= lv_xml_style_part_to_enum(selector_str); + + /* Move to the next token */ + selector_str = lv_xml_split_str(&txt, ':'); + } + + return style_name; +} + +void lv_xml_style_add_to_obj(lv_xml_parser_state_t * state, lv_obj_t * obj, const char * text) +{ + char * str = lv_strdup(text); + char * str_ori = str; + + /* Split the string based on space and colons */ + char * onestyle_str = lv_xml_split_str(&str, ' '); + while(onestyle_str != NULL) { + /* Parse the parts and states after the space */ + lv_style_selector_t selector = 0; + const char * style_name = lv_xml_style_string_process(onestyle_str, &selector); + if(style_name != NULL) { + lv_xml_style_t * xml_style = NULL; + /*Resolve parameters or just find the style*/ + if(style_name[0] == '$') { + /*E.g. `$pr_style` style name means use the value + *coming from the parent's `pr_style` named attribute*/ + const char * name_clean = &style_name[1]; + const char * parent_style_name = lv_xml_get_value_of(state->parent_attrs, name_clean); + if(parent_style_name) { + xml_style = lv_xml_get_style_by_name(state->parent_scope, parent_style_name); + } + } + else { + xml_style = lv_xml_get_style_by_name(&state->scope, style_name); + } + if(xml_style) { + /* Apply with the selector */ + lv_obj_add_style(obj, &xml_style->style, selector); + } + } + onestyle_str = lv_xml_split_str(&str, ' '); + } + + lv_free(str_ori); +} + +lv_xml_style_t * lv_xml_get_style_by_name(lv_xml_component_scope_t * scope, const char * style_name_raw) +{ + const char * style_name = strrchr(style_name_raw, '.'); + + if(style_name) { + char component_name[256]; + size_t len = (size_t)(style_name - style_name_raw); + lv_memcpy(component_name, style_name_raw, len); + component_name[len] = '\0'; + scope = lv_xml_component_get_scope(component_name); + if(scope == NULL) { + LV_LOG_WARN("'%s' component or widget is not found", component_name); + } + style_name++; /*Skip the dot*/ + } + else { + style_name = style_name_raw; + } + + /*Use the global scope is not specified*/ + if(scope == NULL) scope = lv_xml_component_get_scope("globals"); + if(scope == NULL) return NULL; + + lv_xml_style_t * xml_style; + LV_LL_READ(&scope->style_ll, xml_style) { + if(lv_streq(xml_style->name, style_name)) return xml_style; + } + + /*If not found in the component check the global space*/ + if(!lv_streq(scope->name, "globals")) { + scope = lv_xml_component_get_scope("globals"); + if(scope) { + LV_LL_READ(&scope->style_ll, xml_style) { + if(lv_streq(xml_style->name, style_name)) return xml_style; + } + } + } + + LV_LOG_WARN("No style found with %s name", style_name_raw); + + return NULL; +} + +lv_grad_dsc_t * lv_xml_component_get_grad(lv_xml_component_scope_t * scope, const char * name) +{ + lv_xml_grad_t * d; + LV_LL_READ(&scope->gradient_ll, d) { + if(lv_streq(d->name, name)) return &d->grad_dsc; + } + + return NULL; +} + + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_style_prop_t style_prop_text_to_enum(const char * txt) +{ + if(lv_streq(txt, "width")) return LV_STYLE_WIDTH; + if(lv_streq(txt, "min_width")) return LV_STYLE_MIN_WIDTH; + if(lv_streq(txt, "max_width")) return LV_STYLE_MAX_WIDTH; + else if(lv_streq(txt, "height")) return LV_STYLE_HEIGHT; + else if(lv_streq(txt, "min_height")) return LV_STYLE_MIN_HEIGHT; + else if(lv_streq(txt, "max_height")) return LV_STYLE_MAX_HEIGHT; + else if(lv_streq(txt, "length")) return LV_STYLE_LENGTH; + else if(lv_streq(txt, "radius")) return LV_STYLE_RADIUS; + + else if(lv_streq(txt, "pad_left")) return LV_STYLE_PAD_LEFT; + else if(lv_streq(txt, "pad_right")) return LV_STYLE_PAD_RIGHT; + else if(lv_streq(txt, "pad_top")) return LV_STYLE_PAD_TOP; + else if(lv_streq(txt, "pad_bottom")) return LV_STYLE_PAD_BOTTOM; + else if(lv_streq(txt, "pad_row")) return LV_STYLE_PAD_ROW; + else if(lv_streq(txt, "pad_column")) return LV_STYLE_PAD_COLUMN; + else if(lv_streq(txt, "pad_radial")) return LV_STYLE_PAD_RADIAL; + + else if(lv_streq(txt, "margin_left")) return LV_STYLE_MARGIN_LEFT; + else if(lv_streq(txt, "margin_right")) return LV_STYLE_MARGIN_RIGHT; + else if(lv_streq(txt, "margin_top")) return LV_STYLE_MARGIN_TOP; + else if(lv_streq(txt, "margin_bottom")) return LV_STYLE_MARGIN_BOTTOM; + + else if(lv_streq(txt, "base_dir")) return LV_STYLE_BASE_DIR; + else if(lv_streq(txt, "clip_corner")) return LV_STYLE_CLIP_CORNER; + + else if(lv_streq(txt, "bg_opa")) return LV_STYLE_BG_OPA; + else if(lv_streq(txt, "bg_color")) return LV_STYLE_BG_COLOR; + else if(lv_streq(txt, "bg_grad_dir")) return LV_STYLE_BG_GRAD_DIR; + else if(lv_streq(txt, "bg_grad_color")) return LV_STYLE_BG_GRAD_COLOR; + else if(lv_streq(txt, "bg_main_stop")) return LV_STYLE_BG_MAIN_STOP; + else if(lv_streq(txt, "bg_grad_stop")) return LV_STYLE_BG_GRAD_STOP; + else if(lv_streq(txt, "bg_grad")) return LV_STYLE_BG_GRAD; + + else if(lv_streq(txt, "bg_image_src")) return LV_STYLE_BG_IMAGE_SRC; + else if(lv_streq(txt, "bg_image_tiled")) return LV_STYLE_BG_IMAGE_TILED; + else if(lv_streq(txt, "bg_image_recolor")) return LV_STYLE_BG_IMAGE_RECOLOR; + else if(lv_streq(txt, "bg_image_recolor_opa")) return LV_STYLE_BG_IMAGE_RECOLOR_OPA; + + else if(lv_streq(txt, "border_color")) return LV_STYLE_BORDER_COLOR; + else if(lv_streq(txt, "border_width")) return LV_STYLE_BORDER_WIDTH; + else if(lv_streq(txt, "border_opa")) return LV_STYLE_BORDER_OPA; + else if(lv_streq(txt, "border_side")) return LV_STYLE_BORDER_SIDE; + else if(lv_streq(txt, "border_post")) return LV_STYLE_BORDER_POST; + + else if(lv_streq(txt, "outline_color")) return LV_STYLE_OUTLINE_COLOR; + else if(lv_streq(txt, "outline_width")) return LV_STYLE_OUTLINE_WIDTH; + else if(lv_streq(txt, "outline_opa")) return LV_STYLE_OUTLINE_OPA; + else if(lv_streq(txt, "outline_pad")) return LV_STYLE_OUTLINE_PAD; + + else if(lv_streq(txt, "shadow_width")) return LV_STYLE_SHADOW_WIDTH; + else if(lv_streq(txt, "shadow_color")) return LV_STYLE_SHADOW_COLOR; + else if(lv_streq(txt, "shadow_offset_x")) return LV_STYLE_SHADOW_OFFSET_X; + else if(lv_streq(txt, "shadow_offset_y")) return LV_STYLE_SHADOW_OFFSET_Y; + else if(lv_streq(txt, "shadow_spread")) return LV_STYLE_SHADOW_SPREAD; + else if(lv_streq(txt, "shadow_opa")) return LV_STYLE_SHADOW_OPA; + + else if(lv_streq(txt, "text_color")) return LV_STYLE_TEXT_COLOR; + else if(lv_streq(txt, "text_font")) return LV_STYLE_TEXT_FONT; + else if(lv_streq(txt, "text_opa")) return LV_STYLE_TEXT_OPA; + else if(lv_streq(txt, "text_align")) return LV_STYLE_TEXT_ALIGN; + else if(lv_streq(txt, "text_letter_space")) return LV_STYLE_TEXT_LETTER_SPACE; + else if(lv_streq(txt, "text_line_space")) return LV_STYLE_TEXT_LINE_SPACE; + else if(lv_streq(txt, "text_decor")) return LV_STYLE_TEXT_DECOR; + + else if(lv_streq(txt, "image_opa")) return LV_STYLE_IMAGE_OPA; + else if(lv_streq(txt, "image_recolor")) return LV_STYLE_IMAGE_RECOLOR; + else if(lv_streq(txt, "image_recolor_opa")) return LV_STYLE_IMAGE_RECOLOR_OPA; + + else if(lv_streq(txt, "line_color")) return LV_STYLE_LINE_COLOR; + else if(lv_streq(txt, "line_opa")) return LV_STYLE_LINE_OPA; + else if(lv_streq(txt, "line_width")) return LV_STYLE_LINE_WIDTH; + else if(lv_streq(txt, "line_dash_width")) return LV_STYLE_LINE_DASH_WIDTH; + else if(lv_streq(txt, "line_dash_gap")) return LV_STYLE_LINE_DASH_GAP; + else if(lv_streq(txt, "line_rounded")) return LV_STYLE_LINE_ROUNDED; + + else if(lv_streq(txt, "arc_color")) return LV_STYLE_ARC_COLOR; + else if(lv_streq(txt, "arc_opa")) return LV_STYLE_ARC_OPA; + else if(lv_streq(txt, "arc_width")) return LV_STYLE_ARC_WIDTH; + else if(lv_streq(txt, "arc_rounded")) return LV_STYLE_ARC_ROUNDED; + else if(lv_streq(txt, "arc_image_src")) return LV_STYLE_ARC_IMAGE_SRC; + + else if(lv_streq(txt, "opa")) return LV_STYLE_OPA; + else if(lv_streq(txt, "opa_layered")) return LV_STYLE_OPA_LAYERED; + else if(lv_streq(txt, "color_filter_opa")) return LV_STYLE_COLOR_FILTER_OPA; + else if(lv_streq(txt, "anim_duration")) return LV_STYLE_ANIM_DURATION; + else if(lv_streq(txt, "blend_mode")) return LV_STYLE_BLEND_MODE; + else if(lv_streq(txt, "transform_width")) return LV_STYLE_TRANSFORM_WIDTH; + else if(lv_streq(txt, "transform_height")) return LV_STYLE_TRANSFORM_HEIGHT; + else if(lv_streq(txt, "translate_x")) return LV_STYLE_TRANSLATE_X; + else if(lv_streq(txt, "translate_y")) return LV_STYLE_TRANSLATE_Y; + else if(lv_streq(txt, "translate_radial")) return LV_STYLE_TRANSLATE_RADIAL; + else if(lv_streq(txt, "transform_scale_x")) return LV_STYLE_TRANSFORM_SCALE_X; + else if(lv_streq(txt, "transform_scale_y")) return LV_STYLE_TRANSFORM_SCALE_Y; + else if(lv_streq(txt, "transform_rotation")) return LV_STYLE_TRANSFORM_ROTATION; + else if(lv_streq(txt, "transform_pivot_x")) return LV_STYLE_TRANSFORM_PIVOT_X; + else if(lv_streq(txt, "transform_pivot_y")) return LV_STYLE_TRANSFORM_PIVOT_Y; + else if(lv_streq(txt, "transform_skew_x")) return LV_STYLE_TRANSFORM_SKEW_X; + else if(lv_streq(txt, "bitmap_mask_src")) return LV_STYLE_BITMAP_MASK_SRC; + else if(lv_streq(txt, "rotary_sensitivity")) return LV_STYLE_ROTARY_SENSITIVITY; + else if(lv_streq(txt, "recolor")) return LV_STYLE_RECOLOR; + else if(lv_streq(txt, "recolor_opa")) return LV_STYLE_RECOLOR_OPA; + + else if(lv_streq(txt, "layout")) return LV_STYLE_LAYOUT; + + else if(lv_streq(txt, "flex_flow")) return LV_STYLE_FLEX_FLOW; + else if(lv_streq(txt, "flex_grow")) return LV_STYLE_FLEX_GROW; + else if(lv_streq(txt, "flex_main_place")) return LV_STYLE_FLEX_MAIN_PLACE; + else if(lv_streq(txt, "flex_cross_place")) return LV_STYLE_FLEX_CROSS_PLACE; + else if(lv_streq(txt, "flex_track_place")) return LV_STYLE_FLEX_TRACK_PLACE; + + else if(lv_streq(txt, "grid_column_align")) return LV_STYLE_GRID_COLUMN_ALIGN; + else if(lv_streq(txt, "grid_row_align")) return LV_STYLE_GRID_ROW_ALIGN; + else if(lv_streq(txt, "grid_cell_column_pos")) return LV_STYLE_GRID_CELL_COLUMN_POS; + else if(lv_streq(txt, "grid_cell_column_span")) return LV_STYLE_GRID_CELL_COLUMN_SPAN; + else if(lv_streq(txt, "grid_cell_x_align")) return LV_STYLE_GRID_CELL_X_ALIGN; + else if(lv_streq(txt, "grid_cell_row_pos")) return LV_STYLE_GRID_CELL_ROW_POS; + else if(lv_streq(txt, "grid_cell_row_span")) return LV_STYLE_GRID_CELL_ROW_SPAN; + else if(lv_streq(txt, "grid_cell_y_align")) return LV_STYLE_GRID_CELL_Y_ALIGN; + + return LV_STYLE_PROP_INV; + +} + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_style.h b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_style.h new file mode 100644 index 000000000..2e975aa44 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_style.h @@ -0,0 +1,99 @@ +/** + * @file lv_xml_style.h + * + */ + +#ifndef LV_XML_STYLE_H +#define LV_XML_STYLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_types.h" +#include "../../misc/lv_style.h" +#include "../../core/lv_obj_style.h" + +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +typedef struct _lv_xml_style_t { + const char * name; + const char * long_name; + lv_style_t style; +} lv_xml_style_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Add a style to `ctx` and set the style properties from `attrs` + * @param scope add styles here. (Constants should be already added as style properties might use them) + * @param attrs list of attribute names and values + */ +lv_result_t lv_xml_style_register(lv_xml_component_scope_t * scope, const char ** attrs); + +/** + * Add the styles to an object. Handles multiple styles and selectors too. + * @param state the parser state + * @param obj the target widget + * @param text the styles' string, e.g. "blue red:pressed:knob" + */ +void lv_xml_style_add_to_obj(lv_xml_parser_state_t * state, lv_obj_t * obj, const char * text); + +/** + * Convert a style state to enum + * @param txt e.g. "pressed" + * @return the enum `LV_STATE_PRESSED` + */ +lv_state_t lv_xml_style_state_to_enum(const char * txt); + +/** + * Convert a style part to enum + * @param txt e.g. "knob" + * @return the enum `LV_PART_KNOB` + */ +lv_part_t lv_xml_style_part_to_enum(const char * txt); + +/** + * Decompose a string like `"style1:pressed:checked:knob"` to style name and selector + * @param txt the input string + * @param selector store the selectors here + * @return the style name or `NULL` on any error + */ +const char * lv_xml_style_string_process(char * txt, lv_style_selector_t * selector); + +/** + * Find a style by name which was added by `lv_xml_style_register` + * @param scope the default context to search in + * @param name the name of the style. Can start with a component name prefix (e.g. `my_button.blue`) to overwrite the ctx + * @return the style structure + */ +lv_xml_style_t * lv_xml_get_style_by_name(lv_xml_component_scope_t * scope, const char * name); + +/** + * Get a gradient descriptor defined for a component + * @param scope component context where the gradient should be found + * @param name name of the gradient + * @return a gradient descriptor + */ +lv_grad_dsc_t * lv_xml_component_get_grad(lv_xml_component_scope_t * scope, const char * name); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_STYLE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_update.c b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_update.c new file mode 100644 index 000000000..5741e5e9f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_update.c @@ -0,0 +1,124 @@ +/** + * @file lv_xml_update.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_update.h" +#if LV_USE_XML && LV_USE_OBJ_NAME + +#include "../../lvgl.h" +#include "lv_xml_widget.h" +#include "lv_xml_parser.h" +#include "../../libs/expat/expat.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void start_handler(void * user_data, const char * name, const char ** attrs); +static void end_handler(void * user_data, const char * name); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + + +lv_result_t lv_xml_update_from_data(const char * xml_def) +{ + /*Create a dummy parser state*/ + lv_xml_parser_state_t state; + lv_xml_parser_state_init(&state); + + /* Parse the XML to extract metadata */ + XML_Parser parser = XML_ParserCreate(NULL); + XML_SetUserData(parser, &state); + XML_SetElementHandler(parser, start_handler, end_handler); + + if(XML_Parse(parser, xml_def, lv_strlen(xml_def), XML_TRUE) == XML_STATUS_ERROR) { + LV_LOG_ERROR("XML parsing error: %s on line %lu", + XML_ErrorString(XML_GetErrorCode(parser)), + (unsigned long)XML_GetCurrentLineNumber(parser)); + XML_ParserFree(parser); + return LV_RESULT_INVALID; + } + XML_ParserFree(parser); + return LV_RESULT_OK; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void start_handler(void * user_data, const char * name, const char ** attrs) +{ + lv_xml_parser_state_t * state = (lv_xml_parser_state_t *)user_data; + + size_t update_len = lv_strlen("update-"); + size_t name_len = lv_strlen(name); + if(name_len < update_len) { + LV_LOG_WARN("%s doesn't start with `update-`", name); + return; + } + + if(lv_memcmp(name, "update-", update_len)) { + LV_LOG_WARN("%s doesn't start with `update-`", name); + return; + } + + name = &name[update_len]; /*Get e.g. update-lv_slider -> lv_slider*/ + name_len -= update_len; + + lv_widget_processor_t * proc = lv_xml_widget_get_processor(name); + if(proc == NULL) { + LV_LOG_WARN("%s is not a known widget", name); + return; + } + + const char * widget_name = lv_xml_get_value_of(attrs, "name"); + if(widget_name == NULL) { + LV_LOG_WARN("There is no name property"); + return; + } + + lv_obj_t * obj = lv_obj_get_child_by_name(lv_screen_active(), widget_name); + if(obj == NULL) { + LV_LOG_WARN("No widget is found with the name of `%s`", widget_name); + return; + } + + /*Clean the name property the prevent applying it*/ + for(int i = 0; attrs[i]; i += 2) { + if(lv_streq(attrs[i], "name")) { + attrs[i] = ""; + attrs[i + 1] = ""; + } + } + state->item = obj; + proc->apply_cb(state, attrs); +} + +static void end_handler(void * user_data, const char * name) +{ + LV_UNUSED(user_data); + LV_UNUSED(name); +} + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_update.h b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_update.h new file mode 100644 index 000000000..5c1f12dd0 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_update.h @@ -0,0 +1,46 @@ +/** + * @file lv_xml_update.h + * + */ + +#ifndef LV_XML_UPDATE_H +#define LV_XML_UPDATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_types.h" +#if LV_USE_XML && LV_USE_OBJ_NAME + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Load the styles, constants, another data of the component. It needs to be called only once for each component. + * @param xml_def the XML definition of the component as a NULL terminated string + * @return LV_RES_OK: loaded successfully, LV_RES_INVALID: otherwise + */ +lv_result_t lv_xml_update_from_data(const char * xml_def); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_UPDATE_H*/ + + diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_utils.c b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_utils.c new file mode 100644 index 000000000..2c4d1cd6e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_utils.c @@ -0,0 +1,239 @@ +/** + * @file lv_xml_utils.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_utils.h" +#include "../../stdlib/lv_string.h" +#if LV_USE_XML + +#if LV_USE_STDLIB_STRING == LV_STDLIB_CLIB + #include +#endif + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static bool is_digit(char c, int base); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + + +const char * lv_xml_get_value_of(const char ** attrs, const char * name) +{ + if(attrs == NULL) return NULL; + if(name == NULL) return NULL; + + for(int i = 0; attrs[i]; i += 2) { + if(lv_streq(attrs[i], name)) return attrs[i + 1]; + } + + return NULL; +} + +lv_color_t lv_xml_to_color(const char * str) +{ + /*fff, #fff, 0xfff*/ + if(lv_strlen(str) <= 5) return lv_color_hex3(lv_xml_strtol(str, NULL, 16)); + /*ffffff, #ffffff, 0xffffff*/ + else return lv_color_hex(lv_xml_strtol(str, NULL, 16)); +} + +lv_opa_t lv_xml_to_opa(const char * str) +{ + int32_t v = lv_xml_atoi(str); + size_t len = lv_strlen(str); + if(str[len - 1] == '%') { + v = v * 255 / 100; + } + + v = LV_CLAMP(0, v, 255); + return (lv_opa_t)v; +} + +bool lv_xml_to_bool(const char * str) +{ + return lv_streq(str, "false") ? false : true; +} + +int32_t lv_xml_atoi_split(const char ** str, char delimiter) +{ + const char * s = *str; + int32_t result = 0; + int sign = 1; + + /* Skip leading whitespace */ + while(*s == ' ' || *s == '\t') s++; + + /* Handle optional sign */ + if(*s == '-') { + sign = -1; + s++; + } + else if(*s == '+') { + s++; + } + + /* Convert the string*/ + while(*s != delimiter) { + if(*s >= '0' && *s <= '9') { + int32_t digit = *s - '0'; + + result = result * 10 + digit; + s++; + } + else { + break; /* Non-digit character */ + } + } + + result = result * sign; + + if(*s != '\0') s++; /*Skip the delimiter*/ + *str = s; + return result; + +} + + +int32_t lv_xml_atoi(const char * str) +{ + + return lv_xml_atoi_split(&str, '\0'); + +} + +int32_t lv_xml_strtol(const char * str, char ** endptr, int32_t base) +{ + const char * s = str; + int32_t result = 0; + int32_t sign = 1; + + /* Skip leading whitespace */ + while(*s == ' ' || *s == '\t') s++; + + /* Handle optional sign*/ + if(*s == '-') { + sign = -1; + s++; + } + else if(*s == '+') { + s++; + } + + /* Determine base if 0 is passed as base*/ + if(base == 0) { + if(*s == '0') { + if(*(s + 1) == 'x' || *(s + 1) == 'X') { + base = 16; + s += 2; + } + else { + base = 8; + s++; + } + } + else { + base = 10; + } + } + + /* Convert the string*/ + while(*s) { + int32_t digit; + + if(is_digit(*s, base)) { + if(*s >= '0' && *s <= '9') { + digit = *s - '0'; + } + else if(*s >= 'a' && *s <= 'f') { + digit = *s - 'a' + 10; + } + else if(*s >= 'A' && *s <= 'F') { + digit = *s - 'A' + 10; + } + else { + /* This should not happen due to is_digit check*/ + break; + } + + /* Check for overflow */ + if(result > (INT32_MAX - digit) / base) { + result = (sign == 1) ? INT32_MAX : INT32_MIN; + if(endptr) *endptr = (char *)s; + return result; + } + + result = result * base + digit; + } + s++; + } + + /* Set end pointer to the last character processed*/ + if(endptr) { + *endptr = (char *)s; + } + + return result * sign; +} + +char * lv_xml_split_str(char ** src, char delimiter) +{ + if(*src[0] == '\0') return NULL; + + char * src_first = *src; + char * src_next = *src; + + /*Find the delimiter*/ + while(*src_next != '\0') { + if(*src_next == delimiter) { + *src_next = '\0'; /*Close the string on the delimiter*/ + *src = src_next + 1; /*Change the source continue after the found delimiter*/ + return src_first; + } + src_next++; + } + + /*No delimiter found, return the string as it is*/ + *src = src_next; /*Move the source point to the end*/ + + return src_first; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static bool is_digit(char c, int base) +{ + if(base <= 10) { + return (c >= '0' && c < '0' + base); + } + else { + return (c >= '0' && c <= '9') || (c >= 'a' && c < 'a' + (base - 10)) || (c >= 'A' && c < 'A' + (base - 10)); + } +} + + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_utils.h b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_utils.h new file mode 100644 index 000000000..d5bd5ec34 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_utils.h @@ -0,0 +1,67 @@ +/** + * @file lv_xml_utils.h + * + */ + +#ifndef LV_XML_UTILS_H +#define LV_XML_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../lv_conf_internal.h" +#if LV_USE_XML + +#include LV_STDINT_INCLUDE +#include "../../misc/lv_color.h" + +/********************** + * GLOBAL PROTOTYPES + **********************/ +const char * lv_xml_get_value_of(const char ** attrs, const char * name); + +int32_t lv_xml_atoi(const char * str); + + +/** + * Convert sections of a string to int. + * The end of the string is indicated by the `delimiter`. + * @param str pointer to a string, it will point to the character after the delimiter + * @param delimiter a character to indicate the end of the int + * @return the int before the next delimiter + */ +int32_t lv_xml_atoi_split(const char ** str, char delimiter); + +lv_color_t lv_xml_to_color(const char * str); + +/** + * Concert percentage or integer opacity value from string to integer. + * @param str e.g. "70%" or 180 + * @return 0..255 + */ +lv_opa_t lv_xml_to_opa(const char * str); + +bool lv_xml_to_bool(const char * str); + +int32_t lv_xml_strtol(const char * str, char ** endptr, int32_t base); + +/** + * Find a delimiter in a string, terminate the string on the delimiter and + * update the source string to the next part + * @param src point to a variable containing the input string + * @param delimiter a delimiter character, e.g. ':' + * @return the beginning of next section in the string closed at the delimiter + */ +char * lv_xml_split_str(char ** src, char delimiter); + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_UTILS_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_widget.c b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_widget.c new file mode 100644 index 000000000..6a448618a --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_widget.c @@ -0,0 +1,102 @@ +/** + * @file lv_xml_widget.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_widget.h" +#include "lv_xml_parser.h" +#include "../../stdlib/lv_string.h" +#include "../../stdlib/lv_mem.h" + +#if LV_USE_XML + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ +static lv_widget_processor_t * widget_processor_head; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_result_t lv_xml_widget_register(const char * name, lv_xml_widget_create_cb_t create_cb, + lv_xml_widget_apply_cb_t apply_cb) +{ + lv_widget_processor_t * p = lv_malloc(sizeof(lv_widget_processor_t)); + lv_memzero(p, sizeof(lv_widget_processor_t)); + + p->name = lv_strdup(name); + p->create_cb = create_cb; + p->apply_cb = apply_cb; + + if(widget_processor_head == NULL) widget_processor_head = p; + else { + p->next = widget_processor_head; + widget_processor_head = p; + } + return LV_RESULT_OK; +} + +lv_widget_processor_t * lv_xml_widget_get_processor(const char * name) +{ + /* Select the widget specific parser type based on the name */ + lv_widget_processor_t * p = widget_processor_head; + while(p) { + if(lv_streq(p->name, name)) { + return p; + } + + p = p->next; + } + return NULL; +} + +lv_widget_processor_t * lv_xml_widget_get_extended_widget_processor(const char * extends) +{ + lv_widget_processor_t * proc = NULL; + while(extends) { + proc = lv_xml_widget_get_processor(extends); + if(proc) break; + + lv_xml_component_scope_t * extended_component = lv_xml_component_get_scope(extends); + if(extended_component) { + extends = extended_component->extends; + } + else { + /*Not extending a known component or widget.*/ + break; + } + } + + if(proc == NULL) { + LV_LOG_WARN("The 'extend'ed widget is not found, using `lv_obj` as a fall back"); + proc = lv_xml_widget_get_processor("lv_obj"); + } + + return proc; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_widget.h b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_widget.h new file mode 100644 index 000000000..96690f0b5 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/lv_xml_widget.h @@ -0,0 +1,58 @@ +/** + * @file lv_xml_widget.h + * + */ + +#ifndef LV_XML_WIDGET_H +#define LV_XML_WIDGET_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_types.h" +#if LV_USE_XML + +#include "lv_xml.h" +#include "lv_xml_utils.h" + +/********************** + * TYPEDEFS + **********************/ + +typedef void * (*lv_xml_widget_create_cb_t)(lv_xml_parser_state_t * state, const char ** parent_attrs); +typedef void (*lv_xml_widget_apply_cb_t)(lv_xml_parser_state_t * state, const char ** parent_attrs); + +typedef struct _lv_widget_processor_t { + const char * name; + lv_xml_widget_create_cb_t create_cb; + lv_xml_widget_apply_cb_t apply_cb; + struct _lv_widget_processor_t * next; +} lv_widget_processor_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +lv_result_t lv_xml_widget_register(const char * name, lv_xml_widget_create_cb_t create_cb, + lv_xml_widget_apply_cb_t apply_cb); + +lv_widget_processor_t * lv_xml_widget_get_processor(const char * name); + +lv_widget_processor_t * lv_xml_widget_get_extended_widget_processor(const char * extends); +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_WIDGET_H*/ + + diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_arc_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_arc_parser.c new file mode 100644 index 000000000..8bab7ddd2 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_arc_parser.c @@ -0,0 +1,113 @@ +/** + * @file lv_xml_arc_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_arc_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_arc_mode_t mode_text_to_enum_value(const char * txt); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_arc_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + void * item = lv_arc_create(lv_xml_state_get_parent(state)); + return item; +} + +void lv_xml_arc_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("angles", name)) { + char buf[64]; + lv_strlcpy(buf, value, sizeof(buf)); + char * buf_p = buf; + int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); + int32_t v2 = lv_xml_atoi(buf_p); + lv_arc_set_angles(item, v1, v2); + } + else if(lv_streq("bg_angles", name)) { + char buf[64]; + lv_strlcpy(buf, value, sizeof(buf)); + char * buf_p = buf; + int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); + int32_t v2 = lv_xml_atoi(buf_p); + lv_arc_set_bg_angles(item, v1, v2); + } + else if(lv_streq("range", name)) { + char buf[64]; + lv_strlcpy(buf, value, sizeof(buf)); + char * buf_p = buf; + int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); + int32_t v2 = lv_xml_atoi(buf_p); + lv_arc_set_range(item, v1, v2); + } + else if(lv_streq("value", name)) { + lv_arc_set_value(item, lv_xml_atoi(value)); + } + else if(lv_streq("mode", name)) { + lv_arc_set_mode(item, mode_text_to_enum_value(value)); + } + else if(lv_streq("bind_value", name)) { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); + if(subject) { + lv_arc_bind_value(item, subject); + } + else { + LV_LOG_WARN("Subject \"%s\" doesn't exist in arc bind_value", value); + } + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + + +static lv_arc_mode_t mode_text_to_enum_value(const char * txt) +{ + if(lv_streq("normal", txt)) return LV_ARC_MODE_NORMAL; + if(lv_streq("symmetrical", txt)) return LV_ARC_MODE_SYMMETRICAL; + if(lv_streq("reverse", txt)) return LV_ARC_MODE_REVERSE; + + LV_LOG_WARN("%s is an unknown value for bar's mode", txt); + return 0; /*Return 0 in lack of a better option. */ +} +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_arc_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_arc_parser.h new file mode 100644 index 000000000..10afdcd96 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_arc_parser.h @@ -0,0 +1,40 @@ +/** + * @file lv_xml_arc_parser.h + * + */ + +#ifndef LV_ARC_XML_PARSER_H +#define LV_ARC_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_arc_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_arc_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ARC_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_bar_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_bar_parser.c new file mode 100644 index 000000000..1ee314aeb --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_bar_parser.c @@ -0,0 +1,111 @@ +/** + * @file lv_xml_bar_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_bar_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_bar_orientation_t orentation_text_to_enum_value(const char * txt); +static lv_bar_mode_t mode_text_to_enum_value(const char * txt); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_bar_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + void * item = lv_bar_create(lv_xml_state_get_parent(state)); + return item; +} + +void lv_xml_bar_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("value", name)) { + char buf[64]; + lv_strlcpy(buf, value, sizeof(buf)); + char * buf_p = buf; + int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); + bool v2 = lv_xml_to_bool(buf_p); + lv_bar_set_value(item, v1, v2); + } + if(lv_streq("start_value", name)) { + char buf[64]; + lv_strlcpy(buf, value, sizeof(buf)); + char * buf_p = buf; + int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); + bool v2 = lv_xml_to_bool(buf_p); + lv_bar_set_start_value(item, v1, v2); + } + if(lv_streq("orientation", name)) lv_bar_set_orientation(item, orentation_text_to_enum_value(value)); + if(lv_streq("mode", name)) lv_bar_set_mode(item, mode_text_to_enum_value(value)); + if(lv_streq("range", name)) { + char buf[64]; + lv_strlcpy(buf, value, sizeof(buf)); + char * buf_p = buf; + int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); + int32_t v2 = lv_xml_atoi(buf_p); + lv_bar_set_range(item, v1, v2); + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_bar_orientation_t orentation_text_to_enum_value(const char * txt) +{ + if(lv_streq("auto", txt)) return LV_BAR_ORIENTATION_AUTO; + if(lv_streq("horizontal", txt)) return LV_BAR_ORIENTATION_HORIZONTAL; + if(lv_streq("vertical", txt)) return LV_BAR_ORIENTATION_VERTICAL; + + LV_LOG_WARN("%s is an unknown value for bar's orientation", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +static lv_bar_mode_t mode_text_to_enum_value(const char * txt) +{ + if(lv_streq("normal", txt)) return LV_BAR_MODE_NORMAL; + if(lv_streq("range", txt)) return LV_BAR_MODE_RANGE; + if(lv_streq("symmetrical", txt)) return LV_BAR_MODE_SYMMETRICAL; + + LV_LOG_WARN("%s is an unknown value for bar's mode", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_bar_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_bar_parser.h new file mode 100644 index 000000000..84c53ce3a --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_bar_parser.h @@ -0,0 +1,40 @@ +/** + * @file lv_xml_bar_parser.h + * + */ + +#ifndef LV_BAR_XML_PARSER_H +#define LV_BAR_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_bar_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_bar_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BAR_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_button_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_button_parser.c new file mode 100644 index 000000000..0ab77008b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_button_parser.c @@ -0,0 +1,59 @@ +/** + * @file lv_xml_button_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_xml_button_parser.h" +#if LV_USE_XML +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_button_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + void * item = lv_button_create(lv_xml_state_get_parent(state)); + + return item; +} + +void lv_xml_button_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + /*Apply the common properties, e.g. width, height, styles flags etc*/ + lv_xml_obj_apply(state, attrs); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_button_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_button_parser.h new file mode 100644 index 000000000..7bfcf5be6 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_button_parser.h @@ -0,0 +1,41 @@ +/** + * @file lv_xml_button_parser.h + * + */ + +#ifndef LV_BUTTON_XML_PARSER_H +#define LV_BUTTON_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_button_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_button_apply(lv_xml_parser_state_t * state, const char ** attrs); + + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BUTTON_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_buttonmatrix_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_buttonmatrix_parser.c new file mode 100644 index 000000000..b92f631bc --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_buttonmatrix_parser.c @@ -0,0 +1,171 @@ +/** + * @file lv_xml_buttonmatrix_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_buttonmatrix_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_buttonmatrix_ctrl_t ctrl_text_to_enum_value(const char * txt); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_buttonmatrix_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + void * item = lv_buttonmatrix_create(lv_xml_state_get_parent(state)); + return item; +} + +void lv_xml_buttonmatrix_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("map", name)) { + char * value2 = lv_strdup(value); + uint32_t str_array_size = 8; + char ** str_array = lv_malloc(sizeof(char *) * str_array_size); + char * text_start = NULL; + /*Count the `'`s (`\'`) is an escape sequence*/ + uint32_t j = 0; + uint32_t btn_cnt = 0; + bool in_text = false; + for(j = 0; value2[j]; j++) { + /*Skip the escaped `\`*/ + if(value2[j] == '\\' && value2[j + 1] == '\\') { + j++; + continue; + } + + if(value2[j] == '\'') { + /*Not escaped*/ + if(j == 0 || value2[j - 1] != '\\') { + if(!in_text) { + in_text = true; + text_start = &value2[j + 1]; + } + /*Trailing*/ + else { + value2[j] = '\0'; + if(btn_cnt >= str_array_size) { + str_array_size += 4; + str_array = lv_realloc(str_array, sizeof(char *) * str_array_size); + } + if(lv_streq("\\n", text_start)) text_start = "\n"; + str_array[btn_cnt] = lv_strdup(text_start); + btn_cnt++; + in_text = false; + } + } + } + } + + lv_free(value2); + + if(btn_cnt >= str_array_size) { + str_array_size += 4; + str_array = lv_realloc(str_array, sizeof(char *) * str_array_size); + } + str_array[btn_cnt] = NULL; + + lv_buttonmatrix_set_map(item, (const char * const *)str_array); + ((lv_buttonmatrix_t *)item)->auto_free_map = 1; + } + else if(lv_streq("ctrl_map", name)) { + char buf[512]; + lv_strlcpy(buf, value, sizeof(buf)); + char * buf_p = buf; + char * ctrls_ored = lv_xml_split_str(&buf_p, ' '); + uint32_t btn_i = 0; + while(ctrls_ored) { + lv_buttonmatrix_ctrl_t ctrl_enum = 0; + char * ctrl = ctrls_ored; + ctrl = lv_xml_split_str(&ctrls_ored, '|'); + while(ctrl) { + ctrl_enum |= ctrl_text_to_enum_value(ctrl); + ctrl = lv_xml_split_str(&ctrls_ored, '|'); + } + lv_buttonmatrix_set_button_ctrl(item, btn_i, ctrl_enum); + ctrls_ored = lv_xml_split_str(&buf_p, ' '); + btn_i++; + } + } + else if(lv_streq("selected_button", name)) lv_buttonmatrix_set_selected_button(item, lv_xml_atoi(value)); + else if(lv_streq("one_checked", name)) lv_buttonmatrix_set_one_checked(item, lv_xml_to_bool(value)); + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_buttonmatrix_ctrl_t ctrl_text_to_enum_value(const char * txt) +{ + if(lv_streq("none", txt)) return LV_BUTTONMATRIX_CTRL_NONE; + if(lv_streq("width_1", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_1; + if(lv_streq("width_2", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_2; + if(lv_streq("width_3", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_3; + if(lv_streq("width_4", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_4; + if(lv_streq("width_5", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_5; + if(lv_streq("width_6", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_6; + if(lv_streq("width_7", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_7; + if(lv_streq("width_8", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_8; + if(lv_streq("width_9", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_9; + if(lv_streq("width_10", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_10; + if(lv_streq("width_11", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_11; + if(lv_streq("width_12", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_12; + if(lv_streq("width_13", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_13; + if(lv_streq("width_14", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_14; + if(lv_streq("width_15", txt)) return LV_BUTTONMATRIX_CTRL_WIDTH_15; + if(lv_streq("hidden", txt)) return LV_BUTTONMATRIX_CTRL_HIDDEN; + if(lv_streq("no_repeat", txt)) return LV_BUTTONMATRIX_CTRL_NO_REPEAT; + if(lv_streq("disabled", txt)) return LV_BUTTONMATRIX_CTRL_DISABLED; + if(lv_streq("checkable", txt)) return LV_BUTTONMATRIX_CTRL_CHECKABLE; + if(lv_streq("checked", txt)) return LV_BUTTONMATRIX_CTRL_CHECKED; + if(lv_streq("click_trig", txt)) return LV_BUTTONMATRIX_CTRL_CLICK_TRIG; + if(lv_streq("popover", txt)) return LV_BUTTONMATRIX_CTRL_POPOVER; + if(lv_streq("recolor", txt)) return LV_BUTTONMATRIX_CTRL_RECOLOR; + if(lv_streq("reserved_1", txt)) return LV_BUTTONMATRIX_CTRL_RESERVED_1; + if(lv_streq("reserved_2", txt)) return LV_BUTTONMATRIX_CTRL_RESERVED_2; + if(lv_streq("custom_1", txt)) return LV_BUTTONMATRIX_CTRL_CUSTOM_1; + if(lv_streq("custom_2", txt)) return LV_BUTTONMATRIX_CTRL_CUSTOM_2; + + LV_LOG_WARN("%s is an unknown value for buttonmatrix's map_ctrl", txt); + return 0; /*Return 0 in lack of a better option. */ +} + + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_buttonmatrix_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_buttonmatrix_parser.h new file mode 100644 index 000000000..c1099ec94 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_buttonmatrix_parser.h @@ -0,0 +1,41 @@ +/** + * @file lv_xml_buttonmatrix_parser.h + * + */ + +#ifndef LV_XML_BUTTONMATRIX_PARSER_H +#define LV_XML_BUTTONMATRIX_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_buttonmatrix_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_buttonmatrix_apply(lv_xml_parser_state_t * state, const char ** attrs); + + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_BUTTONMATRIX_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_calendar_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_calendar_parser.c new file mode 100644 index 000000000..4af1a9ff4 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_calendar_parser.c @@ -0,0 +1,104 @@ +/** + * @file lv_xml_calendar_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_calendar_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_calendar_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_calendar_create(lv_xml_state_get_parent(state)); + + return item; +} + + +void lv_xml_calendar_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("today_date", name)) { + const char * bufp = value; + int32_t y = lv_xml_atoi_split(&bufp, ' '); + int32_t m = lv_xml_atoi_split(&bufp, ' '); + int32_t d = lv_xml_atoi_split(&bufp, ' '); + lv_calendar_set_today_date(item, y, m, d); + } + else if(lv_streq("shown_month", name)) { + const char * bufp = value; + int32_t y = lv_xml_atoi_split(&bufp, ' '); + int32_t m = lv_xml_atoi_split(&bufp, ' '); + lv_calendar_set_month_shown(item, y, m); + } + } +} + +void * lv_xml_calendar_header_dropdown_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_calendar_add_header_dropdown(lv_xml_state_get_parent(state)); + return item; +} + +void lv_xml_calendar_header_dropdown_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ +} + +void * lv_xml_calendar_header_arrow_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_calendar_add_header_arrow(lv_xml_state_get_parent(state)); + + return item; +} + +void lv_xml_calendar_header_arrow_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ +} + + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_calendar_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_calendar_parser.h new file mode 100644 index 000000000..881101ecb --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_calendar_parser.h @@ -0,0 +1,43 @@ +/** + * @file lv_xml_calendar_parser.h + * + */ + +#ifndef LV_CALENDAR_XML_PARSER_H +#define LV_CALENDAR_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_calendar_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_calendar_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_calendar_header_arrow_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_calendar_header_arrow_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_calendar_header_dropdown_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_calendar_header_dropdown_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CHART_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_canvas_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_canvas_parser.c new file mode 100644 index 000000000..dde37c623 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_canvas_parser.c @@ -0,0 +1,59 @@ +/** + * @file lv_xml_canvas_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_xml_canvas_parser.h" +#if LV_USE_XML +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_canvas_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + void * item = lv_canvas_create(lv_xml_state_get_parent(state)); + + return item; +} + +void lv_xml_canvas_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + /*Apply the common properties, e.g. width, height, styles flags etc*/ + lv_xml_obj_apply(state, attrs); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_canvas_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_canvas_parser.h new file mode 100644 index 000000000..040478e65 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_canvas_parser.h @@ -0,0 +1,41 @@ +/** + * @file lv_xml_canvas_parser.h + * + */ + +#ifndef LV_CANVAS_XML_PARSER_H +#define LV_CANVAS_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_canvas_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_canvas_apply(lv_xml_parser_state_t * state, const char ** attrs); + + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_BUTTON_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_chart_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_chart_parser.c new file mode 100644 index 000000000..0b06892dc --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_chart_parser.c @@ -0,0 +1,206 @@ +/** + * @file lv_xml_chart_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_chart_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_chart_type_t chart_type_to_enum(const char * txt); +static lv_chart_update_mode_t chart_update_mode_to_enum(const char * txt); +static lv_chart_axis_t chart_axis_to_enum(const char * txt); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_chart_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_chart_create(lv_xml_state_get_parent(state)); + + return item; +} + + +void lv_xml_chart_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("point_count", name)) { + int32_t cnt = lv_xml_atoi(value); + if(cnt < 0) { + LV_LOG_WARN("chart's point count can't be negative"); + cnt = 0; + } + lv_chart_set_point_count(item, cnt); + } + else if(lv_streq("type", name)) lv_chart_set_type(item, chart_type_to_enum(value)); + else if(lv_streq("update_mode", name)) lv_chart_set_update_mode(item, chart_update_mode_to_enum(value)); + else if(lv_streq("div_line_count", name)) { + + int32_t value1 = lv_xml_atoi_split(&value, ' '); + int32_t value2 = lv_xml_atoi_split(&value, ' '); + lv_chart_set_div_line_count(item, value1, value2); + } + } +} + +void * lv_xml_chart_series_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + const char * color = lv_xml_get_value_of(attrs, "color"); + const char * axis = lv_xml_get_value_of(attrs, "axis"); + if(color == NULL) color = "0xff0000"; + if(axis == NULL) axis = "primary_y"; + + void * item = lv_chart_add_series(lv_xml_state_get_parent(state), lv_color_hex(lv_xml_strtol(color, NULL, 16)), + chart_axis_to_enum(axis)); + return item; +} + +void lv_xml_chart_series_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(state); + LV_UNUSED(attrs); + + lv_obj_t * chart = lv_xml_state_get_parent(state); + lv_chart_series_t * ser = lv_xml_state_get_item(state); + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("values", name)) { + while(value[0] != '\0') { + int32_t v = lv_xml_atoi_split(&value, ' '); + lv_chart_set_next_value(chart, ser, v); + } + } + } +} + +void * lv_xml_chart_cursor_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + const char * color = lv_xml_get_value_of(attrs, "color"); + const char * dir = lv_xml_get_value_of(attrs, "dir"); + if(color == NULL) color = "0x0000ff"; + if(dir == NULL) dir = "all"; + + void * item = lv_chart_add_cursor(lv_xml_state_get_parent(state), lv_color_hex(lv_xml_strtol(color, NULL, 16)), + lv_xml_dir_to_enum(dir)); + + return item; +} + +void lv_xml_chart_cursor_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(state); + LV_UNUSED(attrs); + + lv_obj_t * chart = lv_xml_state_get_parent(state); + lv_chart_cursor_t * cursor = lv_xml_state_get_item(state); + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("pos_x", name)) lv_chart_set_cursor_pos_x(chart, cursor, lv_xml_atoi(value)); + if(lv_streq("pos_y", name)) lv_chart_set_cursor_pos_y(chart, cursor, lv_xml_atoi(value)); + } +} + +void * lv_xml_chart_axis_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + /*Nothing to create*/ + return lv_xml_state_get_parent(state); +} + +void lv_xml_chart_axis_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(state); + LV_UNUSED(attrs); + + lv_obj_t * chart = lv_xml_state_get_parent(state); + lv_chart_axis_t axis = chart_axis_to_enum(lv_xml_get_value_of(attrs, "axis")); + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("range", name)) { + int32_t min_val = lv_xml_atoi_split(&value, ' '); + int32_t max_val = lv_xml_atoi_split(&value, ' '); + lv_chart_set_axis_range(chart, axis, min_val, max_val); + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_chart_type_t chart_type_to_enum(const char * txt) +{ + if(lv_streq("none", txt)) return LV_CHART_TYPE_NONE; + if(lv_streq("line", txt)) return LV_CHART_TYPE_LINE; + if(lv_streq("bar", txt)) return LV_CHART_TYPE_BAR; + if(lv_streq("scatter", txt)) return LV_CHART_TYPE_SCATTER; + + LV_LOG_WARN("%s is an unknown value for chart's chart_type", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +static lv_chart_update_mode_t chart_update_mode_to_enum(const char * txt) +{ + if(lv_streq("shift", txt)) return LV_CHART_UPDATE_MODE_SHIFT; + if(lv_streq("circular", txt)) return LV_CHART_UPDATE_MODE_CIRCULAR; + + LV_LOG_WARN("%s is an unknown value for chart's chart_update_mode", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +static lv_chart_axis_t chart_axis_to_enum(const char * txt) +{ + if(lv_streq("primary_x", txt)) return LV_CHART_AXIS_PRIMARY_X; + if(lv_streq("primary_y", txt)) return LV_CHART_AXIS_PRIMARY_Y; + if(lv_streq("secondary_x", txt)) return LV_CHART_AXIS_SECONDARY_X; + if(lv_streq("secondary_y", txt)) return LV_CHART_AXIS_SECONDARY_Y; + + LV_LOG_WARN("%s is an unknown value for chart's chart_axis", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_chart_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_chart_parser.h new file mode 100644 index 000000000..0307e4f8e --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_chart_parser.h @@ -0,0 +1,45 @@ +/** + * @file lv_xml_chart_parser.h + * + */ + +#ifndef LV_CHART_XML_PARSER_H +#define LV_CHART_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_chart_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_chart_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_chart_series_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_chart_series_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_chart_cursor_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_chart_cursor_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_chart_axis_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_chart_axis_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CHART_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_checkbox_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_checkbox_parser.c new file mode 100644 index 000000000..b42f2878a --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_checkbox_parser.c @@ -0,0 +1,65 @@ +/** + * @file lv_xml_checkbox_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_checkbox_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_checkbox_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + void * item = lv_checkbox_create(lv_xml_state_get_parent(state)); + return item; +} + +void lv_xml_checkbox_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("text", name)) lv_checkbox_set_text(item, value); + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_checkbox_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_checkbox_parser.h new file mode 100644 index 000000000..37ac0489d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_checkbox_parser.h @@ -0,0 +1,40 @@ +/** + * @file lv_xml_checkbox_parser.h + * + */ + +#ifndef LV_CHECKBOX_XML_PARSER_H +#define LV_CHECKBOX_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_checkbox_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_checkbox_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_CHECKBOX_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_dropdown_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_dropdown_parser.c new file mode 100644 index 000000000..153ec25d9 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_dropdown_parser.c @@ -0,0 +1,93 @@ +/** + * @file lv_xml_dropdown_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_dropdown_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_dropdown_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_dropdown_create(lv_xml_state_get_parent(state)); + + return item; +} + + +void lv_xml_dropdown_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("options", name)) lv_dropdown_set_options(item, value); + else if(lv_streq("text", name)) lv_dropdown_set_text(item, value); + else if(lv_streq("selected", name)) lv_dropdown_set_selected(item, lv_xml_atoi(value)); + else if(lv_streq("symbol", name)) lv_dropdown_set_symbol(item, lv_xml_get_image(&state->scope, value)); + else if(lv_streq("bind_value", name)) { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); + if(subject) { + lv_dropdown_bind_value(item, subject); + } + else { + LV_LOG_WARN("Subject \"%s\" doesn't exist in dropdown bind_value", value); + } + } + } +} + +void * lv_xml_dropdown_list_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + return lv_dropdown_get_list(lv_xml_state_get_parent(state)); +} + +void lv_xml_dropdown_list_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(state); + LV_UNUSED(attrs); + + lv_xml_obj_apply(state, attrs); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_dropdown_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_dropdown_parser.h new file mode 100644 index 000000000..3a6919256 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_dropdown_parser.h @@ -0,0 +1,41 @@ +/** + * @file lv_xml_dropdown_parser.h + * + */ + +#ifndef LV_DROPDOWN_XML_PARSER_H +#define LV_DROPDOWN_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_dropdown_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_dropdown_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_dropdown_list_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_dropdown_list_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DROPDOWN_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_event_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_event_parser.c new file mode 100644 index 000000000..07901bd9b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_event_parser.c @@ -0,0 +1,170 @@ +/** + * @file lv_xml_event_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_event_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_event_code_t trigger_text_to_enum_value(const char * txt); +static void free_user_data_event_cb(lv_event_t * e); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_event_call_function_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + + const char * trigger = lv_xml_get_value_of(attrs, "trigger"); + lv_event_code_t code = LV_EVENT_CLICKED; + if(trigger) code = trigger_text_to_enum_value(trigger); + if(code == LV_EVENT_LAST) { + LV_LOG_WARN("Couldn't add call function event because \"%s\" trigger is invalid.", trigger); + return NULL; + } + + const char * cb_txt = lv_xml_get_value_of(attrs, "callback"); + if(cb_txt == NULL) { + LV_LOG_WARN("callback is mandatory for event-call_function"); + return NULL; + } + + lv_obj_t * obj = lv_xml_state_get_parent(state); + lv_event_cb_t cb = lv_xml_get_event_cb(&state->scope, cb_txt); + if(cb == NULL) { + LV_LOG_WARN("Couldn't add call function event because \"%s\" callback is not found.", cb_txt); + /*Don't return NULL. + *When the component is isolated e.g. in the editor the callback is not registered */ + return obj; + } + + const char * user_data_xml = lv_xml_get_value_of(attrs, "user_data"); + char * user_data = NULL; + if(user_data_xml) user_data = lv_strdup(user_data_xml); + + lv_obj_add_event_cb(obj, cb, code, user_data); + if(user_data) lv_obj_add_event_cb(obj, free_user_data_event_cb, LV_EVENT_DELETE, user_data); + + return obj; +} + +void lv_xml_event_call_function_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(state); + LV_UNUSED(attrs); + /*Nothing to apply*/ +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void free_user_data_event_cb(lv_event_t * e) +{ + char * user_data = lv_event_get_user_data(e); + lv_free(user_data); +} + +static lv_event_code_t trigger_text_to_enum_value(const char * txt) +{ + + if(lv_streq("all", txt)) return LV_EVENT_ALL; + if(lv_streq("pressed", txt)) return LV_EVENT_PRESSED; + if(lv_streq("pressing", txt)) return LV_EVENT_PRESSING; + if(lv_streq("press_lost", txt)) return LV_EVENT_PRESS_LOST; + if(lv_streq("short_clicked", txt)) return LV_EVENT_SHORT_CLICKED; + if(lv_streq("single_clicked", txt)) return LV_EVENT_SINGLE_CLICKED; + if(lv_streq("double_clicked", txt)) return LV_EVENT_DOUBLE_CLICKED; + if(lv_streq("triple_clicked", txt)) return LV_EVENT_TRIPLE_CLICKED; + if(lv_streq("long_pressed", txt)) return LV_EVENT_LONG_PRESSED; + if(lv_streq("long_pressed_repeat", txt)) return LV_EVENT_LONG_PRESSED_REPEAT; + if(lv_streq("clicked", txt)) return LV_EVENT_CLICKED; + if(lv_streq("released", txt)) return LV_EVENT_RELEASED; + if(lv_streq("scroll_begin", txt)) return LV_EVENT_SCROLL_BEGIN; + if(lv_streq("scroll_throw_begin", txt)) return LV_EVENT_SCROLL_THROW_BEGIN; + if(lv_streq("scroll_end", txt)) return LV_EVENT_SCROLL_END; + if(lv_streq("scroll", txt)) return LV_EVENT_SCROLL; + if(lv_streq("gesture", txt)) return LV_EVENT_GESTURE; + if(lv_streq("key", txt)) return LV_EVENT_KEY; + if(lv_streq("rotary", txt)) return LV_EVENT_ROTARY; + if(lv_streq("focused", txt)) return LV_EVENT_FOCUSED; + if(lv_streq("defocused", txt)) return LV_EVENT_DEFOCUSED; + if(lv_streq("leave", txt)) return LV_EVENT_LEAVE; + if(lv_streq("hit_test", txt)) return LV_EVENT_HIT_TEST; + if(lv_streq("indev_reset", txt)) return LV_EVENT_INDEV_RESET; + if(lv_streq("hover_over", txt)) return LV_EVENT_HOVER_OVER; + if(lv_streq("hover_leave", txt)) return LV_EVENT_HOVER_LEAVE; + if(lv_streq("cover_check", txt)) return LV_EVENT_COVER_CHECK; + if(lv_streq("refr_ext_draw_size", txt)) return LV_EVENT_REFR_EXT_DRAW_SIZE; + if(lv_streq("draw_main_begin", txt)) return LV_EVENT_DRAW_MAIN_BEGIN; + if(lv_streq("draw_main", txt)) return LV_EVENT_DRAW_MAIN; + if(lv_streq("draw_main_end", txt)) return LV_EVENT_DRAW_MAIN_END; + if(lv_streq("draw_post_begin", txt)) return LV_EVENT_DRAW_POST_BEGIN; + if(lv_streq("draw_post", txt)) return LV_EVENT_DRAW_POST; + if(lv_streq("draw_post_end", txt)) return LV_EVENT_DRAW_POST_END; + if(lv_streq("draw_task_added", txt)) return LV_EVENT_DRAW_TASK_ADDED; + if(lv_streq("value_changed", txt)) return LV_EVENT_VALUE_CHANGED; + if(lv_streq("insert", txt)) return LV_EVENT_INSERT; + if(lv_streq("refresh", txt)) return LV_EVENT_REFRESH; + if(lv_streq("ready", txt)) return LV_EVENT_READY; + if(lv_streq("cancel", txt)) return LV_EVENT_CANCEL; + if(lv_streq("create", txt)) return LV_EVENT_CREATE; + if(lv_streq("delete", txt)) return LV_EVENT_DELETE; + if(lv_streq("child_changed", txt)) return LV_EVENT_CHILD_CHANGED; + if(lv_streq("child_created", txt)) return LV_EVENT_CHILD_CREATED; + if(lv_streq("child_deleted", txt)) return LV_EVENT_CHILD_DELETED; + if(lv_streq("screen_unload_start", txt)) return LV_EVENT_SCREEN_UNLOAD_START; + if(lv_streq("screen_load_start", txt)) return LV_EVENT_SCREEN_LOAD_START; + if(lv_streq("screen_loaded", txt)) return LV_EVENT_SCREEN_LOADED; + if(lv_streq("screen_unloaded", txt)) return LV_EVENT_SCREEN_UNLOADED; + if(lv_streq("size_changed", txt)) return LV_EVENT_SIZE_CHANGED; + if(lv_streq("style_changed", txt)) return LV_EVENT_STYLE_CHANGED; + if(lv_streq("layout_changed", txt)) return LV_EVENT_LAYOUT_CHANGED; + if(lv_streq("get_self_size", txt)) return LV_EVENT_GET_SELF_SIZE; + if(lv_streq("invalidate_area", txt)) return LV_EVENT_INVALIDATE_AREA; + if(lv_streq("resolution_changed", txt)) return LV_EVENT_RESOLUTION_CHANGED; + if(lv_streq("color_format_changed", txt)) return LV_EVENT_COLOR_FORMAT_CHANGED; + if(lv_streq("refr_request", txt)) return LV_EVENT_REFR_REQUEST; + if(lv_streq("refr_start", txt)) return LV_EVENT_REFR_START; + if(lv_streq("refr_ready", txt)) return LV_EVENT_REFR_READY; + if(lv_streq("render_start", txt)) return LV_EVENT_RENDER_START; + if(lv_streq("render_ready", txt)) return LV_EVENT_RENDER_READY; + if(lv_streq("flush_start", txt)) return LV_EVENT_FLUSH_START; + if(lv_streq("flush_finish", txt)) return LV_EVENT_FLUSH_FINISH; + if(lv_streq("flush_wait_start", txt)) return LV_EVENT_FLUSH_WAIT_START; + if(lv_streq("flush_wait_finish", txt)) return LV_EVENT_FLUSH_WAIT_FINISH; + if(lv_streq("vsync", txt)) return LV_EVENT_VSYNC; + + LV_LOG_WARN("%s is an unknown value for event's trigger", txt); + return LV_EVENT_LAST; /*Indicate error*/ +} + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_event_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_event_parser.h new file mode 100644 index 000000000..28498fba9 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_event_parser.h @@ -0,0 +1,40 @@ +/** + * @file lv_xml_event_parser.h + * + */ + +#ifndef LV_EVENT_XML_PARSER_H +#define LV_EVENT_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +void * lv_xml_event_call_function_create(lv_xml_parser_state_t * state, const char ** attrs); + +void lv_xml_event_call_function_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_EVENT_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_image_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_image_parser.c new file mode 100644 index 000000000..e6ec71248 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_image_parser.c @@ -0,0 +1,99 @@ +/** + * @file lv_xml_image_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_image_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_image_align_t image_align_to_enum(const char * txt); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_image_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_image_create(lv_xml_state_get_parent(state)); + + if(item == NULL) { + LV_LOG_ERROR("Failed to create image"); + return NULL; + } + + return item; +} + +void lv_xml_image_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("src", name)) lv_image_set_src(item, lv_xml_get_image(&state->scope, value)); + if(lv_streq("inner_align", name)) lv_image_set_inner_align(item, image_align_to_enum(value)); + if(lv_streq("rotation", name)) lv_image_set_rotation(item, lv_xml_atoi(value)); + if(lv_streq("scale_x", name)) lv_image_set_scale_x(item, lv_xml_atoi(value)); + if(lv_streq("scale_y", name)) lv_image_set_scale_y(item, lv_xml_atoi(value)); + if(lv_streq("pivot", name)) { + int32_t x = lv_xml_atoi_split(&value, ' '); + int32_t y = lv_xml_atoi_split(&value, ' '); + lv_image_set_pivot(item, x, y); + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_image_align_t image_align_to_enum(const char * txt) +{ + if(lv_streq("top_left", txt)) return LV_IMAGE_ALIGN_TOP_LEFT; + if(lv_streq("top_mid", txt)) return LV_IMAGE_ALIGN_TOP_MID; + if(lv_streq("top_right", txt)) return LV_IMAGE_ALIGN_TOP_RIGHT; + if(lv_streq("bottom_left", txt)) return LV_IMAGE_ALIGN_BOTTOM_LEFT; + if(lv_streq("bottom_mid", txt)) return LV_IMAGE_ALIGN_BOTTOM_MID; + if(lv_streq("bottom_right", txt)) return LV_IMAGE_ALIGN_BOTTOM_RIGHT; + if(lv_streq("right_mid", txt)) return LV_IMAGE_ALIGN_RIGHT_MID; + if(lv_streq("left_mid", txt)) return LV_IMAGE_ALIGN_LEFT_MID; + if(lv_streq("center", txt)) return LV_IMAGE_ALIGN_CENTER; + if(lv_streq("stretch", txt)) return LV_IMAGE_ALIGN_STRETCH; + if(lv_streq("tile", txt)) return LV_IMAGE_ALIGN_TILE; + + LV_LOG_WARN("%s is an unknown value for image align", txt); + return 0; /*Return 0 in lack of a better option. */ +} + + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_image_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_image_parser.h new file mode 100644 index 000000000..19a978a33 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_image_parser.h @@ -0,0 +1,43 @@ +/** + * @file lv_xml_image_parser.h + * + */ + +#ifndef LV_XML_IMAGE_PARSER_H +#define LV_XML_IMAGE_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_image_create(lv_xml_parser_state_t * state, const char ** attrs); + +void lv_xml_image_apply(lv_xml_parser_state_t * state, const char ** attrs); + +void lv_xml_check_file(const char * filepath); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_IMAGE_PARSER_H*/ \ No newline at end of file diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_keyboard_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_keyboard_parser.c new file mode 100644 index 000000000..f4ed974b5 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_keyboard_parser.c @@ -0,0 +1,85 @@ +/** + * @file lv_xml_keyboard_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_keyboard_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_keyboard_mode_t mode_text_to_enum_value(const char * txt); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_keyboard_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_keyboard_create(lv_xml_state_get_parent(state)); + + return item; +} + +void lv_xml_keyboard_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + // if(lv_streq("textarea", name)) lv_keyboard_set_mode(item, lv_obj_get_child_by_name()); + if(lv_streq("mode", name)) lv_keyboard_set_mode(item, mode_text_to_enum_value(value)); + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_keyboard_mode_t mode_text_to_enum_value(const char * txt) +{ + if(lv_streq("text_upper", txt)) return LV_KEYBOARD_MODE_TEXT_UPPER; + if(lv_streq("text_lower", txt)) return LV_KEYBOARD_MODE_TEXT_LOWER; +#if LV_USE_ARABIC_PERSIAN_CHARS == 1 + if(lv_streq("text_arabic", txt)) return LV_KEYBOARD_MODE_TEXT_ARABIC; +#endif + if(lv_streq("number", txt)) return LV_KEYBOARD_MODE_NUMBER; + if(lv_streq("special", txt)) return LV_KEYBOARD_MODE_SPECIAL; + if(lv_streq("user_1", txt)) return LV_KEYBOARD_MODE_USER_1; + if(lv_streq("user_2", txt)) return LV_KEYBOARD_MODE_USER_2; + if(lv_streq("user_3", txt)) return LV_KEYBOARD_MODE_USER_3; + if(lv_streq("user_4", txt)) return LV_KEYBOARD_MODE_USER_4; + + LV_LOG_WARN("%s is an unknown value for keyboard's mode", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_keyboard_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_keyboard_parser.h new file mode 100644 index 000000000..cfd80f999 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_keyboard_parser.h @@ -0,0 +1,41 @@ +/** + * @file lv_xml_keyboard_parser.h + * + */ + +#ifndef LV_XML_KEYBOARD_PARSER_H +#define LV_XML_KEYBOARD_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_keyboard_create(lv_xml_parser_state_t * state, const char ** attrs); + +void lv_xml_keyboard_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_KEYBOARD_PARSER_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_label_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_label_parser.c new file mode 100644 index 000000000..924118233 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_label_parser.c @@ -0,0 +1,110 @@ +/** + * @file lv_xml_label_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_label_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_label_long_mode_t long_mode_text_to_enum_value(const char * txt); +static void free_fmt_event_cb(lv_event_t * e); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_label_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_label_create(lv_xml_state_get_parent(state)); + + return item; +} + +void lv_xml_label_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("text", name)) lv_label_set_text(item, value); + if(lv_streq("long_mode", name)) lv_label_set_long_mode(item, long_mode_text_to_enum_value(value)); + if(lv_streq("bind_text", name)) { + char buf[256]; + lv_strncpy(buf, value, sizeof(buf)); + char * bufp = buf; + char * subject_name = lv_xml_split_str(&bufp, ' '); + if(subject_name) { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, subject_name); + if(subject) { + char * fmt = bufp; /*The second part is the format text*/ + if(fmt && fmt[0] == '\0') fmt = NULL; + if(fmt) { + if(fmt[0] == '\'') fmt++; + size_t fmt_len = lv_strlen(fmt); + if(fmt_len != 0 && fmt[fmt_len - 1] == '\'') fmt[fmt_len - 1] = '\0'; + fmt = lv_strdup(fmt); + lv_obj_add_event_cb(item, free_fmt_event_cb, LV_EVENT_DELETE, fmt); + } + lv_label_bind_text(item, subject, fmt); + } + else { + LV_LOG_WARN("Subject \"%s\" doesn't exist in label bind_text", value); + } + } + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_label_long_mode_t long_mode_text_to_enum_value(const char * txt) +{ + if(lv_streq("wrap", txt)) return LV_LABEL_LONG_MODE_WRAP; + if(lv_streq("scroll", txt)) return LV_LABEL_LONG_MODE_SCROLL; + if(lv_streq("scroll_circular", txt)) return LV_LABEL_LONG_MODE_SCROLL_CIRCULAR; + if(lv_streq("dots", txt)) return LV_LABEL_LONG_MODE_DOTS; + if(lv_streq("clip", txt)) return LV_LABEL_LONG_MODE_CLIP; + + LV_LOG_WARN("%s is an unknown value for label's long_mode", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +static void free_fmt_event_cb(lv_event_t * e) +{ + void * fmt = lv_event_get_user_data(e); + lv_free(fmt); +} + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_label_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_label_parser.h new file mode 100644 index 000000000..da1ef79be --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_label_parser.h @@ -0,0 +1,41 @@ +/** + * @file lv_xml_label_parser.h + * + */ + +#ifndef LV_LABEL_XML_PARSER_H +#define LV_LABEL_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_label_create(lv_xml_parser_state_t * state, const char ** attrs); + +void lv_xml_label_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_LABEL_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_obj_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_obj_parser.c new file mode 100644 index 000000000..9f61bcd83 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_obj_parser.c @@ -0,0 +1,399 @@ +/** + * @file lv_xml_obj_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_obj_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_obj_flag_t flag_to_enum(const char * txt); +static void apply_styles(lv_xml_parser_state_t * state, lv_obj_t * obj, const char * name, const char * value); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/* Expands to + if(lv_streq(prop_name, "style_height")) lv_obj_set_style_height(obj, value, selector) + */ +#define SET_STYLE_IF(prop, value) if(lv_streq(prop_name, "style_" #prop)) lv_obj_set_style_##prop(obj, value, selector) + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_obj_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_obj_create(lv_xml_state_get_parent(state)); + + return item; +} + +void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + size_t name_len = lv_strlen(name); + +#if LV_USE_OBJ_NAME + if(lv_streq("name", name)) { + lv_obj_set_name(item, value); + } +#endif + if(lv_streq("x", name)) lv_obj_set_x(item, lv_xml_to_size(value)); + else if(lv_streq("y", name)) lv_obj_set_y(item, lv_xml_to_size(value)); + else if(lv_streq("width", name)) lv_obj_set_width(item, lv_xml_to_size(value)); + else if(lv_streq("height", name)) lv_obj_set_height(item, lv_xml_to_size(value)); + else if(lv_streq("align", name)) lv_obj_set_align(item, lv_xml_align_to_enum(value)); + else if(lv_streq("flex_flow", name)) lv_obj_set_flex_flow(item, lv_xml_flex_flow_to_enum(value)); + else if(lv_streq("flex_grow", name)) lv_obj_set_flex_grow(item, lv_xml_atoi(value)); + else if(lv_streq("ext_click_area", name)) lv_obj_set_ext_click_area(item, lv_xml_atoi(value)); + + else if(lv_streq("hidden", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_HIDDEN, lv_xml_to_bool(value)); + else if(lv_streq("clickable", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_CLICKABLE, lv_xml_to_bool(value)); + else if(lv_streq("click_focusable", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_CLICK_FOCUSABLE, + lv_xml_to_bool(value)); + else if(lv_streq("checkable", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_CHECKABLE, lv_xml_to_bool(value)); + else if(lv_streq("scrollable", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_SCROLLABLE, lv_xml_to_bool(value)); + else if(lv_streq("scroll_elastic", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_SCROLL_ELASTIC, + lv_xml_to_bool(value)); + else if(lv_streq("scroll_momentum", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_SCROLL_MOMENTUM, + lv_xml_to_bool(value)); + else if(lv_streq("scroll_one", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_SCROLL_ONE, lv_xml_to_bool(value)); + else if(lv_streq("scroll_chain_hor", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_SCROLL_CHAIN_HOR, + lv_xml_to_bool(value)); + else if(lv_streq("scroll_chain_ver", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_SCROLL_CHAIN_VER, + lv_xml_to_bool(value)); + else if(lv_streq("scroll_chain", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_SCROLL_CHAIN, + lv_xml_to_bool(value)); + else if(lv_streq("scroll_on_focus", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_SCROLL_ON_FOCUS, + lv_xml_to_bool(value)); + else if(lv_streq("scroll_with_arrow", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_SCROLL_WITH_ARROW, + lv_xml_to_bool(value)); + else if(lv_streq("snappable", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_SNAPPABLE, lv_xml_to_bool(value)); + else if(lv_streq("press_lock", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_PRESS_LOCK, lv_xml_to_bool(value)); + else if(lv_streq("event_bubble", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_EVENT_BUBBLE, + lv_xml_to_bool(value)); + else if(lv_streq("gesture_bubble", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_GESTURE_BUBBLE, + lv_xml_to_bool(value)); + else if(lv_streq("adv_hittest", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_ADV_HITTEST, + lv_xml_to_bool(value)); + else if(lv_streq("ignore_layout", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_IGNORE_LAYOUT, + lv_xml_to_bool(value)); + else if(lv_streq("floating", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_FLOATING, lv_xml_to_bool(value)); + else if(lv_streq("send_draw_task_events", name))lv_obj_set_flag(item, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS, + lv_xml_to_bool(value)); + else if(lv_streq("overflow_visible", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_OVERFLOW_VISIBLE, + lv_xml_to_bool(value)); + else if(lv_streq("flex_in_new_track", name)) lv_obj_set_flag(item, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK, + lv_xml_to_bool(value)); + + else if(lv_streq("checked", name)) lv_obj_set_state(item, LV_STATE_CHECKED, lv_xml_to_bool(value)); + else if(lv_streq("focused", name)) lv_obj_set_state(item, LV_STATE_FOCUSED, lv_xml_to_bool(value)); + else if(lv_streq("focus_key", name)) lv_obj_set_state(item, LV_STATE_FOCUS_KEY, lv_xml_to_bool(value)); + else if(lv_streq("edited", name)) lv_obj_set_state(item, LV_STATE_EDITED, lv_xml_to_bool(value)); + else if(lv_streq("hovered", name)) lv_obj_set_state(item, LV_STATE_HOVERED, lv_xml_to_bool(value)); + else if(lv_streq("pressed", name)) lv_obj_set_state(item, LV_STATE_PRESSED, lv_xml_to_bool(value)); + else if(lv_streq("scrolled", name)) lv_obj_set_state(item, LV_STATE_SCROLLED, lv_xml_to_bool(value)); + else if(lv_streq("disabled", name)) lv_obj_set_state(item, LV_STATE_DISABLED, lv_xml_to_bool(value)); + else if(lv_streq("styles", name)) lv_xml_style_add_to_obj(state, item, value); + + else if(lv_streq("bind_checked", name)) { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); + if(subject) { + lv_obj_bind_checked(item, subject); + } + else { + LV_LOG_WARN("Subject \"%s\" doesn't exist in lv_obj bind_checked", value); + } + } + else if(name_len >= 15 && lv_memcmp("bind_flag_if_", name, 13) == 0) { + lv_observer_t * (*cb)(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value) = NULL; + if(name[13] == 'e' && name[14] == 'q') cb = lv_obj_bind_flag_if_eq; + else if(name[13] == 'n' && name[14] == 'o') cb = lv_obj_bind_flag_if_not_eq; + else if(name[13] == 'g' && name[14] == 't') cb = lv_obj_bind_flag_if_gt; + else if(name[13] == 'g' && name[14] == 'e') cb = lv_obj_bind_flag_if_ge; + else if(name[13] == 'l' && name[14] == 't') cb = lv_obj_bind_flag_if_lt; + else if(name[13] == 'l' && name[14] == 'e') cb = lv_obj_bind_flag_if_le; + + if(cb) { + char buf[128]; + lv_strlcpy(buf, value, sizeof(buf)); + char * bufp = buf; + const char * subject_str = lv_xml_split_str(&bufp, ' '); + const char * flag_str = lv_xml_split_str(&bufp, ' '); + const char * ref_value_str = lv_xml_split_str(&bufp, ' '); + + if(subject_str == NULL) { + LV_LOG_WARN("Subject is missing in lv_obj bind_flag"); + } + else if(flag_str == NULL) { + LV_LOG_WARN("Flag is missing in lv_obj bind_flag"); + } + else if(ref_value_str == NULL) { + LV_LOG_WARN("Reference value is missing in lv_obj bind_flag"); + } + else { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, subject_str); + if(subject == NULL) { + LV_LOG_WARN("Subject \"%s\" doesn't exist in lv_obj bind_flag", value); + } + else { + lv_obj_flag_t flag = flag_to_enum(flag_str); + int32_t ref_value = lv_xml_atoi(ref_value_str); + cb(item, subject, flag, ref_value); + } + } + } + } + else if(name_len >= 16 && lv_memcmp("bind_state_if_", name, 14) == 0) { + lv_observer_t * (*cb)(lv_obj_t * obj, lv_subject_t * subject, lv_state_t flag, int32_t ref_value) = NULL; + if(name[14] == 'e' && name[15] == 'q') cb = lv_obj_bind_state_if_eq; + else if(name[14] == 'n' && name[15] == 'o') cb = lv_obj_bind_state_if_not_eq; + else if(name[14] == 'g' && name[15] == 't') cb = lv_obj_bind_state_if_gt; + else if(name[14] == 'g' && name[15] == 'e') cb = lv_obj_bind_state_if_ge; + else if(name[14] == 'l' && name[15] == 't') cb = lv_obj_bind_state_if_lt; + else if(name[14] == 'l' && name[15] == 'e') cb = lv_obj_bind_state_if_le; + + if(cb) { + char buf[128]; + lv_strlcpy(buf, value, sizeof(buf)); + char * bufp = buf; + const char * subject_str = lv_xml_split_str(&bufp, ' '); + const char * state_str = lv_xml_split_str(&bufp, ' '); + const char * ref_value_str = lv_xml_split_str(&bufp, ' '); + + if(subject_str == NULL) { + LV_LOG_WARN("Subject is missing in lv_obj bind_state"); + } + else if(state_str == NULL) { + LV_LOG_WARN("State is missing in lv_obj bind_state"); + } + else if(ref_value_str == NULL) { + LV_LOG_WARN("Reference value is missing in lv_obj bind_state"); + } + else { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, subject_str); + if(subject == NULL) { + LV_LOG_WARN("Subject \"%s\" doesn't exist in lv_obj bind_state", value); + } + else { + lv_state_t obj_state = lv_xml_state_to_enum(state_str); + int32_t ref_value = lv_xml_atoi(ref_value_str); + cb(item, subject, obj_state, ref_value); + } + } + } + } + + else if(name_len > 6 && lv_memcmp("style_", name, 6) == 0) { + apply_styles(state, item, name, value); + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_obj_flag_t flag_to_enum(const char * txt) +{ + if(lv_streq("hidden", txt)) return LV_OBJ_FLAG_HIDDEN; + if(lv_streq("clickable", txt)) return LV_OBJ_FLAG_CLICKABLE; + if(lv_streq("click_focusable", txt)) return LV_OBJ_FLAG_CLICK_FOCUSABLE; + if(lv_streq("checkable", txt)) return LV_OBJ_FLAG_CHECKABLE; + if(lv_streq("scrollable", txt)) return LV_OBJ_FLAG_SCROLLABLE; + if(lv_streq("scroll_elastic", txt)) return LV_OBJ_FLAG_SCROLL_ELASTIC; + if(lv_streq("scroll_momentum", txt)) return LV_OBJ_FLAG_SCROLL_MOMENTUM; + if(lv_streq("scroll_one", txt)) return LV_OBJ_FLAG_SCROLL_ONE; + if(lv_streq("scroll_chain_hor", txt)) return LV_OBJ_FLAG_SCROLL_CHAIN_HOR; + if(lv_streq("scroll_chain_ver", txt)) return LV_OBJ_FLAG_SCROLL_CHAIN_VER; + if(lv_streq("scroll_chain", txt)) return LV_OBJ_FLAG_SCROLL_CHAIN; + if(lv_streq("scroll_on_focus", txt)) return LV_OBJ_FLAG_SCROLL_ON_FOCUS; + if(lv_streq("scroll_with_arrow", txt)) return LV_OBJ_FLAG_SCROLL_WITH_ARROW; + if(lv_streq("snappable", txt)) return LV_OBJ_FLAG_SNAPPABLE; + if(lv_streq("press_lock", txt)) return LV_OBJ_FLAG_PRESS_LOCK; + if(lv_streq("event_bubble", txt)) return LV_OBJ_FLAG_EVENT_BUBBLE; + if(lv_streq("gesture_bubble", txt)) return LV_OBJ_FLAG_GESTURE_BUBBLE; + if(lv_streq("adv_hittest", txt)) return LV_OBJ_FLAG_ADV_HITTEST; + if(lv_streq("ignore_layout", txt)) return LV_OBJ_FLAG_IGNORE_LAYOUT; + if(lv_streq("floating", txt)) return LV_OBJ_FLAG_FLOATING; + if(lv_streq("send_draw_task_evenTS", txt)) return LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS; + if(lv_streq("overflow_visible", txt)) return LV_OBJ_FLAG_OVERFLOW_VISIBLE; + if(lv_streq("flex_in_new_track", txt)) return LV_OBJ_FLAG_FLEX_IN_NEW_TRACK; + if(lv_streq("layout_1", txt)) return LV_OBJ_FLAG_LAYOUT_1; + if(lv_streq("layout_2", txt)) return LV_OBJ_FLAG_LAYOUT_2; + if(lv_streq("widget_1", txt)) return LV_OBJ_FLAG_WIDGET_1; + if(lv_streq("widget_2", txt)) return LV_OBJ_FLAG_WIDGET_2; + if(lv_streq("user_1", txt)) return LV_OBJ_FLAG_USER_1; + if(lv_streq("user_2", txt)) return LV_OBJ_FLAG_USER_2; + if(lv_streq("user_3", txt)) return LV_OBJ_FLAG_USER_3; + if(lv_streq("user_4", txt)) return LV_OBJ_FLAG_USER_4; + + LV_LOG_WARN("%s is an unknown value for flag", txt); + return 0; /*Return 0 in lack of a better option. */ +} + + +static void apply_styles(lv_xml_parser_state_t * state, lv_obj_t * obj, const char * name, const char * value) +{ + char name_local[512]; + lv_strlcpy(name_local, name, sizeof(name_local)); + + lv_style_selector_t selector; + const char * prop_name = lv_xml_style_string_process(name_local, &selector); + + SET_STYLE_IF(width, lv_xml_to_size(value)); + else SET_STYLE_IF(min_width, lv_xml_to_size(value)); + else SET_STYLE_IF(max_width, lv_xml_to_size(value)); + else SET_STYLE_IF(height, lv_xml_to_size(value)); + else SET_STYLE_IF(min_height, lv_xml_to_size(value)); + else SET_STYLE_IF(max_height, lv_xml_to_size(value)); + else SET_STYLE_IF(length, lv_xml_to_size(value)); + else SET_STYLE_IF(radius, lv_xml_to_size(value)); + + else SET_STYLE_IF(pad_left, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_right, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_top, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_bottom, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_hor, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_ver, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_all, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_row, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_column, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_gap, lv_xml_atoi(value)); + else SET_STYLE_IF(pad_radial, lv_xml_atoi(value)); + + else SET_STYLE_IF(margin_left, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_right, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_top, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_bottom, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_hor, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_ver, lv_xml_atoi(value)); + else SET_STYLE_IF(margin_all, lv_xml_atoi(value)); + + else SET_STYLE_IF(base_dir, lv_xml_base_dir_to_enum(value)); + else SET_STYLE_IF(clip_corner, lv_xml_to_bool(value)); + + else SET_STYLE_IF(bg_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(bg_color, lv_xml_to_color(value)); + else SET_STYLE_IF(bg_grad_dir, lv_xml_grad_dir_to_enum(value)); + else SET_STYLE_IF(bg_grad_color, lv_xml_to_color(value)); + else SET_STYLE_IF(bg_main_stop, lv_xml_atoi(value)); + else SET_STYLE_IF(bg_grad_stop, lv_xml_atoi(value)); + else SET_STYLE_IF(bg_grad, lv_xml_component_get_grad(&state->scope, value)); + + else SET_STYLE_IF(bg_image_src, lv_xml_get_image(&state->scope, value)); + else SET_STYLE_IF(bg_image_tiled, lv_xml_to_bool(value)); + else SET_STYLE_IF(bg_image_recolor, lv_xml_to_color(value)); + else SET_STYLE_IF(bg_image_recolor_opa, lv_xml_to_opa(value)); + + else SET_STYLE_IF(border_color, lv_xml_to_color(value)); + else SET_STYLE_IF(border_width, lv_xml_atoi(value)); + else SET_STYLE_IF(border_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(border_side, lv_xml_border_side_to_enum(value)); + else SET_STYLE_IF(border_post, lv_xml_to_bool(value)); + + else SET_STYLE_IF(outline_color, lv_xml_to_color(value)); + else SET_STYLE_IF(outline_width, lv_xml_atoi(value)); + else SET_STYLE_IF(outline_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(outline_pad, lv_xml_atoi(value)); + + else SET_STYLE_IF(shadow_width, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_color, lv_xml_to_color(value)); + else SET_STYLE_IF(shadow_offset_x, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_offset_y, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_spread, lv_xml_atoi(value)); + else SET_STYLE_IF(shadow_opa, lv_xml_to_opa(value)); + + else SET_STYLE_IF(text_color, lv_xml_to_color(value)); + else SET_STYLE_IF(text_font, lv_xml_get_font(&state->scope, value)); + else SET_STYLE_IF(text_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(text_align, lv_xml_text_align_to_enum(value)); + else SET_STYLE_IF(text_letter_space, lv_xml_atoi(value)); + else SET_STYLE_IF(text_line_space, lv_xml_atoi(value)); + else SET_STYLE_IF(text_decor, lv_xml_text_decor_to_enum(value)); + + else SET_STYLE_IF(image_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(image_recolor, lv_xml_to_color(value)); + else SET_STYLE_IF(image_recolor_opa, lv_xml_to_opa(value)); + + else SET_STYLE_IF(line_color, lv_xml_to_color(value)); + else SET_STYLE_IF(line_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(line_width, lv_xml_atoi(value)); + else SET_STYLE_IF(line_dash_width, lv_xml_atoi(value)); + else SET_STYLE_IF(line_dash_gap, lv_xml_atoi(value)); + else SET_STYLE_IF(line_rounded, lv_xml_to_bool(value)); + + else SET_STYLE_IF(arc_color, lv_xml_to_color(value)); + else SET_STYLE_IF(arc_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(arc_width, lv_xml_atoi(value)); + else SET_STYLE_IF(arc_rounded, lv_xml_to_bool(value)); + else SET_STYLE_IF(arc_image_src, lv_xml_get_image(&state->scope, value)); + + else SET_STYLE_IF(opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(opa_layered, lv_xml_to_opa(value)); + else SET_STYLE_IF(color_filter_opa, lv_xml_to_opa(value)); + else SET_STYLE_IF(anim_duration, lv_xml_atoi(value)); + else SET_STYLE_IF(blend_mode, lv_xml_blend_mode_to_enum(value)); + else SET_STYLE_IF(transform_width, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_height, lv_xml_atoi(value)); + else SET_STYLE_IF(translate_x, lv_xml_atoi(value)); + else SET_STYLE_IF(translate_y, lv_xml_atoi(value)); + else SET_STYLE_IF(translate_radial, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_scale_x, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_scale_y, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_rotation, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_pivot_x, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_pivot_y, lv_xml_atoi(value)); + else SET_STYLE_IF(transform_skew_x, lv_xml_atoi(value)); + else SET_STYLE_IF(bitmap_mask_src, lv_xml_get_image(&state->scope, value)); + else SET_STYLE_IF(rotary_sensitivity, lv_xml_atoi(value)); + else SET_STYLE_IF(recolor, lv_xml_to_color(value)); + else SET_STYLE_IF(recolor_opa, lv_xml_to_opa(value)); + + else SET_STYLE_IF(layout, lv_xml_layout_to_enum(value)); + + else SET_STYLE_IF(flex_flow, lv_xml_flex_flow_to_enum(value)); + else SET_STYLE_IF(flex_grow, lv_xml_atoi(value)); + else SET_STYLE_IF(flex_main_place, lv_xml_flex_align_to_enum(value)); + else SET_STYLE_IF(flex_cross_place, lv_xml_flex_align_to_enum(value)); + else SET_STYLE_IF(flex_track_place, lv_xml_flex_align_to_enum(value)); + + else SET_STYLE_IF(grid_column_align, lv_xml_grid_align_to_enum(value)); + else SET_STYLE_IF(grid_row_align, lv_xml_grid_align_to_enum(value)); + else SET_STYLE_IF(grid_cell_column_pos, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_column_span, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_x_align, lv_xml_grid_align_to_enum(value)); + else SET_STYLE_IF(grid_cell_row_pos, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_row_span, lv_xml_atoi(value)); + else SET_STYLE_IF(grid_cell_y_align, lv_xml_grid_align_to_enum(value)); +} + + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_obj_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_obj_parser.h new file mode 100644 index 000000000..238881278 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_obj_parser.h @@ -0,0 +1,40 @@ +/** + * @file lv_xml_obj_parser.h + * + */ + +#ifndef LV_OBJ_XML_PARSER_H +#define LV_OBJ_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_obj_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_obj_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_OBJ_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_roller_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_roller_parser.c new file mode 100644 index 000000000..616af0fa7 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_roller_parser.c @@ -0,0 +1,117 @@ +/** + * @file lv_xml_roller_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_roller_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_roller_mode_t mode_text_to_enum_value(const char * txt); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_roller_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + void * item = lv_roller_create(lv_xml_state_get_parent(state)); + return item; +} + +void lv_xml_roller_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("selected", name)) { + char buf[64]; + lv_strlcpy(buf, value, sizeof(buf)); + char * buf_p = buf; + int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); + bool v2 = lv_xml_to_bool(buf_p); + lv_roller_set_selected(item, v1, v2); + } + if(lv_streq("visible_row_count", name)) { + lv_roller_set_visible_row_count(item, lv_xml_atoi(value)); + } + + if(lv_streq("options", name)) { + /*E.g. 'a\nb\nc' true'*/ + size_t opts_len = lv_strlen(value); + char * opts_buf = lv_malloc(opts_len + 1); + lv_memcpy(opts_buf, value, opts_len + 1); + LV_ASSERT_MALLOC(opts_buf); + + /*Find the last space and trim the rest*/ + uint32_t space_pos_from_back = 1; + while(space_pos_from_back < opts_len && value[opts_len - space_pos_from_back] != ' ') { + space_pos_from_back++; + } + + opts_buf[opts_len - space_pos_from_back - 1] = '\0'; /*Also trim the `'`*/ + + lv_roller_mode_t mode = mode_text_to_enum_value(&opts_buf[opts_len - space_pos_from_back + 1]); + + /*Also skip the leading `'`*/ + lv_roller_set_options(item, opts_buf + 1, mode); + + lv_free(opts_buf); + + } + else if(lv_streq("bind_value", name)) { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); + if(subject) { + lv_roller_bind_value(item, subject); + } + else { + LV_LOG_WARN("Subject \"%s\" doesn't exist in roller bind_value", value); + } + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_roller_mode_t mode_text_to_enum_value(const char * txt) +{ + if(lv_streq("normal", txt)) return LV_ROLLER_MODE_NORMAL; + if(lv_streq("infinite", txt)) return LV_ROLLER_MODE_INFINITE; + + LV_LOG_WARN("%s is an unknown value for roller's mode", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_roller_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_roller_parser.h new file mode 100644 index 000000000..f351b2655 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_roller_parser.h @@ -0,0 +1,40 @@ +/** + * @file lv_xml_roller_parser.h + * + */ + +#ifndef LV_ROLLER_XML_PARSER_H +#define LV_ROLLER_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_roller_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_roller_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_ROLLER_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_scale_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_scale_parser.c new file mode 100644 index 000000000..0d63a116f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_scale_parser.c @@ -0,0 +1,135 @@ +/** + * @file lv_xml_scale_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_scale_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_scale_mode_t scale_mode_to_enum(const char * txt); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_scale_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_scale_create(lv_xml_state_get_parent(state)); + + return item; +} + + +void lv_xml_scale_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + + // + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("mode", name)) lv_scale_set_mode(item, scale_mode_to_enum(value)); + else if(lv_streq("total_tick_count", name)) lv_scale_set_total_tick_count(item, lv_xml_atoi(value)); + else if(lv_streq("major_tick_every", name)) lv_scale_set_major_tick_every(item, lv_xml_atoi(value)); + else if(lv_streq("label_show", name)) lv_scale_set_label_show(item, lv_xml_to_bool(value)); + else if(lv_streq("post_draw", name)) lv_scale_set_post_draw(item, lv_xml_to_bool(value)); + else if(lv_streq("draw_ticks_on_top", name)) lv_scale_set_draw_ticks_on_top(item, lv_xml_to_bool(value)); + else if(lv_streq("range", name)) { + int32_t value1 = lv_xml_atoi_split(&value, ' '); + int32_t value2 = lv_xml_atoi_split(&value, ' '); + lv_scale_set_range(item, value1, value2); + } + else if(lv_streq("angle_range", name)) lv_scale_set_angle_range(item, lv_xml_to_bool(value)); + else if(lv_streq("rotation", name)) lv_scale_set_rotation(item, lv_xml_to_bool(value)); + } +} + +void * lv_xml_scale_section_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_scale_add_section(lv_xml_state_get_parent(state)); + return item; +} + +void lv_xml_scale_section_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(state); + LV_UNUSED(attrs); + + lv_obj_t * scale = lv_xml_state_get_parent(state); + lv_scale_section_t * section = lv_xml_state_get_item(state); + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("range", name)) { + int32_t value1 = lv_xml_atoi_split(&value, ' '); + int32_t value2 = lv_xml_atoi_split(&value, ' '); + lv_scale_set_section_range(scale, section, value1, value2); + } + else if(lv_streq("style_main", name)) { + lv_xml_style_t * style_dsc = lv_xml_get_style_by_name(&state->scope, value); + lv_scale_set_section_style_main(scale, section, &style_dsc->style); + } + else if(lv_streq("style_indicator", name)) { + lv_xml_style_t * style_dsc = lv_xml_get_style_by_name(&state->scope, value); + lv_scale_set_section_style_indicator(scale, section, &style_dsc->style); + } + else if(lv_streq("style_items", name)) { + lv_xml_style_t * style_dsc = lv_xml_get_style_by_name(&state->scope, value); + lv_scale_set_section_style_items(scale, section, &style_dsc->style); + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_scale_mode_t scale_mode_to_enum(const char * txt) +{ + if(lv_streq("horizontal_top", txt)) return LV_SCALE_MODE_HORIZONTAL_TOP; + if(lv_streq("horizontal_bottom", txt)) return LV_SCALE_MODE_HORIZONTAL_BOTTOM; + if(lv_streq("vertical_left", txt)) return LV_SCALE_MODE_VERTICAL_LEFT; + if(lv_streq("vertical_right", txt)) return LV_SCALE_MODE_VERTICAL_RIGHT; + if(lv_streq("round_inner", txt)) return LV_SCALE_MODE_ROUND_INNER; + if(lv_streq("round_outer", txt)) return LV_SCALE_MODE_ROUND_OUTER; + + LV_LOG_WARN("%s is an unknown value for scale's mode", txt); + return 0; /*Return 0 in lack of a better option. */ +} + + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_scale_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_scale_parser.h new file mode 100644 index 000000000..a7fc00841 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_scale_parser.h @@ -0,0 +1,41 @@ +/** + * @file lv_xml_scale_parser.h + * + */ + +#ifndef LV_SCALE_XML_PARSER_H +#define LV_SCALE_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_scale_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_scale_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_scale_section_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_scale_section_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SCALE_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_slider_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_slider_parser.c new file mode 100644 index 000000000..dea62f35d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_slider_parser.c @@ -0,0 +1,122 @@ +/** + * @file lv_xml_slider_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_slider_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_slider_orientation_t orentation_text_to_enum_value(const char * txt); +static lv_slider_mode_t mode_text_to_enum_value(const char * txt); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_slider_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + void * item = lv_slider_create(lv_xml_state_get_parent(state)); + return item; +} + +void lv_xml_slider_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("value", name)) { + char buf[64]; + lv_strlcpy(buf, value, sizeof(buf)); + char * buf_p = buf; + int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); + bool v2 = lv_xml_to_bool(buf_p); + lv_bar_set_value(item, v1, v2); + } + if(lv_streq("bind_value", name)) { + lv_subject_t * subject = lv_xml_get_subject(&state->scope, value); + if(subject) { + lv_slider_bind_value(item, subject); + } + else { + LV_LOG_WARN("Subject \"%s\" doesn't exist in slider bind_value", value); + } + } + if(lv_streq("start_value", name)) { + char buf[64]; + lv_strlcpy(buf, value, sizeof(buf)); + char * buf_p = buf; + int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); + bool v2 = lv_xml_to_bool(buf_p); + lv_bar_set_start_value(item, v1, v2); + } + if(lv_streq("orientation", name)) lv_slider_set_orientation(item, orentation_text_to_enum_value(value)); + if(lv_streq("mode", name)) lv_slider_set_mode(item, mode_text_to_enum_value(value)); + if(lv_streq("range_min", name)) lv_slider_set_range(item, lv_xml_atoi(value), lv_slider_get_max_value(item)); + if(lv_streq("range_max", name)) lv_slider_set_range(item, lv_slider_get_min_value(item), lv_xml_atoi(value)); + if(lv_streq("range", name)) { + char buf[64]; + lv_strlcpy(buf, value, sizeof(buf)); + char * buf_p = buf; + int32_t v1 = lv_xml_atoi(lv_xml_split_str(&buf_p, ' ')); + int32_t v2 = lv_xml_atoi(buf_p); + lv_slider_set_range(item, v1, v2); + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_slider_orientation_t orentation_text_to_enum_value(const char * txt) +{ + if(lv_streq("auto", txt)) return LV_SLIDER_ORIENTATION_AUTO; + if(lv_streq("horizontal", txt)) return LV_SLIDER_ORIENTATION_HORIZONTAL; + if(lv_streq("vertical", txt)) return LV_SLIDER_ORIENTATION_VERTICAL; + + LV_LOG_WARN("%s is an unknown value for slider's orientation", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +static lv_slider_mode_t mode_text_to_enum_value(const char * txt) +{ + if(lv_streq("normal", txt)) return LV_SLIDER_MODE_NORMAL; + if(lv_streq("range", txt)) return LV_SLIDER_MODE_RANGE; + if(lv_streq("symmetrical", txt)) return LV_SLIDER_MODE_SYMMETRICAL; + + LV_LOG_WARN("%s is an unknown value for slider's mode", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_slider_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_slider_parser.h new file mode 100644 index 000000000..cd387efcb --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_slider_parser.h @@ -0,0 +1,40 @@ +/** + * @file lv_xml_slider_parser.h + * + */ + +#ifndef LV_SLIDER_XML_PARSER_H +#define LV_SLIDER_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_slider_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_slider_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SLIDER_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_spangroup_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_spangroup_parser.c new file mode 100644 index 000000000..7d7fc0ea6 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_spangroup_parser.c @@ -0,0 +1,106 @@ +/** + * @file lv_xml_spangroup_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_spangroup_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static lv_span_overflow_t spangroup_overflow_to_enum(const char * txt); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_spangroup_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_spangroup_create(lv_xml_state_get_parent(state)); + + return item; +} + + +void lv_xml_spangroup_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("overflow", name)) lv_spangroup_set_overflow(item, spangroup_overflow_to_enum(value)); + else if(lv_streq("max_lines", name)) lv_spangroup_set_max_lines(item, lv_xml_atoi(value)); + else if(lv_streq("indent", name)) lv_spangroup_set_indent(item, lv_xml_atoi(value)); + } +} + +void * lv_xml_spangroup_span_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_spangroup_add_span(lv_xml_state_get_parent(state)); + return item; +} + +void lv_xml_spangroup_span_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(state); + LV_UNUSED(attrs); + + lv_obj_t * spangroup = lv_xml_state_get_parent(state); + lv_span_t * span = lv_xml_state_get_item(state); + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("text", name)) lv_spangroup_set_span_text(spangroup, span, value); + else if(lv_streq("style", name)) { + lv_xml_style_t * style_dsc = lv_xml_get_style_by_name(&state->scope, value); + lv_spangroup_set_span_style(spangroup, span, &style_dsc->style); + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_span_overflow_t spangroup_overflow_to_enum(const char * txt) +{ + if(lv_streq("clip", txt)) return LV_SPAN_OVERFLOW_CLIP; + if(lv_streq("ellipsis", txt)) return LV_SPAN_OVERFLOW_ELLIPSIS; + + LV_LOG_WARN("%s is an unknown value for span's overflow", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_spangroup_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_spangroup_parser.h new file mode 100644 index 000000000..69e3cf424 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_spangroup_parser.h @@ -0,0 +1,41 @@ +/** + * @file lv_xml_spangroup_parser.h + * + */ + +#ifndef LV_SPANGROUP_XML_PARSER_H +#define LV_SPANGROUP_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_spangroup_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_spangroup_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_spangroup_span_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_spangroup_span_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_SPANGROUP_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_table_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_table_parser.c new file mode 100644 index 000000000..91f55c68f --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_table_parser.c @@ -0,0 +1,149 @@ +/** + * @file lv_xml_table_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_table_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_table_cell_ctrl_t table_ctrl_to_enum(const char * txt); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_table_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_table_create(lv_xml_state_get_parent(state)); + + return item; +} + + +void lv_xml_table_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("column_count", name)) lv_table_set_column_count(item, lv_xml_atoi(value)); + else if(lv_streq("row_count", name)) lv_table_set_row_count(item, lv_xml_atoi(value)); + else if(lv_streq("selected_cell", name)) { + + int32_t value1 = lv_xml_atoi_split(&value, ' '); + int32_t value2 = lv_xml_atoi_split(&value, ' '); + lv_table_set_selected_cell(item, value1, value2); + } + } +} + +void * lv_xml_table_column_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + /*Nothing to create*/ + return lv_xml_state_get_parent(state);; +} + +void lv_xml_table_column_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(state); + LV_UNUSED(attrs); + + lv_obj_t * table = lv_xml_state_get_parent(state); + int32_t column = lv_xml_atoi(lv_xml_get_value_of(attrs, "column")); + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("width", name)) lv_table_set_column_width(table, column, lv_xml_atoi(value)); + } +} + +void * lv_xml_table_cell_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + + /*Nothing to create*/ + return lv_xml_state_get_parent(state);; +} + +void lv_xml_table_cell_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(state); + LV_UNUSED(attrs); + + lv_obj_t * table = lv_xml_state_get_parent(state); + int32_t row = lv_xml_atoi(lv_xml_get_value_of(attrs, "row")); + int32_t column = lv_xml_atoi(lv_xml_get_value_of(attrs, "column")); + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("value", name)) lv_table_set_cell_value(table, row, column, value); + if(lv_streq("ctrl", name)) { + lv_table_cell_ctrl_t ctrl = 0; + char buf[256]; + lv_strncpy(buf, value, sizeof(buf)); + char * buf_p = buf; + const char * str; + while((str = lv_xml_split_str(&buf_p, '|')) != NULL) { + ctrl |= table_ctrl_to_enum(str); + } + + lv_table_set_cell_ctrl(table, row, column, ctrl); + } + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +static lv_table_cell_ctrl_t table_ctrl_to_enum(const char * txt) +{ + if(lv_streq("none", txt)) return LV_TABLE_CELL_CTRL_NONE; + if(lv_streq("merge_right", txt)) return LV_TABLE_CELL_CTRL_MERGE_RIGHT; + if(lv_streq("text_crop", txt)) return LV_TABLE_CELL_CTRL_TEXT_CROP; + if(lv_streq("custom_1", txt)) return LV_TABLE_CELL_CTRL_CUSTOM_1; + if(lv_streq("custom_2", txt)) return LV_TABLE_CELL_CTRL_CUSTOM_2; + if(lv_streq("custom_3", txt)) return LV_TABLE_CELL_CTRL_CUSTOM_3; + if(lv_streq("custom_4", txt)) return LV_TABLE_CELL_CTRL_CUSTOM_4; + + LV_LOG_WARN("%s is an unknown value for table's ctrl", txt); + return 0; /*Return 0 in lack of a better option. */ +} + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_table_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_table_parser.h new file mode 100644 index 000000000..111c1ffaa --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_table_parser.h @@ -0,0 +1,43 @@ +/** + * @file lv_xml_table_parser.h + * + */ + +#ifndef LV_TABLE_XML_PARSER_H +#define LV_TABLE_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_table_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_table_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_table_column_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_table_column_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_table_cell_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_table_cell_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TABLE_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_tabview_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_tabview_parser.c new file mode 100644 index 000000000..e1e8947b0 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_tabview_parser.c @@ -0,0 +1,94 @@ +/** + * @file lv_xml_tabview_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_tabview_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_tabview_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_tabview_create(lv_xml_state_get_parent(state)); + + return item; +} + + +void lv_xml_tabview_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + if(lv_streq("active", name)) lv_tabview_set_active(item, lv_xml_atoi(value), 0); + if(lv_streq("tab_bar_position", name)) lv_tabview_set_tab_bar_position(item, lv_xml_dir_to_enum(value)); + } +} + +void * lv_xml_tabview_tab_bar_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_tabview_get_tab_bar(lv_xml_state_get_parent(state)); + return item; +} + + +void lv_xml_tabview_tab_bar_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + /*Apply the common properties, e.g. width, height, styles flags etc*/ + lv_xml_obj_apply(state, attrs); +} + +void * lv_xml_tabview_tab_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + const char * text = lv_xml_get_value_of(attrs, "text"); + void * item = lv_tabview_add_tab(lv_xml_state_get_parent(state), text); + return item; +} + +void lv_xml_tabview_tab_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + /*Apply the common properties, e.g. width, height, styles flags etc*/ + lv_xml_obj_apply(state, attrs); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_tabview_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_tabview_parser.h new file mode 100644 index 000000000..9959da806 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_tabview_parser.h @@ -0,0 +1,44 @@ +/** + * @file lv_xml_tabview_parser.h + * + */ + +#ifndef LV_TABVIEW_XML_PARSER_H +#define LV_TABVIEW_XML_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_tabview_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_tabview_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_tabview_tab_bar_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_tabview_tab_bar_apply(lv_xml_parser_state_t * state, const char ** attrs); +void * lv_xml_tabview_tab_create(lv_xml_parser_state_t * state, const char ** attrs); +void lv_xml_tabview_tab_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_TABVIEW_XML_PARSE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_textarea_parser.c b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_textarea_parser.c new file mode 100644 index 000000000..cea2c7efc --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_textarea_parser.c @@ -0,0 +1,72 @@ +/** + * @file lv_xml_textarea_parser.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_xml_textarea_parser.h" +#if LV_USE_XML + +#include "../../../lvgl.h" +#include "../../../lvgl_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void * lv_xml_textarea_create(lv_xml_parser_state_t * state, const char ** attrs) +{ + LV_UNUSED(attrs); + void * item = lv_textarea_create(lv_xml_state_get_parent(state)); + + return item; +} + +void lv_xml_textarea_apply(lv_xml_parser_state_t * state, const char ** attrs) +{ + void * item = lv_xml_state_get_item(state); + + lv_xml_obj_apply(state, attrs); /*Apply the common properties, e.g. width, height, styles flags etc*/ + + for(int i = 0; attrs[i]; i += 2) { + const char * name = attrs[i]; + const char * value = attrs[i + 1]; + + + if(lv_streq("text", name)) lv_textarea_set_text(item, value); + else if(lv_streq("placeholder", name)) lv_textarea_set_placeholder_text(item, value); + else if(lv_streq("one_line", name)) lv_textarea_set_one_line(item, lv_xml_to_bool(value)); + else if(lv_streq("password_mode", name)) lv_textarea_set_password_mode(item, lv_xml_to_bool(value)); + else if(lv_streq("password_show_time", name)) lv_textarea_set_password_show_time(item, lv_xml_atoi(value)); + else if(lv_streq("text_selection", name)) lv_textarea_set_text_selection(item, lv_xml_to_bool(value)); + else if(lv_streq("cursor_pos", name)) lv_textarea_set_cursor_pos(item, lv_xml_atoi(value)); + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /* LV_USE_XML */ diff --git a/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_textarea_parser.h b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_textarea_parser.h new file mode 100644 index 000000000..630696ad4 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/others/xml/parsers/lv_xml_textarea_parser.h @@ -0,0 +1,41 @@ +/** + * @file lv_xml_textarea_parser.h + * + */ + +#ifndef LV_XML_TEXTAREA_PARSER_H +#define LV_XML_TEXTAREA_PARSER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_xml.h" +#if LV_USE_XML + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +void * lv_xml_textarea_create(lv_xml_parser_state_t * state, const char ** attrs); + +void lv_xml_textarea_apply(lv_xml_parser_state_t * state, const char ** attrs); + +/********************** + * MACROS + **********************/ + +#endif /* LV_USE_XML */ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_XML_TEXTAREA_PARSER_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/LICENSE_SPRINTF.txt b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/LICENSE_SPRINTF.txt new file mode 100644 index 000000000..bd9d8c1d1 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/LICENSE_SPRINTF.txt @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright (c) 2014 Marco Paland + +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. + +Original repository: https://github.com/mpaland/printf diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/LICENSE_TLSF.txt b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/LICENSE_TLSF.txt new file mode 100644 index 000000000..25b0fff3b --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/LICENSE_TLSF.txt @@ -0,0 +1 @@ +Released under the BSD license. 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 fc34db4d1..c9737523a 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 @@ -36,6 +36,7 @@ #if LV_USE_STDLIB_SPRINTF == LV_STDLIB_BUILTIN #include "../lv_sprintf.h" +#include "../lv_string.h" #include "../../misc/lv_types.h" #define PRINTF_DISABLE_SUPPORT_FLOAT (!LV_USE_FLOAT) @@ -143,15 +144,6 @@ static inline void _out_null(char character, void * buffer, size_t idx, size_t m LV_UNUSED(maxlen); } -// internal secure strlen -// \return The length of the string (excluding the terminating 0) limited by 'maxsize' -static inline unsigned int _strnlen_s(const char * str, size_t maxsize) -{ - const char * s; - for(s = str; *s && maxsize--; ++s); - return (unsigned int)(s - str); -} - // internal test if char is a digit (0-9) // \return true if char is a digit static inline bool _is_digit(char ch) @@ -822,7 +814,7 @@ static int lv_vsnprintf_inner(out_fct_type out, char * buffer, const size_t maxl case 's' : { const char * p = va_arg(va, char *); - unsigned int l = _strnlen_s(p, precision ? precision : (size_t) -1); + unsigned int l = lv_strnlen(p, precision ? precision : (size_t) -1); // pre padding if(flags & FLAGS_PRECISION) { l = (l < precision ? l : precision); 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 f225adccf..9c28592a0 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 @@ -55,7 +55,7 @@ void * LV_ATTRIBUTE_FAST_MEM lv_memcpy(void * dst, const void * src, size_t len) { - uint8_t * d8 = dst; + volatile uint8_t * d8 = dst; const uint8_t * s8 = src; /*Simplify for small memories*/ @@ -191,6 +191,14 @@ size_t lv_strlen(const char * str) return i; } +size_t lv_strnlen(const char * str, size_t max_len) +{ + size_t i = 0; + while(i < max_len && str[i]) i++; + + return i; +} + size_t lv_strlcpy(char * dst, const char * src, size_t dst_size) { size_t i = 0; @@ -232,6 +240,22 @@ int lv_strcmp(const char * s1, const char * s2) return *(const unsigned char *)s1 - *(const unsigned char *)s2; } +int lv_strncmp(const char * s1, const char * s2, size_t len) +{ + if(len == 0) { + return 0; + } + + while(len > 0 && *s1 && (*s1 == *s2)) { + if(--len == 0) { + return 0; + } + s1++; + s2++; + } + return *(const unsigned char *)s1 - *(const unsigned char *)s2; +} + char * lv_strdup(const char * src) { size_t len = lv_strlen(src) + 1; @@ -242,6 +266,17 @@ char * lv_strdup(const char * src) return dst; } +char * lv_strndup(const char * src, size_t max_len) +{ + size_t len = lv_strnlen(src, max_len); + char * dst = lv_malloc(len + 1); + if(dst == NULL) return NULL; + + lv_memcpy(dst, src, len); + dst[len] = '\0'; + return dst; +} + char * lv_strcat(char * dst, const char * src) { lv_strcpy(dst + lv_strlen(dst), src); @@ -262,6 +297,21 @@ char * lv_strncat(char * dst, const char * src, size_t src_len) return tmp; } +char * lv_strchr(const char * s, int c) +{ + for(; ; s++) { + if(*s == c) { + return (char *)s; + } + + if(*s == '\0') { + break; + } + } + + return NULL; +} + /********************** * STATIC FUNCTIONS **********************/ 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 4127271db..d56327274 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf.h +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf.h @@ -1,4 +1,4 @@ -#include "../../lv_conf_internal.h" +#include "../../lv_conf_internal.h" #if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN #ifndef LV_TLSF_H @@ -41,7 +41,6 @@ ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "../../osal/lv_os.h" #include "../../misc/lv_ll.h" #include "../../misc/lv_types.h" 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 index 036e9d73e..abba9573d 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf_private.h +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/builtin/lv_tlsf_private.h @@ -17,6 +17,7 @@ extern "C" { *********************/ #include "lv_tlsf.h" +#include "../../osal/lv_os.h" /********************* * DEFINES 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 fd01b93f9..df9f9761a 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 @@ -60,6 +60,11 @@ size_t lv_strlen(const char * str) return strlen(str); } +size_t lv_strnlen(const char * str, size_t max_len) +{ + return strnlen(str, max_len); +} + size_t lv_strlcpy(char * dst, const char * src, size_t dst_size) { size_t src_len = strlen(src); @@ -86,6 +91,11 @@ int lv_strcmp(const char * s1, const char * s2) return strcmp(s1, s2); } +int lv_strncmp(const char * s1, const char * s2, size_t len) +{ + return strncmp(s1, s2, len); +} + char * lv_strdup(const char * src) { /*strdup uses malloc, so use the lv_malloc when LV_USE_STDLIB_MALLOC is not LV_STDLIB_CLIB */ @@ -97,6 +107,17 @@ char * lv_strdup(const char * src) return dst; } +char * lv_strndup(const char * src, size_t max_len) +{ + size_t len = lv_strnlen(src, max_len); + char * dst = lv_malloc(len + 1); + if(dst == NULL) return NULL; + + lv_memcpy(dst, src, len); + dst[len] = '\0'; + return dst; +} + char * lv_strcat(char * dst, const char * src) { return strcat(dst, src); @@ -107,6 +128,11 @@ char * lv_strncat(char * dst, const char * src, size_t src_len) return strncat(dst, src, src_len); } +char * lv_strchr(const char * str, int c) +{ + return strchr(str, c); +} + /********************** * 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 bfc887fff..41a002d74 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.c +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.c @@ -116,6 +116,17 @@ void * lv_malloc_zeroed(size_t size) return alloc; } +void * lv_calloc(size_t num, size_t size) +{ + LV_TRACE_MEM("allocating number of %zu each %zu bytes", num, size); + return lv_malloc_zeroed(num * size); +} + +void * lv_zalloc(size_t size) +{ + return lv_malloc_zeroed(size); +} + void lv_free(void * data) { LV_TRACE_MEM("freeing %p", data); @@ -125,6 +136,15 @@ void lv_free(void * data) lv_free_core(data); } +void * lv_reallocf(void * data_p, size_t new_size) +{ + void * new = lv_realloc(data_p, new_size); + if(!new) { + lv_free(data_p); + } + return new; +} + void * lv_realloc(void * data_p, size_t new_size) { LV_TRACE_MEM("reallocating %p with %lu size", data_p, (unsigned long)new_size); diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.h b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.h index 210c18988..2b9e2defb 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.h +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_mem.h @@ -1,4 +1,4 @@ -/** +/** * @file lv_mem.h * */ @@ -68,6 +68,21 @@ void lv_mem_remove_pool(lv_mem_pool_t pool); */ void * lv_malloc(size_t size); +/** + * Allocate a block of zeroed memory dynamically + * @param num requested number of element to be allocated. + * @param size requested size of each element in bytes. + * @return pointer to allocated zeroed memory, or NULL on failure + */ +void * lv_calloc(size_t num, size_t size); + +/** + * Allocate zeroed memory dynamically + * @param size requested size in bytes + * @return pointer to allocated zeroed memory, or NULL on failure + */ +void * lv_zalloc(size_t size); + /** * Allocate zeroed memory dynamically * @param size requested size in bytes @@ -90,6 +105,16 @@ void lv_free(void * data); */ void * lv_realloc(void * data_p, size_t new_size); +/** + * Reallocate a memory with a new size. The old content will be kept. + * In case of failure, the old pointer is free'd. + * @param data_p pointer to an allocated memory. + * Its content will be copied to the new memory block and freed + * @param new_size the desired new size in byte + * @return pointer to the new memory, NULL on failure + */ +void * lv_reallocf(void * data_p, size_t new_size); + /** * Used internally to execute a plain `malloc` operation * @param size size in bytes to `malloc` diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_sprintf.h b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_sprintf.h index a7f2188d6..19bfd2f4e 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_sprintf.h +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_sprintf.h @@ -14,11 +14,21 @@ #define LV_PRIu32 PRIu32 #define LV_PRIx32 PRIx32 #define LV_PRIX32 PRIX32 + + #define LV_PRId64 PRId64 + #define LV_PRIu64 PRIu64 + #define LV_PRIx64 PRIx64 + #define LV_PRIX64 PRIX64 #else #define LV_PRId32 "d" #define LV_PRIu32 "u" #define LV_PRIx32 "x" #define LV_PRIX32 "X" + + #define LV_PRId64 "lld" + #define LV_PRIu64 "llu" + #define LV_PRIx64 "llx" + #define LV_PRIX64 "llX" #endif #else /* hope this is correct for ports without __has_include or without inttypes.h */ @@ -26,6 +36,11 @@ #define LV_PRIu32 "u" #define LV_PRIx32 "x" #define LV_PRIX32 "X" + + #define LV_PRId64 "lld" + #define LV_PRIu64 "llu" + #define LV_PRIx64 "llx" + #define LV_PRIX64 "llX" #endif #include "../misc/lv_types.h" diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_string.h b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_string.h index 10aee500f..12466c6cb 100644 --- a/lib/libesp32_lvgl/lvgl/src/stdlib/lv_string.h +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/lv_string.h @@ -76,12 +76,21 @@ static inline void lv_memzero(void * dst, size_t len) } /** - * @brief Computes the length of the string str up to, but not including the terminating null character. + * @brief Computes the length of the string str up to (but not including) the terminating null character. * @param str Pointer to the null-terminated byte string to be examined. * @return The length of the string in bytes. */ size_t lv_strlen(const char * str); +/** + * @brief Computes the length of the string str up to (but not including) the terminating null character, + * or the given maximum length. + * @param str Pointer to byte string that is null-terminated or at least max_len bytes long. + * @param max_len Maximum number of characters to examine. + * @return The length of the string in bytes. + */ +size_t lv_strnlen(const char * str, size_t max_len); + /** * @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. @@ -119,6 +128,26 @@ char * lv_strcpy(char * dst, const char * src); */ int lv_strcmp(const char * s1, const char * s2); +/** + * @brief This function will compare two strings up to the given length. + * @param s1 pointer to the first string + * @param s2 pointer to the second string + * @param len the maximum amount of characters to compare + * @return the difference between the value of the first unmatching character. + */ +int lv_strncmp(const char * s1, const char * s2, size_t len); + +/** Returns true if the two strings are equal. + * Just a wrapper around strcmp for convenience. + * @param s1 pointer to the first string + * @param s2 pointer to the second string + * @return true: the strings are equal; false: otherwise + */ +static inline bool lv_streq(const char * s1, const char * s2) +{ + return lv_strcmp(s1, s2) == 0; +} + /** * @brief Duplicate a string by allocating a new one and copying the content. * @param src Pointer to the source of data to be copied. @@ -126,6 +155,15 @@ int lv_strcmp(const char * s1, const char * s2); */ char * lv_strdup(const char * src); +/** + * @brief Duplicate a string by allocating a new one and copying the content + * up to the end or the specified maximum length, whichever comes first. + * @param src Pointer to the source of data to be copied. + * @param max_len Maximum number of characters to be copied. + * @return Pointer to a newly allocated null-terminated string. NULL if failed. + */ +char * lv_strndup(const char * src, size_t max_len); + /** * @brief Copies the string pointed to by src, including the terminating null character, * to the end of the string pointed to by dst. @@ -147,6 +185,14 @@ char * lv_strcat(char * dst, const char * src); */ char * lv_strncat(char * dst, const char * src, size_t src_len); +/** + * @brief Searches for the first occurrence of character c in the string str. + * @param str Pointer to the null-terminated byte string to be searched. + * @param c The character to be searched for. + * @return A pointer to the first occurrence of character c in the string str, or a null pointer if c is not found. + */ +char * lv_strchr(const char * str, int c); + /********************** * MACROS **********************/ 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 2ab0a4717..fd2ff2a95 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,14 @@ size_t lv_strlen(const char * str) return rt_strlen(str); } +size_t lv_strnlen(const char * str, size_t max_len) +{ + size_t i = 0; + while(i < max_len && str[i]) i++; + + return i; +} + int lv_memcmp(const void * p1, const void * p2, size_t len) { return rt_memcmp(p1, p2, len); @@ -86,6 +94,11 @@ int lv_strcmp(const char * s1, const char * s2) return rt_strcmp(s1, s2); } +int lv_strncmp(const char * s1, const char * s2, size_t len) +{ + return rt_strncmp(s1, s2, len); +} + char * lv_strdup(const char * src) { size_t len = lv_strlen(src) + 1; @@ -96,6 +109,17 @@ char * lv_strdup(const char * src) return dst; } +char * lv_strndup(const char * src, size_t max_len) +{ + size_t len = lv_strnlen(src, max_len); + char * dst = lv_malloc(len + 1); + if(dst == NULL) return NULL; + + lv_memcpy(dst, src, len); + dst[len] = '\0'; + return dst; +} + char * lv_strcat(char * dst, const char * src) { /*Since RT-thread does not have rt_strcat, @@ -116,6 +140,21 @@ char * lv_strncat(char * dst, const char * src, size_t src_len) return tmp; } +char * lv_strchr(const char * s, int c) +{ + for(; ; s++) { + if(*s == c) { + return (char *)s; + } + + if(*s == '\0') { + break; + } + } + + return NULL; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/stdlib/uefi/lv_mem_core_uefi.c b/lib/libesp32_lvgl/lvgl/src/stdlib/uefi/lv_mem_core_uefi.c new file mode 100644 index 000000000..ea03e2c60 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/stdlib/uefi/lv_mem_core_uefi.c @@ -0,0 +1,116 @@ +/** + * @file lv_mem_core_uefi.c + */ + +/********************* + * INCLUDES + *********************/ +#include "../lv_mem.h" +#if LV_USE_UEFI +#if LV_UEFI_USE_MEMORY_SERVICES && LV_USE_STDLIB_MALLOC == LV_STDLIB_CUSTOM +#include "../drivers/uefi/lv_uefi_private.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ +typedef struct _mem_header_t { + size_t size; + uint8_t data[0]; +} mem_header_t; + +void lv_mem_init(void) +{ + LV_ASSERT_NULL(gLvEfiBS); + + return; /*Nothing to init*/ +} + +void lv_mem_deinit(void) +{ + return; /*Nothing to deinit*/ +} + +void * lv_malloc_core(size_t size) +{ + size_t size_with_header = size + sizeof(mem_header_t); + mem_header_t * ptr = NULL; + + if(gLvEfiBS->AllocatePool(EfiBootServicesData, size_with_header, (void **)&ptr) != EFI_SUCCESS) return NULL; + + ptr->size = size; + + return ptr->data; +} + +void * lv_realloc_core(void * p, size_t new_size) +{ + mem_header_t * p_header = NULL; + uintptr_t p_address = (uintptr_t)p; + void * p_new = NULL; + + if(p == NULL) return lv_malloc_core(new_size); + // Check for invalid pointers + if(p_address < sizeof(mem_header_t)) return NULL; + + p_address -= sizeof(mem_header_t); + p_header = (mem_header_t *) p_address; + + // UEFI supportes no realloc, if the size grows a new memory block has to be allocated + if(p_header->size > new_size) return p; + + p_new = lv_malloc_core(new_size); + lv_memcpy(p_new, p, p_header->size); + lv_free_core(p); + + return p_new; +} + +void lv_free_core(void * p) +{ + uintptr_t p_address = (uintptr_t)p; + if(p_address < sizeof(mem_header_t)) return; + + p_address -= sizeof(mem_header_t); + + gLvEfiBS->FreePool((void *)p_address); +} + +void lv_mem_monitor_core(lv_mem_monitor_t * mon_p) +{ + /*Not supported*/ + LV_UNUSED(mon_p); + return; +} + +lv_result_t lv_mem_test_core(void) +{ + /*Not supported*/ + return LV_RESULT_OK; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif +#endif \ No newline at end of file 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 fa1266219..fceb3a35f 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 @@ -170,9 +170,6 @@ struct _my_theme_t { bool inited; my_theme_styles_t styles; - lv_color_filter_dsc_t dark_filter; - lv_color_filter_dsc_t grey_filter; - #if LV_THEME_DEFAULT_TRANSITION_TIME lv_style_transition_dsc_t trans_delayed; lv_style_transition_dsc_t trans_normal; @@ -197,19 +194,6 @@ static void style_init_reset(lv_style_t * style); * STATIC FUNCTIONS **********************/ -static lv_color_t dark_color_filter_cb(const lv_color_filter_dsc_t * f, lv_color_t c, lv_opa_t opa) -{ - LV_UNUSED(f); - return lv_color_darken(c, opa); -} - -static lv_color_t grey_filter_cb(const lv_color_filter_dsc_t * f, lv_color_t color, lv_opa_t opa) -{ - LV_UNUSED(f); - if(theme_def->base.flags & MODE_DARK) return lv_color_mix(lv_palette_darken(LV_PALETTE_GREY, 2), color, opa); - else return lv_color_mix(lv_palette_lighten(LV_PALETTE_GREY, 2), color, opa); -} - static void style_init(my_theme_t * theme) { #if TRANSITION_TIME @@ -219,7 +203,7 @@ static void style_init(my_theme_t * theme) LV_STYLE_TRANSLATE_Y, LV_STYLE_TRANSLATE_X, LV_STYLE_TRANSFORM_ROTATION, LV_STYLE_TRANSFORM_SCALE_X, LV_STYLE_TRANSFORM_SCALE_Y, - LV_STYLE_COLOR_FILTER_OPA, LV_STYLE_COLOR_FILTER_DSC, + LV_STYLE_RECOLOR_OPA, LV_STYLE_RECOLOR, 0 }; #endif @@ -308,16 +292,16 @@ static void style_init(my_theme_t * theme) 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); - style_init_reset(&theme->styles.pressed); - lv_style_set_color_filter_dsc(&theme->styles.pressed, &theme->dark_filter); - lv_style_set_color_filter_opa(&theme->styles.pressed, 35); + lv_style_set_recolor(&theme->styles.pressed, lv_color_black()); + lv_style_set_recolor_opa(&theme->styles.pressed, 35); style_init_reset(&theme->styles.disabled); - lv_style_set_color_filter_dsc(&theme->styles.disabled, &theme->grey_filter); - lv_style_set_color_filter_opa(&theme->styles.disabled, LV_OPA_50); + if(theme_def->base.flags & MODE_DARK) + lv_style_set_recolor(&theme->styles.disabled, lv_palette_darken(LV_PALETTE_GREY, 2)); + else + lv_style_set_recolor(&theme->styles.disabled, lv_palette_lighten(LV_PALETTE_GREY, 2)); + lv_style_set_recolor_opa(&theme->styles.disabled, LV_OPA_50); style_init_reset(&theme->styles.clip_corner); lv_style_set_clip_corner(&theme->styles.clip_corner, true); @@ -664,7 +648,7 @@ lv_theme_t * lv_theme_default_init(lv_display_t * disp, lv_color_t color_primary theme->disp_size == new_size && lv_color_eq(theme->base.color_primary, color_primary) && lv_color_eq(theme->base.color_secondary, color_secondary) && - (theme->base.flags == dark ? MODE_DARK : 0) && + (theme->base.flags == (dark ? MODE_DARK : 0)) && theme->base.font_small == font) { return (lv_theme_t *) theme; @@ -934,11 +918,9 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) lv_obj_add_style(obj, &theme->styles.outline_primary, LV_STATE_FOCUS_KEY); lv_obj_add_style(obj, &theme->styles.bg_color_primary, LV_PART_INDICATOR | LV_STATE_CHECKED); lv_obj_add_style(obj, &theme->styles.circle, LV_PART_INDICATOR); - lv_obj_add_style(obj, &theme->styles.disabled, LV_PART_INDICATOR | LV_STATE_DISABLED); lv_obj_add_style(obj, &theme->styles.knob, LV_PART_KNOB); lv_obj_add_style(obj, &theme->styles.bg_color_white, LV_PART_KNOB); lv_obj_add_style(obj, &theme->styles.switch_knob, LV_PART_KNOB); - lv_obj_add_style(obj, &theme->styles.disabled, LV_PART_KNOB | LV_STATE_DISABLED); lv_obj_add_style(obj, &theme->styles.transition_normal, LV_PART_INDICATOR | LV_STATE_CHECKED); lv_obj_add_style(obj, &theme->styles.transition_normal, LV_PART_INDICATOR); @@ -1061,6 +1043,13 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) lv_obj_add_style(obj, &theme->styles.bg_color_secondary_muted, LV_PART_ITEMS | LV_STATE_EDITED); } #endif + +#if LV_USE_LABEL && LV_USE_TEXTAREA + else if(lv_obj_check_type(obj, &lv_label_class) && lv_obj_check_type(parent, &lv_textarea_class)) { + lv_obj_add_style(obj, &theme->styles.bg_color_primary, LV_PART_SELECTED); + } +#endif + #if LV_USE_LIST else if(lv_obj_check_type(obj, &lv_list_class)) { lv_obj_add_style(obj, &theme->styles.card, 0); diff --git a/lib/libesp32_lvgl/lvgl/src/themes/lv_theme_private.h b/lib/libesp32_lvgl/lvgl/src/themes/lv_theme_private.h index 6fd10a59c..f7bb24cd1 100644 --- a/lib/libesp32_lvgl/lvgl/src/themes/lv_theme_private.h +++ b/lib/libesp32_lvgl/lvgl/src/themes/lv_theme_private.h @@ -24,7 +24,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_theme_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; 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 cd71ecb3d..9f69f7b02 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 @@ -515,6 +515,14 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) #endif } +lv_theme_t * lv_theme_mono_get(void) +{ + if(!lv_theme_mono_is_inited()) { + return NULL; + } + return (lv_theme_t *)theme_def; +} + /********************** * STATIC FUNCTIONS **********************/ 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 30ac4c488..794411b49 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 @@ -44,6 +44,12 @@ lv_theme_t * lv_theme_mono_init(lv_display_t * disp, bool dark_bg, const lv_font */ bool lv_theme_mono_is_inited(void); +/** + * Get mono theme + * @return a pointer to mono theme, or NULL if this is not initialized + */ +lv_theme_t * lv_theme_mono_get(void); + /** * Deinitialize the mono theme */ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/3dtexture/lv_3dtexture.c b/lib/libesp32_lvgl/lvgl/src/widgets/3dtexture/lv_3dtexture.c new file mode 100644 index 000000000..8db3f4e4d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/3dtexture/lv_3dtexture.c @@ -0,0 +1,144 @@ +/** + * @file lv_3dtexture.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "lv_3dtexture_private.h" +#if LV_USE_3DTEXTURE + +#include "../../core/lv_obj_class_private.h" +#include "../../draw/lv_draw_3d.h" + +/********************* + * DEFINES + *********************/ + +#define MY_CLASS (&lv_3dtexture_class) + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static void lv_3dtexture_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); +static void lv_3dtexture_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj); +static void lv_3dtexture_event(const lv_obj_class_t * class_p, lv_event_t * e); +static void draw_3dtexture(lv_event_t * e); + +/********************** + * STATIC VARIABLES + **********************/ + +const lv_obj_class_t lv_3dtexture_class = { + .constructor_cb = lv_3dtexture_constructor, + .destructor_cb = lv_3dtexture_destructor, + .event_cb = lv_3dtexture_event, + .width_def = LV_DPI_DEF, + .height_def = LV_DPI_DEF, + .instance_size = sizeof(lv_3dtexture_t), + .base_class = &lv_obj_class, + .name = "3dtexture", +}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_obj_t * lv_3dtexture_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_3dtexture_set_src(lv_obj_t * obj, lv_3dtexture_id_t id) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_3dtexture_t * tex = (lv_3dtexture_t *)obj; + tex->id = id; +} + +/*====================== + * Add/remove functions + *=====================*/ + +/*===================== + * Setter functions + *====================*/ + +/*===================== + * Getter functions + *====================*/ + +/*===================== + * Other functions + *====================*/ + +/********************** + * STATIC FUNCTIONS + **********************/ + +static void lv_3dtexture_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) +{ + LV_UNUSED(class_p); + LV_TRACE_OBJ_CREATE("begin"); + + lv_3dtexture_t * tex = (lv_3dtexture_t *)obj; + tex->id = LV_3DTEXTURE_ID_NULL; + + LV_TRACE_OBJ_CREATE("finished"); +} + +static void lv_3dtexture_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) +{ + LV_UNUSED(class_p); + lv_3dtexture_t * tex = (lv_3dtexture_t *)obj; + LV_UNUSED(tex); +} + +static void lv_3dtexture_event(const lv_obj_class_t * class_p, lv_event_t * e) +{ + LV_UNUSED(class_p); + + lv_result_t res; + + /*Call the ancestor's event handler*/ + res = lv_obj_event_base(MY_CLASS, e); + if(res != LV_RESULT_OK) return; + + lv_event_code_t code = lv_event_get_code(e); + + if(code == LV_EVENT_DRAW_MAIN) { + draw_3dtexture(e); + } +} + +static void draw_3dtexture(lv_event_t * e) +{ + lv_obj_t * obj = lv_event_get_current_target(e); + lv_3dtexture_t * tex = (lv_3dtexture_t *)obj; + lv_layer_t * layer = lv_event_get_layer(e); + + lv_draw_3d_dsc_t dsc; + lv_draw_3d_dsc_init(&dsc); + dsc.tex_id = tex->id; + dsc.opa = lv_obj_get_style_opa(obj, 0); + lv_area_t coords; + lv_obj_get_coords(obj, &coords); + lv_draw_3d(layer, &dsc, &coords); +} + +#endif /*LV_USE_3DTEXTURE*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/3dtexture/lv_3dtexture.h b/lib/libesp32_lvgl/lvgl/src/widgets/3dtexture/lv_3dtexture.h new file mode 100644 index 000000000..87f158887 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/3dtexture/lv_3dtexture.h @@ -0,0 +1,78 @@ +/** + * @file lv_3dtexture.h + * + */ + +#ifndef LV_3DTEXTURE_H +#define LV_3DTEXTURE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +#include "../../lv_conf_internal.h" +#if LV_USE_3DTEXTURE + +#include "../../core/lv_obj.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_3dtexture_class; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a 3dtexture object + * @param parent pointer to an object, it will be the parent of the new 3dtexture + * @return pointer to the created 3dtexture + */ +lv_obj_t * lv_3dtexture_create(lv_obj_t * parent); + +/** + * Set the source texture of the widget. + * The object size should be manually set to match. + * @param obj the 3dtexture widget + * @param id the texture handle from the 3D graphics backend. + * I.e., an `unsigned int` texture for OpenGL. + */ +void lv_3dtexture_set_src(lv_obj_t * obj, lv_3dtexture_id_t id); + +/*====================== + * Add/remove functions + *=====================*/ + +/*===================== + * Setter functions + *====================*/ + +/*===================== + * Getter functions + *====================*/ + +/*===================== + * Other functions + *====================*/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_3DTEXTURE*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_3DTEXTURE_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient_private.h b/lib/libesp32_lvgl/lvgl/src/widgets/3dtexture/lv_3dtexture_private.h similarity index 56% rename from lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient_private.h rename to lib/libesp32_lvgl/lvgl/src/widgets/3dtexture/lv_3dtexture_private.h index 7e2f2ab3d..0a7b770f5 100644 --- a/lib/libesp32_lvgl/lvgl/src/draw/sw/lv_draw_sw_gradient_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/3dtexture/lv_3dtexture_private.h @@ -1,10 +1,10 @@ /** - * @file lv_draw_sw_gradient_private.h + * @file lv_3dtexture_private.h * */ -#ifndef LV_DRAW_SW_GRADIENT_PRIVATE_H -#define LV_DRAW_SW_GRADIENT_PRIVATE_H +#ifndef LV_3DTEXTURE_PRIVATE_H +#define LV_3DTEXTURE_PRIVATE_H #ifdef __cplusplus extern "C" { @@ -14,9 +14,10 @@ extern "C" { * INCLUDES *********************/ -#include "lv_draw_sw_gradient.h" +#include "lv_3dtexture.h" +#if LV_USE_3DTEXTURE -#if LV_USE_DRAW_SW +#include "../../core/lv_obj_private.h" /********************* * DEFINES @@ -26,13 +27,12 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_grad_t { - lv_color_t * color_map; - lv_opa_t * opa_map; - uint32_t size; +/*Data of 3dtexture*/ +struct _lv_3dtexture_t { + lv_obj_t obj; + lv_3dtexture_id_t id; }; - /********************** * GLOBAL PROTOTYPES **********************/ @@ -41,10 +41,10 @@ struct lv_grad_t { * MACROS **********************/ -#endif /* LV_USE_DRAW_SW */ +#endif /*LV_USE_3DTEXTURE*/ #ifdef __cplusplus } /*extern "C"*/ #endif -#endif /*LV_DRAW_SW_GRADIENT_PRIVATE_H*/ +#endif /*LV_3DTEXTURE_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 548c48c8c..56e9a2f3a 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.c @@ -3,6 +3,10 @@ * */ +/** + * Modified by NXP in 2025 + */ + /********************* * INCLUDES *********************/ @@ -39,16 +43,53 @@ **********************/ 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); +static void lv_animimg_set_src_inner(lv_obj_t * obj, const void * dsc[], size_t num, bool reverse); /********************** * STATIC VARIABLES **********************/ +#if LV_USE_OBJ_PROPERTY +static const lv_property_ops_t properties[] = { + { + .id = LV_PROPERTY_ANIMIMAGE_SRC, + .setter = lv_animimg_set_src, + .getter = lv_animimg_get_src, + }, + { + .id = LV_PROPERTY_ANIMIMAGE_DURATION, + .setter = lv_animimg_set_duration, + .getter = lv_animimg_get_duration, + }, + { + .id = LV_PROPERTY_ANIMIMAGE_REPEAT_COUNT, + .setter = lv_animimg_set_repeat_count, + .getter = lv_animimg_get_repeat_count, + }, + { + .id = LV_PROPERTY_ANIMIMAGE_SRC_COUNT, + .setter = NULL, + .getter = lv_animimg_get_src_count, + }, +}; +#endif + const lv_obj_class_t lv_animimg_class = { .constructor_cb = lv_animimg_constructor, .instance_size = sizeof(lv_animimg_t), .base_class = &lv_image_class, - .name = "animimg", + .name = "lv_animimg", +#if LV_USE_OBJ_PROPERTY + .prop_index_start = LV_PROPERTY_ANIMIMAGE_START, + .prop_index_end = LV_PROPERTY_ANIMIMAGE_END, + .properties = properties, + .properties_count = sizeof(properties) / sizeof(properties[0]), + +#if LV_USE_OBJ_PROPERTY_NAME + .property_names = lv_animimage_property_names, + .names_count = sizeof(lv_animimage_property_names) / sizeof(lv_property_name_t), +#endif +#endif }; /********************** @@ -69,11 +110,12 @@ lv_obj_t * lv_animimg_create(lv_obj_t * parent) void lv_animimg_set_src(lv_obj_t * obj, const void * dsc[], size_t num) { - LV_ASSERT_OBJ(obj, MY_CLASS); - 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); + lv_animimg_set_src_inner(obj, dsc, num, false); +} + +void lv_animimg_set_src_reverse(lv_obj_t * obj, const void * dsc[], size_t num) +{ + lv_animimg_set_src_inner(obj, dsc, num, true); } void lv_animimg_start(lv_obj_t * obj) @@ -83,6 +125,13 @@ void lv_animimg_start(lv_obj_t * obj) lv_anim_start(&animimg->anim); } +bool lv_animimg_delete(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_animimg_t * animimg = (lv_animimg_t *)obj; + return lv_anim_delete(animimg, NULL); +} + /*===================== * Setter functions *====================*/ @@ -92,7 +141,7 @@ void lv_animimg_set_duration(lv_obj_t * obj, uint32_t duration) LV_ASSERT_OBJ(obj, MY_CLASS); lv_animimg_t * animimg = (lv_animimg_t *)obj; lv_anim_set_duration(&animimg->anim, duration); - lv_anim_set_playback_delay(&animimg->anim, duration); + lv_anim_set_reverse_delay(&animimg->anim, duration); } void lv_animimg_set_repeat_count(lv_obj_t * obj, uint32_t count) @@ -102,6 +151,34 @@ void lv_animimg_set_repeat_count(lv_obj_t * obj, uint32_t count) lv_anim_set_repeat_count(&animimg->anim, count); } +void lv_animimg_set_reverse_duration(lv_obj_t * obj, uint32_t duration) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_animimg_t * animimg = (lv_animimg_t *)obj; + lv_anim_set_reverse_duration(&animimg->anim, duration); +} + +void lv_animimg_set_reverse_delay(lv_obj_t * obj, uint32_t duration) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_animimg_t * animimg = (lv_animimg_t *)obj; + lv_anim_set_reverse_delay(&animimg->anim, duration); +} + +void lv_animimg_set_start_cb(lv_obj_t * obj, lv_anim_start_cb_t start_cb) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_animimg_t * animimg = (lv_animimg_t *)obj; + lv_anim_set_start_cb(&animimg->anim, start_cb); +} + +void lv_animimg_set_completed_cb(lv_obj_t * obj, lv_anim_completed_cb_t completed_cb) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_animimg_t * animimg = (lv_animimg_t *)obj; + lv_anim_set_completed_cb(&animimg->anim, completed_cb); +} + /*===================== * Getter functions *====================*/ @@ -178,4 +255,18 @@ static void index_change(lv_obj_t * obj, int32_t idx) lv_image_set_src(obj, animimg->dsc[idx]); } +static void lv_animimg_set_src_inner(lv_obj_t * obj, const void * dsc[], size_t num, bool reverse) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_animimg_t * animimg = (lv_animimg_t *)obj; + animimg->dsc = dsc; + animimg->pic_count = num; + if(reverse) { + lv_anim_set_values(&animimg->anim, (int32_t)num, 0); + } + else { + lv_anim_set_values(&animimg->anim, 0, (int32_t)num); + } +} + #endif 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 a2f1926c1..230eca499 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage.h @@ -3,6 +3,10 @@ * */ +/** + * Modified by NXP in 2025 + */ + #ifndef LV_ANIMIMAGE_H #define LV_ANIMIMAGE_H @@ -31,6 +35,16 @@ extern "C" { * TYPEDEFS **********************/ +#if LV_USE_OBJ_PROPERTY +enum { + LV_PROPERTY_ID2(ANIMIMAGE, SRC, LV_PROPERTY_TYPE_POINTER, LV_PROPERTY_TYPE_INT, 0), + LV_PROPERTY_ID(ANIMIMAGE, DURATION, LV_PROPERTY_TYPE_INT, 1), + LV_PROPERTY_ID(ANIMIMAGE, REPEAT_COUNT, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ID(ANIMIMAGE, SRC_COUNT, LV_PROPERTY_TYPE_INT, 3), + LV_PROPERTY_ANIMIMAGE_END, +}; +#endif + LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_animimg_class; /** Image parts */ @@ -55,11 +69,19 @@ lv_obj_t * lv_animimg_create(lv_obj_t * parent); /** * Set the image animation images source. - * @param img pointer to an animation image object - * @param dsc pointer to a series images - * @param num images' number + * @param obj pointer to an animation image object + * @param dsc pointer to a series images + * @param num images' number */ -void lv_animimg_set_src(lv_obj_t * img, const void * dsc[], size_t num); +void lv_animimg_set_src(lv_obj_t * obj, const void * dsc[], size_t num); + +/** + * Set the images source for flip playback of animation image. + * @param obj pointer to an animation image object + * @param dsc pointer to a series images + * @param num images' number + */ +void lv_animimg_set_src_reverse(lv_obj_t * obj, const void * dsc[], size_t num); /** * Startup the image animation. @@ -67,19 +89,53 @@ void lv_animimg_set_src(lv_obj_t * img, const void * dsc[], size_t num); */ void lv_animimg_start(lv_obj_t * obj); +/** + * Delete the image animation. + * @param obj pointer to an animation image object + */ +bool lv_animimg_delete(lv_obj_t * obj); + /** * Set the image animation duration time. unit:ms - * @param img pointer to an animation image object + * @param obj pointer to an animation image object * @param duration the duration in milliseconds */ -void lv_animimg_set_duration(lv_obj_t * img, uint32_t duration); +void lv_animimg_set_duration(lv_obj_t * obj, uint32_t duration); /** * Set the image animation repeatedly play times. - * @param img pointer to an animation image object + * @param obj pointer to an animation image object * @param count the number of times to repeat the animation */ -void lv_animimg_set_repeat_count(lv_obj_t * img, uint32_t count); +void lv_animimg_set_repeat_count(lv_obj_t * obj, uint32_t count); + +/** + * Make the image animation to play back to when the forward direction is ready. + * @param obj pointer to an animation image object + * @param duration the duration of the playback image animation in milliseconds. 0: disable playback + */ +void lv_animimg_set_reverse_duration(lv_obj_t * obj, uint32_t duration); + +/** + * Make the image animation to play back to when the forward direction is ready. + * @param obj pointer to an animation image object + * @param duration delay in milliseconds before starting the playback image animation. + */ +void lv_animimg_set_reverse_delay(lv_obj_t * obj, uint32_t duration); + +/** + * Set a function call when the animation image really starts (considering `delay`) + * @param obj pointer to an animation image object + * @param start_cb a function call when the animation is start + */ +void lv_animimg_set_start_cb(lv_obj_t * obj, lv_anim_start_cb_t start_cb); + +/** + * Set a function call when the animation is completed + * @param obj pointer to an animation image object + * @param completed_cb a function call when the animation is completed + */ +void lv_animimg_set_completed_cb(lv_obj_t * obj, lv_anim_completed_cb_t completed_cb); /*===================== * Getter functions @@ -87,38 +143,38 @@ void lv_animimg_set_repeat_count(lv_obj_t * img, uint32_t count); /** * Get the image animation images source. - * @param img pointer to an animation image object - * @return a pointer that will point to a series images + * @param obj pointer to an animation image object + * @return a pointer that will point to a series images */ -const void ** lv_animimg_get_src(lv_obj_t * img); +const void ** lv_animimg_get_src(lv_obj_t * obj); /** * Get the image animation images source. - * @param img pointer to an animation image object + * @param obj pointer to an animation image object * @return the number of source images */ -uint8_t lv_animimg_get_src_count(lv_obj_t * img); +uint8_t lv_animimg_get_src_count(lv_obj_t * obj); /** * Get the image animation duration time. unit:ms - * @param img pointer to an animation image object + * @param obj pointer to an animation image object * @return the animation duration time */ -uint32_t lv_animimg_get_duration(lv_obj_t * img); +uint32_t lv_animimg_get_duration(lv_obj_t * obj); /** * Get the image animation repeat play times. - * @param img pointer to an animation image object + * @param obj pointer to an animation image object * @return the repeat count */ -uint32_t lv_animimg_get_repeat_count(lv_obj_t * img); +uint32_t lv_animimg_get_repeat_count(lv_obj_t * obj); /** * Get the image animation underlying animation. - * @param img pointer to an animation image object + * @param obj pointer to an animation image object * @return the animation reference */ -lv_anim_t * lv_animimg_get_anim(lv_obj_t * img); +lv_anim_t * lv_animimg_get_anim(lv_obj_t * obj); #endif /*LV_USE_ANIMIMG*/ 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 index c4cf663d5..a5ef5ebba 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/animimage/lv_animimage_private.h @@ -29,7 +29,7 @@ extern "C" { **********************/ /** Data of the animimage */ -struct lv_animimg_t { +struct _lv_animimg_t { lv_image_t img; lv_anim_t anim; /* picture sequence */ 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 6aa14840d..6d5f230d9 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc.c @@ -60,7 +60,7 @@ const lv_obj_class_t lv_arc_class = { .instance_size = sizeof(lv_arc_t), .editable = LV_OBJ_CLASS_EDITABLE_TRUE, .base_class = &lv_obj_class, - .name = "arc", + .name = "lv_arc", }; /********************** @@ -509,12 +509,14 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e) angle -= arc->rotation; angle -= arc->bg_angle_start; /*Make the angle relative to the start angle*/ + /* ensure the angle is in the range [0, 360) */ while(angle < 0) angle += 360; while(angle >= 360) angle -= 360; + const uint32_t circumference = (uint32_t)((2U * r * 314U) / 100U); /* Equivalent to: 2r * 3.14, avoiding floats */ - const lv_value_precise_t tolerance_deg = (360 * lv_dpx(50U)) / circumference; + const lv_value_precise_t tolerance_deg = (360 * lv_dpx(20U)) / circumference; const uint32_t min_close_prev = (uint32_t) arc->min_close; const bool is_angle_within_bg_bounds = lv_arc_angle_within_bg_bounds(obj, angle, tolerance_deg); @@ -669,7 +671,7 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e) while(angle >= 360) angle -= 360; const uint32_t circumference = (uint32_t)((2U * r * 314U) / 100U); /* Equivalent to: 2r * 3.14, avoiding floats */ - const lv_value_precise_t tolerance_deg = (360 * lv_dpx(50U)) / circumference; + const lv_value_precise_t tolerance_deg = (360 * lv_dpx(20U)) / circumference; /* Check if the angle is outside the drawn background arc */ const bool is_angle_within_bg_bounds = lv_arc_angle_within_bg_bounds(obj, angle, tolerance_deg); @@ -721,6 +723,7 @@ static void lv_arc_draw(lv_event_t * e) lv_draw_arc_dsc_t arc_dsc; if(arc_r > 0) { lv_draw_arc_dsc_init(&arc_dsc); + arc_dsc.base.layer = layer; lv_obj_init_draw_arc_dsc(obj, LV_PART_MAIN, &arc_dsc); arc_dsc.center = center; arc_dsc.start_angle = arc->bg_angle_start + arc->rotation; @@ -738,6 +741,7 @@ static void lv_arc_draw(lv_event_t * e) if(indic_r > 0) { lv_draw_arc_dsc_init(&arc_dsc); + arc_dsc.base.layer = layer; lv_obj_init_draw_arc_dsc(obj, LV_PART_INDICATOR, &arc_dsc); arc_dsc.center = center; arc_dsc.start_angle = arc->indic_angle_start + arc->rotation; @@ -753,6 +757,7 @@ static void lv_arc_draw(lv_event_t * e) lv_draw_rect_dsc_t knob_rect_dsc; lv_draw_rect_dsc_init(&knob_rect_dsc); + knob_rect_dsc.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_KNOB, &knob_rect_dsc); lv_draw_rect(layer, &knob_rect_dsc, &knob_area); } @@ -964,11 +969,15 @@ static bool lv_arc_angle_within_bg_bounds(lv_obj_t * obj, const lv_value_precise lv_arc_t * arc = (lv_arc_t *)obj; lv_value_precise_t bounds_angle = arc->bg_angle_end - arc->bg_angle_start; + if(arc->bg_angle_end == arc->bg_angle_start) return false; /*The arc has 0 deg span*/ /* ensure the angle is in the range [0, 360) */ while(bounds_angle < 0) bounds_angle += 360; while(bounds_angle >= 360) bounds_angle -= 360; + /*Full circle*/ + if(bounds_angle == 0) bounds_angle = 360; + /* Angle is in the bounds */ if(angle <= bounds_angle) { if(angle < (bounds_angle / 2)) { 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 index 03513ea60..71f576a46 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/arc/lv_arc_private.h @@ -26,7 +26,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_arc_t { +struct _lv_arc_t { lv_obj_t obj; int32_t rotation; lv_value_precise_t indic_angle_start; 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 6fc7b231a..b526bd37c 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar.c @@ -69,7 +69,7 @@ const lv_obj_class_t lv_bar_class = { .height_def = LV_DPI_DEF / 10, .instance_size = sizeof(lv_bar_t), .base_class = &lv_obj_class, - .name = "bar", + .name = "lv_bar", }; /********************** @@ -398,6 +398,12 @@ static void draw_indic(lv_event_t * e) bool hor_need_reversed = hor && base_dir == LV_BASE_DIR_RTL; bool reversed = bar->val_reversed ^ hor_need_reversed; + /* An area with width 0 is {x1 = 0 x2 = -1} so subtracting 1 from `anim_cur_value_x` causes... + * anim_start_value_x = 0 anim_cur_value_x = 0 to be {x1 = 0 x2 = -1 } which is width 0 + * anim_start_value_x = 0 anim_cur_value_x = 300 to be {x1 = 0 x2 = 299} which is width 300 + */ + anim_cur_value_x -= 1; + if(reversed) { /*Swap axes*/ int32_t * tmp; @@ -414,7 +420,7 @@ static void draw_indic(lv_event_t * e) *axis1 += anim_start_value_x; } else { - *axis1 = *axis2 - anim_cur_value_x + 1; + *axis1 = *axis2 - anim_cur_value_x; *axis2 -= anim_start_value_x; } @@ -469,6 +475,7 @@ static void draw_indic(lv_event_t * e) lv_draw_rect_dsc_t draw_rect_dsc; lv_draw_rect_dsc_init(&draw_rect_dsc); + draw_rect_dsc.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_INDICATOR, &draw_rect_dsc); int32_t bg_radius = lv_obj_get_style_radius(obj, LV_PART_MAIN); 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 93c88786f..422ba014b 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar.h @@ -85,7 +85,7 @@ void lv_bar_set_range(lv_obj_t * obj, int32_t min, int32_t max); /** * Set the type of bar. * @param obj pointer to bar object - * @param mode bar type from ::lv_bar_mode_t + * @param mode bar type from `lv_bar_mode_t` */ void lv_bar_set_mode(lv_obj_t * obj, lv_bar_mode_t mode); @@ -131,14 +131,14 @@ int32_t lv_bar_get_max_value(const lv_obj_t * obj); /** * Get the type of bar. * @param obj pointer to bar object - * @return bar type from ::lv_bar_mode_t + * @return bar type from `lv_bar_mode_t` */ 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 + * @return bar orientation from `lv_bar_orientation_t` */ lv_bar_orientation_t lv_bar_get_orientation(lv_obj_t * obj); 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 index 1a8dd4bb1..c403805f7 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/bar/lv_bar_private.h @@ -27,14 +27,14 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_bar_anim_t { +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 { +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*/ 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 096dc2954..361e87734 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button.c @@ -35,7 +35,7 @@ const lv_obj_class_t lv_button_class = { .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, .instance_size = sizeof(lv_button_t), .base_class = &lv_obj_class, - .name = "btn", + .name = "lv_button", }; /********************** 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 index ce310f32c..c89c93aad 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/button/lv_button_private.h @@ -31,7 +31,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_button_t { +struct _lv_button_t { lv_obj_t obj; }; 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 e20ac2ebe..5b3f93f8b 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.c @@ -55,6 +55,9 @@ static void allocate_button_areas_and_controls(const lv_obj_t * obj, const char static void invalidate_button_area(const lv_obj_t * obj, uint32_t btn_idx); static void make_one_button_checked(lv_obj_t * obj, uint32_t btn_idx); static bool has_popovers_in_top_row(lv_obj_t * obj); +static bool button_is_recolor(lv_buttonmatrix_ctrl_t ctrl_bits); +static void update_map(lv_obj_t * obj); +static void free_map(lv_buttonmatrix_t * btnm); /********************** * STATIC VARIABLES @@ -73,7 +76,7 @@ const lv_obj_class_t lv_buttonmatrix_class = { .editable = LV_OBJ_CLASS_EDITABLE_TRUE, .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, .base_class = &lv_obj_class, - .name = "btnmatrix", + .name = "lv_buttonmatrix", }; /********************** @@ -102,89 +105,14 @@ void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * const map[]) if(map == NULL) return; lv_buttonmatrix_t * btnm = (lv_buttonmatrix_t *)obj; + if(btnm->auto_free_map) free_map(btnm); + btnm->auto_free_map = 0; /*Analyze the map and create the required number of buttons*/ allocate_button_areas_and_controls(obj, map); btnm->map_p = map; - lv_base_dir_t base_dir = lv_obj_get_style_base_dir(obj, LV_PART_MAIN); - - /*Set size and positions of the buttons*/ - int32_t sleft = lv_obj_get_style_space_left(obj, LV_PART_MAIN); - int32_t stop = lv_obj_get_style_space_top(obj, LV_PART_MAIN); - int32_t prow = lv_obj_get_style_pad_row(obj, LV_PART_MAIN); - int32_t pcol = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); - - int32_t max_w = lv_obj_get_content_width(obj); - int32_t max_h = lv_obj_get_content_height(obj); - - /*Calculate the position of each row*/ - int32_t max_h_no_gap = max_h - (prow * (btnm->row_cnt - 1)); - - /*Count the units and the buttons in a line - *(A button can be 1,2,3... unit wide)*/ - uint32_t txt_tot_i = 0; /*Act. index in the str map*/ - uint32_t btn_tot_i = 0; /*Act. index of button areas*/ - const char * const * map_row = map; - - /*Count the units and the buttons in a line*/ - uint32_t row; - for(row = 0; row < btnm->row_cnt; row++) { - 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] && 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++; - } - - /*Only deal with the non empty lines*/ - if(btn_cnt == 0) { - map_row = &map_row[btn_cnt + 1]; /*Set the map to the next row*/ - continue; - } - - int32_t row_y1 = stop + (max_h_no_gap * row) / btnm->row_cnt + row * prow; - int32_t row_y2 = stop + (max_h_no_gap * (row + 1)) / btnm->row_cnt + row * prow - 1; - - /*Set the button size and positions*/ - int32_t max_w_no_gap = max_w - (pcol * (btn_cnt - 1)); - if(max_w_no_gap < 0) max_w_no_gap = 0; - - uint32_t row_unit_cnt = 0; /*The current unit position in the row*/ - uint32_t btn; - for(btn = 0; btn < btn_cnt; btn++, btn_tot_i++, txt_tot_i++) { - uint32_t btn_u = get_button_width(btnm->ctrl_bits[btn_tot_i]); - - int32_t btn_x1 = (max_w_no_gap * row_unit_cnt) / unit_cnt + btn * pcol; - int32_t btn_x2 = (max_w_no_gap * (row_unit_cnt + btn_u)) / unit_cnt + btn * pcol - 1; - - /*If RTL start from the right*/ - if(base_dir == LV_BASE_DIR_RTL) { - int32_t tmp = btn_x1; - btn_x1 = btn_x2; - btn_x2 = tmp; - - btn_x1 = max_w - btn_x1; - btn_x2 = max_w - btn_x2; - } - - btn_x1 += sleft; - btn_x2 += sleft; - - lv_area_set(&btnm->button_areas[btn_tot_i], btn_x1, row_y1, btn_x2, row_y2); - - row_unit_cnt += btn_u; - } - - map_row = &map_row[btn_cnt + 1]; /*Set the map to the next line*/ - } - - /*Popovers in the top row will draw outside the widget and the extended draw size depends on - *the row height which may have changed when setting the new map*/ - lv_obj_refresh_ext_draw_size(obj); - - lv_obj_invalidate(obj); + update_map(obj); } void lv_buttonmatrix_set_ctrl_map(lv_obj_t * obj, const lv_buttonmatrix_ctrl_t ctrl_map[]) @@ -194,7 +122,7 @@ void lv_buttonmatrix_set_ctrl_map(lv_obj_t * obj, const lv_buttonmatrix_ctrl_t c lv_buttonmatrix_t * btnm = (lv_buttonmatrix_t *)obj; lv_memcpy(btnm->ctrl_bits, ctrl_map, sizeof(lv_buttonmatrix_ctrl_t) * btnm->btn_cnt); - lv_buttonmatrix_set_map(obj, btnm->map_p); + update_map(obj); } void lv_buttonmatrix_set_selected_button(lv_obj_t * obj, uint32_t btn_id) @@ -277,7 +205,7 @@ void lv_buttonmatrix_set_button_width(lv_obj_t * obj, uint32_t btn_id, uint32_t btnm->ctrl_bits[btn_id] &= (~LV_BUTTONMATRIX_WIDTH_MASK); btnm->ctrl_bits[btn_id] |= (LV_BUTTONMATRIX_WIDTH_MASK & width); - lv_buttonmatrix_set_map(obj, btnm->map_p); + update_map(obj); } void lv_buttonmatrix_set_one_checked(lv_obj_t * obj, bool en) @@ -318,7 +246,7 @@ const char * lv_buttonmatrix_get_button_text(const lv_obj_t * obj, uint32_t btn_ if(btn_id == LV_BUTTONMATRIX_BUTTON_NONE) return NULL; lv_buttonmatrix_t * btnm = (lv_buttonmatrix_t *)obj; - if(btn_id > btnm->btn_cnt) return NULL; + if(btn_id >= btnm->btn_cnt) return NULL; uint32_t txt_i = 0; uint32_t btn_i = 0; @@ -371,6 +299,7 @@ static void lv_buttonmatrix_constructor(const lv_obj_class_t * class_p, lv_obj_t btnm->ctrl_bits = NULL; btnm->map_p = NULL; btnm->one_check = 0; + btnm->auto_free_map = 0; #if LV_WIDGETS_HAS_DEFAULT_VALUE lv_buttonmatrix_set_map(obj, lv_buttonmatrix_def_map); @@ -414,10 +343,10 @@ static void lv_buttonmatrix_event(const lv_obj_class_t * class_p, lv_event_t * e } } if(code == LV_EVENT_STYLE_CHANGED) { - lv_buttonmatrix_set_map(obj, btnm->map_p); + update_map(obj); } else if(code == LV_EVENT_SIZE_CHANGED) { - lv_buttonmatrix_set_map(obj, btnm->map_p); + update_map(obj); } else if(code == LV_EVENT_PRESSED) { lv_indev_t * indev = lv_event_get_indev(e); @@ -455,14 +384,17 @@ static void lv_buttonmatrix_event(const lv_obj_class_t * class_p, lv_event_t * e } } else if(code == LV_EVENT_PRESSING) { - /*If a slid to a new button, discard the current button and don't press any buttons*/ if(btnm->btn_id_sel != LV_BUTTONMATRIX_BUTTON_NONE) { lv_indev_t * indev = lv_event_get_indev(e); - lv_indev_get_point(indev, &p); - uint32_t btn_pr = get_button_from_point(obj, &p); - if(btn_pr != btnm->btn_id_sel) { - invalidate_button_area(obj, btnm->btn_id_sel); /*Invalidate the old area*/ - btnm->btn_id_sel = LV_BUTTONMATRIX_BUTTON_NONE; + lv_indev_type_t indev_type = lv_indev_get_type(indev); + if(indev_type == LV_INDEV_TYPE_POINTER || indev_type == LV_INDEV_TYPE_BUTTON) { + /*If pointer device slid to a new button, discard the current button and don't press any buttons*/ + lv_indev_get_point(indev, &p); + uint32_t btn_pr = get_button_from_point(obj, &p); + if(btn_pr != btnm->btn_id_sel) { + invalidate_button_area(obj, btnm->btn_id_sel); /*Invalidate the old area*/ + btnm->btn_id_sel = LV_BUTTONMATRIX_BUTTON_NONE; + } } } } @@ -659,6 +591,9 @@ static void lv_buttonmatrix_event(const lv_obj_class_t * class_p, lv_event_t * e else if(code == LV_EVENT_DRAW_MAIN) { draw_main(e); } + else if(code == LV_EVENT_DELETE) { + if(btnm->auto_free_map) free_map(btnm); + } } @@ -689,7 +624,9 @@ static void draw_main(lv_event_t * e) obj->state = LV_STATE_DEFAULT; obj->skip_trans = 1; lv_draw_rect_dsc_init(&draw_rect_dsc_def); + draw_rect_dsc_def.base.layer = layer; lv_draw_label_dsc_init(&draw_label_dsc_def); + draw_label_dsc_def.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_ITEMS, &draw_rect_dsc_def); lv_obj_init_draw_label_dsc(obj, LV_PART_ITEMS, &draw_label_dsc_def); obj->skip_trans = 0; @@ -742,13 +679,19 @@ static void draw_main(lv_event_t * e) obj->state = btn_state; obj->skip_trans = 1; lv_draw_rect_dsc_init(&draw_rect_dsc_act); + draw_rect_dsc_act.base.layer = layer; lv_draw_label_dsc_init(&draw_label_dsc_act); + draw_label_dsc_act.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_ITEMS, &draw_rect_dsc_act); lv_obj_init_draw_label_dsc(obj, LV_PART_ITEMS, &draw_label_dsc_act); obj->state = state_ori; obj->skip_trans = 0; } + bool recolor = button_is_recolor(btnm->ctrl_bits[btn_i]); + if(recolor) draw_label_dsc_act.flag |= LV_TEXT_FLAG_RECOLOR; + else draw_label_dsc_act.flag &= ~LV_TEXT_FLAG_RECOLOR; + draw_rect_dsc_act.base.id1 = btn_i; /*Remove borders on the edges if `LV_BORDER_SIDE_INTERNAL`*/ @@ -1042,4 +985,104 @@ static bool has_popovers_in_top_row(lv_obj_t * obj) return false; } +static bool button_is_recolor(lv_buttonmatrix_ctrl_t ctrl_bits) +{ + return (ctrl_bits & LV_BUTTONMATRIX_CTRL_RECOLOR) ? true : false; +} + +static void update_map(lv_obj_t * obj) +{ + lv_buttonmatrix_t * btnm = (lv_buttonmatrix_t *)obj; + + lv_base_dir_t base_dir = lv_obj_get_style_base_dir(obj, LV_PART_MAIN); + + /*Set size and positions of the buttons*/ + int32_t sleft = lv_obj_get_style_space_left(obj, LV_PART_MAIN); + int32_t stop = lv_obj_get_style_space_top(obj, LV_PART_MAIN); + int32_t prow = lv_obj_get_style_pad_row(obj, LV_PART_MAIN); + int32_t pcol = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); + + int32_t max_w = lv_obj_get_content_width(obj); + int32_t max_h = lv_obj_get_content_height(obj); + + /*Calculate the position of each row*/ + int32_t max_h_no_gap = max_h - (prow * (btnm->row_cnt - 1)); + + /*Count the units and the buttons in a line + *(A button can be 1,2,3... unit wide)*/ + uint32_t txt_tot_i = 0; /*Act. index in the str map*/ + uint32_t btn_tot_i = 0; /*Act. index of button areas*/ + const char * const * map_row = btnm->map_p; + + /*Count the units and the buttons in a line*/ + uint32_t row; + for(row = 0; row < btnm->row_cnt; row++) { + 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] && 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++; + } + + /*Only deal with the non empty lines*/ + if(btn_cnt == 0) { + map_row = &map_row[btn_cnt + 1]; /*Set the map to the next row*/ + continue; + } + + int32_t row_y1 = stop + (max_h_no_gap * row) / btnm->row_cnt + row * prow; + int32_t row_y2 = stop + (max_h_no_gap * (row + 1)) / btnm->row_cnt + row * prow - 1; + + /*Set the button size and positions*/ + int32_t max_w_no_gap = max_w - (pcol * (btn_cnt - 1)); + if(max_w_no_gap < 0) max_w_no_gap = 0; + + uint32_t row_unit_cnt = 0; /*The current unit position in the row*/ + uint32_t btn; + for(btn = 0; btn < btn_cnt; btn++, btn_tot_i++, txt_tot_i++) { + uint32_t btn_u = get_button_width(btnm->ctrl_bits[btn_tot_i]); + + int32_t btn_x1 = (max_w_no_gap * row_unit_cnt) / unit_cnt + btn * pcol; + int32_t btn_x2 = (max_w_no_gap * (row_unit_cnt + btn_u)) / unit_cnt + btn * pcol - 1; + + /*If RTL start from the right*/ + if(base_dir == LV_BASE_DIR_RTL) { + int32_t tmp = btn_x1; + btn_x1 = btn_x2; + btn_x2 = tmp; + + btn_x1 = max_w - btn_x1; + btn_x2 = max_w - btn_x2; + } + + btn_x1 += sleft; + btn_x2 += sleft; + + lv_area_set(&btnm->button_areas[btn_tot_i], btn_x1, row_y1, btn_x2, row_y2); + + row_unit_cnt += btn_u; + } + + map_row = &map_row[btn_cnt + 1]; /*Set the map to the next line*/ + } + + /*Popovers in the top row will draw outside the widget and the extended draw size depends on + *the row height which may have changed when setting the new map*/ + lv_obj_refresh_ext_draw_size(obj); + + lv_obj_invalidate(obj); + +} + +static void free_map(lv_buttonmatrix_t * btnm) +{ + uint32_t i; + for(i = 0; btnm->map_p[i]; i++) { + lv_free((void *)btnm->map_p[i]); + } + lv_free((void *)btnm->map_p); + btnm->map_p = NULL; +} + #endif 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 c2726627c..fc2550e1f 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.h @@ -29,21 +29,37 @@ LV_EXPORT_CONST_INT(LV_BUTTONMATRIX_BUTTON_NONE); * TYPEDEFS **********************/ -/** Type to store button control bits (disabled, hidden etc.) - * The first 3 bits are used to store the width*/ +/** Type to store button control flags (disabled, hidden etc.) + * The least-significant 4 bits are used to store button-width proportions in range [1..15]. */ 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.*/ - LV_BUTTONMATRIX_CTRL_CHECKABLE = 0x0080, /**< The button can be toggled.*/ - 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_CUSTOM_1 = 0x4000, /**< Custom free to use flag*/ - LV_BUTTONMATRIX_CTRL_CUSTOM_2 = 0x8000, /**< Custom free to use flag*/ + LV_BUTTONMATRIX_CTRL_NONE = 0x0000, /**< No extra control, use the default settings*/ + LV_BUTTONMATRIX_CTRL_WIDTH_1 = 0x0001, /**< Set the width to 1 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_2 = 0x0002, /**< Set the width to 2 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_3 = 0x0003, /**< Set the width to 3 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_4 = 0x0004, /**< Set the width to 4 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_5 = 0x0005, /**< Set the width to 5 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_6 = 0x0006, /**< Set the width to 6 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_7 = 0x0007, /**< Set the width to 7 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_8 = 0x0008, /**< Set the width to 8 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_9 = 0x0009, /**< Set the width to 9 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_10 = 0x000A, /**< Set the width to 10 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_11 = 0x000B, /**< Set the width to 11 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_12 = 0x000C, /**< Set the width to 12 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_13 = 0x000D, /**< Set the width to 13 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_14 = 0x000E, /**< Set the width to 14 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_WIDTH_15 = 0x000F, /**< Set the width to 15 relative to the other buttons in the same row */ + LV_BUTTONMATRIX_CTRL_HIDDEN = 0x0010, /**< Hides button; it continues to hold its space in layout. */ + LV_BUTTONMATRIX_CTRL_NO_REPEAT = 0x0020, /**< Do not emit LV_EVENT_LONG_PRESSED_REPEAT events while button is long-pressed. */ + LV_BUTTONMATRIX_CTRL_DISABLED = 0x0040, /**< Disables button like LV_STATE_DISABLED on normal Widgets. */ + LV_BUTTONMATRIX_CTRL_CHECKABLE = 0x0080, /**< Enable toggling of LV_STATE_CHECKED when clicked. */ + LV_BUTTONMATRIX_CTRL_CHECKED = 0x0100, /**< Make the button checked. It will use the :cpp:enumerator:`LV_STATE_CHECHKED` styles. */ + LV_BUTTONMATRIX_CTRL_CLICK_TRIG = 0x0200, /**< 1: Enables sending LV_EVENT_VALUE_CHANGE on CLICK, 0: sends LV_EVENT_VALUE_CHANGE on PRESS. */ + LV_BUTTONMATRIX_CTRL_POPOVER = 0x0400, /**< Show button text in a pop-over while being pressed. */ + LV_BUTTONMATRIX_CTRL_RECOLOR = 0x0800, /**< Enable text recoloring with `#color` */ + LV_BUTTONMATRIX_CTRL_RESERVED_1 = 0x1000, /**< Reserved for later use */ + LV_BUTTONMATRIX_CTRL_RESERVED_2 = 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 */ } 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, 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 index cab042db9..3f6b0fa53 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/buttonmatrix/lv_buttonmatrix_private.h @@ -28,7 +28,7 @@ extern "C" { **********************/ /** Data of button matrix */ -struct lv_buttonmatrix_t { +struct _lv_buttonmatrix_t { lv_obj_t obj; const char * const * map_p; /**< Pointer to the current map */ lv_area_t * button_areas; /**< Array of areas of buttons */ @@ -36,7 +36,8 @@ struct lv_buttonmatrix_t { 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 */ + uint32_t one_check : 1; /**< 1: Single button toggled at once */ + uint32_t auto_free_map : 1; /**< 1: Automatically free the map when the widget is deleted */ }; 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 560e24a1d..bcdd23e22 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar.c @@ -55,7 +55,7 @@ const lv_obj_class_t lv_calendar_class = { .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, .instance_size = sizeof(lv_calendar_t), .base_class = &lv_obj_class, - .name = "calendar", + .name = "lv_calendar", }; static const char * day_names_def[7] = LV_CALENDAR_DEFAULT_DAY_NAMES; @@ -117,7 +117,7 @@ void lv_calendar_set_highlighted_dates(lv_obj_t * obj, lv_calendar_date_t highli highlight_update(obj); } -void lv_calendar_set_showed_date(lv_obj_t * obj, uint32_t year, uint32_t month) +void lv_calendar_set_month_shown(lv_obj_t * obj, uint32_t year, uint32_t month) { LV_ASSERT_OBJ(obj, MY_CLASS); lv_calendar_t * calendar = (lv_calendar_t *)obj; @@ -332,7 +332,7 @@ static void lv_calendar_constructor(const lv_obj_class_t * class_p, lv_obj_t * o 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_month_shown(obj, calendar->showed_date.year, calendar->showed_date.month); lv_calendar_set_today_date(obj, calendar->today.year, calendar->today.month, calendar->today.day); } 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 38c5d644f..c7159a360 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar.h @@ -70,7 +70,7 @@ void lv_calendar_set_today_date(lv_obj_t * obj, uint32_t year, uint32_t month, u * @param year today's year * @param month today's month [1..12] */ -void lv_calendar_set_showed_date(lv_obj_t * obj, uint32_t year, uint32_t month); +void lv_calendar_set_month_shown(lv_obj_t * obj, uint32_t year, uint32_t month); /** * Set the highlighted dates 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 index ee24133ad..76995fdfc 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese.c @@ -116,7 +116,7 @@ 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); + lv_calendar_set_month_shown(obj, calendar->today.year, calendar->today.month); } const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian) 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 deleted file mode 100644 index 5572259e2..000000000 --- a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_chinese_private.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @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 09b201d04..144f11c7b 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 @@ -40,7 +40,7 @@ const lv_obj_class_t lv_calendar_header_arrow_class = { .constructor_cb = my_constructor, .width_def = LV_PCT(100), .height_def = LV_DPI_DEF / 3, - .name = "calendar-header-arrow", + .name = "lv_calendar_header_arrow", }; static const char * month_names_def[12] = LV_CALENDAR_DEFAULT_MONTH_NAMES; @@ -53,7 +53,7 @@ static const char * month_names_def[12] = LV_CALENDAR_DEFAULT_MONTH_NAMES; * GLOBAL FUNCTIONS **********************/ -lv_obj_t * lv_calendar_header_arrow_create(lv_obj_t * parent) +lv_obj_t * lv_calendar_add_header_arrow(lv_obj_t * parent) { lv_obj_t * obj = lv_obj_class_create_obj(&lv_calendar_header_arrow_class, parent); lv_obj_class_init_obj(obj); @@ -86,7 +86,7 @@ static void my_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_obj_remove_flag(mo_prev, LV_OBJ_FLAG_CLICK_FOCUSABLE); lv_obj_t * label = lv_label_create(obj); - lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR); + lv_label_set_long_mode(label, LV_LABEL_LONG_MODE_SCROLL_CIRCULAR); lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); lv_obj_set_flex_grow(label, 1); @@ -113,8 +113,8 @@ static void month_event_cb(lv_event_t * e) d = lv_calendar_get_showed_date(calendar); lv_calendar_date_t newd = *d; - LV_ASSERT_FORMAT_MSG(newd.year >= 0 && newd.month >= 1 && newd.month <= 12, - "Invalid date: %d-%d", newd.year, newd.month); + LV_ASSERT_FORMAT_MSG(newd.month >= 1 && newd.month <= 12, + "Invalid month: %d (expected 1-12)", newd.month); /*The last child is the right button*/ if(lv_obj_get_child(header, 0) == btn) { @@ -136,7 +136,7 @@ static void month_event_cb(lv_event_t * e) } } - lv_calendar_set_showed_date(calendar, newd.year, newd.month); + lv_calendar_set_month_shown(calendar, newd.year, newd.month); lv_obj_t * label = lv_obj_get_child(header, 1); lv_label_set_text_fmt(label, "%d %s", newd.year, month_names_def[newd.month - 1]); @@ -148,8 +148,8 @@ static void value_changed_event_cb(lv_event_t * e) lv_obj_t * calendar = lv_obj_get_parent(header); const lv_calendar_date_t * date = lv_calendar_get_showed_date(calendar); - LV_ASSERT_FORMAT_MSG(date->year >= 0 && date->month >= 1 && date->month <= 12, - "Invalid date: %d-%d", date->year, date->month); + LV_ASSERT_FORMAT_MSG(date->month >= 1 && date->month <= 12, + "Invalid month: %d (expected 1-12)", date->month); lv_obj_t * label = lv_obj_get_child(header, 1); lv_label_set_text_fmt(label, "%d %s", date->year, month_names_def[date->month - 1]); diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_arrow.h b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_arrow.h index a04b355cc..54f4fbed7 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_arrow.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_arrow.h @@ -34,7 +34,7 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_calendar_header_arrow_cl * @param parent pointer to a calendar object. * @return the created header */ -lv_obj_t * lv_calendar_header_arrow_create(lv_obj_t * parent); +lv_obj_t * lv_calendar_add_header_arrow(lv_obj_t * parent); /********************** * MACROS 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 41fe53a82..766f0d945 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 @@ -39,7 +39,7 @@ const lv_obj_class_t lv_calendar_header_dropdown_class = { .width_def = LV_PCT(100), .height_def = LV_SIZE_CONTENT, .constructor_cb = my_constructor, - .name = "calendar-header-dropdown", + .name = "lv_calendar_header_dropdown", }; static const char * month_list = "01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n12"; @@ -61,7 +61,7 @@ static const char * year_list = { * GLOBAL FUNCTIONS **********************/ -lv_obj_t * lv_calendar_header_dropdown_create(lv_obj_t * parent) +lv_obj_t * lv_calendar_add_header_dropdown(lv_obj_t * parent) { lv_obj_t * obj = lv_obj_class_create_obj(&lv_calendar_header_dropdown_class, parent); lv_obj_class_init_obj(obj); @@ -135,7 +135,7 @@ static void month_event_cb(lv_event_t * e) lv_calendar_date_t newd = *d; newd.month = sel + 1; - lv_calendar_set_showed_date(calendar, newd.year, newd.month); + lv_calendar_set_month_shown(calendar, newd.year, newd.month); } static void year_event_cb(lv_event_t * e) @@ -145,19 +145,22 @@ static void year_event_cb(lv_event_t * e) uint32_t sel = lv_dropdown_get_selected(dropdown); + const char * year_p = lv_dropdown_get_options(dropdown); + + LV_ASSERT(3 + sel * 5 < lv_strlen(year_p)); + + /* NOTE: Assumes YYYY format */ + const uint32_t year = (year_p[0 + sel * 5] - '0') * 1000 + + (year_p[1 + sel * 5] - '0') * 100 + + (year_p[2 + sel * 5] - '0') * 10 + + (year_p[3 + sel * 5] - '0'); + const lv_calendar_date_t * d; d = lv_calendar_get_showed_date(calendar); - - /* Get the first year on the options list - * NOTE: Assumes the first 4 digits in the option list are numbers */ - const char * year_p = lv_dropdown_get_options(dropdown); - const uint32_t year = (year_p[0] - '0') * 1000 + (year_p[1] - '0') * 100 + (year_p[2] - '0') * 10 + - (year_p[3] - '0'); - lv_calendar_date_t newd = *d; - newd.year = year - sel; + newd.year = year; - lv_calendar_set_showed_date(calendar, newd.year, newd.month); + lv_calendar_set_month_shown(calendar, newd.year, newd.month); } static void value_changed_event_cb(lv_event_t * e) @@ -165,18 +168,14 @@ static void value_changed_event_cb(lv_event_t * e) lv_obj_t * header = lv_event_get_current_target(e); lv_obj_t * calendar = lv_obj_get_parent(header); const lv_calendar_date_t * cur_date = lv_calendar_get_showed_date(calendar); - lv_obj_t * year_dd = lv_obj_get_child(header, 0); - - /* Get the first year on the options list - * NOTE: Assumes the first 4 digits in the option list are numbers */ - const char * year_p = lv_dropdown_get_options(year_dd); - const uint32_t year = (year_p[0] - '0') * 1000 + (year_p[1] - '0') * 100 + (year_p[2] - '0') * 10 + - (year_p[3] - '0'); - - lv_dropdown_set_selected(year_dd, year - cur_date->year); - lv_obj_t * month_dd = lv_obj_get_child(header, 1); + const char * year_p = lv_dropdown_get_options(year_dd); + /* NOTE: Assumes YYYY format */ + const int32_t first_year = (year_p[0] - '0') * 1000 + + (year_p[1] - '0') * 100 + + (year_p[2] - '0') * 10 + (year_p[3] - '0'); + lv_dropdown_set_selected(year_dd, LV_ABS(first_year - cur_date->year)); lv_dropdown_set_selected(month_dd, cur_date->month - 1); } diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_dropdown.h b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_dropdown.h index 1ca87762e..13b01304e 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_dropdown.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_header_dropdown.h @@ -38,7 +38,7 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_calendar_header_dropdown * @param parent pointer to a calendar object. * @return the created header */ -lv_obj_t * lv_calendar_header_dropdown_create(lv_obj_t * parent); +lv_obj_t * lv_calendar_add_header_dropdown(lv_obj_t * parent); /** * Sets a custom calendar year list 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 index d4a9b535b..0a5b8a2ef 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/calendar/lv_calendar_private.h @@ -28,7 +28,7 @@ extern "C" { **********************/ /** Data of calendar */ -struct lv_calendar_t { +struct _lv_calendar_t { lv_obj_t obj; /* New data for this type */ lv_obj_t * btnm; 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 4aa46f33b..cd0e60e41 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas.c @@ -1,4 +1,4 @@ -/** +/** * @file lv_canvas.c * */ @@ -45,7 +45,7 @@ const lv_obj_class_t lv_canvas_class = { .destructor_cb = lv_canvas_destructor, .instance_size = sizeof(lv_canvas_t), .base_class = &lv_image_class, - .name = "canvas", + .name = "lv_canvas", }; /********************** @@ -129,6 +129,7 @@ void lv_canvas_set_px(lv_obj_t * obj, int32_t x, int32_t y, lv_color_t color, lv break; case LV_COLOR_FORMAT_I8: /*Indexed8 format is a easy case, process and return.*/ + shift = 0; *data = c_int; default: return; @@ -371,21 +372,18 @@ void lv_canvas_init_layer(lv_obj_t * obj, lv_layer_t * layer) { LV_ASSERT_NULL(obj); LV_ASSERT_NULL(layer); + lv_layer_init(layer); lv_canvas_t * canvas = (lv_canvas_t *)obj; if(canvas->draw_buf == NULL) return; lv_image_header_t * header = &canvas->draw_buf->header; lv_area_t canvas_area = {0, 0, header->w - 1, header->h - 1}; - lv_memzero(layer, sizeof(*layer)); layer->draw_buf = canvas->draw_buf; 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) 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 index e43b8f3f3..55b305477 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/canvas/lv_canvas_private.h @@ -28,7 +28,7 @@ extern "C" { **********************/ /** Canvas data */ -struct lv_canvas_t { +struct _lv_canvas_t { lv_image_t img; lv_draw_buf_t * draw_buf; lv_draw_buf_t static_buf; 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 4639cd5a5..6f17bd373 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart.c @@ -57,7 +57,7 @@ const lv_obj_class_t lv_chart_class = { .height_def = LV_DPI_DEF * 2, .instance_size = sizeof(lv_chart_t), .base_class = &lv_obj_class, - .name = "chart", + .name = "lv_chart", }; /********************** @@ -94,7 +94,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) { - ser->x_points = lv_malloc(sizeof(lv_point_t) * chart->point_cnt); + ser->x_points = lv_malloc(sizeof(int32_t) * chart->point_cnt); LV_ASSERT_MALLOC(ser->x_points); if(ser->x_points == NULL) return; } @@ -129,7 +129,7 @@ void lv_chart_set_point_count(lv_obj_t * obj, uint32_t cnt) lv_chart_refresh(obj); } -void lv_chart_set_range(lv_obj_t * obj, lv_chart_axis_t axis, int32_t min, int32_t max) +void lv_chart_set_axis_range(lv_obj_t * obj, lv_chart_axis_t axis, int32_t min, int32_t max) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -227,7 +227,12 @@ void lv_chart_get_point_pos_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint3 int32_t h = lv_obj_get_content_height(obj); if(chart->type == LV_CHART_TYPE_LINE) { - p_out->x = (w * id) / (chart->point_cnt - 1); + if(chart->point_cnt > 1) { + p_out->x = (w * id) / (chart->point_cnt - 1); + } + else { + p_out->x = 0; + } } else if(chart->type == LV_CHART_TYPE_SCATTER) { p_out->x = lv_map(ser->x_points[id], chart->xmin[ser->x_axis_sec], chart->xmax[ser->x_axis_sec], 0, w); @@ -241,19 +246,33 @@ void lv_chart_get_point_pos_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint3 int32_t block_w = (w - ((chart->point_cnt - 1) * block_gap)) / chart->point_cnt; - p_out->x = (int32_t)((int32_t)(w - block_w) * id) / (chart->point_cnt - 1); + if(chart->point_cnt > 1) { + p_out->x = (int32_t)((int32_t)(w - block_w) * id) / (chart->point_cnt - 1); + } + else { + p_out->x = 0; + } + lv_chart_series_t * ser_i = NULL; uint32_t ser_idx = 0; - LV_LL_READ_BACK(&chart->series_ll, ser_i) { + LV_LL_READ(&chart->series_ll, ser_i) { if(ser_i == ser) break; ser_idx++; } p_out->x = (int32_t)((int32_t)(w + block_gap) * id) / chart->point_cnt; - p_out->x += block_w * ser_idx / ser_cnt; + if(ser_cnt > 0) { + p_out->x += block_w * ser_idx / ser_cnt; - int32_t col_w = (block_w - (ser_gap * (ser_cnt - 1))) / ser_cnt; - p_out->x += col_w / 2; + int32_t col_w = (block_w - (ser_gap * (ser_cnt - 1))) / ser_cnt; + p_out->x += col_w / 2; + } + else { + LV_LOG_WARN("bar chart series count is zero"); + } + } + else { + p_out->x = 0; } int32_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN); @@ -436,6 +455,26 @@ void lv_chart_set_cursor_pos(lv_obj_t * chart, lv_chart_cursor_t * cursor, lv_po lv_chart_refresh(chart); } +void lv_chart_set_cursor_pos_x(lv_obj_t * chart, lv_chart_cursor_t * cursor, int32_t x) +{ + LV_ASSERT_NULL(cursor); + LV_UNUSED(chart); + + cursor->pos.x = x; + cursor->pos_set = 1; + lv_chart_refresh(chart); +} + +void lv_chart_set_cursor_pos_y(lv_obj_t * chart, lv_chart_cursor_t * cursor, int32_t y) +{ + LV_ASSERT_NULL(cursor); + LV_UNUSED(chart); + + cursor->pos.y = y; + cursor->pos_set = 1; + lv_chart_refresh(chart); +} + void lv_chart_set_cursor_point(lv_obj_t * chart, lv_chart_cursor_t * cursor, lv_chart_series_t * ser, uint32_t point_id) { LV_ASSERT_NULL(cursor); @@ -460,7 +499,7 @@ lv_point_t lv_chart_get_cursor_point(lv_obj_t * chart, lv_chart_cursor_t * curso * Set/Get value(s) *====================*/ -void lv_chart_set_all_value(lv_obj_t * obj, lv_chart_series_t * ser, int32_t value) +void lv_chart_set_all_values(lv_obj_t * obj, lv_chart_series_t * ser, int32_t value) { LV_ASSERT_OBJ(obj, MY_CLASS); LV_ASSERT_NULL(ser); @@ -474,6 +513,7 @@ void lv_chart_set_all_value(lv_obj_t * obj, lv_chart_series_t * ser, int32_t val lv_chart_refresh(obj); } + void lv_chart_set_next_value(lv_obj_t * obj, lv_chart_series_t * ser, int32_t value) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -504,7 +544,25 @@ void lv_chart_set_next_value2(lv_obj_t * obj, lv_chart_series_t * ser, int32_t x invalidate_point(obj, ser->start_point); } -void lv_chart_set_value_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id, int32_t value) +void lv_chart_set_series_values(lv_obj_t * obj, lv_chart_series_t * ser, const int32_t values[], size_t values_cnt) +{ + size_t i; + for(i = 0; i < values_cnt; i++) { + lv_chart_set_next_value(obj, ser, values[i]); + } +} + +void lv_chart_set_series_values2(lv_obj_t * obj, lv_chart_series_t * ser, const int32_t x_values[], + const int32_t y_values[], size_t values_cnt) +{ + size_t i; + for(i = 0; i < values_cnt; i++) { + lv_chart_set_next_value2(obj, ser, x_values[i], y_values[i]); + } +} + + +void lv_chart_set_series_value_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id, int32_t value) { LV_ASSERT_OBJ(obj, MY_CLASS); LV_ASSERT_NULL(ser); @@ -515,8 +573,8 @@ void lv_chart_set_value_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t invalidate_point(obj, id); } -void lv_chart_set_value_by_id2(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id, int32_t x_value, - int32_t y_value) +void lv_chart_set_series_value_by_id2(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id, int32_t x_value, + int32_t y_value) { LV_ASSERT_OBJ(obj, MY_CLASS); LV_ASSERT_NULL(ser); @@ -533,7 +591,7 @@ void lv_chart_set_value_by_id2(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t invalidate_point(obj, id); } -void lv_chart_set_ext_y_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t array[]) +void lv_chart_set_series_ext_y_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t array[]) { LV_ASSERT_OBJ(obj, MY_CLASS); LV_ASSERT_NULL(ser); @@ -544,7 +602,7 @@ void lv_chart_set_ext_y_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t a lv_obj_invalidate(obj); } -void lv_chart_set_ext_x_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t array[]) +void lv_chart_set_series_ext_x_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t array[]) { LV_ASSERT_OBJ(obj, MY_CLASS); LV_ASSERT_NULL(ser); @@ -555,7 +613,7 @@ void lv_chart_set_ext_x_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t a lv_obj_invalidate(obj); } -int32_t * lv_chart_get_y_array(const lv_obj_t * obj, lv_chart_series_t * ser) +int32_t * lv_chart_get_series_y_array(const lv_obj_t * obj, lv_chart_series_t * ser) { LV_UNUSED(obj); LV_ASSERT_OBJ(obj, MY_CLASS); @@ -563,7 +621,7 @@ int32_t * lv_chart_get_y_array(const lv_obj_t * obj, lv_chart_series_t * ser) return ser->y_points; } -int32_t * lv_chart_get_x_array(const lv_obj_t * obj, lv_chart_series_t * ser) +int32_t * lv_chart_get_series_x_array(const lv_obj_t * obj, lv_chart_series_t * ser) { LV_UNUSED(obj); LV_ASSERT_OBJ(obj, MY_CLASS); @@ -726,6 +784,7 @@ static void draw_div_lines(lv_obj_t * obj, lv_layer_t * layer) lv_draw_line_dsc_t line_dsc; lv_draw_line_dsc_init(&line_dsc); + line_dsc.base.layer = layer; lv_obj_init_draw_line_dsc(obj, LV_PART_MAIN, &line_dsc); lv_opa_t border_opa = lv_obj_get_style_border_opa(obj, LV_PART_MAIN); @@ -807,29 +866,34 @@ static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer) lv_draw_line_dsc_t line_dsc; lv_draw_line_dsc_init(&line_dsc); + line_dsc.base.layer = layer; lv_obj_init_draw_line_dsc(obj, LV_PART_ITEMS, &line_dsc); lv_draw_rect_dsc_t point_dsc_default; lv_draw_rect_dsc_init(&point_dsc_default); + point_dsc_default.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_INDICATOR, &point_dsc_default); int32_t point_w = lv_obj_get_style_width(obj, LV_PART_INDICATOR) / 2; int32_t point_h = lv_obj_get_style_height(obj, LV_PART_INDICATOR) / 2; - /*Do not bother with line ending is the point will over it*/ - if(LV_MIN(point_w, point_h) > line_dsc.width / 2) line_dsc.raw_end = 1; - if(line_dsc.width == 1) line_dsc.raw_end = 1; - /*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; + uint32_t ser_cnt = lv_ll_get_len(&chart->series_ll); + if(ser_cnt == 0) { + return; + } + + line_dsc.base.id1 = ser_cnt - 1; point_dsc_default.base.id1 = line_dsc.base.id1; /*Go through all data lines*/ LV_LL_READ_BACK(&chart->series_ll, ser) { if(ser->hidden) { - line_dsc.base.id1--; - point_dsc_default.base.id1--; + if(line_dsc.base.id1 > 0) { + line_dsc.base.id1--; + point_dsc_default.base.id1--; + } continue; } line_dsc.color = ser->color; @@ -926,8 +990,10 @@ static void draw_series_line(lv_obj_t * obj, lv_layer_t * layer) } } - point_dsc_default.base.id1--; - line_dsc.base.id1--; + if(line_dsc.base.id1 > 0) { + point_dsc_default.base.id1--; + line_dsc.base.id1--; + } } layer->_clip_area = clip_area_ori; @@ -956,10 +1022,12 @@ static void draw_series_scatter(lv_obj_t * obj, lv_layer_t * layer) lv_draw_line_dsc_t line_dsc; lv_draw_line_dsc_init(&line_dsc); + line_dsc.base.layer = layer; lv_obj_init_draw_line_dsc(obj, LV_PART_ITEMS, &line_dsc); lv_draw_rect_dsc_t point_dsc_default; lv_draw_rect_dsc_init(&point_dsc_default); + point_dsc_default.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_INDICATOR, &point_dsc_default); int32_t point_w = lv_obj_get_style_width(obj, LV_PART_INDICATOR) / 2; @@ -1013,8 +1081,7 @@ static void draw_series_scatter(lv_obj_t * obj, lv_layer_t * layer) continue; } - /*Don't draw the first point. A second point is also required to draw the line*/ - if(i != 0) { + if(i != 0) { /*Don't draw line *to* the first point.*/ lv_area_t point_area; point_area.x1 = (int32_t)line_dsc.p1.x - point_w; point_area.x2 = (int32_t)line_dsc.p1.x + point_w; @@ -1022,10 +1089,10 @@ static void draw_series_scatter(lv_obj_t * obj, lv_layer_t * layer) point_area.y2 = (int32_t)line_dsc.p1.y + point_h; if(ser->y_points[p_prev] != LV_CHART_POINT_NONE && ser->y_points[p_act] != LV_CHART_POINT_NONE) { - line_dsc.base.id2 = i; + line_dsc.base.id2 = i - 1; lv_draw_line(layer, &line_dsc); if(point_w && point_h) { - point_dsc_default.base.id2 = i; + point_dsc_default.base.id2 = i - 1; lv_draw_rect(layer, &point_dsc_default, &point_area); } } @@ -1034,7 +1101,7 @@ static void draw_series_scatter(lv_obj_t * obj, lv_layer_t * layer) } /*Draw the last point*/ - if(i == chart->point_cnt) { + if(i == chart->point_cnt - 1) { if(ser->y_points[p_act] != LV_CHART_POINT_NONE) { lv_area_t point_area; @@ -1073,6 +1140,9 @@ static void draw_series_bar(lv_obj_t * obj, lv_layer_t * layer) int32_t y_tmp; lv_chart_series_t * ser; uint32_t ser_cnt = lv_ll_get_len(&chart->series_ll); + if(ser_cnt == 0) { + return; + } 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*/ @@ -1085,6 +1155,7 @@ static void draw_series_bar(lv_obj_t * obj, lv_layer_t * layer) lv_draw_rect_dsc_t col_dsc; lv_draw_rect_dsc_init(&col_dsc); + col_dsc.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_ITEMS, &col_dsc); col_dsc.bg_grad.dir = LV_GRAD_DIR_NONE; col_dsc.bg_opa = LV_OPA_COVER; @@ -1094,7 +1165,14 @@ static void draw_series_bar(lv_obj_t * obj, lv_layer_t * layer) /*Go through all points*/ for(i = 0; i < chart->point_cnt; i++) { - int32_t x_act = (int32_t)((int32_t)(w - block_w) * i) / (chart->point_cnt - 1) + obj->coords.x1 + x_ofs; + int32_t x_act; + if(chart->point_cnt <= 1) { + x_act = obj->coords.x1 + x_ofs; + } + else { + x_act = (int32_t)((int32_t)(w - block_w) * i) / (chart->point_cnt - 1) + obj->coords.x1 + x_ofs; + } + col_dsc.base.id2 = i; col_dsc.base.id1 = 0; @@ -1147,10 +1225,12 @@ static void draw_cursors(lv_obj_t * obj, lv_layer_t * layer) lv_draw_line_dsc_t line_dsc_ori; lv_draw_line_dsc_init(&line_dsc_ori); + line_dsc_ori.base.layer = layer; lv_obj_init_draw_line_dsc(obj, LV_PART_CURSOR, &line_dsc_ori); lv_draw_rect_dsc_t point_dsc_ori; lv_draw_rect_dsc_init(&point_dsc_ori); + point_dsc_ori.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_CURSOR, &point_dsc_ori); lv_draw_line_dsc_t line_dsc; @@ -1245,6 +1325,22 @@ static uint32_t get_index_from_x(lv_obj_t * obj, int32_t x) if(x > w) return chart->point_cnt - 1; if(chart->type == LV_CHART_TYPE_LINE) return (x * (chart->point_cnt - 1) + w / 2) / w; if(chart->type == LV_CHART_TYPE_BAR) return (x * chart->point_cnt) / w; + if(chart->type == LV_CHART_TYPE_SCATTER) { + /*For scatter charts, the nearest id could be different depending on the series. Just check the first series.*/ + lv_chart_series_t * ser = lv_chart_get_series_next(obj, NULL); + if(ser) { + int32_t best_dist = INT32_MAX; + uint32_t best_index = 0; + for(uint32_t i = 0; i < chart->point_cnt; i++) { + int32_t dist = LV_ABS(x - lv_map(ser->x_points[i], chart->xmin[ser->x_axis_sec], chart->xmax[ser->x_axis_sec], 0, w)); + if(dist < best_dist) { + best_dist = dist; + best_index = i; + } + } + return best_index; + } + } return 0; } 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 de2583146..3f5dc3a71 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart.h @@ -92,7 +92,7 @@ void lv_chart_set_point_count(lv_obj_t * obj, uint32_t cnt); * @param min minimum value of the y axis * @param max maximum value of the y axis */ -void lv_chart_set_range(lv_obj_t * obj, lv_chart_axis_t axis, int32_t min, int32_t max); +void lv_chart_set_axis_range(lv_obj_t * obj, lv_chart_axis_t axis, int32_t min, int32_t max); /** * Set update mode of the chart object. Affects @@ -228,6 +228,22 @@ lv_chart_cursor_t * lv_chart_add_cursor(lv_obj_t * obj, lv_color_t color, lv_di */ void lv_chart_set_cursor_pos(lv_obj_t * chart, lv_chart_cursor_t * cursor, lv_point_t * pos); +/** + * Set the X coordinate of the cursor with respect to the paddings + * @param chart pointer to a chart object + * @param cursor pointer to the cursor + * @param x the new X coordinate of cursor relative to the chart + */ +void lv_chart_set_cursor_pos_x(lv_obj_t * chart, lv_chart_cursor_t * cursor, int32_t x); + +/** + * Set the coordinate of the cursor with respect to the paddings + * @param chart pointer to a chart object + * @param cursor pointer to the cursor + * @param y the new Y coordinate of cursor relative to the chart + */ +void lv_chart_set_cursor_pos_y(lv_obj_t * chart, lv_chart_cursor_t * cursor, int32_t y); + /** * Stick the cursor to a point * @param chart pointer to a chart object @@ -256,7 +272,7 @@ lv_point_t lv_chart_get_cursor_point(lv_obj_t * chart, lv_chart_cursor_t * curso * @param ser pointer to a data series on 'chart' * @param value the new value for all points. `LV_CHART_POINT_NONE` can be used to hide the points. */ -void lv_chart_set_all_value(lv_obj_t * obj, lv_chart_series_t * ser, int32_t value); +void lv_chart_set_all_values(lv_obj_t * obj, lv_chart_series_t * ser, int32_t value); /** * Set the next point's Y value according to the update mode policy. @@ -275,6 +291,26 @@ void lv_chart_set_next_value(lv_obj_t * obj, lv_chart_series_t * ser, int32_t va */ void lv_chart_set_next_value2(lv_obj_t * obj, lv_chart_series_t * ser, int32_t x_value, int32_t y_value); +/** + * Same as `lv_chart_set_next_value` but set the values from an array + * @param obj pointer to chart object + * @param ser pointer to a data series on 'chart' + * @param values the new values to set + * @param values_cnt number of items in `values` + */ +void lv_chart_set_series_values(lv_obj_t * obj, lv_chart_series_t * ser, const int32_t values[], size_t values_cnt); + +/** + * Same as `lv_chart_set_next_value2` but set the values from an array + * @param obj pointer to chart object + * @param ser pointer to a data series on 'chart' + * @param x_values the new values to set on the X axis + * @param y_values the new values to set o nthe Y axis + * @param values_cnt number of items in `x_values` and `y_values` + */ +void lv_chart_set_series_values2(lv_obj_t * obj, lv_chart_series_t * ser, const int32_t x_values[], + const int32_t y_values[], size_t values_cnt); + /** * Set an individual point's y value of a chart's series directly based on its index * @param obj pointer to a chart object @@ -282,7 +318,7 @@ void lv_chart_set_next_value2(lv_obj_t * obj, lv_chart_series_t * ser, int32_t x * @param id the index of the x point in the array * @param value value to assign to array point */ -void lv_chart_set_value_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id, int32_t value); +void lv_chart_set_series_value_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id, int32_t value); /** * Set an individual point's x and y value of a chart's series directly based on its index @@ -293,8 +329,8 @@ void lv_chart_set_value_by_id(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t * @param x_value the new X value of the next data * @param y_value the new Y value of the next data */ -void lv_chart_set_value_by_id2(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id, int32_t x_value, - int32_t y_value); +void lv_chart_set_series_value_by_id2(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t id, int32_t x_value, + int32_t y_value); /** * Set an external array for the y data points to use for the chart @@ -303,7 +339,7 @@ void lv_chart_set_value_by_id2(lv_obj_t * obj, lv_chart_series_t * ser, uint32_t * @param ser pointer to a data series on 'chart' * @param array external array of points for chart */ -void lv_chart_set_ext_y_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t array[]); +void lv_chart_set_series_ext_y_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t array[]); /** * Set an external array for the x data points to use for the chart @@ -312,7 +348,7 @@ void lv_chart_set_ext_y_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t a * @param ser pointer to a data series on 'chart' * @param array external array of points for chart */ -void lv_chart_set_ext_x_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t array[]); +void lv_chart_set_series_ext_x_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t array[]); /** * Get the array of y values of a series @@ -320,7 +356,7 @@ void lv_chart_set_ext_x_array(lv_obj_t * obj, lv_chart_series_t * ser, int32_t a * @param ser pointer to a data series on 'chart' * @return the array of values with 'point_count' elements */ -int32_t * lv_chart_get_y_array(const lv_obj_t * obj, lv_chart_series_t * ser); +int32_t * lv_chart_get_series_y_array(const lv_obj_t * obj, lv_chart_series_t * ser); /** * Get the array of x values of a series @@ -328,7 +364,7 @@ int32_t * lv_chart_get_y_array(const lv_obj_t * obj, lv_chart_series_t * ser); * @param ser pointer to a data series on 'chart' * @return the array of values with 'point_count' elements */ -int32_t * lv_chart_get_x_array(const lv_obj_t * obj, lv_chart_series_t * ser); +int32_t * lv_chart_get_series_x_array(const lv_obj_t * obj, lv_chart_series_t * ser); /** * Get the index of the currently pressed point. It's the same for every series. 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 index 7cf9052aa..7ccda787d 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/chart/lv_chart_private.h @@ -30,7 +30,7 @@ extern "C" { /** * Descriptor a chart series */ -struct lv_chart_series_t { +struct _lv_chart_series_t { int32_t * x_points; int32_t * y_points; lv_color_t color; @@ -42,29 +42,29 @@ struct lv_chart_series_t { uint32_t y_axis_sec : 1; }; -struct lv_chart_cursor_t { +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*/ + uint32_t pos_set: 1; /**< 1: pos is set; 0: point_id is set */ }; -struct lv_chart_t { +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)*/ + lv_ll_t series_ll; /**< Linked list for series (stores lv_chart_series_t) */ + lv_ll_t cursor_ll; /**< Linked list for 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; + uint32_t hdiv_cnt; /**< Number of horizontal division lines */ + uint32_t vdiv_cnt; /**< Number of vertical division lines */ + uint32_t point_cnt; /**< Number of points in all series */ + lv_chart_type_t type : 3; /**< Chart type */ + lv_chart_update_mode_t update_mode : 2; }; 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 7a987ef3e..f394fb8a1 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox.c @@ -46,7 +46,7 @@ const lv_obj_class_t lv_checkbox_class = { .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, .instance_size = sizeof(lv_checkbox_t), .base_class = &lv_obj_class, - .name = "checkbox", + .name = "lv_checkbox", }; /********************** @@ -237,6 +237,7 @@ static void lv_checkbox_draw(lv_event_t * e) lv_draw_rect_dsc_t indic_dsc; lv_draw_rect_dsc_init(&indic_dsc); + indic_dsc.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_INDICATOR, &indic_dsc); lv_area_t marker_area; if(is_rtl) { @@ -264,6 +265,7 @@ static void lv_checkbox_draw(lv_event_t * e) lv_draw_label_dsc_t txt_dsc; lv_draw_label_dsc_init(&txt_dsc); + txt_dsc.base.layer = layer; lv_obj_init_draw_label_dsc(obj, LV_PART_MAIN, &txt_dsc); txt_dsc.text = cb->txt; 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 index c927b65f2..a7167c9de 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/checkbox/lv_checkbox_private.h @@ -31,7 +31,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_checkbox_t { +struct _lv_checkbox_t { lv_obj_t obj; char * txt; uint32_t static_txt : 1; 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 517479cdb..5de58b9d1 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown.c @@ -56,7 +56,7 @@ static lv_result_t btn_release_handler(lv_obj_t * obj); static lv_result_t list_release_handler(lv_obj_t * list_obj); static void list_press_handler(lv_obj_t * page); static uint32_t get_id_on_point(lv_obj_t * dropdown_obj, int32_t y); -static void position_to_selected(lv_obj_t * obj); +static void position_to_selected(lv_obj_t * dropdown_obj, lv_anim_enable_t anim_en); static lv_obj_t * get_label(const lv_obj_t * obj); /********************** @@ -122,7 +122,7 @@ const lv_obj_class_t lv_dropdown_class = { .editable = LV_OBJ_CLASS_EDITABLE_TRUE, .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, .base_class = &lv_obj_class, - .name = "dropdown", + .name = "lv_dropdown", #if LV_USE_OBJ_PROPERTY .prop_index_start = LV_PROPERTY_DROPDOWN_START, .prop_index_end = LV_PROPERTY_DROPDOWN_END, @@ -142,7 +142,7 @@ const lv_obj_class_t lv_dropdownlist_class = { .event_cb = lv_dropdown_list_event, .instance_size = sizeof(lv_dropdown_list_t), .base_class = &lv_obj_class, - .name = "dropdown-list", + .name = "lv_dropdown-list", }; /********************** @@ -347,7 +347,7 @@ void lv_dropdown_set_selected(lv_obj_t * obj, uint32_t sel_opt) dropdown->sel_opt_id_orig = dropdown->sel_opt_id; if(dropdown->list) { - position_to_selected(obj); + position_to_selected(obj, LV_ANIM_OFF); } lv_obj_invalidate(obj); @@ -576,7 +576,7 @@ void lv_dropdown_open(lv_obj_t * dropdown_obj) if(list_h > list_fit_h) list_h = list_fit_h; lv_obj_set_height(dropdown->list, list_h); - position_to_selected(dropdown_obj); + position_to_selected(dropdown_obj, LV_ANIM_OFF); if(dir == LV_DIR_BOTTOM) lv_obj_align_to(dropdown->list, dropdown_obj, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0); else if(dir == LV_DIR_TOP) lv_obj_align_to(dropdown->list, dropdown_obj, LV_ALIGN_OUT_TOP_LEFT, 0, 0); @@ -773,7 +773,7 @@ static void lv_dropdown_event(const lv_obj_class_t * class_p, lv_event_t * e) } else if(dropdown->sel_opt_id + 1 < dropdown->option_cnt) { dropdown->sel_opt_id++; - position_to_selected(obj); + position_to_selected(obj, LV_ANIM_ON); } } else if(c == LV_KEY_LEFT || c == LV_KEY_UP) { @@ -783,7 +783,7 @@ static void lv_dropdown_event(const lv_obj_class_t * class_p, lv_event_t * e) } else if(dropdown->sel_opt_id > 0) { dropdown->sel_opt_id--; - position_to_selected(obj); + position_to_selected(obj, LV_ANIM_ON); } } else if(c == LV_KEY_ESC) { @@ -810,7 +810,7 @@ static void lv_dropdown_event(const lv_obj_class_t * class_p, lv_event_t * e) new_id = LV_CLAMP(0, new_id, (int32_t)dropdown->option_cnt - 1); dropdown->sel_opt_id = new_id; - position_to_selected(obj); + position_to_selected(obj, LV_ANIM_ON); } } else if(code == LV_EVENT_DRAW_MAIN) { @@ -865,6 +865,7 @@ static void draw_main(lv_event_t * e) lv_draw_label_dsc_t symbol_dsc; lv_draw_label_dsc_init(&symbol_dsc); + symbol_dsc.base.layer = layer; lv_obj_init_draw_label_dsc(obj, LV_PART_INDICATOR, &symbol_dsc); /*If no text specified use the selected option*/ @@ -923,6 +924,7 @@ static void draw_main(lv_event_t * e) else { lv_draw_image_dsc_t img_dsc; lv_draw_image_dsc_init(&img_dsc); + img_dsc.base.layer = layer; lv_obj_init_draw_image_dsc(obj, LV_PART_INDICATOR, &img_dsc); lv_point_set(&img_dsc.pivot, symbol_w / 2, symbol_h / 2); img_dsc.rotation = lv_obj_get_style_transform_rotation(obj, LV_PART_INDICATOR); @@ -933,6 +935,7 @@ static void draw_main(lv_event_t * e) lv_draw_label_dsc_t label_dsc; lv_draw_label_dsc_init(&label_dsc); + label_dsc.base.layer = layer; lv_obj_init_draw_label_dsc(obj, LV_PART_MAIN, &label_dsc); lv_point_t size; @@ -1033,6 +1036,7 @@ static void draw_box(lv_obj_t * dropdown_obj, lv_layer_t * layer, uint32_t id, l lv_draw_rect_dsc_t sel_rect; lv_draw_rect_dsc_init(&sel_rect); + sel_rect.base.layer = layer; lv_obj_init_draw_rect_dsc(list_obj, LV_PART_SELECTED, &sel_rect); lv_draw_rect(layer, &sel_rect, &rect_area); @@ -1055,6 +1059,7 @@ static void draw_box_label(lv_obj_t * dropdown_obj, lv_layer_t * layer, uint32_t lv_draw_label_dsc_t label_dsc; lv_draw_label_dsc_init(&label_dsc); + label_dsc.base.layer = layer; lv_obj_init_draw_label_dsc(list_obj, LV_PART_SELECTED, &label_dsc); label_dsc.line_space = lv_obj_get_style_text_line_space(list_obj, @@ -1198,7 +1203,7 @@ static uint32_t get_id_on_point(lv_obj_t * dropdown_obj, int32_t y) * Set the position of list when it is closed to show the selected item * @param ddlist pointer to a drop down list */ -static void position_to_selected(lv_obj_t * dropdown_obj) +static void position_to_selected(lv_obj_t * dropdown_obj, lv_anim_enable_t anim_en) { lv_dropdown_t * dropdown = (lv_dropdown_t *)dropdown_obj; @@ -1214,7 +1219,7 @@ static void position_to_selected(lv_obj_t * dropdown_obj) int32_t line_y1 = dropdown->sel_opt_id * unit_h; /*Scroll to the selected option*/ - lv_obj_scroll_to_y(dropdown->list, line_y1, LV_ANIM_OFF); + lv_obj_scroll_to_y(dropdown->list, line_y1, anim_en); lv_obj_invalidate(dropdown->list); } 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 index 67d879aa1..8229758b5 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/dropdown/lv_dropdown_private.h @@ -31,7 +31,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_dropdown_t { +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*/ @@ -46,7 +46,7 @@ struct lv_dropdown_t { uint8_t selected_highlight: 1; /**< 1: Make the selected option highlighted in the list*/ }; -struct lv_dropdown_list_t { +struct _lv_dropdown_list_t { lv_obj_t obj; lv_obj_t * dropdown; }; 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 5fdcc12d5..3dde44ca7 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.c @@ -12,6 +12,9 @@ #include "../../draw/lv_draw_private.h" #include "../../core/lv_obj_event_private.h" #include "../../core/lv_obj_class_private.h" +#include "../../core/lv_obj_class_private.h" +#include "../../core/lv_obj_draw_private.h" + #if LV_USE_IMAGE != 0 #include "../../stdlib/lv_string.h" @@ -110,7 +113,7 @@ const lv_obj_class_t lv_image_class = { .height_def = LV_SIZE_CONTENT, .instance_size = sizeof(lv_image_t), .base_class = &lv_obj_class, - .name = "image", + .name = "lv_image", #if LV_USE_OBJ_PROPERTY .prop_index_start = LV_PROPERTY_IMAGE_START, .prop_index_end = LV_PROPERTY_IMAGE_END, @@ -172,7 +175,7 @@ void lv_image_set_src(lv_obj_t * obj, const void * src) /*If the new source type is unknown free the memories of the old source*/ if(src_type == LV_IMAGE_SRC_UNKNOWN) { - LV_LOG_WARN("unknown image type"); + if(src) LV_LOG_WARN("unknown image type"); if(img->src_type == LV_IMAGE_SRC_SYMBOL || img->src_type == LV_IMAGE_SRC_FILE) { lv_free((void *)img->src); } @@ -194,6 +197,15 @@ void lv_image_set_src(lv_obj_t * obj, const void * src) /*Save the source*/ if(src_type == LV_IMAGE_SRC_VARIABLE) { + if(header.flags & LV_IMAGE_FLAGS_ALLOCATED) { + lv_draw_buf_t * buf = (lv_draw_buf_t *)src; + if(!buf->unaligned_data || !buf->handlers) { + LV_LOG_ERROR("Invalid draw buffer, unaligned_data: %p, handlers: %p", + buf->unaligned_data, (void *)buf->handlers); + return; + } + } + /*If memory was allocated because of the previous `src_type` then free it*/ if(img->src_type == LV_IMAGE_SRC_FILE || img->src_type == LV_IMAGE_SRC_SYMBOL) { lv_free((void *)img->src); @@ -436,7 +448,8 @@ void lv_image_set_inner_align(lv_obj_t * obj, lv_image_align_t align) if(align == img->align) return; /*If we're removing STRETCH, reset the scale*/ - if(img->align == LV_IMAGE_ALIGN_STRETCH) { + if(img->align == LV_IMAGE_ALIGN_STRETCH || img->align == LV_IMAGE_ALIGN_CONTAIN || + img->align == LV_IMAGE_ALIGN_COVER) { lv_image_set_scale(obj, LV_SCALE_NONE); } @@ -531,6 +544,58 @@ int32_t lv_image_get_scale_y(lv_obj_t * obj) return img->scale_y; } +int32_t lv_image_get_src_width(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_image_t * img = (lv_image_t *)obj; + update_align(obj); + + return img->w; +} + +int32_t lv_image_get_src_height(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_image_t * img = (lv_image_t *)obj; + update_align(obj); + + return img->h; +} + +int32_t lv_image_get_transformed_width(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_image_t * img = (lv_image_t *)obj; + update_align(obj); + + lv_point_t pivot_px; + lv_image_get_pivot(obj, &pivot_px); + + lv_area_t a; + lv_image_buf_get_transformed_area(&a, img->w, img->h, img->rotation, img->scale_x, img->scale_y, &pivot_px); + + return lv_area_get_width(&a); +} + +int32_t lv_image_get_transformed_height(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_image_t * img = (lv_image_t *)obj; + update_align(obj); + + lv_point_t pivot_px; + lv_image_get_pivot(obj, &pivot_px); + + lv_area_t a; + lv_image_buf_get_transformed_area(&a, img->w, img->h, img->rotation, img->scale_x, img->scale_y, &pivot_px); + + return lv_area_get_height(&a); +} + lv_blend_mode_t lv_image_get_blend_mode(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -649,6 +714,15 @@ static void lv_image_event(const lv_obj_class_t * class_p, lv_event_t * e) *s = LV_MAX(*s, a.y2 - h); } } + else if(code == LV_EVENT_SIZE_CHANGED) { + if(img->align == LV_IMAGE_ALIGN_STRETCH || img->align == LV_IMAGE_ALIGN_CONTAIN || + img->align == LV_IMAGE_ALIGN_COVER) { + update_align(obj); + if(img->rotation || img->scale_x != LV_SCALE_NONE || img->scale_y != LV_SCALE_NONE) { + lv_obj_refresh_ext_draw_size(obj); + } + } + } else if(code == LV_EVENT_HIT_TEST) { lv_hit_test_info_t * info = lv_event_get_param(e); @@ -656,7 +730,7 @@ static void lv_image_event(const lv_obj_class_t * class_p, lv_event_t * e) *perform hit test on its transformed area*/ if(img->w == lv_obj_get_width(obj) && img->h == lv_obj_get_height(obj) && (img->scale_x != LV_SCALE_NONE || img->scale_y != LV_SCALE_NONE || - img->rotation != 0 || img->pivot.x != img->w / 2 || img->pivot.y != img->h / 2)) { + img->rotation != 0)) { int32_t w = lv_obj_get_width(obj); int32_t h = lv_obj_get_height(obj); @@ -752,6 +826,7 @@ static void draw_image(lv_event_t * e) if(img->src_type == LV_IMAGE_SRC_FILE || img->src_type == LV_IMAGE_SRC_VARIABLE) { lv_draw_image_dsc_t draw_dsc; lv_draw_image_dsc_init(&draw_dsc); + draw_dsc.base.layer = layer; lv_obj_init_draw_image_dsc(obj, LV_PART_MAIN, &draw_dsc); lv_area_t clip_area_ori = layer->_clip_area; @@ -777,6 +852,15 @@ static void draw_image(lv_event_t * e) 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_CONTAIN || img->align == LV_IMAGE_ALIGN_COVER) { + int32_t scale = lv_image_get_scale(obj); + lv_point_t offset; + offset.x = (lv_obj_get_width(obj) - img->w * scale / LV_SCALE_NONE) / 2; + offset.y = (lv_obj_get_height(obj) - img->h * scale / LV_SCALE_NONE) / 2; + lv_area_move(&draw_dsc.image_area, offset.x, offset.y); + lv_area_move(&draw_dsc.image_area, 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(&draw_dsc.image_area, img->offset.x, img->offset.y); @@ -793,14 +877,33 @@ static void draw_image(lv_event_t * e) lv_draw_image(layer, &draw_dsc, &coords); layer->_clip_area = clip_area_ori; - } else if(img->src_type == LV_IMAGE_SRC_SYMBOL) { lv_draw_label_dsc_t label_dsc; lv_draw_label_dsc_init(&label_dsc); + label_dsc.base.layer = layer; lv_obj_init_draw_label_dsc(obj, LV_PART_MAIN, &label_dsc); label_dsc.text = img->src; - lv_draw_label(layer, &label_dsc, &obj->coords); + lv_area_t * coords; + lv_area_t aligned_coords; + const bool image_area_is_same_as_coords = img->w == lv_area_get_width(&obj->coords) + && img->h == lv_area_get_height(&obj->coords); + const bool needs_inner_alignment = img->align > LV_IMAGE_ALIGN_TOP_LEFT + && !image_area_is_same_as_coords; + const bool has_offset = img->offset.x || img->offset.y; + const bool inner_alignment_is_transforming = img->align >= LV_IMAGE_ALIGN_AUTO_TRANSFORM; + if((needs_inner_alignment || has_offset) && !inner_alignment_is_transforming) { + lv_point_t text_size; + lv_text_get_size(&text_size, label_dsc.text, label_dsc.font, label_dsc.letter_space, + label_dsc.line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); + lv_area_set(&aligned_coords, 0, 0, text_size.x, text_size.y); + lv_area_align(&obj->coords, &aligned_coords, img->align, img->offset.x, img->offset.y); + coords = &aligned_coords; + } + else { + coords = &obj->coords; + } + lv_draw_label(layer, &label_dsc, coords); } else if(img->src == NULL) { /*Do not need to draw image when src is NULL*/ @@ -855,16 +958,38 @@ static void update_align(lv_obj_t * obj) lv_image_set_rotation(obj, 0); lv_image_set_pivot(obj, 0, 0); if(img->w != 0 && img->h != 0) { + lv_obj_update_layout(obj); int32_t scale_x = lv_obj_get_width(obj) * LV_SCALE_NONE / img->w; int32_t scale_y = lv_obj_get_height(obj) * LV_SCALE_NONE / img->h; scale_update(obj, scale_x, scale_y); } } + else if(img->align == LV_IMAGE_ALIGN_CONTAIN) { + lv_image_set_rotation(obj, 0); + lv_image_set_pivot(obj, 0, 0); + if(img->w != 0 && img->h != 0) { + lv_obj_update_layout(obj); + int32_t scale_x = lv_obj_get_width(obj) * LV_SCALE_NONE / img->w; + int32_t scale_y = lv_obj_get_height(obj) * LV_SCALE_NONE / img->h; + int32_t scale = LV_MIN(scale_x, scale_y); + scale_update(obj, scale, scale); + } + } + else if(img->align == LV_IMAGE_ALIGN_COVER) { + lv_image_set_rotation(obj, 0); + lv_image_set_pivot(obj, 0, 0); + if(img->w != 0 && img->h != 0) { + lv_obj_update_layout(obj); + int32_t scale_x = lv_obj_get_width(obj) * LV_SCALE_NONE / img->w; + int32_t scale_y = lv_obj_get_height(obj) * LV_SCALE_NONE / img->h; + int32_t scale = LV_MAX(scale_x, scale_y); + scale_update(obj, scale, scale); + } + } else if(img->align == LV_IMAGE_ALIGN_TILE) { lv_image_set_rotation(obj, 0); lv_image_set_pivot(obj, 0, 0); scale_update(obj, LV_SCALE_NONE, LV_SCALE_NONE); - } } 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 abc521774..39cde0c9d 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image.h @@ -51,8 +51,10 @@ typedef enum { LV_IMAGE_ALIGN_RIGHT_MID, LV_IMAGE_ALIGN_CENTER, LV_IMAGE_ALIGN_AUTO_TRANSFORM, - LV_IMAGE_ALIGN_STRETCH, - LV_IMAGE_ALIGN_TILE, + LV_IMAGE_ALIGN_STRETCH, /* Set X and Y scale to fill the Widget's area. */ + LV_IMAGE_ALIGN_TILE, /* Tile image to fill Widget's area. Offset is applied to shift the tiling. */ + LV_IMAGE_ALIGN_CONTAIN, /* The image keeps its aspect ratio, but is resized to the maximum size that fits within the Widget's area. */ + LV_IMAGE_ALIGN_COVER, /* The image keeps its aspect ratio and fills the Widget's area. */ } lv_image_align_t; #if LV_USE_OBJ_PROPERTY @@ -266,6 +268,34 @@ int32_t lv_image_get_scale_x(lv_obj_t * obj); */ int32_t lv_image_get_scale_y(lv_obj_t * obj); +/** + * Get the width of an image before any transformations. + * @param obj Pointer to an image object. + * @return The width of the image. + */ +int32_t lv_image_get_src_width(lv_obj_t * obj); + +/** + * Get the height of an image before any transformations. + * @param obj Pointer to an image object. + * @return The height of the image. + */ +int32_t lv_image_get_src_height(lv_obj_t * obj); + +/** + * Get the transformed width of an image object. + * @param obj Pointer to an image object. + * @return The transformed width of the image. + */ +int32_t lv_image_get_transformed_width(lv_obj_t * obj); + +/** + * Get the transformed height of an image object. + * @param obj Pointer to an image object. + * @return The transformed height of the image. + */ +int32_t lv_image_get_transformed_height(lv_obj_t * obj); + /** * Get the current blend mode of the image * @param obj pointer to an image object 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 index e880f5d68..4ae950724 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/image/lv_image_private.h @@ -30,7 +30,7 @@ extern "C" { /** * Data of image */ -struct lv_image_t { +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 */ @@ -48,7 +48,6 @@ struct lv_image_t { uint32_t blend_mode: 4; /**< Element of `lv_blend_mode_t`*/ }; - /********************** * GLOBAL PROTOTYPES **********************/ 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 3aef3a42b..4c9e2ffa0 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton.c @@ -49,7 +49,7 @@ const lv_obj_class_t lv_imagebutton_class = { .instance_size = sizeof(lv_imagebutton_t), .constructor_cb = lv_imagebutton_constructor, .event_cb = lv_imagebutton_event, - .name = "imagebutton", + .name = "lv_imagebutton", }; /********************** @@ -79,6 +79,10 @@ void lv_imagebutton_set_src(lv_obj_t * obj, lv_imagebutton_state_t state, const lv_imagebutton_t * imagebutton = (lv_imagebutton_t *)obj; + if((src_left || src_right) && !src_mid) { + LV_LOG_WARN("middle image source is not set while left and/or right image sources are"); + } + update_src_info(&imagebutton->src_left[state], src_left); update_src_info(&imagebutton->src_mid[state], src_mid); update_src_info(&imagebutton->src_right[state], src_right); @@ -201,6 +205,7 @@ static void draw_main(lv_event_t * e) lv_draw_image_dsc_t img_dsc; lv_draw_image_dsc_init(&img_dsc); + img_dsc.base.layer = layer; lv_obj_init_draw_image_dsc(obj, LV_PART_MAIN, &img_dsc); lv_area_t coords_part; 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 index bf9c4ef24..107f49df3 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/imagebutton/lv_imagebutton_private.h @@ -27,13 +27,13 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_imagebutton_src_info_t { +struct _lv_imagebutton_src_info_t { const void * img_src; lv_image_header_t header; }; /** Data of image button */ -struct lv_imagebutton_t { +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 */ 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 e781eb397..64bb09e47 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard.c @@ -69,7 +69,7 @@ const lv_obj_class_t lv_keyboard_class = { .instance_size = sizeof(lv_keyboard_t), .editable = 1, .base_class = &lv_buttonmatrix_class, - .name = "keyboard", + .name = "lv_keyboard", #if LV_USE_OBJ_PROPERTY .prop_index_start = LV_PROPERTY_KEYBOARD_START, .prop_index_end = LV_PROPERTY_KEYBOARD_END, 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 index 757b23e9e..3de02734a 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/keyboard/lv_keyboard_private.h @@ -28,7 +28,7 @@ extern "C" { **********************/ /** Data of keyboard */ -struct lv_keyboard_t { +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 */ 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 ae0711251..8fa790ab5 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label.c @@ -32,7 +32,7 @@ #define LV_LABEL_DEF_SCROLL_SPEED lv_anim_speed_clamped(40, 300, 10000) #define LV_LABEL_SCROLL_DELAY 300 -#define LV_LABEL_DOT_END_INV 0xFFFFFFFF +#define LV_LABEL_DOT_BEGIN_INV 0xFFFFFFFF #define LV_LABEL_HINT_HEIGHT_LIMIT 1024 /*Enable "hint" to buffer info about labels larger than this. (Speed up drawing)*/ /********************** @@ -49,17 +49,15 @@ static void draw_main(lv_event_t * e); static void lv_label_refr_text(lv_obj_t * obj); static void lv_label_revert_dots(lv_obj_t * label); +static void lv_label_set_dots(lv_obj_t * label, uint32_t dot_begin); -static bool lv_label_set_dot_tmp(lv_obj_t * label, char * data, uint32_t len); -static char * lv_label_get_dot_tmp(lv_obj_t * label); -static void lv_label_dot_tmp_free(lv_obj_t * label); static void set_ofs_x_anim(void * obj, int32_t v); static void set_ofs_y_anim(void * obj, int32_t v); static size_t get_text_length(const char * text); static void copy_text_to_label(lv_label_t * label, const char * text); static lv_text_flag_t get_label_flags(lv_label_t * label); static void calculate_x_coordinate(int32_t * x, const lv_text_align_t align, const char * txt, - uint32_t length, const lv_font_t * font, int32_t letter_space, lv_area_t * txt_coords); + uint32_t length, const lv_font_t * font, int32_t letter_space, lv_area_t * txt_coords, lv_text_flag_t flags); /********************** * STATIC VARIABLES @@ -97,7 +95,7 @@ const lv_obj_class_t lv_label_class = { .height_def = LV_SIZE_CONTENT, .instance_size = sizeof(lv_label_t), .base_class = &lv_obj_class, - .name = "label", + .name = "lv_label", #if LV_USE_OBJ_PROPERTY .prop_index_start = LV_PROPERTY_LABEL_START, .prop_index_end = LV_PROPERTY_LABEL_END, @@ -137,11 +135,10 @@ void lv_label_set_text(lv_obj_t * obj, const char * text) LV_ASSERT_OBJ(obj, MY_CLASS); lv_label_t * label = (lv_label_t *)obj; - lv_obj_invalidate(obj); - /*If text is NULL then just refresh with the current text*/ if(text == NULL) text = label->text; + lv_label_revert_dots(obj); /*In case text == label->text*/ const size_t text_len = get_text_length(text); /*If set its own text then reallocate it (maybe its size changed)*/ @@ -232,16 +229,12 @@ void lv_label_set_long_mode(lv_obj_t * obj, lv_label_long_mode_t long_mode) lv_anim_delete(obj, set_ofs_y_anim); lv_point_set(&label->offset, 0, 0); - if(long_mode == LV_LABEL_LONG_SCROLL || long_mode == LV_LABEL_LONG_SCROLL_CIRCULAR || long_mode == LV_LABEL_LONG_CLIP) + if(long_mode == LV_LABEL_LONG_MODE_SCROLL || long_mode == LV_LABEL_LONG_MODE_SCROLL_CIRCULAR || + long_mode == LV_LABEL_LONG_MODE_CLIP) label->expand = 1; else label->expand = 0; - /*Restore the character under the dots*/ - if(label->long_mode == LV_LABEL_LONG_DOT && label->dot_end != LV_LABEL_DOT_END_INV) { - lv_label_revert_dots(obj); - } - label->long_mode = long_mode; lv_label_refr_text(obj); } @@ -274,6 +267,19 @@ void lv_label_set_text_selection_end(lv_obj_t * obj, uint32_t index) #endif } +void lv_label_set_recolor(lv_obj_t * obj, bool en) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_label_t * label = (lv_label_t *)obj; + if(label->recolor == en) return; + + label->recolor = en == false ? 0 : 1; + + /*Refresh the text because the potential color codes in text needs to be hidden or revealed*/ + lv_label_refr_text(obj); +} + /*===================== * Getter functions *====================*/ @@ -314,6 +320,7 @@ void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t pos->x = lv_obj_get_content_width(obj) / 2; break; default: + pos->x = 0; break; } return; @@ -339,9 +346,9 @@ void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t uint32_t new_line_start = 0; while(txt[new_line_start] != '\0') { 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; + if(last_line && label->long_mode == LV_LABEL_LONG_MODE_DOTS) flag |= LV_TEXT_FLAG_BREAK_ALL; - new_line_start += lv_text_get_next_line(&txt[line_start], font, letter_space, max_w, NULL, flag); + new_line_start += lv_text_get_next_line(&txt[line_start], LV_TEXT_LEN_MAX, 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'*/ @@ -386,11 +393,11 @@ void lv_label_get_letter_pos(const lv_obj_t * obj, uint32_t char_id, lv_point_t #endif /*Calculate the x coordinate*/ - int32_t x = lv_text_get_width(bidi_txt, visual_byte_pos, font, letter_space); + int32_t x = lv_text_get_width_with_flags(bidi_txt, visual_byte_pos, font, letter_space, flag); if(char_id != line_start) x += letter_space; uint32_t length = new_line_start - line_start; - calculate_x_coordinate(&x, align, bidi_txt, length, font, letter_space, &txt_coords); + calculate_x_coordinate(&x, align, bidi_txt, length, font, letter_space, &txt_coords, flag); pos->x = x; pos->y = y; @@ -423,6 +430,7 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool const int32_t letter_height = lv_font_get_line_height(font); int32_t y = 0; + lv_text_flag_t flag = get_label_flags(label); /*Search the line of the index letter*/; @@ -430,9 +438,9 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool /*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; + if(last_line && label->long_mode == LV_LABEL_LONG_MODE_DOTS) flag |= LV_TEXT_FLAG_BREAK_ALL; - new_line_start += lv_text_get_next_line(&txt[line_start], font, letter_space, max_w, NULL, flag); + new_line_start += lv_text_get_next_line(&txt[line_start], LV_TEXT_LEN_MAX, font, letter_space, max_w, NULL, flag); if(pos.y <= y + letter_height) { /*The line is found (stored in 'line_start')*/ @@ -468,7 +476,9 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool int32_t x = 0; const lv_text_align_t align = lv_obj_calculate_style_text_align(obj, LV_PART_MAIN, label->text); uint32_t length = new_line_start - line_start; - calculate_x_coordinate(&x, align, bidi_txt, length, font, letter_space, &txt_coords); + calculate_x_coordinate(&x, align, bidi_txt, length, font, letter_space, &txt_coords, flag); + + lv_text_cmd_state_t cmd_state = LV_TEXT_CMD_STATE_WAIT; uint32_t i = 0; uint32_t i_act = i; @@ -481,6 +491,12 @@ uint32_t lv_label_get_letter_on(const lv_obj_t * obj, lv_point_t * pos_in, bool uint32_t letter_next; lv_text_encoded_letter_next_2(bidi_txt, &letter, &letter_next, &i); + if((flag & LV_TEXT_FLAG_RECOLOR) != 0) { + if(lv_text_is_cmd(&cmd_state, bidi_txt[i]) != false) { + continue; /*Skip the letter if it is part of a command*/ + } + } + int32_t gw = lv_font_get_glyph_width(font, letter, letter_next); /*Finish if the x position or the last char of the next line is reached*/ @@ -543,9 +559,9 @@ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) int32_t y = 0; while(txt[line_start] != '\0') { 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; + if(last_line && label->long_mode == LV_LABEL_LONG_MODE_DOTS) flag |= LV_TEXT_FLAG_BREAK_ALL; - new_line_start += lv_text_get_next_line(&txt[line_start], font, letter_space, max_w, NULL, flag); + new_line_start += lv_text_get_next_line(&txt[line_start], LV_TEXT_LEN_MAX, 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; @@ -558,14 +574,18 @@ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) int32_t x = 0; if(align == LV_TEXT_ALIGN_CENTER) { - const int32_t line_w = lv_text_get_width(&txt[line_start], new_line_start - line_start, font, letter_space); + const int32_t line_w = lv_text_get_width_with_flags(&txt[line_start], new_line_start - line_start, font, letter_space, + flag); x += lv_area_get_width(&txt_coords) / 2 - line_w / 2; } else if(align == LV_TEXT_ALIGN_RIGHT) { - const int32_t line_w = lv_text_get_width(&txt[line_start], new_line_start - line_start, font, letter_space); + const int32_t line_w = lv_text_get_width_with_flags(&txt[line_start], new_line_start - line_start, font, letter_space, + flag); x += lv_area_get_width(&txt_coords) - line_w; } + lv_text_cmd_state_t cmd_state = LV_TEXT_CMD_STATE_WAIT; + int32_t last_x = 0; uint32_t i = line_start; uint32_t i_current = i; @@ -578,6 +598,12 @@ bool lv_label_is_char_under_pos(const lv_obj_t * obj, lv_point_t * pos) /*Be careful 'i' already points to the next character*/ lv_text_encoded_letter_next_2(txt, &letter, &letter_next, &i); + if((flag & LV_TEXT_FLAG_RECOLOR) != 0) { + if(lv_text_is_cmd(&cmd_state, txt[i]) != false) { + continue; /*Skip the letter if it is part of a command*/ + } + } + last_x = x; x += lv_font_get_glyph_width(font, letter, letter_next); if(pos->x < x) { @@ -619,6 +645,14 @@ uint32_t lv_label_get_text_selection_end(const lv_obj_t * obj) #endif } +bool lv_label_get_recolor(const lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + + lv_label_t * label = (lv_label_t *)obj; + return label->recolor == 0 ? false : true; +} + /*===================== * Other functions *====================*/ @@ -681,9 +715,10 @@ static void lv_label_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) lv_label_t * label = (lv_label_t *)obj; label->text = NULL; + label->recolor = 0; label->static_txt = 0; - label->dot_end = LV_LABEL_DOT_END_INV; - label->long_mode = LV_LABEL_LONG_WRAP; + label->dot_begin = LV_LABEL_DOT_BEGIN_INV; + label->long_mode = LV_LABEL_LONG_MODE_WRAP; lv_point_set(&label->offset, 0, 0); #if LV_LABEL_LONG_TXT_HINT @@ -696,11 +731,9 @@ static void lv_label_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) label->sel_start = LV_DRAW_LABEL_NO_TXT_SEL; label->sel_end = LV_DRAW_LABEL_NO_TXT_SEL; #endif - label->dot.tmp_ptr = NULL; - label->dot_tmp_alloc = 0; lv_obj_remove_flag(obj, LV_OBJ_FLAG_CLICKABLE); - lv_label_set_long_mode(obj, LV_LABEL_LONG_WRAP); + lv_label_set_long_mode(obj, LV_LABEL_LONG_MODE_WRAP); lv_label_set_text(obj, LV_LABEL_DEFAULT_TEXT); LV_TRACE_OBJ_CREATE("finished"); @@ -711,7 +744,6 @@ static void lv_label_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) LV_UNUSED(class_p); lv_label_t * label = (lv_label_t *)obj; - lv_label_dot_tmp_free(obj); if(!label->static_txt) lv_free(label->text); label->text = NULL; } @@ -728,8 +760,6 @@ static void lv_label_event(const lv_obj_class_t * class_p, lv_event_t * e) lv_obj_t * obj = lv_event_get_current_target(e); if((code == LV_EVENT_STYLE_CHANGED) || (code == LV_EVENT_SIZE_CHANGED)) { - /*Revert dots for proper refresh*/ - lv_label_revert_dots(obj); lv_label_refr_text(obj); } else if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) { @@ -746,17 +776,24 @@ static void lv_label_event(const lv_obj_class_t * class_p, lv_event_t * e) if(label->invalid_size_cache) { const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); int32_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); + int32_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); lv_text_flag_t flag = LV_TEXT_FLAG_NONE; + if(label->recolor != 0) flag |= LV_TEXT_FLAG_RECOLOR; if(label->expand != 0) flag |= LV_TEXT_FLAG_EXPAND; - int32_t w = lv_obj_get_content_width(obj); + int32_t w; if(lv_obj_get_style_width(obj, LV_PART_MAIN) == LV_SIZE_CONTENT && !obj->w_layout) w = LV_COORD_MAX; else w = lv_obj_get_content_width(obj); + w = LV_MIN(w, lv_obj_get_style_max_width(obj, LV_PART_MAIN)); - w = LV_MIN(w, lv_obj_get_style_max_width(obj, 0)); - + uint32_t dot_begin = label->dot_begin; + lv_label_revert_dots(obj); lv_text_get_size(&label->size_cache, label->text, font, letter_space, line_space, w, flag); + lv_label_set_dots(obj, dot_begin); + + label->size_cache.y = LV_MIN(label->size_cache.y, lv_obj_get_style_max_height(obj, LV_PART_MAIN)); + label->invalid_size_cache = false; } @@ -783,15 +820,19 @@ static void draw_main(lv_event_t * e) lv_draw_label_dsc_t label_draw_dsc; lv_draw_label_dsc_init(&label_draw_dsc); label_draw_dsc.text = label->text; + label_draw_dsc.text_static = label->static_txt; label_draw_dsc.ofs_x = label->offset.x; label_draw_dsc.ofs_y = label->offset.y; + label_draw_dsc.text_size = label->text_size; #if LV_LABEL_LONG_TXT_HINT - if(label->long_mode != LV_LABEL_LONG_SCROLL_CIRCULAR && lv_area_get_height(&txt_coords) >= LV_LABEL_HINT_HEIGHT_LIMIT) { + if(label->long_mode != LV_LABEL_LONG_MODE_SCROLL_CIRCULAR && + lv_area_get_height(&txt_coords) >= LV_LABEL_HINT_HEIGHT_LIMIT) { label_draw_dsc.hint = &label->hint; } #endif label_draw_dsc.flag = flag; + label_draw_dsc.base.layer = layer; lv_obj_init_draw_label_dsc(obj, LV_PART_MAIN, &label_draw_dsc); lv_bidi_calculate_align(&label_draw_dsc.align, &label_draw_dsc.bidi_dir, label->text); @@ -802,15 +843,24 @@ static void draw_main(lv_event_t * e) label_draw_dsc.sel_bg_color = lv_obj_get_style_bg_color(obj, LV_PART_SELECTED); } + /* get the style attributes of a letter outline */ + label_draw_dsc.outline_stroke_color = lv_obj_get_style_text_outline_stroke_color(obj, LV_PART_MAIN); + label_draw_dsc.outline_stroke_opa = lv_obj_get_style_text_outline_stroke_opa(obj, LV_PART_MAIN); + label_draw_dsc.outline_stroke_width = lv_obj_get_style_text_outline_stroke_width(obj, LV_PART_MAIN); + + /* In SCROLL and SCROLL_CIRCULAR mode the CENTER and RIGHT are pointless, so remove them. * (In addition, they will create misalignment in this situation)*/ - if((label->long_mode == LV_LABEL_LONG_SCROLL || label->long_mode == LV_LABEL_LONG_SCROLL_CIRCULAR) && + if((label->long_mode == LV_LABEL_LONG_MODE_SCROLL || label->long_mode == LV_LABEL_LONG_MODE_SCROLL_CIRCULAR) && (label_draw_dsc.align == LV_TEXT_ALIGN_CENTER || label_draw_dsc.align == LV_TEXT_ALIGN_RIGHT)) { - lv_point_t size; - lv_text_get_size(&size, label->text, label_draw_dsc.font, label_draw_dsc.letter_space, label_draw_dsc.line_space, - LV_COORD_MAX, flag); + lv_point_t size = label->text_size; if(size.x > lv_area_get_width(&txt_coords)) { +#if LV_USE_BIDI + const lv_base_dir_t base_dir = lv_obj_get_style_base_dir(obj, LV_PART_MAIN); + label_draw_dsc.align = base_dir == LV_BASE_DIR_RTL ? LV_TEXT_ALIGN_RIGHT : LV_TEXT_ALIGN_LEFT; +#else label_draw_dsc.align = LV_TEXT_ALIGN_LEFT; +#endif } } @@ -820,12 +870,14 @@ static void draw_main(lv_event_t * e) return; } - if(label->long_mode == LV_LABEL_LONG_WRAP) { + if(label->long_mode == LV_LABEL_LONG_MODE_WRAP) { int32_t s = lv_obj_get_scroll_top(obj); lv_area_move(&txt_coords, 0, -s); txt_coords.y2 = obj->coords.y2; } - if(label->long_mode == LV_LABEL_LONG_SCROLL || label->long_mode == LV_LABEL_LONG_SCROLL_CIRCULAR) { + if(label->long_mode == LV_LABEL_LONG_MODE_SCROLL || + label->long_mode == LV_LABEL_LONG_MODE_SCROLL_CIRCULAR || + label->long_mode == LV_LABEL_LONG_MODE_CLIP) { const lv_area_t clip_area_ori = layer->_clip_area; layer->_clip_area = txt_clip; lv_draw_label(layer, &label_draw_dsc, &txt_coords); @@ -838,10 +890,8 @@ static void draw_main(lv_event_t * e) lv_area_t clip_area_ori = layer->_clip_area; layer->_clip_area = txt_clip; - if(label->long_mode == LV_LABEL_LONG_SCROLL_CIRCULAR) { - lv_point_t size; - lv_text_get_size(&size, label->text, label_draw_dsc.font, label_draw_dsc.letter_space, label_draw_dsc.line_space, - LV_COORD_MAX, flag); + if(label->long_mode == LV_LABEL_LONG_MODE_SCROLL_CIRCULAR) { + lv_point_t size = label->text_size; /*Draw the text again on label to the original to make a circular effect */ if(size.x > lv_area_get_width(&txt_coords)) { @@ -867,17 +917,17 @@ static void draw_main(lv_event_t * e) static void overwrite_anim_property(lv_anim_t * dest, const lv_anim_t * src, lv_label_long_mode_t mode) { switch(mode) { - case LV_LABEL_LONG_SCROLL: - /** If the dest animation is already running, overwrite is not allowed */ + case LV_LABEL_LONG_MODE_SCROLL: + /* If the dest animation is already running, overwrite is not allowed */ if(dest->act_time <= 0) dest->act_time = src->act_time; dest->repeat_cnt = src->repeat_cnt; dest->repeat_delay = src->repeat_delay; dest->completed_cb = src->completed_cb; - dest->playback_delay = src->playback_delay; + dest->reverse_delay = src->reverse_delay; break; - case LV_LABEL_LONG_SCROLL_CIRCULAR: - /** If the dest animation is already running, overwrite is not allowed */ + case LV_LABEL_LONG_MODE_SCROLL_CIRCULAR: + /* If the dest animation is already running, overwrite is not allowed */ if(dest->act_time <= 0) dest->act_time = src->act_time; dest->repeat_cnt = src->repeat_cnt; @@ -913,12 +963,14 @@ static void lv_label_refr_text(lv_obj_t * obj) lv_point_t size; lv_text_flag_t flag = get_label_flags(label); + lv_label_revert_dots(obj); lv_text_get_size(&size, label->text, font, letter_space, line_space, max_w, flag); + label->text_size = size; lv_obj_refresh_self_size(obj); /*In scroll mode start an offset animation*/ - if(label->long_mode == LV_LABEL_LONG_SCROLL) { + if(label->long_mode == LV_LABEL_LONG_MODE_SCROLL) { const lv_anim_t * anim_template = lv_obj_get_style_anim(obj, LV_PART_MAIN); uint32_t anim_time = lv_obj_get_style_anim_duration(obj, LV_PART_MAIN); if(anim_time == 0) anim_time = LV_LABEL_DEF_SCROLL_SPEED; @@ -926,8 +978,8 @@ static void lv_label_refr_text(lv_obj_t * obj) lv_anim_init(&a); lv_anim_set_var(&a, obj); lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE); - lv_anim_set_playback_delay(&a, LV_LABEL_SCROLL_DELAY); - lv_anim_set_repeat_delay(&a, a.playback_delay); + lv_anim_set_reverse_delay(&a, LV_LABEL_SCROLL_DELAY); + lv_anim_set_repeat_delay(&a, a.reverse_delay); bool hor_anim = false; if(size.x > lv_area_get_width(&txt_coords)) { @@ -957,31 +1009,36 @@ static void lv_label_refr_text(lv_obj_t * obj) lv_anim_t * anim_cur = lv_anim_get(obj, set_ofs_x_anim); int32_t act_time = 0; - bool playback_now = false; + bool reverse_play_in_progress = false; if(anim_cur) { act_time = anim_cur->act_time; - playback_now = anim_cur->playback_now; - } - if(act_time < a.duration) { - a.act_time = act_time; /*To keep the old position*/ - a.early_apply = 0; - if(playback_now) { - a.playback_now = 1; - /*Swap the start and end values*/ - int32_t tmp; - tmp = a.start_value; - a.start_value = a.end_value; - a.end_value = tmp; - } + reverse_play_in_progress = anim_cur->reverse_play_in_progress; } + int32_t duration_resolved = lv_anim_resolve_speed(anim_time, start, end); + /*To keep the old position*/ + if(act_time > duration_resolved) act_time = duration_resolved; + + a.act_time = act_time; + if(reverse_play_in_progress) { + a.reverse_play_in_progress = 1; + /*Swap the start and end values*/ + int32_t tmp; + tmp = a.start_value; + a.start_value = a.end_value; + a.end_value = tmp; + } lv_anim_set_duration(&a, anim_time); - lv_anim_set_playback_duration(&a, a.duration); + lv_anim_set_reverse_duration(&a, anim_time); /*If a template animation exists, overwrite some property*/ if(anim_template) overwrite_anim_property(&a, anim_template, label->long_mode); lv_anim_start(&a); + + /*If a delay is happening, apply the start value manually*/ + if(act_time < 0) label->offset.x = start; + hor_anim = true; } else { @@ -996,30 +1053,29 @@ static void lv_label_refr_text(lv_obj_t * obj) lv_anim_t * anim_cur = lv_anim_get(obj, set_ofs_y_anim); int32_t act_time = 0; - bool playback_now = false; + bool reverse_play_in_progress = false; if(anim_cur) { act_time = anim_cur->act_time; - playback_now = anim_cur->playback_now; + reverse_play_in_progress = anim_cur->reverse_play_in_progress; } - if(act_time < a.duration) { - a.act_time = act_time; /*To keep the old position*/ - a.early_apply = 0; - if(playback_now) { - a.playback_now = 1; - /*Swap the start and end values*/ - int32_t tmp; - tmp = a.start_value; - a.start_value = a.end_value; - a.end_value = tmp; - } + if(act_time > a.duration) act_time = a.duration; + a.act_time = act_time; /*To keep the old position*/ + if(reverse_play_in_progress) { + a.reverse_play_in_progress = 1; + /*Swap the start and end values*/ + int32_t tmp; + tmp = a.start_value; + a.start_value = a.end_value; + a.end_value = tmp; } lv_anim_set_duration(&a, anim_time); - lv_anim_set_playback_duration(&a, a.duration); + lv_anim_set_reverse_duration(&a, anim_time); /*If a template animation exists, overwrite some property*/ - if(anim_template) + if(anim_template) { overwrite_anim_property(&a, anim_template, label->long_mode); + } lv_anim_start(&a); } else { @@ -1029,7 +1085,7 @@ static void lv_label_refr_text(lv_obj_t * obj) } } /*In roll inf. mode keep the size but start offset animations*/ - else if(label->long_mode == LV_LABEL_LONG_SCROLL_CIRCULAR) { + else if(label->long_mode == LV_LABEL_LONG_MODE_SCROLL_CIRCULAR) { const lv_anim_t * anim_template = lv_obj_get_style_anim(obj, LV_PART_MAIN); uint32_t anim_time = lv_obj_get_style_anim_duration(obj, LV_PART_MAIN); if(anim_time == 0) anim_time = LV_LABEL_DEF_SCROLL_SPEED; @@ -1066,14 +1122,16 @@ static void lv_label_refr_text(lv_obj_t * obj) lv_anim_t * anim_cur = lv_anim_get(obj, set_ofs_x_anim); int32_t act_time = anim_cur ? anim_cur->act_time : 0; + /*To keep the old position when the label text is updated mid-scrolling*/ + int32_t duration_resolved = lv_anim_resolve_speed(anim_time, a.start_value, a.end_value); + if(act_time < duration_resolved) { + a.act_time = act_time; + } + /*If a template animation exists, overwrite some property*/ if(anim_template) { overwrite_anim_property(&a, anim_template, label->long_mode); } - else if(act_time < a.duration) { - a.act_time = act_time; /*To keep the old position when the label text is updated mid-scrolling*/ - a.early_apply = 0; - } lv_anim_start(&a); hor_anim = true; @@ -1096,9 +1154,9 @@ static void lv_label_refr_text(lv_obj_t * obj) if(anim_template) { overwrite_anim_property(&a, anim_template, label->long_mode); } + /*To keep the old position when the label text is updated mid-scrolling*/ else if(act_time < a.duration) { - a.act_time = act_time; /*To keep the old position when the label text is updated mid-scrolling*/ - a.early_apply = 0; + a.act_time = act_time; } lv_anim_start(&a); @@ -1109,17 +1167,10 @@ static void lv_label_refr_text(lv_obj_t * obj) label->offset.y = 0; } } - else if(label->long_mode == LV_LABEL_LONG_DOT) { - if(size.y <= lv_area_get_height(&txt_coords)) { /*No dots are required, the text is short enough*/ - label->dot_end = LV_LABEL_DOT_END_INV; - } - 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*/ - label->dot_end = LV_LABEL_DOT_END_INV; - } - else { + else if(label->long_mode == LV_LABEL_LONG_MODE_DOTS) { + if(size.y > lv_area_get_height(&txt_coords) && /*Text overflows available area*/ + size.y > lv_font_get_line_height(font) && /*No break requested, so no dots required*/ + lv_text_get_encoded_length(label->text) > LV_LABEL_DOT_NUM) { /*Do not turn all characters into dots*/ lv_point_t p; int32_t y_overed; p.x = lv_area_get_width(&txt_coords) - @@ -1148,27 +1199,10 @@ static void lv_label_refr_text(lv_obj_t * obj) } /*Save letters under the dots and replace them with dots*/ - uint32_t byte_id_ori = byte_id; - 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); - if(len > LV_LABEL_DOT_NUM || byte_id > txt_len) { - break; - } - } - - if(lv_label_set_dot_tmp(obj, &label->text[byte_id_ori], len)) { - for(i = 0; i < LV_LABEL_DOT_NUM; i++) { - label->text[byte_id_ori + i] = '.'; - } - label->text[byte_id_ori + LV_LABEL_DOT_NUM] = '\0'; - label->dot_end = letter_id + LV_LABEL_DOT_NUM; - } + lv_label_set_dots(obj, byte_id); } } - else if(label->long_mode == LV_LABEL_LONG_CLIP) { + else if(label->long_mode == LV_LABEL_LONG_MODE_CLIP || label->long_mode == LV_LABEL_LONG_MODE_WRAP) { /*Do nothing*/ } @@ -1178,88 +1212,30 @@ static void lv_label_refr_text(lv_obj_t * obj) static void lv_label_revert_dots(lv_obj_t * obj) { lv_label_t * label = (lv_label_t *)obj; - - if(label->long_mode != LV_LABEL_LONG_DOT) return; - 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); - - /*Restore the characters*/ - uint8_t i = 0; - char * dot_tmp = lv_label_get_dot_tmp(obj); - while(label->text[byte_i + i] != '\0') { - label->text[byte_i + i] = dot_tmp[i]; - i++; - } - label->text[byte_i + i] = dot_tmp[i]; - - lv_label_dot_tmp_free(obj); - - label->dot_end = LV_LABEL_DOT_END_INV; -} - -/** - * Store `len` characters from `data`. Allocates space if necessary. - * - * @param label pointer to label object - * @param len Number of characters to store. - * @return true on success. - */ -static bool lv_label_set_dot_tmp(lv_obj_t * obj, char * data, uint32_t len) -{ - - lv_label_t * label = (lv_label_t *)obj; - lv_label_dot_tmp_free(obj); /*Deallocate any existing space*/ - if(len > sizeof(char *)) { - /*Memory needs to be allocated. Allocates an additional byte - *for a NULL-terminator so it can be copied.*/ - label->dot.tmp_ptr = lv_malloc(len + 1); - if(label->dot.tmp_ptr == NULL) { - LV_LOG_ERROR("Failed to allocate memory for dot_tmp_ptr"); - return false; + if(label->dot_begin != LV_LABEL_DOT_BEGIN_INV) { + for(int i = 0; i < LV_LABEL_DOT_NUM + 1 && label->dot[i]; i++) { + label->text[label->dot_begin + i] = label->dot[i]; } - lv_memcpy(label->dot.tmp_ptr, data, len); - label->dot.tmp_ptr[len] = '\0'; - label->dot_tmp_alloc = true; - } - else { - /*Characters can be directly stored in object*/ - label->dot_tmp_alloc = false; - lv_memcpy(label->dot.tmp, data, len); - } - return true; -} - -/** - * Get the stored dot_tmp characters - * @param label pointer to label object - * @return char pointer to a stored characters. Is *not* necessarily NULL-terminated. - */ -static char * lv_label_get_dot_tmp(lv_obj_t * obj) -{ - lv_label_t * label = (lv_label_t *)obj; - if(label->dot_tmp_alloc) { - return label->dot.tmp_ptr; - } - else { - return label->dot.tmp; + label->dot_begin = LV_LABEL_DOT_BEGIN_INV; } } -/** - * Free the dot_tmp_ptr field if it was previously allocated. - * Always clears the field - * @param label pointer to label object. - */ -static void lv_label_dot_tmp_free(lv_obj_t * obj) +static void lv_label_set_dots(lv_obj_t * obj, uint32_t dot_begin) { lv_label_t * label = (lv_label_t *)obj; - if(label->dot_tmp_alloc && label->dot.tmp_ptr) { - lv_free(label->dot.tmp_ptr); + LV_ASSERT_MSG(label->dot_begin == LV_LABEL_DOT_BEGIN_INV, "Label dots already set"); + if(dot_begin != LV_LABEL_DOT_BEGIN_INV) { + /*Save characters*/ + lv_strncpy(label->dot, &label->text[dot_begin], LV_LABEL_DOT_NUM + 1); + label->dot_begin = dot_begin; + + /*Overwrite up to LV_LABEL_DOT_NUM + 1 characters with dots and null terminator*/ + int i = 0; + for(; i < LV_LABEL_DOT_NUM && label->text[dot_begin + i]; i++) { + label->text[dot_begin + i] = '.'; + } + label->text[dot_begin + i] = '\0'; } - label->dot_tmp_alloc = false; - label->dot.tmp_ptr = NULL; } static void set_ofs_x_anim(void * obj, int32_t v) @@ -1301,6 +1277,7 @@ static lv_text_flag_t get_label_flags(lv_label_t * label) { lv_text_flag_t flag = LV_TEXT_FLAG_NONE; + if(label->recolor) flag |= LV_TEXT_FLAG_RECOLOR; if(label->expand) flag |= LV_TEXT_FLAG_EXPAND; lv_obj_t * obj = (lv_obj_t *) label; @@ -1315,14 +1292,14 @@ static lv_text_flag_t get_label_flags(lv_label_t * label) /* Function created because of this pattern be used in multiple functions */ static void calculate_x_coordinate(int32_t * x, const lv_text_align_t align, const char * txt, uint32_t length, - const lv_font_t * font, int32_t letter_space, lv_area_t * txt_coords) + const lv_font_t * font, int32_t letter_space, lv_area_t * txt_coords, lv_text_flag_t flags) { if(align == LV_TEXT_ALIGN_CENTER) { - const int32_t line_w = lv_text_get_width(txt, length, font, letter_space); + const int32_t line_w = lv_text_get_width_with_flags(txt, length, font, letter_space, flags); *x += lv_area_get_width(txt_coords) / 2 - line_w / 2; } else if(align == LV_TEXT_ALIGN_RIGHT) { - const int32_t line_w = lv_text_get_width(txt, length, font, letter_space); + const int32_t line_w = lv_text_get_width_with_flags(txt, length, font, letter_space, flags); *x += lv_area_get_width(txt_coords) - line_w; } else { 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 86964f33f..0cc657622 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label.h @@ -46,11 +46,11 @@ LV_EXPORT_CONST_INT(LV_LABEL_TEXT_SELECTION_OFF); /** Long mode behaviors. Used in 'lv_label_ext_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_WRAP, /**< Keep the object width, wrap lines longer than object width and expand the object height*/ + LV_LABEL_LONG_MODE_DOTS, /**< Keep the size and write dots at the end if the text is too long*/ + LV_LABEL_LONG_MODE_SCROLL, /**< Keep the size and roll the text back and forth*/ + LV_LABEL_LONG_MODE_SCROLL_CIRCULAR, /**< Keep the size and roll the text circularly*/ + LV_LABEL_LONG_MODE_CLIP, /**< Keep the size and clip the text out of it*/ } lv_label_long_mode_t; #if LV_USE_OBJ_PROPERTY @@ -129,6 +129,14 @@ void lv_label_set_text_selection_start(lv_obj_t * obj, uint32_t index); */ void lv_label_set_text_selection_end(lv_obj_t * obj, uint32_t index); +/** + * Enable the recoloring by in-line commands + * @param obj pointer to a label object + * @param en true: enable recoloring, false: disable + * Example: "This is a #ff0000 red# word" + */ +void lv_label_set_recolor(lv_obj_t * obj, bool en); + /*===================== * Getter functions *====================*/ @@ -188,6 +196,13 @@ uint32_t lv_label_get_text_selection_start(const lv_obj_t * obj); */ uint32_t lv_label_get_text_selection_end(const lv_obj_t * obj); +/** + * @brief Get the recoloring attribute + * @param obj pointer to a label object. + * @return true: recoloring is enabled, false: recoloring is disabled + */ +bool lv_label_get_recolor(const lv_obj_t * obj); + /*===================== * Other functions *====================*/ 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 index 81a2e68ec..6f1e715bc 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/label/lv_label_private.h @@ -28,14 +28,11 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_label_t { +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 */ + char dot[LV_LABEL_DOT_NUM + 1]; /**< Bytes that have been replaced with dots */ + uint32_t dot_begin; /**< Offset where bytes have been replaced with dots */ #if LV_LABEL_LONG_TXT_HINT lv_draw_label_hint_t hint; @@ -48,11 +45,13 @@ struct lv_label_t { 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 */ + lv_label_long_mode_t long_mode : 4; /**< 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 recolor : 1; /**< Enable in-line letter re-coloring*/ + uint8_t expand : 1; /**< Ignore real width (used by the library with LV_LABEL_LONG_MODE_SCROLL) */ uint8_t invalid_size_cache : 1; /**< 1: Recalculate size and update cache */ + + lv_point_t text_size; }; 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 6a8c29bbf..82815abf7 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led.c @@ -42,7 +42,7 @@ const lv_obj_class_t lv_led_class = { .height_def = LV_DPI_DEF / 5, .event_cb = lv_led_event, .instance_size = sizeof(lv_led_t), - .name = "led", + .name = "lv_led", }; /********************** @@ -147,9 +147,11 @@ static void lv_led_event(const lv_obj_class_t * class_p, lv_event_t * e) if(code == LV_EVENT_DRAW_MAIN) { /*Make darker colors in a temporary style according to the brightness*/ lv_led_t * led = (lv_led_t *)obj; + lv_layer_t * layer = lv_event_get_layer(e); lv_draw_rect_dsc_t rect_dsc; lv_draw_rect_dsc_init(&rect_dsc); + rect_dsc.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_MAIN, &rect_dsc); /*Use the original colors brightness to modify color->led*/ @@ -177,8 +179,6 @@ static void lv_led_event(const lv_obj_class_t * class_p, lv_event_t * e) rect_dsc.shadow_spread = ((led->bright - LV_LED_BRIGHT_MIN) * rect_dsc.shadow_spread) / (LV_LED_BRIGHT_MAX - LV_LED_BRIGHT_MIN); - lv_layer_t * layer = lv_event_get_layer(e); - lv_draw_rect(layer, &rect_dsc, &obj->coords); } } 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 index af76b4fb9..77b5490f7 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/led/lv_led_private.h @@ -28,7 +28,7 @@ extern "C" { **********************/ /** Data of led */ -struct lv_led_t { +struct _lv_led_t { lv_obj_t obj; lv_color_t color; uint8_t bright; /**< Current brightness of the LED (0..255)*/ 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 a251aae72..81236d95a 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line.c @@ -42,7 +42,7 @@ const lv_obj_class_t lv_line_class = { .height_def = LV_SIZE_CONTENT, .instance_size = sizeof(lv_line_t), .base_class = &lv_obj_class, - .name = "line", + .name = "lv_line", }; /********************** @@ -236,6 +236,7 @@ static void lv_line_event(const lv_obj_class_t * class_p, lv_event_t * e) lv_draw_line_dsc_t line_dsc; lv_draw_line_dsc_init(&line_dsc); + line_dsc.base.layer = layer; lv_obj_init_draw_line_dsc(obj, LV_PART_MAIN, &line_dsc); /*Read all points and draw the lines*/ 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 index 4cbce9c8e..4899392bc 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/line/lv_line_private.h @@ -28,7 +28,7 @@ extern "C" { **********************/ /** Data of line */ -struct lv_line_t { +struct _lv_line_t { lv_obj_t obj; union { const lv_point_precise_t * constant; 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 3556ef1dc..e30bb5f83 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/list/lv_list.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/list/lv_list.c @@ -34,21 +34,21 @@ const lv_obj_class_t lv_list_class = { .base_class = &lv_obj_class, .width_def = (LV_DPI_DEF * 3) / 2, .height_def = LV_DPI_DEF * 2, - .name = "list", + .name = "lv_list", }; const lv_obj_class_t lv_list_button_class = { .base_class = &lv_button_class, .width_def = LV_PCT(100), .height_def = LV_SIZE_CONTENT, - .name = "list-btn", + .name = "lv_list_button", }; const lv_obj_class_t lv_list_text_class = { .base_class = &lv_label_class, .width_def = LV_PCT(100), .height_def = LV_SIZE_CONTENT, - .name = "list-text", + .name = "lv_list_text", }; /********************** @@ -99,7 +99,7 @@ lv_obj_t * lv_list_add_button(lv_obj_t * list, const void * icon, const char * t if(txt) { lv_obj_t * label = lv_label_create(obj); lv_label_set_text(label, txt); - lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR); + lv_label_set_long_mode(label, LV_LABEL_LONG_MODE_SCROLL_CIRCULAR); lv_obj_set_flex_grow(label, 1); } 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 0c3894d04..0c4ffed1e 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/list/lv_list.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/list/lv_list.h @@ -17,6 +17,10 @@ extern "C" { #if LV_USE_LIST +#if LV_USE_FLEX == 0 +#error "lv_list: lv_flex is required. Enable it in lv_conf.h (LV_USE_FLEX 1)" +#endif + /********************* * DEFINES *********************/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie.c b/lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie.c index 48ae25814..f3b968afa 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/lottie/lv_lottie.c @@ -18,6 +18,7 @@ #include "../../misc/lv_timer.h" #include "../../core/lv_obj_class_private.h" +#include "../../misc/cache/lv_cache.h" /********************* * DEFINES @@ -46,7 +47,7 @@ const lv_obj_class_t lv_lottie_class = { .height_def = LV_DPI_DEF, .instance_size = sizeof(lv_lottie_t), .base_class = &lv_canvas_class, - .name = "lottie", + .name = "lv_lottie", }; /********************** @@ -72,12 +73,12 @@ lv_obj_t * lv_lottie_create(lv_obj_t * parent) 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); + int32_t stride = lv_draw_buf_width_to_stride(w, LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED); + buf = lv_draw_buf_align(buf, LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED); 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); + lv_canvas_set_buffer(obj, buf, w, h, LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED); tvg_picture_set_size(lottie->tvg_paint, w, h); /* Rendered output images are premultiplied */ @@ -92,8 +93,8 @@ void lv_lottie_set_buffer(lv_obj_t * obj, int32_t w, int32_t h, void * buf) 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"); + if(draw_buf->header.cf != LV_COLOR_FORMAT_ARGB8888 && draw_buf->header.cf != LV_COLOR_FORMAT_ARGB8888_PREMULTIPLIED) { + LV_LOG_WARN("The draw buf needs to have ARGB8888 or ARGB8888_PREMULTIPLIED color format"); return; } @@ -124,10 +125,10 @@ void lv_lottie_set_src_data(lv_obj_t * obj, const void * src, size_t src_size) 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*/ + lv_anim_set_duration(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->anim->reverse_play_in_progress = false; lottie_update(lottie, 0); /*Render immediately*/ } @@ -142,10 +143,10 @@ void lv_lottie_set_src_file(lv_obj_t * obj, const char * src) 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*/ + lv_anim_set_duration(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->anim->reverse_play_in_progress = false; lottie_update(lottie, 0); /*Render immediately*/ } 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 f9b49fc0e..e508c926e 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu.c @@ -44,7 +44,7 @@ const lv_obj_class_t lv_menu_class = { .width_def = (LV_DPI_DEF * 3) / 2, .height_def = LV_DPI_DEF * 2, .instance_size = sizeof(lv_menu_t), - .name = "menu", + .name = "lv_menu", }; const lv_obj_class_t lv_menu_page_class = { .constructor_cb = lv_menu_page_constructor, @@ -53,7 +53,7 @@ const lv_obj_class_t lv_menu_page_class = { .width_def = LV_PCT(100), .height_def = LV_SIZE_CONTENT, .instance_size = sizeof(lv_menu_page_t), - .name = "menu-page", + .name = "lv_menu_page", }; const lv_obj_class_t lv_menu_cont_class = { @@ -61,7 +61,7 @@ const lv_obj_class_t lv_menu_cont_class = { .base_class = &lv_obj_class, .width_def = LV_PCT(100), .height_def = LV_SIZE_CONTENT, - .name = "menu-cont", + .name = "lv_menu_cont", }; const lv_obj_class_t lv_menu_section_class = { @@ -69,14 +69,14 @@ const lv_obj_class_t lv_menu_section_class = { .base_class = &lv_obj_class, .width_def = LV_PCT(100), .height_def = LV_SIZE_CONTENT, - .name = "menu-section", + .name = "lv_menu_section", }; const lv_obj_class_t lv_menu_separator_class = { .base_class = &lv_obj_class, .width_def = LV_SIZE_CONTENT, .height_def = LV_SIZE_CONTENT, - .name = "menu-separator", + .name = "lv_menu_separator", }; const lv_obj_class_t lv_menu_sidebar_cont_class = { @@ -113,7 +113,6 @@ static void lv_menu_value_changed_event_cb(lv_event_t * e); /********************** * GLOBAL FUNCTIONS **********************/ -bool lv_menu_item_back_button_is_root(lv_obj_t * menu, lv_obj_t * obj); void lv_menu_clear_history(lv_obj_t * obj); lv_obj_t * lv_menu_create(lv_obj_t * parent) @@ -124,10 +123,12 @@ lv_obj_t * lv_menu_create(lv_obj_t * parent) return obj; } -lv_obj_t * lv_menu_page_create(lv_obj_t * parent, char const * const title) +lv_obj_t * lv_menu_page_create(lv_obj_t * menu, char const * const title) { + LV_ASSERT_OBJ(menu, MY_CLASS); + LV_LOG_INFO("begin"); - lv_obj_t * obj = lv_obj_class_create_obj(&lv_menu_page_class, parent); + lv_obj_t * obj = lv_obj_class_create_obj(&lv_menu_page_class, menu); lv_obj_class_init_obj(obj); lv_menu_page_t * page = (lv_menu_page_t *)obj; @@ -141,6 +142,8 @@ lv_obj_t * lv_menu_page_create(lv_obj_t * parent, char const * const title) lv_obj_t * lv_menu_cont_create(lv_obj_t * parent) { + LV_ASSERT_OBJ(parent, &lv_menu_page_class); + LV_LOG_INFO("begin"); lv_obj_t * obj = lv_obj_class_create_obj(&lv_menu_cont_class, parent); lv_obj_class_init_obj(obj); @@ -149,6 +152,8 @@ lv_obj_t * lv_menu_cont_create(lv_obj_t * parent) lv_obj_t * lv_menu_section_create(lv_obj_t * parent) { + LV_ASSERT_OBJ(parent, &lv_menu_page_class); + LV_LOG_INFO("begin"); lv_obj_t * obj = lv_obj_class_create_obj(&lv_menu_section_class, parent); lv_obj_class_init_obj(obj); @@ -157,6 +162,8 @@ lv_obj_t * lv_menu_section_create(lv_obj_t * parent) lv_obj_t * lv_menu_separator_create(lv_obj_t * parent) { + LV_ASSERT_OBJ(parent, &lv_menu_page_class); + LV_LOG_INFO("begin"); lv_obj_t * obj = lv_obj_class_create_obj(&lv_menu_separator_class, parent); lv_obj_class_init_obj(obj); @@ -389,6 +396,8 @@ void lv_menu_set_load_page_event(lv_obj_t * menu, lv_obj_t * obj, lv_obj_t * pag void lv_menu_set_page_title(lv_obj_t * page_obj, char const * const title) { + LV_ASSERT_OBJ(page_obj, &lv_menu_page_class); + LV_LOG_INFO("begin"); lv_menu_page_t * page = (lv_menu_page_t *)page_obj; @@ -414,6 +423,8 @@ void lv_menu_set_page_title(lv_obj_t * page_obj, char const * const title) void lv_menu_set_page_title_static(lv_obj_t * page_obj, char const * const title) { + LV_ASSERT_OBJ(page_obj, &lv_menu_page_class); + LV_LOG_INFO("begin"); lv_menu_page_t * page = (lv_menu_page_t *)page_obj; 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 3d75f8d9a..34edb6c4e 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu.h @@ -18,7 +18,7 @@ extern "C" { #if LV_USE_MENU #if LV_USE_FLEX == 0 -#error "LV_USE_FLEX needs to be enabled" +#error "lv_menu: lv_flex is required. Enable it in lv_conf.h (LV_USE_FLEX 1)" #endif /********************* @@ -60,30 +60,34 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_menu_main_header_cont_cl lv_obj_t * lv_menu_create(lv_obj_t * parent); /** - * Create a menu page object - * @param parent pointer to menu object + * Create a menu page object. + * + * This call inserts the new page under menu->storage as its parent, which is itself a + * child of the menu, so the resulting object hierarchy is: menu => storage => new_page + * where `storage` is a Base Widget. + * @param menu pointer to menu object. * @param title pointer to text for title in header (NULL to not display title) * @return pointer to the created menu page */ -lv_obj_t * lv_menu_page_create(lv_obj_t * parent, char const * const title); +lv_obj_t * lv_menu_page_create(lv_obj_t * menu, char const * const title); /** * Create a menu cont object - * @param parent pointer to an object, it will be the parent of the new menu cont object + * @param parent pointer to a menu page object, it will be the parent of the new menu cont object * @return pointer to the created menu cont */ lv_obj_t * lv_menu_cont_create(lv_obj_t * parent); /** * Create a menu section object - * @param parent pointer to an object, it will be the parent of the new menu section object + * @param parent pointer to a menu page object, it will be the parent of the new menu section object * @return pointer to the created menu section */ lv_obj_t * lv_menu_section_create(lv_obj_t * parent); /** * Create a menu separator object - * @param parent pointer to an object, it will be the parent of the new menu separator object + * @param parent pointer to a menu page object, it will be the parent of the new menu separator object * @return pointer to the created menu separator */ lv_obj_t * lv_menu_separator_create(lv_obj_t * parent); 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 index fca898df9..12d3059f1 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/menu/lv_menu_private.h @@ -27,16 +27,16 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_menu_load_page_event_data_t { +struct _lv_menu_load_page_event_data_t { lv_obj_t * menu; lv_obj_t * page; }; -struct lv_menu_history_t { +struct _lv_menu_history_t { lv_obj_t * page; }; -struct lv_menu_t { +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; @@ -56,11 +56,11 @@ struct lv_menu_t { uint8_t cur_depth; uint8_t prev_depth; uint8_t sidebar_generated : 1; - lv_menu_mode_header_t mode_header : 2; + lv_menu_mode_header_t mode_header : 3; lv_menu_mode_root_back_button_t mode_root_back_btn : 1; }; -struct lv_menu_page_t { +struct _lv_menu_page_t { lv_obj_t obj; char * title; bool static_title; 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 98ad81e16..3fea09ea2 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox.c @@ -43,7 +43,7 @@ const lv_obj_class_t lv_msgbox_class = { .width_def = LV_DPI_DEF * 2, .height_def = LV_SIZE_CONTENT, .instance_size = sizeof(lv_msgbox_t), - .name = "msgbox", + .name = "lv_msgbox", }; const lv_obj_class_t lv_msgbox_header_class = { @@ -51,7 +51,7 @@ const lv_obj_class_t lv_msgbox_header_class = { .width_def = LV_PCT(100), .height_def = LV_DPI_DEF / 3, .instance_size = sizeof(lv_obj_t), - .name = "msgbox-header", + .name = "lv_msgbox_header", }; const lv_obj_class_t lv_msgbox_content_class = { @@ -59,7 +59,7 @@ const lv_obj_class_t lv_msgbox_content_class = { .width_def = LV_PCT(100), .height_def = LV_SIZE_CONTENT, .instance_size = sizeof(lv_obj_t), - .name = "msgbox-content", + .name = "lv_msgbox_content", }; const lv_obj_class_t lv_msgbox_footer_class = { @@ -67,7 +67,7 @@ const lv_obj_class_t lv_msgbox_footer_class = { .width_def = LV_PCT(100), .height_def = LV_DPI_DEF / 3, .instance_size = sizeof(lv_obj_t), - .name = "msgbox-footer", + .name = "lv_msgbox_footer", }; const lv_obj_class_t lv_msgbox_footer_button_class = { @@ -76,7 +76,7 @@ const lv_obj_class_t lv_msgbox_footer_button_class = { .height_def = LV_PCT(100), .instance_size = sizeof(lv_obj_t), .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, - .name = "msgbox-footer-button", + .name = "lv_msgbox_footer_button", }; const lv_obj_class_t lv_msgbox_header_button_class = { @@ -85,7 +85,7 @@ const lv_obj_class_t lv_msgbox_header_button_class = { .height_def = LV_PCT(100), .instance_size = sizeof(lv_obj_t), .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, - .name = "msgbox-header-button", + .name = "lv_msgbox_header_button", }; const lv_obj_class_t lv_msgbox_backdrop_class = { @@ -93,7 +93,7 @@ const lv_obj_class_t lv_msgbox_backdrop_class = { .width_def = LV_PCT(100), .height_def = LV_PCT(100), .instance_size = sizeof(lv_obj_t), - .name = "msgbox-backdrop", + .name = "lv_msgbox_backdrop", }; /********************** 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 index 640a39cbd..4799ea3c6 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/msgbox/lv_msgbox_private.h @@ -31,7 +31,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_msgbox_t { +struct _lv_msgbox_t { lv_obj_t obj; lv_obj_t * header; lv_obj_t * content; diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/objx_templ/lv_objx_templ.c b/lib/libesp32_lvgl/lvgl/src/widgets/objx_templ/lv_objx_templ.c index eaf5c1270..953cc2987 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/objx_templ/lv_objx_templ.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/objx_templ/lv_objx_templ.c @@ -48,7 +48,7 @@ const lv_obj_class_t lv_templ_class = { .group_def = LV_OBJ_CLASS_GROUP_DEF_INHERIT, .editable = LV_OBJ_CLASS_EDITABLE_INHERIT, .base_class = &lv_templ_class, - .name = "templ", + .name = "lv_templ", }; /********************** @@ -128,7 +128,7 @@ static void lv_templ_event(const lv_obj_class_t * class_p, lv_event_t * e) lv_result_t res; /*Call the ancestor's event handler*/ - res = LV_EVENT_base(MY_CLASS, e); + res = lv_obj_event_base(MY_CLASS, e); if(res != LV_RESULT_OK) return; /*Add the widget specific event handling here*/ diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_animimage_properties.c b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_animimage_properties.c new file mode 100644 index 000000000..36e3e329d --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_animimage_properties.c @@ -0,0 +1,26 @@ + +/** + * GENERATED FILE, DO NOT EDIT IT! + * @file lv_animimage_properties.c + */ + +#include "../animimage/lv_animimage.h" + +#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME + +#if LV_USE_ANIMIMAGE +/** + * Animimage widget property names, name must be in order. + * Generated code from properties.py + */ +/* *INDENT-OFF* */ +const lv_property_name_t lv_animimage_property_names[4] = { + {"duration", LV_PROPERTY_ANIMIMAGE_DURATION,}, + {"repeat_count", LV_PROPERTY_ANIMIMAGE_REPEAT_COUNT,}, + {"src", LV_PROPERTY_ANIMIMAGE_SRC,}, + {"src_count", LV_PROPERTY_ANIMIMAGE_SRC_COUNT,}, +}; +#endif /*LV_USE_ANIMIMAGE*/ + +/* *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 index 4b4ff67ae..d9a054321 100644 --- 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 @@ -10,13 +10,15 @@ #if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME + extern const lv_property_name_t lv_animimage_property_names[4]; 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_slider_property_names[8]; + extern const lv_property_name_t lv_style_property_names[120]; extern const lv_property_name_t lv_textarea_property_names[15]; #endif #endif diff --git a/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_slider_properties.c b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_slider_properties.c new file mode 100644 index 000000000..0015011c8 --- /dev/null +++ b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_slider_properties.c @@ -0,0 +1,30 @@ + +/** + * GENERATED FILE, DO NOT EDIT IT! + * @file lv_slider_properties.c + */ + +#include "../slider/lv_slider.h" + +#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME + +#if LV_USE_SLIDER +/** + * Slider widget property names, name must be in order. + * Generated code from properties.py + */ +/* *INDENT-OFF* */ +const lv_property_name_t lv_slider_property_names[8] = { + {"is_dragged", LV_PROPERTY_SLIDER_IS_DRAGGED,}, + {"is_symmetrical", LV_PROPERTY_SLIDER_IS_SYMMETRICAL,}, + {"left_value", LV_PROPERTY_SLIDER_LEFT_VALUE,}, + {"max_value", LV_PROPERTY_SLIDER_MAX_VALUE,}, + {"min_value", LV_PROPERTY_SLIDER_MIN_VALUE,}, + {"mode", LV_PROPERTY_SLIDER_MODE,}, + {"range", LV_PROPERTY_SLIDER_RANGE,}, + {"value", LV_PROPERTY_SLIDER_VALUE,}, +}; +#endif /*LV_USE_SLIDER*/ + +/* *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 index 22ef3e257..61ad99ba1 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_style_properties.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_style_properties.c @@ -14,7 +14,7 @@ * Generated code from properties.py */ /* *INDENT-OFF* */ -const lv_property_name_t lv_style_property_names[112] = { +const lv_property_name_t lv_style_property_names[120] = { {"align", LV_PROPERTY_STYLE_ALIGN,}, {"anim", LV_PROPERTY_STYLE_ANIM,}, {"anim_duration", LV_PROPERTY_STYLE_ANIM_DURATION,}, @@ -93,11 +93,15 @@ const lv_property_name_t lv_style_property_names[112] = { {"pad_bottom", LV_PROPERTY_STYLE_PAD_BOTTOM,}, {"pad_column", LV_PROPERTY_STYLE_PAD_COLUMN,}, {"pad_left", LV_PROPERTY_STYLE_PAD_LEFT,}, + {"pad_radial", LV_PROPERTY_STYLE_PAD_RADIAL,}, {"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,}, + {"radial_offset", LV_PROPERTY_STYLE_RADIAL_OFFSET,}, {"radius", LV_PROPERTY_STYLE_RADIUS,}, + {"recolor", LV_PROPERTY_STYLE_RECOLOR,}, + {"recolor_opa", LV_PROPERTY_STYLE_RECOLOR_OPA,}, {"rotary_sensitivity", LV_PROPERTY_STYLE_ROTARY_SENSITIVITY,}, {"shadow_color", LV_PROPERTY_STYLE_SHADOW_COLOR,}, {"shadow_offset_x", LV_PROPERTY_STYLE_SHADOW_OFFSET_X,}, @@ -112,6 +116,9 @@ const lv_property_name_t lv_style_property_names[112] = { {"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,}, + {"text_outline_stroke_color", LV_PROPERTY_STYLE_TEXT_OUTLINE_STROKE_COLOR,}, + {"text_outline_stroke_opa", LV_PROPERTY_STYLE_TEXT_OUTLINE_STROKE_OPA,}, + {"text_outline_stroke_width", LV_PROPERTY_STYLE_TEXT_OUTLINE_STROKE_WIDTH,}, {"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,}, @@ -122,6 +129,7 @@ const lv_property_name_t lv_style_property_names[112] = { {"transform_skew_y", LV_PROPERTY_STYLE_TRANSFORM_SKEW_Y,}, {"transform_width", LV_PROPERTY_STYLE_TRANSFORM_WIDTH,}, {"transition", LV_PROPERTY_STYLE_TRANSITION,}, + {"translate_radial", LV_PROPERTY_STYLE_TRANSLATE_RADIAL,}, {"translate_x", LV_PROPERTY_STYLE_TRANSLATE_X,}, {"translate_y", LV_PROPERTY_STYLE_TRANSLATE_Y,}, {"width", LV_PROPERTY_STYLE_WIDTH,}, 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 index 146f35ad7..b53c751b7 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_style_properties.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/property/lv_style_properties.h @@ -90,11 +90,15 @@ enum { 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_RADIAL, LV_PROPERTY_TYPE_INT, LV_STYLE_PAD_RADIAL), 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, RADIAL_OFFSET, LV_PROPERTY_TYPE_INT, LV_STYLE_RADIAL_OFFSET), LV_PROPERTY_ID(STYLE, RADIUS, LV_PROPERTY_TYPE_INT, LV_STYLE_RADIUS), + LV_PROPERTY_ID(STYLE, RECOLOR, LV_PROPERTY_TYPE_INT, LV_STYLE_RECOLOR), + LV_PROPERTY_ID(STYLE, RECOLOR_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_RECOLOR_OPA), 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), @@ -109,6 +113,9 @@ enum { 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, TEXT_OUTLINE_STROKE_COLOR, LV_PROPERTY_TYPE_INT, LV_STYLE_TEXT_OUTLINE_STROKE_COLOR), + LV_PROPERTY_ID(STYLE, TEXT_OUTLINE_STROKE_OPA, LV_PROPERTY_TYPE_INT, LV_STYLE_TEXT_OUTLINE_STROKE_OPA), + LV_PROPERTY_ID(STYLE, TEXT_OUTLINE_STROKE_WIDTH, LV_PROPERTY_TYPE_INT, LV_STYLE_TEXT_OUTLINE_STROKE_WIDTH), 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), @@ -119,6 +126,7 @@ enum { 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_RADIAL, LV_PROPERTY_TYPE_INT, LV_STYLE_TRANSLATE_RADIAL), 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), 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 b762a1e25..f9ac5c2e9 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.c @@ -59,12 +59,12 @@ static void transform_vect_recursive(lv_obj_t * roller, lv_point_t * vect); static const lv_property_ops_t properties[] = { { .id = LV_PROPERTY_ROLLER_OPTIONS, - .setter = NULL, + .setter = lv_roller_set_options, .getter = lv_roller_get_options, }, { .id = LV_PROPERTY_ROLLER_SELECTED, - .setter = NULL, + .setter = lv_roller_set_selected, .getter = lv_roller_get_selected, }, { @@ -84,7 +84,7 @@ const lv_obj_class_t lv_roller_class = { .editable = LV_OBJ_CLASS_EDITABLE_TRUE, .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, .base_class = &lv_obj_class, - .name = "roller", + .name = "lv_roller", #if LV_USE_OBJ_PROPERTY .prop_index_start = LV_PROPERTY_ROLLER_START, .prop_index_end = LV_PROPERTY_ROLLER_END, @@ -102,7 +102,7 @@ const lv_obj_class_t lv_roller_label_class = { .event_cb = lv_roller_label_event, .instance_size = sizeof(lv_label_t), .base_class = &lv_label_class, - .name = "roller-label", + .name = "lv_roller_label", }; /********************** @@ -220,6 +220,33 @@ void lv_roller_set_selected(lv_obj_t * obj, uint32_t sel_opt, lv_anim_enable_t a refr_position(obj, anim); } +bool lv_roller_set_selected_str(lv_obj_t * obj, const char * sel_opt, lv_anim_enable_t anim) +{ + const char * options = lv_roller_get_options(obj); + size_t options_len = lv_strlen(options); + + bool option_found = false; + + uint32_t current_option = 0; + size_t line_start = 0; + + for(size_t i = 0; i < options_len; i++) { + if(options[i] == '\n') { + /* See if this is the correct option */ + if(lv_strncmp(&options[line_start], sel_opt, i - line_start) == 0) { + lv_roller_set_selected(obj, current_option, anim); + option_found = true; + break; + } + + current_option++; + line_start = i + 1; + } + } + + return option_found; +} + void lv_roller_set_visible_row_count(lv_obj_t * obj, uint32_t row_cnt) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -360,6 +387,11 @@ static void lv_roller_event(const lv_obj_class_t * class_p, lv_event_t * e) roller->moved = 0; lv_anim_delete(get_label(obj), set_y_anim); } + else if(code == LV_EVENT_CLICKED) { + if(roller->moved == 1) { + lv_event_stop_processing(e); + } + } else if(code == LV_EVENT_PRESSING) { if(roller->option_cnt <= 1) return; @@ -492,6 +524,7 @@ static void draw_main(lv_event_t * e) get_sel_area(obj, &sel_area); lv_draw_rect_dsc_t sel_dsc; lv_draw_rect_dsc_init(&sel_dsc); + sel_dsc.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_SELECTED, &sel_dsc); lv_draw_rect(layer, &sel_dsc, &sel_area); } @@ -501,6 +534,7 @@ static void draw_main(lv_event_t * e) lv_draw_label_dsc_t label_dsc; lv_draw_label_dsc_init(&label_dsc); + label_dsc.base.layer = layer; lv_obj_init_draw_label_dsc(obj, LV_PART_SELECTED, &label_dsc); /*Redraw the text on the selected area*/ @@ -511,6 +545,7 @@ static void draw_main(lv_event_t * e) area_ok = lv_area_intersect(&mask_sel, &layer->_clip_area, &sel_area); if(area_ok) { lv_obj_t * label = get_label(obj); + if(lv_label_get_recolor(label)) label_dsc.flag |= LV_TEXT_FLAG_RECOLOR; /*Get the size of the "selected text"*/ lv_point_t label_sel_size; @@ -566,10 +601,12 @@ static void draw_label(lv_event_t * e) * and a lower (below the selected area)*/ lv_obj_t * label_obj = lv_event_get_current_target(e); lv_obj_t * roller = lv_obj_get_parent(label_obj); + lv_layer_t * layer = lv_event_get_layer(e); lv_draw_label_dsc_t label_draw_dsc; lv_draw_label_dsc_init(&label_draw_dsc); + label_draw_dsc.base.layer = layer; lv_obj_init_draw_label_dsc(roller, LV_PART_MAIN, &label_draw_dsc); - lv_layer_t * layer = lv_event_get_layer(e); + if(lv_label_get_recolor(label_obj)) label_draw_dsc.flag |= LV_TEXT_FLAG_RECOLOR; /*If the roller has shadow or outline it has some ext. draw size *therefore the label can overflow the roller's boundaries. @@ -849,12 +886,20 @@ static void transform_vect_recursive(lv_obj_t * roller, lv_point_t * vect) angle += lv_obj_get_style_transform_rotation(parent, 0); int32_t zoom_act_x = lv_obj_get_style_transform_scale_x_safe(parent, 0); int32_t zoom_act_y = lv_obj_get_style_transform_scale_y_safe(parent, 0); - scale_x = (scale_y * zoom_act_x) >> 8; + scale_x = (scale_x * zoom_act_x) >> 8; scale_y = (scale_y * zoom_act_y) >> 8; parent = lv_obj_get_parent(parent); } lv_point_t pivot = { 0, 0 }; + if(scale_x == 0) { + scale_x = 1; + } + + if(scale_y == 0) { + scale_y = 1; + } + scale_x = 256 * 256 / scale_x; scale_y = 256 * 256 / scale_y; lv_point_transform(vect, -angle, scale_x, scale_y, &pivot, false); 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 e6a94b299..551d333de 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller.h @@ -40,9 +40,9 @@ typedef enum { #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_ID2(ROLLER, OPTIONS, LV_PROPERTY_TYPE_TEXT, LV_PROPERTY_TYPE_INT, 0), + LV_PROPERTY_ID2(ROLLER, SELECTED, LV_PROPERTY_TYPE_INT, LV_PROPERTY_TYPE_INT, 1), + LV_PROPERTY_ID(ROLLER, VISIBLE_ROW_COUNT, LV_PROPERTY_TYPE_INT, 2), LV_PROPERTY_ROLLER_END, }; #endif @@ -76,10 +76,19 @@ void lv_roller_set_options(lv_obj_t * obj, const char * options, lv_roller_mode_ * Set the selected option * @param obj pointer to a roller object * @param sel_opt index of the selected option (0 ... number of option - 1); - * @param anim LV_ANIM_ON: set with animation; LV_ANOM_OFF set immediately + * @param anim LV_ANIM_ON: set with animation; LV_ANIM_OFF set immediately */ void lv_roller_set_selected(lv_obj_t * obj, uint32_t sel_opt, lv_anim_enable_t anim); +/** + * Sets the given string as the selection on the roller. Does not alter the current selection on failure. + * @param obj pointer to roller object + * @param sel_opt pointer to the string you want to set as an option + * @param anim LV_ANIM_ON: set with animation; LV_ANIM_OFF set immediately + * @return `true` if set successfully and `false` if the given string does not exist as an option in the roller + */ +bool lv_roller_set_selected_str(lv_obj_t * obj, const char * sel_opt, lv_anim_enable_t anim); + /** * Set the height to show the given number of rows (options) * @param obj pointer to a roller object 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 index 5f784a3bb..686c0d50f 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/roller/lv_roller_private.h @@ -27,7 +27,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_roller_t { +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*/ 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 fbab46018..1cc5aaaab 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale.c @@ -51,10 +51,10 @@ static void scale_get_tick_points(lv_obj_t * obj, const uint32_t tick_idx, bool static void scale_get_label_coords(lv_obj_t * obj, lv_draw_label_dsc_t * label_dsc, lv_point_t * tick_point, lv_area_t * label_coords); 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, + const lv_style_t * indicator_section_style); +static void scale_set_line_properties(lv_obj_t * obj, lv_draw_line_dsc_t * line_dsc, const lv_style_t * section_style, 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); +static void scale_set_arc_properties(lv_obj_t * obj, lv_draw_arc_dsc_t * arc_dsc, const 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, @@ -67,6 +67,8 @@ static void scale_build_custom_label_text(lv_obj_t * obj, lv_draw_label_dsc_t * static void scale_free_line_needle_points_cb(lv_event_t * e); +static bool scale_is_major_tick(lv_scale_t * scale, uint32_t tick_idx); + /********************** * STATIC VARIABLES **********************/ @@ -78,7 +80,7 @@ const lv_obj_class_t lv_scale_class = { .instance_size = sizeof(lv_scale_t), .editable = LV_OBJ_CLASS_EDITABLE_TRUE, .base_class = &lv_obj_class, - .name = "scale", + .name = "lv_scale", }; /********************** @@ -174,9 +176,17 @@ void lv_scale_set_rotation(lv_obj_t * obj, int32_t rotation) { LV_ASSERT_OBJ(obj, MY_CLASS); lv_scale_t * scale = (lv_scale_t *)obj; + int32_t normalized_angle = rotation; - scale->rotation = rotation; + if(normalized_angle < 0 || normalized_angle > 360) { + normalized_angle = rotation % 360; + if(normalized_angle < 0) { + normalized_angle += 360; + } + } + + scale->rotation = normalized_angle; lv_obj_invalidate(obj); } @@ -332,31 +342,68 @@ lv_scale_section_t * lv_scale_add_section(lv_obj_t * obj) if(section == NULL) return NULL; /* Section default values */ - section->main_style = NULL; - section->indicator_style = NULL; - section->items_style = NULL; - section->minor_range = 0U; - section->major_range = 0U; + lv_memzero(section, sizeof(lv_scale_section_t)); section->first_tick_idx_in_section = LV_SCALE_TICK_IDX_DEFAULT_ID; section->last_tick_idx_in_section = LV_SCALE_TICK_IDX_DEFAULT_ID; - section->first_tick_idx_is_major = 0U; - section->last_tick_idx_is_major = 0U; - section->first_tick_in_section_width = 0U; - section->last_tick_in_section_width = 0U; + /* Initial range is [0..-1] to make it "neutral" (i.e. will not be drawn until user + * sets a different range). `range_min` is already 0 from `lv_memzero()` above. */ + section->range_max = -1; return section; } -void lv_scale_section_set_range(lv_scale_section_t * section, int32_t minor_range, int32_t major_range) + +void lv_scale_set_section_range(lv_obj_t * scale, lv_scale_section_t * section, int32_t min, int32_t max) +{ + LV_ASSERT_OBJ(scale, MY_CLASS); + LV_ASSERT_NULL(section); + + section->range_min = min; + section->range_max = max; + + lv_obj_invalidate(scale); +} + +void lv_scale_section_set_range(lv_scale_section_t * section, int32_t min, int32_t max) { if(NULL == section) return; - section->minor_range = minor_range; - section->major_range = major_range; + section->range_min = min; + section->range_max = max; +} + + +void lv_scale_set_section_style_main(lv_obj_t * scale, lv_scale_section_t * section, const lv_style_t * style) +{ + LV_ASSERT_OBJ(scale, MY_CLASS); + LV_ASSERT_NULL(section); + + section->main_style = style; + lv_obj_invalidate(scale); +} + +void lv_scale_set_section_style_indicator(lv_obj_t * scale, lv_scale_section_t * section, const lv_style_t * style) +{ + LV_ASSERT_OBJ(scale, MY_CLASS); + LV_ASSERT_NULL(section); + + section->indicator_style = style; + lv_obj_invalidate(scale); +} + +void lv_scale_set_section_style_items(lv_obj_t * scale, lv_scale_section_t * section, const lv_style_t * style) +{ + LV_ASSERT_OBJ(scale, MY_CLASS); + LV_ASSERT_NULL(section); + + section->items_style = style; + lv_obj_invalidate(scale); } void lv_scale_section_set_style(lv_scale_section_t * section, lv_part_t part, lv_style_t * section_part_style) { + LV_LOG_WARN("Deprecated, use lv_scale_set_section_style_main/indicator/items instead"); + if(NULL == section) return; switch(part) { @@ -397,6 +444,12 @@ int32_t lv_scale_get_major_tick_every(lv_obj_t * obj) return scale->major_tick_every; } +int32_t lv_scale_get_rotation(lv_obj_t * obj) +{ + lv_scale_t * scale = (lv_scale_t *)obj; + return scale->rotation; +} + bool lv_scale_get_label_show(lv_obj_t * obj) { lv_scale_t * scale = (lv_scale_t *)obj; @@ -444,13 +497,13 @@ static void lv_scale_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) scale->label_enabled = LV_SCALE_LABEL_ENABLED_DEFAULT; scale->angle_range = LV_SCALE_DEFAULT_ANGLE_RANGE; scale->rotation = LV_SCALE_DEFAULT_ROTATION; - scale->range_min = 0U; - scale->range_max = 100U; - scale->last_tick_width = 0U; - scale->first_tick_width = 0U; + scale->range_min = 0; + scale->range_max = 100; + scale->last_tick_width = 0; + scale->first_tick_width = 0; scale->post_draw = false; scale->draw_ticks_on_top = false; - scale->custom_label_cnt = 0U; + scale->custom_label_cnt = 0; scale->txt_src = NULL; lv_obj_remove_flag(obj, LV_OBJ_FLAG_SCROLLABLE); @@ -536,12 +589,14 @@ static void scale_draw_indicator(lv_obj_t * obj, lv_event_t * event) lv_draw_label_dsc_t label_dsc; lv_draw_label_dsc_init(&label_dsc); + label_dsc.base.layer = layer; /* Formatting the labels with the configured style for LV_PART_INDICATOR */ lv_obj_init_draw_label_dsc(obj, LV_PART_INDICATOR, &label_dsc); /* Major tick style */ lv_draw_line_dsc_t major_tick_dsc; lv_draw_line_dsc_init(&major_tick_dsc); + major_tick_dsc.base.layer = layer; 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; @@ -550,31 +605,35 @@ static void scale_draw_indicator(lv_obj_t * obj, lv_event_t * event) /* 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); + minor_tick_dsc.base.layer = layer; lv_obj_init_draw_line_dsc(obj, LV_PART_ITEMS, &minor_tick_dsc); /* Main line style */ lv_draw_line_dsc_t main_line_dsc; lv_draw_line_dsc_init(&main_line_dsc); + main_line_dsc.base.layer = layer; lv_obj_init_draw_line_dsc(obj, LV_PART_MAIN, &main_line_dsc); - const uint32_t total_tick_count = scale->total_tick_count; - uint32_t tick_idx = 0; - uint32_t major_tick_idx = 0; + /* These 2 values need to be signed since they are being passed + * to `lv_map()` which expects signed integers. */ + const int32_t total_tick_count = scale->total_tick_count; + int32_t tick_idx = 0; + uint32_t major_tick_idx = 0U; 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; + bool is_major_tick = scale_is_major_tick(scale, tick_idx); 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); + const int32_t tick_value = lv_map(tick_idx, 0, total_tick_count - 1, scale->range_min, scale->range_max); label_dsc.base.id1 = tick_idx; label_dsc.base.id2 = tick_value; + label_dsc.base.layer = layer; /* 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(section->range_min <= tick_value && section->range_max >= 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); @@ -605,11 +664,15 @@ static void scale_draw_indicator(lv_obj_t * obj, lv_event_t * event) 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); + major_tick_dsc.base.id1 = tick_idx; + major_tick_dsc.base.id2 = tick_value; 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); + minor_tick_dsc.base.id1 = tick_idx; + minor_tick_dsc.base.id2 = tick_value; lv_draw_line(layer, &minor_tick_dsc); } } @@ -636,26 +699,38 @@ static void scale_draw_label(lv_obj_t * obj, lv_event_t * event, lv_draw_label_d label_dsc->text_local = 1; } + int32_t translate_x = lv_obj_get_style_translate_x(obj, LV_PART_INDICATOR); + int32_t translate_y = lv_obj_get_style_translate_y(obj, LV_PART_INDICATOR); + int32_t label_rotation = lv_obj_get_style_transform_rotation(obj, LV_PART_INDICATOR); + int32_t translate_rotation = 0; + 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)) { - scale_get_label_coords(obj, label_dsc, tick_point_b, &label_coords); + lv_point_t label_origin; + label_origin.x = tick_point_b->x + translate_x; + label_origin.y = tick_point_b->y + translate_y; + scale_get_label_coords(obj, label_dsc, &label_origin, &label_coords); + label_rotation = (label_rotation & LV_SCALE_ROTATION_ANGLE_MASK); } else if(LV_SCALE_MODE_ROUND_OUTER == scale->mode || LV_SCALE_MODE_ROUND_INNER == scale->mode) { + translate_rotation = lv_obj_get_style_translate_radial(obj, LV_PART_INDICATOR); + uint32_t label_gap = lv_obj_get_style_pad_radial(obj, LV_PART_INDICATOR) + LV_SCALE_DEFAULT_LABEL_GAP; + lv_area_t scale_area; lv_obj_get_content_coords(obj, &scale_area); /* Find the center of the scale */ lv_point_t center_point; - int32_t radius_edge = LV_MIN(lv_area_get_width(&scale_area) / 2U, lv_area_get_height(&scale_area) / 2U); + int32_t radius_edge = LV_MIN(lv_area_get_width(&scale_area) / 2, lv_area_get_height(&scale_area) / 2); center_point.x = scale_area.x1 + radius_edge; center_point.y = scale_area.y1 + radius_edge; 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 */ /* 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; + int32_t angle_upscale = ((tick_idx * scale->angle_range) * 10U) / (scale->total_tick_count - 1U) + + (translate_rotation * 10); + angle_upscale += scale->rotation * 10; uint32_t radius_text = 0; if(LV_SCALE_MODE_ROUND_INNER == scale->mode) { @@ -667,8 +742,28 @@ static void scale_draw_label(lv_obj_t * obj, lv_event_t * event, lv_draw_label_d else { /* Nothing to do */ } lv_point_t point; - point.x = center_point.x + radius_text; - point.y = center_point.y; + point.x = center_point.x + radius_text + translate_x; + point.y = center_point.y + translate_y; + int32_t label_rotation_temp = 0; + + if(label_rotation & LV_SCALE_LABEL_ROTATE_MATCH_TICKS) { + label_rotation_temp = (label_rotation & LV_SCALE_ROTATION_ANGLE_MASK) + angle_upscale; + + /* keep text upright if the user asked for it, otherwise it will be upside-down on half the dial */ + if(label_rotation & LV_SCALE_LABEL_ROTATE_KEEP_UPRIGHT) { + while(label_rotation_temp > 3600) { + label_rotation_temp -= 3600; + } + if(label_rotation_temp > 900 && label_rotation_temp < 2400) { + label_rotation_temp += 1800; + } + } + label_rotation = label_rotation_temp; + } + else { + label_rotation = label_rotation & LV_SCALE_ROTATION_ANGLE_MASK; + } + 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); } @@ -677,7 +772,32 @@ static void scale_draw_label(lv_obj_t * obj, lv_event_t * event, lv_draw_label_d return; } - lv_draw_label(layer, label_dsc, &label_coords); + if(label_rotation > 0) { + /*Draw the label to a new layer and draw the layer rotated*/ + lv_layer_t * layer_label = lv_draw_layer_create(layer, LV_COLOR_FORMAT_ARGB8888, &label_coords); + lv_draw_label(layer_label, label_dsc, &label_coords); + + lv_point_t pivot_point; + /* Set pivot point to the center of the label so it matches the scale curve */ + pivot_point.x = lv_area_get_width(&label_coords) / 2; + pivot_point.y = lv_area_get_height(&label_coords) / 2; + + lv_draw_image_dsc_t layer_draw_dsc; + lv_draw_image_dsc_init(&layer_draw_dsc); + layer_draw_dsc.src = layer_label; + layer_draw_dsc.rotation = label_rotation; + layer_draw_dsc.pivot = pivot_point; + lv_draw_layer(layer, &layer_draw_dsc, &label_coords); + } + else { + lv_draw_label(layer, label_dsc, &label_coords); + } + + if(label_dsc->text_local) { + /* clear the reference to the text buffer on the stack */ + label_dsc->text = NULL; + label_dsc->text_local = false; + } } static void scale_calculate_main_compensation(lv_obj_t * obj) @@ -703,14 +823,14 @@ static void scale_calculate_main_compensation(lv_obj_t * obj) 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 bool is_major_tick = scale_is_major_tick(scale, tick_idx); - const int32_t tick_value = lv_map(tick_idx, 0U, total_tick_count - 1, scale->range_min, scale->range_max); + const int32_t tick_value = lv_map(tick_idx, 0, 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(section->range_min <= tick_value && section->range_max >= tick_value) { if(is_major_tick) { scale_set_line_properties(obj, &major_tick_dsc, section->indicator_style, LV_PART_INDICATOR); } @@ -752,6 +872,7 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event) /* Configure both line and label draw descriptors for the tick and label drawings */ lv_draw_line_dsc_t line_dsc; lv_draw_line_dsc_init(&line_dsc); + line_dsc.base.layer = layer; lv_obj_init_draw_line_dsc(obj, LV_PART_MAIN, &line_dsc); /* Get style properties so they can be used in the main line drawing */ @@ -761,24 +882,24 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event) const int32_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN) + border_width; const int32_t pad_right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN) + border_width; - int32_t x_ofs = 0U; - int32_t y_ofs = 0U; + int32_t x_ofs = 0; + int32_t y_ofs = 0; if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode) { - x_ofs = obj->coords.x2 + (line_dsc.width / 2U) - pad_right; + x_ofs = obj->coords.x2 + (line_dsc.width / 2) - pad_right; y_ofs = obj->coords.y1 + pad_top; } else if(LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) { - x_ofs = obj->coords.x1 + (line_dsc.width / 2U) + pad_left; + x_ofs = obj->coords.x1 + (line_dsc.width / 2) + pad_left; y_ofs = obj->coords.y1 + pad_top; } if(LV_SCALE_MODE_HORIZONTAL_BOTTOM == scale->mode) { x_ofs = obj->coords.x1 + pad_right; - y_ofs = obj->coords.y1 + (line_dsc.width / 2U) + pad_top; + y_ofs = obj->coords.y1 + (line_dsc.width / 2) + pad_top; } else if(LV_SCALE_MODE_HORIZONTAL_TOP == scale->mode) { x_ofs = obj->coords.x1 + pad_left; - y_ofs = obj->coords.y2 + (line_dsc.width / 2U) - pad_bottom; + y_ofs = obj->coords.y2 + (line_dsc.width / 2) - pad_bottom; } else { /* Nothing to do */ } @@ -787,14 +908,14 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event) /* Setup the tick points */ if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode || LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) { - main_line_point_a.x = x_ofs - 1U; + main_line_point_a.x = x_ofs - 1; main_line_point_a.y = y_ofs; - main_line_point_b.x = x_ofs - 1U; + main_line_point_b.x = x_ofs - 1; main_line_point_b.y = obj->coords.y2 - pad_bottom; /* Adjust main line with initial and last tick width */ - main_line_point_a.y -= scale->last_tick_width / 2U; - main_line_point_b.y += scale->first_tick_width / 2U; + main_line_point_a.y -= scale->last_tick_width / 2; + main_line_point_b.y += scale->first_tick_width / 2; } else { main_line_point_a.x = x_ofs; @@ -804,8 +925,8 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event) main_line_point_b.y = y_ofs; /* Adjust main line with initial and last tick width */ - main_line_point_a.x -= scale->last_tick_width / 2U; - main_line_point_b.x += scale->first_tick_width / 2U; + main_line_point_a.x -= scale->last_tick_width / 2; + main_line_point_b.x += scale->first_tick_width / 2; } line_dsc.p1 = lv_point_to_precise(&main_line_point_a); @@ -816,14 +937,15 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event) LV_LL_READ_BACK(&scale->section_ll, section) { lv_draw_line_dsc_t section_line_dsc; lv_draw_line_dsc_init(§ion_line_dsc); + section_line_dsc.base.layer = layer; lv_obj_init_draw_line_dsc(obj, LV_PART_MAIN, §ion_line_dsc); /* Calculate the points of the section line */ 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); + const int32_t first_tick_width_halved = (int32_t)(section->first_tick_in_section_width / 2); + const int32_t last_tick_width_halved = (int32_t)(section->last_tick_in_section_width / 2); /* 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) { @@ -858,6 +980,7 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event) /* Configure arc draw descriptors for the main part */ lv_draw_arc_dsc_t arc_dsc; lv_draw_arc_dsc_init(&arc_dsc); + arc_dsc.base.layer = layer; lv_obj_init_draw_arc_dsc(obj, LV_PART_MAIN, &arc_dsc); lv_point_t arc_center; @@ -881,6 +1004,7 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event) 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); + main_arc_section_dsc.base.layer = layer; lv_obj_init_draw_arc_dsc(obj, LV_PART_MAIN, &main_arc_section_dsc); lv_point_t section_arc_center; @@ -888,9 +1012,9 @@ static void scale_draw_main(lv_obj_t * obj, lv_event_t * event) scale_get_center(obj, §ion_arc_center, §ion_arc_radius); /* TODO: Add compensation for the width of the first and last tick over the arc */ - const int32_t section_start_angle = lv_map(section->minor_range, scale->range_min, scale->range_max, scale->rotation, + const int32_t section_start_angle = lv_map(section->range_min, scale->range_min, scale->range_max, scale->rotation, scale->rotation + scale->angle_range); - const int32_t section_end_angle = lv_map(section->major_range, scale->range_min, scale->range_max, scale->rotation, + const int32_t section_end_angle = lv_map(section->range_max, scale->range_min, scale->range_max, scale->rotation, scale->rotation + scale->angle_range); scale_set_arc_properties(obj, &main_arc_section_dsc, section->main_style); @@ -919,7 +1043,7 @@ static void scale_get_center(const lv_obj_t * obj, lv_point_t * center, int32_t int32_t top_bg = lv_obj_get_style_pad_top(obj, LV_PART_MAIN); int32_t bottom_bg = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN); - int32_t r = (LV_MIN(lv_obj_get_width(obj) - left_bg - right_bg, lv_obj_get_height(obj) - top_bg - bottom_bg)) / 2U; + int32_t r = (LV_MIN(lv_obj_get_width(obj) - left_bg - right_bg, lv_obj_get_height(obj) - top_bg - bottom_bg)) / 2; center->x = obj->coords.x1 + r + left_bg; center->y = obj->coords.y1 + r + top_bg; @@ -950,12 +1074,15 @@ static void scale_get_tick_points(lv_obj_t * obj, const uint32_t tick_idx, bool int32_t minor_len = 0; int32_t major_len = 0; + int32_t radial_offset = 0; if(is_major_tick) { major_len = lv_obj_get_style_length(obj, LV_PART_INDICATOR); + radial_offset = lv_obj_get_style_radial_offset(obj, LV_PART_INDICATOR); } else { minor_len = lv_obj_get_style_length(obj, LV_PART_ITEMS); + radial_offset = lv_obj_get_style_radial_offset(obj, LV_PART_ITEMS); } if((LV_SCALE_MODE_VERTICAL_LEFT == scale->mode || LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) @@ -972,25 +1099,25 @@ static void scale_get_tick_points(lv_obj_t * obj, const uint32_t tick_idx, bool const int32_t tick_pad_top = lv_obj_get_style_pad_top(obj, LV_PART_ITEMS); const int32_t tick_pad_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_ITEMS); - int32_t x_ofs = 0U; - int32_t y_ofs = 0U; + int32_t x_ofs = 0; + int32_t y_ofs = 0; if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode) { - x_ofs = obj->coords.x2 + (main_line_dsc.width / 2U) - pad_right; + x_ofs = obj->coords.x2 + (main_line_dsc.width / 2) - pad_right; y_ofs = obj->coords.y1 + (pad_top + tick_pad_top); } else if(LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) { - x_ofs = obj->coords.x1 + (main_line_dsc.width / 2U) + pad_left; + x_ofs = obj->coords.x1 + (main_line_dsc.width / 2) + pad_left; y_ofs = obj->coords.y1 + (pad_top + tick_pad_top); } else if(LV_SCALE_MODE_HORIZONTAL_BOTTOM == scale->mode) { x_ofs = obj->coords.x1 + (pad_right + tick_pad_right); - y_ofs = obj->coords.y1 + (main_line_dsc.width / 2U) + pad_top; + y_ofs = obj->coords.y1 + (main_line_dsc.width / 2) + pad_top; } /* LV_SCALE_MODE_HORIZONTAL_TOP == scale->mode */ else { x_ofs = obj->coords.x1 + (pad_left + tick_pad_left); - y_ofs = obj->coords.y2 + (main_line_dsc.width / 2U) - pad_bottom; + y_ofs = obj->coords.y2 + (main_line_dsc.width / 2) - pad_bottom; } /* Adjust length when tick will be drawn on horizontal top or vertical right scales */ @@ -1028,7 +1155,7 @@ static void scale_get_tick_points(lv_obj_t * obj, const uint32_t tick_idx, bool } else { /* Nothing to do */ } - tick_point_a->x = x_ofs - 1U; /* Move extra pixel out of scale boundary */ + tick_point_a->x = x_ofs - 1; /* Move extra pixel out of scale boundary */ tick_point_a->y = vertical_position; tick_point_b->x = tick_point_a->x - tick_length; tick_point_b->y = vertical_position; @@ -1061,12 +1188,12 @@ static void scale_get_tick_points(lv_obj_t * obj, const uint32_t tick_idx, bool /* Find the center of the scale */ lv_point_t center_point; - const int32_t radius_edge = LV_MIN(lv_area_get_width(&scale_area) / 2U, lv_area_get_height(&scale_area) / 2U); + const int32_t radius_edge = LV_MIN(lv_area_get_width(&scale_area) / 2, lv_area_get_height(&scale_area) / 2); center_point.x = scale_area.x1 + radius_edge; center_point.y = scale_area.y1 + radius_edge; - int32_t angle_upscale = ((tick_idx * scale->angle_range) * 10U) / (scale->total_tick_count - 1); - angle_upscale += scale->rotation * 10U; + int32_t angle_upscale = (int32_t)((tick_idx * scale->angle_range) * 10U) / (scale->total_tick_count - 1U); + angle_upscale += scale->rotation * 10; /* Draw a little bit longer lines to be sure the mask will clip them correctly * and to get a better precision. Adding the main line width to the calculation so we don't have gaps @@ -1083,11 +1210,11 @@ static void scale_get_tick_points(lv_obj_t * obj, const uint32_t tick_idx, bool adjusted_radio_with_tick_len = point_closer_to_arc + (is_major_tick ? major_len : minor_len); } - tick_point_a->x = center_point.x + point_closer_to_arc; + tick_point_a->x = center_point.x + point_closer_to_arc + radial_offset; tick_point_a->y = center_point.y; lv_point_transform(tick_point_a, angle_upscale, LV_SCALE_NONE, LV_SCALE_NONE, ¢er_point, false); - tick_point_b->x = center_point.x + adjusted_radio_with_tick_len; + tick_point_b->x = center_point.x + adjusted_radio_with_tick_len + radial_offset; tick_point_b->y = center_point.y; lv_point_transform(tick_point_b, angle_upscale, LV_SCALE_NONE, LV_SCALE_NONE, ¢er_point, false); } @@ -1114,8 +1241,8 @@ static void scale_get_label_coords(lv_obj_t * obj, lv_draw_label_dsc_t * label_d /* Set the label draw area at some distance of the major tick */ if((LV_SCALE_MODE_HORIZONTAL_BOTTOM == scale->mode) || (LV_SCALE_MODE_HORIZONTAL_TOP == scale->mode)) { - label_coords->x1 = tick_point->x - (label_size.x / 2U); - label_coords->x2 = tick_point->x + (label_size.x / 2U); + label_coords->x1 = tick_point->x - (label_size.x / 2); + label_coords->x2 = tick_point->x + (label_size.x / 2); if(LV_SCALE_MODE_HORIZONTAL_BOTTOM == scale->mode) { label_coords->y1 = tick_point->y + lv_obj_get_style_pad_bottom(obj, LV_PART_INDICATOR); @@ -1127,8 +1254,8 @@ static void scale_get_label_coords(lv_obj_t * obj, lv_draw_label_dsc_t * label_d } } else if((LV_SCALE_MODE_VERTICAL_LEFT == scale->mode) || (LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode)) { - label_coords->y1 = tick_point->y - (label_size.y / 2U); - label_coords->y2 = tick_point->y + (label_size.y / 2U); + label_coords->y1 = tick_point->y - (label_size.y / 2); + label_coords->y2 = tick_point->y + (label_size.y / 2); if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode) { label_coords->x1 = tick_point->x - label_size.x - lv_obj_get_style_pad_left(obj, LV_PART_INDICATOR); @@ -1140,8 +1267,8 @@ static void scale_get_label_coords(lv_obj_t * obj, lv_draw_label_dsc_t * label_d } } else if(LV_SCALE_MODE_ROUND_OUTER == scale->mode || LV_SCALE_MODE_ROUND_INNER == scale->mode) { - label_coords->x1 = tick_point->x - (label_size.x / 2U); - label_coords->y1 = tick_point->y - (label_size.y / 2U); + label_coords->x1 = tick_point->x - (label_size.x / 2); + label_coords->y1 = tick_point->y - (label_size.y / 2); label_coords->x2 = label_coords->x1 + label_size.x; label_coords->y2 = label_coords->y1 + label_size.y; } @@ -1158,7 +1285,7 @@ static void scale_get_label_coords(lv_obj_t * obj, lv_draw_label_dsc_t * label_d * @param items_section_style pointer to indicator section style * @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, +static void scale_set_line_properties(lv_obj_t * obj, lv_draw_line_dsc_t * line_dsc, const lv_style_t * section_style, lv_part_t part) { if(section_style) { @@ -1205,46 +1332,66 @@ static void scale_set_line_properties(lv_obj_t * obj, lv_draw_line_dsc_t * line_ * Checks if the arc has a custom section configuration or not and sets the properties accordingly. * * @param obj pointer to a scale object - * @param line_dsc pointer to arc descriptor + * @param arc_dsc pointer to arc descriptor * @param items_section_style pointer to indicator section style */ -static void scale_set_arc_properties(lv_obj_t * obj, lv_draw_arc_dsc_t * arc_dsc, lv_style_t * section_style) +static void scale_set_arc_properties(lv_obj_t * obj, lv_draw_arc_dsc_t * arc_dsc, const lv_style_t * section_style) { if(section_style) { lv_style_value_t value; lv_style_res_t res; - /* Line width */ + /* arc width */ res = lv_style_get_prop(section_style, LV_STYLE_ARC_WIDTH, &value); if(res == LV_STYLE_RES_FOUND) { arc_dsc->width = (int32_t)value.num; } else { - arc_dsc->width = lv_obj_get_style_line_width(obj, LV_PART_MAIN); + arc_dsc->width = lv_obj_get_style_arc_width(obj, LV_PART_MAIN); } - /* Line color */ + /* arc color */ res = lv_style_get_prop(section_style, LV_STYLE_ARC_COLOR, &value); if(res == LV_STYLE_RES_FOUND) { arc_dsc->color = value.color; } else { - arc_dsc->color = lv_obj_get_style_line_color(obj, LV_PART_MAIN); + arc_dsc->color = lv_obj_get_style_arc_color(obj, LV_PART_MAIN); } - /* Line opa */ + /* arc opa */ res = lv_style_get_prop(section_style, LV_STYLE_ARC_OPA, &value); if(res == LV_STYLE_RES_FOUND) { arc_dsc->opa = (lv_opa_t)value.num; } else { - arc_dsc->opa = lv_obj_get_style_line_opa(obj, LV_PART_MAIN); + arc_dsc->opa = lv_obj_get_style_arc_opa(obj, LV_PART_MAIN); + } + + /* arc rounded */ + res = lv_style_get_prop(section_style, LV_STYLE_ARC_ROUNDED, &value); + if(res == LV_STYLE_RES_FOUND) { + arc_dsc->rounded = (uint8_t)value.num; + } + else { + arc_dsc->rounded = lv_obj_get_style_arc_rounded(obj, LV_PART_MAIN); + } + + /* arc image src */ + res = lv_style_get_prop(section_style, LV_STYLE_ARC_IMAGE_SRC, &value); + if(res == LV_STYLE_RES_FOUND) { + arc_dsc->img_src = (const void *)value.ptr; + } + else { + arc_dsc->img_src = lv_obj_get_style_arc_image_src(obj, LV_PART_MAIN); } } else { - arc_dsc->color = lv_obj_get_style_line_color(obj, LV_PART_MAIN); - arc_dsc->opa = lv_obj_get_style_line_opa(obj, LV_PART_MAIN); - arc_dsc->width = lv_obj_get_style_line_width(obj, LV_PART_MAIN); + arc_dsc->color = lv_obj_get_style_arc_color(obj, LV_PART_MAIN); + arc_dsc->opa = lv_obj_get_style_arc_opa(obj, LV_PART_MAIN); + arc_dsc->width = lv_obj_get_style_arc_width(obj, LV_PART_MAIN); + arc_dsc->rounded = lv_obj_get_style_arc_rounded(obj, LV_PART_MAIN); + arc_dsc->img_src = lv_obj_get_style_arc_image_src(obj, LV_PART_MAIN); } } @@ -1258,7 +1405,7 @@ static void scale_set_arc_properties(lv_obj_t * obj, lv_draw_arc_dsc_t * arc_dsc * @param items_section_style pointer to indicator section style */ static void scale_set_indicator_label_properties(lv_obj_t * obj, lv_draw_label_dsc_t * label_dsc, - lv_style_t * indicator_section_style) + const lv_style_t * indicator_section_style) { if(indicator_section_style) { lv_style_value_t value; @@ -1320,24 +1467,34 @@ static void scale_find_section_tick_idx(lv_obj_t * obj) /* Section handling */ uint32_t tick_idx = 0; for(tick_idx = 0; tick_idx < total_tick_count; tick_idx++) { - bool is_major_tick = false; - if(tick_idx % scale->major_tick_every == 0) is_major_tick = true; + bool is_major_tick = scale_is_major_tick(scale, tick_idx); - const int32_t tick_value = lv_map(tick_idx, 0U, total_tick_count - 1, min_out, max_out); + const int32_t tick_value = lv_map(tick_idx, 0, total_tick_count - 1, min_out, max_out); 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(section->range_min <= tick_value && section->range_max >= tick_value) { if(LV_SCALE_TICK_IDX_DEFAULT_ID == section->first_tick_idx_in_section) { section->first_tick_idx_in_section = tick_idx; section->first_tick_idx_is_major = is_major_tick; } - if(section->first_tick_idx_in_section != tick_idx) { + if(LV_SCALE_TICK_IDX_DEFAULT_ID == section->last_tick_idx_in_section) { + /* This gets it initialized when the beginning and ending range values are the same. */ + section->last_tick_idx_in_section = tick_idx; + section->last_tick_idx_is_major = is_major_tick; + } + /* Now keep setting the `last_tick_idx_...` values as we + * proceed through the `for` loop so it is left with the + * actual last-tick value that is within the Scale's range. */ + else if(section->first_tick_idx_in_section != tick_idx) { section->last_tick_idx_in_section = tick_idx; section->last_tick_idx_is_major = is_major_tick; } } - else { /* Nothing to do */ } + else { + /* `tick_value` is outside Section's range. + * Nothing to do. */ + } } } } @@ -1440,7 +1597,7 @@ static void scale_store_section_line_tick_width_compensation(lv_obj_t * obj, con 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(section->range_min <= tick_value && section->range_max >= tick_value) { if(is_major_tick) { scale_set_line_properties(obj, major_tick_dsc, section->indicator_style, LV_PART_INDICATOR); } @@ -1459,19 +1616,23 @@ static void scale_store_section_line_tick_width_compensation(lv_obj_t * obj, con tmp_width = minor_tick_dsc->width; } - section->first_tick_in_section.y = tick_point_a->y; + section->first_tick_in_section = *tick_point_a; /* Add 1px as adjustment if tmp_width is odd */ if(tmp_width & 0x01U) { if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode || LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) { - tmp_width += 1U; + tmp_width += 1; } else { - tmp_width -= 1U; + tmp_width -= 1; } } section->first_tick_in_section_width = tmp_width; } - else if(tick_idx == section->last_tick_idx_in_section) { + + /* This can also apply when + * (tick_idx == section->first_tick_idx_in_section) when the + * beginning and ending values of the range are the same. */ + if(tick_idx == section->last_tick_idx_in_section) { if(section->last_tick_idx_is_major) { tmp_width = major_tick_dsc->width; } @@ -1479,14 +1640,14 @@ static void scale_store_section_line_tick_width_compensation(lv_obj_t * obj, con tmp_width = minor_tick_dsc->width; } - section->last_tick_in_section.y = tick_point_a->y; + section->last_tick_in_section = *tick_point_a; /* Add 1px as adjustment if tmp_width is odd */ if(tmp_width & 0x01U) { if(LV_SCALE_MODE_VERTICAL_LEFT == scale->mode || LV_SCALE_MODE_VERTICAL_RIGHT == scale->mode) { - tmp_width -= 1U; + tmp_width -= 1; } else { - tmp_width += 1U; + tmp_width += 1; } } section->last_tick_in_section_width = tmp_width; @@ -1501,4 +1662,9 @@ static void scale_free_line_needle_points_cb(lv_event_t * e) lv_free(needle_line_points); } +static bool scale_is_major_tick(lv_scale_t * scale, uint32_t tick_idx) +{ + return scale->major_tick_every != 0 && tick_idx % scale->major_tick_every == 0; +} + #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 ad1bd2b45..ebb98b0a9 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale.h @@ -54,6 +54,15 @@ typedef enum { LV_SCALE_MODE_LAST } lv_scale_mode_t; +#define LV_SCALE_LABEL_ROTATE_MATCH_TICKS 0x100000 +LV_EXPORT_CONST_INT(LV_SCALE_LABEL_ROTATE_MATCH_TICKS); + +#define LV_SCALE_LABEL_ROTATE_KEEP_UPRIGHT 0x80000 +LV_EXPORT_CONST_INT(LV_SCALE_LABEL_ROTATE_KEEP_UPRIGHT); + +#define LV_SCALE_ROTATION_ANGLE_MASK 0x7FFFF +LV_EXPORT_CONST_INT(LV_SCALE_ROTATION_ANGLE_MASK); + LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_scale_class; /********************** @@ -63,7 +72,7 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_scale_class; /** * Create an scale object * @param parent pointer to an object, it will be the parent of the new scale - * @return pointer to the created scale + * @return pointer to created Scale Widget */ lv_obj_t * lv_scale_create(lv_obj_t * parent); @@ -76,172 +85,232 @@ lv_obj_t * lv_scale_create(lv_obj_t * parent); *====================*/ /** - * Set scale mode. See lv_scale_mode_t - * @param obj pointer the scale object + * Set scale mode. See lv_scale_mode_t. + * @param obj pointer to Scale Widget * @param mode the new scale mode */ void lv_scale_set_mode(lv_obj_t * obj, lv_scale_mode_t mode); /** - * Set scale total tick count (including minor and major ticks) - * @param obj pointer the scale object + * Set scale total tick count (including minor and major ticks). + * @param obj pointer to Scale Widget * @param total_tick_count New total tick count */ void lv_scale_set_total_tick_count(lv_obj_t * obj, uint32_t total_tick_count); /** - * Sets how often the major tick will be drawn - * @param obj pointer the scale object + * Sets how often major ticks are drawn. + * @param obj pointer to Scale Widget * @param major_tick_every the new count for major tick drawing */ void lv_scale_set_major_tick_every(lv_obj_t * obj, uint32_t major_tick_every); /** - * Sets label visibility - * @param obj pointer the scale object + * Sets label visibility. + * @param obj pointer to Scale Widget * @param show_label true/false to enable tick label */ void lv_scale_set_label_show(lv_obj_t * obj, bool show_label); /** - * Set the minimal and maximal values on a scale - * @param obj pointer to a scale object - * @param min minimum value of the scale - * @param max maximum value of the scale + * Set minimum and maximum values on Scale. + * @param obj pointer to Scale Widget + * @param min minimum value of Scale + * @param max maximum value of Scale */ void lv_scale_set_range(lv_obj_t * obj, int32_t min, int32_t max); /** - * Set properties specific to round scale - * @param obj pointer to a scale object - * @param angle_range the angular range of the scale + * Set angle between the low end and the high end of the Scale. + * (Applies only to round Scales.) + * @param obj pointer to Scale Widget + * @param max_angle angle in degrees from Scale minimum where top end of Scale will be drawn */ void lv_scale_set_angle_range(lv_obj_t * obj, uint32_t angle_range); /** - * Set properties specific to round scale - * @param obj pointer to a scale object - * @param rotation the angular offset from the 3 o'clock position (clock-wise) + * Set angular offset from the 3-o'clock position of the low end of the Scale. + * (Applies only to round Scales.) + * @param obj pointer to Scale Widget + * @param rotation clockwise angular offset (in degrees) from the 3-o'clock position + * of the low end of the scale; negative and >360 values are first normalized + * to range [0..360]. + * Examples: + * - 0 = 3 o'clock (right side) + * - 30 = 4 o'clock + * - 60 = 5 o'clock + * - 90 = 6 o'clock + * - 135 = midway between 7 and 8 o'clock (default) + * - 180 = 9 o'clock + * - 270 = 12 o'clock + * - 300 = 1 o'clock + * - 330 = 2 o'clock + * - -30 = 2 o'clock + * - 390 = 4 o'clock */ 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. The line points will be allocated and - * managed by the scale unless the line point array was previously set + * Point line needle to specified value. + * @param obj pointer to Scale Widget + * @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|; - * @param value needle to point to the corresponding value + * - needle_length>0: needle_length=needle_length; + * - needle_length<0: needle_length=radius-|needle_length|; + * @param value Scale value needle will point to */ void lv_scale_set_line_needle_value(lv_obj_t * obj, lv_obj_t * needle_line, int32_t needle_length, int32_t value); /** - * Point the needle to the corresponding value through the image, + * Point image needle to specified value; image must point to the right. E.g. -O------> - * @param obj pointer to a scale object - * @param needle_img needle_img of the scale - * @param value needle to point to the corresponding value + * @param obj pointer to Scale Widget + * @param needle_img pointer to needle's Image + * @param value Scale value needle will point to */ void lv_scale_set_image_needle_value(lv_obj_t * obj, lv_obj_t * needle_img, int32_t value); /** - * Set custom text source for major ticks labels - * @param obj pointer to a scale object - * @param txt_src pointer to an array of strings which will be display at major ticks + * Set custom text source for major ticks labels. + * @param obj pointer to Scale Widget + * @param txt_src pointer to an array of strings which will be display at major ticks; + * last element must be a NULL pointer. */ void lv_scale_set_text_src(lv_obj_t * obj, const char * txt_src[]); /** - * Draw the scale after all the children are drawn - * @param obj pointer to a scale object + * Draw Scale after all its children are drawn. + * @param obj pointer to Scale Widget * @param en true: enable post draw */ 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 + * Draw Scale ticks on top of all other parts. + * @param obj pointer to Scale Widget * @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 - * @return pointer to the new section + * Add a Section to specified Scale. Section will not be drawn until + * a valid range is set for it using `lv_scale_set_section_range()`. + * @param obj pointer to Scale Widget + * @return pointer to new Section */ lv_scale_section_t * lv_scale_add_section(lv_obj_t * obj); /** - * Set the range for the given scale section - * @param section pointer to a scale section object - * @param minor_range section new minor range - * @param major_range section new major range + * DEPRECATED, use lv_scale_set_section_rangeinstead. + * Set range for specified Scale Section + * @param section pointer to Section + * @param range_min Section new minimum value + * @param range_max Section new maximum value */ -void lv_scale_section_set_range(lv_scale_section_t * section, int32_t minor_range, int32_t major_range); +void lv_scale_section_set_range(lv_scale_section_t * section, int32_t min, int32_t max); /** - * Set the style of the part for the given scale section - * @param section pointer to a scale section object - * @param part the part for the section, e.g. LV_PART_INDICATOR - * @param section_part_style Pointer to the section part style + * Set the range of a scale section + * @param scale pointer to scale + * @param section pointer to section + * @param range_min section new minimum value + * @param range_max section new maximum value + */ +void lv_scale_set_section_range(lv_obj_t * scale, lv_scale_section_t * section, int32_t min, int32_t max); + +/** + * DEPRECATED, use lv_scale_set_section_style_main/indicator/items instead. + * Set style for specified part of Section. + * @param section pointer to Section + * @param part the part of the Scale the style will apply to, e.g. LV_PART_INDICATOR + * @param section_part_style pointer to style to apply */ void lv_scale_section_set_style(lv_scale_section_t * section, lv_part_t part, lv_style_t * section_part_style); +/** + * Set the style of the line on a section. + * @param scale pointer to scale + * @param section pointer to section + * @param style point to a style + */ +void lv_scale_set_section_style_main(lv_obj_t * scale, lv_scale_section_t * section, const lv_style_t * style); + +/** + * Set the style of the major ticks and label on a section. + * @param scale pointer to scale + * @param section pointer to section + * @param style point to a style + */ +void lv_scale_set_section_style_indicator(lv_obj_t * scale, lv_scale_section_t * section, const lv_style_t * style); + +/** + * Set the style of the minor ticks on a section. + * @param scale pointer to scale + * @param section pointer to section + * @param style point to a style + */ +void lv_scale_set_section_style_items(lv_obj_t * scale, lv_scale_section_t * section, const lv_style_t * style); + /*===================== * Getter functions *====================*/ /** * Get scale mode. See lv_scale_mode_t - * @param obj pointer the scale object + * @param obj pointer to Scale Widget * @return Scale mode */ lv_scale_mode_t lv_scale_get_mode(lv_obj_t * obj); /** * Get scale total tick count (including minor and major ticks) - * @param obj pointer the scale object + * @param obj pointer to Scale Widget * @return Scale total tick count */ int32_t lv_scale_get_total_tick_count(lv_obj_t * obj); /** - * Gets how often the major tick will be drawn - * @param obj pointer the scale object + * Get how often the major tick will be drawn + * @param obj pointer to Scale Widget * @return Scale major tick every count */ int32_t lv_scale_get_major_tick_every(lv_obj_t * obj); +/** + * Get angular location of low end of Scale. + * @param obj pointer to Scale Widget + * @return Scale low end anglular location + */ +int32_t lv_scale_get_rotation(lv_obj_t * obj); + /** * Gets label visibility - * @param obj pointer the scale object + * @param obj pointer to Scale Widget * @return true if tick label is enabled, false otherwise */ bool lv_scale_get_label_show(lv_obj_t * obj); /** - * Get angle range of a round scale - * @param obj pointer to a scale object - * @return Scale angle_range + * Get Scale's range in degrees + * @param obj pointer to Scale Widget + * @return Scale's angle_range */ uint32_t lv_scale_get_angle_range(lv_obj_t * obj); /** - * Get the min range for the given scale section - * @param obj pointer to a scale section object - * @return section minor range + * Get minimum value for Scale + * @param obj pointer to Scale Widget + * @return Scale's minimum value */ int32_t lv_scale_get_range_min_value(lv_obj_t * obj); /** - * Get the max range for the given scale section - * @param obj pointer to a scale section object - * @return section max range + * Get maximum value for Scale + * @param obj pointer to Scale Widget + * @return Scale's maximum value */ int32_t lv_scale_get_range_max_value(lv_obj_t * obj); 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 index c755c1774..76f65383c 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/scale/lv_scale_private.h @@ -27,41 +27,56 @@ extern "C" { * 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_section_t { + /** Style to use for MAIN part(s) of scale + * when it falls within this section's range */ + const lv_style_t * main_style; + + /** Style to use for INDICATOR part(s) of scale + * when it falls within this section's range */ + const lv_style_t * indicator_style; + + /** Style to use for ITEMS part(s) of scale + * when it falls within this section's range */ + const lv_style_t * items_style; + + int32_t range_min; /**< Scale parts with value >= this value will be drawn using applicable style. */ + int32_t range_max; /**< Scale parts with value <= this value will be drawn using applicable style. */ + uint32_t first_tick_idx_in_section; /**< Internal (set during drawing): Tick index of first tick that falls within + * this section; LV_SCALE_TICK_IDX_DEFAULT_ID if section contains no ticks. */ + uint32_t last_tick_idx_in_section; /**< Internal (set during drawing): Tick index of last tick that falls within + * this section; LV_SCALE_TICK_IDX_DEFAULT_ID if section contains no ticks. */ + int32_t first_tick_in_section_width; /**< Internal (set during drawing) */ + int32_t last_tick_in_section_width; /**< Internal (set during drawing) */ + lv_point_t first_tick_in_section; /**< Internal (set during drawing) */ + lv_point_t last_tick_in_section; /**< Internal (set during drawing) */ + uint32_t first_tick_idx_is_major : 1; /**< Internal (set during drawing): true if + * `first_tick_idx_in_section` represents a major tick. */ + uint32_t last_tick_idx_is_major : 1; /**< Internal (set during drawing): true if + * `last_tick_idx_in_section` represents a major tick. */ }; -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; +struct _lv_scale_t { + lv_obj_t obj; /**< Base Widget part of Scale */ + lv_ll_t section_ll; /**< Linked list for the sections (stores lv_scale_section_t)*/ + const char ** txt_src; /**< Optional list of text strings for major ticks + * when custom labels are provided. */ + lv_scale_mode_t mode; /**< Orientation and layout of scale. */ + int32_t range_min; /**< Scale's minimum value */ + int32_t range_max; /**< Scale's maximum value */ + uint32_t total_tick_count : 15; /**< Total number of ticks (major and minor) */ + uint32_t major_tick_every : 15; /**< Frequency of major ticks to minor ticks */ + uint32_t label_enabled : 1; /**< Draw labels for major ticks? */ + uint32_t post_draw : 1; /**< false: drawing occurs during LV_EVENT_DRAW_MAIN; + * true : drawing occurs during LV_EVENT_DRAW_POST. */ + uint32_t draw_ticks_on_top : 1; /**< Draw ticks on top of main line? */ /* Round scale */ - uint32_t angle_range; - int32_t rotation; + uint32_t angle_range; /**< Degrees between low end and high end of scale */ + int32_t rotation; /**< Clockwise angular offset from 3-o'clock position of low end of scale */ /* Private properties */ - int32_t custom_label_cnt; - int32_t last_tick_width; - int32_t first_tick_width; + int32_t custom_label_cnt; /**< Number of custom labels provided in `txt_src` */ + int32_t last_tick_width; /**< Width of last tick in pixels */ + int32_t first_tick_width; /**< Width of first tick in pixels */ }; 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 e58597c88..7d6e45bbc 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider.c @@ -49,6 +49,52 @@ static void update_knob_pos(lv_obj_t * obj, bool check_drag); /********************** * STATIC VARIABLES **********************/ + +#if LV_USE_OBJ_PROPERTY +static const lv_property_ops_t properties[] = { + { + .id = LV_PROPERTY_SLIDER_VALUE, + .setter = lv_slider_set_value, + .getter = lv_slider_get_value, + }, + { + .id = LV_PROPERTY_SLIDER_LEFT_VALUE, + .setter = lv_slider_set_start_value, + .getter = lv_slider_get_left_value, + }, + { + .id = LV_PROPERTY_SLIDER_RANGE, + .setter = lv_slider_set_range, + .getter = NULL, + }, + { + .id = LV_PROPERTY_SLIDER_MIN_VALUE, + .setter = NULL, + .getter = lv_slider_get_min_value, + }, + { + .id = LV_PROPERTY_SLIDER_MAX_VALUE, + .setter = NULL, + .getter = lv_slider_get_max_value, + }, + { + .id = LV_PROPERTY_SLIDER_MODE, + .setter = lv_slider_set_mode, + .getter = lv_slider_get_mode, + }, + { + .id = LV_PROPERTY_SLIDER_IS_DRAGGED, + .setter = NULL, + .getter = lv_slider_is_dragged, + }, + { + .id = LV_PROPERTY_SLIDER_IS_SYMMETRICAL, + .setter = NULL, + .getter = lv_slider_is_symmetrical, + }, +}; +#endif + const lv_obj_class_t lv_slider_class = { .constructor_cb = lv_slider_constructor, .event_cb = lv_slider_event, @@ -56,7 +102,18 @@ const lv_obj_class_t lv_slider_class = { .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, .instance_size = sizeof(lv_slider_t), .base_class = &lv_bar_class, - .name = "slider", + .name = "lv_slider", +#if LV_USE_OBJ_PROPERTY + .prop_index_start = LV_PROPERTY_SLIDER_START, + .prop_index_end = LV_PROPERTY_SLIDER_END, + .properties = properties, + .properties_count = sizeof(properties) / sizeof(properties[0]), + +#if LV_USE_OBJ_PROPERTY_NAME + .property_names = lv_slider_property_names, + .names_count = sizeof(lv_slider_property_names) / sizeof(lv_property_name_t), +#endif +#endif }; /********************** @@ -88,7 +145,7 @@ 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) +void lv_slider_set_start_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim) { lv_bar_set_start_value(obj, value, anim); } @@ -103,6 +160,11 @@ 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_orientation(lv_obj_t * obj, lv_slider_orientation_t orientation) +{ + lv_bar_set_orientation(obj, (lv_bar_orientation_t)orientation); +} + int32_t lv_slider_get_value(const lv_obj_t * obj) { return lv_bar_get_value(obj); @@ -131,6 +193,14 @@ lv_slider_mode_t lv_slider_get_mode(lv_obj_t * slider) else return LV_SLIDER_MODE_NORMAL; } +lv_slider_orientation_t lv_slider_get_orientation(lv_obj_t * slider) +{ + lv_bar_orientation_t ori = lv_bar_get_orientation(slider); + if(ori == LV_BAR_ORIENTATION_HORIZONTAL) return LV_SLIDER_ORIENTATION_HORIZONTAL; + else if(ori == LV_BAR_ORIENTATION_VERTICAL) return LV_SLIDER_ORIENTATION_VERTICAL; + else return LV_SLIDER_ORIENTATION_AUTO; +} + bool lv_slider_is_symmetrical(lv_obj_t * obj) { return lv_bar_is_symmetrical(obj); @@ -268,11 +338,11 @@ static void lv_slider_event(const lv_obj_class_t * class_p, lv_event_t * e) if(c == LV_KEY_RIGHT || c == LV_KEY_UP) { if(!slider->left_knob_focus) lv_slider_set_value(obj, lv_slider_get_value(obj) + 1, LV_ANIM_ON); - else lv_slider_set_left_value(obj, lv_slider_get_left_value(obj) + 1, LV_ANIM_ON); + else lv_slider_set_start_value(obj, lv_slider_get_left_value(obj) + 1, LV_ANIM_ON); } else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) { if(!slider->left_knob_focus) lv_slider_set_value(obj, lv_slider_get_value(obj) - 1, LV_ANIM_ON); - else lv_slider_set_left_value(obj, lv_slider_get_left_value(obj) - 1, LV_ANIM_ON); + else lv_slider_set_start_value(obj, lv_slider_get_left_value(obj) - 1, LV_ANIM_ON); } else { return; @@ -285,7 +355,7 @@ static void lv_slider_event(const lv_obj_class_t * class_p, lv_event_t * e) int32_t r = lv_event_get_rotary_diff(e); if(!slider->left_knob_focus) lv_slider_set_value(obj, lv_slider_get_value(obj) + r, LV_ANIM_ON); - else lv_slider_set_left_value(obj, lv_slider_get_left_value(obj) + 1, LV_ANIM_ON); + else lv_slider_set_start_value(obj, lv_slider_get_left_value(obj) + 1, LV_ANIM_ON); res = lv_obj_send_event(obj, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RESULT_OK) return; @@ -323,6 +393,7 @@ static void draw_knob(lv_event_t * e) } lv_draw_rect_dsc_t knob_rect_dsc; lv_draw_rect_dsc_init(&knob_rect_dsc); + knob_rect_dsc.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_KNOB, &knob_rect_dsc); /* Update knob area with knob style */ position_knob(obj, &knob_area, knob_size, is_horizontal); @@ -388,7 +459,10 @@ static void position_knob(lv_obj_t * obj, lv_area_t * knob_area, const int32_t k static bool is_slider_horizontal(lv_obj_t * obj) { - return lv_obj_get_width(obj) >= lv_obj_get_height(obj); + lv_slider_t * slider = (lv_slider_t *)obj; + if(slider->bar.orientation == LV_BAR_ORIENTATION_AUTO) return lv_obj_get_width(obj) >= lv_obj_get_height(obj); + else if(slider->bar.orientation == LV_BAR_ORIENTATION_HORIZONTAL) return true; + else return false; } static void drag_start(lv_obj_t * obj) 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 5f08a5c58..1b3892676 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider.h @@ -35,8 +35,27 @@ typedef enum { LV_SLIDER_MODE_RANGE = LV_BAR_MODE_RANGE } lv_slider_mode_t; +typedef enum { + LV_SLIDER_ORIENTATION_AUTO = LV_BAR_ORIENTATION_AUTO, + LV_SLIDER_ORIENTATION_HORIZONTAL = LV_BAR_ORIENTATION_HORIZONTAL, + LV_SLIDER_ORIENTATION_VERTICAL = LV_BAR_ORIENTATION_VERTICAL +} lv_slider_orientation_t; + LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_slider_class; +#if LV_USE_OBJ_PROPERTY +enum { + LV_PROPERTY_ID2(SLIDER, VALUE, LV_PROPERTY_TYPE_INT, LV_PROPERTY_TYPE_BOOL, 0), + LV_PROPERTY_ID2(SLIDER, LEFT_VALUE, LV_PROPERTY_TYPE_INT, LV_PROPERTY_TYPE_BOOL, 1), + LV_PROPERTY_ID2(SLIDER, RANGE, LV_PROPERTY_TYPE_INT, LV_PROPERTY_TYPE_INT, 2), + LV_PROPERTY_ID(SLIDER, MIN_VALUE, LV_PROPERTY_TYPE_INT, 4), + LV_PROPERTY_ID(SLIDER, MAX_VALUE, LV_PROPERTY_TYPE_INT, 5), + LV_PROPERTY_ID(SLIDER, MODE, LV_PROPERTY_TYPE_INT, 6), + LV_PROPERTY_ID(SLIDER, IS_DRAGGED, LV_PROPERTY_TYPE_BOOL, 7), + LV_PROPERTY_ID(SLIDER, IS_SYMMETRICAL, LV_PROPERTY_TYPE_BOOL, 8), + LV_PROPERTY_SLIDER_END, +}; +#endif /********************** * GLOBAL PROTOTYPES **********************/ @@ -66,7 +85,7 @@ void lv_slider_set_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim); * @param value new value * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately */ -void lv_slider_set_left_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim); +void lv_slider_set_start_value(lv_obj_t * obj, int32_t value, lv_anim_enable_t anim); /** * Set minimum and the maximum values of a bar @@ -79,10 +98,17 @@ 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 + * @param mode the mode of the slider. See `lv_slider_mode_t` */ void lv_slider_set_mode(lv_obj_t * obj, lv_slider_mode_t mode); +/** + * Set the orientation of slider. + * @param obj pointer to a slider object + * @param orientation slider orientation from `lv_slider_orientation_t` + */ +void lv_slider_set_orientation(lv_obj_t * obj, lv_slider_orientation_t orientation); + /*===================== * Getter functions *====================*/ @@ -125,10 +151,17 @@ bool lv_slider_is_dragged(const lv_obj_t * obj); /** * Get the mode of the slider. * @param slider pointer to a slider object - * @return see ::lv_slider_mode_t + * @return see `lv_slider_mode_t` */ lv_slider_mode_t lv_slider_get_mode(lv_obj_t * slider); +/** + * Get the orientation of slider. + * @param obj pointer to a slider object + * @return slider orientation from `lv_slider_orientation_t` + */ +lv_slider_orientation_t lv_slider_get_orientation(lv_obj_t * slider); + /** * Give the slider is in symmetrical mode or not * @param obj pointer to slider object 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 index a1eab2f5b..0b4464db6 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/slider/lv_slider_private.h @@ -27,7 +27,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_slider_t { +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; 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 c4afb4373..9583ca647 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.c @@ -15,6 +15,8 @@ #include "../../misc/lv_assert.h" #include "../../misc/lv_text_private.h" +#include "../../misc/lv_bidi_private.h" +#include "../../misc/lv_text_ap.h" #include "../../core/lv_global.h" /********************* @@ -48,13 +50,11 @@ static void lv_spangroup_destructor(const lv_obj_class_t * class_p, lv_obj_t * o static void lv_spangroup_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj); static void lv_spangroup_event(const lv_obj_class_t * class_p, lv_event_t * e); static void draw_main(lv_event_t * e); -static void refresh_self_size(lv_obj_t * obj); static const lv_font_t * lv_span_get_style_text_font(lv_obj_t * par, lv_span_t * span); 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_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); @@ -69,6 +69,9 @@ static void lv_snippet_push(lv_snippet_t * item); static lv_snippet_t * lv_get_snippet(uint32_t index); static int32_t convert_indent_pct(lv_obj_t * spans, int32_t width); +static lv_span_coords_t make_span_coords(const lv_span_t * prev_span, const lv_span_t * curr_span, int32_t width, + lv_area_t padding, int32_t indent); + /********************** * STATIC VARIABLES **********************/ @@ -81,7 +84,7 @@ const lv_obj_class_t lv_spangroup_class = { .instance_size = sizeof(lv_spangroup_t), .width_def = LV_SIZE_CONTENT, .height_def = LV_SIZE_CONTENT, - .name = "span", + .name = "lv_span", }; /********************** @@ -112,7 +115,7 @@ lv_obj_t * lv_spangroup_create(lv_obj_t * par) return obj; } -lv_span_t * lv_spangroup_new_span(lv_obj_t * obj) +lv_span_t * lv_spangroup_add_span(lv_obj_t * obj) { if(obj == NULL) { return NULL; @@ -126,9 +129,8 @@ lv_span_t * lv_spangroup_new_span(lv_obj_t * obj) lv_style_init(&span->style); span->txt = (char *)""; span->static_flag = 1; - span->spangroup = obj; - refresh_self_size(obj); + lv_spangroup_refresh(obj); return span; } @@ -156,7 +158,7 @@ void lv_spangroup_delete_span(lv_obj_t * obj, lv_span_t * span) } } - refresh_self_size(obj); + lv_spangroup_refresh(obj); } /*===================== @@ -169,7 +171,13 @@ void lv_span_set_text(lv_span_t * span, const char * text) return; } - size_t text_alloc_len = lv_strlen(text) + 1; + size_t text_alloc_len = 0; + +#if LV_USE_ARABIC_PERSIAN_CHARS + text_alloc_len = lv_text_ap_calc_bytes_count(text); +#else + text_alloc_len = lv_strlen(text) + 1; +#endif if(span->txt == NULL || span->static_flag == 1) { span->txt = lv_malloc(text_alloc_len); @@ -183,9 +191,18 @@ void lv_span_set_text(lv_span_t * span, const char * text) if(span->txt == NULL) return; span->static_flag = 0; - lv_memcpy(span->txt, text, text_alloc_len); - refresh_self_size(span->spangroup); +#if LV_USE_ARABIC_PERSIAN_CHARS + lv_text_ap_proc(text, span->txt); +#else + lv_memcpy(span->txt, text, text_alloc_len); +#endif +} + +void lv_spangroup_set_span_text(lv_obj_t * obj, lv_span_t * span, const char * text) +{ + lv_span_set_text(span, text); + lv_spangroup_refresh(obj); } void lv_span_set_text_static(lv_span_t * span, const char * text) @@ -199,13 +216,38 @@ void lv_span_set_text_static(lv_span_t * span, const char * text) span->txt = NULL; } span->static_flag = 1; - span->txt = (char *)text; - refresh_self_size(span->spangroup); +#if LV_USE_ARABIC_PERSIAN_CHARS + size_t text_alloc_len = lv_text_ap_calc_bytes_count(text); + span->txt = lv_malloc(text_alloc_len); + LV_ASSERT_MALLOC(span->txt) + lv_text_ap_proc(text, span->txt); + span->static_flag = 0; +#else + span->txt = (char *)text; +#endif +} + +void lv_spangroup_set_span_text_static(lv_obj_t * obj, lv_span_t * span, const char * text) +{ + lv_span_set_text_static(span, text); + lv_spangroup_refresh(obj); +} + +void lv_spangroup_set_span_style(lv_obj_t * obj, lv_span_t * span, const lv_style_t * style) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + LV_ASSERT_NULL(span); + + lv_style_copy(&span->style, style); + + lv_spangroup_refresh(obj); } void lv_spangroup_set_align(lv_obj_t * obj, lv_text_align_t align) { + LV_LOG_WARN("DEPRECATED. Use the text_align style property instead"); + lv_obj_set_style_text_align(obj, align, LV_PART_MAIN); } @@ -227,18 +269,38 @@ void lv_spangroup_set_indent(lv_obj_t * obj, int32_t indent) spans->indent = indent; - refresh_self_size(obj); + lv_spangroup_refresh(obj); } void lv_spangroup_set_mode(lv_obj_t * obj, lv_span_mode_t mode) { + LV_LOG_WARN("DEPRECATED, set the width to LV_SIZE_CONTENT or fixed value to control expanding/wrapping"); LV_ASSERT_OBJ(obj, MY_CLASS); - lv_spangroup_t * spans = (lv_spangroup_t *)obj; if(mode >= LV_SPAN_MODE_LAST) return; - spans->mode = mode; - lv_spangroup_refr_mode(obj); + if(mode == LV_SPAN_MODE_EXPAND) { + lv_obj_set_width(obj, LV_SIZE_CONTENT); + lv_obj_set_height(obj, LV_SIZE_CONTENT); + } + else if(mode == LV_SPAN_MODE_BREAK) { + if(lv_obj_get_style_width(obj, LV_PART_MAIN) == LV_SIZE_CONTENT) { + lv_obj_set_width(obj, 100); + } + lv_obj_set_height(obj, LV_SIZE_CONTENT); + } + else if(mode == LV_SPAN_MODE_FIXED) { + /* use this mode, The user needs to set the size. */ + /* This is just to prevent an infinite loop. */ + if(lv_obj_get_style_width(obj, LV_PART_MAIN) == LV_SIZE_CONTENT) { + lv_obj_set_width(obj, 100); + } + if(lv_obj_get_style_height(obj, LV_PART_MAIN) == LV_SIZE_CONTENT) { + lv_obj_set_content_height(obj, 100); + } + } + + lv_spangroup_refresh(obj); } void lv_spangroup_set_max_lines(lv_obj_t * obj, int32_t lines) @@ -246,7 +308,8 @@ void lv_spangroup_set_max_lines(lv_obj_t * obj, int32_t lines) LV_ASSERT_OBJ(obj, MY_CLASS); lv_spangroup_t * spans = (lv_spangroup_t *)obj; spans->lines = lines; - lv_spangroup_refr_mode(obj); + + lv_spangroup_refresh(obj); } /*===================== @@ -258,6 +321,11 @@ lv_style_t * lv_span_get_style(lv_span_t * span) return &span->style; } +const char * lv_span_get_text(lv_span_t * span) +{ + return span->txt; +} + lv_span_t * lv_spangroup_get_child(const lv_obj_t * obj, int32_t id) { if(obj == NULL) { @@ -330,8 +398,19 @@ int32_t lv_spangroup_get_indent(lv_obj_t * obj) lv_span_mode_t lv_spangroup_get_mode(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); - lv_spangroup_t * spans = (lv_spangroup_t *)obj; - return spans->mode; + + if(lv_obj_get_style_width(obj, LV_PART_MAIN) == LV_SIZE_CONTENT) { + return LV_SPAN_MODE_EXPAND; + } + + /*Width is fixed for the following cases*/ + else if(lv_obj_get_style_height(obj, LV_PART_MAIN) == LV_SIZE_CONTENT) { + return LV_SPAN_MODE_BREAK; + } + /*Both fixed*/ + else { + return LV_SPAN_MODE_FIXED; + } } int32_t lv_spangroup_get_max_lines(lv_obj_t * obj) @@ -341,39 +420,6 @@ int32_t lv_spangroup_get_max_lines(lv_obj_t * obj) return spans->lines; } -void lv_spangroup_refr_mode(lv_obj_t * obj) -{ - LV_ASSERT_OBJ(obj, MY_CLASS); - lv_spangroup_t * spans = (lv_spangroup_t *)obj; - - if(spans->mode == LV_SPAN_MODE_EXPAND) { - lv_obj_set_width(obj, LV_SIZE_CONTENT); - lv_obj_set_height(obj, LV_SIZE_CONTENT); - } - else if(spans->mode == LV_SPAN_MODE_BREAK) { - if(lv_obj_get_style_width(obj, LV_PART_MAIN) == LV_SIZE_CONTENT) { - lv_obj_set_width(obj, 100); - } - lv_obj_set_height(obj, LV_SIZE_CONTENT); - } - else if(spans->mode == LV_SPAN_MODE_FIXED) { - /* use this mode, The user needs to set the size. */ - /* This is just to prevent an infinite loop. */ - if(lv_obj_get_style_width(obj, LV_PART_MAIN) == LV_SIZE_CONTENT) { - lv_obj_set_width(obj, 100); - } - if(lv_obj_get_style_height(obj, LV_PART_MAIN) == LV_SIZE_CONTENT) { - int32_t width = lv_obj_get_style_width(obj, LV_PART_MAIN); - if(LV_COORD_IS_PCT(width)) { - width = 100; - } - int32_t height = lv_spangroup_get_expand_height(obj, width); - lv_obj_set_content_height(obj, height); - } - } - - refresh_self_size(obj); -} int32_t lv_spangroup_get_max_line_height(lv_obj_t * obj) { @@ -451,6 +497,7 @@ int32_t lv_spangroup_get_expand_height(lv_obj_t * obj, int32_t width) lv_snippet_t snippet; /* use to save cur_span info and push it to stack */ lv_memset(&snippet, 0, sizeof(snippet)); + lv_span_t * prev_span = cur_span; int32_t line_cnt = 0; int32_t lines = spans->lines < 0 ? INT32_MAX : spans->lines; /* the loop control how many lines need to draw */ @@ -462,6 +509,8 @@ 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->trailing_pos = txt_pos; + cur_span = lv_ll_get_next(&spans->child_ll, cur_span); if(cur_span == NULL) break; cur_txt = cur_span->txt; @@ -484,6 +533,8 @@ int32_t lv_spangroup_get_expand_height(lv_obj_t * obj, int32_t width) int32_t use_width = 0; bool isfill = lv_text_get_snippet(&cur_txt[cur_txt_ofs], snippet.font, snippet.letter_space, max_w, txt_flag, &use_width, &next_ofs); + if(isfill) txt_pos.x = 0; + else txt_pos.x += use_width; /* break word deal width */ if(isfill && next_ofs > 0 && snippet_cnt > 0) { @@ -521,8 +572,16 @@ int32_t lv_spangroup_get_expand_height(lv_obj_t * obj, int32_t width) } /* next line init */ - txt_pos.x = 0; txt_pos.y += max_line_h; + + /* iterate all the spans in the current line and set the trailing height to the max line height */ + for(lv_span_t * tmp_span = prev_span; + tmp_span && tmp_span != cur_span; + tmp_span = lv_ll_get_next(&spans->child_ll, tmp_span)) + tmp_span->trailing_height = max_line_h; + + prev_span = cur_span; + max_w = max_width; line_cnt += 1; if(line_cnt >= lines) { @@ -534,6 +593,86 @@ int32_t lv_spangroup_get_expand_height(lv_obj_t * obj, int32_t width) return txt_pos.y; } +lv_span_coords_t lv_spangroup_get_span_coords(lv_obj_t * obj, const lv_span_t * span) +{ + if(obj == NULL) return (lv_span_coords_t) { + 0 + }; + + /* find previous span */ + const lv_spangroup_t * spangroup = (lv_spangroup_t *)obj; + const lv_ll_t * spans = &spangroup->child_ll; + const int32_t width = lv_obj_get_content_width(obj); + const int32_t indent = lv_spangroup_get_indent(obj); + + if(span == NULL || lv_ll_get_head(spans) == NULL) return (lv_span_coords_t) { + 0 + }; + + lv_span_t * prev_span = NULL; + lv_span_t * curr_span; + LV_LL_READ(spans, curr_span) { + if(curr_span == span) break; + prev_span = curr_span; + } + + const uint32_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN); + return make_span_coords(prev_span, curr_span, width, (lv_area_t) { + .x1 = lv_obj_get_style_pad_left(obj, LV_PART_MAIN) + border_width, + .y1 = lv_obj_get_style_pad_top(obj, LV_PART_MAIN) + border_width, + .x2 = lv_obj_get_style_pad_right(obj, LV_PART_MAIN) + border_width, .y2 = 0 + }, + indent); +} + +lv_span_t * lv_spangroup_get_span_by_point(lv_obj_t * obj, const lv_point_t * p) +{ + const lv_spangroup_t * spangroup = (lv_spangroup_t *)obj; + const lv_ll_t * spans = &spangroup->child_ll; + const int32_t width = lv_obj_get_content_width(obj); + const int32_t indent = lv_spangroup_get_indent(obj); + + if(obj == NULL || p == NULL || lv_ll_get_head(spans) == NULL) return NULL; + + lv_point_t point; + point.x = p->x - obj->coords.x1; + point.y = p->y - obj->coords.y1; + + /* find previous span */ + + const lv_span_t * prev_span = NULL; + lv_span_t * curr_span; + LV_LL_READ(spans, curr_span) { + lv_span_coords_t coords = make_span_coords(prev_span, curr_span, width, (lv_area_t) { + .x1 = lv_obj_get_style_pad_left(obj, LV_PART_MAIN), + .y1 = lv_obj_get_style_pad_top(obj, LV_PART_MAIN), + .x2 = lv_obj_get_style_pad_right(obj, LV_PART_MAIN), + .y2 = 0 + }, + indent); + if(lv_area_is_point_on(&coords.heading, &point, 0) || + lv_area_is_point_on(&coords.middle, &point, 0) || + lv_area_is_point_on(&coords.trailing, &point, 0)) { + return curr_span; + } + prev_span = curr_span; + } + return NULL; +} + + +/*===================== + * Other functions + *====================*/ + +void lv_spangroup_refresh(lv_obj_t * obj) +{ + lv_spangroup_t * spans = (lv_spangroup_t *)obj; + spans->refresh = 1; + lv_obj_invalidate(obj); + lv_obj_refresh_self_size(obj); +} + /********************** * STATIC FUNCTIONS **********************/ @@ -545,7 +684,6 @@ static void lv_spangroup_constructor(const lv_obj_class_t * class_p, lv_obj_t * lv_ll_init(&spans->child_ll, sizeof(lv_span_t)); spans->indent = 0; spans->lines = -1; - spans->mode = LV_SPAN_MODE_EXPAND; spans->overflow = LV_SPAN_OVERFLOW_CLIP; spans->cache_w = 0; spans->cache_h = 0; @@ -584,17 +722,18 @@ static void lv_spangroup_event(const lv_obj_class_t * class_p, lv_event_t * e) draw_main(e); } else if(code == LV_EVENT_STYLE_CHANGED) { - refresh_self_size(obj); + lv_spangroup_refresh(obj); } else if(code == LV_EVENT_SIZE_CHANGED) { - refresh_self_size(obj); + lv_spangroup_refresh(obj); } else if(code == LV_EVENT_GET_SELF_SIZE) { int32_t width = 0; int32_t height = 0; lv_point_t * self_size = lv_event_get_param(e); - if(spans->mode == LV_SPAN_MODE_EXPAND) { + lv_span_mode_t mode = lv_spangroup_get_mode(obj); + if(mode == LV_SPAN_MODE_EXPAND) { if(spans->refresh) { spans->cache_w = (int32_t)lv_spangroup_get_expand_width(obj, 0); spans->cache_h = lv_spangroup_get_max_line_height(obj); @@ -603,7 +742,7 @@ static void lv_spangroup_event(const lv_obj_class_t * class_p, lv_event_t * e) width = spans->cache_w; height = spans->cache_h; } - else if(spans->mode == LV_SPAN_MODE_BREAK) { + else if(mode == LV_SPAN_MODE_BREAK) { width = lv_obj_get_content_width(obj); if(self_size->y >= 0) { if(width != spans->cache_w || spans->refresh) { @@ -617,7 +756,7 @@ static void lv_spangroup_event(const lv_obj_class_t * class_p, lv_event_t * e) } } } - else if(spans->mode == LV_SPAN_MODE_FIXED) { + else if(mode == LV_SPAN_MODE_FIXED) { width = self_size->x >= 0 ? lv_obj_get_content_width(obj) : 0; height = self_size->y >= 0 ? lv_obj_get_content_height(obj) : 0; } @@ -654,7 +793,7 @@ 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, LV_TEXT_LEN_MAX, font, letter_space, real_max_width, use_width, flag); *end_ofs = ofs; if(txt[ofs] == '\0' && *use_width < max_width && !(ofs && (txt[ofs - 1] == '\n' || txt[ofs - 1] == '\r'))) { @@ -744,20 +883,6 @@ static lv_opa_t lv_span_get_style_text_opa(lv_obj_t * par, lv_span_t * span) return opa; } -static lv_blend_mode_t lv_span_get_style_text_blend_mode(lv_obj_t * par, lv_span_t * span) -{ - lv_blend_mode_t mode; - lv_style_value_t value; - 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 { - mode = (lv_blend_mode_t)value.num; - } - return mode; -} - static int32_t lv_span_get_style_text_decor(lv_obj_t * par, lv_span_t * span) { int32_t decor; @@ -786,7 +911,7 @@ static int32_t convert_indent_pct(lv_obj_t * obj, int32_t width) int32_t indent = spans->indent; if(LV_COORD_IS_PCT(spans->indent)) { - if(spans->mode == LV_SPAN_MODE_EXPAND) { + if(lv_spangroup_get_mode(obj) == LV_SPAN_MODE_EXPAND) { indent = 0; } else { @@ -838,6 +963,28 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) lv_span_t * cur_span = lv_ll_get_head(&spans->child_ll); const char * cur_txt = cur_span->txt; span_text_check(&cur_txt); + + lv_text_align_t align = lv_obj_get_style_text_align(obj, LV_PART_MAIN); +#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(cur_txt) == LV_BASE_DIR_RTL ? LV_BASE_DIR_RTL : LV_BASE_DIR_AUTO; + } + + while(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); + + if(base_dir == LV_BASE_DIR_AUTO) { + base_dir = lv_bidi_detect_base_dir(cur_txt) == LV_BASE_DIR_RTL ? LV_BASE_DIR_RTL : LV_BASE_DIR_AUTO; + } + } + cur_span = lv_ll_get_head(&spans->child_ll); + cur_txt = cur_span->txt; +#endif + uint32_t cur_txt_ofs = 0; lv_snippet_t snippet; /* use to save cur_span info and push it to stack */ lv_memzero(&snippet, sizeof(snippet)); @@ -934,16 +1081,11 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) 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); - if(next_span) { /* have the next line */ + if(next_span && next_span->txt && next_span->txt[0]) { /* have the next line */ next_line_h = lv_font_get_line_height(lv_span_get_style_text_font(obj, next_span)) + line_space; } } if(txt_pos.y + max_line_h + next_line_h - line_space > coords.y2 + 1) { /* for overflow if is end line. */ - if(last_snippet->txt[last_snippet->bytes] != '\0') { - last_snippet->bytes = lv_strlen(last_snippet->txt); - last_snippet->txt_w = lv_text_get_width(last_snippet->txt, last_snippet->bytes, last_snippet->font, - last_snippet->letter_space); - } ellipsis_valid = spans->overflow == LV_SPAN_OVERFLOW_ELLIPSIS; is_end_line = true; } @@ -955,30 +1097,75 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) } /* align deal with */ - lv_text_align_t align = lv_obj_get_style_text_align(obj, LV_PART_MAIN); +#if LV_USE_BIDI + if(base_dir == LV_BASE_DIR_AUTO) { + base_dir = LV_BASE_DIR_LTR; + } + + if(align == LV_TEXT_ALIGN_AUTO) { + if(base_dir == LV_BASE_DIR_RTL) align = LV_TEXT_ALIGN_RIGHT; + else align = LV_TEXT_ALIGN_LEFT; + } +#endif + int32_t align_ofs = 0; + int32_t txts_w = is_first_line ? indent : 0; + uint32_t i_item; + for(i_item = 0; i_item < item_cnt; i_item++) { + lv_snippet_t * pinfo = lv_get_snippet(i_item); + if(ellipsis_valid && i_item == item_cnt - 1) { + uint32_t n_ofs = 0; + lv_text_get_snippet(pinfo->txt, pinfo->font, pinfo->letter_space, max_width - txts_w, + LV_TEXT_FLAG_BREAK_ALL, &pinfo->txt_w, &n_ofs); + pinfo->bytes = n_ofs; + } + 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; + if(align == LV_TEXT_ALIGN_CENTER) { + align_ofs = align_ofs >> 1; + } if(align == LV_TEXT_ALIGN_CENTER || align == LV_TEXT_ALIGN_RIGHT) { - int32_t align_ofs = 0; - int32_t txts_w = is_first_line ? indent : 0; - 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; - } - txts_w -= lv_get_snippet(item_cnt - 1)->letter_space; - align_ofs = max_width > txts_w ? max_width - txts_w : 0; - if(align == LV_TEXT_ALIGN_CENTER) { - align_ofs = align_ofs >> 1; - } txt_pos.x += align_ofs; } +#if LV_USE_BIDI + int32_t first_txt_pos_x = txt_pos.x; + bool is_draw_rtl = false; + lv_snippet_t * pinfo0 = lv_get_snippet(0); + lv_base_dir_t bidi_dir = lv_bidi_detect_base_dir(pinfo0->txt); + if(bidi_dir == LV_BASE_DIR_RTL && base_dir == LV_BASE_DIR_RTL) { + is_draw_rtl = true; + if(align == LV_TEXT_ALIGN_LEFT || align == LV_TEXT_ALIGN_CENTER) { + txt_pos.x = coords.x2 - align_ofs; + } + else if(align == LV_TEXT_ALIGN_RIGHT) { + txt_pos.x = coords.x2; + } + } +#endif /* draw line letters */ uint32_t i; for(i = 0; i < item_cnt; i++) { lv_snippet_t * pinfo = lv_get_snippet(i); - /* bidi deal with:todo */ +#if LV_USE_BIDI + char * bidi_txt; + if(base_dir == LV_BASE_DIR_RTL) { + bidi_txt = lv_malloc(pinfo->bytes + 1); + LV_ASSERT_MALLOC(bidi_txt); + lv_memcpy(bidi_txt, pinfo->txt, (size_t)pinfo->bytes); + label_draw_dsc.bidi_dir = base_dir; + label_draw_dsc.has_bided = true; + label_draw_dsc.text_local = true; + lv_bidi_process_paragraph(pinfo->txt, bidi_txt, pinfo->bytes, label_draw_dsc.bidi_dir, NULL, 0); + } + else { + bidi_txt = (char *)pinfo->txt; + } +#else const char * bidi_txt = pinfo->txt; +#endif lv_point_t pos; pos.x = txt_pos.x; @@ -986,82 +1173,104 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer) label_draw_dsc.color = lv_span_get_style_text_color(obj, pinfo->span); label_draw_dsc.opa = lv_span_get_style_text_opa(obj, pinfo->span); label_draw_dsc.font = lv_span_get_style_text_font(obj, pinfo->span); - label_draw_dsc.blend_mode = lv_span_get_style_text_blend_mode(obj, pinfo->span); if(obj_opa < LV_OPA_MAX) { label_draw_dsc.opa = LV_OPA_MIX2(label_draw_dsc.opa, obj_opa); } uint32_t txt_bytes = pinfo->bytes; - /* overflow */ - uint32_t dot_letter_w = 0; - uint32_t dot_width = 0; - if(ellipsis_valid) { - dot_letter_w = lv_font_get_glyph_width(pinfo->font, '.', '.'); - dot_width = dot_letter_w * 3; + if(pos.x > clip_area.x2) { + continue; } - int32_t ellipsis_width = coords.x1 + max_width - dot_width; - uint32_t j = 0; - while(j < txt_bytes) { - /* skip invalid fields */ - if(pos.x > clip_area.x2) { - break; + label_draw_dsc.text = bidi_txt; + label_draw_dsc.text_length = txt_bytes; + label_draw_dsc.letter_space = pinfo->letter_space; + label_draw_dsc.decor = lv_span_get_style_text_decor(obj, pinfo->span); + lv_area_t a; + a.x1 = pos.x; + a.y1 = pos.y; + a.x2 = a.x1 + pinfo->txt_w; + a.y2 = a.y1 + pinfo->line_h; + +#if LV_USE_BIDI + if(is_draw_rtl) { + a.x1 = pos.x - pinfo->txt_w; + a.x2 = pos.x; + } +#endif + + bool need_draw_ellipsis = false; + uint32_t dot_width = 0; + /* deal overflow */ + if(ellipsis_valid) { + uint32_t dot_letter_w = lv_font_get_glyph_width(pinfo->font, '.', '.'); + dot_width = dot_letter_w * 3; + + label_draw_dsc.flag = LV_TEXT_FLAG_BREAK_ALL; + uint32_t next_ofs; + need_draw_ellipsis = lv_text_get_snippet(pinfo->txt, pinfo->font, pinfo->letter_space, coords.x2 - a.x1 - dot_width, + label_draw_dsc.flag, &pinfo->txt_w, &next_ofs); + a.x2 = a.x1 + pinfo->txt_w; + label_draw_dsc.text_length = next_ofs + 1; +#if LV_USE_BIDI + if(base_dir == LV_BASE_DIR_RTL) { + if(txt_bytes > label_draw_dsc.text_length) { + char * tmp_txt = lv_malloc(label_draw_dsc.text_length + 1); + LV_ASSERT_MALLOC(tmp_txt); + + if(lv_bidi_detect_base_dir(bidi_txt) == LV_BASE_DIR_RTL) { + lv_memcpy(tmp_txt, bidi_txt + (txt_bytes - label_draw_dsc.text_length), (size_t)label_draw_dsc.text_length); + } + else { + lv_memcpy(tmp_txt, bidi_txt, (size_t)label_draw_dsc.text_length); + } + + label_draw_dsc.text = tmp_txt; + lv_free(bidi_txt); + } + if(i == 0) { + a.x1 = a.x1 + dot_width; + a.x2 = a.x2 + dot_width; + } } - 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); +#endif + } - /* skip invalid fields */ - if(pos.x + letter_w + pinfo->letter_space < clip_area.x1) { - if(letter_w > 0) { - pos.x = pos.x + letter_w + pinfo->letter_space; - } - continue; - } + lv_draw_label(layer, &label_draw_dsc, &a); +#if LV_USE_BIDI + if(label_draw_dsc.has_bided) { + lv_free((void *)label_draw_dsc.text); + } +#endif - if(ellipsis_valid && pos.x + letter_w + pinfo->letter_space > ellipsis_width) { - for(int ell = 0; ell < 3; ell++) { - lv_draw_character(layer, &label_draw_dsc, &pos, '.'); - pos.x = pos.x + dot_letter_w + pinfo->letter_space; - } - if(pos.x <= ellipsis_width) { - pos.x = ellipsis_width + 1; - } - break; + if(need_draw_ellipsis) { + label_draw_dsc.text = "..."; + +#if LV_USE_BIDI + if(label_draw_dsc.bidi_dir == LV_BASE_DIR_RTL) { + a.x1 = first_txt_pos_x; + a.x2 = a.x1 + dot_width; } else { - lv_draw_character(layer, &label_draw_dsc, &pos, letter); - if(letter_w > 0) { - pos.x = pos.x + letter_w + pinfo->letter_space; - } + a.x1 = a.x2; + a.x2 = a.x1 + dot_width; } + label_draw_dsc.text_local = false; +#else + a.x1 = a.x2; + a.x2 = a.x1 + dot_width; +#endif + + lv_draw_label(layer, &label_draw_dsc, &a); } - /* draw decor */ - lv_text_decor_t decor = lv_span_get_style_text_decor(obj, pinfo->span); - if(decor != LV_TEXT_DECOR_NONE) { - lv_draw_line_dsc_t line_dsc; - lv_draw_line_dsc_init(&line_dsc); - line_dsc.color = label_draw_dsc.color; - line_dsc.width = label_draw_dsc.font->underline_thickness ? pinfo->font->underline_thickness : 1; - line_dsc.opa = label_draw_dsc.opa; - line_dsc.blend_mode = label_draw_dsc.blend_mode; + txt_pos.x = a.x2; - if(decor & LV_TEXT_DECOR_STRIKETHROUGH) { - int32_t y = pos.y + ((pinfo->line_h - line_space) >> 1) + (line_dsc.width >> 1); - lv_point_precise_set(&line_dsc.p1, txt_pos.x, y); - lv_point_precise_set(&line_dsc.p2, pos.x, y); - lv_draw_line(layer, &line_dsc); - } - - if(decor & LV_TEXT_DECOR_UNDERLINE) { - int32_t y = pos.y + pinfo->line_h - line_space - pinfo->font->base_line - pinfo->font->underline_position; - lv_point_precise_set(&line_dsc.p1, txt_pos.x, y); - lv_point_precise_set(&line_dsc.p2, pos.x, y); - lv_draw_line(layer, &line_dsc); - } +#if LV_USE_BIDI + if(is_draw_rtl) { + txt_pos.x = a.x1; } - txt_pos.x = pos.x; +#endif } Next_line_init: @@ -1078,12 +1287,52 @@ Next_line_init: layer->_clip_area = clip_area_ori; } -static void refresh_self_size(lv_obj_t * obj) +static lv_span_coords_t make_span_coords(const lv_span_t * prev_span, const lv_span_t * curr_span, const int32_t width, + const lv_area_t padding, const int32_t indent) { - lv_spangroup_t * spans = (lv_spangroup_t *)obj; - spans->refresh = 1; - lv_obj_invalidate(obj); - lv_obj_refresh_self_size(obj); + lv_span_coords_t coords = { 0 }; + + if(curr_span == NULL) return coords; + + /* first line */ + if(prev_span == NULL) { + lv_area_set(&coords.heading, padding.x1 + indent, padding.y1, width + padding.x1, + curr_span->trailing_pos.y + padding.y1); + lv_area_set(&coords.middle, coords.heading.x1, coords.heading.y2, curr_span->trailing_pos.x + padding.x1, + coords.heading.y2 + curr_span->trailing_height); + lv_area_set(&coords.trailing, 0, 0, 0, 0); + + return coords; + } + + /* start and end on the same line */ + const bool is_same_line = prev_span->trailing_pos.y == curr_span->trailing_pos.y; + if(is_same_line == true) { + lv_area_set(&coords.heading, + prev_span->trailing_pos.x + padding.x1, prev_span->trailing_pos.y + padding.y1, + curr_span->trailing_pos.x + padding.x1, curr_span->trailing_pos.y + curr_span->trailing_height + padding.y1); + return coords; + } + + /* common case */ + const lv_point_t pre_trailing_pos = prev_span->trailing_pos; + const int32_t pre_trailing_height = prev_span->trailing_height; + + lv_area_set(&coords.heading, + pre_trailing_pos.x + padding.x1, pre_trailing_pos.y + padding.y1, + width + padding.x1, pre_trailing_pos.y + pre_trailing_height + padding.y1); + /* When it happens to be two lines of text, + * the y2 of the middle area is exactly the y1 + line height of the first line of text, + * so the area of the middle area is empty. + * */ + lv_area_set(&coords.middle, + padding.x1, coords.heading.y2, + width + padding.x1, curr_span->trailing_pos.y + padding.y1); + lv_area_set(&coords.trailing, + coords.middle.x1, coords.middle.y2, + curr_span->trailing_pos.x + padding.x1, curr_span->trailing_pos.y + curr_span->trailing_height + padding.y1); + + return coords; } #endif 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 f0406b918..ff6fd310f 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span.h @@ -41,6 +41,13 @@ typedef enum { LV_SPAN_MODE_LAST /**< Fence member */ } lv_span_mode_t; +/** Coords of a span */ +typedef struct _lv_span_coords_t { + lv_area_t heading; + lv_area_t middle; + lv_area_t trailing; +} lv_span_coords_t; + LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_spangroup_class; /********************** @@ -62,7 +69,7 @@ lv_obj_t * lv_spangroup_create(lv_obj_t * parent); * @param obj pointer to a spangroup object. * @return pointer to the created span. */ -lv_span_t * lv_spangroup_new_span(lv_obj_t * obj); +lv_span_t * lv_spangroup_add_span(lv_obj_t * obj); /** * Remove the span from the spangroup and free memory. @@ -77,11 +84,40 @@ void lv_spangroup_delete_span(lv_obj_t * obj, lv_span_t * span); /** * Set a new text for a span. Memory will be allocated to store the text by the span. + * As the spangroup is not passed a redraw (invalidation) can't be triggered automatically. + * Therefore `lv_spangroup_refresh(spangroup)` needs to be called manually, * @param span pointer to a span. * @param text pointer to a text. */ void lv_span_set_text(lv_span_t * span, const char * text); +/** + * Set a static text. It will not be saved by the span so the 'text' variable + * has to be 'alive' while the span exist. + * As the spangroup is not passed a redraw (invalidation) can't be triggered automatically. + * Therefore `lv_spangroup_refresh(spangroup)` needs to be called manually, + * + * @param span pointer to a span. + * @param text pointer to a text. + */ +void lv_span_set_text_static(lv_span_t * span, const char * text); + +/** + * Set a new text for a span. Memory will be allocated to store the text by the span. + * @param obj pointer to a spangroup widget. + * @param span pointer to a span. + * @param text pointer to a text. + */ +void lv_spangroup_set_span_text(lv_obj_t * obj, lv_span_t * span, const char * text); + +/** + * Set a new text for a span. Memory will be allocated to store the text by the span. + * @param obj pointer to a spangroup widget. + * @param span pointer to a span. + * @param text pointer to a text. + */ +void lv_spangroup_set_span_text_static(lv_obj_t * obj, lv_span_t * span, const char * text); + /** * Set a static text. It will not be saved by the span so the 'text' variable * has to be 'alive' while the span exist. @@ -91,6 +127,15 @@ void lv_span_set_text(lv_span_t * span, const char * text); void lv_span_set_text_static(lv_span_t * span, const char * text); /** + * Copy all style properties of style to the bbuilt-in static style of the span. + * @param obj pointer_to a spangroup + * @param span pointer to a span. + * @param style pointer to a style to copy into the span's built-in style + */ +void lv_spangroup_set_span_style(lv_obj_t * obj, lv_span_t * span, const lv_style_t * style); + +/** + * DEPRECATED. Use the text_align style property instead * Set the align of the spangroup. * @param obj pointer to a spangroup object. * @param align see lv_text_align_t for details. @@ -112,6 +157,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); /** + * DEPRECATED, set the width to LV_SIZE_CONTENT or fixed value to control expanding/wrapping" * Set the mode of the spangroup. * @param obj pointer to a spangroup object. * @param mode see lv_span_mode_t for details. @@ -130,12 +176,20 @@ void lv_spangroup_set_max_lines(lv_obj_t * obj, int32_t lines); *====================*/ /** - * Get a pointer to the style of a span + * Get a pointer to the style of a span's built-in style. + * Any lv_style_set_... functions can be applied on the returned style. * @param span pointer to the span - * @return pointer to the style. valid as long as the span is valid -*/ + * @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 pointer to the text of a span + * @param span pointer to the span + * @return pointer to the text +*/ +const char * lv_span_get_text(lv_span_t * span); + /** * Get a spangroup child by its index. * @@ -214,6 +268,39 @@ uint32_t lv_spangroup_get_expand_width(lv_obj_t * obj, uint32_t max_width); */ int32_t lv_spangroup_get_expand_height(lv_obj_t * obj, int32_t width); +/** + * Get the span's coords in the spangroup. + * @note Before calling this function, please make sure that the layout of span group has been updated. + * Like calling lv_obj_update_layout() like function. + * + * +--------+ + * |Heading +--->------------------+ + * | Pos | | Heading | + * +--------+---+------------------+ + * | | + * | | + * | | + * | Middle +--------+| + * | |Trailing|| + * | +-| Pos || + * | | +--------+| + * +-------------------v-----------+ + * | Trailing | + * +-------------------+ + * @param obj pointer to a spangroup object. + * @param span pointer to a span. + * @return the span's coords in the spangroup. + */ +lv_span_coords_t lv_spangroup_get_span_coords(lv_obj_t * obj, const lv_span_t * span); + +/** + * Get the span object by point. + * @param obj pointer to a spangroup object. + * @param point pointer to point containing absolute coordinates + * @return pointer to the span under the point or `NULL` if not found. + */ +lv_span_t * lv_spangroup_get_span_by_point(lv_obj_t * obj, const lv_point_t * point); + /*===================== * Other functions *====================*/ @@ -222,7 +309,7 @@ int32_t lv_spangroup_get_expand_height(lv_obj_t * obj, int32_t width); * Update the mode of the spangroup. * @param obj pointer to a spangroup object. */ -void lv_spangroup_refr_mode(lv_obj_t * obj); +void lv_spangroup_refresh(lv_obj_t * obj); /********************** * MACROS 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 index 099ea1b7e..3a8201319 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/span/lv_span_private.h @@ -27,22 +27,23 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_span_t { +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 */ + + lv_point_t trailing_pos; + int32_t trailing_height; }; /** Data of label*/ -struct lv_spangroup_t { +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 */ }; 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 69e8d13da..231992053 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox.c @@ -43,7 +43,7 @@ const lv_obj_class_t lv_spinbox_class = { .instance_size = sizeof(lv_spinbox_t), .editable = LV_OBJ_CLASS_EDITABLE_TRUE, .base_class = &lv_textarea_class, - .name = "spinbox", + .name = "lv_spinbox", }; /********************** * MACROS 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 index 0569f2103..333bd5061 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/spinbox/lv_spinbox_private.h @@ -28,7 +28,7 @@ extern "C" { **********************/ /** Data of spinbox */ -struct lv_spinbox_t { +struct _lv_spinbox_t { lv_textarea_t ta; /**< Ext. of ancestor */ /*New data for this type*/ int32_t value; 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 18cb0050f..a1a3fe5e1 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/spinner/lv_spinner.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/spinner/lv_spinner.c @@ -34,7 +34,7 @@ static void arc_anim_end_angle(void * obj, int32_t v); const lv_obj_class_t lv_spinner_class = { .base_class = &lv_arc_class, .constructor_cb = lv_spinner_constructor, - .name = "spinner", + .name = "lv_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 89b4b6363..bfbb3a399 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch.c @@ -49,6 +49,7 @@ static void draw_main(lv_event_t * e); static void lv_switch_anim_exec_cb(void * sw, int32_t value); static void lv_switch_trigger_anim(lv_obj_t * obj); static void lv_switch_anim_completed(lv_anim_t * a); + /********************** * STATIC VARIABLES **********************/ @@ -61,7 +62,7 @@ const lv_obj_class_t lv_switch_class = { .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, .instance_size = sizeof(lv_switch_t), .base_class = &lv_obj_class, - .name = "switch", + .name = "lv_switch", }; /********************** @@ -80,6 +81,31 @@ lv_obj_t * lv_switch_create(lv_obj_t * parent) return obj; } +/*===================== + * Setter functions + *====================*/ + +void lv_switch_set_orientation(lv_obj_t * obj, lv_switch_orientation_t orientation) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_switch_t * sw = (lv_switch_t *)obj; + + sw->orientation = orientation; + lv_obj_invalidate(obj); +} + +/*===================== + * Getter functions + *====================*/ + +lv_switch_orientation_t lv_switch_get_orientation(lv_obj_t * obj) +{ + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_switch_t * sw = (lv_switch_t *)obj; + + return sw->orientation; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -92,6 +118,7 @@ static void lv_switch_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj lv_switch_t * sw = (lv_switch_t *)obj; sw->anim_state = LV_SWITCH_ANIM_STATE_INV; + sw->orientation = LV_SWITCH_ORIENTATION_AUTO; lv_obj_remove_flag(obj, LV_OBJ_FLAG_SCROLLABLE); lv_obj_add_flag(obj, LV_OBJ_FLAG_CHECKABLE); @@ -159,32 +186,72 @@ static void draw_main(lv_event_t * e) lv_draw_rect_dsc_t draw_indic_dsc; lv_draw_rect_dsc_init(&draw_indic_dsc); + draw_indic_dsc.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_INDICATOR, &draw_indic_dsc); lv_draw_rect(layer, &draw_indic_dsc, &indic_area); /*Draw the knob*/ - int32_t anim_value_x = 0; - int32_t knob_size = lv_obj_get_height(obj); - int32_t anim_length = lv_area_get_width(&obj->coords) - knob_size; - - if(LV_SWITCH_IS_ANIMATING(sw)) { - /* Use the animation's coordinate */ - anim_value_x = (anim_length * sw->anim_state) / LV_SWITCH_ANIM_STATE_END; - } - else { - /* Use LV_STATE_CHECKED to decide the coordinate */ - bool chk = lv_obj_get_state(obj) & LV_STATE_CHECKED; - anim_value_x = chk ? anim_length : 0; - } - - if(LV_BASE_DIR_RTL == lv_obj_get_style_base_dir(obj, LV_PART_MAIN)) { - anim_value_x = anim_length - anim_value_x; - } - lv_area_t knob_area; lv_area_copy(&knob_area, &obj->coords); - knob_area.x1 += anim_value_x; - knob_area.x2 = knob_area.x1 + (knob_size > 0 ? knob_size - 1 : 0); + + int32_t switch_w = lv_area_get_width(&obj->coords); + int32_t switch_h = lv_area_get_height(&obj->coords); + bool hor = false; + + switch(sw->orientation) { + case LV_SWITCH_ORIENTATION_HORIZONTAL: + hor = true; + break; + case LV_SWITCH_ORIENTATION_VERTICAL: + hor = false; + break; + case LV_SWITCH_ORIENTATION_AUTO: + default: + hor = (switch_w >= switch_h); + break; + } + + if(hor) { + int32_t anim_value_x = 0; + int32_t knob_size = lv_obj_get_height(obj); + int32_t anim_length = lv_area_get_width(&obj->coords) - knob_size; + if(LV_SWITCH_IS_ANIMATING(sw)) { + /* Use the animation's coordinate */ + anim_value_x = (anim_length * sw->anim_state) / LV_SWITCH_ANIM_STATE_END; + } + else { + /* Use LV_STATE_CHECKED to decide the coordinate */ + bool chk = lv_obj_get_state(obj) & LV_STATE_CHECKED; + anim_value_x = chk ? anim_length : 0; + } + + if(LV_BASE_DIR_RTL == lv_obj_get_style_base_dir(obj, LV_PART_MAIN)) { + anim_value_x = anim_length - anim_value_x; + } + knob_area.x1 += anim_value_x; + knob_area.x2 = knob_area.x1 + (knob_size > 0 ? knob_size - 1 : 0); + } + else { + int32_t anim_value_y = 0; + int32_t knob_size = lv_obj_get_width(obj); + int32_t anim_length = lv_area_get_height(&obj->coords) - knob_size; + if(LV_SWITCH_IS_ANIMATING(sw)) { + /* Use the animation's coordinate */ + anim_value_y = (anim_length * sw->anim_state) / LV_SWITCH_ANIM_STATE_END; + } + else { + /* Use LV_STATE_CHECKED to decide the coordinate */ + bool chk = lv_obj_get_state(obj) & LV_STATE_CHECKED; + anim_value_y = chk ? anim_length : 0; + } + + if(LV_BASE_DIR_RTL == lv_obj_get_style_base_dir(obj, LV_PART_MAIN)) { + anim_value_y = anim_length - anim_value_y; + } + + knob_area.y2 -= anim_value_y; + knob_area.y1 = knob_area.y2 - (knob_size > 0 ? knob_size - 1 : 0); + } int32_t knob_left = lv_obj_get_style_pad_left(obj, LV_PART_KNOB); int32_t knob_right = lv_obj_get_style_pad_right(obj, LV_PART_KNOB); @@ -199,6 +266,7 @@ static void draw_main(lv_event_t * e) lv_draw_rect_dsc_t knob_rect_dsc; lv_draw_rect_dsc_init(&knob_rect_dsc); + knob_rect_dsc.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_KNOB, &knob_rect_dsc); lv_draw_rect(layer, &knob_rect_dsc, &knob_area); 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 989a3dd1b..3cc0d2846 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch.h @@ -28,6 +28,16 @@ extern "C" { LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_switch_class; +/********************** + * TYPEDEFS + **********************/ + +typedef enum { + LV_SWITCH_ORIENTATION_AUTO, + LV_SWITCH_ORIENTATION_HORIZONTAL, + LV_SWITCH_ORIENTATION_VERTICAL +} lv_switch_orientation_t; + /********************** * GLOBAL PROTOTYPES **********************/ @@ -39,6 +49,28 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_switch_class; */ lv_obj_t * lv_switch_create(lv_obj_t * parent); +/*===================== + * Setter functions + *====================*/ + +/** + * Set the orientation of switch. + * @param obj pointer to switch object + * @param orientation switch orientation from `lv_switch_orientation_t` + */ +void lv_switch_set_orientation(lv_obj_t * obj, lv_switch_orientation_t orientation); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the orientation of switch. + * @param obj pointer to switch object + * @return switch orientation from ::lv_switch_orientation_t + */ +lv_switch_orientation_t lv_switch_get_orientation(lv_obj_t * obj); + /********************** * MACROS **********************/ 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 index 7bc25763c..66e90d324 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/switch/lv_switch_private.h @@ -31,9 +31,10 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_switch_t { +struct _lv_switch_t { lv_obj_t obj; int32_t anim_state; + lv_switch_orientation_t orientation : 3; /**< Orientation of switch*/ }; 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 affb99b88..379bde80e 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table.c @@ -66,7 +66,7 @@ const lv_obj_class_t lv_table_class = { .editable = LV_OBJ_CLASS_EDITABLE_TRUE, .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE, .instance_size = sizeof(lv_table_t), - .name = "table", + .name = "lv_table", }; /********************** * MACROS @@ -277,7 +277,7 @@ void lv_table_set_column_count(lv_obj_t * obj, uint32_t col_cnt) int32_t i; for(i = 0; i < (int32_t)old_col_cnt - (int32_t)col_cnt; i++) { uint32_t idx = old_col_start + min_col_cnt + i; - if(table->cell_data[idx]->user_data) { + if(table->cell_data[idx] && table->cell_data[idx]->user_data) { lv_free(table->cell_data[idx]->user_data); table->cell_data[idx]->user_data = NULL; } @@ -315,7 +315,7 @@ void lv_table_set_column_width(lv_obj_t * obj, uint32_t col_id, int32_t w) refr_size_form_row(obj, 0); } -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_set_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_table_cell_ctrl_t ctrl) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -338,6 +338,7 @@ void lv_table_add_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_table } table->cell_data[cell]->ctrl |= ctrl; + refr_cell_size(obj, row, col); } void lv_table_clear_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_table_cell_ctrl_t ctrl) @@ -521,6 +522,8 @@ static void lv_table_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) table->row_h[0] = LV_DPI_DEF; table->cell_data = lv_realloc(table->cell_data, table->row_cnt * table->col_cnt * sizeof(lv_table_cell_t *)); table->cell_data[0] = NULL; + table->row_act = LV_TABLE_CELL_NONE; + table->col_act = LV_TABLE_CELL_NONE; LV_TRACE_OBJ_CREATE("finished"); } @@ -694,11 +697,13 @@ static void draw_main(lv_event_t * e) lv_draw_rect_dsc_t rect_dsc_def; lv_draw_rect_dsc_t rect_dsc_act; /*Passed to the event to modify it*/ lv_draw_rect_dsc_init(&rect_dsc_def); + rect_dsc_def.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_ITEMS, &rect_dsc_def); lv_draw_label_dsc_t label_dsc_def; lv_draw_label_dsc_t label_dsc_act; /*Passed to the event to modify it*/ lv_draw_label_dsc_init(&label_dsc_def); + label_dsc_def.base.layer = layer; lv_obj_init_draw_label_dsc(obj, LV_PART_ITEMS, &label_dsc_def); obj->state = state_ori; obj->skip_trans = 0; @@ -797,7 +802,9 @@ static void draw_main(lv_event_t * e) obj->state = cell_state; obj->skip_trans = 1; lv_draw_rect_dsc_init(&rect_dsc_act); + rect_dsc_act.base.layer = layer; lv_draw_label_dsc_init(&label_dsc_act); + label_dsc_act.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_ITEMS, &rect_dsc_act); lv_obj_init_draw_label_dsc(obj, LV_PART_ITEMS, &label_dsc_act); obj->state = state_ori; @@ -826,7 +833,10 @@ static void draw_main(lv_event_t * e) /*Align the content to the middle if not cropped*/ bool crop = ctrl & LV_TABLE_CELL_CTRL_TEXT_CROP; - if(crop) txt_flags = LV_TEXT_FLAG_EXPAND; + if(crop) { + txt_flags = LV_TEXT_FLAG_EXPAND; + label_dsc_act.flag |= LV_TEXT_FLAG_EXPAND; + } lv_text_get_size(&txt_size, table->cell_data[cell]->txt, label_dsc_def.font, label_dsc_act.letter_space, label_dsc_act.line_space, @@ -998,6 +1008,9 @@ static lv_result_t get_pressed_cell(lv_obj_t * obj, uint32_t * row, uint32_t * c lv_indev_get_point(lv_indev_active(), &p); int32_t tmp; + bool is_click_on_valid_column = false; + bool is_click_on_valid_row = false; + if(col) { int32_t x = p.x + lv_obj_get_scroll_x(obj); @@ -1013,7 +1026,10 @@ static lv_result_t get_pressed_cell(lv_obj_t * obj, uint32_t * row, uint32_t * c tmp = 0; for(*col = 0; *col < table->col_cnt; (*col)++) { tmp += table->col_w[*col]; - if(x < tmp) break; + if(x < tmp) { + is_click_on_valid_column = true; + break; + } } } @@ -1027,11 +1043,20 @@ static lv_result_t get_pressed_cell(lv_obj_t * obj, uint32_t * row, uint32_t * c for(*row = 0; *row < table->row_cnt; (*row)++) { tmp += table->row_h[*row]; - if(y < tmp) break; + if(y < tmp) { + is_click_on_valid_row = true; + break; + } } } - return LV_RESULT_OK; + /* If the click was on valid column AND row then return valid result, return invalid otherwise */ + lv_result_t result = LV_RESULT_INVALID; + if((is_click_on_valid_column) && (is_click_on_valid_row)) { + result = LV_RESULT_OK; + } + + return result; } /* Returns number of bytes to allocate based on chars configuration */ @@ -1067,18 +1092,35 @@ static void get_cell_area(lv_obj_t * obj, uint32_t row, uint32_t col, lv_area_t for(c = 0; c < col; c++) { area->x1 += table->col_w[c]; } + /* Traverse the current row from the first until the penultimate column. + * Increment the offset if the cell has the LV_TABLE_CELL_CTRL_MERGE_RIGHT control, + * exit the traversal when the current cell control is not LV_TABLE_CELL_CTRL_MERGE_RIGHT */ + uint32_t col_merge = 0; + int32_t offset = 0; + for(col_merge = 0; col_merge + col < table->col_cnt - 1; col_merge++) { + lv_table_cell_t * next_cell_data = table->cell_data[row * table->col_cnt + col_merge]; + if(is_cell_empty(next_cell_data)) break; + + lv_table_cell_ctrl_t ctrl = (lv_table_cell_ctrl_t) next_cell_data->ctrl; + if(ctrl & LV_TABLE_CELL_CTRL_MERGE_RIGHT) { + offset += table->col_w[col + col_merge + 1]; + } + else { + break; + } + } bool rtl = lv_obj_get_style_base_dir(obj, LV_PART_MAIN) == LV_BASE_DIR_RTL; if(rtl) { area->x1 += lv_obj_get_scroll_x(obj); int32_t w = lv_obj_get_width(obj); area->x2 = w - area->x1 - lv_obj_get_style_pad_right(obj, 0); - area->x1 = area->x2 - table->col_w[col]; + area->x1 = area->x2 - (table->col_w[col] + offset); } else { area->x1 -= lv_obj_get_scroll_x(obj); area->x1 += lv_obj_get_style_pad_left(obj, 0); - area->x2 = area->x1 + table->col_w[col] - 1; + area->x2 = area->x1 + (table->col_w[col] + offset) - 1; } uint32_t r; 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 0d615a1b1..e4c56e635 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table.h @@ -34,6 +34,7 @@ LV_EXPORT_CONST_INT(LV_TABLE_CELL_NONE); **********************/ typedef enum { + LV_TABLE_CELL_CTRL_NONE = 0 << 0, LV_TABLE_CELL_CTRL_MERGE_RIGHT = 1 << 0, LV_TABLE_CELL_CTRL_TEXT_CROP = 1 << 1, LV_TABLE_CELL_CTRL_CUSTOM_1 = 1 << 4, @@ -109,7 +110,7 @@ void lv_table_set_column_width(lv_obj_t * obj, uint32_t col_id, int32_t w); * @param col id of the column [0 .. col_cnt -1] * @param ctrl OR-ed values from ::lv_table_cell_ctrl_t */ -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_set_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_table_cell_ctrl_t ctrl); /** * Clear control bits of the cell. 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 index 498ef5e28..816de1e70 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/table/lv_table_private.h @@ -28,14 +28,14 @@ extern "C" { **********************/ /** Cell data */ -struct lv_table_cell_t { +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 { +struct _lv_table_t { lv_obj_t obj; uint32_t col_cnt; uint32_t row_cnt; 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 29e3e2e27..ab114d258 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview.c @@ -42,7 +42,7 @@ const lv_obj_class_t lv_tabview_class = { .height_def = LV_PCT(100), .base_class = &lv_obj_class, .instance_size = sizeof(lv_tabview_t), - .name = "tabview", + .name = "lv_tabview", }; typedef struct { @@ -74,7 +74,6 @@ lv_obj_t * lv_tabview_add_tab(lv_obj_t * obj, const char * name) lv_obj_t * page = lv_obj_create(cont); lv_obj_set_size(page, lv_pct(100), lv_pct(100)); - uint32_t tab_idx = lv_obj_get_child_count(cont); lv_obj_t * tab_bar = lv_tabview_get_tab_bar(obj); @@ -89,8 +88,10 @@ lv_obj_t * lv_tabview_add_tab(lv_obj_t * obj, const char * name) lv_label_set_text(label, name); lv_obj_center(label); - if(tab_idx == 1) { - lv_tabview_set_active(obj, 0, LV_ANIM_OFF); + uint32_t tab_idx = lv_obj_get_child_count(cont) - 1; + lv_tabview_t * tabview = (lv_tabview_t *)obj; + if(tab_idx == tabview->tab_cur) { + lv_tabview_set_active(obj, tab_idx, LV_ANIM_OFF); } return page; @@ -111,19 +112,19 @@ void lv_tabview_set_active(lv_obj_t * obj, uint32_t idx, lv_anim_enable_t anim_e LV_ASSERT_OBJ(obj, MY_CLASS); lv_tabview_t * tabview = (lv_tabview_t *)obj; + tabview->tab_cur = idx; + lv_obj_t * cont = lv_tabview_get_content(obj); lv_obj_t * tab_bar = lv_tabview_get_tab_bar(obj); uint32_t tab_cnt = lv_tabview_get_tab_count(obj); - if(idx >= tab_cnt) { - idx = tab_cnt - 1; - } + if(idx >= tab_cnt) return; /*To be sure lv_obj_get_content_width will return valid value*/ - lv_obj_update_layout(obj); - if(cont == NULL) return; + lv_obj_update_layout(obj); + if((tabview->tab_pos & LV_DIR_VER) != 0) { int32_t gap = lv_obj_get_style_pad_column(cont, LV_PART_MAIN); int32_t w = lv_obj_get_content_width(cont); @@ -149,7 +150,6 @@ void lv_tabview_set_active(lv_obj_t * obj, uint32_t idx, lv_anim_enable_t anim_e button = lv_obj_get_child_by_type(tab_bar, (int32_t)i, &lv_button_class); } - tabview->tab_cur = idx; } void lv_tabview_set_tab_bar_position(lv_obj_t * obj, lv_dir_t dir) @@ -233,7 +233,6 @@ void lv_tabview_set_tab_bar_size(lv_obj_t * obj, int32_t size) else { lv_obj_set_width(tab_bar, size); } - } uint32_t lv_tabview_get_tab_active(lv_obj_t * obj) @@ -278,7 +277,8 @@ static void lv_tabview_constructor(const lv_obj_class_t * class_p, lv_obj_t * ob cont = lv_obj_create(obj); lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW); - lv_obj_add_event_cb(cont, cont_scroll_end_event_cb, LV_EVENT_ALL, NULL); + lv_obj_add_event_cb(cont, cont_scroll_end_event_cb, LV_EVENT_LAYOUT_CHANGED, NULL); + lv_obj_add_event_cb(cont, cont_scroll_end_event_cb, LV_EVENT_SCROLL_END, NULL); lv_obj_set_scrollbar_mode(cont, LV_SCROLLBAR_MODE_OFF); lv_tabview_set_tab_bar_position(obj, LV_DIR_TOP); 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 index b08c96820..0e00351c7 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/tabview/lv_tabview_private.h @@ -31,7 +31,7 @@ extern "C" { * TYPEDEFS **********************/ -struct lv_tabview_t { +struct _lv_tabview_t { lv_obj_t obj; uint32_t tab_cur; lv_dir_t tab_pos; 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 1958371b3..511b11317 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea.c @@ -157,7 +157,7 @@ const lv_obj_class_t lv_textarea_class = { .editable = LV_OBJ_CLASS_EDITABLE_TRUE, .instance_size = sizeof(lv_textarea_t), .base_class = &lv_obj_class, - .name = "textarea", + .name = "lv_textarea", #if LV_USE_OBJ_PROPERTY .prop_index_start = LV_PROPERTY_TEXTAREA_START, .prop_index_end = LV_PROPERTY_TEXTAREA_END, @@ -948,7 +948,8 @@ static void lv_textarea_constructor(const lv_obj_class_t * class_p, lv_obj_t * o ta->label = lv_label_create(obj); lv_obj_set_width(ta->label, lv_pct(100)); lv_label_set_text(ta->label, ""); - lv_obj_add_event_cb(ta->label, label_event_cb, LV_EVENT_ALL, NULL); + lv_obj_add_event_cb(ta->label, label_event_cb, LV_EVENT_STYLE_CHANGED, NULL); + lv_obj_add_event_cb(ta->label, label_event_cb, LV_EVENT_SIZE_CHANGED, NULL); lv_obj_add_flag(obj, LV_OBJ_FLAG_SCROLL_ON_FOCUS); lv_obj_remove_flag(obj, LV_OBJ_FLAG_SCROLL_WITH_ARROW); @@ -1160,7 +1161,7 @@ static void start_cursor_blink(lv_obj_t * obj) lv_anim_set_var(&a, ta); lv_anim_set_exec_cb(&a, cursor_blink_anim_cb); lv_anim_set_duration(&a, blink_time); - lv_anim_set_playback_duration(&a, blink_time); + lv_anim_set_reverse_duration(&a, blink_time); lv_anim_set_values(&a, 1, 0); lv_anim_set_path_cb(&a, lv_anim_path_step); lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE); @@ -1398,6 +1399,7 @@ static void draw_placeholder(lv_event_t * e) if(txt[0] == '\0' && ta->placeholder_txt && ta->placeholder_txt[0] != 0) { lv_draw_label_dsc_t ph_dsc; lv_draw_label_dsc_init(&ph_dsc); + ph_dsc.base.layer = layer; lv_obj_init_draw_label_dsc(obj, LV_PART_TEXTAREA_PLACEHOLDER, &ph_dsc); if(ta->one_line) ph_dsc.flag |= LV_TEXT_FLAG_EXPAND; @@ -1429,6 +1431,7 @@ static void draw_cursor(lv_event_t * e) lv_draw_rect_dsc_t cur_dsc; lv_draw_rect_dsc_init(&cur_dsc); + cur_dsc.base.layer = layer; lv_obj_init_draw_rect_dsc(obj, LV_PART_CURSOR, &cur_dsc); /*Draw he cursor according to the type*/ @@ -1457,6 +1460,7 @@ static void draw_cursor(lv_event_t * e) lv_color_t label_color = lv_obj_get_style_text_color(ta->label, 0); lv_draw_label_dsc_t cur_label_dsc; lv_draw_label_dsc_init(&cur_label_dsc); + cur_label_dsc.base.layer = layer; lv_obj_init_draw_label_dsc(obj, LV_PART_CURSOR, &cur_label_dsc); if(cur_dsc.bg_opa > LV_OPA_MIN || !lv_color_eq(cur_label_dsc.color, label_color)) { cur_label_dsc.text = letter_buf; 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 index e2d3aaab9..68102e8ca 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/textarea/lv_textarea_private.h @@ -28,7 +28,7 @@ extern "C" { **********************/ /** Data of text area */ -struct lv_textarea_t { +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 */ 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 8844a89ae..fbec0b771 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview.c @@ -35,14 +35,14 @@ const lv_obj_class_t lv_tileview_class = { .constructor_cb = lv_tileview_constructor, .base_class = &lv_obj_class, .instance_size = sizeof(lv_tileview_t), - .name = "tileview", + .name = "lv_tileview", }; const lv_obj_class_t lv_tileview_tile_class = { .constructor_cb = lv_tileview_tile_constructor, .base_class = &lv_obj_class, .instance_size = sizeof(lv_tileview_tile_t), - .name = "tile", + .name = "lv_tile", }; /********************** @@ -133,11 +133,10 @@ static void lv_tileview_constructor(const lv_obj_class_t * class_p, lv_obj_t * o { LV_UNUSED(class_p); lv_obj_set_size(obj, LV_PCT(100), LV_PCT(100)); - lv_obj_add_event_cb(obj, tileview_event_cb, LV_EVENT_ALL, NULL); + lv_obj_add_event_cb(obj, tileview_event_cb, LV_EVENT_SCROLL_END, NULL); lv_obj_add_flag(obj, LV_OBJ_FLAG_SCROLL_ONE); lv_obj_set_scroll_snap_x(obj, LV_SCROLL_SNAP_CENTER); lv_obj_set_scroll_snap_y(obj, LV_SCROLL_SNAP_CENTER); - } static void lv_tileview_tile_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) 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 d373a2684..4058bb65d 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview.h @@ -29,17 +29,44 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_tileview_tile_class; **********************/ /** - * Create a Tileview object - * @param parent pointer to an object, it will be the parent of the new tileview - * @return pointer to the created tileview + * Create a tileview object + * @param parent pointer to an object, it will be the parent of the new tileview + * @return pointer to the created tileview */ lv_obj_t * lv_tileview_create(lv_obj_t * parent); +/** + * Add a tile to the tileview + * @param tv pointer to the tileview object + * @param col_id column id of the tile + * @param row_id row id of the tile + * @param dir direction to move to the next tile + * @return pointer to the added tile object + */ lv_obj_t * lv_tileview_add_tile(lv_obj_t * tv, uint8_t col_id, uint8_t row_id, lv_dir_t dir); +/** + * Set the active tile in the tileview. + * @param parent pointer to the tileview object + * @param tile_obj pointer to the tile object to be set as active + * @param anim_en animation enable flag (LV_ANIM_ON or LV_ANIM_OFF) + */ void lv_tileview_set_tile(lv_obj_t * tv, lv_obj_t * tile_obj, lv_anim_enable_t anim_en); + +/** + * Set the active tile by index in the tileview + * @param tv pointer to the tileview object + * @param col_id column id of the tile to be set as active + * @param row_id row id of the tile to be set as active + * @param anim_en animation enable flag (LV_ANIM_ON or LV_ANIM_OFF) + */ void lv_tileview_set_tile_by_index(lv_obj_t * tv, uint32_t col_id, uint32_t row_id, lv_anim_enable_t anim_en); +/** + * Get the currently active tile in the tileview + * @param obj pointer to the tileview object + * @return pointer to the currently active tile object + */ lv_obj_t * lv_tileview_get_tile_active(lv_obj_t * obj); /*===================== 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 index 5c91a409e..e343db0c5 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/tileview/lv_tileview_private.h @@ -30,12 +30,12 @@ extern "C" { /********************** * TYPEDEFS **********************/ -struct lv_tileview_t { +struct _lv_tileview_t { lv_obj_t obj; lv_obj_t * tile_act; }; -struct lv_tileview_tile_t { +struct _lv_tileview_tile_t { lv_obj_t obj; lv_dir_t dir; }; 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 508d2f010..164889550 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win.c +++ b/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win.c @@ -33,7 +33,7 @@ const lv_obj_class_t lv_win_class = { .height_def = LV_PCT(100), .base_class = &lv_obj_class, .instance_size = sizeof(lv_win_t), - .name = "win", + .name = "lv_win", }; /********************** * MACROS @@ -55,7 +55,7 @@ lv_obj_t * lv_win_add_title(lv_obj_t * win, const char * txt) { lv_obj_t * header = lv_win_get_header(win); lv_obj_t * title = lv_label_create(header); - lv_label_set_long_mode(title, LV_LABEL_LONG_DOT); + lv_label_set_long_mode(title, LV_LABEL_LONG_MODE_DOTS); lv_label_set_text(title, txt); lv_obj_set_flex_grow(title, 1); return title; 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 8191bd116..366a8b1b7 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win.h @@ -26,12 +26,42 @@ LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_win_class; * GLOBAL PROTOTYPES **********************/ +/** + * Create a window widget + * @param parent pointer to a parent widget + * @return the created window + */ lv_obj_t * lv_win_create(lv_obj_t * parent); +/** + * Add a title to the window + * @param obj pointer to a window widget + * @param txt the text of the title + * @return the widget where the content of the title can be created + */ lv_obj_t * lv_win_add_title(lv_obj_t * win, const char * txt); + +/** + * Add a button to the window + * @param obj pointer to a window widget + * @param icon an icon to be displayed on the button + * @param btn_w width of the button + * @return the widget where the content of the button can be created + */ lv_obj_t * lv_win_add_button(lv_obj_t * win, const void * icon, int32_t btn_w); +/** + * Get the header of the window + * @param win pointer to a window widget + * @return the header of the window + */ lv_obj_t * lv_win_get_header(lv_obj_t * win); + +/** + * Get the content of the window + * @param win pointer to a window widget + * @return the content of the window + */ lv_obj_t * lv_win_get_content(lv_obj_t * win); /********************** * MACROS 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 index 015224712..25e40c594 100644 --- a/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win_private.h +++ b/lib/libesp32_lvgl/lvgl/src/widgets/win/lv_win_private.h @@ -30,7 +30,7 @@ extern "C" { /********************** * TYPEDEFS **********************/ -struct lv_win_t { +struct _lv_win_t { lv_obj_t obj; }; diff --git a/tasmota/lvgl_berry/tasmota_lv_conf.h b/tasmota/lvgl_berry/tasmota_lv_conf.h index 64170fe68..3210415fa 100644 --- a/tasmota/lvgl_berry/tasmota_lv_conf.h +++ b/tasmota/lvgl_berry/tasmota_lv_conf.h @@ -1,23 +1,23 @@ /** * @file lv_conf.h - * Configuration file for v9.2.2 + * Configuration file for v9.3.0 */ /* * Copy this file as `lv_conf.h` - * 1. simply next to the `lvgl` folder - * 2. or any other places and - * - define `LV_CONF_INCLUDE_SIMPLE` - * - add the path as include path + * 1. simply next to `lvgl` folder + * 2. or to any other place and + * - define `LV_CONF_INCLUDE_SIMPLE`; + * - add the path as an include path. */ /* clang-format off */ -#if 1 /*Set it to "1" to enable content*/ +#if 1 /* Set this to "1" to enable content */ #ifndef LV_CONF_H #define LV_CONF_H -/*If you need to include anything here, do it inside the `__ASSEMBLY__` guard */ +/* If you need to include anything here, do it inside the `__ASSEMBLY__` guard */ #if 0 && defined(__ASSEMBLY__) #include "my_include.h" #endif @@ -26,22 +26,41 @@ COLOR SETTINGS *====================*/ -/*Color depth: 1 (I1), 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ +/** Color depth: 1 (I1), 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888) */ #define LV_COLOR_DEPTH 16 /*========================= STDLIB WRAPPER SETTINGS *=========================*/ -/* Possible values +/** Possible values * - LV_STDLIB_BUILTIN: LVGL's built in implementation * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc * - LV_STDLIB_MICROPYTHON: MicroPython implementation * - LV_STDLIB_RTTHREAD: RT-Thread implementation * - LV_STDLIB_CUSTOM: Implement the functions externally */ +//#define LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN #define LV_USE_STDLIB_MALLOC LV_STDLIB_CUSTOM // TASMOTA + +/** Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ +// #define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN #define LV_USE_STDLIB_STRING LV_STDLIB_CLIB // TASMOTA + +/** Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ +// #define LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN #define LV_USE_STDLIB_SPRINTF LV_STDLIB_CLIB // TASMOTA #define LV_STDINT_INCLUDE @@ -52,15 +71,15 @@ #define LV_STDARG_INCLUDE #if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN - /*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/ - #define LV_MEM_SIZE (64 * 1024U) /*[bytes]*/ + /** Size of memory available for `lv_malloc()` in bytes (>= 2kB) */ + #define LV_MEM_SIZE (64 * 1024U) /**< [bytes] */ - /*Size of the memory expand for `lv_malloc()` in bytes*/ + /** Size of the memory expand for `lv_malloc()` in bytes */ #define LV_MEM_POOL_EXPAND_SIZE 0 - /*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/ - #define LV_MEM_ADR 0 /*0: unused*/ - /*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/ + /** Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too. */ + #define LV_MEM_ADR 0 /**< 0: unused*/ + /* Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc */ #if LV_MEM_ADR == 0 #undef LV_MEM_POOL_INCLUDE #undef LV_MEM_POOL_ALLOC @@ -71,17 +90,17 @@ HAL SETTINGS *====================*/ -/*Default display refresh, input device read and animation step period.*/ -#define LV_DEF_REFR_PERIOD 33 /*[ms]*/ +/** Default display refresh, input device read and animation step period. */ +#define LV_DEF_REFR_PERIOD 33 /**< [ms] */ -/*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings. - *(Not so important, you can adjust it to modify default sizes and spaces)*/ -#define LV_DPI_DEF 130 /*[px/inch]*/ +/** Default Dots Per Inch. Used to initialize default sizes such as widgets sized, style paddings. + * (Not so important, you can adjust it to modify default sizes and spaces.) */ +#define LV_DPI_DEF 130 /**< [px/inch] */ /*================= * OPERATING SYSTEM *=================*/ -/*Select an operating system to use. Possible options: +/** Select operating system to use. Possible options: * - LV_OS_NONE * - LV_OS_PTHREAD * - LV_OS_FREERTOS @@ -89,6 +108,7 @@ * - LV_OS_RTTHREAD * - LV_OS_WINDOWS * - LV_OS_MQX + * - LV_OS_SDL2 * - LV_OS_CUSTOM */ #define LV_USE_OS LV_OS_NONE @@ -96,28 +116,28 @@ #define LV_OS_CUSTOM_INCLUDE #endif #if LV_USE_OS == LV_OS_FREERTOS - /* - * Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM - * than unblocking a task using an intermediary object such as a binary semaphore. - * RTOS task notifications can only be used when there is only one task that can be the recipient of the event. - */ - #define LV_USE_FREERTOS_TASK_NOTIFY 1 + /* + * Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM + * than unblocking a task using an intermediary object such as a binary semaphore. + * RTOS task notifications can only be used when there is only one task that can be the recipient of the event. + */ + #define LV_USE_FREERTOS_TASK_NOTIFY 1 #endif /*======================== * RENDERING CONFIGURATION *========================*/ -/*Align the stride of all layers and images to this bytes*/ +/** Align stride of all layers and images to this bytes */ #define LV_DRAW_BUF_STRIDE_ALIGN 1 -/*Align the start address of draw_buf addresses to this bytes*/ +/** Align 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.*/ +/** Using matrix for transformations. + * Requirements: + * - `LV_USE_MATRIX = 1`. + * - 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 @@ -125,59 +145,79 @@ * "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers * and can't be drawn in chunks. */ -/*The target buffer size for simple layer chunks.*/ -#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /*[bytes]*/ +/** 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. +/* Limit the max allocated memory for simple and transformed layers. + * It should be at least `LV_DRAW_LAYER_SIMPLE_BUF_SIZE` sized but if transformed layers are also used + * it should be enough to store the largest widget too (width x height x 4 area). + * Set it to 0 to have no limit. */ +#define LV_DRAW_LAYER_MAX_MEMORY 0 /**< No limit by default [bytes]*/ + +/** Stack size of 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_DRAW_THREAD_STACK_SIZE (8 * 1024) /**< [bytes]*/ + +/** Thread priority of the drawing task. + * Higher values mean higher priority. + * Can use values from lv_thread_prio_t enum in lv_os.h: LV_THREAD_PRIO_LOWEST, + * LV_THREAD_PRIO_LOW, LV_THREAD_PRIO_MID, LV_THREAD_PRIO_HIGH, LV_THREAD_PRIO_HIGHEST + * Make sure the priority value aligns with the OS-specific priority levels. + * On systems with limited priority levels (e.g., FreeRTOS), a higher value can improve + * rendering performance but might cause other tasks to starve. */ +#define LV_DRAW_THREAD_PRIO LV_THREAD_PRIO_HIGH #define LV_USE_DRAW_SW 1 #if LV_USE_DRAW_SW == 1 + /* + * 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_RGB565_SWAPPED 0 // TASMOTA + #define LV_DRAW_SW_SUPPORT_RGB565A8 0 // TASMOTA + #define LV_DRAW_SW_SUPPORT_RGB888 1 + #define LV_DRAW_SW_SUPPORT_XRGB8888 0 // TASMOTA + #define LV_DRAW_SW_SUPPORT_ARGB8888 1 + #define LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED 0 // TASMOTA + #define LV_DRAW_SW_SUPPORT_L8 0 // TASMOTA + #define LV_DRAW_SW_SUPPORT_AL88 1 + #define LV_DRAW_SW_SUPPORT_A8 0 // TASMOTA + #define LV_DRAW_SW_SUPPORT_I1 1 - /* - * 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 - */ + /* The threshold of the luminance to consider a pixel as + * active in indexed color format */ + #define LV_DRAW_SW_I1_LUM_THRESHOLD 127 - #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 multiple threads will render the screen in parallel */ + /** Set number of draw units. + * - > 1 requires operating system to be enabled in `LV_USE_OS`. + * - > 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 */ + /** Use Arm-2D to accelerate software (sw) rendering. */ #define LV_USE_DRAW_ARM2D_SYNC 0 - /* Enable native helium assembly to be compiled */ + /** 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 */ + /** + * - 0: Use a simple renderer capable of drawing only simple rectangles with gradient, images, text, 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 #if LV_DRAW_SW_COMPLEX == 1 - /*Allow buffering some shadow calculation. - *LV_DRAW_SW_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius` - *Caching has LV_DRAW_SW_SHADOW_CACHE_SIZE^2 RAM cost*/ + /** Allow buffering some shadow calculation. + * LV_DRAW_SW_SHADOW_CACHE_SIZE is the maximum shadow size to buffer, where shadow size is + * `shadow_width + radius`. Caching has LV_DRAW_SW_SHADOW_CACHE_SIZE^2 RAM cost. */ #define LV_DRAW_SW_SHADOW_CACHE_SIZE 0 - /* Set number of maximally cached circle data. - * The circumference of 1/4 circle are saved for anti-aliasing - * radius * 4 bytes are used per circle (the most often used radiuses are saved) - * 0: to disable caching */ + /** Set number of maximally-cached circle data. + * The circumference of 1/4 circle are saved for anti-aliasing. + * `radius * 4` bytes are used per circle (the most often used radiuses are saved). + * - 0: disables caching */ #define LV_DRAW_SW_CIRCLE_CACHE_SIZE 4 #endif @@ -187,85 +227,139 @@ #define LV_DRAW_SW_ASM_CUSTOM_INCLUDE "" #endif - /* Enable drawing complex gradients in software: linear at an angle, radial or conical */ + /** 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. */ +/*Use TSi's aka (Think Silicon) NemaGFX */ +#define LV_USE_NEMA_GFX 0 + +#if LV_USE_NEMA_GFX + /** Select which NemaGFX HAL to use. Possible options: + * - LV_NEMA_HAL_CUSTOM + * - LV_NEMA_HAL_STM32 */ + #define LV_USE_NEMA_HAL LV_NEMA_HAL_CUSTOM + #if LV_USE_NEMA_HAL == LV_NEMA_HAL_STM32 + #define LV_NEMA_STM32_HAL_INCLUDE + #endif + + /*Enable Vector Graphics Operations. Available only if NemaVG library is present*/ + #define LV_USE_NEMA_VG 0 + #if LV_USE_NEMA_VG + /*Define application's resolution used for VG related buffer allocation */ + #define LV_NEMA_GFX_MAX_RESX 800 + #define LV_NEMA_GFX_MAX_RESY 600 + #endif +#endif + +/** Use NXP's VG-Lite GPU on iMX RTxxx platforms. */ #define LV_USE_DRAW_VGLITE 0 #if LV_USE_DRAW_VGLITE - /* Enable blit quality degradation workaround recommended for screen's dimension > 352 pixels. */ + /** Enable blit quality degradation workaround recommended for screen's dimension > 352 pixels. */ #define LV_USE_VGLITE_BLIT_SPLIT 0 #if LV_USE_OS - /* Use additional draw thread for VG-Lite processing.*/ + /** 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. */ + /** 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. */ + /** Enable VGLite asserts. */ #define LV_USE_VGLITE_ASSERT 0 + + /** Enable VGLite error checks. */ + #define LV_USE_VGLITE_CHECK_ERROR 0 #endif -/* Use NXP's PXP on iMX RTxxx platforms. */ +/** Use NXP's PXP on iMX RTxxx platforms. */ #define LV_USE_PXP 0 #if LV_USE_PXP - /* Use PXP for drawing.*/ + /** Use PXP for drawing.*/ #define LV_USE_DRAW_PXP 1 - /* Use PXP to rotate display.*/ + /** Use PXP to rotate display.*/ #define LV_USE_ROTATE_PXP 0 #if LV_USE_DRAW_PXP && LV_USE_OS - /* Use additional draw thread for PXP processing.*/ + /** Use additional draw thread for PXP processing.*/ #define LV_USE_PXP_DRAW_THREAD 1 #endif - /* Enable PXP asserts. */ + /** Enable PXP asserts. */ #define LV_USE_PXP_ASSERT 0 #endif -/* Use Renesas Dave2D on RA platforms. */ +/** Use NXP's G2D on MPU platforms. */ +#define LV_USE_DRAW_G2D 0 + +#if LV_USE_DRAW_G2D + /** Maximum number of buffers that can be stored for G2D draw unit. + * Includes the frame buffers and assets. */ + #define LV_G2D_HASH_TABLE_SIZE 50 + + #if LV_USE_OS + /** Use additional draw thread for G2D processing.*/ + #define LV_USE_G2D_DRAW_THREAD 1 + #endif + + /** Enable G2D asserts. */ + #define LV_USE_G2D_ASSERT 0 +#endif + +/** Use Renesas Dave2D on RA platforms. */ #define LV_USE_DRAW_DAVE2D 0 -/* Draw using cached SDL textures*/ +/** Draw using cached SDL textures*/ #define LV_USE_DRAW_SDL 0 -/* Use VG-Lite GPU. */ +/** Use VG-Lite GPU. */ #define LV_USE_DRAW_VG_LITE 0 #if LV_USE_DRAW_VG_LITE - /* Enable VG-Lite custom external 'gpu_init()' function */ + /** Enable VG-Lite custom external 'gpu_init()' function */ #define LV_VG_LITE_USE_GPU_INIT 0 - /* Enable VG-Lite assert. */ + /** 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. */ + /** 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 1 - /* VG-Lite gradient maximum cache number. - * NOTE: The memory usage of a single gradient image is 4K bytes. - */ + /** 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. - */ + /** VG-Lite stroke maximum cache number. */ #define LV_VG_LITE_STROKE_CACHE_CNT 32 - #endif +/** Accelerate blends, fills, etc. with STM32 DMA2D */ +#define LV_USE_DRAW_DMA2D 0 + +#if LV_USE_DRAW_DMA2D + #define LV_DRAW_DMA2D_HAL_INCLUDE "stm32h7xx_hal.h" + + /* if enabled, the user is required to call `lv_draw_dma2d_transfer_complete_interrupt_handler` + * upon receiving the DMA2D global interrupt + */ + #define LV_USE_DRAW_DMA2D_INTERRUPT 0 +#endif + +/** Draw using cached OpenGLES textures */ +#define LV_USE_DRAW_OPENGLES 0 + /*======================= * FEATURE CONFIGURATION *=======================*/ @@ -274,79 +368,77 @@ * Logging *-----------*/ -/*Enable the log module*/ +/** Enable log module */ #define LV_USE_LOG 0 #if LV_USE_LOG - - /*How important log should be added: - *LV_LOG_LEVEL_TRACE A lot of logs to give detailed information - *LV_LOG_LEVEL_INFO Log important events - *LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem - *LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail - *LV_LOG_LEVEL_USER Only logs added by the user - *LV_LOG_LEVEL_NONE Do not log anything*/ + /** Set value to one of the following levels of logging detail: + * - LV_LOG_LEVEL_TRACE Log detailed information. + * - LV_LOG_LEVEL_INFO Log important events. + * - LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem. + * - LV_LOG_LEVEL_ERROR Log only critical issues, when system may fail. + * - LV_LOG_LEVEL_USER Log only custom log messages added by the user. + * - LV_LOG_LEVEL_NONE Do not log anything. */ #define LV_LOG_LEVEL LV_LOG_LEVEL_INFO - /*1: Print the log with 'printf'; - *0: User need to register a callback with `lv_log_register_print_cb()`*/ + /** - 1: Print log with 'printf'; + * - 0: User needs 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`*/ + /** Set callback to print 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*/ + /** - 1: Enable printing timestamp; + * - 0: Disable printing timestamp. */ #define LV_LOG_USE_TIMESTAMP 1 - /*1: Print file and line number of the log; - *0: Do not print file and line number of the log*/ + /** - 1: Print file and line number of the log; + * - 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 - #define LV_LOG_TRACE_INDEV 1 - #define LV_LOG_TRACE_DISP_REFR 0 - #define LV_LOG_TRACE_EVENT 1 - #define LV_LOG_TRACE_OBJ_CREATE 0 - #define LV_LOG_TRACE_LAYOUT 0 - #define LV_LOG_TRACE_ANIM 0 - #define LV_LOG_TRACE_CACHE 1 - + /* Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs. */ + #define LV_LOG_TRACE_MEM 0 /**< Enable/disable trace logs in memory operations. */ + #define LV_LOG_TRACE_TIMER 0 /**< Enable/disable trace logs in timer operations. */ + #define LV_LOG_TRACE_INDEV 1 /**< Enable/disable trace logs in input device operations. */ + #define LV_LOG_TRACE_DISP_REFR 0 /**< Enable/disable trace logs in display re-draw operations. */ + #define LV_LOG_TRACE_EVENT 1 /**< Enable/disable trace logs in event dispatch logic. */ + #define LV_LOG_TRACE_OBJ_CREATE 0 /**< Enable/disable trace logs in object creation (core `obj` creation plus every widget). */ + #define LV_LOG_TRACE_LAYOUT 0 /**< Enable/disable trace logs in flex- and grid-layout operations. */ + #define LV_LOG_TRACE_ANIM 0 /**< Enable/disable trace logs in animation logic. */ + #define LV_LOG_TRACE_CACHE 1 /**< Enable/disable trace logs in cache operations. */ #endif /*LV_USE_LOG*/ /*------------- * Asserts *-----------*/ -/*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*/ -#define LV_USE_ASSERT_NULL 1 /*Check if the parameter is NULL. (Very fast, recommended)*/ -#define LV_USE_ASSERT_MALLOC 1 /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/ -#define LV_USE_ASSERT_STYLE 0 /*Check if the styles are properly initialized. (Very fast, recommended)*/ -#define LV_USE_ASSERT_MEM_INTEGRITY 0 /*Check the integrity of `lv_mem` after critical operations. (Slow)*/ -#define LV_USE_ASSERT_OBJ 0 /*Check the object's type and existence (e.g. not deleted). (Slow)*/ +/* Enable assertion failures if an operation fails or invalid data is found. + * If LV_USE_LOG is enabled, an error message will be printed on failure. */ +#define LV_USE_ASSERT_NULL 1 /**< Check if the parameter is NULL. (Very fast, recommended) */ +#define LV_USE_ASSERT_MALLOC 1 /**< Checks is the memory is successfully allocated or no. (Very fast, recommended) */ +#define LV_USE_ASSERT_STYLE 0 /**< Check if the styles are properly initialized. (Very fast, recommended) */ +#define LV_USE_ASSERT_MEM_INTEGRITY 0 /**< Check the integrity of `lv_mem` after critical operations. (Slow) */ +#define LV_USE_ASSERT_OBJ 0 /**< Check the object's type and existence (e.g. not deleted). (Slow) */ -/*Add a custom handler when assert happens e.g. to restart the MCU*/ +/** Add a custom handler when assert happens e.g. to restart MCU. */ #define LV_ASSERT_HANDLER_INCLUDE -#define LV_ASSERT_HANDLER while(1); /*Halt by default*/ +#define LV_ASSERT_HANDLER while(1); /**< Halt by default */ /*------------- * Debug *-----------*/ -/*1: Draw random colored rectangles over the redrawn areas*/ +/** 1: Draw random colored rectangles over the redrawn areas. */ #define LV_USE_REFR_DEBUG 0 -/*1: Draw a red overlay for ARGB layers and a green overlay for RGB layers*/ +/** 1: Draw a red overlay for ARGB layers and a green overlay for RGB layers*/ #define LV_USE_LAYER_DEBUG 0 -/*1: Draw overlays with different colors for each draw_unit's tasks. - *Also add the index number of the draw unit on white background. - *For layers add the index number of the draw unit on black background.*/ +/** 1: Adds the following behaviors for debugging: + * - Draw overlays with different colors for each draw_unit's tasks. + * - Draw index number of draw unit on white background. + * - For layers, draws index number of draw unit on black background. */ #define LV_USE_PARALLEL_DRAW_DEBUG 0 /*------------- @@ -355,134 +447,147 @@ #define LV_ENABLE_GLOBAL_CUSTOM 0 #if LV_ENABLE_GLOBAL_CUSTOM - /*Header to include for the custom 'lv_global' function"*/ + /** Header to include for custom 'lv_global' function" */ #define LV_GLOBAL_CUSTOM_INCLUDE #endif -/*Default cache size in bytes. - *Used by image decoders such as `lv_lodepng` to keep the decoded image in the memory. - *If size is not set to 0, the decoder will fail to decode when the cache is full. - *If size is 0, the cache function is not enabled and the decoded mem will be released immediately after use.*/ -#define LV_IMG_CACHE_DEF_SIZE_PSRAM (2048*1024) -#define LV_IMG_CACHE_DEF_SIZE_NOPSRAM (32*1024) +/** Default cache size in bytes. + * Used by image decoders such as `lv_lodepng` to keep the decoded image in memory. + * If size is not set to 0, the decoder will fail to decode when the cache is full. + * If size is 0, the cache function is not enabled and the decoded memory will be + * released immediately after use. */ +#define LV_IMG_CACHE_DEF_SIZE_PSRAM (2048*1024) // TASMOTA +#define LV_IMG_CACHE_DEF_SIZE_NOPSRAM (32*1024) // TASMOTA #define LV_CACHE_DEF_SIZE 1024 // TASMOTA very low value as a place-holder, the true value is adjusted later -/*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.*/ +/** 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 0 -/*Number of stops allowed per gradient. Increase this to allow more stops. - *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/ +/** Number of stops allowed per gradient. Increase this to allow more stops. + * This adds (sizeof(lv_color_t) + 1) bytes per additional stop. */ #define LV_GRADIENT_MAX_STOPS 2 -/* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. - * 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */ +/** Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. + * - 0: round down, + * - 64: round up from x.75, + * - 128: round up from half, + * - 192: round up from x.25, + * - 254: round up */ #define LV_COLOR_MIX_ROUND_OFS 0 -/* Add 2 x 32 bit variables to each lv_obj_t to speed up getting style properties */ +/** Add 2 x 32-bit variables to each `lv_obj_t` to speed up getting style properties */ #define LV_OBJ_STYLE_CACHE 0 -/* Add `id` field to `lv_obj_t` */ +/** Add `id` field to `lv_obj_t` */ #define LV_USE_OBJ_ID 1 // TASMOTA -/* Automatically assign an ID when obj is created */ +/** Enable support widget names*/ +#define LV_USE_OBJ_NAME 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: +/** Use 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. +* - lv_obj_stringify_id: Return string-ified identifier, 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*/ +/** Use obj property set/get API. */ #define LV_USE_OBJ_PROPERTY 0 -/*Enable property name support*/ +/** 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 */ +/* Use VG-Lite Simulator. + * - Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ #define LV_USE_VG_LITE_THORVG 0 #if LV_USE_VG_LITE_THORVG - - /*Enable LVGL's blend mode support*/ + /** Enable LVGL's blend mode support */ #define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT 0 - /*Enable YUV color format support*/ + /** Enable YUV color format support */ #define LV_VG_LITE_THORVG_YUV_SUPPORT 0 - /*Enable Linear gradient extension support*/ + /** Enable Linear gradient extension support */ #define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT 0 - /*Enable 16 pixels alignment*/ + /** Enable alignment on 16 pixels */ #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1 - /*Buffer address alignment*/ + /** Buffer address alignment */ #define LV_VG_LITE_THORVG_BUF_ADDR_ALIGN 64 - /*Enable multi-thread render*/ + /** Enable multi-thread render */ #define LV_VG_LITE_THORVG_THREAD_RENDER 0 - #endif +/* Enable the multi-touch gesture recognition feature */ +/* Gesture recognition requires the use of floats */ +#define LV_USE_GESTURE_RECOGNITION 0 + /*===================== * COMPILER SETTINGS *====================*/ -/*For big endian systems set to 1*/ +/** For big endian systems set to 1 */ #define LV_BIG_ENDIAN_SYSTEM 0 -/*Define a custom attribute to `lv_tick_inc` function*/ +/** Define a custom attribute for `lv_tick_inc` function */ #define LV_ATTRIBUTE_TICK_INC -/*Define a custom attribute to `lv_timer_handler` function*/ +/** Define a custom attribute for `lv_timer_handler` function */ #define LV_ATTRIBUTE_TIMER_HANDLER -/*Define a custom attribute to `lv_display_flush_ready` function*/ +/** Define a custom attribute for `lv_display_flush_ready` function */ #define LV_ATTRIBUTE_FLUSH_READY -/*Required alignment size for buffers*/ +/** Align VG_LITE buffers on this number of bytes. + * @note vglite_src_buf_aligned() uses this value to validate alignment of passed buffer pointers. */ #define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1 -/*Will be added where memories needs to be aligned (with -Os data might not be aligned to boundary by default). - * E.g. __attribute__((aligned(4)))*/ +/** Will be added where memory needs to be aligned (with -Os data might not be aligned to boundary by default). + * E.g. __attribute__((aligned(4)))*/ #define LV_ATTRIBUTE_MEM_ALIGN -/*Attribute to mark large constant arrays for example font's bitmaps*/ +/** Attribute to mark large constant arrays, for example for font bitmaps */ #define LV_ATTRIBUTE_LARGE_CONST -/*Compiler prefix for a big array declaration in RAM*/ +/** Compiler prefix for a large array declaration in RAM */ #define LV_ATTRIBUTE_LARGE_RAM_ARRAY -/*Place performance critical functions into a faster memory (e.g RAM)*/ +/** Place performance critical functions into a faster memory (e.g RAM) */ #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.*/ -#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/ +/** 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. */ +#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*/ +/** Prefix all global extern data with this */ #define LV_ATTRIBUTE_EXTERN_DATA -/* Use `float` as `lv_value_precise_t` */ +/** Use `float` as `lv_value_precise_t` */ #define LV_USE_FLOAT 0 -/*Enable matrix support - *Requires `LV_USE_FLOAT = 1`*/ +/** 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 +/** Include `lvgl_private.h` in `lvgl.h` to access internal data and functions by default */ +#ifndef LV_USE_PRIVATE_API + #define LV_USE_PRIVATE_API 0 +#endif /*================== * FONT USAGE *===================*/ -/*Montserrat fonts with ASCII range and some symbols using bpp = 4 - *https://fonts.google.com/specimen/Montserrat*/ +/* Montserrat fonts with ASCII range and some symbols using bpp = 4 + * https://fonts.google.com/specimen/Montserrat */ #define LV_FONT_MONTSERRAT_8 0 #define LV_FONT_MONTSERRAT_10 0 #define LV_FONT_MONTSERRAT_TASMOTA_10 1 // TASMOTA @@ -511,18 +616,27 @@ #define LV_FONT_ICONS_18 1 -/*Demonstrate special features*/ -#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 -#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, Persian letters and all their forms*/ -#define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/ +/* 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 */ +#define LV_FONT_SOURCE_HAN_SANS_SC_14_CJK 0 /**< 1338 most common CJK radicals */ +#define LV_FONT_SOURCE_HAN_SANS_SC_16_CJK 0 /**< 1338 most common CJK radicals */ -/*Pixel perfect monospace fonts*/ +/** Pixel perfect monospaced fonts */ #define LV_FONT_UNSCII_8 1 // TASMOTA #define LV_FONT_UNSCII_16 1 // TASMOTA -/*Optionally declare custom fonts here. - *You can use these fonts as default font too and they will be available globally. - *E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/ +/** Optionally declare custom fonts here. + * + * You can use any of these fonts as the default font too and they will be available + * globally. Example: + * + * @code + * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2) + * @endcode + */ // TASMOTA specific #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(seg7_8) \ LV_FONT_DECLARE(seg7_10) \ @@ -583,19 +697,19 @@ #define ROBOTOCONDENSED_REGULAR_36_LATIN1 0 #define ROBOTOCONDENSED_REGULAR_48_LATIN1 0 -/*Always set a default font*/ -#define LV_FONT_DEFAULT &lv_font_montserrat_tasmota_14 -// #define LV_FONT_DEFAULT &lv_font_montserrat_14 -/*Enable handling large font and/or fonts with a lot of characters. - *The limit depends on the font size, font face and bpp. - *Compiler error will be triggered if a font needs it.*/ +/** Always set a default font */ +#define LV_FONT_DEFAULT &lv_font_montserrat_tasmota_14 // TASMOTA + +/** Enable handling large font and/or fonts with a lot of characters. + * The limit depends on the font size, font face and bpp. + * A compiler error will be triggered if a font needs it. */ #define LV_FONT_FMT_TXT_LARGE 0 -/*Enables/disables support for compressed fonts.*/ +/** Enables/disables support for compressed fonts. */ #define LV_USE_FONT_COMPRESSED 1 // TASMOTA -/*Enable drawing placeholders when glyph dsc is not found*/ +/** Enable drawing placeholders when glyph dsc is not found. */ #define LV_USE_FONT_PLACEHOLDER 1 /*================= @@ -604,49 +718,58 @@ /** * Select a character encoding for strings. - * Your IDE or editor should have the same character encoding + * Your IDE or editor should have the same character encoding. * - LV_TXT_ENC_UTF8 * - LV_TXT_ENC_ASCII */ #define LV_TXT_ENC LV_TXT_ENC_UTF8 -/*Can break (wrap) texts on these chars*/ +/** While rendering text strings, break (wrap) text on these chars. */ #define LV_TXT_BREAK_CHARS " ,.;:-_)]}" -/*If a word is at least this long, will break wherever "prettiest" - *To disable, set to a value <= 0*/ +/** If a word is at least this long, will break wherever "prettiest". + * To disable, set to a value <= 0. */ #define LV_TXT_LINE_BREAK_LONG_LEN 0 -/*Minimum number of characters in a long word to put on a line before a break. - *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ +/** Minimum number of characters in a long word to put on a line before a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ #define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 -/*Minimum number of characters in a long word to put on a line after a break. - *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ +/** Minimum number of characters in a long word to put on a line after a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ #define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 -/*Support bidirectional texts. Allows mixing Left-to-Right and Right-to-Left texts. - *The direction will be processed according to the Unicode Bidirectional Algorithm: - *https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/ +/** Support bidirectional text. Allows mixing Left-to-Right and Right-to-Left text. + * The direction will be processed according to the Unicode Bidirectional Algorithm: + * https://www.w3.org/International/articles/inline-bidi-markup/uba-basics */ #define LV_USE_BIDI 0 #if LV_USE_BIDI /*Set the default direction. Supported values: *`LV_BASE_DIR_LTR` Left-to-Right *`LV_BASE_DIR_RTL` Right-to-Left - *`LV_BASE_DIR_AUTO` detect texts base direction*/ + *`LV_BASE_DIR_AUTO` detect text base direction*/ #define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO #endif -/*Enable Arabic/Persian processing - *In these languages characters should be replaced with another form based on their position in the text*/ +/** Enable Arabic/Persian processing + * In these languages characters should be replaced with another form based on their position in the text */ #define LV_USE_ARABIC_PERSIAN_CHARS 0 +/*The control character to use for signaling text recoloring*/ +#define LV_TXT_COLOR_CMD "#" + /*================== * WIDGETS *================*/ +/* Documentation for widgets can be found here: https://docs.lvgl.io/master/details/widgets/index.html . */ -/*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/ - +/** 1: Causes these widgets to be given default values at creation time. + * - lv_buttonmatrix_t: Get default maps: {"Btn1", "Btn2", "Btn3", "\n", "Btn4", "Btn5", ""}, else map not set. + * - lv_checkbox_t : String label set to "Check box", else set to empty string. + * - lv_dropdown_t : Options set to "Option 1", "Option 2", "Option 3", else no values are set. + * - lv_roller_t : Options set to "Option 1", "Option 2", "Option 3", "Option 4", "Option 5", else no values are set. + * - lv_label_t : Text set to "Text", else empty string. + * */ #define LV_WIDGETS_HAS_DEFAULT_VALUE 1 #define LV_USE_ANIMIMG 1 @@ -680,9 +803,9 @@ #define LV_USE_CHECKBOX 1 -#define LV_USE_DROPDOWN 1 /*Requires: lv_label*/ +#define LV_USE_DROPDOWN 1 /**< Requires: lv_label */ -#define LV_USE_IMAGE 1 /*Requires: lv_label*/ +#define LV_USE_IMAGE 1 /**< Requires: lv_label */ #define LV_USE_IMAGEBUTTON 1 @@ -690,9 +813,9 @@ #define LV_USE_LABEL 1 #if LV_USE_LABEL - #define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/ - #define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/ - #define LV_LABEL_WAIT_CHAR_COUNT 3 /*The count of wait chart*/ + #define LV_LABEL_TEXT_SELECTION 1 /**< Enable selecting text of the label */ + #define LV_LABEL_LONG_TXT_HINT 1 /**< Store some extra info in labels to speed up drawing of very long text */ + #define LV_LABEL_WAIT_CHAR_COUNT 3 /**< The count of wait chart */ #endif #define LV_USE_LED 1 @@ -701,21 +824,21 @@ #define LV_USE_LIST 1 -#define LV_USE_LOTTIE 0 /*Requires: lv_canvas, thorvg */ +#define LV_USE_LOTTIE 0 /**< Requires: lv_canvas, thorvg */ #define LV_USE_MENU 1 #define LV_USE_MSGBOX 1 -#define LV_USE_ROLLER 1 /*Requires: lv_label*/ +#define LV_USE_ROLLER 1 /**< Requires: lv_label */ #define LV_USE_SCALE 1 -#define LV_USE_SLIDER 1 /*Requires: lv_bar*/ +#define LV_USE_SLIDER 1 /**< Requires: lv_bar */ #define LV_USE_SPAN 1 #if LV_USE_SPAN - /*A line text can contain maximum num of span descriptor */ + /** A line of text can contain this maximum number of span descriptors. */ #define LV_SPAN_SNIPPET_STACK_SIZE 64 #endif @@ -725,166 +848,182 @@ #define LV_USE_SWITCH 1 -#define LV_USE_TEXTAREA 1 /*Requires: lv_label*/ -#if LV_USE_TEXTAREA != 0 - #define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/ -#endif - #define LV_USE_TABLE 1 #define LV_USE_TABVIEW 1 +#define LV_USE_TEXTAREA 1 /**< Requires: lv_label */ +#if LV_USE_TEXTAREA != 0 + #define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /**< [ms] */ +#endif + #define LV_USE_TILEVIEW 1 #define LV_USE_WIN 1 +#define LV_USE_3DTEXTURE 0 + /*================== * THEMES *==================*/ +/* Documentation for themes can be found here: https://docs.lvgl.io/master/details/common-widget-features/styles/style.html#themes . */ -/*A simple, impressive and very complete theme*/ +/** A simple, impressive and very complete theme */ #define LV_USE_THEME_DEFAULT 1 #if LV_USE_THEME_DEFAULT + /** 0: Light mode; 1: Dark mode */ + #define LV_THEME_DEFAULT_DARK 1 // TASMOTA - /*0: Light mode; 1: Dark mode*/ - #define LV_THEME_DEFAULT_DARK 1 + /** 1: Enable grow on press */ + #define LV_THEME_DEFAULT_GROW 0 // TASMOTA - /*1: Enable grow on press*/ - #define LV_THEME_DEFAULT_GROW 0 - - /*Default transition time in [ms]*/ + /** Default transition time in ms. */ #define LV_THEME_DEFAULT_TRANSITION_TIME 80 #endif /*LV_USE_THEME_DEFAULT*/ -/*A very simple theme that is a good starting point for a custom theme*/ +/** A very simple theme that is a good starting point for a custom theme */ #define LV_USE_THEME_SIMPLE 1 -/*A theme designed for monochrome displays*/ +/** A theme designed for monochrome displays */ #define LV_USE_THEME_MONO 1 /*================== * LAYOUTS *==================*/ +/* Documentation for layouts can be found here: https://docs.lvgl.io/master/details/common-widget-features/layouts/index.html . */ -/*A layout similar to Flexbox in CSS.*/ +/** A layout similar to Flexbox in CSS. */ #define LV_USE_FLEX 1 -/*A layout similar to Grid in CSS.*/ +/** A layout similar to Grid in CSS. */ #define LV_USE_GRID 1 /*==================== * 3RD PARTS LIBRARIES *====================*/ +/* Documentation for libraries can be found here: https://docs.lvgl.io/master/details/libs/index.html . */ -/*File system interfaces for common APIs */ +/* 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' +/** Setting a default driver letter allows skipping the driver prefix in filepaths. + * Documentation about how to use the below driver-identifier letters can be found at + * https://docs.lvgl.io/master/details/main-modules/fs.html#lv-fs-identifier-letters . */ +#define LV_FS_DEFAULT_DRIVER_LETTER 'A' -/*API for fopen, fread, etc*/ +/** API for fopen, fread, etc. */ #define LV_USE_FS_STDIO 0 #if LV_USE_FS_STDIO - #define LV_FS_STDIO_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ - #define LV_FS_STDIO_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ - #define LV_FS_STDIO_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ + #define LV_FS_STDIO_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_STDIO_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ + #define LV_FS_STDIO_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ #endif -/*API for open, read, etc*/ +/** API for open, read, etc. */ #define LV_USE_FS_POSIX 0 #if LV_USE_FS_POSIX - #define LV_FS_POSIX_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ - #define LV_FS_POSIX_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ - #define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ + #define LV_FS_POSIX_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_POSIX_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ + #define LV_FS_POSIX_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ #endif -/*API for CreateFile, ReadFile, etc*/ +/** API for CreateFile, ReadFile, etc. */ #define LV_USE_FS_WIN32 0 #if LV_USE_FS_WIN32 - #define LV_FS_WIN32_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ - #define LV_FS_WIN32_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ - #define LV_FS_WIN32_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ + #define LV_FS_WIN32_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_WIN32_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ + #define LV_FS_WIN32_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ #endif -/*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/ +/** API for FATFS (needs to be added separately). Uses f_open, f_read, etc. */ #define LV_USE_FS_FATFS 0 #if LV_USE_FS_FATFS - #define LV_FS_FATFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ - #define LV_FS_FATFS_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ + #define LV_FS_FATFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_FATFS_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ + #define LV_FS_FATFS_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ #endif -/*API for memory-mapped file access. */ +/** API for memory-mapped file access. */ #define LV_USE_FS_MEMFS 0 #if LV_USE_FS_MEMFS - #define LV_FS_MEMFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_MEMFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ #endif -/*API for LittleFs. */ +/** API for LittleFs. */ #define LV_USE_FS_LITTLEFS 0 #if LV_USE_FS_LITTLEFS - #define LV_FS_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_LITTLEFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_LITTLEFS_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ #endif -/*API for Arduino LittleFs. */ +/** 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')*/ + #define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_ARDUINO_ESP_LITTLEFS_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ #endif -/*API for Arduino Sd. */ +/** 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')*/ + #define LV_FS_ARDUINO_SD_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ + #define LV_FS_ARDUINO_SD_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ #endif -/*LODEPNG decoder library*/ +/** API for UEFI */ +#define LV_USE_FS_UEFI 0 +#if LV_USE_FS_UEFI + #define LV_FS_UEFI_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ +#endif + +/** LODEPNG decoder library */ #define LV_USE_LODEPNG 1 // TASMOTA -/*PNG decoder(libpng) library*/ +/** PNG decoder(libpng) library */ #define LV_USE_LIBPNG 0 -/*BMP decoder library*/ +/** BMP decoder library */ #define LV_USE_BMP 0 -/* JPG + split JPG decoder library. - * Split JPG is a custom format optimized for embedded systems. */ +/** JPG + split JPG decoder library. + * Split JPG is a custom format optimized for embedded systems. */ #define LV_USE_TJPGD 0 -/* libjpeg-turbo decoder library. - * Supports complete JPEG specifications and high-performance JPEG decoding. */ +/** libjpeg-turbo decoder library. + * - Supports complete JPEG specifications and high-performance JPEG decoding. */ #define LV_USE_LIBJPEG_TURBO 0 -/*GIF decoder library*/ +/** GIF decoder library */ #define LV_USE_GIF 0 #if LV_USE_GIF - /*GIF decoder accelerate*/ + /** GIF decoder accelerate */ #define LV_GIF_CACHE_DECODE_DATA 0 #endif -/*Decode bin images to RAM*/ +/** Decode bin images to RAM */ #define LV_BIN_DECODER_RAM_LOAD 0 -/*RLE decompress library*/ +/** RLE decompress library */ #define LV_USE_RLE 0 -/*QR code library*/ +/** QR code library */ #define LV_USE_QRCODE 1 // TASMOTA -/*Barcode code library*/ +/** Barcode code library */ #define LV_USE_BARCODE 0 -/*FreeType library*/ +/** FreeType library */ #define LV_USE_FREETYPE 1 // TASMOTA #if LV_USE_FREETYPE - /*Let FreeType to use LVGL memory and file porting*/ + /** Let FreeType use LVGL memory and file porting */ #define LV_FREETYPE_USE_LVGL_PORT 0 - /*Cache count of the glyphs in FreeType. It means the number of glyphs that can be cached. - *The higher the value, the more memory will be used.*/ + /** Cache count of glyphs in FreeType, i.e. number of glyphs that can be cached. + * The higher the value, the more memory will be used. */ #define LV_FREETYPE_CACHE_FT_GLYPH_CNT 256 #endif -/* Built-in TTF decoder */ +/** Built-in TTF decoder */ #define LV_USE_TINY_TTF 0 #if LV_USE_TINY_TTF /* Enable loading TTF data from files */ @@ -892,299 +1031,433 @@ #define LV_TINY_TTF_CACHE_GLYPH_CNT 256 #endif -/*Rlottie library*/ +/** Rlottie library */ #define LV_USE_RLOTTIE 0 -/*Enable Vector Graphic APIs - *Requires `LV_USE_MATRIX = 1`*/ +/** 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 */ +/** Enable ThorVG (vector graphics library) from the src/libs folder */ #define LV_USE_THORVG_INTERNAL 0 -/* Enable ThorVG by assuming that its installed and linked to the project */ +/** Enable ThorVG by assuming that its installed and linked to the project */ #define LV_USE_THORVG_EXTERNAL 0 -/*Use lvgl built-in LZ4 lib*/ +/** Use lvgl built-in LZ4 lib */ #define LV_USE_LZ4_INTERNAL 0 -/*Use external LZ4 library*/ +/** Use external LZ4 library */ #define LV_USE_LZ4_EXTERNAL 0 -/*FFmpeg library for image decoding and playing videos - *Supports all major image formats so do not enable other image decoder with it*/ +/*SVG library + * - Requires `LV_USE_VECTOR_GRAPHIC = 1` */ +#define LV_USE_SVG 0 +#define LV_USE_SVG_ANIMATION 0 +#define LV_USE_SVG_DEBUG 0 + +/** FFmpeg library for image decoding and playing videos. + * Supports all major image formats so do not enable other image decoder with it. */ #define LV_USE_FFMPEG 0 #if LV_USE_FFMPEG - /*Dump input information to stderr*/ + /** Dump input information to stderr */ #define LV_FFMPEG_DUMP_FORMAT 0 + /** Use lvgl file path in FFmpeg Player widget + * You won't be able to open URLs after enabling this feature. + * Note that FFmpeg image decoder will always use lvgl file system. */ + #define LV_FFMPEG_PLAYER_USE_LV_FS 0 #endif /*================== * OTHERS *==================*/ +/* Documentation for several of the below items can be found here: https://docs.lvgl.io/master/details/auxiliary-modules/index.html . */ -/*1: Enable API to take snapshot for object*/ +/** 1: Enable API to take snapshot for object */ #define LV_USE_SNAPSHOT 0 -/*1: Enable system monitor component*/ +/** 1: Enable system monitor component */ #define LV_USE_SYSMON 0 #if LV_USE_SYSMON - /*Get the idle percentage. E.g. uint32_t my_get_idle(void);*/ - #define LV_SYSMON_GET_IDLE lv_timer_get_idle + /** Get the idle percentage. E.g. uint32_t my_get_idle(void); */ + #define LV_SYSMON_GET_IDLE lv_os_get_idle_percent - /*1: Show CPU usage and FPS count - * Requires `LV_USE_SYSMON = 1`*/ + /** 1: Show CPU usage and FPS count. + * - Requires `LV_USE_SYSMON = 1` */ #define LV_USE_PERF_MONITOR 0 #if LV_USE_PERF_MONITOR #define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT - /*0: Displays performance data on the screen, 1: Prints performance data using log.*/ + /** 0: Displays performance data on the screen; 1: Prints performance data using log. */ #define LV_USE_PERF_MONITOR_LOG_MODE 0 #endif - /*1: Show the used memory and the memory fragmentation - * Requires `LV_USE_STDLIB_MALLOC = LV_STDLIB_BUILTIN` - * Requires `LV_USE_SYSMON = 1`*/ + /** 1: Show used memory and memory fragmentation. + * - Requires `LV_USE_STDLIB_MALLOC = LV_STDLIB_BUILTIN` + * - Requires `LV_USE_SYSMON = 1`*/ #define LV_USE_MEM_MONITOR 0 #if LV_USE_MEM_MONITOR #define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT #endif - #endif /*LV_USE_SYSMON*/ -/*1: Enable the runtime performance profiler*/ +/** 1: Enable runtime performance profiler */ #define LV_USE_PROFILER 0 #if LV_USE_PROFILER - /*1: Enable the built-in profiler*/ + /** 1: Enable the built-in profiler */ #define LV_USE_PROFILER_BUILTIN 1 #if LV_USE_PROFILER_BUILTIN - /*Default profiler trace buffer size*/ - #define LV_PROFILER_BUILTIN_BUF_SIZE (16 * 1024) /*[bytes]*/ + /** Default profiler trace buffer size */ + #define LV_PROFILER_BUILTIN_BUF_SIZE (16 * 1024) /**< [bytes] */ + #define LV_PROFILER_BUILTIN_DEFAULT_ENABLE 1 #endif - /*Header to include for the profiler*/ + /** Header to include for profiler */ #define LV_PROFILER_INCLUDE "lvgl/src/misc/lv_profiler_builtin.h" - /*Profiler start point function*/ + /** Profiler start point function */ #define LV_PROFILER_BEGIN LV_PROFILER_BUILTIN_BEGIN - /*Profiler end point function*/ + /** Profiler end point function */ #define LV_PROFILER_END LV_PROFILER_BUILTIN_END - /*Profiler start point function with custom tag*/ + /** Profiler start point function with custom tag */ #define LV_PROFILER_BEGIN_TAG LV_PROFILER_BUILTIN_BEGIN_TAG - /*Profiler end point function with custom tag*/ + /** Profiler end point function with custom tag */ #define LV_PROFILER_END_TAG LV_PROFILER_BUILTIN_END_TAG + + /*Enable layout profiler*/ + #define LV_PROFILER_LAYOUT 1 + + /*Enable disp refr profiler*/ + #define LV_PROFILER_REFR 1 + + /*Enable draw profiler*/ + #define LV_PROFILER_DRAW 1 + + /*Enable indev profiler*/ + #define LV_PROFILER_INDEV 1 + + /*Enable decoder profiler*/ + #define LV_PROFILER_DECODER 1 + + /*Enable font profiler*/ + #define LV_PROFILER_FONT 1 + + /*Enable fs profiler*/ + #define LV_PROFILER_FS 1 + + /*Enable style profiler*/ + #define LV_PROFILER_STYLE 0 + + /*Enable timer profiler*/ + #define LV_PROFILER_TIMER 1 + + /*Enable cache profiler*/ + #define LV_PROFILER_CACHE 1 + + /*Enable event profiler*/ + #define LV_PROFILER_EVENT 1 #endif -/*1: Enable Monkey test*/ +/** 1: Enable Monkey test */ #define LV_USE_MONKEY 0 -/*1: Enable grid navigation*/ +/** 1: Enable grid navigation */ #define LV_USE_GRIDNAV 0 -/*1: Enable lv_obj fragment*/ +/** 1: Enable `lv_obj` fragment logic */ #define LV_USE_FRAGMENT 0 -/*1: Support using images as font in label or span widgets */ +/** 1: Support using images as font in label or span widgets */ #define LV_USE_IMGFONT 0 -/*1: Enable an observer pattern implementation*/ +/** 1: Enable an observer pattern implementation */ #define LV_USE_OBSERVER 0 // TASMOTA -/*1: Enable Pinyin input method*/ -/*Requires: lv_keyboard*/ +/** 1: Enable Pinyin input method + * - Requires: lv_keyboard */ #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 thesaurus*/ + /** 1: Use default thesaurus. + * @note 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*/ + /** Set maximum number of candidate panels that can be displayed. + * @note This needs to be adjusted according to size of screen. */ #define LV_IME_PINYIN_CAND_TEXT_NUM 6 - /*Use 9 key input(k9)*/ + /** Use 9-key input (k9). */ #define LV_IME_PINYIN_USE_K9_MODE 1 #if LV_IME_PINYIN_USE_K9_MODE == 1 #define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3 #endif /*LV_IME_PINYIN_USE_K9_MODE*/ #endif -/*1: Enable file explorer*/ -/*Requires: lv_table*/ +/** 1: Enable file explorer. + * - Requires: lv_table */ #define LV_USE_FILE_EXPLORER 0 #if LV_USE_FILE_EXPLORER - /*Maximum length of path*/ + /** Maximum length of path */ #define LV_FILE_EXPLORER_PATH_MAX_LEN (128) - /*Quick access bar, 1:use, 0:not use*/ - /*Requires: lv_list*/ + /** Quick access bar, 1:use, 0:do not use. + * - Requires: lv_list */ #define LV_FILE_EXPLORER_QUICK_ACCESS 1 #endif +/** 1: Enable Font manager */ +#define LV_USE_FONT_MANAGER 0 +#if LV_USE_FONT_MANAGER + +/**Font manager name max length*/ +#define LV_FONT_MANAGER_NAME_MAX_LEN 32 + +#endif + +/** Enable emulated input devices, time emulation, and screenshot compares. */ +#define LV_USE_TEST 0 +#if LV_USE_TEST + +/** Enable `lv_test_screenshot_compare`. + * Requires libpng and a few MB of extra RAM. */ +#define LV_USE_TEST_SCREENSHOT_COMPARE 0 +#endif /*LV_USE_TEST*/ + +/** Enable loading XML UIs runtime */ +#define LV_USE_XML 0 + +/*1: Enable color filter style*/ +#define LV_USE_COLOR_FILTER 0 /*================== * DEVICES *==================*/ -/*Use SDL to open window on PC and handle mouse and keyboard*/ +/** Use SDL to open window on PC and handle mouse and keyboard. */ #define LV_USE_SDL 0 #if LV_USE_SDL #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_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*/ #endif -/*Use X11 to open window on Linux desktop and handle mouse and keyboard*/ +/** Use X11 to open window on Linux desktop and handle mouse and keyboard */ #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 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*/ + #define LV_X11_DIRECT_EXIT 1 /**< Exit application when all X11 windows have been closed */ + #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 */ +/** 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*/ + #define LV_WAYLAND_BUF_COUNT 1 /**< Use 1 for single buffer with partial render mode or 2 for double buffer with full render mode*/ + #define LV_WAYLAND_USE_DMABUF 0 /**< Use DMA buffers for frame buffers. Requires LV_DRAW_USE_G2D */ + #define LV_WAYLAND_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL /**< DMABUF supports LV_DISPLAY_RENDER_MODE_FULL and LV_DISPLAY_RENDER_MODE_DIRECT*/ + /**< When LV_WAYLAND_USE_DMABUF is disabled, only LV_DISPLAY_RENDER_MODE_PARTIAL is supported*/ + #define LV_WAYLAND_WINDOW_DECORATIONS 0 /**< Draw client side window decorations only necessary on Mutter/GNOME. Not supported using DMABUF*/ + #define LV_WAYLAND_WL_SHELL 0 /**< Use the legacy wl_shell protocol instead of the default XDG shell*/ #endif -/*Driver for /dev/fb*/ +/** Driver for /dev/fb */ #define LV_USE_LINUX_FBDEV 0 #if LV_USE_LINUX_FBDEV #define LV_LINUX_FBDEV_BSD 0 #define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL #define LV_LINUX_FBDEV_BUFFER_COUNT 0 #define LV_LINUX_FBDEV_BUFFER_SIZE 60 + #define LV_LINUX_FBDEV_MMAP 1 #endif -/*Use Nuttx to open window and handle touchscreen*/ +/** Use Nuttx to open window and handle touchscreen */ #define LV_USE_NUTTX 0 #if LV_USE_NUTTX + #define LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP 0 + + /** Use independent image heap for default draw buffer */ + #define LV_NUTTX_DEFAULT_DRAW_BUF_USE_INDEPENDENT_IMAGE_HEAP 0 + #define LV_USE_NUTTX_LIBUV 0 - /*Use Nuttx custom init API to open window and handle touchscreen*/ + /** Use Nuttx custom init API to open window and handle touchscreen */ #define LV_USE_NUTTX_CUSTOM_INIT 0 - /*Driver for /dev/lcd*/ + /** Driver for /dev/lcd */ #define LV_USE_NUTTX_LCD 0 #if LV_USE_NUTTX_LCD #define LV_NUTTX_LCD_BUFFER_COUNT 0 #define LV_NUTTX_LCD_BUFFER_SIZE 60 #endif - /*Driver for /dev/input*/ + /** Driver for /dev/input */ #define LV_USE_NUTTX_TOUCHSCREEN 0 + /*Touchscreen cursor size in pixels(<=0: disable cursor)*/ + #define LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE 0 #endif -/*Driver for /dev/dri/card*/ +/** Driver for /dev/dri/card */ #define LV_USE_LINUX_DRM 0 -/*Interface for TFT_eSPI*/ +#if LV_USE_LINUX_DRM + + /* Use the MESA GBM library to allocate DMA buffers that can be + * shared across sub-systems and libraries using the Linux DMA-BUF API. + * The GBM library aims to provide a platform independent memory management system + * it supports the major GPU vendors - This option requires linking with libgbm */ + #define LV_LINUX_DRM_GBM_BUFFERS 0 +#endif + +/** Interface for TFT_eSPI */ #define LV_USE_TFT_ESPI 0 -/*Driver for evdev input devices*/ +/** Driver for evdev input devices */ #define LV_USE_EVDEV 0 -/*Driver for libinput input devices*/ +/** Driver for libinput input devices */ #define LV_USE_LIBINPUT 0 #if LV_USE_LIBINPUT #define LV_LIBINPUT_BSD 0 - /*Full keyboard support*/ + /** Full keyboard support */ #define LV_LIBINPUT_XKB 0 #if LV_LIBINPUT_XKB - /*"setxkbmap -query" can help find the right values for your keyboard*/ + /** "setxkbmap -query" can help find the right values for your keyboard */ #define LV_LIBINPUT_XKB_KEY_MAP { .rules = NULL, .model = "pc101", .layout = "us", .variant = NULL, .options = NULL } #endif #endif -/*Drivers for LCD devices connected via SPI/parallel port*/ +/* 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_FT81X 0 -#define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) +#if (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) + #define LV_USE_GENERIC_MIPI 1 +#else + #define LV_USE_GENERIC_MIPI 0 +#endif -/*Driver for Renesas GLCD*/ +/** Driver for Renesas GLCD */ #define LV_USE_RENESAS_GLCDC 0 -/* LVGL Windows backend */ +/** Driver for ST LTDC */ +#define LV_USE_ST_LTDC 0 +#if LV_USE_ST_LTDC + /* Only used for partial. */ + #define LV_ST_LTDC_USE_DMA2D_FLUSH 0 +#endif + +/** LVGL Windows backend */ #define LV_USE_WINDOWS 0 -/* Use OpenGL to open window on PC and handle mouse and keyboard */ +/** LVGL UEFI backend */ +#define LV_USE_UEFI 0 +#if LV_USE_UEFI + #define LV_USE_UEFI_INCLUDE "myefi.h" /**< Header that hides the actual framework (EDK2, gnu-efi, ...) */ + #define LV_UEFI_USE_MEMORY_SERVICES 0 /**< Use the memory functions from the boot services table */ +#endif + +/** 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 */ + #define LV_USE_OPENGLES_DEBUG 1 /**< Enable or disable debug for opengles */ #endif -/* QNX Screen display and input drivers */ +/** QNX Screen display and input drivers */ #define LV_USE_QNX 0 #if LV_USE_QNX - #define LV_QNX_BUF_COUNT 1 /*1 or 2*/ + #define LV_QNX_BUF_COUNT 1 /**< 1 or 2 */ #endif -/*================== -* EXAMPLES -*==================*/ +/*===================== +* BUILD OPTIONS +*======================*/ -/*Enable the examples to be built with the library*/ +/** Enable examples to be built with the library. */ #define LV_BUILD_EXAMPLES 0 // TASMOTA +/** Build the demos */ +#define LV_BUILD_DEMOS 0 // TASMOTA + /*=================== * DEMO USAGE ====================*/ -/*Show some widget. It might be required to increase `LV_MEM_SIZE` */ -#define LV_USE_DEMO_WIDGETS 0 +#if LV_BUILD_DEMOS + /** Show some widgets. This might be required to increase `LV_MEM_SIZE`. */ + #define LV_USE_DEMO_WIDGETS 0 + + /** Demonstrate usage of encoder and keyboard. */ + #define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 + + /** Benchmark your system */ + #define LV_USE_DEMO_BENCHMARK 0 -/*Demonstrate the usage of encoder and keyboard*/ -#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 + #if LV_USE_DEMO_BENCHMARK + /** Use fonts where bitmaps are aligned 16 byte and has Nx16 byte stride */ + #define LV_DEMO_BENCHMARK_ALIGNED_FONTS 0 + #endif -/*Benchmark your system*/ -#define LV_USE_DEMO_BENCHMARK 0 - -/*Render test for each primitives. Requires at least 480x272 display*/ -#define LV_USE_DEMO_RENDER 0 - -/*Stress test for LVGL*/ -#define LV_USE_DEMO_STRESS 0 - -/*Music player demo*/ -#define LV_USE_DEMO_MUSIC 0 -#if LV_USE_DEMO_MUSIC - #define LV_DEMO_MUSIC_SQUARE 0 - #define LV_DEMO_MUSIC_LANDSCAPE 0 - #define LV_DEMO_MUSIC_ROUND 0 - #define LV_DEMO_MUSIC_LARGE 0 - #define LV_DEMO_MUSIC_AUTO_PLAY 0 -#endif - -/*Flex layout demo*/ -#define LV_USE_DEMO_FLEX_LAYOUT 0 - -/*Smart-phone like multi-language demo*/ -#define LV_USE_DEMO_MULTILANG 0 - -/*Widget transformation demo*/ -#define LV_USE_DEMO_TRANSFORM 0 - -/*Demonstrate scroll settings*/ -#define LV_USE_DEMO_SCROLL 0 - -/*Vector graphic demo*/ -#define LV_USE_DEMO_VECTOR_GRAPHIC 0 + /** Render test for each primitive. + * - Requires at least 480x272 display. */ + #define LV_USE_DEMO_RENDER 0 + + /** Stress test for LVGL */ + #define LV_USE_DEMO_STRESS 0 + + /** Music player demo */ + #define LV_USE_DEMO_MUSIC 0 + #if LV_USE_DEMO_MUSIC + #define LV_DEMO_MUSIC_SQUARE 0 + #define LV_DEMO_MUSIC_LANDSCAPE 0 + #define LV_DEMO_MUSIC_ROUND 0 + #define LV_DEMO_MUSIC_LARGE 0 + #define LV_DEMO_MUSIC_AUTO_PLAY 0 + #endif + + /** Vector graphic demo */ + #define LV_USE_DEMO_VECTOR_GRAPHIC 0 + + /*--------------------------- + * Demos from lvgl/lv_demos + ---------------------------*/ + + /** Flex layout demo */ + #define LV_USE_DEMO_FLEX_LAYOUT 0 + + /** Smart-phone like multi-language demo */ + #define LV_USE_DEMO_MULTILANG 0 + + /** Widget transformation demo */ + #define LV_USE_DEMO_TRANSFORM 0 + + /** Demonstrate scroll settings */ + #define LV_USE_DEMO_SCROLL 0 + + /*E-bike demo with Lottie animations (if LV_USE_LOTTIE is enabled)*/ + #define LV_USE_DEMO_EBIKE 0 + #if LV_USE_DEMO_EBIKE + #define LV_DEMO_EBIKE_PORTRAIT 0 /*0: for 480x270..480x320, 1: for 480x800..720x1280*/ + #endif + + /** High-resolution demo */ + #define LV_USE_DEMO_HIGH_RES 0 + + /* Smart watch demo */ + #define LV_USE_DEMO_SMARTWATCH 0 +#endif /* LV_BUILD_DEMOS */ /*--END OF LV_CONF_H--*/