diff --git a/.gitlab/ci/astyle-rules.yml b/.gitlab/ci/astyle-rules.yml index 8a29d0a..c4a6faf 100644 --- a/.gitlab/ci/astyle-rules.yml +++ b/.gitlab/ci/astyle-rules.yml @@ -22,34 +22,7 @@ not_formatted_permanent: # - Upstream source code we don't want to modify # - Generated files check: false - include: - - "components/audio/dac_audio/test/wave_1ch_16bits.c" - - "components/audio/dac_audio/test/wave_1ch_8bits.c" - - "components/audio/dac_audio/test/wave_2ch_16bits.c" - - "components/audio/dac_audio/test/wave_2ch_8bits.c" - - "components/audio/pwm_audio/test/wave_1ch_16bits.c" - - "components/audio/pwm_audio/test/wave_1ch_8bits.c" - - "components/audio/pwm_audio/test/wave_2ch_16bits.c" - - "components/audio/pwm_audio/test/wave_2ch_8bits.c" - - "components/bluetooth/ble_profiles/esp/ble_ota/proto-c/" - - "components/bluetooth/ble_profiles/esp/ble_ota/python/" - - "components/display/touch_panel/calibration/basic_painter/fonts/" - - "components/usb/usb_stream/test_apps/main/wave_1ch_16bits.c" - - "components/utilities/xz/" - - "docs/_static/esp32s2_adc_range_to_3300.patch" - - "docs/_static/esp32s2_adc_range_to_3300_v531.patch" - - "docs/_static/esp32s3_adc_range_to_3300.patch" - - "docs/_static/esp32s3_adc_range_to_3300_v531.patch" - - "docs/doxygen-known-warnings.txt" - - "docs/sphinx-known-warnings.txt" - - "examples/usb/device/usb_webcam/eyes_show/" - - "examples/ai/esp_dl/self_learning_classification/main/ui" - - "examples/usb/host/usb_camera_lcd_display/components/esp_painter/font/" - - "examples/usb/host/usb_camera_mic_spk/main/wave_1ch_16bits.c" - - "examples/robot/ragtime_panther/follower/main/ui/" - - "components/sensors/gas/bme690/bme69x.c" - - "components/sensors/gas/bme690/bme69x.h" - - "components/sensors/gas/bme690/bme69x_defs.h" + docs: # Docs directory contains some .inc files, which are not C include files diff --git a/.gitlab/ci/build.yml b/.gitlab/ci/build.yml index 7b02f15..689aa82 100644 --- a/.gitlab/ci/build.yml +++ b/.gitlab/ci/build.yml @@ -38,15 +38,16 @@ # By configuring this macro, you can append the compiled configuration file. # For example, using "sdkconf.etc=default" specifies the default sdkconfig file. EXAMPLE_CONFIG: "=" + EXAMPLE_TARGET: "" EXAMPLE_APPEND_ARGS: "" EXAMPLE_BOARD: "default" BUILD_RECURSIVE: "1" script: - - pip install idf_build_apps + - pip install idf_build_apps esp-bmgr-assist - | python .gitlab/ci/build_apps.py ${EXAMPLE_DIR} \ --config ${EXAMPLE_CONFIG} \ - -t all \ + -t ${EXAMPLE_TARGET} \ -r ${BUILD_RECURSIVE} \ -vv \ --board ${EXAMPLE_BOARD} \ @@ -62,25 +63,25 @@ .build_idf_active_release_version: parallel: matrix: # EOL date - - IMAGE: espressif/idf:release-v5.5 # 2028-01-21 - -# ESP-IDF 6.0 is currently in pre-release stage. - -.build_idf_active_release_version_with_pre_release: - parallel: - matrix: - - IMAGE: espressif/idf:release-v5.2 - - IMAGE: espressif/idf:release-v5.3 - - IMAGE: espressif/idf:release-v5.4 - - IMAGE: espressif/idf:release-v5.5 - - IMAGE: espressif/idf:release-v6.0 - build_application_basic_demo: extends: - .build_examples_template - .rules:build:application_basic_demo - - .build_idf_active_release_version + parallel: + matrix: + - IMAGE: espressif/idf:release-v5.5 + EXAMPLE_BOARD: esp_SensairHalo + EXAMPLE_TARGET: esp32c5 + - IMAGE: espressif/idf:release-v5.5 + EXAMPLE_BOARD: esp_SensairShuttle + EXAMPLE_TARGET: esp32c5 + - IMAGE: espressif/idf:release-v5.5 + EXAMPLE_BOARD: esp_vocat_board_v1_2 + EXAMPLE_TARGET: esp32s3 + - IMAGE: espressif/idf:release-v5.5 + EXAMPLE_BOARD: esp32_S3_DevKitC_1 + EXAMPLE_TARGET: esp32s3 variables: EXAMPLE_DIR: application/basic_demo diff --git a/.gitlab/ci/build_apps.py b/.gitlab/ci/build_apps.py index e11964e..4ee3a85 100644 --- a/.gitlab/ci/build_apps.py +++ b/.gitlab/ci/build_apps.py @@ -134,50 +134,6 @@ class CustomApp(CMakeApp): shutil.rmtree(proj_path / 'components' / 'gen_bmgr_codes', ignore_errors=True) (proj_path / 'board_manager.defaults').unlink(missing_ok=True) - def _download_bmgr_component(self) -> bool: - """ - Extract the esp_board_manager dependency from the manifest file and download it. - Returns True if successful, False otherwise. - """ - if not all([yaml, download_project_dependencies, ManifestManager, ProjectRequirements]): - logger.warning('idf-component-manager is not available, cannot download board manager component') - return False - - proj = Path(self.work_dir).absolute() - managed_path = proj / 'managed_components' - lock_path = proj / 'dependencies.lock' - - bmgr_dep = self._find_bmgr_dependency() - if not bmgr_dep: - logger.warning( - 'esp_board_manager dependency not found in project manifests under %s/main or %s/components/*', - proj, - proj, - ) - return False - - manifest_path, bmgr_key, bmgr_value = bmgr_dep - - managed_path.mkdir(parents=True, exist_ok=True) - - try: - with tempfile.TemporaryDirectory() as temp_dir: - temp_manifest = Path(temp_dir) / 'idf_component.yml' - with open(temp_manifest, 'w', encoding='utf-8') as f: - yaml.dump({'dependencies': {bmgr_key: bmgr_value}}, f) - - manifest = ManifestManager(str(temp_dir), 'temp').load() - download_project_dependencies( - ProjectRequirements([manifest]), - str(lock_path), - str(managed_path), - ) - logger.info('Successfully downloaded esp_board_manager component from %s to %s', manifest_path, managed_path) - return True - except Exception as e: - logger.error('Error downloading esp_board_manager component: %s', e) - return False - def _pre_hook(self, board_name: str) -> None: logger.info( "Pre build hook for app '%s' at '%s' for target '%s', board '%s'", @@ -194,17 +150,8 @@ class CustomApp(CMakeApp): logger.warning('IDF_PATH is not set; skip board manager config generation.') return - # Download board manager component if needed - bmgr_path = Path(self.work_dir).absolute() / 'managed_components' / 'espressif__esp_board_manager' - if not bmgr_path.exists(): - logger.info('Board manager component not found, downloading...') - if not self._download_bmgr_component(): - logger.error('Failed to download board manager component, cannot generate config') - return - # Set environment variable for IDF_EXTRA_ACTIONS_PATH env = os.environ.copy() - env['IDF_EXTRA_ACTIONS_PATH'] = str(bmgr_path) subprocess.run( [ diff --git a/application/basic_demo/CMakeLists.txt b/application/basic_demo/CMakeLists.txt index 7ea5fab..dd1bf86 100644 --- a/application/basic_demo/CMakeLists.txt +++ b/application/basic_demo/CMakeLists.txt @@ -1,14 +1,5 @@ cmake_minimum_required(VERSION 3.16) -set(EXTRA_COMPONENT_DIRS - "../../components/claw_modules" - "../../components/lua_modules" - "../../components/claw_capabilities" - ) -if(NOT DEFINED IDF_TARGET) - set(IDF_TARGET "esp32s3" CACHE STRING "ESP-IDF target") -endif() - include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(basic_demo) diff --git a/application/basic_demo/boards/esp32_S3_DevKitC_1/board_devices.yaml b/application/basic_demo/boards/esp32_S3_DevKitC_1/board_devices.yaml new file mode 100644 index 0000000..594490e --- /dev/null +++ b/application/basic_demo/boards/esp32_S3_DevKitC_1/board_devices.yaml @@ -0,0 +1,53 @@ +version: 1.0.0 +# Devices Configuration +devices: + + - name: led_strip + chip: ws2812 + type: custom + version: default + init_skip: true + dependencies: + espressif/led_strip: + version: "^3.0" + public: true + config: + max_leds: 1 # Number of LEDs in the strip + peripherals: + - name: rmt_tx # RMT TX peripheral used by the LED strip + + # Example GPIO Button device configuration + - name: gpio_button_0 # The name of the device, must be unique + type: button # The type of the device + sub_type: gpio # Button sub type: "gpio", "adc_single", or "adc_multi" + config: + # GPIO Configuration + active_level: 0 # [TO_BE_CONFIRMED] Active level (0-low, 1-high) when button is pressed + enable_power_save: false # Enable power save mode (default: false) + disable_pull: false # Disable internal pull-up/pull-down (default: false) + + # Button Timing Configuration + long_press_time: 2000 # Long press time in milliseconds (default: 2000) + short_press_time: 100 # Short press time in milliseconds (default: 100) + + # Event Configuration (NEW - Easy button features) + events_cfg: + press_down: true # Enable press down event (default: true) + press_up: true # Enable press up event (default: true) + single_click: true # Enable single click event (default: true) + double_click: true # Enable double click event (default: true) + multi_click: false # Enable multi click event (default: false) + click_counts: [] # Multi click counts configuration (default: []) + # eg: Set to [3, 4] means enable multi_click event with 3 and 4 counts + long_press_start: true # Enable long press start event (default: true) + long_press_start_time: [] # Long press start time configuration in ms (default: []) + # eg: Set to [3000, 4000] means enable long_press_start event with 3 and 4 seconds + long_press_hold: false # Enable long press hold event (default: false) + long_press_up: true # Enable long press up event (default: true) + long_press_up_time: [] # Long press up time configuration in ms (default: []) + press_repeat: false # Enable press repeat event (default: false) + press_repeat_done: false # Enable press repeat done event (default: false) + press_end: false # Enable press end event (default: false) + + peripherals: + - name: gpio_button # [TO_BE_CONFIRMED] GPIO peripheral name diff --git a/application/basic_demo/boards/esp32_S3_DevKitC_1/board_info.yaml b/application/basic_demo/boards/esp32_S3_DevKitC_1/board_info.yaml new file mode 100644 index 0000000..2d9ce06 --- /dev/null +++ b/application/basic_demo/boards/esp32_S3_DevKitC_1/board_info.yaml @@ -0,0 +1,5 @@ +board: esp32_S3_DevKitC_1 +chip: esp32s3 +version: 1.3.0 +description: "ESP32-S3-DevKitC-1 Development Board" +manufacturer: "ESPRESSIF" diff --git a/application/basic_demo/boards/esp32_S3_DevKitC_1/board_peripherals.yaml b/application/basic_demo/boards/esp32_S3_DevKitC_1/board_peripherals.yaml new file mode 100644 index 0000000..855ff8a --- /dev/null +++ b/application/basic_demo/boards/esp32_S3_DevKitC_1/board_peripherals.yaml @@ -0,0 +1,27 @@ +version: 1.0.0 +# Peripherals Configuration +peripherals: + - name: gpio_button + type: gpio + config: + pin: 0 + mode: GPIO_MODE_INPUT + default_level: 1 + + - name: rmt_tx + type: rmt + role: tx + config: + gpio_num: 38 + clk_src: RMT_CLK_SRC_DEFAULT + resolution_hz: 10000000 + mem_block_symbols: 64 + trans_queue_depth: 4 + intr_priority: 1 + flags: + invert_out: false + with_dma: true # RMT peripheral can connect to DMA channel in esp32s3 + io_loop_back: false + io_od_mode: false + allow_pd: false + init_level: false diff --git a/application/basic_demo/boards/esp32_S3_DevKitC_1/sdkconfig.defaults.board b/application/basic_demo/boards/esp32_S3_DevKitC_1/sdkconfig.defaults.board new file mode 100644 index 0000000..98269c9 --- /dev/null +++ b/application/basic_demo/boards/esp32_S3_DevKitC_1/sdkconfig.defaults.board @@ -0,0 +1,9 @@ + +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_8MB.csv" +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_120M=y diff --git a/application/basic_demo/boards/esp32_S3_DevKitC_1/setup_device.c b/application/basic_demo/boards/esp32_S3_DevKitC_1/setup_device.c new file mode 100644 index 0000000..a1be78d --- /dev/null +++ b/application/basic_demo/boards/esp32_S3_DevKitC_1/setup_device.c @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "esp_log.h" +#include "esp_check.h" +#include "esp_board_manager_includes.h" +#include "gen_board_device_custom.h" +#include "periph_rmt.h" +#include "led_strip.h" +#include "led_strip_rmt.h" +#include "led_strip_types.h" diff --git a/application/basic_demo/boards/esp_SensairHalo/board_devices.yaml b/application/basic_demo/boards/esp_SensairHalo/board_devices.yaml new file mode 100644 index 0000000..80b635c --- /dev/null +++ b/application/basic_demo/boards/esp_SensairHalo/board_devices.yaml @@ -0,0 +1,143 @@ +version: 1.0.0 +# Devices Configuration +devices: + - name: display_lcd + type: display_lcd + version: default + sub_type: parlio + chip: ili9341 + dependencies: + espressif/esp_lcd_ili9341: "*" + config: + mirror_x: false + mirror_y: true + swap_xy: true + x_max: 284 # [TO_BE_CONFIRMED] Horizontal resolution + y_max: 240 # [TO_BE_CONFIRMED] Vertical resolution + need_reset: true # Whether to reset the LCD panel during initialization (default: true) + # dev_display_lcd_parlio_sub_config_t fields for Parlio communication + io_parl_config: + dc_gpio_num: 7 # [IO] GPIO used for D/C line + clk_gpio_num: 1 # [IO] GPIO used for CLK line + cs_gpio_num: 6 # [IO] GPIO used for CS line + # GPIOs used for data lines (ESP_PARLIO_LCD_WIDTH_MAX == 8); 1-line SPI uses index 0 only, rest -1 + data_gpio_nums: [0, -1, -1, -1, -1, -1, -1, -1] # [IO] GPIOs used for data lines + data_width: 1 # Number of data lines, 1 (SPI) or 8 (I80) + pclk_hz: 40000000 # [TO_BE_CONFIRMED] Frequency of pixel clock + clk_src: PARLIO_CLK_SRC_DEFAULT # Clock source for the Parlio peripheral (parlio_clock_source_t) + max_transfer_bytes: 136320 # Maximum transfer size; determines internal DMA link length + dma_burst_size: 32 # DMA burst size, in bytes + trans_queue_depth: 10 # Transaction queue size; larger queue, higher throughput + lcd_cmd_bits: 8 # [TO_BE_CONFIRMED] Bit-width of LCD command + lcd_param_bits: 8 # [TO_BE_CONFIRMED] Bit-width of LCD parameter + dc_levels: + dc_cmd_level: 0 # [TO_BE_CONFIRMED] Level of DC line in CMD phase + dc_data_level: 1 # [TO_BE_CONFIRMED] Level of DC line in DATA phase + flags: + # If set, high CS selects device; otherwise CS is low-active + cs_active_high: false + lcd_panel_config: + reset_gpio_num: -1 + rgb_ele_order: LCD_RGB_ELEMENT_ORDER_RGB # [TO_BE_CONFIRMED] RGB element order (default: RGB) + # Valid values: + # - LCD_RGB_ELEMENT_ORDER_RGB + # - LCD_RGB_ELEMENT_ORDER_BGR + data_endian: LCD_RGB_DATA_ENDIAN_LITTLE # [TO_BE_CONFIRMED] Data endianness (default: LITTLE) + # Valid values: + # - LCD_RGB_DATA_ENDIAN_BIG + # - LCD_RGB_DATA_ENDIAN_LITTLE + bits_per_pixel: 16 # [TO_BE_CONFIRMED] Bits per pixel (default: 16) + flags: + reset_active_high: true # Reset pin active level (default: false) + vendor_config: "" + + + # Touch Panel Configuration + - name: lcd_touch + chip: cst816s + type: lcd_touch_i2c + version: default + dependencies: + espressif/esp_lcd_touch_cst816s: "*" + config: + # esp_lcd_panel_io_i2c_config_t fields for touch communication + io_i2c_config: + dev_addr: 0x15 # CST816S I2C address (different from default 0x5A) + peripherals: + - name: i2c_master # I2C peripheral for touch communication + + # esp_lcd_touch_config_t fields for touch configuration + touch_config: + x_max: 284 # Maximum X coordinate (BSP_LCD_H_RES) + y_max: 240 # Maximum Y coordinate (BSP_LCD_V_RES) + int_gpio_num: -1 # Interrupt GPIO (BSP_LCD_TOUCH_INT) + flags: + swap_xy: true # Swap X and Y coordinates (default: false) + mirror_x: false # Mirror X coordinates (default: false) + mirror_y: true # Mirror Y coordinates (default: false) + + - name: touch_button + chip: bs8112 + type: custom + version: default + dependencies: + touch_ic_bs8112a3: + version: "^0.1" + peripherals: + - name: i2c_master # I2C peripheral for touch communication + config: + irq_pin: 4 + + - name: camera + type: camera + sub_type: spi + config: + spi_config: + intf: ESP_CAM_CTLR_SPI_CAM_INTF_SPI + # SPI CAM data I/O mode (SPI interface only supports 1-bit): ESP_CAM_CTLR_SPI_CAM_IO_MODE_1BIT / _2BIT + io_mode: ESP_CAM_CTLR_SPI_CAM_IO_MODE_1BIT + spi_port: 1 # [TO_BE_CONFIRMED] SPI port + spi_cs_pin: 27 # [IO] SPI CS pin + spi_sclk_pin: 25 # [IO] SPI SCLK pin + spi_data0_io_pin: 23 # [IO] SPI data0 I/O pin + spi_data1_io_pin: -1 # [IO] SPI data1 I/O pin + reset_pin: -1 # [IO] SPI interface camera sensor reset pin + pwdn_pin: -1 # [IO] SPI interface camera sensor power down pin + xclk_source: ESP_CAM_SENSOR_XCLK_LEDC + xclk_freq: 24000000 # [TO_BE_CONFIRMED] XCLK frequency in Hz (default: 20MHz) + xclk_pin: 24 # [IO] XCLK pin + xclk_ledc_cfg: + timer: 0 # [TO_BE_CONFIRMED] The timer source of channel + clk_cfg: LEDC_AUTO_CLK # [TO_BE_CONFIRMED] LEDC source clock from ledc_clk_cfg_t + channel: 0 # [TO_BE_CONFIRMED] LEDC channel used for XCLK + peripherals: + - name: i2c_master # Must match a periph_i2c name; provides SCCB i2c_handle to esp_video + frequency: 100000 # SCCB I2C frequency (Hz) + + - name: audio_adc + chip: internal + type: audio_codec + config: + adc_enabled: true + dac_enabled: false + adc_local_cfg: + channel_list: [4] # required + sample_rate_hz: 16000 + max_store_buf_size: 1024 + conv_frame_size: 256 + unit_id: ADC_UNIT_1 + atten: ADC_ATTEN_DB_0 + + - name: audio_dac + chip: internal + type: audio_codec + version: default + config: + dac_enabled: true + peripherals: + - name: i2s_audio_out + tx_aux_out_io: 10 + tx_aux_out_invert: true + - name: gpio_pa_control + gain: 6 + active_level: 1 diff --git a/application/basic_demo/boards/esp_SensairHalo/board_info.yaml b/application/basic_demo/boards/esp_SensairHalo/board_info.yaml new file mode 100644 index 0000000..4fc033d --- /dev/null +++ b/application/basic_demo/boards/esp_SensairHalo/board_info.yaml @@ -0,0 +1,5 @@ +board: esp_SensairHalo +chip: esp32c5 +version: 1.3.0 +description: "ESP-SensairHalo Development Board" +manufacturer: "ESPRESSIF" diff --git a/application/basic_demo/boards/esp_SensairHalo/board_peripherals.yaml b/application/basic_demo/boards/esp_SensairHalo/board_peripherals.yaml new file mode 100644 index 0000000..db549a4 --- /dev/null +++ b/application/basic_demo/boards/esp_SensairHalo/board_peripherals.yaml @@ -0,0 +1,51 @@ +version: 1.0.0 +# Peripherals Configuration +peripherals: + - name: i2c_master + type: i2c + role: master + config: + port: 0 + pins: + sda: 2 + scl: 3 + + - name: i2s_audio_out + type: i2s + role: master + format: pdm-out + config: + sample_rate_hz: 16000 + clk_src: I2S_CLK_SRC_DEFAULT + mclk_multiple: 256 + up_sample_fp: 960 + up_sample_fs: 441 + bclk_div: 8 + data_bit_width: 16 + slot_bit_width: I2S_SLOT_BIT_WIDTH_AUTO + slot_mode: I2S_SLOT_MODE_MONO + slot_mask: I2S_PDM_SLOT_LEFT + data_fmt: "I2S_PDM_DATA_FMT_PCM" + sd_prescale: 0 + sd_scale: I2S_PDM_SIG_SCALING_MUL_4 + hp_scale: I2S_PDM_SIG_SCALING_MUL_4 + lp_scale: I2S_PDM_SIG_SCALING_MUL_4 + sinc_scale: I2S_PDM_SIG_SCALING_MUL_4 + line_mode: I2S_PDM_TX_ONE_LINE_CODEC + hp_en: false + hp_cut_off_freq_hz: 35.5 + sd_dither: 0 + sd_dither2: 1 + pins: + doubt: 9 # [IO] Data output pin + invert_flags: + clk_inv: false + + # PA CONTROL + - name: gpio_pa_control + type: gpio + role: io + config: + pin: 8 # GPIO pin number + mode: GPIO_MODE_OUTPUT + default_level: 1 diff --git a/application/basic_demo/boards/esp_SensairHalo/sdkconfig.defaults.board b/application/basic_demo/boards/esp_SensairHalo/sdkconfig.defaults.board new file mode 100644 index 0000000..d9f4f61 --- /dev/null +++ b/application/basic_demo/boards/esp_SensairHalo/sdkconfig.defaults.board @@ -0,0 +1,20 @@ + +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_16MB.csv" +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_80M=y + +CONFIG_CODEC_DUMMY_SUPPORT=y +CONFIG_CODEC_DATA_ADC_SUPPORT=y +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y +CONFIG_ESP_CONSOLE_SECONDARY_NONE=y +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED=y +CONFIG_ESP_CONSOLE_UART_NUM=-1 + +CONFIG_CAMERA_BF3901=y +CONFIG_CAMERA_BF3901_SPI_RGB565_240X320_15FPS=y +CONFIG_CAMERA_BF3901_SPI_YUV422_240X320_15FPS=n diff --git a/application/basic_demo/boards/esp_SensairHalo/setup_device.c b/application/basic_demo/boards/esp_SensairHalo/setup_device.c new file mode 100644 index 0000000..ca70341 --- /dev/null +++ b/application/basic_demo/boards/esp_SensairHalo/setup_device.c @@ -0,0 +1,131 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "esp_board_device.h" +#include "esp_codec_dev.h" +#include "periph_i2c.h" +#include "periph_gpio.h" +#include "gen_board_device_custom.h" +#include "dev_audio_codec.h" +#include "touch_ic_bs8112a3.h" +#include "dev_custom.h" +#include "esp_lcd_panel_ops.h" +#include "esp_lcd_ili9341.h" +#include "esp_lcd_touch_cst816s.h" +#include "esp_log.h" +#include "esp_check.h" + +static const char *TAG = "SETUP_DEVICE"; + +static const ili9341_lcd_init_cmd_t s_vendor_init_cmds[] = { + {0x11, NULL, 0, 120}, + {0x3A, (uint8_t []){0x05}, 1, 0}, + {0xB2, (uint8_t []){0x0C, 0x0C, 0x00, 0x33, 0x33}, 5, 0}, + {0xB7, (uint8_t []){0x05}, 1, 0}, + {0xBB, (uint8_t []){0x21}, 1, 0}, + {0xC0, (uint8_t []){0x2C}, 1, 0}, + {0xC2, (uint8_t []){0x01}, 1, 0}, + {0xC3, (uint8_t []){0x15}, 1, 0}, + {0xC6, (uint8_t []){0x0F}, 1, 0}, + {0xD0, (uint8_t []){0xA7}, 1, 0}, + {0xD0, (uint8_t []){0xA4, 0xA1}, 2, 0}, + {0xD6, (uint8_t []){0xA1}, 1, 0}, + {0xE0, (uint8_t []){0xF0, 0x05, 0x0E, 0x08, 0x0A, 0x17, 0x39, 0x54, + 0x4E, 0x37, 0x12, 0x12, 0x31, 0x37}, 14, 0}, + {0xE1, (uint8_t []){0xF0, 0x10, 0x14, 0x0D, 0x0B, 0x05, 0x39, 0x44, + 0x4D, 0x38, 0x14, 0x14, 0x2E, 0x35}, 14, 0}, + {0xE4, (uint8_t []){0x23, 0x00, 0x00}, 3, 0}, + {0x21, NULL, 0, 0}, + {0x29, NULL, 0, 0}, + {0x2C, NULL, 0, 0}, +}; + +static const ili9341_vendor_config_t vendor_config = { + .init_cmds = s_vendor_init_cmds, + .init_cmds_size = sizeof(s_vendor_init_cmds) / sizeof(s_vendor_init_cmds[0]), +}; + +esp_err_t lcd_panel_factory_entry_t(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_dev_config_t *panel_dev_config, esp_lcd_panel_handle_t *ret_panel) +{ + esp_lcd_panel_dev_config_t panel_dev_cfg = {0}; + memcpy(&panel_dev_cfg, panel_dev_config, sizeof(esp_lcd_panel_dev_config_t)); + + panel_dev_cfg.vendor_config = (void *)&vendor_config; + int ret = esp_lcd_new_panel_ili9341(io, &panel_dev_cfg, ret_panel); + if (ret != ESP_OK) { + ESP_LOGE("lcd_panel_factory_entry_t", "New ili9341 panel failed"); + return ret; + } + esp_lcd_panel_set_gap(*ret_panel, 36, 0); + return ESP_OK; +} + +esp_err_t lcd_touch_factory_entry_t(esp_lcd_panel_io_handle_t io, const esp_lcd_touch_config_t *touch_dev_config, esp_lcd_touch_handle_t *ret_touch) +{ + esp_lcd_touch_config_t touch_cfg = {0}; + memcpy(&touch_cfg, touch_dev_config, sizeof(esp_lcd_touch_config_t)); + if (touch_cfg.int_gpio_num != GPIO_NUM_NC) { + ESP_LOGW("lcd_touch_factory_entry_t", "Touch interrupt supported!"); + touch_cfg.interrupt_callback = NULL; + } + esp_err_t ret = esp_lcd_touch_new_i2c_cst816s(io, &touch_cfg, ret_touch); + if (ret != ESP_OK) { + ESP_LOGE("lcd_touch_factory_entry_t", "Failed to create gt911 touch driver: %s", esp_err_to_name(ret)); + return ret; + } + return ESP_OK; +} + +static int touch_button_init(void *config, int cfg_size, void **device_handle) +{ + esp_err_t ret = ESP_OK; + dev_custom_touch_button_config_t *touch_button_cfg = (dev_custom_touch_button_config_t *)config; + ESP_LOGI(TAG, "Initializing %s device", touch_button_cfg->name); + + ESP_RETURN_ON_FALSE(strcmp(touch_button_cfg->chip, "bs8112") == 0, ESP_ERR_INVALID_ARG, + TAG, "Unsupported chip: %s", touch_button_cfg->chip); + + // Try to get existing I2C bus handle first + i2c_master_bus_handle_t i2c_bus_handle = NULL; + esp_board_periph_ref_handle(touch_button_cfg->peripheral_name, (void**)&i2c_bus_handle); + ESP_RETURN_ON_FALSE(i2c_bus_handle != NULL, ESP_ERR_INVALID_STATE, TAG, "Failed to get I2C bus handle"); + + // Use default chip configuration + bs8112a3_chip_config_t default_chip_cfg = TOUCH_IC_BS8112A3_DEFAULT_CHIP_CONFIG(); + default_chip_cfg.lsc_mode = BS8112A3_LSC_MODE_NORMAL; + default_chip_cfg.irq_oms = BS8112A3_IRQ_OMS_LEVEL_HOLD; + default_chip_cfg.k12_mode = BS8112A3_K12_MODE_IRQ; + + touch_ic_bs8112a3_config_t bs8112_cfg = { + .i2c_bus_handle = i2c_bus_handle, + .device_address = BS8112A3_I2C_ADDR, + .scl_speed_hz = 400000, + .irq_pin = touch_button_cfg->irq_pin, + .chip_config = &default_chip_cfg, + }; + + touch_ic_bs8112a3_handle_t touch_handle = NULL; + ret = touch_ic_bs8112a3_create(&bs8112_cfg, &touch_handle); + ESP_RETURN_ON_ERROR(ret, TAG, "Failed to create BS8112A3 touch IC instance"); + + // Store handle in device_handle + *device_handle = (void *)touch_handle; + return ESP_OK; +} + +static int touch_button_deinit(void *device_handle) +{ + if (!device_handle) { + return ESP_OK; + } + + touch_ic_bs8112a3_handle_t touch_handle = (touch_ic_bs8112a3_handle_t)device_handle; + esp_err_t ret = touch_ic_bs8112a3_delete(touch_handle); + + return ret; +} + +CUSTOM_DEVICE_IMPLEMENT(touch_button, touch_button_init, touch_button_deinit); diff --git a/application/basic_demo/boards/esp_SensairShuttle/board_devices.yaml b/application/basic_demo/boards/esp_SensairShuttle/board_devices.yaml new file mode 100644 index 0000000..a723284 --- /dev/null +++ b/application/basic_demo/boards/esp_SensairShuttle/board_devices.yaml @@ -0,0 +1,87 @@ +version: 1.0.0 +# Devices Configuration +devices: + + - name: display_lcd + chip: ili9341 + type: display_lcd + sub_type: spi + version: default + dependencies: + espressif/esp_lcd_ili9341: "*" + config: + mirror_x: true + mirror_y: false + swap_xy: true + x_max: 284 + y_max: 240 + # esp_lcd_panel_io_spi_config_t fields + io_spi_config: + cs_gpio_num: 25 # GPIO14 - LCD_CS (BSP_LCD_CS) + dc_gpio_num: 26 # GPIO45 - LCD_DC (BSP_LCD_DC) + spi_mode: 3 # Traditional SPI mode (0~3) + pclk_hz: 20000000 # Frequency of pixel clock + flags: + sio_mode: true # Single line mode + peripherals: + - name: spi_display # SPI peripheral for LCD communication + + lcd_panel_config: + reset_gpio_num: -1 + data_endian: "LCD_RGB_DATA_ENDIAN_LITTLE" # LCD_RGB_DATA_ENDIAN_LITTLE + flags: + reset_active_high: true + # ST77916 specific configuration + vendor_config: NULL + + # Touch Panel Configuration + - name: lcd_touch + chip: cst816s + type: lcd_touch_i2c + version: default + dependencies: + espressif/esp_lcd_touch_cst816s: "*" + config: + # esp_lcd_panel_io_i2c_config_t fields for touch communication + io_i2c_config: + dev_addr: 0x15 # CST816S I2C address (different from default 0x5A) + peripherals: + - name: i2c_master # I2C peripheral for touch communication + + # esp_lcd_touch_config_t fields for touch configuration + touch_config: + x_max: 240 # Maximum X coordinate (BSP_LCD_H_RES) + y_max: 284 # Maximum Y coordinate (BSP_LCD_V_RES) + int_gpio_num: -1 # Interrupt GPIO (BSP_LCD_TOUCH_INT) + flags: + swap_xy: true # Swap X and Y coordinates (default: false) + mirror_x: true # Mirror X coordinates (default: false) + mirror_y: true # Mirror Y coordinates (default: false) + + - name: audio_dac + chip: internal + type: audio_codec + version: default + config: + dac_enabled: true + peripherals: + - name: i2s_audio_out + tx_aux_out_io: 8 + tx_aux_out_invert: true + - name: gpio_pa_control + gain: 6 + active_level: 1 + + - name: audio_adc + chip: internal + type: audio_codec + config: + adc_enabled: true + dac_enabled: false + adc_local_cfg: + channel_list: [5] # required + sample_rate_hz: 16000 + max_store_buf_size: 1024 + conv_frame_size: 256 + unit_id: ADC_UNIT_1 + atten: ADC_ATTEN_DB_0 diff --git a/application/basic_demo/boards/esp_SensairShuttle/board_info.yaml b/application/basic_demo/boards/esp_SensairShuttle/board_info.yaml new file mode 100644 index 0000000..65afd5d --- /dev/null +++ b/application/basic_demo/boards/esp_SensairShuttle/board_info.yaml @@ -0,0 +1,5 @@ +board: esp_SensairShuttle +chip: esp32c5 +version: 1.3.0 +description: "ESP-SensairShuttle Development Board" +manufacturer: "ESPRESSIF" diff --git a/application/basic_demo/boards/esp_SensairShuttle/board_peripherals.yaml b/application/basic_demo/boards/esp_SensairShuttle/board_peripherals.yaml new file mode 100644 index 0000000..e8c8172 --- /dev/null +++ b/application/basic_demo/boards/esp_SensairShuttle/board_peripherals.yaml @@ -0,0 +1,63 @@ +version: 1.0.0 +# Peripherals Configuration +peripherals: + - name: i2c_master + type: i2c + role: master + config: + port: 0 + pins: + sda: 2 + scl: 3 + + # LCD SPI Configuration for ST77916 QSPI + - name: spi_display + type: spi + role: master + config: + # spi_bus_config_t fields + spi_bus_config: + spi_port: SPI2_HOST # 0: SPI1_HOST, 1: SPI2_HOST, 2: SPI3_HOST + data0_io_num: 23 # MOSI_IO_NUM + sclk_io_num: 24 # SPI Clock signal + max_transfer_sz: 3600 # Maximum transfer size in bytes + + - name: i2s_audio_out + type: i2s + role: master + format: pdm-out + config: + sample_rate_hz: 16000 + clk_src: I2S_CLK_SRC_DEFAULT + mclk_multiple: 256 + up_sample_fp: 960 + up_sample_fs: 441 + bclk_div: 8 + data_bit_width: 16 + slot_bit_width: I2S_SLOT_BIT_WIDTH_AUTO + slot_mode: I2S_SLOT_MODE_MONO + slot_mask: I2S_PDM_SLOT_LEFT + data_fmt: "I2S_PDM_DATA_FMT_PCM" + sd_prescale: 0 + sd_scale: I2S_PDM_SIG_SCALING_MUL_4 + hp_scale: I2S_PDM_SIG_SCALING_MUL_4 + lp_scale: I2S_PDM_SIG_SCALING_MUL_4 + sinc_scale: I2S_PDM_SIG_SCALING_MUL_4 + line_mode: I2S_PDM_TX_ONE_LINE_CODEC + hp_en: false + hp_cut_off_freq_hz: 35.5 + sd_dither: 0 + sd_dither2: 1 + pins: + doubt: 7 # [IO] Data output pin + invert_flags: + clk_inv: false + + # PA CONTROL + - name: gpio_pa_control + type: gpio + role: io + config: + pin: 1 # GPIO pin number + mode: GPIO_MODE_OUTPUT + default_level: 1 diff --git a/application/basic_demo/boards/esp_SensairShuttle/sdkconfig.defaults.board b/application/basic_demo/boards/esp_SensairShuttle/sdkconfig.defaults.board new file mode 100644 index 0000000..d7d9cda --- /dev/null +++ b/application/basic_demo/boards/esp_SensairShuttle/sdkconfig.defaults.board @@ -0,0 +1,16 @@ + +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_16MB.csv" +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_80M=y + +CONFIG_CODEC_DUMMY_SUPPORT=y +CONFIG_CODEC_DATA_ADC_SUPPORT=y +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y +CONFIG_ESP_CONSOLE_SECONDARY_NONE=y +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED=y +CONFIG_ESP_CONSOLE_UART_NUM=-1 diff --git a/application/basic_demo/boards/esp_SensairShuttle/setup_device.c b/application/basic_demo/boards/esp_SensairShuttle/setup_device.c new file mode 100644 index 0000000..d6acfea --- /dev/null +++ b/application/basic_demo/boards/esp_SensairShuttle/setup_device.c @@ -0,0 +1,85 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "esp_board_manager_includes.h" +#include "esp_lcd_panel_ops.h" +#include "esp_lcd_ili9341.h" +#include "esp_lcd_touch_cst816s.h" +#include "esp_log.h" +#include "esp_check.h" + +static const char *TAG = "SETUP_DEVICE"; + +static const ili9341_lcd_init_cmd_t vendor_specific_init[] = { + {0x11, NULL, 0, 120}, // Sleep Out + {0x36, (uint8_t []){0x00}, 1, 0}, // Memory Data Access Control + {0x3A, (uint8_t []){0x05}, 1, 0}, // Interface Pixel Format (16-bit) + {0xB2, (uint8_t []){0x0C, 0x0C, 0x00, 0x33, 0x33}, 5, 0}, // Porch Setting + {0xB7, (uint8_t []){0x05}, 1, 0}, // Gate Control + {0xBB, (uint8_t []){0x21}, 1, 0}, // VCOM Setting + {0xC0, (uint8_t []){0x2C}, 1, 0}, // LCM Control + {0xC2, (uint8_t []){0x01}, 1, 0}, // VDV and VRH Command Enable + {0xC3, (uint8_t []){0x15}, 1, 0}, // VRH Set + {0xC6, (uint8_t []){0x0F}, 1, 0}, // Frame Rate Control + {0xD0, (uint8_t []){0xA7}, 1, 0}, // Power Control 1 + {0xD0, (uint8_t []){0xA4, 0xA1}, 2, 0}, // Power Control 1 + {0xD6, (uint8_t []){0xA1}, 1, 0}, // Gate output GND in sleep mode + { + 0xE0, (uint8_t []) + { + 0xF0, 0x05, 0x0E, 0x08, 0x0A, 0x17, 0x39, 0x54, + 0x4E, 0x37, 0x12, 0x12, 0x31, 0x37 + }, 14, 0 + }, // Positive Gamma Control + { + 0xE1, (uint8_t []) + { + 0xF0, 0x10, 0x14, 0x0D, 0x0B, 0x05, 0x39, 0x44, + 0x4D, 0x38, 0x14, 0x14, 0x2E, 0x35 + }, 14, 0 + }, // Negative Gamma Control + {0xE4, (uint8_t []){0x23, 0x00, 0x00}, 3, 0}, // Gate position control + {0x21, NULL, 0, 0}, // Display Inversion On + {0x29, NULL, 0, 0}, // Display On + {0x2C, NULL, 0, 0}, // Memory Write +}; + +// define st77916_vendor_config_t +static const ili9341_vendor_config_t vendor_config = { + .init_cmds = vendor_specific_init, + .init_cmds_size = sizeof(vendor_specific_init) / sizeof(vendor_specific_init[0]), +}; + +esp_err_t lcd_panel_factory_entry_t(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_dev_config_t *panel_dev_config, esp_lcd_panel_handle_t *ret_panel) +{ + esp_lcd_panel_dev_config_t panel_dev_cfg = {0}; + memcpy(&panel_dev_cfg, panel_dev_config, sizeof(esp_lcd_panel_dev_config_t)); + + panel_dev_cfg.vendor_config = (void *)&vendor_config; + int ret = esp_lcd_new_panel_ili9341(io, &panel_dev_cfg, ret_panel); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "New ili9341 panel failed"); + return ret; + } + // esp_lcd_panel_set_gap(*ret_panel, 36, 0); + return ESP_OK; +} + +esp_err_t lcd_touch_factory_entry_t(esp_lcd_panel_io_handle_t io, const esp_lcd_touch_config_t *touch_dev_config, esp_lcd_touch_handle_t *ret_touch) +{ + esp_lcd_touch_config_t touch_cfg = {0}; + memcpy(&touch_cfg, touch_dev_config, sizeof(esp_lcd_touch_config_t)); + if (touch_cfg.int_gpio_num != GPIO_NUM_NC) { + ESP_LOGW(TAG, "Touch interrupt supported!"); + touch_cfg.interrupt_callback = NULL; + } + esp_err_t ret = esp_lcd_touch_new_i2c_cst816s(io, &touch_cfg, ret_touch); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to create gt911 touch driver: %s", esp_err_to_name(ret)); + return ret; + } + return ESP_OK; +} diff --git a/application/basic_demo/boards/esp_vocat_board_v1_2/board_devices.yaml b/application/basic_demo/boards/esp_vocat_board_v1_2/board_devices.yaml new file mode 100644 index 0000000..db81ca4 --- /dev/null +++ b/application/basic_demo/boards/esp_vocat_board_v1_2/board_devices.yaml @@ -0,0 +1,153 @@ +# Devices Configuration for EchoEar Core Board V1.0 +devices: + # Audio Power Control after Audio init + - name: audio_power + type: gpio_ctrl + version: default + config: + active_level: 1 + default_level: 0 + peripherals: + - name: gpio_power_audio + + # LCD and SDCard Power Control before LCD init + - name: lcd_sdcard_power + type: power_ctrl + sub_type: gpio + peripherals: + - name: gpio_power_lcd_sdcard + active_level: 0 + + - name: lcd_brightness + type: ledc_ctrl + version: default + config: + default_percent: 100 # 0-100, default 0 percent + peripherals: + - name: ledc_backlight # LEDC peripheral for GPIO 44 + + - name: audio_dac + chip: es8311 + type: audio_codec + version: default + config: + adc_enabled: false + dac_enabled: true + dac_max_channel: 1 + # DAC channel mask, 1-enable, 0-disable, layout: left,right + dac_channel_mask: "1" # Left, Right enable + mclk_enabled: true + + # Power amplifier configuration + peripherals: + - name: gpio_pa_control + gain: 6 # dB + active_level: 1 # 0-low, 1-high + + # I2S interface configuration + - name: i2s_audio_out + # I2C interface configuration + - name: i2c_master + address: 0x30 + frequency: 400000 # Hz + + # Audio ADC Configuration (ES7210) + - name: audio_adc + chip: es7210 + type: audio_codec + version: default + config: + adc_enabled: true + adc_max_channel: 4 + # The channel mask, 1-enable, 0-disable + # e.g."0111", bit0: Mic0 enable, bit1: Mic1 enable, bit2: Mic2 enable, bit3: Mic3 enable, bit4: Mic4 disable + adc_channel_mask: "0111" # Mic0, Mic1, Mic2 enable + adc_channel_labels: ['NA', 'RE', 'FR', 'FL'] # MSB ~ LSB + adc_init_gain: 0 # dB + + # I2S interface configuration + peripherals: + # I2S interface configuration + - name: i2s_audio_in + # I2C interface configuration + - name: i2c_master + address: 0x80 + frequency: 400000 # Hz + + - name: fs_sdcard + type: fs_fat + sub_type: sdmmc + power_ctrl_device: lcd_sdcard_power + version: default + config: + vfs_config: + format_if_mount_failed: true + sub_config: + bus_width: 1 # 1, 4, or 8 for slot 0; 1 or 4 for slot 1 + slot_flags: "SDMMC_SLOT_FLAG_INTERNAL_PULLUP" # SDMMC_SLOT_FLAG_INTERNAL_PULLUP, SDMMC_SLOT_FLAG_WP_ACTIVE_HIGH, SDMMC_SLOT_FLAG_UHS1 + pins: + clk: 16 # GPIO_NUM_16 + cmd: 38 # GPIO_NUM_38 + d0: 17 # GPIO_NUM_17 + + # LCD Display Configuration + - name: display_lcd + chip: st77916 + type: display_lcd + sub_type: spi + power_ctrl_device: lcd_sdcard_power + version: default + dependencies: + espressif/esp_lcd_st77916: "*" + config: + x_max: 360 + y_max: 360 + need_reset: false + # esp_lcd_panel_io_spi_config_t fields + io_spi_config: + cs_gpio_num: 14 # GPIO14 - LCD_CS (BSP_LCD_CS) + dc_gpio_num: 45 # GPIO45 - LCD_DC (BSP_LCD_DC) + spi_mode: 0 # Traditional SPI mode (0~3) + lcd_cmd_bits: 32 # Bit-width of LCD command + flags: + quad_mode: true # Quad mode (4 data lines) - ST77916 uses quad mode + + lcd_panel_config: + reset_gpio_num: 47 + flags: + reset_active_high: true # Reset pin active level (default: false) + # ST77916 specific configuration + vendor_config: NULL + + peripherals: + - name: spi_display # SPI peripheral for LCD communication + + # Touch Panel Configuration + - name: lcd_touch + chip: cst816s + type: lcd_touch_i2c + version: default + dependencies: + espressif/esp_lcd_touch_cst816s: "*" + config: + # esp_lcd_panel_io_i2c_config_t fields for touch communication + io_i2c_config: + dev_addr: 0x15 # CST816S I2C address (different from default 0x5A) + peripherals: + - name: i2c_master # I2C peripheral for touch communication + + # esp_lcd_touch_config_t fields for touch configuration + touch_config: + x_max: 360 # Maximum X coordinate (BSP_LCD_H_RES) + y_max: 360 # Maximum Y coordinate (BSP_LCD_V_RES) + int_gpio_num: 10 # Interrupt GPIO (BSP_LCD_TOUCH_INT) + + # LED GREEN + - name: led_green + type: gpio_ctrl + version: default + config: + active_level: 0 + default_level: 1 + peripherals: + - name: gpio_led_g diff --git a/application/basic_demo/boards/esp_vocat_board_v1_2/board_info.yaml b/application/basic_demo/boards/esp_vocat_board_v1_2/board_info.yaml new file mode 100644 index 0000000..256abc8 --- /dev/null +++ b/application/basic_demo/boards/esp_vocat_board_v1_2/board_info.yaml @@ -0,0 +1,5 @@ +board: esp_vocat_board_v1_2 +chip: esp32s3 +version: 1.2.0 +description: "ESP VoCat Board V1.2 AI Pet Companion Development Board" +manufacturer: "ESPRESSIF" diff --git a/application/basic_demo/boards/esp_vocat_board_v1_2/board_peripherals.yaml b/application/basic_demo/boards/esp_vocat_board_v1_2/board_peripherals.yaml new file mode 100644 index 0000000..fffe109 --- /dev/null +++ b/application/basic_demo/boards/esp_vocat_board_v1_2/board_peripherals.yaml @@ -0,0 +1,94 @@ +peripherals: + # I2C Configuration + - name: i2c_master + type: i2c + role: master + config: + port: 0 + pins: + sda: 2 # GPIO2 - I2C SDA + scl: 1 # GPIO1 - I2C SCL + + # I2S Audio Configuration + - name: i2s_audio_out + type: i2s + role: master + format: std-out # std-out, std-in + config: &i2s_config + port: 0 + # Clock configuration + sample_rate_hz: 16000 # Sample rate in Hz + mclk_multiple: 256 # Multiple of MCLK to sample rate (256 or 384 for 24-bit) + # Slot configuration + data_bit_width: 16 # Data bit width (valid data bits per sample) + slot_bit_width: I2S_SLOT_BIT_WIDTH_AUTO # Total bits per slot (I2S_SLOT_BIT_WIDTH_AUTO or specific value) + slot_mode: I2S_SLOT_MODE_MONO # I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO + slot_mask: I2S_STD_SLOT_BOTH # I2S_STD_SLOT_LEFT, I2S_STD_SLOT_RIGHT, or I2S_STD_SLOT_BOTH slots + ws_width: 16 # WS signal width in BCLK ticks + + # GPIO configuration + pins: + mclk: 42 # GPIO42 - I2S_MCLK (BSP_I2S_MCLK) + bclk: 40 # GPIO40 - I2S_SCLK (BSP_I2S_SCLK) + ws: 39 # GPIO39 - I2S_LCLK (BSP_I2S_LCLK) + doubt: 41 # GPIO41 - I2S_DOUT (BSP_I2S_DOUT) + din: 3 # GPIO3 - I2S_DSIN (BSP_I2S_DSIN) + + - name: i2s_audio_in + type: i2s + role: master + format: std-in + config: *i2s_config + + # LCD SPI Configuration for ST77916 QSPI + - name: spi_display + type: spi + role: master + config: + # spi_bus_config_t fields + spi_bus_config: + spi_port: SPI2_HOST # 0: SPI1_HOST, 1: SPI2_HOST, 2: SPI3_HOST + data0_io_num: 46 # MOSI_IO_NUM + data1_io_num: 13 # MISO_IO_NUM + data2_io_num: 11 # QUADWP_IO_NUM + data3_io_num: 12 # QUADHD_IO_NUM + sclk_io_num: 18 # SPI Clock signal + max_transfer_sz: 14400 # Maximum transfer size in bytes : width * 2 * 20 + + - name: ledc_backlight + type: ledc + role: none + config: + gpio_num: 44 # GPIO44 - LED control pin + freq_hz: 2000 # PWM frequency 2kHz + duty: 100 # Initial duty cycle (0%) + duty_resolution: LEDC_TIMER_10_BIT # 10-bit duty resolution + + ## CHIP POWER_ON_OFF LCD and SD card power control + - name: gpio_power_lcd_sdcard + type: gpio + config: + pin: 9 # GPIO9 - LCD_RST (CHIP POWER_ON_OFF) + mode: GPIO_MODE_OUTPUT + default_level: 1 + + - name: gpio_power_audio + type: gpio + config: + pin: 48 # GPIO48 - POWER_AUDIO + mode: GPIO_MODE_OUTPUT + default_level: 1 + + - name: gpio_pa_control + type: gpio + config: + pin: 15 # GPIO15 - AMP Control + mode: GPIO_MODE_OUTPUT + default_level: 0 + + - name: gpio_led_g + type: gpio + config: + pin: 43 # GPIO43 - LED GREEN + mode: GPIO_MODE_OUTPUT + default_level: 1 diff --git a/application/basic_demo/boards/esp_vocat_board_v1_2/sdkconfig.defaults.board b/application/basic_demo/boards/esp_vocat_board_v1_2/sdkconfig.defaults.board new file mode 100644 index 0000000..364fd4c --- /dev/null +++ b/application/basic_demo/boards/esp_vocat_board_v1_2/sdkconfig.defaults.board @@ -0,0 +1,10 @@ +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_16MB.csv" +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_80M=y + +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y diff --git a/application/basic_demo/boards/esp_vocat_board_v1_2/setup_device.c b/application/basic_demo/boards/esp_vocat_board_v1_2/setup_device.c new file mode 100644 index 0000000..33bace3 --- /dev/null +++ b/application/basic_demo/boards/esp_vocat_board_v1_2/setup_device.c @@ -0,0 +1,233 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_board_device.h" +#include "esp_lcd_st77916.h" +#include "esp_lcd_touch_cst816s.h" +#include "esp_log.h" + +static const st77916_lcd_init_cmd_t vendor_specific_init_default[] = { + {0xF0, (uint8_t[]) {0x28}, 1, 0}, + {0xF2, (uint8_t[]) {0x28}, 1, 0}, + {0x73, (uint8_t[]) {0xF0}, 1, 0}, + {0x7C, (uint8_t[]) {0xD1}, 1, 0}, + {0x83, (uint8_t[]) {0xE0}, 1, 0}, + {0x84, (uint8_t[]) {0x61}, 1, 0}, + {0xF2, (uint8_t[]) {0x82}, 1, 0}, + {0xF0, (uint8_t[]) {0x00}, 1, 0}, + {0xF0, (uint8_t[]) {0x01}, 1, 0}, + {0xF1, (uint8_t[]) {0x01}, 1, 0}, + {0xB0, (uint8_t[]) {0x56}, 1, 0}, + {0xB1, (uint8_t[]) {0x4D}, 1, 0}, + {0xB2, (uint8_t[]) {0x24}, 1, 0}, + {0xB4, (uint8_t[]) {0x87}, 1, 0}, + {0xB5, (uint8_t[]) {0x44}, 1, 0}, + {0xB6, (uint8_t[]) {0x8B}, 1, 0}, + {0xB7, (uint8_t[]) {0x40}, 1, 0}, + {0xB8, (uint8_t[]) {0x86}, 1, 0}, + {0xBA, (uint8_t[]) {0x00}, 1, 0}, + {0xBB, (uint8_t[]) {0x08}, 1, 0}, + {0xBC, (uint8_t[]) {0x08}, 1, 0}, + {0xBD, (uint8_t[]) {0x00}, 1, 0}, + {0xC0, (uint8_t[]) {0x80}, 1, 0}, + {0xC1, (uint8_t[]) {0x10}, 1, 0}, + {0xC2, (uint8_t[]) {0x37}, 1, 0}, + {0xC3, (uint8_t[]) {0x80}, 1, 0}, + {0xC4, (uint8_t[]) {0x10}, 1, 0}, + {0xC5, (uint8_t[]) {0x37}, 1, 0}, + {0xC6, (uint8_t[]) {0xA9}, 1, 0}, + {0xC7, (uint8_t[]) {0x41}, 1, 0}, + {0xC8, (uint8_t[]) {0x01}, 1, 0}, + {0xC9, (uint8_t[]) {0xA9}, 1, 0}, + {0xCA, (uint8_t[]) {0x41}, 1, 0}, + {0xCB, (uint8_t[]) {0x01}, 1, 0}, + {0xD0, (uint8_t[]) {0x91}, 1, 0}, + {0xD1, (uint8_t[]) {0x68}, 1, 0}, + {0xD2, (uint8_t[]) {0x68}, 1, 0}, + {0xF5, (uint8_t[]) {0x00, 0xA5}, 2, 0}, + {0xDD, (uint8_t[]) {0x4F}, 1, 0}, + {0xDE, (uint8_t[]) {0x4F}, 1, 0}, + {0xF1, (uint8_t[]) {0x10}, 1, 0}, + {0xF0, (uint8_t[]) {0x00}, 1, 0}, + {0xF0, (uint8_t[]) {0x02}, 1, 0}, + {0xE0, (uint8_t[]) {0xF0, 0x0A, 0x10, 0x09, 0x09, 0x36, 0x35, 0x33, 0x4A, 0x29, 0x15, 0x15, 0x2E, 0x34}, 14, 0}, + {0xE1, (uint8_t[]) {0xF0, 0x0A, 0x0F, 0x08, 0x08, 0x05, 0x34, 0x33, 0x4A, 0x39, 0x15, 0x15, 0x2D, 0x33}, 14, 0}, + {0xF0, (uint8_t[]) {0x10}, 1, 0}, + {0xF3, (uint8_t[]) {0x10}, 1, 0}, + {0xE0, (uint8_t[]) {0x07}, 1, 0}, + {0xE1, (uint8_t[]) {0x00}, 1, 0}, + {0xE2, (uint8_t[]) {0x00}, 1, 0}, + {0xE3, (uint8_t[]) {0x00}, 1, 0}, + {0xE4, (uint8_t[]) {0xE0}, 1, 0}, + {0xE5, (uint8_t[]) {0x06}, 1, 0}, + {0xE6, (uint8_t[]) {0x21}, 1, 0}, + {0xE7, (uint8_t[]) {0x01}, 1, 0}, + {0xE8, (uint8_t[]) {0x05}, 1, 0}, + {0xE9, (uint8_t[]) {0x02}, 1, 0}, + {0xEA, (uint8_t[]) {0xDA}, 1, 0}, + {0xEB, (uint8_t[]) {0x00}, 1, 0}, + {0xEC, (uint8_t[]) {0x00}, 1, 0}, + {0xED, (uint8_t[]) {0x0F}, 1, 0}, + {0xEE, (uint8_t[]) {0x00}, 1, 0}, + {0xEF, (uint8_t[]) {0x00}, 1, 0}, + {0xF8, (uint8_t[]) {0x00}, 1, 0}, + {0xF9, (uint8_t[]) {0x00}, 1, 0}, + {0xFA, (uint8_t[]) {0x00}, 1, 0}, + {0xFB, (uint8_t[]) {0x00}, 1, 0}, + {0xFC, (uint8_t[]) {0x00}, 1, 0}, + {0xFD, (uint8_t[]) {0x00}, 1, 0}, + {0xFE, (uint8_t[]) {0x00}, 1, 0}, + {0xFF, (uint8_t[]) {0x00}, 1, 0}, + {0x60, (uint8_t[]) {0x40}, 1, 0}, + {0x61, (uint8_t[]) {0x04}, 1, 0}, + {0x62, (uint8_t[]) {0x00}, 1, 0}, + {0x63, (uint8_t[]) {0x42}, 1, 0}, + {0x64, (uint8_t[]) {0xD9}, 1, 0}, + {0x65, (uint8_t[]) {0x00}, 1, 0}, + {0x66, (uint8_t[]) {0x00}, 1, 0}, + {0x67, (uint8_t[]) {0x00}, 1, 0}, + {0x68, (uint8_t[]) {0x00}, 1, 0}, + {0x69, (uint8_t[]) {0x00}, 1, 0}, + {0x6A, (uint8_t[]) {0x00}, 1, 0}, + {0x6B, (uint8_t[]) {0x00}, 1, 0}, + {0x70, (uint8_t[]) {0x40}, 1, 0}, + {0x71, (uint8_t[]) {0x03}, 1, 0}, + {0x72, (uint8_t[]) {0x00}, 1, 0}, + {0x73, (uint8_t[]) {0x42}, 1, 0}, + {0x74, (uint8_t[]) {0xD8}, 1, 0}, + {0x75, (uint8_t[]) {0x00}, 1, 0}, + {0x76, (uint8_t[]) {0x00}, 1, 0}, + {0x77, (uint8_t[]) {0x00}, 1, 0}, + {0x78, (uint8_t[]) {0x00}, 1, 0}, + {0x79, (uint8_t[]) {0x00}, 1, 0}, + {0x7A, (uint8_t[]) {0x00}, 1, 0}, + {0x7B, (uint8_t[]) {0x00}, 1, 0}, + {0x80, (uint8_t[]) {0x48}, 1, 0}, + {0x81, (uint8_t[]) {0x00}, 1, 0}, + {0x82, (uint8_t[]) {0x06}, 1, 0}, + {0x83, (uint8_t[]) {0x02}, 1, 0}, + {0x84, (uint8_t[]) {0xD6}, 1, 0}, + {0x85, (uint8_t[]) {0x04}, 1, 0}, + {0x86, (uint8_t[]) {0x00}, 1, 0}, + {0x87, (uint8_t[]) {0x00}, 1, 0}, + {0x88, (uint8_t[]) {0x48}, 1, 0}, + {0x89, (uint8_t[]) {0x00}, 1, 0}, + {0x8A, (uint8_t[]) {0x08}, 1, 0}, + {0x8B, (uint8_t[]) {0x02}, 1, 0}, + {0x8C, (uint8_t[]) {0xD8}, 1, 0}, + {0x8D, (uint8_t[]) {0x04}, 1, 0}, + {0x8E, (uint8_t[]) {0x00}, 1, 0}, + {0x8F, (uint8_t[]) {0x00}, 1, 0}, + {0x90, (uint8_t[]) {0x48}, 1, 0}, + {0x91, (uint8_t[]) {0x00}, 1, 0}, + {0x92, (uint8_t[]) {0x0A}, 1, 0}, + {0x93, (uint8_t[]) {0x02}, 1, 0}, + {0x94, (uint8_t[]) {0xDA}, 1, 0}, + {0x95, (uint8_t[]) {0x04}, 1, 0}, + {0x96, (uint8_t[]) {0x00}, 1, 0}, + {0x97, (uint8_t[]) {0x00}, 1, 0}, + {0x98, (uint8_t[]) {0x48}, 1, 0}, + {0x99, (uint8_t[]) {0x00}, 1, 0}, + {0x9A, (uint8_t[]) {0x0C}, 1, 0}, + {0x9B, (uint8_t[]) {0x02}, 1, 0}, + {0x9C, (uint8_t[]) {0xDC}, 1, 0}, + {0x9D, (uint8_t[]) {0x04}, 1, 0}, + {0x9E, (uint8_t[]) {0x00}, 1, 0}, + {0x9F, (uint8_t[]) {0x00}, 1, 0}, + {0xA0, (uint8_t[]) {0x48}, 1, 0}, + {0xA1, (uint8_t[]) {0x00}, 1, 0}, + {0xA2, (uint8_t[]) {0x05}, 1, 0}, + {0xA3, (uint8_t[]) {0x02}, 1, 0}, + {0xA4, (uint8_t[]) {0xD5}, 1, 0}, + {0xA5, (uint8_t[]) {0x04}, 1, 0}, + {0xA6, (uint8_t[]) {0x00}, 1, 0}, + {0xA7, (uint8_t[]) {0x00}, 1, 0}, + {0xA8, (uint8_t[]) {0x48}, 1, 0}, + {0xA9, (uint8_t[]) {0x00}, 1, 0}, + {0xAA, (uint8_t[]) {0x07}, 1, 0}, + {0xAB, (uint8_t[]) {0x02}, 1, 0}, + {0xAC, (uint8_t[]) {0xD7}, 1, 0}, + {0xAD, (uint8_t[]) {0x04}, 1, 0}, + {0xAE, (uint8_t[]) {0x00}, 1, 0}, + {0xAF, (uint8_t[]) {0x00}, 1, 0}, + {0xB0, (uint8_t[]) {0x48}, 1, 0}, + {0xB1, (uint8_t[]) {0x00}, 1, 0}, + {0xB2, (uint8_t[]) {0x09}, 1, 0}, + {0xB3, (uint8_t[]) {0x02}, 1, 0}, + {0xB4, (uint8_t[]) {0xD9}, 1, 0}, + {0xB5, (uint8_t[]) {0x04}, 1, 0}, + {0xB6, (uint8_t[]) {0x00}, 1, 0}, + {0xB7, (uint8_t[]) {0x00}, 1, 0}, + {0xB8, (uint8_t[]) {0x48}, 1, 0}, + {0xB9, (uint8_t[]) {0x00}, 1, 0}, + {0xBA, (uint8_t[]) {0x0B}, 1, 0}, + {0xBB, (uint8_t[]) {0x02}, 1, 0}, + {0xBC, (uint8_t[]) {0xDB}, 1, 0}, + {0xBD, (uint8_t[]) {0x04}, 1, 0}, + {0xBE, (uint8_t[]) {0x00}, 1, 0}, + {0xBF, (uint8_t[]) {0x00}, 1, 0}, + {0xC0, (uint8_t[]) {0x10}, 1, 0}, + {0xC1, (uint8_t[]) {0x47}, 1, 0}, + {0xC2, (uint8_t[]) {0x56}, 1, 0}, + {0xC3, (uint8_t[]) {0x65}, 1, 0}, + {0xC4, (uint8_t[]) {0x74}, 1, 0}, + {0xC5, (uint8_t[]) {0x88}, 1, 0}, + {0xC6, (uint8_t[]) {0x99}, 1, 0}, + {0xC7, (uint8_t[]) {0x01}, 1, 0}, + {0xC8, (uint8_t[]) {0xBB}, 1, 0}, + {0xC9, (uint8_t[]) {0xAA}, 1, 0}, + {0xD0, (uint8_t[]) {0x10}, 1, 0}, + {0xD1, (uint8_t[]) {0x47}, 1, 0}, + {0xD2, (uint8_t[]) {0x56}, 1, 0}, + {0xD3, (uint8_t[]) {0x65}, 1, 0}, + {0xD4, (uint8_t[]) {0x74}, 1, 0}, + {0xD5, (uint8_t[]) {0x88}, 1, 0}, + {0xD6, (uint8_t[]) {0x99}, 1, 0}, + {0xD7, (uint8_t[]) {0x01}, 1, 0}, + {0xD8, (uint8_t[]) {0xBB}, 1, 0}, + {0xD9, (uint8_t[]) {0xAA}, 1, 0}, + {0xF3, (uint8_t[]) {0x01}, 1, 0}, + {0xF0, (uint8_t[]) {0x00}, 1, 0}, + {0x21, (uint8_t[]) {}, 0, 0}, + {0x11, (uint8_t[]) {}, 0, 0}, + {0x00, (uint8_t[]) {}, 0, 120}, +}; + +// define st77916_vendor_config_t +static const st77916_vendor_config_t vendor_config = { + .init_cmds = vendor_specific_init_default, + .init_cmds_size = sizeof(vendor_specific_init_default) / sizeof(vendor_specific_init_default[0]), + .flags = { + .use_qspi_interface = 1, // QSPI + } +}; + +esp_err_t lcd_panel_factory_entry_t(esp_lcd_panel_io_handle_t io, const esp_lcd_panel_dev_config_t *panel_dev_config, esp_lcd_panel_handle_t *ret_panel) +{ + esp_lcd_panel_dev_config_t panel_dev_cfg = {0}; + memcpy(&panel_dev_cfg, panel_dev_config, sizeof(esp_lcd_panel_dev_config_t)); + + panel_dev_cfg.vendor_config = (void *)&vendor_config; + int ret = esp_lcd_new_panel_st77916(io, &panel_dev_cfg, ret_panel); + if (ret != ESP_OK) { + ESP_LOGE("lcd_panel_factory_entry_t", "New ST77916 panel failed"); + return ret; + } + return ESP_OK; +} + +esp_err_t lcd_touch_factory_entry_t(esp_lcd_panel_io_handle_t io, const esp_lcd_touch_config_t *touch_dev_config, esp_lcd_touch_handle_t *ret_touch) +{ + esp_lcd_touch_config_t touch_cfg = {0}; + memcpy(&touch_cfg, touch_dev_config, sizeof(esp_lcd_touch_config_t)); + esp_err_t ret = esp_lcd_touch_new_i2c_cst816s(io, &touch_cfg, ret_touch); + if (ret != ESP_OK) { + ESP_LOGE("lcd_touch_factory_entry_t", "Failed to create CST816S touch driver: %s", esp_err_to_name(ret)); + return ret; + } + return ESP_OK; +} diff --git a/application/basic_demo/fatfs_image/lua/audio_demo.lua b/application/basic_demo/fatfs_image/lua/audio_demo.lua new file mode 100644 index 0000000..3756d0f --- /dev/null +++ b/application/basic_demo/fatfs_image/lua/audio_demo.lua @@ -0,0 +1,66 @@ +local audio = require("audio") +local bm = require("board_manager") +local delay = require("delay") + +local REC_PATH = "/fatfs/data/rec.wav" +local input_codec, input_rate, input_channels, input_bits, input_gain = + bm.get_audio_codec_input_params("audio_adc") +if not input_codec then + print("[audio_demo] ERROR: get_audio_codec_input_params(audio_adc) failed: " .. tostring(input_rate)) + return +end + +local output_codec, output_rate, output_channels, output_bits = + bm.get_audio_codec_output_params("audio_dac") +if not output_codec then + print("[audio_demo] ERROR: get_audio_codec_output_params(audio_dac) failed: " .. tostring(output_rate)) + return +end + +local input, in_err = audio.new_input(input_codec, input_rate, input_channels, input_bits) +if not input then + print("[audio_demo] ERROR: new_input failed: " .. tostring(in_err)) + return +end + +local output, out_err = audio.new_output(output_codec, output_rate, output_channels, output_bits) +if not output then + print("[audio_demo] ERROR: new_output failed: " .. tostring(out_err)) + audio.close(input) + return +end + +print(string.format("[audio_demo] input=%dHz/%dch/%dbit output=%dHz/%dch/%dbit", + input_rate, input_channels, input_bits, + output_rate, output_channels, output_bits)) + +local function close_all() + pcall(audio.close, output) + pcall(audio.close, input) +end + +local ok, err = xpcall(function() + -- ── 1. volume ──────────────────────────────────────────────────────────── + print("[audio_demo] setting volume to 100...") + audio.set_volume(output, 100) + local vol = audio.get_volume(output) + print("[audio_demo] current volume: " .. tostring(vol)) + + -- ── 2. record ──────────────────────────────────────────────────────────── + print("[audio_demo] recording 3 seconds to " .. REC_PATH .. " ...") + local info = audio.record_wav(input, REC_PATH, 3000) + print(string.format("[audio_demo] recorded path=%s bytes=%d duration=%d ms", + info.path, info.bytes, info.duration_ms)) + + delay.delay_ms(200) + + -- ── 3. play back the recording ─────────────────────────────────────────── + print("[audio_demo] playing back " .. REC_PATH .. " ...") + audio.play_wav(output, REC_PATH) + print("[audio_demo] playback done") +end, debug.traceback) + +close_all() +if not ok then + error(err) +end diff --git a/application/basic_demo/fatfs_image/lua/audio_play_test_wav.lua b/application/basic_demo/fatfs_image/lua/audio_play_test_wav.lua new file mode 100644 index 0000000..cddc17d --- /dev/null +++ b/application/basic_demo/fatfs_image/lua/audio_play_test_wav.lua @@ -0,0 +1,30 @@ +local audio = require("audio") +local bm = require("board_manager") + +local TEST_WAV_PATH = "/fatfs/data/test.wav" + +local output_codec, output_rate, output_channels, output_bits = + bm.get_audio_codec_output_params("audio_dac") +if not output_codec then + print("[audio_play_test_wav] ERROR: get_audio_codec_output_params(audio_dac) failed: " .. tostring(output_rate)) + return +end + +local output, out_err = audio.new_output(output_codec, output_rate, output_channels, output_bits) +if not output then + print("[audio_play_test_wav] ERROR: new_output failed: " .. tostring(out_err)) + return +end + +local ok, err = xpcall(function() + print(string.format("[audio_play_test_wav] output=%dHz/%dch/%dbit", + output_rate, output_channels, output_bits)) + print("[audio_play_test_wav] playing " .. TEST_WAV_PATH .. " ...") + audio.play_wav(output, TEST_WAV_PATH) +end, debug.traceback) + +pcall(audio.close, output) +if not ok then + error(err) +end +print("[audio_play_test_wav] done") diff --git a/application/basic_demo/fatfs_image/lua/button_demo.lua b/application/basic_demo/fatfs_image/lua/button_demo.lua new file mode 100644 index 0000000..c5e8551 --- /dev/null +++ b/application/basic_demo/fatfs_image/lua/button_demo.lua @@ -0,0 +1,58 @@ +local bm = require("board_manager") +local btn = require("button") +local delay = require("delay") + +local cfg_pin = 0 + +local handle, herr = btn.new(cfg_pin, 0) +if not handle then + print("[button_demo] ERROR: button.new failed: " .. tostring(herr)) + return +end +print("[button_demo] button handle created on gpio " .. tostring(cfg_pin)) + +-- Read initial button state +local level, lerr = btn.get_key_level(handle) +if level == nil then + print("[button_demo] ERROR: get_key_level: " .. tostring(lerr)) +else + print("[button_demo] initial key level: " .. tostring(level)) +end + +-- Register callbacks for the events we care about +btn.on(handle, "press_down", function(info) + print("[button_demo] press_down (pressed_time=" .. tostring(info.pressed_time_ms) .. "ms)") +end) + +btn.on(handle, "press_up", function(info) + print("[button_demo] press_up (pressed_time=" .. tostring(info.pressed_time_ms) .. "ms)") +end) + +btn.on(handle, "single_click", function(info) + print("[button_demo] single_click") +end) + +btn.on(handle, "double_click", function(info) + print("[button_demo] double_click") +end) + +btn.on(handle, "long_press_start", function(info) + print("[button_demo] long_press_start (pressed_time=" .. tostring(info.pressed_time_ms) .. "ms)") +end) + +btn.on(handle, "long_press_up", function(info) + print("[button_demo] long_press_up (pressed_time=" .. tostring(info.pressed_time_ms) .. "ms)") +end) + +print("[button_demo] listening for 30 seconds, press the button...") + +-- Poll for events; dispatch() invokes the callbacks registered above +for _ = 1, 3000 do + btn.dispatch() + delay.delay_ms(10) +end + +-- Clean up callbacks +btn.off(handle) +btn.close(handle) +print("[button_demo] done") diff --git a/application/basic_demo/fatfs_image/lua/button_play_test_wav.lua b/application/basic_demo/fatfs_image/lua/button_play_test_wav.lua new file mode 100644 index 0000000..4055127 --- /dev/null +++ b/application/basic_demo/fatfs_image/lua/button_play_test_wav.lua @@ -0,0 +1,66 @@ +local audio = require("audio") +local bm = require("board_manager") +local btn = require("button") +local delay = require("delay") + +local BUTTON_GPIO_NUM = 28 +local TEST_WAV_PATH = "/fatfs/data/test.wav" +local POLL_INTERVAL_MS = 10 +local RUN_TIME_MS = 60000 + +local output_codec, output_rate, output_channels, output_bits = + bm.get_audio_codec_output_params("audio_dac") +if not output_codec then + print("[button_play_test_wav] ERROR: get_audio_codec_output_params(audio_dac) failed: " .. tostring(output_rate)) + return +end + +local output, out_err = audio.new_output(output_codec, output_rate, output_channels, output_bits) +if not output then + print("[button_play_test_wav] ERROR: new_output failed: " .. tostring(out_err)) + return +end + +local handle, herr = btn.new(BUTTON_GPIO_NUM, 0) +if not handle then + print("[button_play_test_wav] ERROR: button.new failed: " .. tostring(herr)) + audio.close(output) + return +end + +local is_playing = false + +btn.on(handle, "single_click", function() + if is_playing then + print("[button_play_test_wav] playback already in progress") + return + end + + is_playing = true + print("[button_play_test_wav] playing " .. TEST_WAV_PATH .. " ...") + audio.play_wav(output, TEST_WAV_PATH) + print("[button_play_test_wav] playback done") + is_playing = false +end) + +print(string.format("[button_play_test_wav] button gpio=%d output=%dHz/%dch/%dbit", + BUTTON_GPIO_NUM, output_rate, output_channels, output_bits)) +print("[button_play_test_wav] press the button once to play test.wav") +print("[button_play_test_wav] running for " .. tostring(RUN_TIME_MS) .. " ms") + +local ok, err = xpcall(function() + for _ = 1, math.floor(RUN_TIME_MS / POLL_INTERVAL_MS) do + btn.dispatch() + delay.delay_ms(POLL_INTERVAL_MS) + end +end, debug.traceback) + +pcall(btn.off, handle) +pcall(btn.close, handle) +pcall(audio.close, output) + +if not ok then + error(err) +end + +print("[button_play_test_wav] done") diff --git a/application/basic_demo/fatfs_image/lua/camera_capture_demo.lua b/application/basic_demo/fatfs_image/lua/camera_capture_demo.lua new file mode 100644 index 0000000..63cddec --- /dev/null +++ b/application/basic_demo/fatfs_image/lua/camera_capture_demo.lua @@ -0,0 +1,69 @@ +local board_manager = require("board_manager") +local camera = require("camera") + +local SAVE_PATH = "/fatfs/data/capture_demo.jpg" +local CAPTURE_TIMEOUT_MS = 3000 + +local function close_camera() + local ok, err = pcall(camera.close) + if not ok then + print("[camera_capture_demo] WARN: close failed: " .. tostring(err)) + end +end + +local camera_paths, path_err = board_manager.get_camera_paths() +if not camera_paths then + print("[camera_capture_demo] ERROR: get_camera_paths failed: " .. tostring(path_err)) + return +end + +print("[camera_capture_demo] camera dev_path: " .. tostring(camera_paths.dev_path)) +if camera_paths.meta_path then + print("[camera_capture_demo] camera meta_path: " .. tostring(camera_paths.meta_path)) +end + +local opened, open_err = pcall(camera.open, camera_paths.dev_path) +if not opened then + print("[camera_capture_demo] ERROR: " .. tostring(open_err)) + return +end + +local info_ok, info_or_err = pcall(camera.info) +if not info_ok then + print("[camera_capture_demo] ERROR: " .. tostring(info_or_err)) + close_camera() + return +end + +print(string.format( + "[camera_capture_demo] stream: %dx%d format=%s", + info_or_err.width, + info_or_err.height, + tostring(info_or_err.pixel_format) +)) + +print(string.format( + "[camera_capture_demo] capturing to %s (timeout=%d ms) ...", + SAVE_PATH, + CAPTURE_TIMEOUT_MS +)) + +local capture_ok, result_or_err = pcall(camera.capture, SAVE_PATH, CAPTURE_TIMEOUT_MS) +if not capture_ok then + print("[camera_capture_demo] ERROR: " .. tostring(result_or_err)) + close_camera() + return +end + +print(string.format( + "[camera_capture_demo] saved: path=%s bytes=%d frame=%dx%d format=%s timestamp_us=%d", + result_or_err.path, + result_or_err.bytes, + result_or_err.width, + result_or_err.height, + tostring(result_or_err.pixel_format), + result_or_err.timestamp_us +)) + +close_camera() +print("[camera_capture_demo] done") diff --git a/application/basic_demo/fatfs_image/lua/coroutine_demo.lua b/application/basic_demo/fatfs_image/lua/coroutine_demo.lua new file mode 100644 index 0000000..ec0464f --- /dev/null +++ b/application/basic_demo/fatfs_image/lua/coroutine_demo.lua @@ -0,0 +1,47 @@ +local delay = require("delay") + +print("[coroutine_demo] start") + +local co = coroutine.create(function(name) + print("[coroutine_demo] worker enter: " .. tostring(name)) + + for step = 1, 3 do + print(string.format("[coroutine_demo] worker step=%d before yield", step)) + coroutine.yield("yield@" .. tostring(step)) + print(string.format("[coroutine_demo] worker step=%d after resume", step)) + delay.delay_ms(100) + end + + return "done:" .. tostring(name) +end) + +print("[coroutine_demo] initial status: " .. coroutine.status(co)) + +local ok, value = coroutine.resume(co, "demo-task") +print(string.format("[coroutine_demo] resume #1 ok=%s value=%s status=%s", + tostring(ok), tostring(value), coroutine.status(co))) + +ok, value = coroutine.resume(co) +print(string.format("[coroutine_demo] resume #2 ok=%s value=%s status=%s", + tostring(ok), tostring(value), coroutine.status(co))) + +ok, value = coroutine.resume(co) +print(string.format("[coroutine_demo] resume #3 ok=%s value=%s status=%s", + tostring(ok), tostring(value), coroutine.status(co))) + +ok, value = coroutine.resume(co) +print(string.format("[coroutine_demo] resume #4 ok=%s value=%s status=%s", + tostring(ok), tostring(value), coroutine.status(co))) + +local wrapped = coroutine.wrap(function() + for i = 1, 2 do + coroutine.yield("wrap@" .. tostring(i)) + end + return "wrap-done" +end) + +print("[coroutine_demo] wrap call #1: " .. tostring(wrapped())) +print("[coroutine_demo] wrap call #2: " .. tostring(wrapped())) +print("[coroutine_demo] wrap call #3: " .. tostring(wrapped())) + +print("[coroutine_demo] done") diff --git a/application/basic_demo/fatfs_image/lua/display_demo.lua b/application/basic_demo/fatfs_image/lua/display_demo.lua new file mode 100644 index 0000000..786b8da --- /dev/null +++ b/application/basic_demo/fatfs_image/lua/display_demo.lua @@ -0,0 +1,142 @@ +local bm = require("board_manager") +local display = require("display") +local delay = require("delay") + +local function rgb(r, g, b) + return { r = r, g = g, b = b } +end + +local function clear_with(color) + display.clear(color.r, color.g, color.b) +end + +local function centered_text(y, text, color, font_size) + local w = display.width() + local tw, th = display.measure_text(text, { font_size = font_size }) + local x = math.floor((w - tw) / 2) + display.draw_text(x, y, text, { + r = color.r, + g = color.g, + b = color.b, + font_size = font_size, + }) + return th +end + +local function wait_frame(ms) + display.present() + delay.delay_ms(ms) +end + +local panel_handle, io_handle, width, height = bm.get_display_lcd_params("display_lcd") +if not panel_handle then + print("[display_demo] ERROR: get_display_lcd_params(display_lcd) failed: " .. tostring(io_handle)) + return +end + +local ok, err = pcall(display.create_screen, panel_handle, io_handle, width, height) +if not ok then + print("[display_demo] ERROR: create_screen failed: " .. tostring(err)) + return +end + +local screen_created = true + +local function cleanup() + if screen_created then + pcall(display.end_frame) + pcall(display.destroy_screen) + screen_created = false + end +end + +width = display.width() +height = display.height() + +if width <= 0 or height <= 0 then + print("[display_demo] ERROR: invalid display size after create_screen") + cleanup() + return +end + +print(string.format("[display_demo] screen ready: %dx%d", width, height)) +print("[display_demo] created from board_manager handle + config") + +local bg = rgb(12, 18, 28) +local fg = rgb(245, 244, 238) +local accent = rgb(255, 160, 60) +local cyan = rgb(72, 208, 235) +local green = rgb(88, 210, 124) +local red = rgb(235, 90, 90) + +local run_ok, run_err = xpcall(function() + display.begin_frame({ clear = true, r = bg.r, g = bg.g, b = bg.b }) + + local title_h = centered_text(16, "Lua Display Demo", fg, 24) + centered_text(16 + title_h + 6, "basic primitives + frame API", accent, 16) + + display.draw_rect(12, 12, width - 24, height - 24, 80, 120, 160) + display.draw_line(20, 72, width - 20, 72, 40, 70, 95) + + display.fill_rect(20, 92, 56, 36, cyan.r, cyan.g, cyan.b) + display.draw_rect(20, 92, 56, 36, fg.r, fg.g, fg.b) + display.fill_circle(110, 110, 18, accent.r, accent.g, accent.b) + display.draw_circle(110, 110, 24, fg.r, fg.g, fg.b) + display.draw_line(142, 92, 196, 128, red.r, red.g, red.b) + display.draw_triangle(212, 90, 252, 126, 220, 136, green.r, green.g, green.b) + display.fill_triangle(262, 92, 298, 126, 278, 138, 110, 130, 250) + + display.draw_round_rect(18, 148, 92, 50, 10, 255, 205, 90) + display.fill_round_rect(122, 148, 92, 50, 12, 64, 104, 255) + display.draw_ellipse(244, 172, 34, 18, 250, 120, 140) + display.fill_ellipse(292, 172, 20, 12, 80, 200, 150) + + display.draw_arc(56, 218, 18, -90, 210, 255, 180, 70) + display.fill_arc(122, 218, 10, 24, -45, 225, 88, 210, 124) + + display.draw_text_aligned(18, height - 42, width - 36, 20, + string.format("%dx%d frame_active=%s", width, height, tostring(display.frame_active())), + { + r = 210, + g = 220, + b = 228, + font_size = 16, + align = "center", + valign = "middle", + }) + wait_frame(1200) + display.end_frame() + + display.begin_frame({ clear = true, r = 8, g = 10, b = 14 }) + for i = 0, 5 do + local y = 20 + i * 34 + local rr = 40 + i * 30 + local gg = 120 + i * 18 + local bb = 220 - i * 22 + display.fill_rect(18, y, width - 36, 22, rr, gg, bb) + display.draw_text_aligned(24, y, width - 48, 22, + string.format("row %d rgb(%d,%d,%d)", i + 1, rr, gg, bb), + { + r = 255, + g = 255, + b = 255, + font_size = 16, + align = "center", + valign = "middle", + }) + end + wait_frame(1200) + display.end_frame() + + display.begin_frame({ clear = true, r = 0, g = 0, b = 0 }) + centered_text(math.floor(height / 2) - 10, "display_demo done", fg, 20) + display.present() + display.end_frame() +end, debug.traceback) + +cleanup() +if not run_ok then + error(run_err) +end + +print("[display_demo] done") diff --git a/application/basic_demo/fatfs_image/lua/gc_demo.lua b/application/basic_demo/fatfs_image/lua/gc_demo.lua new file mode 100644 index 0000000..4da00aa --- /dev/null +++ b/application/basic_demo/fatfs_image/lua/gc_demo.lua @@ -0,0 +1,33 @@ +local function kb() + return collectgarbage("count") +end + +local function print_kb(label) + print(string.format("[gc_demo] %s: %.2f KB", label, kb())) +end + +print("[gc_demo] start") +print_kb("initial") + +local blocks = {} +for i = 1, 400 do + local t = {} + for j = 1, 64 do + t[j] = string.format("block=%d item=%d", i, j) + end + blocks[i] = t +end + +print_kb("after allocation") + +blocks = nil +print_kb("after release refs") + +local step_done = collectgarbage("step", 64) +print(string.format("[gc_demo] step result: %s", tostring(step_done))) +print_kb("after one step") + +collectgarbage("collect") +print_kb("after full collect") + +print("[gc_demo] done") diff --git a/application/basic_demo/fatfs_image/lua/gc_userdata_demo.lua b/application/basic_demo/fatfs_image/lua/gc_userdata_demo.lua new file mode 100644 index 0000000..bf68614 --- /dev/null +++ b/application/basic_demo/fatfs_image/lua/gc_userdata_demo.lua @@ -0,0 +1,39 @@ +local btn = require("button") + +local gpio_num = (args and args.gpio_num) or 0 +local rounds = (args and args.rounds) or 12 + +print(string.format( + "[gc_userdata_demo] start gpio=%d rounds=%d", + gpio_num, + rounds +)) + +local function make_and_drop_button(index) + local handle, err = btn.new(gpio_num, 0) + if not handle then + error(string.format("button.new failed at round %d: %s", index, tostring(err))) + end + + print(string.format("[gc_userdata_demo] round=%d created handle=%s", index, tostring(handle))) + + -- Drop the only Lua reference on purpose. The userdata __gc should release + -- the native button handle so repeated creation does not exhaust BTN_MAX_HANDLES. + handle = nil + collectgarbage("collect") + collectgarbage("collect") +end + +for i = 1, rounds do + make_and_drop_button(i) +end + +local final_handle, final_err = btn.new(gpio_num, 0) +if not final_handle then + error("[gc_userdata_demo] final create failed after GC cycling: " .. tostring(final_err)) +end + +print("[gc_userdata_demo] final create succeeded after repeated GC") +btn.close(final_handle) +collectgarbage("collect") +print("[gc_userdata_demo] done") diff --git a/application/basic_demo/fatfs_image/lua/lcd_touch_demo.lua b/application/basic_demo/fatfs_image/lua/lcd_touch_demo.lua new file mode 100644 index 0000000..e10343b --- /dev/null +++ b/application/basic_demo/fatfs_image/lua/lcd_touch_demo.lua @@ -0,0 +1,53 @@ +local bm = require("board_manager") +local touch = require("lcd_touch") +local delay = require("delay") + +local touch_handle, err = bm.get_lcd_touch_handle("lcd_touch") +if not touch_handle then + print("[lcd_touch_demo] ERROR: get_lcd_touch_handle(lcd_touch) failed: " .. tostring(err)) + return +end + +local ok, info = pcall(touch.sync, touch_handle) +if not ok then + print("[lcd_touch_demo] ERROR: sync failed: " .. tostring(info)) + return +end + +print("[lcd_touch_demo] listening for touch events for 30 seconds...") +print("[lcd_touch_demo] touch the LCD to see press / move / release events") + +local last_pressed = info.pressed +local last_x = info.x or 0 +local last_y = info.y or 0 + +for _ = 1, 600 do + ok, info = pcall(touch.poll, touch_handle) + if not ok then + print("[lcd_touch_demo] ERROR: poll failed: " .. tostring(info)) + return + end + + if info.just_pressed then + print(string.format("[lcd_touch_demo] press x=%d y=%d", info.x, info.y)) + elseif info.pressed and info.moved then + print(string.format( + "[lcd_touch_demo] move x=%d y=%d dx=%d dy=%d held=%.0fms", + info.x, info.y, info.dx, info.dy, info.held_ms)) + elseif info.just_released then + print(string.format( + "[lcd_touch_demo] release x=%d y=%d held=%.0fms", + info.x, info.y, info.held_ms)) + elseif info.pressed and (not last_pressed or info.x ~= last_x or info.y ~= last_y) then + print(string.format( + "[lcd_touch_demo] hold x=%d y=%d held=%.0fms", + info.x, info.y, info.held_ms)) + end + + last_pressed = info.pressed + last_x = info.x + last_y = info.y + delay.delay_ms(50) +end + +print("[lcd_touch_demo] done") diff --git a/application/basic_demo/fatfs_image/lua/lcd_touch_paint.lua b/application/basic_demo/fatfs_image/lua/lcd_touch_paint.lua new file mode 100644 index 0000000..a20f04d --- /dev/null +++ b/application/basic_demo/fatfs_image/lua/lcd_touch_paint.lua @@ -0,0 +1,217 @@ +local bm = require("board_manager") +local display = require("display") +local lcd_touch = require("lcd_touch") +local delay = require("delay") + +local panel_handle, io_handle, width, height = bm.get_display_lcd_params("display_lcd") +if not panel_handle then + print("[lcd_touch_paint] ERROR: get_display_lcd_params(display_lcd) failed: " .. tostring(io_handle)) + return +end + +local ok, err = pcall(display.create_screen, panel_handle, io_handle, width, height) +if not ok then + print("[lcd_touch_paint] ERROR: create_screen failed: " .. tostring(err)) + return +end + +local screen_created = true + +local function cleanup() + if screen_created then + pcall(display.end_frame) + pcall(display.destroy_screen) + screen_created = false + end +end + +width = display.width() +height = display.height() + +if width <= 0 or height <= 0 then + print("[lcd_touch_paint] ERROR: invalid display size after create_screen") + cleanup() + return +end + +local BG_R, BG_G, BG_B = 250, 246, 238 +local INK_R, INK_G, INK_B = 24, 74, 126 +local ACCENT_R, ACCENT_G, ACCENT_B = 210, 88, 52 +local TEXT_R, TEXT_G, TEXT_B = 32, 36, 42 + +local CLEAR_W = 74 +local CLEAR_H = 32 +local CLEAR_X = math.floor((width - CLEAR_W) / 2) +local CLEAR_Y = 8 +local BRUSH_R = 4 +local POLL_INTERVAL_MS = 10 +local FLUSH_INTERVAL_MS = 16 +local RUN_TIME_MS = 50000 + +local dirty_x0 = nil +local dirty_y0 = nil +local dirty_x1 = nil +local dirty_y1 = nil +local dirty_age_ms = 0 + +local function draw_ui() + display.fill_rect(CLEAR_X, CLEAR_Y, CLEAR_W, CLEAR_H, ACCENT_R, ACCENT_G, ACCENT_B) + display.draw_rect(CLEAR_X, CLEAR_Y, CLEAR_W, CLEAR_H, 120, 30, 12) + display.draw_text_aligned(CLEAR_X, CLEAR_Y, CLEAR_W, CLEAR_H, "CLEAR", { + r = 255, + g = 255, + b = 255, + font_size = 16, + align = "center", + valign = "middle", + }) + display.draw_text(10, 10, "LCD Touch Paint", { + r = TEXT_R, + g = TEXT_G, + b = TEXT_B, + font_size = 20, + }) + display.draw_text(10, 34, "draw with finger, tap CLEAR to wipe", { + r = 90, + g = 96, + b = 104, + font_size = 12, + }) + display.present() +end + +local function inside_clear_button(x, y) + return x >= CLEAR_X and x < (CLEAR_X + CLEAR_W) and y >= CLEAR_Y and y < (CLEAR_Y + CLEAR_H) +end + +local function stamp_brush(x, y) + display.fill_circle(x, y, BRUSH_R, INK_R, INK_G, INK_B) +end + +local function mark_dirty(x, y, w, h) + if w <= 0 or h <= 0 then + return + end + + local x0 = math.max(0, x) + local y0 = math.max(0, y) + local x1 = math.min(width, x + w) + local y1 = math.min(height, y + h) + if x1 <= x0 or y1 <= y0 then + return + end + + if dirty_x0 == nil then + dirty_x0 = x0 + dirty_y0 = y0 + dirty_x1 = x1 + dirty_y1 = y1 + else + dirty_x0 = math.min(dirty_x0, x0) + dirty_y0 = math.min(dirty_y0, y0) + dirty_x1 = math.max(dirty_x1, x1) + dirty_y1 = math.max(dirty_y1, y1) + end +end + +local function mark_brush_dirty(x, y) + mark_dirty(x - BRUSH_R - 1, y - BRUSH_R - 1, BRUSH_R * 2 + 3, BRUSH_R * 2 + 3) +end + +local function draw_segment(x0, y0, x1, y1) + display.draw_line(x0, y0, x1, y1, INK_R, INK_G, INK_B) + stamp_brush(x1, y1) + local min_x = math.min(x0, x1) - BRUSH_R - 1 + local min_y = math.min(y0, y1) - BRUSH_R - 1 + local max_x = math.max(x0, x1) + BRUSH_R + 1 + local max_y = math.max(y0, y1) + BRUSH_R + 1 + mark_dirty(min_x, min_y, max_x - min_x + 1, max_y - min_y + 1) +end + +local function flush_dirty(force) + if dirty_x0 == nil then + dirty_age_ms = 0 + return + end + if not force and dirty_age_ms < FLUSH_INTERVAL_MS then + return + end + + display.present_rect(dirty_x0, dirty_y0, dirty_x1 - dirty_x0, dirty_y1 - dirty_y0) + dirty_x0 = nil + dirty_y0 = nil + dirty_x1 = nil + dirty_y1 = nil + dirty_age_ms = 0 +end + +display.begin_frame({ clear = true, r = BG_R, g = BG_G, b = BG_B }) + +local touch_handle, touch_err = bm.get_lcd_touch_handle("lcd_touch") +if not touch_handle then + print("[lcd_touch_paint] ERROR: get_lcd_touch_handle(lcd_touch) failed: " .. tostring(touch_err)) + cleanup() + return +end + +local synced, info = pcall(lcd_touch.sync, touch_handle) +if not synced then + print("[lcd_touch_paint] ERROR: lcd_touch.sync failed: " .. tostring(info)) + cleanup() + return +end + +display.clear(BG_R, BG_G, BG_B) +draw_ui() + +print("[lcd_touch_paint] ready") +print("[lcd_touch_paint] drag on the LCD to paint, tap CLEAR to wipe, running for 60 seconds") + +local drawing = false +local last_x = 0 +local last_y = 0 + +for _ = 1, math.floor(RUN_TIME_MS / POLL_INTERVAL_MS) do + local polled + polled, info = pcall(lcd_touch.poll, touch_handle) + if not polled then + print("[lcd_touch_paint] ERROR: lcd_touch.poll failed: " .. tostring(info)) + break + end + + if info.just_pressed then + if inside_clear_button(info.x, info.y) then + display.clear(BG_R, BG_G, BG_B) + draw_ui() + drawing = false + dirty_x0 = nil + dirty_y0 = nil + dirty_x1 = nil + dirty_y1 = nil + dirty_age_ms = 0 + else + drawing = true + last_x = info.x + last_y = info.y + stamp_brush(info.x, info.y) + mark_brush_dirty(info.x, info.y) + end + elseif info.pressed and drawing then + if not inside_clear_button(info.x, info.y) then + draw_segment(last_x, last_y, info.x, info.y) + last_x = info.x + last_y = info.y + end + elseif info.just_released then + flush_dirty(true) + drawing = false + end + + dirty_age_ms = dirty_age_ms + POLL_INTERVAL_MS + flush_dirty(false) + delay.delay_ms(POLL_INTERVAL_MS) +end + +flush_dirty(true) +cleanup() +print("[lcd_touch_paint] done") diff --git a/application/basic_demo/fatfs_image/lua/led_strip_demo.lua b/application/basic_demo/fatfs_image/lua/led_strip_demo.lua new file mode 100644 index 0000000..f886d20 --- /dev/null +++ b/application/basic_demo/fatfs_image/lua/led_strip_demo.lua @@ -0,0 +1,40 @@ +local ls = require("led_strip") +local delay = require("delay") + +-- Update these values to match the LED strip wiring on the target board. +local LED_GPIO_NUM = 26 +local LED_COUNT = 16 + +-- Create the strip handle and drive all pixels together. +print("[led] creating led strip on gpio " .. tostring(LED_GPIO_NUM)) +local strip, serr = ls.new(LED_GPIO_NUM, LED_COUNT) +if not strip then + print("[led] ERROR: failed to create led strip: " .. tostring(serr)) + return +end +print("[led] led strip created") + +-- Clear first so the demo always starts from a known LED state. +strip:clear() +print("[led] strip cleared") + +local function fill_all(r, g, b) + for index = 0, LED_COUNT - 1 do + strip:set_pixel(index, r, g, b) + end +end + +-- Flash solid red twice. +for i = 1, 2 do + print("[led] flash " .. i .. ": on") + fill_all(255, 0, 0) + strip:refresh() + delay.delay_ms(300) + + print("[led] flash " .. i .. ": off") + strip:clear() + strip:refresh() + delay.delay_ms(300) +end + +print("[led] done") diff --git a/application/basic_demo/fatfs_image/lua/random_demo_stress.lua b/application/basic_demo/fatfs_image/lua/random_demo_stress.lua new file mode 100644 index 0000000..bcf8ace --- /dev/null +++ b/application/basic_demo/fatfs_image/lua/random_demo_stress.lua @@ -0,0 +1,184 @@ +local delay = require("delay") +local esp_heap = require("esp_heap") + +local LUA_ROOT = "/fatfs/data/lua" +local caps = esp_heap.caps() + +local iterations = (args and args.iterations) or 20 +local pause_ms = (args and args.pause_ms) or 200 +local gc_each_round = (args and args.gc_each_round) ~= false +local include_interactive = (args and args.include_interactive) == true +local summary = { + ok = 0, + failed = 0, + failures = {}, +} + +local demos = { + "hello.lua", + "coroutine_demo.lua", + "gc_demo.lua", + "led_strip_demo.lua", + "display_demo.lua", + "audio_play_test_wav.lua", + "audio_demo.lua", + "camera_capture_demo.lua", +} + +if include_interactive then + demos[#demos + 1] = "button_demo.lua" + demos[#demos + 1] = "button_play_test_wav.lua" + demos[#demos + 1] = "lcd_touch_demo.lua" + demos[#demos + 1] = "lcd_touch_paint.lua" +end + +local function info(c) + return esp_heap.get_info(c) +end + +local function print_heap_snapshot(tag) + local default_info = info(caps.DEFAULT) + local internal_info = info(caps.INTERNAL) + local spiram_info = info(caps.SPIRAM) + + print(string.format( + "[random_demo_stress] heap %s default free=%d min=%d largest=%d | internal free=%d min=%d | spiram free=%d min=%d", + tag, + default_info.free_size, + default_info.minimum_free_size, + default_info.largest_free_block, + internal_info.free_size, + internal_info.minimum_free_size, + spiram_info.free_size, + spiram_info.minimum_free_size + )) +end + +local function print_task_watermarks(tag) + local tasks = esp_heap.get_task_watermarks() + + if tasks._warning then + print("[random_demo_stress] task watermark note: " .. tostring(tasks._warning)) + end + + table.sort(tasks, function(a, b) + if a.stack_high_water_mark_bytes == b.stack_high_water_mark_bytes then + return a.name < b.name + end + return a.stack_high_water_mark_bytes < b.stack_high_water_mark_bytes + end) + + print("[random_demo_stress] task watermarks " .. tag) + for i = 1, math.min(#tasks, 6) do + local task = tasks[i] + print(string.format( + "[random_demo_stress] #%d %s state=%s stack_hwm=%dB prio=%d", + i, + tostring(task.name), + tostring(task.state), + tonumber(task.stack_high_water_mark_bytes) or -1, + tonumber(task.current_priority) or -1 + )) + end +end + +local function run_demo(name) + local path = LUA_ROOT .. "/" .. name + local original_print = print + local saw_error_output = false + local result_ok = false + local result_reason = nil + + local function wrapped_print(...) + local parts = {} + for i = 1, select("#", ...) do + parts[i] = tostring(select(i, ...)) + end + local line = table.concat(parts, "\t") + if string.find(line, "ERROR:", 1, true) then + saw_error_output = true + end + original_print(...) + end + + print(string.format("[random_demo_stress] running %s", name)) + print = wrapped_print + local ok, err = xpcall(function() + dofile(path) + end, debug.traceback) + print = original_print + + if ok and not saw_error_output then + print(string.format("[random_demo_stress] result %s ok", name)) + result_ok = true + elseif ok then + print(string.format("[random_demo_stress] result %s failed: demo printed ERROR output", name)) + result_reason = "demo printed ERROR output" + else + print(string.format("[random_demo_stress] result %s failed: %s", name, tostring(err))) + result_reason = tostring(err) + end + + return result_ok, result_reason +end + +math.randomseed((os.time() % 2147483647) + math.floor(collectgarbage("count"))) + +print(string.format( + "[random_demo_stress] start iterations=%d pause_ms=%d gc_each_round=%s include_interactive=%s", + iterations, + pause_ms, + tostring(gc_each_round), + tostring(include_interactive) +)) + +print_heap_snapshot("initial") +print_task_watermarks("initial") + +for i = 1, iterations do + local index = math.random(1, #demos) + local name = demos[index] + + print(string.format("[random_demo_stress] round %d/%d pick=%s", i, iterations, name)) + print_heap_snapshot("before") + local ok, reason = run_demo(name) + if ok then + summary.ok = summary.ok + 1 + else + summary.failed = summary.failed + 1 + summary.failures[#summary.failures + 1] = { + round = i, + name = name, + reason = reason or "unknown failure", + } + end + + if gc_each_round then + collectgarbage("collect") + end + + print_heap_snapshot("after") + print_task_watermarks("after round " .. tostring(i)) + if pause_ms > 0 then + delay.delay_ms(pause_ms) + end +end + +print_heap_snapshot("final") +print_task_watermarks("final") +print(string.format( + "[random_demo_stress] summary total=%d ok=%d failed=%d", + iterations, + summary.ok, + summary.failed +)) +for i = 1, #summary.failures do + local item = summary.failures[i] + print(string.format( + "[random_demo_stress] summary failure round=%d demo=%s reason=%s", + item.round, + item.name, + tostring(item.reason) + )) +end +print("[random_demo_stress] done") diff --git a/application/basic_demo/fatfs_image/test.wav b/application/basic_demo/fatfs_image/test.wav new file mode 100644 index 0000000..8148f8b Binary files /dev/null and b/application/basic_demo/fatfs_image/test.wav differ diff --git a/application/basic_demo/main/CMakeLists.txt b/application/basic_demo/main/CMakeLists.txt index 680f154..27d640a 100644 --- a/application/basic_demo/main/CMakeLists.txt +++ b/application/basic_demo/main/CMakeLists.txt @@ -1,51 +1,8 @@ idf_component_register( - SRCS - "app_clawgent.c" - "main.c" - "basic_demo_cli.c" - "basic_demo_lua_modules.c" - "basic_demo_settings.c" - "basic_demo_wifi.c" - "config_http_server.c" + SRC_DIRS + "." INCLUDE_DIRS "." - REQUIRES - cap_cli - cap_files - cap_im_feishu - cap_im_qq - cap_im_tg - cap_im_wechat - cap_llm_inspect - cap_lua - cap_mcp_client - cap_mcp_server - cap_router_mgr - cap_session_mng - cap_scheduler - cap_skill - cap_time - cap_web_search - claw_event_router - claw_cap - claw_core - claw_memory - claw_skill - console - driver - esp_event - esp_http_server - esp_netif - esp_wifi - fatfs - json - nvs_flash - wear_levelling - lua_module_delay - lua_module_event_publisher - lua_module_gpio - lua_module_led_strip - lua_module_storage EMBED_TXTFILES "web/index.html" "web/styles.css" diff --git a/application/basic_demo/main/app_clawgent.c b/application/basic_demo/main/app_clawgent.c index 4346133..a10dc6b 100644 --- a/application/basic_demo/main/app_clawgent.c +++ b/application/basic_demo/main/app_clawgent.c @@ -224,16 +224,9 @@ static esp_err_t init_capabilities(const basic_demo_settings_t *settings) TAG, "Failed to register WeChat cap"); ESP_RETURN_ON_ERROR(cap_files_register_group(), TAG, "Failed to register files cap"); - // ESP_RETURN_ON_ERROR(basic_demo_lua_modules_register(), - // TAG, - // "Failed to register app Lua modules"); - // ESP_RETURN_ON_ERROR(cap_lua_register_group(), TAG, "Failed to register Lua cap"); - // ESP_RETURN_ON_ERROR(cap_mcp_client_register_group(), - // TAG, - // "Failed to register MCP client cap"); - // ESP_RETURN_ON_ERROR(cap_mcp_server_register_group(), - // TAG, - // "Failed to register MCP server cap"); + ESP_RETURN_ON_ERROR(basic_demo_lua_modules_register(), + TAG, + "Failed to register app Lua modules"); ESP_RETURN_ON_ERROR(cap_scheduler_register_group(), TAG, "Failed to register scheduler cap"); diff --git a/application/basic_demo/main/basic_demo_lua_modules.c b/application/basic_demo/main/basic_demo_lua_modules.c index b4498ab..5c65a7f 100644 --- a/application/basic_demo/main/basic_demo_lua_modules.c +++ b/application/basic_demo/main/basic_demo_lua_modules.c @@ -10,6 +10,20 @@ #include "lua_module_gpio.h" #include "lua_module_led_strip.h" #include "lua_module_storage.h" +#include "lua_module_button.h" +#include "lua_module_esp_heap.h" +#include "lua_module_board_manager.h" + +#if defined(CONFIG_ESP_BOARD_DEV_AUDIO_CODEC_SUPPORT) +#include "lua_module_audio.h" +#endif +#include "lua_module_display.h" +#if defined(CONFIG_ESP_BOARD_DEV_LCD_TOUCH_I2C_SUPPORT) +#include "lua_module_lcd_touch.h" +#endif +#if defined(CONFIG_ESP_BOARD_DEV_CAMERA_SUPPORT) +#include "lua_module_camera.h" +#endif esp_err_t basic_demo_lua_modules_register(void) { @@ -35,5 +49,46 @@ esp_err_t basic_demo_lua_modules_register(void) return err; } +#if defined(CONFIG_ESP_BOARD_DEV_AUDIO_CODEC_SUPPORT) + err = lua_module_audio_register(); + if (err != ESP_OK) { + return err; + } +#endif + + err = lua_module_button_register(); + if (err != ESP_OK) { + return err; + } + + err = lua_module_display_register(); + if (err != ESP_OK) { + return err; + } + + err = lua_module_board_manager_register(); + if (err != ESP_OK) { + return err; + } + +#if defined(CONFIG_ESP_BOARD_DEV_LCD_TOUCH_I2C_SUPPORT) + err = lua_module_lcd_touch_register(); + if (err != ESP_OK) { + return err; + } +#endif + +#if defined(CONFIG_ESP_BOARD_DEV_CAMERA_SUPPORT) + err = lua_module_camera_register(); + if (err != ESP_OK) { + return err; + } +#endif + + err = lua_module_esp_heap_register(); + if (err != ESP_OK) { + return err; + } + return lua_module_event_publisher_register(); } diff --git a/application/basic_demo/main/idf_component.yml b/application/basic_demo/main/idf_component.yml index 48d23d0..8efb716 100644 --- a/application/basic_demo/main/idf_component.yml +++ b/application/basic_demo/main/idf_component.yml @@ -1,3 +1,116 @@ ## IDF Component Manager Manifest File dependencies: - espressif/led_strip: ^3.0.3 + espressif/esp_board_manager: + version: "^0.5.7" + public: true + + cap_cli: + path: ../../../components/claw_capabilities/cap_cli + + cap_files: + path: ../../../components/claw_capabilities/cap_files + + cap_im_attachment: + path: ../../../components/claw_capabilities/cap_im_attachment + + cap_im_feishu: + path: ../../../components/claw_capabilities/cap_im_feishu + + cap_im_qq: + path: ../../../components/claw_capabilities/cap_im_qq + + cap_im_tg: + path: ../../../components/claw_capabilities/cap_im_tg + + cap_im_wechat: + path: ../../../components/claw_capabilities/cap_im_wechat + + cap_llm_inspect: + path: ../../../components/claw_capabilities/cap_llm_inspect + + cap_lua: + path: ../../../components/claw_capabilities/cap_lua + + cap_mcp_client: + path: ../../../components/claw_capabilities/cap_mcp_client + + cap_mcp_server: + path: ../../../components/claw_capabilities/cap_mcp_server + + cap_router_mgr: + path: ../../../components/claw_capabilities/cap_router_mgr + + cap_session_mng: + path: ../../../components/claw_capabilities/cap_session_mng + + cap_skill: + path: ../../../components/claw_capabilities/cap_skill + + cap_scheduler: + path: ../../../components/claw_capabilities/cap_scheduler + + cap_time: + path: ../../../components/claw_capabilities/cap_time + + cap_web_search: + path: ../../../components/claw_capabilities/cap_web_search + + claw_cap: + path: ../../../components/claw_modules/claw_cap + + claw_core: + path: ../../../components/claw_modules/claw_core + + claw_event_router: + path: ../../../components/claw_modules/claw_event_router + + claw_memory: + path: ../../../components/claw_modules/claw_memory + + claw_skill: + path: ../../../components/claw_modules/claw_skill + + esp_painter: + path: ../../../components/lua_modules/esp_painter + + lua_module_audio: + matches: + - if: $CONFIG{ESP_BOARD_DEV_AUDIO_CODEC_SUPPORT} == True + path: ../../../components/lua_modules/lua_module_audio + + lua_module_board_manager: + path: ../../../components/lua_modules/lua_module_board_manager + + lua_module_button: + path: ../../../components/lua_modules/lua_module_button + + lua_module_camera: + matches: + - if: $CONFIG{ESP_BOARD_DEV_CAMERA_SUPPORT} == True + path: ../../../components/lua_modules/lua_module_camera + + lua_module_delay: + path: ../../../components/lua_modules/lua_module_delay + + lua_module_display: + path: ../../../components/lua_modules/lua_module_display + + lua_module_esp_heap: + path: ../../../components/lua_modules/lua_module_esp_heap + + lua_module_event_publisher: + path: ../../../components/lua_modules/lua_module_event_publisher + + lua_module_gpio: + path: ../../../components/lua_modules/lua_module_gpio + + lua_module_lcd_touch: + matches: + - if: $CONFIG{ESP_BOARD_DEV_LCD_TOUCH_I2C_SUPPORT} == True + path: ../../../components/lua_modules/lua_module_lcd_touch + + lua_module_led_strip: + path: ../../../components/lua_modules/lua_module_led_strip + + lua_module_storage: + path: ../../../components/lua_modules/lua_module_storage diff --git a/application/basic_demo/main/main.c b/application/basic_demo/main/main.c index b6cc928..a355e7a 100644 --- a/application/basic_demo/main/main.c +++ b/application/basic_demo/main/main.c @@ -13,6 +13,7 @@ #include "freertos/task.h" #include "nvs_flash.h" #include "wear_levelling.h" +#include "esp_board_manager_includes.h" static const char *TAG = "basic_demo"; static basic_demo_settings_t s_settings = {0}; @@ -110,6 +111,7 @@ void app_main(void) ESP_ERROR_CHECK(init_nvs()); ESP_ERROR_CHECK(basic_demo_settings_init()); ESP_ERROR_CHECK(basic_demo_settings_load(&s_settings)); + ESP_ERROR_CHECK(esp_board_manager_init()); ESP_ERROR_CHECK(init_fatfs()); ESP_ERROR_CHECK(basic_demo_wifi_init()); ESP_ERROR_CHECK(config_http_server_init(BASIC_DEMO_FATFS_BASE_PATH)); diff --git a/application/basic_demo/partitions.csv b/application/basic_demo/partitions.csv deleted file mode 100644 index 6cc8b92..0000000 --- a/application/basic_demo/partitions.csv +++ /dev/null @@ -1,8 +0,0 @@ -# Name, Type, SubType, Offset, Size -nvs, data, nvs, 0x9000, 0x6000 -otadata, data, ota, 0xF000, 0x2000 -phy_init, data, phy, 0x11000, 0x1000 -ota_0, app, ota_0, 0x20000, 0x200000 -ota_1, app, ota_1, 0x220000, 0x200000 -storage, data, fat, 0x420000, 0xBD0000 -coredump, data, coredump,0xFF0000, 0x10000 diff --git a/application/basic_demo/partitions_16MB.csv b/application/basic_demo/partitions_16MB.csv new file mode 100644 index 0000000..cc5ec83 --- /dev/null +++ b/application/basic_demo/partitions_16MB.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size +nvs, data, nvs, 0x9000, 0x6000 +otadata, data, ota, 0xF000, 0x2000 +phy_init, data, phy, 0x11000, 0x1000 +ota_0, app, ota_0, , 4M +ota_1, app, ota_1, , 4M +storage, data, fat, , 7M diff --git a/application/basic_demo/partitions_4MB.csv b/application/basic_demo/partitions_4MB.csv new file mode 100644 index 0000000..c15cf35 --- /dev/null +++ b/application/basic_demo/partitions_4MB.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size +nvs, data, nvs, 0x9000, 0x6000 +otadata, data, ota, 0xF000, 0x2000 +phy_init, data, phy, 0x11000, 0x1000 +ota_0, app, ota_0, , 3M +storage, data, fat, , 800K diff --git a/application/basic_demo/partitions_8MB.csv b/application/basic_demo/partitions_8MB.csv new file mode 100644 index 0000000..49e003a --- /dev/null +++ b/application/basic_demo/partitions_8MB.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size +nvs, data, nvs, 0x9000, 0x6000 +otadata, data, ota, 0xF000, 0x2000 +phy_init, data, phy, 0x11000, 0x1000 +ota_0, app, ota_0, , 3M +ota_1, app, ota_1, , 3M +storage, data, fat, , 1500K diff --git a/application/basic_demo/partitions_8mb.csv b/application/basic_demo/partitions_8mb.csv deleted file mode 100644 index ed10197..0000000 --- a/application/basic_demo/partitions_8mb.csv +++ /dev/null @@ -1,8 +0,0 @@ -# Name, Type, SubType, Offset, Size -nvs, data, nvs, 0x9000, 0x6000 -otadata, data, ota, 0xF000, 0x2000 -phy_init, data, phy, 0x11000, 0x1000 -ota_0, app, ota_0, 0x20000, 0x200000 -ota_1, app, ota_1, 0x220000, 0x200000 -storage, data, fat, 0x420000, 0x3D0000 -coredump, data, coredump,0x7F0000, 0x10000 diff --git a/application/basic_demo/sdkconfig.defaults b/application/basic_demo/sdkconfig.defaults index 8781e58..d9b1fee 100644 --- a/application/basic_demo/sdkconfig.defaults +++ b/application/basic_demo/sdkconfig.defaults @@ -1,15 +1,8 @@ # This file was generated using idf.py save-defconfig. It can be edited manually. # Espressif IoT Development Framework (ESP-IDF) 5.5.1 Project Minimal Configuration # -CONFIG_IDF_TARGET="esp32s3" -CONFIG_ESPTOOLPY_FLASHMODE_QIO=y -CONFIG_ESPTOOLPY_FLASHFREQ_120M=y -CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y -CONFIG_PARTITION_TABLE_CUSTOM=y + CONFIG_HTTPD_WS_SUPPORT=y -CONFIG_SPIRAM=y -CONFIG_SPIRAM_MODE_OCT=y -CONFIG_SPIRAM_SPEED_120M=y CONFIG_SPIRAM_MEMTEST=n CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=2048 CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y diff --git a/components/claw_capabilities/cap_lua/src/cap_lua_async.c b/components/claw_capabilities/cap_lua/src/cap_lua_async.c index 4678f4a..0cf0709 100644 --- a/components/claw_capabilities/cap_lua/src/cap_lua_async.c +++ b/components/claw_capabilities/cap_lua/src/cap_lua_async.c @@ -24,11 +24,11 @@ typedef struct { char job_id[9]; char path[192]; char *args_json; + char *summary; uint32_t timeout_ms; time_t created_at; time_t started_at; time_t finished_at; - char summary[CAP_LUA_OUTPUT_SIZE]; TaskHandle_t task_handle; } cap_lua_job_record_t; @@ -111,6 +111,16 @@ static int cap_lua_find_slot_by_id_locked(const char *job_id) return -1; } +static void cap_lua_clear_slot(cap_lua_job_record_t *job) +{ + if (!job) { + return; + } + free(job->args_json); + free(job->summary); + memset(job, 0, sizeof(*job)); +} + static void cap_lua_finish_job(cap_lua_job_ctx_t *ctx, bool ok, bool timed_out, @@ -129,7 +139,8 @@ static void cap_lua_finish_job(cap_lua_job_ctx_t *ctx, s_jobs[ctx->slot].finished_at = time(NULL); s_jobs[ctx->slot].task_handle = NULL; if (summary && summary[0]) { - strlcpy(s_jobs[ctx->slot].summary, summary, sizeof(s_jobs[ctx->slot].summary)); + free(s_jobs[ctx->slot].summary); + s_jobs[ctx->slot].summary = strdup(summary); } } @@ -179,6 +190,8 @@ static void cap_lua_job_task(void *arg) esp_err_t cap_lua_async_init(void) { + int i; + if (!s_job_lock) { s_job_lock = xSemaphoreCreateMutex(); } @@ -186,6 +199,9 @@ esp_err_t cap_lua_async_init(void) return ESP_ERR_NO_MEM; } + for (i = 0; i < CAP_LUA_ASYNC_MAX_JOBS; i++) { + cap_lua_clear_slot(&s_jobs[i]); + } memset(s_jobs, 0, sizeof(s_jobs)); s_running_jobs = 0; s_runner_started = false; @@ -254,7 +270,7 @@ esp_err_t cap_lua_async_submit(const cap_lua_async_job_t *job, return ESP_ERR_NO_MEM; } - memset(&s_jobs[slot], 0, sizeof(s_jobs[slot])); + cap_lua_clear_slot(&s_jobs[slot]); s_jobs[slot].used = true; s_jobs[slot].status = CAP_LUA_JOB_QUEUED; s_jobs[slot].created_at = job->created_at ? job->created_at : now; @@ -263,7 +279,7 @@ esp_err_t cap_lua_async_submit(const cap_lua_async_job_t *job, if (ctx->args_json) { s_jobs[slot].args_json = strdup(ctx->args_json); if (!s_jobs[slot].args_json) { - memset(&s_jobs[slot], 0, sizeof(s_jobs[slot])); + cap_lua_clear_slot(&s_jobs[slot]); xSemaphoreGive(s_job_lock); free(ctx->args_json); free(ctx); @@ -282,8 +298,7 @@ esp_err_t cap_lua_async_submit(const cap_lua_async_job_t *job, CAP_LUA_ASYNC_PRIO, &s_jobs[slot].task_handle) != pdPASS) { if (xSemaphoreTake(s_job_lock, pdMS_TO_TICKS(1000)) == pdTRUE) { - free(s_jobs[slot].args_json); - memset(&s_jobs[slot], 0, sizeof(s_jobs[slot])); + cap_lua_clear_slot(&s_jobs[slot]); if (s_running_jobs > 0) { s_running_jobs--; } @@ -381,7 +396,7 @@ esp_err_t cap_lua_async_get_job(const char *job_id, s_jobs[slot].job_id, cap_lua_job_status_name(s_jobs[slot].status), s_jobs[slot].path, - s_jobs[slot].summary[0] ? s_jobs[slot].summary : "(empty)"); + (s_jobs[slot].summary && s_jobs[slot].summary[0]) ? s_jobs[slot].summary : "(empty)"); xSemaphoreGive(s_job_lock); return ESP_OK; } diff --git a/components/claw_capabilities/cap_lua/src/cap_lua_runtime.c b/components/claw_capabilities/cap_lua/src/cap_lua_runtime.c index aa78d98..cf0fa4f 100644 --- a/components/claw_capabilities/cap_lua/src/cap_lua_runtime.c +++ b/components/claw_capabilities/cap_lua/src/cap_lua_runtime.c @@ -107,12 +107,16 @@ static int cap_lua_print_capture(lua_State *L) if (i > 1) { cap_lua_output_append(ctx, "\t", 1); + fwrite("\t", sizeof(char), 1, stdout); } cap_lua_output_append(ctx, text, len); + fwrite(text, sizeof(char), len, stdout); lua_pop(L, 1); } cap_lua_output_append(ctx, "\n", 1); + fwrite("\n", sizeof(char), 1, stdout); + fflush(stdout); return 0; } diff --git a/components/claw_capabilities/cap_lua/src/cmd_cap_lua.c b/components/claw_capabilities/cap_lua/src/cmd_cap_lua.c index f067ed0..b6cfd7f 100644 --- a/components/claw_capabilities/cap_lua/src/cmd_cap_lua.c +++ b/components/claw_capabilities/cap_lua/src/cmd_cap_lua.c @@ -7,6 +7,7 @@ #include #include +#include #include "argtable3/argtable3.h" #include "cap_lua.h" @@ -37,6 +38,71 @@ static void print_lua_result(const char *result) } } +static const char *lua_result_last_nonempty_line(const char *result, size_t *len_out) +{ + const char *line_start = NULL; + const char *cursor = NULL; + const char *last_start = NULL; + size_t last_len = 0; + + if (len_out) { + *len_out = 0; + } + if (!result || !result[0]) { + return NULL; + } + + line_start = result; + cursor = result; + while (1) { + if (*cursor == '\n' || *cursor == '\0') { + size_t line_len = (size_t)(cursor - line_start); + if (line_len > 0) { + last_start = line_start; + last_len = line_len; + } + if (*cursor == '\0') { + break; + } + line_start = cursor + 1; + } + cursor++; + } + + if (len_out) { + *len_out = last_len; + } + return last_start; +} + +static void print_lua_run_tail(const char *result, bool is_error) +{ + size_t line_len = 0; + const char *line = NULL; + + if (!result || !result[0]) { + return; + } + + if (!is_error) { + if (strcmp(result, "Lua script completed with no output.\n") == 0) { + printf("%s", result); + return; + } + line = strstr(result, "[output truncated]\n"); + if (line) { + printf("%s", line); + } + return; + } + + line = lua_result_last_nonempty_line(result, &line_len); + if (!line || line_len == 0) { + return; + } + printf("%.*s\n", (int)line_len, line); +} + static int lua_func(int argc, char **argv) { int nerrors = arg_parse(argc, argv, (void **)&lua_args); @@ -44,6 +110,7 @@ static int lua_func(int argc, char **argv) char *result = NULL; esp_err_t err = ESP_OK; uint32_t timeout_ms = 0; + bool sync_run = false; if (nerrors != 0) { arg_print_errors(stderr, lua_args.end, argv[0]); @@ -95,6 +162,7 @@ static int lua_func(int argc, char **argv) result, 4096); } else if (lua_args.run->count) { + sync_run = true; if (!lua_args.path->count) { printf("'--run' requires '--path'\n"); free(result); @@ -125,13 +193,21 @@ static int lua_func(int argc, char **argv) } if (err != ESP_OK) { - print_lua_result(result); + if (sync_run) { + print_lua_run_tail(result, true); + } else { + print_lua_result(result); + } printf("lua command failed: %s\n", esp_err_to_name(err)); free(result); return 1; } - print_lua_result(result); + if (sync_run) { + print_lua_run_tail(result, false); + } else { + print_lua_result(result); + } free(result); return 0; } diff --git a/components/lua_modules/esp_painter/CMakeLists.txt b/components/lua_modules/esp_painter/CMakeLists.txt new file mode 100644 index 0000000..ab065e1 --- /dev/null +++ b/components/lua_modules/esp_painter/CMakeLists.txt @@ -0,0 +1,16 @@ +file(GLOB_RECURSE FONT_SRCS font/*.c) + +set(painter_reqs esp_mm) +if(CONFIG_SOC_PPA_SUPPORTED) + list(APPEND painter_reqs esp_driver_ppa) +endif() + +idf_component_register( + SRCS + ${FONT_SRCS} + "esp_painter.c" + INCLUDE_DIRS + "include" + REQUIRES + ${painter_reqs} +) diff --git a/components/lua_modules/esp_painter/Kconfig b/components/lua_modules/esp_painter/Kconfig new file mode 100644 index 0000000..e9095a9 --- /dev/null +++ b/components/lua_modules/esp_painter/Kconfig @@ -0,0 +1,49 @@ +menu "ESP Painter" + config ESP_PAINTER_FORMAT_SIZE_MAX + int "Size of format string buffer" + default 128 + help + Maximum size of the buffer used for formatted string output. + + menu "Fonts" + config ESP_PAINTER_BASIC_FONT_12 + bool "Enable basic_font_12" + default n + + config ESP_PAINTER_BASIC_FONT_16 + bool "Enable basic_font_16" + default n + + config ESP_PAINTER_BASIC_FONT_20 + bool "Enable basic_font_20" + default n + + config ESP_PAINTER_BASIC_FONT_24 + bool "Enable basic_font_24" + default y + + config ESP_PAINTER_BASIC_FONT_28 + bool "Enable basic_font_28" + default n + + config ESP_PAINTER_BASIC_FONT_32 + bool "Enable basic_font_32" + default n + + config ESP_PAINTER_BASIC_FONT_36 + bool "Enable basic_font_36" + default n + + config ESP_PAINTER_BASIC_FONT_40 + bool "Enable basic_font_40" + default n + + config ESP_PAINTER_BASIC_FONT_44 + bool "Enable basic_font_44" + default n + + config ESP_PAINTER_BASIC_FONT_48 + bool "Enable basic_font_48" + default n + endmenu +endmenu diff --git a/components/lua_modules/esp_painter/esp_painter.c b/components/lua_modules/esp_painter/esp_painter.c new file mode 100644 index 0000000..63eb8ba --- /dev/null +++ b/components/lua_modules/esp_painter/esp_painter.c @@ -0,0 +1,622 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include "esp_log.h" +#include "esp_painter.h" +#include "esp_cache.h" +#include "esp_heap_caps.h" +#if CONFIG_SOC_PPA_SUPPORTED +#include "esp_private/esp_cache_private.h" +#include "driver/ppa.h" +#endif + +static const char *TAG = "esp_painter"; + +#if CONFIG_SOC_PPA_SUPPORTED +#define ALIGN_UP(size) (((size) + data_cache_line_size - 1) & ~(data_cache_line_size - 1)) +#endif + +typedef struct { + struct { + uint16_t width; + uint16_t height; + } canvas; + struct { + uint16_t width; + uint16_t height; + } text_canvas; + esp_painter_color_format_t color_format; + const esp_painter_basic_font_t *default_font; + bool swap_rgb565; // Whether to swap RGB565 bytes +#if CONFIG_SOC_PPA_SUPPORTED + ppa_client_handle_t ppa_client; + uint8_t *ppa_output_buffer; +#endif +} esp_painter_t; + +#if CONFIG_SOC_PPA_SUPPORTED +static size_t data_cache_line_size = 0; +#endif + +static const struct { + uint8_t r; + uint8_t g; + uint8_t b; +} rgb_colors[] = { + {0x00, 0x00, 0x00}, // BLACK + {0x00, 0x00, 0x80}, // NAVY + {0x00, 0x80, 0x00}, // DARKGREEN + {0x00, 0x80, 0x80}, // DARKCYAN + {0x80, 0x00, 0x00}, // MAROON + {0x80, 0x00, 0x80}, // PURPLE + {0x80, 0x80, 0x00}, // OLIVE + {0xC0, 0xC0, 0xC0}, // LIGHTGREY + {0x80, 0x80, 0x80}, // DARKGREY + {0x00, 0x00, 0xFF}, // BLUE + {0x00, 0xFF, 0x00}, // GREEN + {0x00, 0xFF, 0xFF}, // CYAN + {0xFF, 0x00, 0x00}, // RED + {0xFF, 0x00, 0xFF}, // MAGENTA + {0xFF, 0xFF, 0x00}, // YELLOW + {0xFF, 0xFF, 0xFF}, // WHITE + {0xFF, 0xA5, 0x00}, // ORANGE + {0xAD, 0xFF, 0x2F}, // GREENYELLOW + {0xFF, 0xC0, 0xCB}, // PINK +}; + +static uint32_t esp_painter_get_color(esp_painter_handle_t handle, esp_painter_color_t color) +{ + esp_painter_t *painter = (esp_painter_t *)handle; + if (!painter || color >= sizeof(rgb_colors) / sizeof(rgb_colors[0])) { + return 0; + } + + uint8_t r = rgb_colors[color].r; + uint8_t g = rgb_colors[color].g; + uint8_t b = rgb_colors[color].b; + + uint32_t color_value = 0; + switch (painter->color_format) { + case ESP_PAINTER_COLOR_FORMAT_YUV420: + case ESP_PAINTER_COLOR_FORMAT_YUV422: + case ESP_PAINTER_COLOR_FORMAT_RGB565: + color_value = RGB565(r, g, b); + // Swap bytes if needed for RGB565 + if (painter->swap_rgb565) { + color_value = ((color_value & 0xFF) << 8) | ((color_value >> 8) & 0xFF); + } + return color_value; + case ESP_PAINTER_COLOR_FORMAT_RGB888: + return RGB888(r, g, b); + default: + return 0; + } +} + +static uint16_t esp_painter_get_rgb565_color_value(esp_painter_handle_t handle, uint16_t color565) +{ + esp_painter_t *painter = (esp_painter_t *)handle; + if (!painter) { + return 0; + } + + if (painter->swap_rgb565) { + return (uint16_t)((color565 << 8) | (color565 >> 8)); + } + + return color565; +} + +static void esp_painter_measure_text(const esp_painter_basic_font_t *font, const char *text, + uint16_t *out_width, uint16_t *out_height) +{ + uint16_t max_cols = 0; + uint16_t cols = 0; + uint16_t lines = 1; + + if (!font || !text) { + if (out_width) { + *out_width = 0; + } + if (out_height) { + *out_height = 0; + } + return; + } + + for (const char *p = text; *p; ++p) { + if (*p == '\n') { + if (cols > max_cols) { + max_cols = cols; + } + cols = 0; + lines++; + } else if (*p != '\r') { + cols++; + } + } + if (cols > max_cols) { + max_cols = cols; + } + + if (out_width) { + *out_width = (uint16_t)(max_cols * font->width); + } + if (out_height) { + *out_height = (uint16_t)(lines * font->height); + } +} + +#if CONFIG_SOC_PPA_SUPPORTED +static esp_err_t esp_painter_convert_yuv420_to_rgb565(esp_painter_handle_t handle, uint8_t *in_buffer, uint8_t *out_buffer, + uint32_t out_buffer_size, + uint32_t block_w, uint32_t block_h, + uint32_t block_offset_x, uint32_t block_offset_y) +{ + esp_painter_t *painter = (esp_painter_t *)handle; + if (!painter || !in_buffer || !out_buffer) { + return ESP_ERR_INVALID_ARG; + } + + ppa_srm_oper_config_t srm_config = { + .in.buffer = in_buffer, + .in.pic_w = painter->canvas.width, + .in.pic_h = painter->canvas.height, + .in.block_w = block_w, + .in.block_h = block_h, + .in.block_offset_x = block_offset_x, + .in.block_offset_y = block_offset_y, + .in.srm_cm = PPA_SRM_COLOR_MODE_YUV420, + .out.buffer = out_buffer, + .out.buffer_size = out_buffer_size, + .out.pic_w = block_w, + .out.pic_h = block_h, + .out.block_offset_x = 0, + .out.block_offset_y = 0, + .out.srm_cm = PPA_SRM_COLOR_MODE_RGB565, + .rotation_angle = PPA_SRM_ROTATION_ANGLE_0, + .scale_x = 1, + .scale_y = 1, + .rgb_swap = 0, + .byte_swap = 0, + .mode = PPA_TRANS_MODE_BLOCKING, + }; + + int ret = ppa_do_scale_rotate_mirror(painter->ppa_client, &srm_config); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "First PPA conversion failed"); + } + + return ret; +} + +static esp_err_t esp_painter_convert_rgb565_to_yuv420(esp_painter_handle_t handle, uint8_t *in_buffer, uint8_t *out_buffer, uint32_t buffer_size, + uint32_t in_width, uint32_t in_height, + uint32_t out_width, uint32_t out_height, + uint32_t out_offset_x, uint32_t out_offset_y) +{ + esp_painter_t *painter = (esp_painter_t *)handle; + if (!painter || !in_buffer || !out_buffer) { + return ESP_ERR_INVALID_ARG; + } + + ppa_srm_oper_config_t srm_out_config = { + .in.buffer = in_buffer, + .in.pic_w = in_width, + .in.pic_h = in_height, + .in.block_w = in_width, + .in.block_h = in_height, + .in.block_offset_x = 0, + .in.block_offset_y = 0, + .in.srm_cm = PPA_SRM_COLOR_MODE_RGB565, + .out.buffer = out_buffer, + .out.buffer_size = buffer_size, + .out.pic_w = out_width, + .out.pic_h = out_height, + .out.block_offset_x = out_offset_x, + .out.block_offset_y = out_offset_y, + .out.srm_cm = PPA_SRM_COLOR_MODE_YUV420, + .rotation_angle = PPA_SRM_ROTATION_ANGLE_0, + .scale_x = 1, + .scale_y = 1, + .rgb_swap = 0, + .byte_swap = 0, + .mode = PPA_TRANS_MODE_BLOCKING, + }; + + int ret = ppa_do_scale_rotate_mirror(painter->ppa_client, &srm_out_config); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Second PPA conversion failed"); + } + + return ESP_OK; +} +#endif + +static esp_err_t esp_painter_draw_pixel(esp_painter_handle_t handle, uint8_t *buffer, uint32_t buffer_size, + uint16_t x, uint16_t y, uint16_t color_value) +{ + esp_painter_t *painter = (esp_painter_t *)handle; + if (!painter || !buffer) { + return ESP_ERR_INVALID_ARG; + } + +#if CONFIG_SOC_PPA_SUPPORTED + bool using_ppa = (painter->color_format == ESP_PAINTER_COLOR_FORMAT_YUV420 || + painter->color_format == ESP_PAINTER_COLOR_FORMAT_YUV422); +#else + bool using_ppa = false; +#endif + + if (using_ppa) { + ESP_LOGD(TAG, "Drawing pixel at (%d,%d) with color 0x%04" PRIx32, x, y, color_value); + + uint32_t offset = (y * painter->text_canvas.width + x) * 2; + if (offset + 2 > buffer_size) { + ESP_LOGW(TAG, "Buffer overflow: offset %" PRIu32 ", size %" PRIu32, offset, buffer_size); + return ESP_ERR_INVALID_SIZE; + } + + uint8_t low_byte = color_value & 0xFF; + uint8_t high_byte = (color_value >> 8) & 0xFF; + buffer[offset] = low_byte; + buffer[offset + 1] = high_byte; + + return ESP_OK; + } + + switch (painter->color_format) { + case ESP_PAINTER_COLOR_FORMAT_RGB565: { + uint32_t offset = (y * painter->canvas.width + x) * 2; + if (offset + 2 > buffer_size) { + return ESP_ERR_INVALID_SIZE; + } + buffer[offset] = color_value & 0xFF; + buffer[offset + 1] = (color_value >> 8) & 0xFF; + break; + } + case ESP_PAINTER_COLOR_FORMAT_RGB888: { + uint32_t offset = (y * painter->canvas.width + x) * 3; + if (offset + 3 > buffer_size) { + return ESP_ERR_INVALID_SIZE; + } + buffer[offset] = color_value & 0xFF; + buffer[offset + 1] = (color_value >> 8) & 0xFF; + buffer[offset + 2] = (color_value >> 16) & 0xFF; + break; + } + default: + return ESP_ERR_NOT_SUPPORTED; + } + + return ESP_OK; +} + +static esp_err_t esp_painter_draw_char(esp_painter_handle_t handle, uint8_t *buffer, uint32_t buffer_size, + uint16_t x, uint16_t y, const esp_painter_basic_font_t *font, + uint16_t color_value, char c) +{ + esp_painter_t *painter = (esp_painter_t *)handle; + if (!painter || !buffer) { + return ESP_ERR_INVALID_ARG; + } + + if (!font) { + font = painter->default_font; + } + if (!font) { + ESP_LOGE(TAG, "No font specified"); + return ESP_ERR_INVALID_ARG; + } + + if (c < 32 || c > 127) { + return ESP_ERR_INVALID_ARG; + } + + uint32_t char_offset = (c - 32) * font->height * ((font->width + 7) / 8); + const uint8_t *char_bitmap = font->bitmap + char_offset; + ESP_LOGD(TAG, "Drawing char '%c' at (%d,%d)", c, x, y); + + for (int dy = 0; dy < font->height; dy++) { + for (int dx = 0; dx < font->width; dx++) { + uint8_t byte = char_bitmap[dy * ((font->width + 7) / 8) + (dx / 8)]; + if (byte & (0x80 >> (dx % 8))) { + ESP_LOGD(TAG, "Setting pixel at relative pos (%d,%d)", dx, dy); + esp_err_t ret = esp_painter_draw_pixel(handle, buffer, buffer_size, x + dx, y + dy, color_value); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to draw pixel at (%d,%d)", x + dx, y + dy); + return ret; + } + } + } + } + + return ESP_OK; +} + +static esp_err_t esp_painter_draw_text(esp_painter_t *painter, uint8_t *buffer, + uint32_t buffer_size, uint16_t x, uint16_t y, + uint32_t text_width, uint32_t text_height, + const esp_painter_basic_font_t *font, + uint16_t color_value, const char *text) +{ + uint16_t cursor_x = x; + uint16_t cursor_y = y; + esp_err_t ret = ESP_OK; + + while (*text) { + if (cursor_y >= text_height) { + break; + } + + switch (*text) { + case '\n': + cursor_x = x; + cursor_y += font->height; + break; + case '\r': + cursor_x = x; + break; + default: + if (cursor_x + font->width <= text_width) { + ret = esp_painter_draw_char(painter, buffer, buffer_size, + cursor_x, cursor_y, font, color_value, *text); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to draw char at (%d,%d)", cursor_x, cursor_y); + return ret; + } + } + cursor_x += font->width; + + if (cursor_x >= text_width) { + cursor_x = x; + cursor_y += font->height; + } + break; + } + text++; + } + return ret; +} + +esp_err_t esp_painter_draw_string(esp_painter_handle_t handle, uint8_t *buffer, uint32_t buffer_size, + uint16_t x, uint16_t y, const esp_painter_basic_font_t *font, + esp_painter_color_t color, const char* text) +{ + esp_err_t ret = ESP_OK; + esp_painter_t *painter = (esp_painter_t *)handle; + if (!painter || !buffer || !text) { + return ESP_ERR_INVALID_ARG; + } + + if (!font) { + font = painter->default_font; + if (!font) { + ESP_LOGE(TAG, "No font specified"); + return ESP_ERR_INVALID_ARG; + } + } + + if (x >= painter->canvas.width || y >= painter->canvas.height) { + ESP_LOGW(TAG, "Starting position out of bounds: (%d,%d)", x, y); + return ESP_ERR_INVALID_ARG; + } + + uint16_t color_value = (uint16_t)esp_painter_get_color(handle, color); + +#if CONFIG_SOC_PPA_SUPPORTED + bool using_ppa = (painter->color_format == ESP_PAINTER_COLOR_FORMAT_YUV420 || + painter->color_format == ESP_PAINTER_COLOR_FORMAT_YUV422); + if (using_ppa) { + uint16_t text_width = strlen(text) * font->width; + uint16_t text_height = font->height; + + painter->text_canvas.width = text_width; + painter->text_canvas.height = text_height; + + uint32_t aligned_size = ALIGN_UP(text_width * text_height * 2); + if (aligned_size > buffer_size) { + ESP_LOGE(TAG, "Buffer too small: need %" PRIu32 ", have %" PRIu32, aligned_size, buffer_size); + return ESP_ERR_INVALID_SIZE; + } + + uint8_t *ppa_output_buffer = heap_caps_aligned_alloc( + data_cache_line_size, + aligned_size, + MALLOC_CAP_SPIRAM + ); + if (!ppa_output_buffer) { + ESP_LOGE(TAG, "Failed to allocate PPA output buffer"); + return ESP_ERR_NO_MEM; + } + + int ret = esp_painter_convert_yuv420_to_rgb565(painter, buffer, ppa_output_buffer, + aligned_size, + text_width, text_height, + x, y); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "First PPA conversion failed"); + goto cleanup; + } + + ret = esp_painter_draw_text(painter, ppa_output_buffer, aligned_size, 0, 0, text_width, text_height, font, color_value, text); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to draw text"); + goto cleanup; + } + + ret = esp_painter_convert_rgb565_to_yuv420(painter, ppa_output_buffer, buffer, + buffer_size, + text_width, text_height, + painter->canvas.width, painter->canvas.height, + x, y); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Second PPA conversion failed"); + goto cleanup; + } + +cleanup: + if (ppa_output_buffer) { + heap_caps_free(ppa_output_buffer); + ppa_output_buffer = NULL; + } + + if (ret != ESP_OK) { + return ret; + } + } else { + ret = esp_painter_draw_text(painter, buffer, buffer_size, x, y, painter->canvas.width, painter->canvas.height, font, color_value, text); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to draw text"); + return ret; + } + } +#else + ret = esp_painter_draw_text(painter, buffer, buffer_size, x, y, painter->canvas.width, painter->canvas.height, font, color_value, text); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to draw text"); + return ret; + } +#endif + + ret = esp_cache_msync(buffer, buffer_size, ESP_CACHE_MSYNC_FLAG_INVALIDATE); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Cache sync failed"); + } + + return ret; +} + +esp_err_t esp_painter_draw_string_rgb565(esp_painter_handle_t handle, uint8_t *buffer, uint32_t buffer_size, + uint16_t x, uint16_t y, const esp_painter_basic_font_t *font, + uint16_t color565, const char *text) +{ + esp_painter_t *painter = (esp_painter_t *)handle; + esp_painter_t local_painter; + uint16_t text_width = 0; + uint16_t text_height = 0; + esp_err_t ret; + + if (!painter || !buffer || !text) { + return ESP_ERR_INVALID_ARG; + } + if (painter->color_format != ESP_PAINTER_COLOR_FORMAT_RGB565) { + return ESP_ERR_NOT_SUPPORTED; + } + if (!font) { + font = painter->default_font; + if (!font) { + ESP_LOGE(TAG, "No font specified"); + return ESP_ERR_INVALID_ARG; + } + } + if (x >= painter->canvas.width || y >= painter->canvas.height) { + ESP_LOGW(TAG, "Starting position out of bounds: (%d,%d)", x, y); + return ESP_ERR_INVALID_ARG; + } + + esp_painter_measure_text(font, text, &text_width, &text_height); + if (text_width == 0 || text_height == 0) { + return ESP_OK; + } + if (buffer_size < (uint32_t)text_width * text_height * 2) { + return ESP_ERR_INVALID_SIZE; + } + + local_painter = *painter; + local_painter.canvas.width = text_width; + local_painter.canvas.height = text_height; + + ret = esp_painter_draw_text(&local_painter, buffer, buffer_size, 0, 0, + text_width, text_height, + font, esp_painter_get_rgb565_color_value(handle, color565), text); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to draw RGB565 text"); + return ret; + } + + ret = esp_cache_msync(buffer, buffer_size, ESP_CACHE_MSYNC_FLAG_INVALIDATE); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Cache sync failed"); + } + + return ret; +} + +esp_err_t esp_painter_draw_string_format(esp_painter_handle_t handle, uint8_t *buffer, uint32_t buffer_size, + uint16_t x, uint16_t y, const esp_painter_basic_font_t *font, + esp_painter_color_t color, const char* fmt, ...) +{ + char buf[CONFIG_ESP_PAINTER_FORMAT_SIZE_MAX]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + return esp_painter_draw_string(handle, buffer, buffer_size, x, y, font, color, buf); +} + +esp_err_t esp_painter_init(esp_painter_config_t *config, esp_painter_handle_t *handle) +{ + if (!config || !handle) { + ESP_LOGE(TAG, "Invalid arguments"); + return ESP_ERR_INVALID_ARG; + } + + esp_painter_t *painter = (esp_painter_t *)calloc(1, sizeof(esp_painter_t)); + if (!painter) { + ESP_LOGE(TAG, "Memory allocation failed"); + return ESP_ERR_NO_MEM; + } + + painter->canvas.width = config->canvas.width; + painter->canvas.height = config->canvas.height; + painter->color_format = config->color_format; + painter->default_font = config->default_font; + painter->swap_rgb565 = config->swap_rgb565; + + if (config->color_format == ESP_PAINTER_COLOR_FORMAT_YUV420 || + config->color_format == ESP_PAINTER_COLOR_FORMAT_YUV422) { +#if CONFIG_SOC_PPA_SUPPORTED + ppa_client_config_t ppa_srm_config = { + .oper_type = PPA_OPERATION_SRM, + }; + ESP_ERROR_CHECK(ppa_register_client(&ppa_srm_config, &painter->ppa_client)); + ESP_ERROR_CHECK(esp_cache_get_alignment(MALLOC_CAP_SPIRAM, &data_cache_line_size)); +#else + free(painter); + ESP_LOGE(TAG, "YUV painter mode requires PPA support on this target"); + return ESP_ERR_NOT_SUPPORTED; +#endif + } + + *handle = painter; + ESP_LOGI(TAG, "Painter initialized: %dx%d, format: %d", + config->canvas.width, config->canvas.height, config->color_format); + return ESP_OK; +} + +esp_err_t esp_painter_deinit(esp_painter_handle_t handle) +{ + esp_painter_t *painter = (esp_painter_t *)handle; + if (!painter) { + return ESP_ERR_INVALID_ARG; + } + + +#if CONFIG_SOC_PPA_SUPPORTED + if(painter->ppa_client) { + ppa_unregister_client(painter->ppa_client); + painter->ppa_client = NULL; + } +#endif + + free(painter); + return ESP_OK; +} diff --git a/components/lua_modules/esp_painter/font/basic_font_12.c b/components/lua_modules/esp_painter/font/basic_font_12.c new file mode 100644 index 0000000..594afc3 --- /dev/null +++ b/components/lua_modules/esp_painter/font/basic_font_12.c @@ -0,0 +1,212 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "sdkconfig.h" + +#include "esp_painter_font.h" + +#if CONFIG_ESP_PAINTER_BASIC_FONT_12 + +static const uint8_t bitmap[] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*" ",0*/ + + 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, /*"!",1*/ + + 0x28, 0x28, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*""",2*/ + + 0x00, 0x00, 0x50, 0x50, 0xF8, 0x50, 0x50, 0xF8, 0x50, 0x50, 0x00, 0x00, /*"#",3*/ + + 0x00, 0x20, 0x70, 0xA8, 0xA0, 0x60, 0x30, 0x28, 0xA8, 0x70, 0x20, 0x00, /*"$",4*/ + + 0x00, 0x00, 0x48, 0xA8, 0xB0, 0xA8, 0x74, 0x34, 0x54, 0x48, 0x00, 0x00, /*"%",5*/ + + 0x00, 0x00, 0x20, 0x50, 0x50, 0x6C, 0xA8, 0xA8, 0x94, 0x68, 0x00, 0x00, /*"&",6*/ + + 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"'",7*/ + + 0x08, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x08, 0x00, /*"(",8*/ + + 0x40, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x40, 0x00, /*")",9*/ + + 0x00, 0x00, 0x00, 0x20, 0xA8, 0x70, 0x70, 0xA8, 0x20, 0x00, 0x00, 0x00, /*"*",10*/ + + 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, /*"+",11*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x80, 0x00, /*",",12*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"-",13*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, /*".",14*/ + + 0x00, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x00, /*"/",15*/ + + 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, /*"0",16*/ + + 0x00, 0x00, 0x20, 0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x00, 0x00, /*"1",17*/ + + 0x00, 0x00, 0x70, 0x88, 0x88, 0x10, 0x20, 0x40, 0x80, 0xF8, 0x00, 0x00, /*"2",18*/ + + 0x00, 0x00, 0x70, 0x88, 0x08, 0x30, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, /*"3",19*/ + + 0x00, 0x00, 0x10, 0x30, 0x30, 0x50, 0x90, 0xF8, 0x10, 0x38, 0x00, 0x00, /*"4",20*/ + + 0x00, 0x00, 0xF8, 0x80, 0x80, 0xF0, 0x88, 0x08, 0x88, 0x70, 0x00, 0x00, /*"5",21*/ + + 0x00, 0x00, 0x30, 0x48, 0x80, 0xB0, 0xC8, 0x88, 0x88, 0x70, 0x00, 0x00, /*"6",22*/ + + 0x00, 0x00, 0x78, 0x08, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, /*"7",23*/ + + 0x00, 0x00, 0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, /*"8",24*/ + + 0x00, 0x00, 0x70, 0x88, 0x88, 0x98, 0x68, 0x08, 0x90, 0x60, 0x00, 0x00, /*"9",25*/ + + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, /*":",26*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, /*";",27*/ + + 0x00, 0x00, 0x08, 0x10, 0x20, 0x40, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, /*"<",28*/ + + 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, /*"=",29*/ + + 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, /*">",30*/ + + 0x00, 0x00, 0x70, 0x88, 0x88, 0x10, 0x20, 0x20, 0x00, 0x20, 0x00, 0x00, /*"?",31*/ + + 0x00, 0x00, 0x38, 0x44, 0x94, 0xB4, 0xB4, 0xB8, 0x44, 0x38, 0x00, 0x00, /*"@",32*/ + + 0x00, 0x00, 0x20, 0x20, 0x30, 0x50, 0x50, 0x78, 0x48, 0xCC, 0x00, 0x00, /*"A",33*/ + + 0x00, 0x00, 0xF0, 0x48, 0x48, 0x70, 0x48, 0x48, 0x48, 0xF0, 0x00, 0x00, /*"B",34*/ + + 0x00, 0x00, 0x78, 0x88, 0x80, 0x80, 0x80, 0x80, 0x88, 0x70, 0x00, 0x00, /*"C",35*/ + + 0x00, 0x00, 0xF0, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0xF0, 0x00, 0x00, /*"D",36*/ + + 0x00, 0x00, 0xF8, 0x48, 0x50, 0x70, 0x50, 0x40, 0x48, 0xF8, 0x00, 0x00, /*"E",37*/ + + 0x00, 0x00, 0xF8, 0x48, 0x50, 0x70, 0x50, 0x40, 0x40, 0xE0, 0x00, 0x00, /*"F",38*/ + + 0x00, 0x00, 0x38, 0x48, 0x80, 0x80, 0x9C, 0x88, 0x48, 0x30, 0x00, 0x00, /*"G",39*/ + + 0x00, 0x00, 0xCC, 0x48, 0x48, 0x78, 0x48, 0x48, 0x48, 0xCC, 0x00, 0x00, /*"H",40*/ + + 0x00, 0x00, 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xF8, 0x00, 0x00, /*"I",41*/ + + 0x00, 0x00, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0xE0, /*"J",42*/ + + 0x00, 0x00, 0xEC, 0x48, 0x50, 0x60, 0x50, 0x48, 0x48, 0xEC, 0x00, 0x00, /*"K",43*/ + + 0x00, 0x00, 0xE0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0xFC, 0x00, 0x00, /*"L",44*/ + + 0x00, 0x00, 0xDC, 0xD8, 0xD8, 0xD8, 0xA8, 0xA8, 0xA8, 0xAC, 0x00, 0x00, /*"M",45*/ + + 0x00, 0x00, 0xDC, 0x48, 0x68, 0x68, 0x58, 0x58, 0x48, 0xE8, 0x00, 0x00, /*"N",46*/ + + 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, /*"O",47*/ + + 0x00, 0x00, 0xF0, 0x48, 0x48, 0x70, 0x40, 0x40, 0x40, 0xE0, 0x00, 0x00, /*"P",48*/ + + 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x88, 0xE8, 0x98, 0x70, 0x18, 0x00, /*"Q",49*/ + + 0x00, 0x00, 0xF0, 0x48, 0x48, 0x70, 0x50, 0x48, 0x48, 0xEC, 0x00, 0x00, /*"R",50*/ + + 0x00, 0x00, 0x78, 0x88, 0x80, 0x60, 0x10, 0x08, 0x88, 0xF0, 0x00, 0x00, /*"S",51*/ + + 0x00, 0x00, 0xF8, 0xA8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x00, 0x00, /*"T",52*/ + + 0x00, 0x00, 0xCC, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x30, 0x00, 0x00, /*"U",53*/ + + 0x00, 0x00, 0xCC, 0x48, 0x48, 0x50, 0x50, 0x30, 0x20, 0x20, 0x00, 0x00, /*"V",54*/ + + 0x00, 0x00, 0xA8, 0xA8, 0xA8, 0xA8, 0x70, 0x50, 0x50, 0x50, 0x00, 0x00, /*"W",55*/ + + 0x00, 0x00, 0xD8, 0x50, 0x50, 0x20, 0x20, 0x50, 0x50, 0xD8, 0x00, 0x00, /*"X",56*/ + + 0x00, 0x00, 0xD8, 0x50, 0x50, 0x50, 0x20, 0x20, 0x20, 0x70, 0x00, 0x00, /*"Y",57*/ + + 0x00, 0x00, 0xF8, 0x90, 0x10, 0x20, 0x20, 0x40, 0x48, 0xF8, 0x00, 0x00, /*"Z",58*/ + + 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, /*"[",59*/ + + 0x00, 0x40, 0x40, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x08, 0x08, 0x00, /*"\",60*/ + + 0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x00, /*"]",61*/ + + 0x20, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"^",62*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, /*"_",63*/ + + 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"`",64*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x48, 0x38, 0x48, 0x3C, 0x00, 0x00, /*"a",65*/ + + 0x00, 0xC0, 0x40, 0x40, 0x40, 0x70, 0x48, 0x48, 0x48, 0x70, 0x00, 0x00, /*"b",66*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x48, 0x40, 0x48, 0x30, 0x00, 0x00, /*"c",67*/ + + 0x00, 0x18, 0x08, 0x08, 0x08, 0x38, 0x48, 0x48, 0x48, 0x3C, 0x00, 0x00, /*"d",68*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x48, 0x78, 0x40, 0x38, 0x00, 0x00, /*"e",69*/ + + 0x00, 0x18, 0x24, 0x20, 0x20, 0x78, 0x20, 0x20, 0x20, 0x78, 0x00, 0x00, /*"f",70*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x48, 0x30, 0x40, 0x38, 0x44, 0x38, /*"g",71*/ + + 0x00, 0xC0, 0x40, 0x40, 0x40, 0x70, 0x48, 0x48, 0x48, 0xEC, 0x00, 0x00, /*"h",72*/ + + 0x00, 0x20, 0x20, 0x00, 0x00, 0x60, 0x20, 0x20, 0x20, 0x70, 0x00, 0x00, /*"i",73*/ + + 0x00, 0x10, 0x10, 0x00, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0xE0, /*"j",74*/ + + 0x00, 0xC0, 0x40, 0x40, 0x40, 0x58, 0x50, 0x60, 0x50, 0xC8, 0x00, 0x00, /*"k",75*/ + + 0x00, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xF8, 0x00, 0x00, /*"l",76*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xA8, 0xA8, 0xA8, 0xA8, 0x00, 0x00, /*"m",77*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x48, 0x48, 0x48, 0xEC, 0x00, 0x00, /*"n",78*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x48, 0x48, 0x48, 0x30, 0x00, 0x00, /*"o",79*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x48, 0x48, 0x48, 0x70, 0x40, 0xE0, /*"p",80*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x48, 0x48, 0x48, 0x38, 0x08, 0x1C, /*"q",81*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x60, 0x40, 0x40, 0xE0, 0x00, 0x00, /*"r",82*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x40, 0x30, 0x08, 0x78, 0x00, 0x00, /*"s",83*/ + + 0x00, 0x00, 0x00, 0x20, 0x20, 0x78, 0x20, 0x20, 0x20, 0x38, 0x00, 0x00, /*"t",84*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x48, 0x48, 0x48, 0x3C, 0x00, 0x00, /*"u",85*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x50, 0x50, 0x20, 0x20, 0x00, 0x00, /*"v",86*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xA8, 0x70, 0x50, 0x50, 0x00, 0x00, /*"w",87*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x50, 0x20, 0x50, 0xD8, 0x00, 0x00, /*"x",88*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x48, 0x48, 0x30, 0x10, 0x20, 0xC0, /*"y",89*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x10, 0x20, 0x20, 0x78, 0x00, 0x00, /*"z",90*/ + + 0x18, 0x10, 0x10, 0x10, 0x10, 0x30, 0x10, 0x10, 0x10, 0x10, 0x18, 0x00, /*"{",91*/ + + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, /*"|",92*/ + + 0x60, 0x20, 0x20, 0x20, 0x20, 0x10, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, /*"}",93*/ + + 0x68, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"~",94*/ +}; + +const esp_painter_basic_font_t esp_painter_basic_font_12 = { + .bitmap = bitmap, + .width = 6, + .height = 12, +}; + +#endif diff --git a/components/lua_modules/esp_painter/font/basic_font_16.c b/components/lua_modules/esp_painter/font/basic_font_16.c new file mode 100644 index 0000000..18f8fde --- /dev/null +++ b/components/lua_modules/esp_painter/font/basic_font_16.c @@ -0,0 +1,212 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "sdkconfig.h" + +#include "esp_painter_font.h" + +#if CONFIG_ESP_PAINTER_BASIC_FONT_16 + +static const uint8_t bitmap[] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*" ",0*/ + + 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, /*"!",1*/ + + 0x00, 0x12, 0x24, 0x24, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*""",2*/ + + 0x00, 0x00, 0x00, 0x12, 0x12, 0x12, 0x7E, 0x24, 0x24, 0x24, 0x7E, 0x24, 0x24, 0x24, 0x00, 0x00, /*"#",3*/ + + 0x00, 0x00, 0x08, 0x3C, 0x4A, 0x4A, 0x48, 0x38, 0x0C, 0x0A, 0x0A, 0x4A, 0x4A, 0x3C, 0x08, 0x08, /*"$",4*/ + + 0x00, 0x00, 0x00, 0x44, 0xA4, 0xA8, 0xA8, 0xB0, 0x54, 0x1A, 0x2A, 0x2A, 0x4A, 0x44, 0x00, 0x00, /*"%",5*/ + + 0x00, 0x00, 0x00, 0x30, 0x48, 0x48, 0x48, 0x50, 0x6E, 0xA4, 0x94, 0x98, 0x89, 0x76, 0x00, 0x00, /*"&",6*/ + + 0x00, 0x60, 0x20, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"'",7*/ + + 0x00, 0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x02, 0x00, /*"(",8*/ + + 0x00, 0x40, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x00, /*")",9*/ + + 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0xD6, 0x38, 0x38, 0xD6, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, /*"*",10*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x7F, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /*"+",11*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x20, 0x20, 0x40, /*",",12*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"-",13*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, /*".",14*/ + + 0x00, 0x00, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x00, /*"/",15*/ + + 0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00, /*"0",16*/ + + 0x00, 0x00, 0x00, 0x08, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00, /*"1",17*/ + + 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x02, 0x04, 0x08, 0x10, 0x20, 0x42, 0x7E, 0x00, 0x00, /*"2",18*/ + + 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x02, 0x04, 0x18, 0x04, 0x02, 0x42, 0x42, 0x3C, 0x00, 0x00, /*"3",19*/ + + 0x00, 0x00, 0x00, 0x04, 0x0C, 0x0C, 0x14, 0x24, 0x24, 0x44, 0x7F, 0x04, 0x04, 0x1F, 0x00, 0x00, /*"4",20*/ + + 0x00, 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x78, 0x44, 0x02, 0x02, 0x42, 0x44, 0x38, 0x00, 0x00, /*"5",21*/ + + 0x00, 0x00, 0x00, 0x18, 0x24, 0x40, 0x40, 0x5C, 0x62, 0x42, 0x42, 0x42, 0x22, 0x1C, 0x00, 0x00, /*"6",22*/ + + 0x00, 0x00, 0x00, 0x7E, 0x42, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, /*"7",23*/ + + 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x24, 0x18, 0x24, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, /*"8",24*/ + + 0x00, 0x00, 0x00, 0x38, 0x44, 0x42, 0x42, 0x42, 0x46, 0x3A, 0x02, 0x02, 0x24, 0x18, 0x00, 0x00, /*"9",25*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, /*":",26*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, /*";",27*/ + + 0x00, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, /*"<",28*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"=",29*/ + + 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, /*">",30*/ + + 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x62, 0x04, 0x08, 0x08, 0x08, 0x00, 0x18, 0x18, 0x00, 0x00, /*"?",31*/ + + 0x00, 0x00, 0x00, 0x38, 0x44, 0x5A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x5C, 0x42, 0x3C, 0x00, 0x00, /*"@",32*/ + + 0x00, 0x00, 0x00, 0x10, 0x10, 0x18, 0x28, 0x28, 0x24, 0x3C, 0x44, 0x42, 0x42, 0xE7, 0x00, 0x00, /*"A",33*/ + + 0x00, 0x00, 0x00, 0xF8, 0x44, 0x44, 0x44, 0x78, 0x44, 0x42, 0x42, 0x42, 0x44, 0xF8, 0x00, 0x00, /*"B",34*/ + + 0x00, 0x00, 0x00, 0x3E, 0x42, 0x42, 0x80, 0x80, 0x80, 0x80, 0x80, 0x42, 0x44, 0x38, 0x00, 0x00, /*"C",35*/ + + 0x00, 0x00, 0x00, 0xF8, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0xF8, 0x00, 0x00, /*"D",36*/ + + 0x00, 0x00, 0x00, 0xFC, 0x42, 0x48, 0x48, 0x78, 0x48, 0x48, 0x40, 0x42, 0x42, 0xFC, 0x00, 0x00, /*"E",37*/ + + 0x00, 0x00, 0x00, 0xFC, 0x42, 0x48, 0x48, 0x78, 0x48, 0x48, 0x40, 0x40, 0x40, 0xE0, 0x00, 0x00, /*"F",38*/ + + 0x00, 0x00, 0x00, 0x3C, 0x44, 0x44, 0x80, 0x80, 0x80, 0x8E, 0x84, 0x44, 0x44, 0x38, 0x00, 0x00, /*"G",39*/ + + 0x00, 0x00, 0x00, 0xE7, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0xE7, 0x00, 0x00, /*"H",40*/ + + 0x00, 0x00, 0x00, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x00, /*"I",41*/ + + 0x00, 0x00, 0x00, 0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x88, 0xF0, /*"J",42*/ + + 0x00, 0x00, 0x00, 0xEE, 0x44, 0x48, 0x50, 0x70, 0x50, 0x48, 0x48, 0x44, 0x44, 0xEE, 0x00, 0x00, /*"K",43*/ + + 0x00, 0x00, 0x00, 0xE0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0xFE, 0x00, 0x00, /*"L",44*/ + + 0x00, 0x00, 0x00, 0xEE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x54, 0x54, 0x54, 0x54, 0xD6, 0x00, 0x00, /*"M",45*/ + + 0x00, 0x00, 0x00, 0xC7, 0x62, 0x62, 0x52, 0x52, 0x4A, 0x4A, 0x4A, 0x46, 0x46, 0xE2, 0x00, 0x00, /*"N",46*/ + + 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x44, 0x38, 0x00, 0x00, /*"O",47*/ + + 0x00, 0x00, 0x00, 0xFC, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x40, 0x40, 0x40, 0x40, 0xE0, 0x00, 0x00, /*"P",48*/ + + 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xB2, 0x4C, 0x38, 0x06, 0x00, /*"Q",49*/ + + 0x00, 0x00, 0x00, 0xFC, 0x42, 0x42, 0x42, 0x7C, 0x48, 0x48, 0x44, 0x44, 0x42, 0xE3, 0x00, 0x00, /*"R",50*/ + + 0x00, 0x00, 0x00, 0x3E, 0x42, 0x42, 0x40, 0x20, 0x18, 0x04, 0x02, 0x42, 0x42, 0x7C, 0x00, 0x00, /*"S",51*/ + + 0x00, 0x00, 0x00, 0xFE, 0x92, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, /*"T",52*/ + + 0x00, 0x00, 0x00, 0xE7, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, /*"U",53*/ + + 0x00, 0x00, 0x00, 0xE7, 0x42, 0x42, 0x44, 0x24, 0x24, 0x28, 0x28, 0x18, 0x10, 0x10, 0x00, 0x00, /*"V",54*/ + + 0x00, 0x00, 0x00, 0xD6, 0x54, 0x54, 0x54, 0x54, 0x54, 0x6C, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, /*"W",55*/ + + 0x00, 0x00, 0x00, 0xE7, 0x42, 0x24, 0x24, 0x18, 0x18, 0x18, 0x24, 0x24, 0x42, 0xE7, 0x00, 0x00, /*"X",56*/ + + 0x00, 0x00, 0x00, 0xEE, 0x44, 0x44, 0x28, 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, /*"Y",57*/ + + 0x00, 0x00, 0x00, 0x7E, 0x84, 0x04, 0x08, 0x08, 0x10, 0x20, 0x20, 0x42, 0x42, 0xFC, 0x00, 0x00, /*"Z",58*/ + + 0x00, 0x1E, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1E, 0x00, /*"[",59*/ + + 0x00, 0x00, 0x40, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x04, 0x02, 0x02, /*"\",60*/ + + 0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x78, 0x00, /*"]",61*/ + + 0x00, 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"^",62*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, /*"_",63*/ + + 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"`",64*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x0C, 0x34, 0x44, 0x4C, 0x36, 0x00, 0x00, /*"a",65*/ + + 0x00, 0x00, 0x00, 0x00, 0xC0, 0x40, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x64, 0x58, 0x00, 0x00, /*"b",66*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x40, 0x40, 0x40, 0x22, 0x1C, 0x00, 0x00, /*"c",67*/ + + 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x02, 0x3E, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3B, 0x00, 0x00, /*"d",68*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x7E, 0x40, 0x42, 0x3C, 0x00, 0x00, /*"e",69*/ + + 0x00, 0x00, 0x00, 0x00, 0x0C, 0x12, 0x10, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x00, /*"f",70*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x44, 0x44, 0x38, 0x40, 0x3C, 0x42, 0x42, 0x3C, /*"g",71*/ + + 0x00, 0x00, 0x00, 0x00, 0xC0, 0x40, 0x40, 0x5C, 0x62, 0x42, 0x42, 0x42, 0x42, 0xE7, 0x00, 0x00, /*"h",72*/ + + 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x00, /*"i",73*/ + + 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x1C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x78, /*"j",74*/ + + 0x00, 0x00, 0x00, 0x00, 0xC0, 0x40, 0x40, 0x4E, 0x48, 0x50, 0x70, 0x48, 0x44, 0xEE, 0x00, 0x00, /*"k",75*/ + + 0x00, 0x00, 0x00, 0x10, 0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x00, /*"l",76*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x49, 0x49, 0x49, 0x49, 0x49, 0xED, 0x00, 0x00, /*"m",77*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x62, 0x42, 0x42, 0x42, 0x42, 0xE7, 0x00, 0x00, /*"n",78*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, /*"o",79*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x64, 0x42, 0x42, 0x42, 0x64, 0x58, 0x40, 0xE0, /*"p",80*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x26, 0x42, 0x42, 0x42, 0x26, 0x1A, 0x02, 0x07, /*"q",81*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x32, 0x20, 0x20, 0x20, 0x20, 0xF8, 0x00, 0x00, /*"r",82*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x42, 0x40, 0x3C, 0x02, 0x42, 0x7C, 0x00, 0x00, /*"s",83*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x12, 0x0C, 0x00, 0x00, /*"t",84*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3B, 0x00, 0x00, /*"u",85*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x44, 0x44, 0x28, 0x28, 0x10, 0x10, 0x00, 0x00, /*"v",86*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDB, 0x89, 0x4A, 0x5A, 0x54, 0x24, 0x24, 0x00, 0x00, /*"w",87*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x24, 0x18, 0x18, 0x18, 0x24, 0x6E, 0x00, 0x00, /*"x",88*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x42, 0x24, 0x24, 0x18, 0x18, 0x10, 0x10, 0x60, /*"y",89*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x44, 0x08, 0x10, 0x10, 0x22, 0x7E, 0x00, 0x00, /*"z",90*/ + + 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, /*"{",91*/ + + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /*"|",92*/ + + 0x00, 0xC0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0xC0, 0x00, /*"}",93*/ + + 0x20, 0x5A, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"~",94*/ +}; + +const esp_painter_basic_font_t esp_painter_basic_font_16 = { + .bitmap = bitmap, + .width = 8, + .height = 16, +}; + +#endif diff --git a/components/lua_modules/esp_painter/font/basic_font_20.c b/components/lua_modules/esp_painter/font/basic_font_20.c new file mode 100644 index 0000000..4876f47 --- /dev/null +++ b/components/lua_modules/esp_painter/font/basic_font_20.c @@ -0,0 +1,402 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "sdkconfig.h" + +#include "esp_painter_font.h" + +#if CONFIG_ESP_PAINTER_BASIC_FONT_20 + +static const uint8_t bitmap[] = +{ + 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, /*" ",0*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"!",1*/ + + 0x00, 0x00, 0x1B, 0x00, 0x1B, 0x00, 0x36, 0x00, 0x24, 0x00, 0x48, 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, /*""",2*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x7F, 0x80, 0x7F, 0x80, + 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x7F, 0x80, 0x7F, 0x80, 0x22, 0x00, 0x22, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"#",3*/ + + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1E, 0x00, 0x29, 0x00, 0x49, 0x00, 0x49, 0x00, 0x48, 0x00, + 0x28, 0x00, 0x1C, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x09, 0x00, 0x49, 0x00, 0x49, 0x00, 0x4A, 0x00, + 0x3C, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, /*"$",4*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x92, 0x00, 0x94, 0x00, 0x94, 0x00, 0x94, 0x00, + 0x98, 0x00, 0x9B, 0x00, 0x6C, 0x80, 0x14, 0x80, 0x14, 0x80, 0x14, 0x80, 0x24, 0x80, 0x24, 0x80, + 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"%",5*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x24, 0x00, 0x24, 0x00, 0x24, 0x00, 0x24, 0x00, + 0x28, 0x00, 0x33, 0x80, 0x51, 0x00, 0x91, 0x00, 0x89, 0x00, 0x8A, 0x00, 0x86, 0x00, 0x46, 0x40, + 0x39, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"&",6*/ + + 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x40, 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, /*"'",7*/ + + 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, /*"(",8*/ + + 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, + 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, /*")",9*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0xC9, 0x80, + 0xEB, 0x80, 0x1C, 0x00, 0x1C, 0x00, 0xEB, 0x80, 0xC9, 0x80, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"*",10*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x7F, 0xC0, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"+",11*/ + + 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, 0x60, 0x00, 0x60, 0x00, + 0x20, 0x00, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, /*",",12*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"-",13*/ + + 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, 0x60, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*".",14*/ + + 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, + 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, /*"/",15*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x21, 0x00, 0x21, 0x00, 0x40, 0x80, 0x40, 0x80, + 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x21, 0x00, 0x21, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"0",16*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"1",17*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x21, 0x00, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, + 0x00, 0x80, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x80, 0x40, 0x80, + 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"2",18*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x42, 0x00, 0x41, 0x00, 0x41, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x0E, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x80, 0x40, 0x80, 0x40, 0x80, 0x41, 0x00, + 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"3",19*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x06, 0x00, 0x0A, 0x00, 0x0A, 0x00, + 0x12, 0x00, 0x22, 0x00, 0x22, 0x00, 0x42, 0x00, 0x7F, 0x80, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"4",20*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, + 0x2E, 0x00, 0x31, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x40, 0x80, 0x40, 0x80, 0x41, 0x00, + 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"5",21*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x11, 0x00, 0x21, 0x00, 0x40, 0x00, 0x40, 0x00, + 0x5E, 0x00, 0x61, 0x00, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x20, 0x80, 0x21, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"6",22*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x40, 0x80, 0x41, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"7",23*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x21, 0x00, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, + 0x21, 0x00, 0x1E, 0x00, 0x21, 0x00, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x21, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"8",24*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x21, 0x00, 0x41, 0x00, 0x40, 0x80, 0x40, 0x80, + 0x40, 0x80, 0x41, 0x80, 0x22, 0x80, 0x1C, 0x80, 0x00, 0x80, 0x01, 0x00, 0x21, 0x00, 0x22, 0x00, + 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"9",25*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*":",26*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x0C, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, /*";",27*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, + 0x20, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"<",28*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"=",29*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*">",30*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x21, 0x00, 0x40, 0x80, 0x40, 0x80, + 0x60, 0x80, 0x01, 0x00, 0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"?",31*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x21, 0x00, 0x40, 0x80, 0x4E, 0x80, 0x92, 0x80, + 0x92, 0x80, 0xA4, 0x80, 0xA4, 0x80, 0xA4, 0x80, 0xA5, 0x00, 0x9E, 0x00, 0x40, 0x80, 0x21, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"@",32*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x14, 0x00, 0x14, 0x00, + 0x14, 0x00, 0x14, 0x00, 0x22, 0x00, 0x22, 0x00, 0x3E, 0x00, 0x22, 0x00, 0x41, 0x00, 0x41, 0x00, + 0xE3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"A",33*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, + 0x44, 0x00, 0x7C, 0x00, 0x42, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x42, 0x00, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"B",34*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x80, 0x21, 0x80, 0x40, 0x80, 0x40, 0x80, + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x40, 0x80, 0x61, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"C",35*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x42, 0x00, 0x41, 0x00, 0x40, 0x80, + 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x41, 0x00, 0x42, 0x00, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"D",36*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x41, 0x00, 0x40, 0x80, 0x42, 0x00, + 0x42, 0x00, 0x7E, 0x00, 0x42, 0x00, 0x42, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x80, 0x41, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"E",37*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x41, 0x00, 0x40, 0x80, 0x42, 0x00, + 0x42, 0x00, 0x7E, 0x00, 0x42, 0x00, 0x42, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"F",38*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x80, 0x11, 0x80, 0x20, 0x80, 0x40, 0x80, + 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x41, 0xC0, 0x40, 0x80, 0x40, 0x80, 0x20, 0x80, 0x30, 0x80, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"G",39*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0x80, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, + 0x41, 0x00, 0x41, 0x00, 0x7F, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, + 0xE3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"H",40*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"I",41*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x84, 0x00, 0x88, 0x00, 0x70, 0x00, /*"J",42*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x80, 0x42, 0x00, 0x44, 0x00, 0x44, 0x00, + 0x48, 0x00, 0x58, 0x00, 0x68, 0x00, 0x44, 0x00, 0x44, 0x00, 0x42, 0x00, 0x42, 0x00, 0x41, 0x00, + 0xE3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"K",43*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, + 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x80, 0x41, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"L",44*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0x80, 0x63, 0x00, 0x63, 0x00, 0x63, 0x00, + 0x55, 0x00, 0x55, 0x00, 0x55, 0x00, 0x55, 0x00, 0x55, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, + 0xEB, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"M",45*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0x80, 0x61, 0x00, 0x51, 0x00, 0x51, 0x00, + 0x51, 0x00, 0x49, 0x00, 0x49, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x43, 0x00, 0x43, 0x00, + 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"N",46*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x63, 0x00, 0x41, 0x00, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x41, 0x00, 0x63, 0x00, + 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"O",47*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x41, 0x00, 0x40, 0x80, 0x40, 0x80, + 0x40, 0x80, 0x41, 0x00, 0x7E, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"P",48*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x63, 0x00, 0x41, 0x00, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xB8, 0x80, 0x45, 0x00, 0x63, 0x00, + 0x1E, 0x00, 0x02, 0x80, 0x01, 0x00, 0x00, 0x00, /*"Q",49*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x42, 0x00, 0x41, 0x00, 0x41, 0x00, + 0x42, 0x00, 0x7C, 0x00, 0x48, 0x00, 0x44, 0x00, 0x44, 0x00, 0x42, 0x00, 0x42, 0x00, 0x41, 0x00, + 0xE1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"R",50*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x23, 0x00, 0x41, 0x00, 0x40, 0x00, + 0x40, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x02, 0x00, 0x01, 0x00, 0x41, 0x00, 0x41, 0x00, 0x62, 0x00, + 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"S",51*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x88, 0x80, 0x88, 0x80, 0x08, 0x00, + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"T",52*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0x80, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, + 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x22, 0x00, + 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"U",53*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0x80, 0x41, 0x00, 0x41, 0x00, 0x22, 0x00, + 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"V",54*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0x80, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, + 0x49, 0x00, 0x55, 0x00, 0x55, 0x00, 0x55, 0x00, 0x55, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"W",55*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x80, 0x21, 0x00, 0x12, 0x00, 0x12, 0x00, + 0x14, 0x00, 0x0C, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x14, 0x00, 0x12, 0x00, 0x22, 0x00, 0x21, 0x00, + 0x73, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"X",56*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0x80, 0x41, 0x00, 0x41, 0x00, 0x22, 0x00, + 0x22, 0x00, 0x14, 0x00, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Y",57*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x21, 0x00, 0x41, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x80, 0x21, 0x00, + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Z",58*/ + + 0x00, 0x00, 0x0F, 0x80, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, /*"[",59*/ + + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, /*"\",60*/ + + 0x00, 0x00, 0x7C, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, /*"]",61*/ + + 0x00, 0x00, 0x1C, 0x00, 0x22, 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, /*"^",62*/ + + 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, 0xFF, 0xC0, /*"_",63*/ + + 0x00, 0x00, 0x18, 0x00, 0x04, 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, /*"`",64*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x00, 0x41, 0x00, 0x41, 0x00, 0x07, 0x00, 0x39, 0x00, 0x41, 0x00, 0x41, 0x00, 0x43, 0x40, + 0x3D, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"a",65*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, + 0x2E, 0x00, 0x31, 0x00, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x31, 0x00, + 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"b",66*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1E, 0x00, 0x21, 0x00, 0x41, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x80, 0x21, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"c",67*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x1D, 0x00, 0x23, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x23, 0x00, + 0x1D, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"d",68*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1E, 0x00, 0x21, 0x00, 0x40, 0x80, 0x40, 0x80, 0x7F, 0x80, 0x40, 0x00, 0x40, 0x80, 0x21, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"e",69*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x08, 0x80, 0x08, 0x00, 0x08, 0x00, + 0x3F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"f",70*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0x80, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x1E, 0x00, 0x20, 0x00, 0x3F, 0x00, + 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x3F, 0x00, /*"g",71*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, + 0x2E, 0x00, 0x31, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, + 0x73, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"h",72*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"i",73*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x22, 0x00, 0x3C, 0x00, /*"j",74*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, + 0x27, 0x00, 0x22, 0x00, 0x24, 0x00, 0x28, 0x00, 0x34, 0x00, 0x24, 0x00, 0x22, 0x00, 0x21, 0x00, + 0x73, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"k",75*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x78, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"l",76*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xDE, 0x00, 0x69, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, + 0xED, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"m",77*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6E, 0x00, 0x31, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, + 0x73, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"n",78*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1E, 0x00, 0x21, 0x00, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x21, 0x00, + 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"o",79*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6E, 0x00, 0x31, 0x00, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x31, 0x00, + 0x2E, 0x00, 0x20, 0x00, 0x20, 0x00, 0x70, 0x00, /*"p",80*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1D, 0x00, 0x23, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0x23, 0x00, + 0x1D, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x80, /*"q",81*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x73, 0x80, 0x14, 0x80, 0x18, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, + 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"r",82*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0x43, 0x00, 0x41, 0x00, 0x60, 0x00, 0x1C, 0x00, 0x03, 0x00, 0x41, 0x00, 0x61, 0x00, + 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"s",83*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x3F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x80, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"t",84*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x63, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x23, 0x00, + 0x1D, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"u",85*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xE3, 0x80, 0x41, 0x00, 0x41, 0x00, 0x22, 0x00, 0x22, 0x00, 0x14, 0x00, 0x14, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"v",86*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xDD, 0x80, 0x49, 0x00, 0x49, 0x00, 0x49, 0x00, 0x55, 0x00, 0x55, 0x00, 0x55, 0x00, 0x22, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"w",87*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x73, 0x80, 0x21, 0x00, 0x12, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x12, 0x00, 0x21, 0x00, + 0x73, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"x",88*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x73, 0x80, 0x21, 0x00, 0x12, 0x00, 0x12, 0x00, 0x12, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x08, 0x00, 0x28, 0x00, 0x30, 0x00, /*"y",89*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0x00, 0x42, 0x00, 0x44, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x80, 0x20, 0x80, 0x21, 0x00, + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"z",90*/ + + 0x00, 0x00, 0x01, 0x80, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x0C, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x01, 0x80, 0x00, 0x00, /*"{",91*/ + + 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, /*"|",92*/ + + 0x00, 0x00, 0x60, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, + 0x10, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, + 0x10, 0x00, 0x10, 0x00, 0x60, 0x00, 0x00, 0x00, /*"}",93*/ + + 0x30, 0x00, 0x48, 0x80, 0x44, 0x80, 0x03, 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, /*"~",94*/ +}; + +const esp_painter_basic_font_t esp_painter_basic_font_20 = { + .bitmap = bitmap, + .width = 10, + .height = 20, +}; + +#endif diff --git a/components/lua_modules/esp_painter/font/basic_font_24.c b/components/lua_modules/esp_painter/font/basic_font_24.c new file mode 100644 index 0000000..46da691 --- /dev/null +++ b/components/lua_modules/esp_painter/font/basic_font_24.c @@ -0,0 +1,402 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "sdkconfig.h" + +#include "esp_painter_font.h" + +#if CONFIG_ESP_PAINTER_BASIC_FONT_24 + +static const uint8_t bitmap[] = +{ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*" ",0*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"!",1*/ + + 0x00, 0x00, 0x00, 0x00, 0x06, 0x60, 0x06, 0x60, 0x0C, 0xC0, 0x19, 0x80, 0x11, 0x00, 0x22, 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, /*""",2*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x08, 0x40, 0x08, 0x40, 0x08, 0x40, + 0x7F, 0xE0, 0x7F, 0xE0, 0x10, 0x40, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x7F, 0xE0, + 0x7F, 0xE0, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"#",3*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x0F, 0x80, 0x1A, 0xC0, 0x32, 0xC0, + 0x33, 0xC0, 0x32, 0x00, 0x1A, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x80, 0x03, 0x80, 0x02, 0xC0, + 0x32, 0xC0, 0x3A, 0xC0, 0x32, 0xC0, 0x12, 0x80, 0x0F, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, /*"$",4*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x80, 0x50, 0x80, 0x89, 0x00, 0x89, 0x00, + 0x89, 0x00, 0x8A, 0x00, 0x8A, 0x00, 0x5C, 0x00, 0x75, 0xC0, 0x05, 0x40, 0x0A, 0x20, 0x0A, 0x20, + 0x12, 0x20, 0x12, 0x20, 0x12, 0x20, 0x21, 0x40, 0x21, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"%",5*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, + 0x36, 0x00, 0x36, 0x00, 0x34, 0x00, 0x19, 0xE0, 0x38, 0x80, 0x58, 0x80, 0xCC, 0x80, 0xCC, 0x80, + 0xC6, 0x80, 0xC7, 0x00, 0xC3, 0x10, 0x63, 0x90, 0x3C, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"&",6*/ + + 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x38, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 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, /*"'",7*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, /*"(",8*/ + + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, /*")",9*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, + 0x02, 0x00, 0x62, 0x30, 0x72, 0xF0, 0x0B, 0x80, 0x0F, 0x80, 0x7A, 0xF0, 0x62, 0x30, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"*",10*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7F, 0xF0, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"+",11*/ + + 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, 0x30, 0x00, 0x38, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, /*",",12*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"-",13*/ + + 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, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*".",14*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x60, 0x00, 0x40, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x80, + 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x06, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x20, 0x00, 0x60, 0x00, 0x40, 0x00, 0x00, 0x00, /*"/",15*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x19, 0x80, 0x30, 0xC0, + 0x30, 0xC0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x60, 0x60, 0x30, 0xC0, 0x30, 0xC0, 0x19, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"0",16*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3E, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"1",17*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x21, 0x80, 0x40, 0xC0, + 0x60, 0xC0, 0x60, 0xC0, 0x00, 0xC0, 0x00, 0x80, 0x01, 0x80, 0x03, 0x00, 0x06, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x10, 0x40, 0x20, 0x40, 0x60, 0x40, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"2",18*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x63, 0x00, 0x61, 0x80, + 0x61, 0x80, 0x01, 0x80, 0x01, 0x80, 0x03, 0x00, 0x0E, 0x00, 0x01, 0x80, 0x00, 0x80, 0x00, 0xC0, + 0x00, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x61, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"3",19*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x03, 0x80, + 0x05, 0x80, 0x05, 0x80, 0x09, 0x80, 0x11, 0x80, 0x11, 0x80, 0x21, 0x80, 0x41, 0x80, 0x7F, 0xF0, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"4",20*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0x20, 0x00, 0x20, 0x00, + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x2F, 0x00, 0x31, 0x80, 0x20, 0xC0, 0x00, 0xC0, 0x00, 0xC0, + 0x60, 0xC0, 0x60, 0xC0, 0x41, 0x80, 0x21, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"5",21*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x18, 0xC0, 0x30, 0xC0, + 0x30, 0x00, 0x20, 0x00, 0x60, 0x00, 0x67, 0x80, 0x68, 0xC0, 0x70, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x60, 0x60, 0x20, 0x60, 0x30, 0x40, 0x18, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"6",22*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xE0, 0x30, 0x60, 0x20, 0x40, + 0x20, 0x80, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"7",23*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x80, 0x30, 0xC0, 0x60, 0x60, + 0x60, 0x60, 0x60, 0x60, 0x30, 0x40, 0x38, 0xC0, 0x0F, 0x00, 0x13, 0x80, 0x30, 0xC0, 0x60, 0x60, + 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x30, 0xC0, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"8",24*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x30, 0x80, 0x30, 0xC0, + 0x60, 0x40, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xE0, 0x31, 0x60, 0x1E, 0x60, 0x00, 0x60, + 0x00, 0xC0, 0x00, 0xC0, 0x30, 0x80, 0x31, 0x80, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"9",25*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*":",26*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, /*";",27*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x01, 0x00, + 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"<",28*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"=",29*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x01, 0x00, + 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*">",30*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xC0, 0x18, 0x60, 0x20, 0x30, + 0x20, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0xE0, 0x01, 0x80, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"?",31*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x18, 0xC0, 0x30, 0x40, 0x33, 0xA0, + 0x26, 0xA0, 0x66, 0xA0, 0x65, 0xA0, 0x6D, 0x20, 0x6D, 0x20, 0x6D, 0x20, 0x6D, 0x20, 0x6D, 0x40, + 0x27, 0x80, 0x30, 0x20, 0x30, 0x40, 0x18, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"@",32*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x0A, 0x00, + 0x0B, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x11, 0x80, 0x10, 0x80, 0x1F, 0x80, 0x20, 0xC0, + 0x20, 0xC0, 0x20, 0x40, 0x40, 0x40, 0x40, 0x60, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"A",33*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x31, 0xC0, 0x30, 0xC0, + 0x30, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x31, 0x80, 0x3F, 0x00, 0x30, 0xC0, 0x30, 0x40, 0x30, 0x60, + 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0xC0, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"B",34*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xC0, 0x18, 0xC0, 0x30, 0x60, + 0x30, 0x20, 0x20, 0x20, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, + 0x60, 0x20, 0x30, 0x20, 0x30, 0x40, 0x18, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"C",35*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x31, 0x80, 0x30, 0xC0, + 0x30, 0xC0, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, + 0x30, 0x60, 0x30, 0xC0, 0x30, 0xC0, 0x31, 0x80, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"D",36*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x60, 0xC0, 0x60, 0x20, + 0x60, 0x20, 0x60, 0x00, 0x61, 0x00, 0x61, 0x00, 0x7F, 0x00, 0x61, 0x00, 0x61, 0x00, 0x61, 0x00, + 0x60, 0x00, 0x60, 0x20, 0x60, 0x20, 0x60, 0x40, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"E",37*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x60, 0xC0, 0x60, 0x20, + 0x60, 0x20, 0x60, 0x00, 0x61, 0x00, 0x61, 0x00, 0x7F, 0x00, 0x61, 0x00, 0x61, 0x00, 0x61, 0x00, + 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"F",38*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x18, 0x80, 0x30, 0x40, + 0x30, 0x40, 0x20, 0x40, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x63, 0xF0, 0x60, 0xC0, + 0x60, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x18, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"G",39*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x60, 0x60, 0x60, 0x60, + 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7F, 0xE0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"H",40*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0x06, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"I",41*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xE0, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x63, 0x00, 0x66, 0x00, 0x3C, 0x00, /*"J",42*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF3, 0xC0, 0x61, 0x80, 0x63, 0x00, + 0x62, 0x00, 0x64, 0x00, 0x68, 0x00, 0x6C, 0x00, 0x74, 0x00, 0x76, 0x00, 0x62, 0x00, 0x63, 0x00, + 0x61, 0x00, 0x61, 0x80, 0x60, 0x80, 0x60, 0xC0, 0xF1, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"K",43*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x60, 0x00, 0x60, 0x00, + 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, + 0x60, 0x00, 0x60, 0x20, 0x60, 0x20, 0x60, 0x40, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"L",44*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x61, 0xC0, 0x61, 0xC0, + 0x71, 0xC0, 0x71, 0xC0, 0x72, 0xC0, 0x72, 0xC0, 0x52, 0xC0, 0x5A, 0xC0, 0x5A, 0xC0, 0x5C, 0xC0, + 0x4C, 0xC0, 0x4C, 0xC0, 0x4C, 0xC0, 0x48, 0xC0, 0xE1, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"M",45*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xF0, 0x30, 0x40, 0x38, 0x40, + 0x38, 0x40, 0x2C, 0x40, 0x2C, 0x40, 0x26, 0x40, 0x26, 0x40, 0x22, 0x40, 0x23, 0x40, 0x21, 0x40, + 0x21, 0xC0, 0x21, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0xF8, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"N",46*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x19, 0x80, 0x30, 0xC0, + 0x30, 0x40, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x60, 0x60, 0x30, 0x40, 0x30, 0xC0, 0x19, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"O",47*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x60, 0xC0, 0x60, 0x60, + 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x61, 0xC0, 0x7F, 0x00, 0x60, 0x00, 0x60, 0x00, + 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"P",48*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x19, 0x80, 0x30, 0xC0, + 0x30, 0x40, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x6E, 0x60, 0x32, 0x40, 0x33, 0xC0, 0x19, 0x80, 0x0F, 0x00, 0x01, 0xE0, 0x00, 0xC0, 0x00, 0x00, /*"Q",49*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x60, 0xC0, 0x60, 0x60, + 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xC0, 0x7F, 0x00, 0x62, 0x00, 0x63, 0x00, 0x61, 0x00, + 0x61, 0x80, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0x60, 0xF0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"R",50*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x40, 0x30, 0xC0, 0x60, 0x40, + 0x60, 0x40, 0x60, 0x00, 0x70, 0x00, 0x3C, 0x00, 0x1F, 0x00, 0x07, 0xC0, 0x01, 0xC0, 0x00, 0xE0, + 0x40, 0x60, 0x40, 0x60, 0x60, 0x60, 0x30, 0xC0, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"S",51*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x46, 0x20, 0x86, 0x10, + 0x86, 0x10, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"T",52*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xE0, 0x30, 0x40, 0x30, 0x40, + 0x30, 0x40, 0x30, 0x40, 0x30, 0x40, 0x30, 0x40, 0x30, 0x40, 0x30, 0x40, 0x30, 0x40, 0x30, 0x40, + 0x30, 0x40, 0x30, 0x40, 0x30, 0x40, 0x18, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"U",53*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xE0, 0x60, 0x40, 0x20, 0x80, + 0x20, 0x80, 0x30, 0x80, 0x30, 0x80, 0x11, 0x00, 0x11, 0x00, 0x19, 0x00, 0x19, 0x00, 0x0A, 0x00, + 0x0A, 0x00, 0x0E, 0x00, 0x0C, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"V",54*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0x70, 0x46, 0x20, 0x42, 0x20, + 0x62, 0x20, 0x62, 0x20, 0x26, 0x40, 0x26, 0x40, 0x27, 0x40, 0x27, 0x40, 0x39, 0x40, 0x39, 0x80, + 0x19, 0x80, 0x19, 0x80, 0x11, 0x80, 0x11, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"W",55*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xE0, 0x30, 0x80, 0x10, 0x80, + 0x18, 0x80, 0x09, 0x00, 0x0D, 0x00, 0x06, 0x00, 0x04, 0x00, 0x06, 0x00, 0x06, 0x00, 0x0B, 0x00, + 0x09, 0x00, 0x11, 0x80, 0x10, 0x80, 0x20, 0xC0, 0x71, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"X",56*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x60, 0x20, 0x20, 0x40, + 0x30, 0x40, 0x10, 0x80, 0x18, 0x80, 0x1D, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Y",57*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xE0, 0x30, 0x40, 0x60, 0xC0, + 0x40, 0x80, 0x01, 0x80, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, + 0x18, 0x00, 0x10, 0x20, 0x30, 0x20, 0x20, 0x40, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Z",58*/ + + 0x00, 0x00, 0x00, 0x00, 0x07, 0xC0, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x07, 0xC0, 0x00, 0x00, /*"[",59*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, /*"\",60*/ + + 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x3E, 0x00, 0x00, 0x00, /*"]",61*/ + + 0x00, 0x00, 0x06, 0x00, 0x09, 0x00, 0x10, 0x80, 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, /*"^",62*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF0, /*"_",63*/ + + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x06, 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, 0x00, /*"`",64*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x30, 0xC0, 0x30, 0xC0, 0x00, 0xC0, 0x07, 0xC0, 0x38, 0xC0, + 0x70, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x71, 0xD0, 0x3E, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"a",65*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70, 0x00, 0x30, 0x00, 0x30, 0x00, + 0x30, 0x00, 0x30, 0x00, 0x33, 0x80, 0x3C, 0xC0, 0x38, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, + 0x30, 0x60, 0x30, 0x60, 0x30, 0x40, 0x38, 0xC0, 0x27, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"b",66*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x31, 0x80, 0x31, 0x80, 0x61, 0x80, 0x60, 0x00, 0x60, 0x00, + 0x60, 0x00, 0x60, 0x40, 0x30, 0x40, 0x30, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"c",67*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x03, 0xC0, 0x00, 0xC0, 0x00, 0xC0, + 0x00, 0xC0, 0x00, 0xC0, 0x1E, 0xC0, 0x31, 0xC0, 0x30, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, + 0x60, 0xC0, 0x60, 0xC0, 0x20, 0xC0, 0x31, 0xE0, 0x1E, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"d",68*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x18, 0xC0, 0x10, 0x40, 0x30, 0x60, 0x30, 0x60, 0x3F, 0xE0, + 0x30, 0x00, 0x30, 0x00, 0x18, 0x20, 0x18, 0x40, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"e",69*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x06, 0x60, 0x0C, 0x60, + 0x0C, 0x00, 0x0C, 0x00, 0x7F, 0x80, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, + 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"f",70*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x1B, 0x60, 0x31, 0x80, 0x31, 0x80, 0x31, 0x80, 0x19, 0x80, + 0x1F, 0x00, 0x30, 0x00, 0x3F, 0x00, 0x33, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x71, 0xC0, 0x1F, 0x00, /*"g",71*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70, 0x00, 0x30, 0x00, 0x30, 0x00, + 0x30, 0x00, 0x30, 0x00, 0x37, 0x80, 0x38, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x30, 0xC0, + 0x30, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"h",72*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x3E, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"i",73*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x0F, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x33, 0x00, 0x3E, 0x00, /*"j",74*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70, 0x00, 0x30, 0x00, 0x30, 0x00, + 0x30, 0x00, 0x30, 0x00, 0x31, 0xC0, 0x31, 0x00, 0x31, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, + 0x31, 0x00, 0x31, 0x80, 0x30, 0x80, 0x30, 0xC0, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"k",75*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3E, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"l",76*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xEC, 0xE0, 0x77, 0x60, 0x66, 0x60, 0x66, 0x60, 0x66, 0x60, 0x66, 0x60, + 0x66, 0x60, 0x66, 0x60, 0x66, 0x60, 0x66, 0x60, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"m",77*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, 0x38, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x30, 0xC0, + 0x30, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"n",78*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x19, 0x80, 0x30, 0xC0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x60, 0x60, 0x60, 0x60, 0x30, 0xC0, 0x30, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"o",79*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, 0x38, 0xC0, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, + 0x30, 0x60, 0x30, 0x60, 0x30, 0xC0, 0x38, 0xC0, 0x37, 0x80, 0x30, 0x00, 0x30, 0x00, 0x7C, 0x00, /*"p",80*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1E, 0x40, 0x31, 0xC0, 0x30, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, + 0x60, 0xC0, 0x60, 0xC0, 0x20, 0xC0, 0x31, 0xC0, 0x1E, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x03, 0xE0, /*"q",81*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF9, 0xC0, 0x1A, 0x60, 0x1C, 0x60, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, + 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"r",82*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xC0, 0x38, 0xC0, 0x30, 0x40, 0x30, 0x40, 0x1C, 0x00, 0x0F, 0x00, + 0x03, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x31, 0xC0, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"s",83*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x0C, 0x00, 0x0C, 0x00, 0x7F, 0x80, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, + 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x40, 0x0C, 0x40, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"t",84*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x40, 0x71, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x30, 0xC0, + 0x30, 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x39, 0xE0, 0x1E, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"u",85*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x78, 0xE0, 0x30, 0x40, 0x10, 0x80, 0x10, 0x80, 0x18, 0x80, 0x09, 0x00, + 0x0D, 0x00, 0x0D, 0x00, 0x06, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"v",86*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xEF, 0x70, 0x46, 0x20, 0x62, 0x20, 0x26, 0x40, 0x26, 0x40, 0x37, 0x40, + 0x39, 0x80, 0x19, 0x80, 0x19, 0x80, 0x19, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"w",87*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3D, 0xE0, 0x18, 0x80, 0x08, 0x80, 0x0D, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x07, 0x00, 0x09, 0x00, 0x10, 0x80, 0x10, 0xC0, 0x79, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"x",88*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x79, 0xE0, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x09, 0x00, 0x09, 0x00, + 0x0D, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x04, 0x00, 0x04, 0x00, 0x24, 0x00, 0x38, 0x00, /*"y",89*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x21, 0x80, 0x23, 0x00, 0x22, 0x00, 0x06, 0x00, 0x04, 0x00, + 0x0C, 0x00, 0x18, 0x40, 0x10, 0x40, 0x30, 0xC0, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"z",90*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00, /*"{",91*/ + + 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, /*"|",92*/ + + 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x30, 0x00, 0x00, 0x00, /*"}",93*/ + + 0x00, 0x00, 0x38, 0x00, 0x44, 0x20, 0x43, 0x20, 0x01, 0xC0, 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, /*"~",94*/ +}; + +const esp_painter_basic_font_t esp_painter_basic_font_24 = { + .bitmap = bitmap, + .width = 12, + .height = 24, +}; + +#endif diff --git a/components/lua_modules/esp_painter/font/basic_font_28.c b/components/lua_modules/esp_painter/font/basic_font_28.c new file mode 100644 index 0000000..d20996b --- /dev/null +++ b/components/lua_modules/esp_painter/font/basic_font_28.c @@ -0,0 +1,497 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "sdkconfig.h" + +#include "esp_painter_font.h" + +#if CONFIG_ESP_PAINTER_BASIC_FONT_28 + +static const uint8_t bitmap[] = +{ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*" ",0*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, + 0x07, 0x00, 0x07, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"!",1*/ + + 0x00, 0x00, 0x00, 0x00, 0x06, 0x60, 0x0E, 0xE0, 0x0C, 0xC0, 0x19, 0x80, 0x19, 0x80, 0x33, 0x00, + 0x22, 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, /*""",2*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x08, 0x20, 0x08, 0x20, + 0x08, 0x20, 0x7F, 0xF8, 0x7F, 0xF8, 0x08, 0x20, 0x08, 0x20, 0x08, 0x20, 0x10, 0x40, 0x10, 0x40, + 0x10, 0x40, 0x7F, 0xF8, 0x7F, 0xF8, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, 0x10, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"#",3*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x07, 0xC0, 0x0D, 0x60, 0x19, 0x30, + 0x19, 0x30, 0x19, 0x70, 0x19, 0x00, 0x0D, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x01, 0xC0, 0x01, 0xE0, + 0x01, 0x60, 0x01, 0x30, 0x31, 0x30, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30, 0x19, 0x60, 0x07, 0x80, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, /*"$",4*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x20, 0x48, 0x20, 0x84, 0x40, + 0x84, 0x40, 0x84, 0x80, 0x84, 0x80, 0x85, 0x00, 0x85, 0x00, 0x4A, 0x00, 0x3A, 0x60, 0x02, 0x90, + 0x05, 0x08, 0x05, 0x08, 0x09, 0x08, 0x09, 0x08, 0x11, 0x08, 0x11, 0x08, 0x20, 0x90, 0x20, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"%",5*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x19, 0x80, 0x31, 0x80, + 0x31, 0x80, 0x31, 0x80, 0x31, 0x80, 0x33, 0x00, 0x3E, 0x00, 0x18, 0xF8, 0x38, 0x20, 0x4C, 0x20, + 0x4C, 0x20, 0xC6, 0x20, 0xC6, 0x40, 0xC3, 0x40, 0xC3, 0x80, 0x61, 0x84, 0x71, 0xCC, 0x3E, 0x38, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"&",6*/ + + 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x38, 0x00, 0x38, 0x00, 0x18, 0x00, 0x18, 0x00, 0x10, 0x00, + 0x20, 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, /*"'",7*/ + + 0x00, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, + 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /*"(",8*/ + + 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, + 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, /*")",9*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, + 0x03, 0x80, 0x01, 0x80, 0x61, 0x0C, 0x79, 0x3C, 0x1D, 0x70, 0x03, 0x80, 0x03, 0x80, 0x1D, 0x70, + 0x79, 0x3C, 0x61, 0x0C, 0x03, 0x00, 0x03, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"*",10*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x3F, 0xF8, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"+",11*/ + + 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, 0x30, 0x00, 0x38, 0x00, 0x38, 0x00, 0x18, 0x00, + 0x18, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, /*",",12*/ + + 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, 0x7F, 0xF8, 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, /*"-",13*/ + + 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, 0x00, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*".",14*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x18, 0x00, 0x10, 0x00, 0x30, 0x00, 0x20, 0x00, 0x60, + 0x00, 0x40, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x08, 0x00, 0x18, 0x00, 0x10, 0x00, 0x30, 0x00, 0x20, 0x00, + 0x60, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, /*"/",15*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0C, 0x60, 0x18, 0x20, + 0x30, 0x30, 0x30, 0x30, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, + 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x30, 0x30, 0x30, 0x30, 0x18, 0x20, 0x0C, 0x40, 0x07, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"0",16*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x1F, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x1F, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"1",17*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x30, 0xE0, 0x40, 0x70, + 0x40, 0x30, 0x60, 0x30, 0x60, 0x30, 0x00, 0x30, 0x00, 0x60, 0x00, 0x60, 0x00, 0xC0, 0x01, 0x80, + 0x03, 0x00, 0x06, 0x00, 0x0C, 0x00, 0x18, 0x10, 0x30, 0x10, 0x60, 0x30, 0x7F, 0xF0, 0x7F, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"2",18*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x10, 0xC0, 0x30, 0x60, + 0x30, 0x60, 0x30, 0x60, 0x00, 0x60, 0x00, 0x40, 0x00, 0xC0, 0x03, 0x80, 0x00, 0xC0, 0x00, 0x60, + 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x60, 0x10, 0xC0, 0x0F, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"3",19*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0, + 0x03, 0xC0, 0x02, 0xC0, 0x04, 0xC0, 0x04, 0xC0, 0x08, 0xC0, 0x10, 0xC0, 0x10, 0xC0, 0x20, 0xC0, + 0x40, 0xC0, 0x7F, 0xF8, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x07, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"4",20*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF0, 0x1F, 0xF0, 0x10, 0x00, + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x17, 0xC0, 0x18, 0x60, 0x10, 0x60, 0x00, 0x30, + 0x00, 0x30, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x60, 0x10, 0xE0, 0x0F, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"5",21*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x0C, 0x30, 0x18, 0x30, + 0x30, 0x30, 0x30, 0x00, 0x20, 0x00, 0x60, 0x00, 0x67, 0xC0, 0x68, 0x70, 0x70, 0x30, 0x60, 0x18, + 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x20, 0x18, 0x30, 0x18, 0x30, 0x30, 0x1C, 0x60, 0x07, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"6",22*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF0, 0x1F, 0xF0, 0x30, 0x20, + 0x20, 0x20, 0x20, 0x40, 0x00, 0x40, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"7",23*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x30, 0x60, 0x30, 0x70, + 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x30, 0x20, 0x38, 0x60, 0x0F, 0x80, 0x0B, 0x80, 0x31, 0xC0, + 0x30, 0x60, 0x60, 0x70, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x30, 0x60, 0x18, 0x60, 0x0F, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"8",24*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x18, 0xC0, 0x30, 0x60, + 0x60, 0x20, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x70, 0x30, 0x70, 0x38, 0xB0, + 0x1F, 0x30, 0x00, 0x30, 0x00, 0x60, 0x00, 0x60, 0x30, 0x60, 0x30, 0xC0, 0x31, 0x80, 0x1F, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"9",25*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*":",26*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x03, 0x80, + 0x00, 0x80, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, /*";",27*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, + 0x00, 0x80, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, + 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"<",28*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"=",29*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, + 0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x20, + 0x00, 0x40, 0x00, 0x80, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*">",30*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x10, 0xE0, 0x20, 0x60, + 0x40, 0x30, 0x40, 0x30, 0x70, 0x30, 0x70, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x01, 0x80, 0x03, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"?",31*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xC0, 0x0C, 0x60, 0x18, 0x10, + 0x31, 0xB0, 0x33, 0x68, 0x22, 0x68, 0x66, 0x68, 0x66, 0x48, 0x6C, 0x48, 0x6C, 0x48, 0x6C, 0x48, + 0x6C, 0x48, 0x6C, 0xD0, 0x6D, 0x50, 0x36, 0x60, 0x30, 0x08, 0x18, 0x10, 0x0C, 0x20, 0x07, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"@",32*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, 0x00, 0x07, 0x00, + 0x05, 0x00, 0x05, 0x00, 0x09, 0x80, 0x09, 0x80, 0x08, 0x80, 0x08, 0x80, 0x10, 0xC0, 0x10, 0xC0, + 0x1F, 0xC0, 0x10, 0x40, 0x20, 0x60, 0x20, 0x60, 0x20, 0x60, 0x20, 0x20, 0x60, 0x30, 0xF0, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"A",33*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x30, 0x60, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x60, 0x30, 0xC0, 0x3F, 0x80, 0x30, 0x60, 0x30, 0x30, + 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x30, 0x30, 0x70, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"B",34*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xC0, 0x0C, 0x30, 0x18, 0x18, + 0x30, 0x08, 0x30, 0x08, 0x20, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, + 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x30, 0x08, 0x30, 0x08, 0x18, 0x10, 0x1C, 0x20, 0x07, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"C",35*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x30, 0xC0, 0x30, 0x60, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, + 0x30, 0x18, 0x30, 0x18, 0x30, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x60, 0x30, 0xC0, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"D",36*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x30, 0x30, 0x30, 0x18, + 0x30, 0x08, 0x30, 0x00, 0x30, 0x40, 0x30, 0x40, 0x30, 0xC0, 0x3F, 0xC0, 0x30, 0xC0, 0x30, 0x40, + 0x30, 0x40, 0x30, 0x00, 0x30, 0x00, 0x30, 0x08, 0x30, 0x08, 0x30, 0x10, 0x30, 0x30, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"E",37*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x30, 0x30, 0x30, 0x10, + 0x30, 0x08, 0x30, 0x08, 0x30, 0x40, 0x30, 0x40, 0x30, 0x40, 0x3F, 0xC0, 0x30, 0xC0, 0x30, 0x40, + 0x30, 0x40, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"F",38*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0C, 0x60, 0x18, 0x30, + 0x30, 0x10, 0x30, 0x10, 0x20, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, + 0x60, 0xFC, 0x60, 0x30, 0x60, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x30, 0x0C, 0x70, 0x07, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"G",39*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3F, 0xF0, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xFC, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"H",40*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x3F, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"I",41*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0xC0, 0x00, 0xC0, + 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, + 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, + 0x60, 0xC0, 0x61, 0x80, 0x63, 0x80, 0x3E, 0x00, /*"J",42*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xF0, 0x30, 0x40, 0x30, 0x80, + 0x30, 0x80, 0x31, 0x00, 0x32, 0x00, 0x32, 0x00, 0x36, 0x00, 0x36, 0x00, 0x3B, 0x00, 0x33, 0x00, + 0x31, 0x80, 0x31, 0x80, 0x30, 0xC0, 0x30, 0xC0, 0x30, 0x60, 0x30, 0x60, 0x30, 0x70, 0xFC, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"K",43*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x18, 0x00, 0x18, 0x00, + 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, + 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x08, 0x18, 0x08, 0x18, 0x18, 0x18, 0x30, 0x7F, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"L",44*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x38, 0x30, 0x70, 0x30, 0x70, + 0x38, 0x70, 0x38, 0x70, 0x38, 0x70, 0x28, 0xB0, 0x28, 0xB0, 0x2C, 0xB0, 0x2C, 0xB0, 0x2D, 0x30, + 0x25, 0x30, 0x25, 0x30, 0x27, 0x30, 0x27, 0x30, 0x26, 0x30, 0x22, 0x30, 0x22, 0x30, 0x72, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"M",45*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7C, 0x38, 0x10, 0x38, 0x10, + 0x3C, 0x10, 0x2C, 0x10, 0x2E, 0x10, 0x26, 0x10, 0x26, 0x10, 0x23, 0x10, 0x23, 0x10, 0x21, 0x90, + 0x21, 0x90, 0x20, 0xD0, 0x20, 0xD0, 0x20, 0x70, 0x20, 0x70, 0x20, 0x30, 0x20, 0x30, 0xF8, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"N",46*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x08, 0x40, 0x10, 0x20, + 0x30, 0x30, 0x30, 0x30, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, + 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x30, 0x10, 0x30, 0x30, 0x10, 0x20, 0x08, 0x40, 0x07, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"O",47*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x30, 0x70, 0x30, 0x30, + 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x30, 0x30, 0x70, 0x3F, 0xC0, 0x30, 0x00, + 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"P",48*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x18, 0x60, 0x10, 0x20, + 0x30, 0x30, 0x30, 0x10, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, + 0x60, 0x18, 0x60, 0x18, 0x67, 0x18, 0x29, 0x10, 0x31, 0xB0, 0x18, 0xA0, 0x18, 0xE0, 0x07, 0xC0, + 0x00, 0x78, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, /*"Q",49*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC0, 0x18, 0x60, 0x18, 0x30, + 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x60, 0x18, 0x60, 0x1F, 0xC0, 0x19, 0x80, + 0x18, 0x80, 0x18, 0xC0, 0x18, 0xC0, 0x18, 0x40, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x7E, 0x38, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"R",50*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x20, 0x30, 0xE0, 0x20, 0x60, + 0x60, 0x20, 0x60, 0x20, 0x60, 0x00, 0x70, 0x00, 0x3C, 0x00, 0x1F, 0x00, 0x07, 0xC0, 0x01, 0xE0, + 0x00, 0x60, 0x00, 0x70, 0x40, 0x30, 0x40, 0x30, 0x60, 0x30, 0x20, 0x60, 0x38, 0x60, 0x07, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"S",51*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x23, 0x10, 0x63, 0x08, + 0x43, 0x08, 0x43, 0x08, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x0F, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"T",52*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x7C, 0x30, 0x10, 0x30, 0x10, + 0x30, 0x10, 0x30, 0x10, 0x30, 0x10, 0x30, 0x10, 0x30, 0x10, 0x30, 0x10, 0x30, 0x10, 0x30, 0x10, + 0x30, 0x10, 0x30, 0x10, 0x30, 0x10, 0x30, 0x10, 0x30, 0x10, 0x30, 0x30, 0x18, 0x60, 0x07, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"U",53*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x78, 0x70, 0x30, 0x30, 0x20, + 0x30, 0x20, 0x30, 0x20, 0x10, 0x40, 0x18, 0x40, 0x18, 0x40, 0x18, 0x40, 0x08, 0x80, 0x0C, 0x80, + 0x0C, 0x80, 0x0D, 0x00, 0x05, 0x00, 0x07, 0x00, 0x07, 0x00, 0x06, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"V",54*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF7, 0x9C, 0x63, 0x08, 0x63, 0x08, + 0x61, 0x10, 0x21, 0x10, 0x23, 0x10, 0x23, 0x90, 0x33, 0x90, 0x33, 0x90, 0x33, 0xA0, 0x34, 0xA0, + 0x14, 0xA0, 0x14, 0xA0, 0x14, 0xE0, 0x18, 0xC0, 0x18, 0xC0, 0x18, 0x40, 0x08, 0x40, 0x08, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"W",55*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x78, 0x18, 0x20, 0x18, 0x20, + 0x08, 0x40, 0x0C, 0x40, 0x04, 0x80, 0x06, 0x80, 0x07, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x05, 0x80, 0x04, 0x80, 0x08, 0xC0, 0x08, 0xC0, 0x08, 0x60, 0x10, 0x60, 0x10, 0x30, 0x78, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"X",56*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x78, 0x30, 0x30, 0x18, 0x20, + 0x18, 0x20, 0x18, 0x40, 0x0C, 0x40, 0x0C, 0x40, 0x04, 0x80, 0x06, 0x80, 0x07, 0x80, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x0F, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Y",57*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x18, 0x10, 0x30, 0x30, + 0x20, 0x60, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x80, 0x01, 0x80, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, + 0x06, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x18, 0x08, 0x18, 0x08, 0x30, 0x10, 0x20, 0x30, 0x7F, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Z",58*/ + + 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, /*"[",59*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x30, 0x00, 0x10, 0x00, 0x18, 0x00, + 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, + 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, /*"\",60*/ + + 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, /*"]",61*/ + + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x08, 0x80, 0x10, 0x40, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"^",62*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, /*"_",63*/ + + 0x00, 0x00, 0x3C, 0x00, 0x06, 0x00, 0x01, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"`",64*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x10, 0xE0, 0x30, 0x60, 0x30, 0x60, 0x00, 0x60, + 0x07, 0xE0, 0x18, 0x60, 0x30, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x68, 0x31, 0xE8, 0x1E, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"a",65*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xF0, 0x00, 0x30, 0x00, 0x30, 0x00, + 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0xC0, 0x34, 0x60, 0x38, 0x60, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x60, 0x38, 0x60, 0x27, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"b",66*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0C, 0x60, 0x18, 0x60, 0x18, 0x60, 0x30, 0x00, + 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x10, 0x18, 0x20, 0x0C, 0x20, 0x07, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"c",67*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xF0, 0x00, 0x30, 0x00, 0x30, + 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x07, 0xB0, 0x0C, 0x70, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x70, 0x18, 0xFC, 0x07, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"d",68*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0C, 0x60, 0x18, 0x60, 0x10, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x3F, 0xF0, 0x30, 0x00, 0x30, 0x00, 0x30, 0x10, 0x18, 0x10, 0x0C, 0x20, 0x07, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"e",69*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF0, 0x03, 0x18, 0x06, 0x18, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x3F, 0xE0, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x3F, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"f",70*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xB8, 0x0C, 0xD8, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, + 0x18, 0x60, 0x0C, 0xC0, 0x0F, 0x80, 0x18, 0x00, 0x18, 0x00, 0x0F, 0xC0, 0x19, 0xF0, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x18, 0x60, 0x0F, 0xC0, /*"g",71*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xF0, 0x00, 0x30, 0x00, 0x30, 0x00, + 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0xE0, 0x34, 0x70, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xFC, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"h",72*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x07, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1F, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x1F, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"i",73*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x03, 0xE0, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, + 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, + 0x00, 0x60, 0x30, 0x40, 0x30, 0xC0, 0x1F, 0x00, /*"j",74*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x78, 0x00, 0x18, 0x00, 0x18, 0x00, + 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0xF0, 0x18, 0x40, 0x18, 0x80, 0x18, 0x80, 0x19, 0x00, + 0x1B, 0x00, 0x1D, 0x80, 0x1C, 0x80, 0x18, 0xC0, 0x18, 0x60, 0x18, 0x60, 0x18, 0x30, 0x7E, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"k",75*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1F, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x3F, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"l",76*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x70, 0x73, 0x98, 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, + 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, 0xF7, 0xBC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"m",77*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xC0, 0xF4, 0x60, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xFC, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"n",78*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x18, 0x60, 0x30, 0x30, 0x30, 0x30, 0x60, 0x18, + 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x20, 0x10, 0x30, 0x30, 0x18, 0x60, 0x07, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"o",79*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xC0, 0xF4, 0x70, 0x38, 0x30, 0x30, 0x18, 0x30, 0x18, + 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x30, 0x38, 0x60, 0x37, 0xC0, + 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0xFC, 0x00, /*"p",80*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x20, 0x18, 0xE0, 0x30, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x30, 0x60, 0x30, 0xE0, 0x0F, 0x60, + 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x01, 0xF8, /*"q",81*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x70, 0x7C, 0x98, 0x0D, 0x18, 0x0E, 0x00, 0x0C, 0x00, + 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x7F, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"r",82*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x90, 0x18, 0x70, 0x30, 0x30, 0x30, 0x10, 0x38, 0x00, + 0x1E, 0x00, 0x07, 0xC0, 0x01, 0xE0, 0x20, 0x70, 0x20, 0x30, 0x30, 0x30, 0x38, 0x60, 0x27, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"s",83*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x3F, 0xE0, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x10, 0x06, 0x10, 0x03, 0x20, 0x03, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"t",84*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0xF1, 0xE0, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, + 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x38, 0xF8, 0x1F, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"u",85*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x78, 0x10, 0x30, 0x18, 0x20, 0x18, 0x20, 0x08, 0x40, + 0x0C, 0x40, 0x0C, 0x40, 0x04, 0x80, 0x06, 0x80, 0x06, 0x80, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"v",86*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF7, 0xBC, 0x63, 0x08, 0x23, 0x10, 0x23, 0x10, 0x33, 0x10, + 0x33, 0x90, 0x37, 0xA0, 0x14, 0xA0, 0x1C, 0xA0, 0x1C, 0xC0, 0x18, 0xC0, 0x08, 0x40, 0x08, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"w",87*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0xF8, 0x0C, 0x20, 0x0C, 0x40, 0x06, 0x40, 0x06, 0x80, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x80, 0x04, 0xC0, 0x08, 0xC0, 0x08, 0x60, 0x10, 0x30, 0x78, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"x",88*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xF8, 0x10, 0x20, 0x18, 0x20, 0x18, 0x40, 0x08, 0x40, + 0x0C, 0x40, 0x0C, 0x80, 0x04, 0x80, 0x06, 0x80, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x34, 0x00, 0x38, 0x00, /*"y",89*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xE0, 0x30, 0x60, 0x20, 0xC0, 0x21, 0x80, 0x01, 0x80, + 0x03, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0C, 0x10, 0x08, 0x10, 0x18, 0x10, 0x30, 0x20, 0x3F, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"z",90*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x40, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, + 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, + 0x00, 0x40, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, /*"{",91*/ + + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, /*"|",92*/ + + 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, /*"}",93*/ + + 0x1C, 0x00, 0x26, 0x08, 0x43, 0x08, 0x41, 0x90, 0x00, 0xE0, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"~",94*/ +}; + +const esp_painter_basic_font_t esp_painter_basic_font_28 = { + .bitmap = bitmap, + .width = 14, + .height = 28, +}; + +#endif diff --git a/components/lua_modules/esp_painter/font/basic_font_32.c b/components/lua_modules/esp_painter/font/basic_font_32.c new file mode 100644 index 0000000..ab6959e --- /dev/null +++ b/components/lua_modules/esp_painter/font/basic_font_32.c @@ -0,0 +1,497 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "sdkconfig.h" + +#include "esp_painter_font.h" + +#if CONFIG_ESP_PAINTER_BASIC_FONT_32 + +static const uint8_t bitmap[] = +{ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*" ",0*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x03, 0xC0, + 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x01, 0xC0, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x80, 0x03, 0xC0, 0x03, 0xC0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"!",1*/ + + 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x07, 0x38, 0x07, 0x38, 0x0E, 0x70, 0x0C, 0x60, 0x18, 0xC0, + 0x31, 0x80, 0x21, 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, 0x00, 0x00, 0x00, 0x00, 0x00, /*""",2*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x04, 0x08, + 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x08, 0x10, 0x08, 0x10, + 0x08, 0x10, 0x08, 0x10, 0x08, 0x10, 0x08, 0x10, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x18, 0x30, + 0x10, 0x20, 0x10, 0x20, 0x10, 0x20, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"#",3*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0xC0, 0x0D, 0x30, + 0x09, 0x18, 0x19, 0x18, 0x19, 0x38, 0x19, 0x38, 0x1D, 0x00, 0x0D, 0x00, 0x0F, 0x00, 0x07, 0x00, + 0x03, 0xC0, 0x01, 0xE0, 0x01, 0xF0, 0x01, 0x30, 0x01, 0x38, 0x01, 0x18, 0x39, 0x18, 0x39, 0x18, + 0x31, 0x18, 0x31, 0x30, 0x19, 0x60, 0x07, 0xC0, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, /*"$",4*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x10, 0x6C, 0x10, + 0x44, 0x20, 0xC6, 0x20, 0xC6, 0x40, 0xC6, 0x40, 0xC6, 0x40, 0xC6, 0x80, 0xC6, 0x80, 0x44, 0x80, + 0x6D, 0x38, 0x39, 0x6C, 0x02, 0x44, 0x02, 0xC6, 0x02, 0xC6, 0x04, 0xC6, 0x04, 0xC6, 0x08, 0xC6, + 0x08, 0xC6, 0x08, 0x44, 0x10, 0x6C, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"%",5*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x19, 0x00, + 0x31, 0x80, 0x31, 0x80, 0x31, 0x80, 0x31, 0x80, 0x31, 0x00, 0x33, 0x00, 0x3A, 0x00, 0x1C, 0x00, + 0x38, 0x7C, 0x3C, 0x10, 0x4C, 0x10, 0xCE, 0x10, 0xC6, 0x20, 0xC7, 0x20, 0xC3, 0x20, 0xC1, 0xC0, + 0xC1, 0xC2, 0x60, 0xE6, 0x31, 0x7C, 0x1E, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"&",6*/ + + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x08, 0x00, + 0x30, 0x00, 0x60, 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, 0x00, 0x00, 0x00, 0x00, 0x00, /*"'",7*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x18, 0x00, 0x30, 0x00, 0x20, + 0x00, 0x60, 0x00, 0x40, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x40, + 0x00, 0x60, 0x00, 0x20, 0x00, 0x30, 0x00, 0x18, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, /*"(",8*/ + + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x18, 0x00, 0x0C, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x06, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, /*")",9*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xC0, 0x01, 0xC0, 0x01, 0xC0, 0x30, 0xC6, 0x38, 0x8E, 0x1C, 0x9C, 0x06, 0xB0, 0x01, 0xC0, + 0x01, 0xC0, 0x06, 0xB0, 0x1C, 0x9C, 0x38, 0x8E, 0x31, 0x86, 0x01, 0xC0, 0x01, 0xC0, 0x01, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"*",10*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, + 0x3F, 0xFE, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"+",11*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x08, 0x00, 0x30, 0x00, 0x60, 0x00, /*",",12*/ + + 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, + 0x7F, 0xFE, 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, /*"-",13*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*".",14*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x08, + 0x00, 0x18, 0x00, 0x10, 0x00, 0x30, 0x00, 0x20, 0x00, 0x60, 0x00, 0x40, 0x00, 0xC0, 0x00, 0x80, + 0x01, 0x80, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x06, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x08, 0x00, + 0x18, 0x00, 0x10, 0x00, 0x30, 0x00, 0x20, 0x00, 0x60, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, /*"/",15*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x06, 0x20, + 0x0C, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x08, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, + 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x18, 0x08, 0x18, 0x18, + 0x18, 0x18, 0x0C, 0x30, 0x06, 0x20, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"0",16*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x80, + 0x1F, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x03, 0xC0, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"1",17*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x08, 0x38, + 0x10, 0x18, 0x20, 0x0C, 0x20, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x18, + 0x00, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x02, 0x00, 0x04, 0x04, 0x08, 0x04, + 0x10, 0x04, 0x20, 0x0C, 0x3F, 0xF8, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"2",18*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xC0, 0x18, 0x60, + 0x30, 0x30, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x30, 0x00, 0x60, + 0x03, 0xC0, 0x00, 0x70, 0x00, 0x18, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x0C, 0x30, 0x0C, 0x30, 0x0C, + 0x30, 0x08, 0x30, 0x18, 0x18, 0x30, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"3",19*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, + 0x00, 0xE0, 0x00, 0xE0, 0x01, 0x60, 0x01, 0x60, 0x02, 0x60, 0x04, 0x60, 0x04, 0x60, 0x08, 0x60, + 0x08, 0x60, 0x10, 0x60, 0x30, 0x60, 0x20, 0x60, 0x40, 0x60, 0x7F, 0xFC, 0x00, 0x60, 0x00, 0x60, + 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x03, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"4",20*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x0F, 0xFC, + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x13, 0xE0, 0x14, 0x30, + 0x18, 0x18, 0x10, 0x08, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x30, 0x0C, 0x30, 0x0C, + 0x20, 0x18, 0x20, 0x18, 0x18, 0x30, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"5",21*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x06, 0x18, + 0x0C, 0x18, 0x08, 0x18, 0x18, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x33, 0xE0, 0x36, 0x30, + 0x38, 0x18, 0x38, 0x08, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x18, 0x0C, + 0x18, 0x08, 0x0C, 0x18, 0x0E, 0x30, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"6",22*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFC, 0x1F, 0xFC, + 0x10, 0x08, 0x30, 0x10, 0x20, 0x10, 0x20, 0x20, 0x00, 0x20, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, + 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"7",23*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x0C, 0x30, + 0x18, 0x18, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x38, 0x0C, 0x38, 0x08, 0x1E, 0x18, 0x0F, 0x20, + 0x07, 0xC0, 0x18, 0xF0, 0x30, 0x78, 0x30, 0x38, 0x60, 0x1C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, + 0x60, 0x0C, 0x30, 0x18, 0x18, 0x30, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"8",24*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xC0, 0x18, 0x20, + 0x30, 0x10, 0x30, 0x18, 0x60, 0x08, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, 0x60, 0x0C, + 0x70, 0x1C, 0x30, 0x2C, 0x18, 0x6C, 0x0F, 0x8C, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x18, 0x00, 0x10, + 0x30, 0x30, 0x30, 0x60, 0x30, 0xC0, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"9",25*/ + + 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, 0x80, 0x03, 0xC0, 0x03, 0xC0, + 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x80, 0x03, 0xC0, 0x03, 0xC0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*":",26*/ + + 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, 0x03, 0x80, 0x03, 0x80, + 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x01, 0x80, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, /*";",27*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, + 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, + 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, + 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"<",28*/ + + 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, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"=",29*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, + 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, + 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x01, 0x00, 0x02, 0x00, + 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*">",30*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x0C, 0x18, + 0x18, 0x0C, 0x10, 0x06, 0x30, 0x06, 0x38, 0x06, 0x38, 0x06, 0x38, 0x06, 0x00, 0x0C, 0x00, 0x18, + 0x00, 0x70, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x80, 0x03, 0xC0, 0x03, 0xC0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"?",31*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x06, 0x10, + 0x0C, 0x08, 0x18, 0x04, 0x30, 0xD4, 0x31, 0xB2, 0x21, 0x32, 0x63, 0x32, 0x63, 0x22, 0x66, 0x22, + 0x66, 0x22, 0x66, 0x22, 0x66, 0x62, 0x66, 0x64, 0x66, 0x64, 0x26, 0xE8, 0x33, 0x30, 0x30, 0x02, + 0x10, 0x04, 0x18, 0x0C, 0x0C, 0x18, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"@",32*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x03, 0x80, + 0x03, 0x80, 0x03, 0x80, 0x04, 0xC0, 0x04, 0xC0, 0x04, 0xC0, 0x04, 0xC0, 0x0C, 0x40, 0x08, 0x60, + 0x08, 0x60, 0x08, 0x60, 0x18, 0x20, 0x1F, 0xF0, 0x10, 0x30, 0x10, 0x30, 0x10, 0x30, 0x20, 0x18, + 0x20, 0x18, 0x20, 0x18, 0x60, 0x1C, 0xF8, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"A",33*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x18, 0x38, + 0x18, 0x18, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x18, 0x18, 0x30, + 0x1F, 0xE0, 0x18, 0x18, 0x18, 0x0C, 0x18, 0x04, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, + 0x18, 0x06, 0x18, 0x0C, 0x18, 0x18, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"B",34*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x06, 0x1C, + 0x08, 0x0C, 0x18, 0x06, 0x30, 0x02, 0x30, 0x02, 0x30, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, + 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x30, 0x02, 0x30, 0x02, + 0x10, 0x04, 0x18, 0x08, 0x0C, 0x10, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"C",35*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC0, 0x18, 0x70, + 0x18, 0x18, 0x18, 0x08, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, + 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x04, 0x18, 0x0C, 0x18, 0x0C, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x60, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"D",36*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFC, 0x18, 0x0C, + 0x18, 0x04, 0x18, 0x02, 0x18, 0x02, 0x18, 0x00, 0x18, 0x00, 0x18, 0x10, 0x18, 0x10, 0x18, 0x30, + 0x1F, 0xF0, 0x18, 0x30, 0x18, 0x10, 0x18, 0x10, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x02, + 0x18, 0x02, 0x18, 0x04, 0x18, 0x0C, 0x7F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"E",37*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFC, 0x18, 0x1C, + 0x18, 0x04, 0x18, 0x02, 0x18, 0x02, 0x18, 0x00, 0x18, 0x00, 0x18, 0x10, 0x18, 0x10, 0x18, 0x30, + 0x1F, 0xF0, 0x18, 0x30, 0x18, 0x10, 0x18, 0x10, 0x18, 0x10, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, + 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"F",38*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x0C, 0x30, + 0x08, 0x10, 0x18, 0x18, 0x30, 0x08, 0x30, 0x08, 0x20, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, + 0x60, 0x00, 0x60, 0x00, 0x60, 0x7E, 0x60, 0x18, 0x60, 0x18, 0x20, 0x18, 0x30, 0x18, 0x30, 0x18, + 0x10, 0x18, 0x18, 0x18, 0x0C, 0x20, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"G",39*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0x30, 0x0C, + 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, + 0x3F, 0xFC, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, + 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0xFC, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"H",40*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"I",41*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x60, + 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, + 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, + 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x70, 0x60, 0x70, 0xC0, 0x71, 0x80, 0x3F, 0x00, /*"J",42*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7C, 0x18, 0x30, + 0x18, 0x20, 0x18, 0x60, 0x18, 0x40, 0x18, 0x80, 0x18, 0x80, 0x19, 0x00, 0x19, 0x00, 0x1B, 0x00, + 0x1D, 0x80, 0x1D, 0x80, 0x18, 0xC0, 0x18, 0xC0, 0x18, 0x60, 0x18, 0x60, 0x18, 0x30, 0x18, 0x30, + 0x18, 0x30, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"K",43*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x18, 0x00, + 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, + 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x02, + 0x18, 0x02, 0x18, 0x04, 0x18, 0x0C, 0x7F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"L",44*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x38, 0x1C, + 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x1C, 0x38, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x4C, + 0x2C, 0x4C, 0x26, 0x4C, 0x26, 0x4C, 0x26, 0x4C, 0x26, 0x8C, 0x22, 0x8C, 0x23, 0x8C, 0x23, 0x8C, + 0x23, 0x0C, 0x23, 0x0C, 0x21, 0x0C, 0xF1, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"M",45*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x1F, 0x38, 0x04, + 0x38, 0x04, 0x2C, 0x04, 0x2C, 0x04, 0x26, 0x04, 0x26, 0x04, 0x23, 0x04, 0x23, 0x04, 0x21, 0x84, + 0x21, 0x84, 0x20, 0xC4, 0x20, 0xC4, 0x20, 0x64, 0x20, 0x64, 0x20, 0x34, 0x20, 0x34, 0x20, 0x1C, + 0x20, 0x1C, 0x20, 0x0C, 0x20, 0x0C, 0xF8, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"N",46*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x0C, 0x30, + 0x18, 0x18, 0x10, 0x08, 0x30, 0x0C, 0x30, 0x0C, 0x60, 0x04, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, + 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x20, 0x06, 0x30, 0x0C, 0x30, 0x0C, + 0x10, 0x08, 0x18, 0x18, 0x0C, 0x30, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"O",47*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF0, 0x18, 0x18, + 0x18, 0x0C, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x06, 0x18, 0x0C, + 0x18, 0x18, 0x1F, 0xE0, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, + 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"P",48*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x0C, 0x30, + 0x18, 0x18, 0x10, 0x08, 0x30, 0x0C, 0x30, 0x0C, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, + 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x27, 0x84, 0x38, 0xCC, + 0x38, 0x6C, 0x18, 0x78, 0x0C, 0x70, 0x03, 0xE0, 0x00, 0x32, 0x00, 0x3C, 0x00, 0x1C, 0x00, 0x00, /*"Q",49*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x18, 0x38, + 0x18, 0x18, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x18, 0x18, 0x30, + 0x1F, 0xE0, 0x18, 0xC0, 0x18, 0xC0, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x30, 0x18, 0x30, + 0x18, 0x30, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"R",50*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xC8, 0x18, 0x78, + 0x30, 0x18, 0x60, 0x18, 0x60, 0x08, 0x60, 0x08, 0x60, 0x00, 0x70, 0x00, 0x3C, 0x00, 0x1F, 0x00, + 0x07, 0xC0, 0x01, 0xF0, 0x00, 0x78, 0x00, 0x18, 0x00, 0x1C, 0x40, 0x0C, 0x40, 0x0C, 0x60, 0x0C, + 0x20, 0x0C, 0x30, 0x18, 0x38, 0x30, 0x27, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"S",51*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFC, 0x31, 0x84, + 0x21, 0x86, 0x41, 0x82, 0x41, 0x82, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"T",52*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x3E, 0x30, 0x08, + 0x30, 0x08, 0x30, 0x08, 0x30, 0x08, 0x30, 0x08, 0x30, 0x08, 0x30, 0x08, 0x30, 0x08, 0x30, 0x08, + 0x30, 0x08, 0x30, 0x08, 0x30, 0x08, 0x30, 0x08, 0x30, 0x08, 0x30, 0x08, 0x30, 0x08, 0x30, 0x08, + 0x30, 0x08, 0x18, 0x10, 0x1C, 0x20, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"U",53*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x1E, 0x18, 0x0C, + 0x18, 0x08, 0x18, 0x08, 0x18, 0x08, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x20, + 0x06, 0x20, 0x06, 0x20, 0x06, 0x20, 0x06, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x40, 0x03, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"V",54*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF3, 0xCF, 0x61, 0x86, + 0x61, 0x84, 0x21, 0x84, 0x20, 0x84, 0x30, 0xC4, 0x31, 0xC4, 0x31, 0xC4, 0x31, 0xC8, 0x31, 0xC8, + 0x11, 0xC8, 0x12, 0x48, 0x1A, 0x68, 0x1A, 0x68, 0x1A, 0x70, 0x1C, 0x70, 0x0C, 0x70, 0x0C, 0x70, + 0x0C, 0x30, 0x0C, 0x20, 0x08, 0x20, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"W",55*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x3E, 0x18, 0x08, + 0x18, 0x10, 0x0C, 0x10, 0x0C, 0x20, 0x06, 0x20, 0x06, 0x40, 0x03, 0x40, 0x03, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0xC0, 0x02, 0xC0, 0x02, 0x60, 0x04, 0x60, 0x04, 0x70, 0x08, 0x30, + 0x08, 0x30, 0x18, 0x18, 0x10, 0x1C, 0x7C, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"X",56*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x3E, 0x38, 0x08, + 0x18, 0x08, 0x18, 0x10, 0x0C, 0x10, 0x0C, 0x10, 0x0C, 0x20, 0x06, 0x20, 0x06, 0x20, 0x03, 0x40, + 0x03, 0x40, 0x03, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Y",57*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFE, 0x1C, 0x0C, + 0x18, 0x0C, 0x30, 0x18, 0x20, 0x18, 0x00, 0x30, 0x00, 0x60, 0x00, 0x60, 0x00, 0xC0, 0x00, 0xC0, + 0x01, 0x80, 0x01, 0x80, 0x03, 0x00, 0x03, 0x00, 0x06, 0x00, 0x06, 0x00, 0x0C, 0x00, 0x18, 0x02, + 0x18, 0x06, 0x30, 0x04, 0x30, 0x1C, 0x7F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Z",58*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFC, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x00, 0x00, /*"[",59*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x08, 0x00, + 0x0C, 0x00, 0x04, 0x00, 0x06, 0x00, 0x06, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x80, + 0x01, 0x80, 0x00, 0x80, 0x00, 0xC0, 0x00, 0x40, 0x00, 0x60, 0x00, 0x60, 0x00, 0x30, 0x00, 0x30, + 0x00, 0x30, 0x00, 0x18, 0x00, 0x18, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x00, /*"\",60*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, + 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, + 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, + 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, /*"]",61*/ + + 0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x03, 0xE0, 0x06, 0x20, 0x08, 0x10, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"^",62*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, /*"_",63*/ + + 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x03, 0x00, 0x00, 0x80, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"`",64*/ + + 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, 0x07, 0xE0, 0x18, 0x30, 0x30, 0x18, + 0x30, 0x18, 0x30, 0x18, 0x00, 0x38, 0x07, 0xD8, 0x1C, 0x18, 0x30, 0x18, 0x60, 0x18, 0x60, 0x18, + 0x60, 0x18, 0x60, 0x19, 0x30, 0x79, 0x1F, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"a",65*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x78, 0x00, 0x18, 0x00, + 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x19, 0xE0, 0x1A, 0x38, 0x1C, 0x18, + 0x1C, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, + 0x18, 0x08, 0x1C, 0x18, 0x1C, 0x30, 0x13, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"b",66*/ + + 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, 0x03, 0xE0, 0x0E, 0x10, 0x0C, 0x18, + 0x18, 0x18, 0x30, 0x18, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x04, + 0x18, 0x04, 0x18, 0x08, 0x0C, 0x10, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"c",67*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x78, 0x00, 0x18, + 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x07, 0xD8, 0x0C, 0x38, 0x18, 0x18, + 0x18, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, + 0x10, 0x18, 0x18, 0x38, 0x0C, 0x5E, 0x07, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"d",68*/ + + 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, 0x03, 0xC0, 0x0C, 0x30, 0x08, 0x18, + 0x18, 0x08, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x3F, 0xFC, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, + 0x18, 0x04, 0x18, 0x08, 0x0E, 0x18, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"e",69*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x86, + 0x01, 0x06, 0x03, 0x06, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x3F, 0xF8, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"f",70*/ + + 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, 0x03, 0xEE, 0x0C, 0x36, 0x08, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x08, 0x18, 0x0C, 0x30, 0x0F, 0xE0, 0x18, 0x00, 0x18, 0x00, + 0x1F, 0xC0, 0x0F, 0xF8, 0x18, 0x1C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x18, 0x18, 0x07, 0xE0, /*"g",71*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x78, 0x00, 0x18, 0x00, + 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x19, 0xE0, 0x1A, 0x30, 0x1C, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"h",72*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0xC0, + 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"i",73*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x78, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0xF0, 0x00, 0x30, 0x00, 0x30, + 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, + 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x18, 0x60, 0x18, 0x40, 0x0F, 0x80, /*"j",74*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x78, 0x00, 0x18, 0x00, + 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x7C, 0x18, 0x30, 0x18, 0x20, + 0x18, 0x40, 0x18, 0x80, 0x19, 0x80, 0x1B, 0x80, 0x1E, 0xC0, 0x1C, 0xC0, 0x18, 0x60, 0x18, 0x30, + 0x18, 0x30, 0x18, 0x18, 0x18, 0x1C, 0x7E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"k",75*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"l",76*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xEF, 0x3C, 0x71, 0xC6, 0x61, 0x86, + 0x61, 0x86, 0x61, 0x86, 0x61, 0x86, 0x61, 0x86, 0x61, 0x86, 0x61, 0x86, 0x61, 0x86, 0x61, 0x86, + 0x61, 0x86, 0x61, 0x86, 0x61, 0x86, 0xF3, 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"m",77*/ + + 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, 0x09, 0xE0, 0x7A, 0x30, 0x1C, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"n",78*/ + + 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, 0x03, 0xC0, 0x0C, 0x30, 0x08, 0x18, + 0x18, 0x18, 0x10, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x30, 0x0C, + 0x18, 0x18, 0x18, 0x18, 0x0C, 0x30, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"o",79*/ + + 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, 0x09, 0xE0, 0x7A, 0x30, 0x1C, 0x18, + 0x18, 0x08, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, 0x18, 0x0C, + 0x18, 0x18, 0x1C, 0x18, 0x1E, 0x30, 0x19, 0xE0, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x7E, 0x00, /*"p",80*/ + + 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, 0x03, 0xC8, 0x0C, 0x78, 0x18, 0x38, + 0x18, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, + 0x10, 0x18, 0x18, 0x38, 0x0C, 0x78, 0x07, 0x98, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x7E, /*"q",81*/ + + 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, 0x06, 0x1C, 0x7E, 0x66, 0x06, 0x86, + 0x07, 0x80, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"r",82*/ + + 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, 0x03, 0xE4, 0x06, 0x1C, 0x0C, 0x0C, + 0x0C, 0x04, 0x0C, 0x04, 0x0E, 0x00, 0x07, 0xC0, 0x01, 0xF0, 0x00, 0x78, 0x00, 0x1C, 0x10, 0x0C, + 0x10, 0x0C, 0x18, 0x0C, 0x1C, 0x18, 0x13, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"s",83*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x07, 0x00, 0x3F, 0xF8, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, + 0x03, 0x04, 0x03, 0x04, 0x01, 0x88, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"t",84*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x78, 0x78, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x38, 0x0C, 0x5E, 0x07, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"u",85*/ + + 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, 0x7C, 0x3E, 0x18, 0x0C, 0x18, 0x08, + 0x18, 0x18, 0x0C, 0x10, 0x0C, 0x10, 0x04, 0x20, 0x06, 0x20, 0x06, 0x20, 0x03, 0x40, 0x03, 0x40, + 0x03, 0xC0, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"v",86*/ + + 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, 0xFB, 0xCF, 0x61, 0x86, 0x21, 0x84, + 0x31, 0x84, 0x31, 0x84, 0x31, 0xC8, 0x11, 0xC8, 0x1A, 0xC8, 0x1A, 0x48, 0x1A, 0x70, 0x0E, 0x70, + 0x0C, 0x70, 0x0C, 0x30, 0x0C, 0x20, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"w",87*/ + + 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, 0x3E, 0x7C, 0x0C, 0x10, 0x0E, 0x10, + 0x06, 0x20, 0x03, 0x40, 0x03, 0x40, 0x01, 0x80, 0x01, 0x80, 0x01, 0xC0, 0x02, 0x60, 0x04, 0x60, + 0x04, 0x30, 0x08, 0x18, 0x18, 0x18, 0x7C, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"x",88*/ + + 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, 0x7C, 0x3E, 0x18, 0x18, 0x18, 0x10, + 0x08, 0x10, 0x0C, 0x10, 0x04, 0x20, 0x06, 0x20, 0x06, 0x20, 0x02, 0x40, 0x03, 0x40, 0x01, 0x40, + 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x3E, 0x00, 0x3C, 0x00, /*"y",89*/ + + 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, 0x3F, 0xF8, 0x30, 0x38, 0x30, 0x30, + 0x20, 0x60, 0x20, 0xE0, 0x00, 0xC0, 0x01, 0x80, 0x03, 0x80, 0x03, 0x00, 0x06, 0x00, 0x0E, 0x04, + 0x0C, 0x04, 0x18, 0x0C, 0x30, 0x18, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"z",90*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, + 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xC0, + 0x01, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, + 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x00, /*"{",91*/ + + 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, + 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, + 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, + 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, /*"|",92*/ + + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x80, + 0x00, 0xC0, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, /*"}",93*/ + + 0x00, 0x00, 0x1E, 0x00, 0x23, 0x00, 0x41, 0x82, 0x40, 0x82, 0x00, 0xE4, 0x00, 0x38, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"~",94*/ +}; + +const esp_painter_basic_font_t esp_painter_basic_font_32 = { + .bitmap = bitmap, + .width = 16, + .height = 32, +}; + +#endif diff --git a/components/lua_modules/esp_painter/font/basic_font_36.c b/components/lua_modules/esp_painter/font/basic_font_36.c new file mode 100644 index 0000000..a5510f7 --- /dev/null +++ b/components/lua_modules/esp_painter/font/basic_font_36.c @@ -0,0 +1,782 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "sdkconfig.h" + +#include "esp_painter_font.h" + +#if CONFIG_ESP_PAINTER_BASIC_FONT_36 + +static const uint8_t bitmap[] = +{ + 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, 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, + 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, /*" ",0*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xE0, + 0x00, 0x01, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"!",1*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC7, 0x00, 0x01, 0xC7, 0x00, 0x03, 0xCF, 0x00, 0x03, + 0x8E, 0x00, 0x07, 0x1C, 0x00, 0x06, 0x18, 0x00, 0x0C, 0x30, 0x00, 0x18, 0x60, 0x00, 0x10, 0x40, + 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, 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, /*""",2*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, 0x04, 0x00, 0x04, 0x04, 0x00, 0x04, 0x04, 0x00, 0x04, 0x04, + 0x00, 0x04, 0x04, 0x00, 0x7F, 0xFF, 0x80, 0x7F, 0xFF, 0x80, 0x7F, 0xFF, 0x80, 0x0C, 0x0C, 0x00, + 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x08, + 0x08, 0x00, 0x7F, 0xFF, 0x80, 0x7F, 0xFF, 0x80, 0x7F, 0xFF, 0x80, 0x18, 0x18, 0x00, 0x18, 0x18, + 0x00, 0x18, 0x18, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"#",3*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x80, 0x00, 0x03, 0xF0, 0x00, 0x06, 0x88, 0x00, 0x0C, 0x84, 0x00, 0x18, 0x86, 0x00, 0x18, 0x86, + 0x00, 0x18, 0x8E, 0x00, 0x18, 0x8E, 0x00, 0x1C, 0x80, 0x00, 0x0E, 0x80, 0x00, 0x0F, 0x80, 0x00, + 0x07, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x01, 0xF0, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xBC, 0x00, 0x00, + 0x9C, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x86, 0x00, 0x38, 0x86, 0x00, 0x38, 0x86, 0x00, 0x38, 0x86, + 0x00, 0x30, 0x84, 0x00, 0x10, 0x8C, 0x00, 0x08, 0x98, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, /*"$",4*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3C, 0x04, 0x00, 0x66, 0x0C, 0x00, 0x42, 0x08, 0x00, 0xC3, 0x08, 0x00, 0xC3, 0x10, + 0x00, 0xC3, 0x10, 0x00, 0xC3, 0x20, 0x00, 0xC3, 0x20, 0x00, 0xC3, 0x20, 0x00, 0xC3, 0x40, 0x00, + 0x42, 0x40, 0x00, 0x66, 0x80, 0x00, 0x3C, 0x9E, 0x00, 0x00, 0xB3, 0x00, 0x01, 0x31, 0x00, 0x01, + 0x61, 0x80, 0x02, 0x61, 0x80, 0x02, 0x61, 0x80, 0x06, 0x61, 0x80, 0x04, 0x61, 0x80, 0x04, 0x61, + 0x80, 0x08, 0x61, 0x80, 0x08, 0x21, 0x00, 0x10, 0x33, 0x00, 0x10, 0x1E, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"%",5*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x80, 0x00, 0x0C, 0x80, 0x00, 0x08, 0xC0, 0x00, 0x18, 0xC0, 0x00, 0x18, 0xC0, + 0x00, 0x18, 0xC0, 0x00, 0x18, 0xC0, 0x00, 0x18, 0x80, 0x00, 0x19, 0x80, 0x00, 0x1D, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0C, 0x3E, 0x00, 0x1E, 0x18, 0x00, 0x26, 0x08, 0x00, 0x67, 0x08, 0x00, 0x43, + 0x08, 0x00, 0xC3, 0x10, 0x00, 0xC3, 0x90, 0x00, 0xC1, 0xD0, 0x00, 0xC0, 0xD0, 0x00, 0xC0, 0xE0, + 0x00, 0x60, 0x70, 0x80, 0x60, 0x79, 0x80, 0x30, 0x9F, 0x00, 0x1F, 0x0E, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"&",6*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x0E, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 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, 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, /*"'",7*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"(",8*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0xC0, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*")",9*/ + + 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, 0xC0, 0x00, 0x01, 0xC0, + 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x70, 0xC7, 0x00, 0x78, 0x8F, 0x00, 0x3C, 0x9E, 0x00, + 0x0E, 0xB8, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x0E, 0xB8, 0x00, 0x3C, 0x9E, 0x00, 0x78, + 0x8F, 0x00, 0x71, 0x87, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, + 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, /*"*",10*/ + + 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, 0x40, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x40, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 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, /*"+",11*/ + + 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, 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, 0x0C, 0x00, + 0x00, 0x1E, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, /*",",12*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x80, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"-",13*/ + + 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, 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, + 0x00, 0x18, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*".",14*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0x80, 0x00, + 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0C, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"/",15*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xE0, 0x00, 0x06, 0x18, 0x00, 0x04, 0x0C, 0x00, 0x0C, 0x0C, 0x00, 0x18, 0x06, + 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, + 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, + 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, + 0x00, 0x0C, 0x0C, 0x00, 0x04, 0x08, 0x00, 0x06, 0x18, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"0",16*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xC0, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, + 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, + 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x01, 0xE0, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"1",17*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xF0, 0x00, 0x0C, 0x1C, 0x00, 0x18, 0x06, 0x00, 0x30, 0x06, 0x00, 0x30, 0x03, + 0x00, 0x38, 0x03, 0x00, 0x38, 0x03, 0x00, 0x38, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, + 0xC0, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x01, 0x00, 0x08, 0x01, + 0x00, 0x10, 0x03, 0x00, 0x30, 0x07, 0x00, 0x3F, 0xFE, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"2",18*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xE0, 0x00, 0x08, 0x38, 0x00, 0x10, 0x0C, 0x00, 0x20, 0x0E, 0x00, 0x30, 0x06, + 0x00, 0x30, 0x06, 0x00, 0x30, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x30, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x18, 0x03, 0x00, 0x38, 0x03, 0x00, 0x38, 0x03, + 0x00, 0x38, 0x06, 0x00, 0x18, 0x04, 0x00, 0x0C, 0x18, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"3",19*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x58, + 0x00, 0x00, 0xD8, 0x00, 0x00, 0x98, 0x00, 0x01, 0x18, 0x00, 0x03, 0x18, 0x00, 0x02, 0x18, 0x00, + 0x04, 0x18, 0x00, 0x0C, 0x18, 0x00, 0x08, 0x18, 0x00, 0x10, 0x18, 0x00, 0x10, 0x18, 0x00, 0x20, + 0x18, 0x00, 0x60, 0x18, 0x00, 0x7F, 0xFF, 0x80, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"4",20*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x0F, 0xFF, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x11, 0xF0, 0x00, + 0x16, 0x0C, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x18, 0x03, 0x00, 0x38, 0x03, 0x00, 0x38, 0x06, + 0x00, 0x30, 0x06, 0x00, 0x10, 0x0C, 0x00, 0x0C, 0x18, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"5",21*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xF8, 0x00, 0x03, 0x04, 0x00, 0x06, 0x06, 0x00, 0x0C, 0x06, 0x00, 0x08, 0x06, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x31, 0xF0, 0x00, + 0x36, 0x1C, 0x00, 0x34, 0x06, 0x00, 0x38, 0x06, 0x00, 0x38, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, + 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x02, + 0x00, 0x0C, 0x06, 0x00, 0x0C, 0x04, 0x00, 0x06, 0x08, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"6",22*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x1F, 0xFF, 0x00, 0x18, 0x02, 0x00, 0x30, 0x04, 0x00, 0x20, 0x04, + 0x00, 0x20, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x80, 0x00, 0x01, + 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, + 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"7",23*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xF0, 0x00, 0x06, 0x0C, 0x00, 0x0C, 0x06, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, + 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x1C, 0x03, 0x00, 0x0E, 0x06, 0x00, 0x0F, 0x06, 0x00, + 0x07, 0x88, 0x00, 0x03, 0xF0, 0x00, 0x06, 0xF8, 0x00, 0x0C, 0x3C, 0x00, 0x18, 0x1E, 0x00, 0x18, + 0x0E, 0x00, 0x30, 0x07, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, + 0x00, 0x18, 0x02, 0x00, 0x18, 0x06, 0x00, 0x0E, 0x0C, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"8",24*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xE0, 0x00, 0x0E, 0x18, 0x00, 0x08, 0x0C, 0x00, 0x18, 0x04, 0x00, 0x10, 0x06, + 0x00, 0x30, 0x02, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, + 0x30, 0x07, 0x00, 0x18, 0x07, 0x00, 0x18, 0x0B, 0x00, 0x0E, 0x13, 0x00, 0x03, 0xE3, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x18, 0x0C, + 0x00, 0x18, 0x08, 0x00, 0x18, 0x18, 0x00, 0x08, 0x70, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"9",25*/ + + 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, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x01, 0xE0, 0x00, + 0x01, 0xE0, 0x00, 0x00, 0xC0, 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, 0xC0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*":",26*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x00, + 0x01, 0xC0, 0x00, 0x01, 0xC0, 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, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x00, 0xC0, 0x00, + 0x00, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, /*";",27*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x40, 0x00, 0x00, 0xC0, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"<",28*/ + + 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, 0x00, 0x00, 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0x80, 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, 0x00, 0x00, /*"=",29*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*">",30*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xF0, 0x00, 0x06, 0x0C, 0x00, 0x08, 0x06, 0x00, 0x10, 0x02, 0x00, 0x30, 0x03, + 0x00, 0x30, 0x03, 0x00, 0x3C, 0x03, 0x00, 0x3C, 0x03, 0x00, 0x1C, 0x03, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x78, 0x00, 0x00, 0x60, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"?",31*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xF0, 0x00, 0x07, 0x0C, 0x00, 0x0C, 0x02, 0x00, 0x08, 0x01, 0x00, 0x18, 0x7D, + 0x00, 0x30, 0xCD, 0x00, 0x31, 0x8C, 0x80, 0x21, 0x8C, 0x80, 0x63, 0x08, 0x80, 0x63, 0x08, 0x80, + 0x63, 0x18, 0x80, 0x66, 0x18, 0x80, 0x66, 0x18, 0x80, 0x66, 0x18, 0x80, 0x66, 0x18, 0x80, 0x66, + 0x31, 0x00, 0x66, 0x31, 0x00, 0x22, 0x52, 0x00, 0x33, 0x9C, 0x00, 0x30, 0x00, 0x80, 0x10, 0x01, + 0x00, 0x18, 0x03, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x0C, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"@",32*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x03, 0x60, + 0x00, 0x02, 0x60, 0x00, 0x02, 0x60, 0x00, 0x02, 0x60, 0x00, 0x06, 0x30, 0x00, 0x04, 0x30, 0x00, + 0x04, 0x30, 0x00, 0x04, 0x30, 0x00, 0x0C, 0x38, 0x00, 0x08, 0x18, 0x00, 0x08, 0x18, 0x00, 0x0F, + 0xF8, 0x00, 0x18, 0x18, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x0C, 0x00, 0x10, 0x0C, 0x00, 0x30, 0x0C, + 0x00, 0x20, 0x0E, 0x00, 0x20, 0x06, 0x00, 0x30, 0x06, 0x00, 0xF8, 0x1F, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"A",33*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x18, 0x1E, 0x00, 0x18, 0x06, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, + 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, + 0x18, 0x18, 0x00, 0x1F, 0xF0, 0x00, 0x18, 0x0C, 0x00, 0x18, 0x06, 0x00, 0x18, 0x03, 0x00, 0x18, + 0x01, 0x00, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, + 0x80, 0x18, 0x03, 0x00, 0x18, 0x07, 0x00, 0x18, 0x0E, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"B",34*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xF9, 0x00, 0x02, 0x0F, 0x00, 0x0C, 0x03, 0x00, 0x08, 0x01, 0x00, 0x18, 0x01, + 0x80, 0x30, 0x00, 0x80, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x80, 0x30, 0x00, 0x80, 0x30, 0x01, + 0x00, 0x18, 0x01, 0x00, 0x0C, 0x02, 0x00, 0x06, 0x0C, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"C",35*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x18, 0x38, 0x00, 0x18, 0x0C, 0x00, 0x18, 0x06, 0x00, 0x18, 0x02, + 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, + 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, + 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x06, + 0x00, 0x18, 0x06, 0x00, 0x18, 0x0C, 0x00, 0x18, 0x38, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"D",36*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x18, 0x07, 0x00, 0x18, 0x03, 0x00, 0x18, 0x01, 0x80, 0x18, 0x00, + 0x80, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x08, 0x00, 0x18, 0x08, 0x00, 0x18, 0x08, 0x00, + 0x18, 0x18, 0x00, 0x1F, 0xF8, 0x00, 0x18, 0x18, 0x00, 0x18, 0x08, 0x00, 0x18, 0x08, 0x00, 0x18, + 0x08, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x80, 0x18, 0x00, + 0x80, 0x18, 0x01, 0x00, 0x18, 0x03, 0x00, 0x18, 0x07, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"E",37*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x18, 0x0F, 0x00, 0x18, 0x03, 0x00, 0x18, 0x01, 0x00, 0x18, 0x00, + 0x80, 0x18, 0x00, 0x80, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x08, 0x00, 0x18, 0x08, 0x00, + 0x18, 0x18, 0x00, 0x1F, 0xF8, 0x00, 0x18, 0x18, 0x00, 0x18, 0x08, 0x00, 0x18, 0x08, 0x00, 0x18, + 0x08, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"F",38*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xE0, 0x00, 0x06, 0x1C, 0x00, 0x0C, 0x0C, 0x00, 0x18, 0x04, 0x00, 0x10, 0x06, + 0x00, 0x30, 0x02, 0x00, 0x30, 0x02, 0x00, 0x20, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x3F, 0x80, 0x60, + 0x06, 0x00, 0x60, 0x06, 0x00, 0x30, 0x06, 0x00, 0x30, 0x06, 0x00, 0x30, 0x06, 0x00, 0x10, 0x06, + 0x00, 0x18, 0x06, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x08, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"G",39*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7E, 0x1F, 0x80, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, + 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, + 0x18, 0x06, 0x00, 0x1F, 0xFE, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, + 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, + 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x7E, 0x1F, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"H",40*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, + 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, + 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"I",41*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xC0, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x70, 0x18, 0x00, + 0x70, 0x30, 0x00, 0x70, 0x30, 0x00, 0x30, 0x40, 0x00, 0x1F, 0x80, 0x00, /*"J",42*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7E, 0x3F, 0x00, 0x18, 0x0C, 0x00, 0x18, 0x08, 0x00, 0x18, 0x10, 0x00, 0x18, 0x30, + 0x00, 0x18, 0x20, 0x00, 0x18, 0x40, 0x00, 0x18, 0xC0, 0x00, 0x18, 0x80, 0x00, 0x19, 0x80, 0x00, + 0x19, 0x80, 0x00, 0x1B, 0xC0, 0x00, 0x1C, 0xC0, 0x00, 0x1C, 0xE0, 0x00, 0x18, 0x60, 0x00, 0x18, + 0x60, 0x00, 0x18, 0x30, 0x00, 0x18, 0x30, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x18, 0x1C, + 0x00, 0x18, 0x0C, 0x00, 0x18, 0x0E, 0x00, 0x18, 0x06, 0x00, 0x7E, 0x1F, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"K",43*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7E, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x80, 0x18, 0x00, + 0x80, 0x18, 0x01, 0x00, 0x18, 0x03, 0x00, 0x18, 0x07, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"L",44*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF8, 0x07, 0xC0, 0x38, 0x07, 0x00, 0x38, 0x07, 0x00, 0x38, 0x07, 0x00, 0x38, 0x07, + 0x00, 0x2C, 0x0B, 0x00, 0x2C, 0x0B, 0x00, 0x2C, 0x0B, 0x00, 0x2C, 0x0B, 0x00, 0x2E, 0x13, 0x00, + 0x26, 0x13, 0x00, 0x26, 0x13, 0x00, 0x26, 0x13, 0x00, 0x26, 0x23, 0x00, 0x23, 0x23, 0x00, 0x23, + 0x23, 0x00, 0x23, 0x23, 0x00, 0x23, 0x43, 0x00, 0x23, 0xC3, 0x00, 0x21, 0xC3, 0x00, 0x21, 0xC3, + 0x00, 0x21, 0xC3, 0x00, 0x21, 0x83, 0x00, 0x20, 0x83, 0x00, 0xF8, 0x8F, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"M",45*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0x0F, 0x80, 0x1C, 0x02, 0x00, 0x1C, 0x02, 0x00, 0x16, 0x02, 0x00, 0x16, 0x02, + 0x00, 0x16, 0x02, 0x00, 0x13, 0x02, 0x00, 0x13, 0x02, 0x00, 0x11, 0x82, 0x00, 0x11, 0x82, 0x00, + 0x10, 0xC2, 0x00, 0x10, 0xC2, 0x00, 0x10, 0xE2, 0x00, 0x10, 0x62, 0x00, 0x10, 0x62, 0x00, 0x10, + 0x32, 0x00, 0x10, 0x32, 0x00, 0x10, 0x1A, 0x00, 0x10, 0x1A, 0x00, 0x10, 0x0E, 0x00, 0x10, 0x0E, + 0x00, 0x10, 0x0E, 0x00, 0x10, 0x06, 0x00, 0x10, 0x06, 0x00, 0x7C, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"N",46*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xF0, 0x00, 0x06, 0x18, 0x00, 0x0C, 0x04, 0x00, 0x18, 0x06, 0x00, 0x10, 0x02, + 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x20, 0x01, 0x00, 0x60, 0x01, 0x80, 0x60, 0x01, 0x80, + 0x60, 0x01, 0x80, 0x60, 0x01, 0x80, 0x60, 0x01, 0x80, 0x60, 0x01, 0x80, 0x60, 0x01, 0x80, 0x60, + 0x01, 0x80, 0x60, 0x01, 0x80, 0x20, 0x01, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x10, 0x02, + 0x00, 0x18, 0x06, 0x00, 0x0C, 0x04, 0x00, 0x06, 0x18, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"O",47*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x18, 0x0E, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x01, + 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x03, 0x00, + 0x18, 0x07, 0x00, 0x18, 0x0E, 0x00, 0x1F, 0xF8, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"P",48*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xF0, 0x00, 0x06, 0x18, 0x00, 0x0C, 0x04, 0x00, 0x18, 0x06, 0x00, 0x10, 0x02, + 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x60, 0x01, 0x80, 0x60, 0x01, 0x80, 0x60, 0x01, 0x80, + 0x60, 0x01, 0x80, 0x60, 0x01, 0x80, 0x60, 0x01, 0x80, 0x60, 0x01, 0x80, 0x60, 0x01, 0x80, 0x60, + 0x01, 0x80, 0x60, 0x01, 0x80, 0x60, 0x01, 0x80, 0x27, 0xC1, 0x00, 0x3C, 0x63, 0x00, 0x38, 0x33, + 0x00, 0x18, 0x32, 0x00, 0x08, 0x3C, 0x00, 0x06, 0x18, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x1C, 0x80, + 0x00, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Q",49*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xF0, 0x00, 0x18, 0x1C, 0x00, 0x18, 0x06, 0x00, 0x18, 0x07, 0x00, 0x18, 0x03, + 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, + 0x18, 0x1C, 0x00, 0x1F, 0xF0, 0x00, 0x18, 0x60, 0x00, 0x18, 0x60, 0x00, 0x18, 0x70, 0x00, 0x18, + 0x30, 0x00, 0x18, 0x30, 0x00, 0x18, 0x38, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x18, 0x1C, + 0x00, 0x18, 0x0C, 0x00, 0x18, 0x0E, 0x00, 0x18, 0x06, 0x00, 0x7E, 0x07, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"R",50*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xE0, 0x00, 0x0C, 0x1E, 0x00, 0x18, 0x0E, 0x00, 0x10, 0x06, 0x00, 0x30, 0x02, + 0x00, 0x30, 0x02, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x38, 0x00, 0x00, 0x1E, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x00, 0x20, 0x03, 0x00, 0x20, 0x03, 0x00, 0x30, 0x03, + 0x00, 0x10, 0x06, 0x00, 0x18, 0x06, 0x00, 0x1E, 0x0C, 0x00, 0x11, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"S",51*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x30, 0xC3, 0x00, 0x20, 0xC1, 0x00, 0x20, 0xC1, 0x80, 0x40, 0xC0, + 0x80, 0x40, 0xC0, 0x80, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, + 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"T",52*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7E, 0x0F, 0x80, 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, 0x02, + 0x00, 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, + 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, + 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, 0x02, + 0x00, 0x18, 0x04, 0x00, 0x0C, 0x04, 0x00, 0x06, 0x18, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"U",53*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7E, 0x0F, 0x80, 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, 0x1C, 0x06, 0x00, 0x0C, 0x04, + 0x00, 0x0C, 0x04, 0x00, 0x0C, 0x04, 0x00, 0x0E, 0x0C, 0x00, 0x0E, 0x08, 0x00, 0x06, 0x08, 0x00, + 0x06, 0x08, 0x00, 0x06, 0x18, 0x00, 0x07, 0x10, 0x00, 0x03, 0x10, 0x00, 0x03, 0x10, 0x00, 0x03, + 0x20, 0x00, 0x03, 0xA0, 0x00, 0x01, 0xA0, 0x00, 0x01, 0xA0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, + 0x00, 0x01, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"V",54*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xF9, 0xF3, 0xC0, 0x70, 0xC1, 0x80, 0x30, 0xC1, 0x00, 0x30, 0xC1, 0x00, 0x30, 0xC1, + 0x00, 0x30, 0x61, 0x00, 0x30, 0xE1, 0x00, 0x30, 0xE2, 0x00, 0x30, 0xE2, 0x00, 0x18, 0xE2, 0x00, + 0x18, 0xE2, 0x00, 0x19, 0x62, 0x00, 0x19, 0x32, 0x00, 0x19, 0x34, 0x00, 0x19, 0x34, 0x00, 0x19, + 0x34, 0x00, 0x0E, 0x34, 0x00, 0x0E, 0x34, 0x00, 0x0E, 0x38, 0x00, 0x0E, 0x18, 0x00, 0x0E, 0x18, + 0x00, 0x0E, 0x18, 0x00, 0x04, 0x18, 0x00, 0x04, 0x18, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"W",55*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7E, 0x1F, 0x00, 0x1C, 0x06, 0x00, 0x0C, 0x04, 0x00, 0x0C, 0x08, 0x00, 0x0E, 0x08, + 0x00, 0x06, 0x18, 0x00, 0x07, 0x10, 0x00, 0x03, 0x30, 0x00, 0x03, 0xA0, 0x00, 0x01, 0xE0, 0x00, + 0x01, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x01, + 0x70, 0x00, 0x03, 0x30, 0x00, 0x02, 0x30, 0x00, 0x06, 0x18, 0x00, 0x04, 0x18, 0x00, 0x04, 0x1C, + 0x00, 0x08, 0x0C, 0x00, 0x08, 0x0E, 0x00, 0x18, 0x06, 0x00, 0x7C, 0x1F, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"X",56*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7E, 0x0F, 0x80, 0x38, 0x06, 0x00, 0x18, 0x06, 0x00, 0x1C, 0x04, 0x00, 0x0C, 0x04, + 0x00, 0x0C, 0x08, 0x00, 0x06, 0x08, 0x00, 0x06, 0x08, 0x00, 0x07, 0x10, 0x00, 0x03, 0x10, 0x00, + 0x03, 0x30, 0x00, 0x01, 0xA0, 0x00, 0x01, 0xA0, 0x00, 0x01, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, + 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Y",57*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x1C, 0x06, 0x00, 0x18, 0x0E, 0x00, 0x30, 0x0C, 0x00, 0x20, 0x1C, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x60, 0x00, + 0x00, 0xE0, 0x00, 0x00, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0C, 0x01, 0x00, 0x1C, 0x01, + 0x00, 0x18, 0x02, 0x00, 0x38, 0x06, 0x00, 0x30, 0x0E, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Z",58*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"[",59*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, + 0x01, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /*"\",60*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"]",61*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x03, 0x60, 0x00, 0x06, 0x10, 0x00, 0x08, + 0x08, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"^",62*/ + + 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, 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, + 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, 0xFF, 0xFF, 0xC0, /*"_",63*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, + 0x40, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"`",64*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x00, + 0x0C, 0x18, 0x00, 0x18, 0x0C, 0x00, 0x18, 0x0C, 0x00, 0x18, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x01, + 0xFC, 0x00, 0x07, 0x0C, 0x00, 0x1C, 0x0C, 0x00, 0x18, 0x0C, 0x00, 0x30, 0x0C, 0x00, 0x30, 0x0C, + 0x00, 0x30, 0x0C, 0x80, 0x30, 0x1C, 0x80, 0x18, 0x3C, 0x80, 0x0F, 0xC7, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"a",65*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x78, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0xF8, 0x00, + 0x1B, 0x0C, 0x00, 0x1E, 0x06, 0x00, 0x1C, 0x06, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, + 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, + 0x00, 0x18, 0x06, 0x00, 0x1C, 0x06, 0x00, 0x1E, 0x0C, 0x00, 0x11, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"b",66*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF8, 0x00, + 0x07, 0x0C, 0x00, 0x0C, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x30, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10, 0x01, + 0x00, 0x18, 0x02, 0x00, 0x0C, 0x02, 0x00, 0x06, 0x0C, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"c",67*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x03, 0xE6, 0x00, + 0x06, 0x1E, 0x00, 0x0C, 0x0E, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x30, 0x06, 0x00, 0x30, + 0x06, 0x00, 0x30, 0x06, 0x00, 0x30, 0x06, 0x00, 0x30, 0x06, 0x00, 0x30, 0x06, 0x00, 0x30, 0x06, + 0x00, 0x18, 0x0E, 0x00, 0x18, 0x0E, 0x00, 0x0C, 0x17, 0x80, 0x03, 0xE4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"d",68*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF0, 0x00, + 0x06, 0x0C, 0x00, 0x0C, 0x06, 0x00, 0x18, 0x06, 0x00, 0x10, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, + 0x03, 0x00, 0x3F, 0xFF, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10, 0x01, + 0x00, 0x18, 0x01, 0x00, 0x0C, 0x02, 0x00, 0x06, 0x0C, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"e",69*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xC1, 0x00, 0x01, 0x81, 0x80, 0x01, 0x01, 0x80, 0x03, 0x01, + 0x80, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x3F, 0xFC, 0x00, + 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"f",70*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE3, 0x80, + 0x06, 0x3D, 0x80, 0x0C, 0x18, 0x00, 0x18, 0x0C, 0x00, 0x18, 0x0C, 0x00, 0x18, 0x0C, 0x00, 0x18, + 0x0C, 0x00, 0x0C, 0x18, 0x00, 0x06, 0x18, 0x00, 0x0F, 0xE0, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x1F, 0xC0, 0x00, 0x07, 0xFC, 0x00, 0x18, 0x1E, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, + 0x30, 0x03, 0x00, 0x38, 0x02, 0x00, 0x1C, 0x0E, 0x00, 0x07, 0xF8, 0x00, /*"g",71*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x78, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0xF8, 0x00, + 0x1B, 0x0C, 0x00, 0x1C, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, + 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, + 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x7E, 0x1F, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"h",72*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xC0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x0F, 0xC0, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, + 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"i",73*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0xFC, 0x00, + 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, + 0x18, 0x08, 0x00, 0x18, 0x18, 0x00, 0x18, 0x30, 0x00, 0x0F, 0xC0, 0x00, /*"j",74*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x78, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x3F, 0x00, + 0x18, 0x1C, 0x00, 0x18, 0x10, 0x00, 0x18, 0x30, 0x00, 0x18, 0x60, 0x00, 0x18, 0xC0, 0x00, 0x19, + 0xC0, 0x00, 0x1B, 0xE0, 0x00, 0x1E, 0x60, 0x00, 0x1C, 0x70, 0x00, 0x18, 0x38, 0x00, 0x18, 0x18, + 0x00, 0x18, 0x1C, 0x00, 0x18, 0x0E, 0x00, 0x18, 0x06, 0x00, 0x7E, 0x1F, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"k",75*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, + 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, + 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"l",76*/ + + 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, 0x00, 0x00, 0x10, 0x00, 0x00, 0x77, 0x9E, 0x00, + 0x38, 0xE3, 0x00, 0x38, 0xC3, 0x00, 0x30, 0xC3, 0x00, 0x30, 0xC3, 0x00, 0x30, 0xC3, 0x00, 0x30, + 0xC3, 0x00, 0x30, 0xC3, 0x00, 0x30, 0xC3, 0x00, 0x30, 0xC3, 0x00, 0x30, 0xC3, 0x00, 0x30, 0xC3, + 0x00, 0x30, 0xC3, 0x00, 0x30, 0xC3, 0x00, 0x30, 0xC3, 0x00, 0x79, 0xE7, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"m",77*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xF8, 0x00, + 0x7B, 0x0C, 0x00, 0x1E, 0x06, 0x00, 0x1C, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, + 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, + 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x7E, 0x1F, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"n",78*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x00, + 0x06, 0x18, 0x00, 0x0C, 0x0C, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x30, 0x03, 0x00, 0x30, + 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x10, 0x02, + 0x00, 0x18, 0x06, 0x00, 0x0C, 0x0C, 0x00, 0x06, 0x18, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"o",79*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xF0, 0x00, + 0x7B, 0x0C, 0x00, 0x1C, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, + 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x06, + 0x00, 0x18, 0x06, 0x00, 0x1C, 0x0C, 0x00, 0x1A, 0x18, 0x00, 0x19, 0xF0, 0x00, 0x18, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x7E, 0x00, 0x00, /*"p",80*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE2, 0x00, + 0x06, 0x1E, 0x00, 0x0C, 0x0E, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x30, 0x06, 0x00, 0x30, + 0x06, 0x00, 0x30, 0x06, 0x00, 0x30, 0x06, 0x00, 0x30, 0x06, 0x00, 0x30, 0x06, 0x00, 0x30, 0x06, + 0x00, 0x18, 0x06, 0x00, 0x18, 0x0E, 0x00, 0x0C, 0x16, 0x00, 0x03, 0xE6, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x1F, 0x80, /*"q",81*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x1E, 0x00, + 0x7E, 0x23, 0x00, 0x06, 0xC3, 0x00, 0x06, 0x83, 0x00, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"r",82*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF2, 0x00, + 0x06, 0x0E, 0x00, 0x0C, 0x06, 0x00, 0x0C, 0x02, 0x00, 0x0C, 0x02, 0x00, 0x0E, 0x00, 0x00, 0x07, + 0x80, 0x00, 0x03, 0xE0, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x1C, 0x00, 0x10, 0x0E, 0x00, 0x10, 0x06, + 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x1E, 0x0C, 0x00, 0x11, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"s",83*/ + + 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, 0x01, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x3F, 0xFC, 0x00, + 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x03, 0x02, 0x00, 0x03, 0x04, 0x00, 0x01, 0x84, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"t",84*/ + + 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, 0x00, 0x00, 0x08, 0x02, 0x00, 0x78, 0x1E, 0x00, + 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, + 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, 0x00, 0x18, 0x06, + 0x00, 0x18, 0x06, 0x00, 0x18, 0x0E, 0x00, 0x0C, 0x17, 0x80, 0x07, 0xE4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"u",85*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1F, 0x00, + 0x18, 0x0C, 0x00, 0x18, 0x04, 0x00, 0x0C, 0x08, 0x00, 0x0C, 0x08, 0x00, 0x0C, 0x18, 0x00, 0x06, + 0x10, 0x00, 0x06, 0x10, 0x00, 0x06, 0x20, 0x00, 0x03, 0x20, 0x00, 0x03, 0x20, 0x00, 0x03, 0xC0, + 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"v",86*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, 0xE7, 0xC0, + 0x70, 0xC1, 0x00, 0x30, 0xC1, 0x00, 0x30, 0xC1, 0x00, 0x30, 0xE2, 0x00, 0x10, 0xE2, 0x00, 0x18, + 0xE2, 0x00, 0x19, 0x66, 0x00, 0x19, 0x34, 0x00, 0x0D, 0x34, 0x00, 0x0F, 0x34, 0x00, 0x0E, 0x38, + 0x00, 0x0E, 0x18, 0x00, 0x06, 0x18, 0x00, 0x06, 0x18, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"w",87*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3E, 0x00, + 0x0E, 0x08, 0x00, 0x06, 0x10, 0x00, 0x06, 0x10, 0x00, 0x03, 0x20, 0x00, 0x03, 0xE0, 0x00, 0x01, + 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0x60, 0x00, 0x02, 0x30, 0x00, 0x06, 0x30, + 0x00, 0x04, 0x18, 0x00, 0x08, 0x18, 0x00, 0x18, 0x0C, 0x00, 0x7C, 0x3F, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"x",88*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x1F, 0x80, + 0x0C, 0x06, 0x00, 0x0C, 0x04, 0x00, 0x06, 0x04, 0x00, 0x06, 0x0C, 0x00, 0x02, 0x08, 0x00, 0x03, + 0x08, 0x00, 0x03, 0x18, 0x00, 0x01, 0x90, 0x00, 0x01, 0x90, 0x00, 0x01, 0xB0, 0x00, 0x00, 0xE0, + 0x00, 0x00, 0xE0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x80, 0x00, 0x19, 0x80, 0x00, 0x1F, 0x00, 0x00, 0x1E, 0x00, 0x00, /*"y",89*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFC, 0x00, + 0x38, 0x1C, 0x00, 0x30, 0x38, 0x00, 0x20, 0x30, 0x00, 0x20, 0x70, 0x00, 0x00, 0xE0, 0x00, 0x00, + 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x03, 0x80, 0x00, 0x03, 0x00, 0x00, 0x06, 0x02, 0x00, 0x0E, 0x02, + 0x00, 0x0C, 0x06, 0x00, 0x18, 0x04, 0x00, 0x38, 0x0C, 0x00, 0x3F, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"z",90*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x60, 0x00, 0x00, 0x80, 0x00, 0x00, 0x60, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"{",91*/ + + 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, /*"|",92*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"}",93*/ + + 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x23, 0x00, 0x00, 0x21, 0x80, 0x80, 0x40, 0xC0, 0x80, 0x40, + 0x61, 0x00, 0x00, 0x31, 0x00, 0x00, 0x1E, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, /*"~",94*/ +}; + +const esp_painter_basic_font_t esp_painter_basic_font_36 = { + .bitmap = bitmap, + .width = 18, + .height = 36, +}; + +#endif diff --git a/components/lua_modules/esp_painter/font/basic_font_40.c b/components/lua_modules/esp_painter/font/basic_font_40.c new file mode 100644 index 0000000..a9c5a5c --- /dev/null +++ b/components/lua_modules/esp_painter/font/basic_font_40.c @@ -0,0 +1,877 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "sdkconfig.h" + +#include "esp_painter_font.h" + +#if CONFIG_ESP_PAINTER_BASIC_FONT_40 + +static const uint8_t bitmap[] = +{ + 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, 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, + 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, /*" ",0*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, + 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x70, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xF0, 0x00, + 0x00, 0xF0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"!",1*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0x00, 0x01, 0xE7, 0x80, 0x01, 0xE7, 0x80, 0x03, + 0xCF, 0x00, 0x03, 0x8E, 0x00, 0x07, 0x1C, 0x00, 0x06, 0x18, 0x00, 0x0C, 0x30, 0x00, 0x18, 0x60, + 0x00, 0x10, 0x40, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, /*""",2*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, + 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x7F, 0xFF, 0xC0, 0x7F, 0xFF, 0xC0, 0x7F, 0xFF, 0xC0, + 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, 0x04, 0x04, 0x00, 0x04, 0x04, 0x00, 0x04, + 0x04, 0x00, 0x04, 0x04, 0x00, 0x04, 0x04, 0x00, 0x7F, 0xFF, 0xC0, 0x7F, 0xFF, 0xC0, 0x7F, 0xFF, + 0xC0, 0x0C, 0x0C, 0x00, 0x0C, 0x0C, 0x00, 0x0C, 0x0C, 0x00, 0x0C, 0x0C, 0x00, 0x0C, 0x0C, 0x00, + 0x0C, 0x0C, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"#",3*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0xFC, 0x00, 0x03, 0x22, 0x00, 0x06, 0x21, 0x00, 0x04, 0x21, + 0x80, 0x0C, 0x21, 0x80, 0x0C, 0x23, 0x80, 0x0C, 0x23, 0x80, 0x0E, 0x20, 0x00, 0x07, 0x20, 0x00, + 0x07, 0xA0, 0x00, 0x03, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x7C, 0x00, 0x00, + 0x3E, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x27, 0x00, 0x00, 0x23, 0x80, 0x00, 0x23, 0x80, 0x0C, 0x21, + 0x80, 0x1C, 0x21, 0x80, 0x1C, 0x21, 0x80, 0x18, 0x21, 0x80, 0x18, 0x21, 0x00, 0x08, 0x23, 0x00, + 0x06, 0x24, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"$",4*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3C, 0x01, 0x00, 0x66, 0x03, 0x00, 0x62, 0x02, 0x00, 0x42, 0x06, 0x00, 0xC3, 0x04, + 0x00, 0xC3, 0x0C, 0x00, 0xC3, 0x08, 0x00, 0xC3, 0x08, 0x00, 0xC3, 0x18, 0x00, 0xC3, 0x10, 0x00, + 0xC3, 0x30, 0x00, 0xC3, 0x20, 0x00, 0x66, 0x60, 0x00, 0x66, 0x47, 0x80, 0x3C, 0x44, 0xC0, 0x00, + 0x8C, 0xC0, 0x00, 0x88, 0x40, 0x01, 0x98, 0x60, 0x01, 0x18, 0x60, 0x03, 0x18, 0x60, 0x02, 0x18, + 0x60, 0x02, 0x18, 0x60, 0x04, 0x18, 0x60, 0x04, 0x18, 0x60, 0x0C, 0x08, 0x60, 0x08, 0x08, 0x40, + 0x18, 0x04, 0xC0, 0x10, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"%",5*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xC0, 0x00, 0x04, 0x60, 0x00, 0x08, 0x30, 0x00, 0x18, 0x30, 0x00, 0x18, 0x30, + 0x00, 0x18, 0x30, 0x00, 0x18, 0x30, 0x00, 0x18, 0x30, 0x00, 0x18, 0x60, 0x00, 0x1C, 0x60, 0x00, + 0x0C, 0xC0, 0x00, 0x0F, 0x00, 0x00, 0x0E, 0x1F, 0xC0, 0x1E, 0x07, 0x00, 0x36, 0x06, 0x00, 0x27, + 0x06, 0x00, 0x67, 0x06, 0x00, 0x43, 0x84, 0x00, 0xC3, 0x84, 0x00, 0xC1, 0xC4, 0x00, 0xC1, 0xCC, + 0x00, 0xC0, 0xE8, 0x00, 0xC0, 0x78, 0x00, 0xC0, 0x70, 0x00, 0x60, 0x38, 0x20, 0x60, 0x3C, 0x60, + 0x38, 0x4F, 0xC0, 0x0F, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"&",6*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x0F, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x30, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"'",7*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x00, + 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"(",8*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, + 0x00, 0x01, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, + 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*")",9*/ + + 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, 0xE0, 0x00, 0x00, 0xE0, + 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x70, 0xE1, 0xC0, 0x78, 0x43, 0xC0, 0x7C, 0x47, 0xC0, + 0x1E, 0x4F, 0x00, 0x07, 0x5C, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x07, 0x5C, 0x00, 0x1E, + 0x4F, 0x00, 0x7C, 0x47, 0xC0, 0x78, 0x43, 0xC0, 0x70, 0xE1, 0xC0, 0x00, 0xE0, 0x00, 0x00, 0xE0, + 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 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, /*"*",10*/ + + 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, 0x20, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x20, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 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, /*"+",11*/ + + 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, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x1F, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, /*",",12*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"-",13*/ + + 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, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x1F, 0x00, 0x00, + 0x1F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*".",14*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xC0, 0x00, + 0x00, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"/",15*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x03, 0x0C, 0x00, 0x06, 0x06, 0x00, 0x0C, 0x03, + 0x00, 0x0C, 0x01, 0x00, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x30, 0x00, 0xC0, + 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, + 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x18, 0x01, + 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x0C, 0x01, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x06, 0x00, + 0x03, 0x0C, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"0",16*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0xF0, 0x00, 0x07, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"1",17*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x06, 0x0E, 0x00, 0x1C, 0x03, 0x00, 0x18, 0x03, + 0x00, 0x38, 0x01, 0x80, 0x38, 0x01, 0x80, 0x3C, 0x01, 0x80, 0x3C, 0x01, 0x80, 0x1C, 0x01, 0x80, + 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, 0xC0, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x80, 0x0C, 0x00, 0x80, 0x18, 0x01, 0x80, 0x30, 0x03, 0x00, + 0x3F, 0xFF, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"2",18*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x0C, 0x1C, 0x00, 0x18, 0x06, 0x00, 0x30, 0x06, + 0x00, 0x38, 0x03, 0x00, 0x38, 0x03, 0x00, 0x38, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, + 0x80, 0x18, 0x01, 0x80, 0x3C, 0x01, 0x80, 0x3C, 0x01, 0x00, 0x38, 0x03, 0x00, 0x1C, 0x06, 0x00, + 0x0E, 0x0C, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"3",19*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x3C, + 0x00, 0x00, 0x2C, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x8C, 0x00, 0x01, 0x8C, 0x00, + 0x01, 0x0C, 0x00, 0x02, 0x0C, 0x00, 0x06, 0x0C, 0x00, 0x04, 0x0C, 0x00, 0x08, 0x0C, 0x00, 0x18, + 0x0C, 0x00, 0x10, 0x0C, 0x00, 0x20, 0x0C, 0x00, 0x60, 0x0C, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x0C, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"4",20*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x0F, 0xFF, 0x80, 0x08, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x11, 0xF8, 0x00, 0x16, 0x0C, 0x00, 0x1C, 0x06, 0x00, 0x18, 0x03, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x1C, 0x01, + 0x80, 0x3C, 0x01, 0x80, 0x3C, 0x01, 0x80, 0x38, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x06, 0x00, + 0x0E, 0x0C, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"5",21*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x01, 0x83, 0x00, 0x02, 0x03, 0x80, 0x04, 0x03, + 0x80, 0x08, 0x03, 0x80, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x30, 0xFC, 0x00, 0x33, 0x06, 0x00, 0x34, 0x03, 0x00, 0x3C, 0x01, 0x80, 0x38, + 0x01, 0x80, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, + 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x01, 0x80, 0x0C, 0x01, 0x80, 0x06, 0x03, 0x00, + 0x03, 0x06, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"6",22*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xC0, 0x0F, 0xFF, 0xC0, 0x0C, 0x00, 0x80, 0x18, 0x01, + 0x80, 0x10, 0x03, 0x00, 0x10, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x60, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, + 0x00, 0x01, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xE0, 0x00, + 0x01, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"7",23*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x07, 0x07, 0x00, 0x0C, 0x01, 0x80, 0x0C, 0x01, + 0x80, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x1C, 0x00, 0xC0, + 0x0E, 0x01, 0x80, 0x0F, 0x83, 0x00, 0x07, 0xE6, 0x00, 0x01, 0xF8, 0x00, 0x03, 0x7C, 0x00, 0x06, + 0x1E, 0x00, 0x0C, 0x07, 0x00, 0x18, 0x03, 0x80, 0x38, 0x01, 0xC0, 0x30, 0x01, 0xC0, 0x30, 0x00, + 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x18, 0x01, 0x80, 0x0C, 0x01, 0x00, + 0x06, 0x06, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"8",24*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x06, 0x04, 0x00, 0x0C, 0x02, 0x00, 0x18, 0x01, + 0x00, 0x18, 0x01, 0x80, 0x30, 0x00, 0x80, 0x30, 0x00, 0x80, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, + 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x18, 0x01, 0xC0, 0x18, 0x03, 0xC0, 0x0C, + 0x06, 0xC0, 0x06, 0x0C, 0xC0, 0x03, 0xF0, 0xC0, 0x00, 0x00, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, + 0x80, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x1C, 0x03, 0x00, 0x1C, 0x06, 0x00, 0x1C, 0x0C, 0x00, + 0x0C, 0x18, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"9",25*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, + 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x60, 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, 0x60, 0x00, 0x00, 0xF0, 0x00, + 0x00, 0xF0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*":",26*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 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, 0xF0, 0x00, + 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*";",27*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x00, + 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"<",28*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"=",29*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, + 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*">",30*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFC, 0x00, 0x03, 0x06, 0x00, 0x06, 0x01, 0x00, 0x0C, 0x01, 0x80, 0x08, 0x00, + 0xC0, 0x18, 0x00, 0xC0, 0x1C, 0x00, 0xC0, 0x1E, 0x00, 0xC0, 0x1E, 0x00, 0xC0, 0x0E, 0x00, 0xC0, + 0x00, 0x01, 0xC0, 0x00, 0x03, 0x80, 0x00, 0x07, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xF0, 0x00, + 0x00, 0xF0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"?",31*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7C, 0x00, 0x01, 0x83, 0x00, 0x03, 0x01, 0x80, 0x06, 0x00, 0x80, 0x0C, 0x00, + 0x40, 0x08, 0x1F, 0x40, 0x18, 0x67, 0x20, 0x18, 0x63, 0x20, 0x10, 0xC3, 0x20, 0x30, 0x86, 0x20, + 0x31, 0x86, 0x20, 0x31, 0x86, 0x20, 0x33, 0x06, 0x20, 0x33, 0x06, 0x20, 0x33, 0x06, 0x20, 0x33, + 0x0E, 0x20, 0x33, 0x0C, 0x40, 0x33, 0x0C, 0x40, 0x33, 0x1C, 0x40, 0x11, 0x14, 0x80, 0x18, 0xE7, + 0x00, 0x18, 0x00, 0x20, 0x08, 0x00, 0x40, 0x0C, 0x00, 0x40, 0x04, 0x00, 0x80, 0x02, 0x01, 0x00, + 0x01, 0x86, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"@",32*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xF0, + 0x00, 0x01, 0x30, 0x00, 0x01, 0x30, 0x00, 0x01, 0x30, 0x00, 0x03, 0x38, 0x00, 0x03, 0x38, 0x00, + 0x02, 0x18, 0x00, 0x02, 0x18, 0x00, 0x06, 0x18, 0x00, 0x06, 0x1C, 0x00, 0x04, 0x0C, 0x00, 0x04, + 0x0C, 0x00, 0x0C, 0x0C, 0x00, 0x0F, 0xFE, 0x00, 0x08, 0x06, 0x00, 0x08, 0x06, 0x00, 0x18, 0x06, + 0x00, 0x10, 0x07, 0x00, 0x10, 0x07, 0x00, 0x10, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x80, + 0x30, 0x03, 0x80, 0xFC, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"A",33*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x18, 0x07, 0x00, 0x18, 0x01, 0x80, 0x18, 0x01, + 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, + 0x18, 0x01, 0x80, 0x18, 0x03, 0x00, 0x18, 0x0E, 0x00, 0x1F, 0xF8, 0x00, 0x18, 0x06, 0x00, 0x18, + 0x01, 0x80, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0x60, 0x18, 0x00, 0x60, 0x18, 0x00, + 0x60, 0x18, 0x00, 0x60, 0x18, 0x00, 0x60, 0x18, 0x00, 0xE0, 0x18, 0x00, 0xC0, 0x18, 0x01, 0x80, + 0x18, 0x07, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"B",34*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x40, 0x03, 0x03, 0xC0, 0x06, 0x01, 0xC0, 0x0C, 0x00, + 0xC0, 0x18, 0x00, 0x40, 0x18, 0x00, 0x60, 0x30, 0x00, 0x20, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x30, 0x00, 0x20, 0x30, 0x00, 0x40, 0x18, 0x00, 0x40, 0x18, 0x00, 0x80, 0x0C, 0x01, 0x00, + 0x03, 0x06, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"C",35*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x18, 0x1C, 0x00, 0x18, 0x06, 0x00, 0x18, 0x03, + 0x00, 0x18, 0x01, 0x80, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0x60, + 0x18, 0x00, 0x60, 0x18, 0x00, 0x60, 0x18, 0x00, 0x60, 0x18, 0x00, 0x60, 0x18, 0x00, 0x60, 0x18, + 0x00, 0x60, 0x18, 0x00, 0x60, 0x18, 0x00, 0x60, 0x18, 0x00, 0x60, 0x18, 0x00, 0x40, 0x18, 0x00, + 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0x80, 0x18, 0x01, 0x80, 0x18, 0x03, 0x00, 0x18, 0x06, 0x00, + 0x18, 0x1C, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"D",36*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x80, 0x18, 0x03, 0xC0, 0x18, 0x01, 0xC0, 0x18, 0x00, + 0xC0, 0x18, 0x00, 0x60, 0x18, 0x00, 0x20, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x04, 0x00, + 0x18, 0x04, 0x00, 0x18, 0x04, 0x00, 0x18, 0x0C, 0x00, 0x1F, 0xFC, 0x00, 0x18, 0x0C, 0x00, 0x18, + 0x04, 0x00, 0x18, 0x04, 0x00, 0x18, 0x04, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x20, 0x18, 0x00, 0x60, 0x18, 0x00, 0x40, 0x18, 0x00, 0xC0, + 0x18, 0x03, 0xC0, 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"E",37*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x80, 0x18, 0x03, 0xC0, 0x18, 0x01, 0xC0, 0x18, 0x00, + 0xC0, 0x18, 0x00, 0x60, 0x18, 0x00, 0x20, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x02, 0x00, + 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, 0x06, 0x00, 0x1F, 0xFE, 0x00, 0x18, 0x06, 0x00, 0x18, + 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, 0x02, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x18, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"F",38*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0x00, 0x03, 0x0F, 0x00, 0x04, 0x03, 0x00, 0x0C, 0x03, + 0x00, 0x18, 0x01, 0x80, 0x10, 0x00, 0x80, 0x30, 0x00, 0x80, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x0F, 0xF0, 0x60, 0x01, 0x80, 0x60, 0x01, 0x80, 0x30, 0x01, 0x80, 0x30, 0x01, + 0x80, 0x30, 0x01, 0x80, 0x10, 0x01, 0x80, 0x18, 0x01, 0x80, 0x0C, 0x01, 0x80, 0x0C, 0x01, 0x80, + 0x07, 0x06, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"G",39*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x07, 0xE0, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, + 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, + 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x1F, 0xFF, 0x80, 0x18, 0x01, 0x80, 0x18, + 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, + 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, + 0x18, 0x01, 0x80, 0x7E, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"H",40*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"I",41*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xE0, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x70, 0x0C, 0x00, 0x70, 0x18, 0x00, 0x70, 0x10, 0x00, 0x30, + 0x60, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, /*"J",42*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x1F, 0xC0, 0x18, 0x07, 0x00, 0x18, 0x06, 0x00, 0x18, 0x04, + 0x00, 0x18, 0x08, 0x00, 0x18, 0x18, 0x00, 0x18, 0x30, 0x00, 0x18, 0x20, 0x00, 0x18, 0x40, 0x00, + 0x18, 0xC0, 0x00, 0x18, 0xC0, 0x00, 0x19, 0xC0, 0x00, 0x1A, 0xE0, 0x00, 0x1E, 0xE0, 0x00, 0x1C, + 0x70, 0x00, 0x18, 0x70, 0x00, 0x18, 0x38, 0x00, 0x18, 0x38, 0x00, 0x18, 0x1C, 0x00, 0x18, 0x1C, + 0x00, 0x18, 0x0E, 0x00, 0x18, 0x0E, 0x00, 0x18, 0x06, 0x00, 0x18, 0x07, 0x00, 0x18, 0x03, 0x00, + 0x18, 0x03, 0x80, 0x7E, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"K",43*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x20, 0x0C, 0x00, 0x20, 0x0C, 0x00, 0x40, 0x0C, 0x00, 0xC0, + 0x0C, 0x01, 0xC0, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"L",44*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x03, 0xE0, 0x38, 0x03, 0x80, 0x38, 0x03, 0x80, 0x38, 0x03, + 0x80, 0x3C, 0x07, 0x80, 0x2C, 0x05, 0x80, 0x2C, 0x05, 0x80, 0x2C, 0x05, 0x80, 0x2C, 0x05, 0x80, + 0x26, 0x09, 0x80, 0x26, 0x09, 0x80, 0x26, 0x09, 0x80, 0x26, 0x09, 0x80, 0x27, 0x11, 0x80, 0x23, + 0x11, 0x80, 0x23, 0x11, 0x80, 0x23, 0x11, 0x80, 0x23, 0x21, 0x80, 0x23, 0xA1, 0x80, 0x21, 0xA1, + 0x80, 0x21, 0xA1, 0x80, 0x21, 0xE1, 0x80, 0x21, 0xC1, 0x80, 0x20, 0xC1, 0x80, 0x20, 0xC1, 0x80, + 0x20, 0xC1, 0x80, 0xF8, 0x87, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"M",45*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x07, 0xF0, 0x1C, 0x00, 0x80, 0x1C, 0x00, 0x80, 0x16, 0x00, + 0x80, 0x16, 0x00, 0x80, 0x13, 0x00, 0x80, 0x13, 0x00, 0x80, 0x11, 0x80, 0x80, 0x11, 0x80, 0x80, + 0x10, 0xC0, 0x80, 0x10, 0xC0, 0x80, 0x10, 0x60, 0x80, 0x10, 0x60, 0x80, 0x10, 0x30, 0x80, 0x10, + 0x30, 0x80, 0x10, 0x38, 0x80, 0x10, 0x18, 0x80, 0x10, 0x1C, 0x80, 0x10, 0x0C, 0x80, 0x10, 0x0E, + 0x80, 0x10, 0x06, 0x80, 0x10, 0x07, 0x80, 0x10, 0x03, 0x80, 0x10, 0x03, 0x80, 0x10, 0x01, 0x80, + 0x10, 0x01, 0x80, 0xFE, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"N",46*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x03, 0x04, 0x00, 0x0C, 0x03, 0x00, 0x08, 0x01, + 0x00, 0x18, 0x01, 0x80, 0x30, 0x00, 0x80, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x20, 0x00, 0x40, + 0x60, 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, + 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00, 0x60, 0x20, 0x00, 0x40, 0x30, 0x00, + 0xC0, 0x30, 0x00, 0xC0, 0x10, 0x00, 0xC0, 0x18, 0x01, 0x80, 0x08, 0x01, 0x00, 0x04, 0x03, 0x00, + 0x03, 0x0C, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"O",47*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x18, 0x06, 0x00, 0x18, 0x03, 0x00, 0x18, 0x01, + 0x80, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, + 0x18, 0x00, 0xC0, 0x18, 0x01, 0x80, 0x18, 0x03, 0x00, 0x18, 0x0E, 0x00, 0x1F, 0xF8, 0x00, 0x18, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x18, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"P",48*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x07, 0x06, 0x00, 0x0C, 0x03, 0x00, 0x08, 0x01, + 0x00, 0x18, 0x00, 0x80, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x60, 0x00, 0x60, + 0x60, 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, + 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00, 0x60, 0x23, 0xE0, + 0x40, 0x37, 0xF0, 0xC0, 0x3E, 0x38, 0xC0, 0x1C, 0x1C, 0x80, 0x18, 0x1D, 0x80, 0x0C, 0x1F, 0x00, + 0x06, 0x0E, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x07, 0xC0, 0x00, 0x03, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Q",49*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x0C, 0x0E, 0x00, 0x0C, 0x03, 0x00, 0x0C, 0x03, + 0x80, 0x0C, 0x01, 0x80, 0x0C, 0x01, 0x80, 0x0C, 0x01, 0x80, 0x0C, 0x01, 0x80, 0x0C, 0x01, 0x80, + 0x0C, 0x03, 0x00, 0x0C, 0x03, 0x00, 0x0C, 0x0E, 0x00, 0x0F, 0xF8, 0x00, 0x0C, 0x30, 0x00, 0x0C, + 0x30, 0x00, 0x0C, 0x38, 0x00, 0x0C, 0x18, 0x00, 0x0C, 0x1C, 0x00, 0x0C, 0x1C, 0x00, 0x0C, 0x0C, + 0x00, 0x0C, 0x0E, 0x00, 0x0C, 0x06, 0x00, 0x0C, 0x07, 0x00, 0x0C, 0x07, 0x00, 0x0C, 0x03, 0x00, + 0x0C, 0x03, 0x80, 0x3F, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"R",50*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x06, 0x0F, 0x00, 0x08, 0x03, 0x80, 0x18, 0x03, + 0x80, 0x30, 0x01, 0x80, 0x30, 0x00, 0x80, 0x30, 0x00, 0x80, 0x30, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x07, 0x80, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x7C, 0x00, 0x00, + 0x1E, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x80, 0x00, 0x01, 0xC0, 0x00, 0x00, 0xC0, 0x20, 0x00, + 0xC0, 0x20, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x10, 0x00, 0xC0, 0x18, 0x01, 0x80, 0x1C, 0x01, 0x00, + 0x1F, 0x06, 0x00, 0x10, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"S",51*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x38, 0x60, 0xC0, 0x30, 0x60, 0x40, 0x20, 0x60, + 0x40, 0x60, 0x60, 0x20, 0x40, 0x60, 0x20, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"T",52*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x03, 0xE0, 0x18, 0x00, 0x80, 0x18, 0x00, 0x80, 0x18, 0x00, + 0x80, 0x18, 0x00, 0x80, 0x18, 0x00, 0x80, 0x18, 0x00, 0x80, 0x18, 0x00, 0x80, 0x18, 0x00, 0x80, + 0x18, 0x00, 0x80, 0x18, 0x00, 0x80, 0x18, 0x00, 0x80, 0x18, 0x00, 0x80, 0x18, 0x00, 0x80, 0x18, + 0x00, 0x80, 0x18, 0x00, 0x80, 0x18, 0x00, 0x80, 0x18, 0x00, 0x80, 0x18, 0x00, 0x80, 0x18, 0x00, + 0x80, 0x18, 0x00, 0x80, 0x18, 0x00, 0x80, 0x18, 0x00, 0x80, 0x08, 0x01, 0x00, 0x0C, 0x03, 0x00, + 0x06, 0x06, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"U",53*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x07, 0xE0, 0x1C, 0x01, 0x80, 0x1C, 0x01, 0x80, 0x0C, 0x01, + 0x00, 0x0C, 0x01, 0x00, 0x0E, 0x01, 0x00, 0x0E, 0x03, 0x00, 0x0E, 0x02, 0x00, 0x06, 0x02, 0x00, + 0x07, 0x02, 0x00, 0x07, 0x04, 0x00, 0x07, 0x04, 0x00, 0x03, 0x04, 0x00, 0x03, 0x04, 0x00, 0x03, + 0x88, 0x00, 0x03, 0x88, 0x00, 0x01, 0x88, 0x00, 0x01, 0x98, 0x00, 0x01, 0xD0, 0x00, 0x01, 0xD0, + 0x00, 0x00, 0xD0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"V",54*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xF9, 0xF0, 0x70, 0x60, 0x40, 0x30, 0x60, 0x40, 0x30, 0x60, + 0x40, 0x30, 0x70, 0x40, 0x30, 0x70, 0xC0, 0x38, 0x30, 0x80, 0x38, 0x70, 0x80, 0x18, 0x70, 0x80, + 0x18, 0x70, 0x80, 0x18, 0x70, 0x80, 0x18, 0xF9, 0x00, 0x18, 0xB9, 0x00, 0x1C, 0x99, 0x00, 0x0C, + 0x99, 0x00, 0x0C, 0x99, 0x00, 0x0D, 0x9B, 0x00, 0x0D, 0x1A, 0x00, 0x0D, 0x1E, 0x00, 0x0D, 0x0E, + 0x00, 0x0F, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x06, 0x0E, 0x00, 0x06, 0x0C, 0x00, 0x06, 0x0C, 0x00, + 0x06, 0x04, 0x00, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"W",55*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x0F, 0xC0, 0x1C, 0x03, 0x00, 0x0C, 0x03, 0x00, 0x0E, 0x02, + 0x00, 0x06, 0x06, 0x00, 0x07, 0x04, 0x00, 0x03, 0x0C, 0x00, 0x03, 0x88, 0x00, 0x01, 0x98, 0x00, + 0x01, 0xD0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x70, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xB8, 0x00, 0x01, 0x98, 0x00, 0x01, 0x1C, 0x00, 0x03, 0x0C, + 0x00, 0x02, 0x0E, 0x00, 0x06, 0x0E, 0x00, 0x04, 0x07, 0x00, 0x0C, 0x07, 0x00, 0x08, 0x03, 0x00, + 0x18, 0x03, 0x80, 0x7E, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"X",56*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x07, 0xE0, 0x1C, 0x01, 0x80, 0x1C, 0x01, 0x00, 0x0C, 0x01, + 0x00, 0x0E, 0x03, 0x00, 0x0E, 0x02, 0x00, 0x06, 0x06, 0x00, 0x07, 0x04, 0x00, 0x03, 0x04, 0x00, + 0x03, 0x08, 0x00, 0x01, 0x88, 0x00, 0x01, 0x98, 0x00, 0x01, 0xD0, 0x00, 0x00, 0xD0, 0x00, 0x00, + 0xE0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Y",57*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xC0, 0x1E, 0x01, 0x80, 0x18, 0x03, 0x80, 0x18, 0x03, + 0x00, 0x30, 0x07, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x60, 0x00, 0x00, 0xE0, 0x00, 0x00, + 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x40, 0x1C, 0x00, 0xC0, 0x18, 0x00, 0x80, 0x38, 0x01, 0x80, + 0x30, 0x07, 0x80, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Z",58*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"[",59*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"\",60*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x1F, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"]",61*/ + + 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x01, 0xF8, 0x00, 0x01, 0x9C, 0x00, 0x03, 0x0C, 0x00, 0x04, + 0x02, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"^",62*/ + + 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, 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, + 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, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, /*"_",63*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0x20, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"`",64*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xF8, 0x00, 0x0C, 0x06, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0xFB, 0x00, 0x07, 0x03, 0x00, 0x0C, 0x03, 0x00, 0x18, 0x03, + 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x20, 0x18, 0x07, 0x20, + 0x1C, 0x1B, 0x20, 0x07, 0xE1, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"a",65*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x78, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x18, 0x7C, 0x00, 0x19, 0x87, 0x00, 0x1A, 0x01, 0x00, 0x1C, 0x01, 0x80, 0x1C, 0x01, 0x80, 0x18, + 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, + 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x1C, 0x03, 0x00, + 0x1E, 0x06, 0x00, 0x11, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"b",66*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xF8, 0x00, 0x03, 0x06, 0x00, 0x0E, 0x02, 0x00, 0x0C, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, + 0x03, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x80, 0x18, 0x00, 0x80, 0x18, 0x01, 0x00, 0x0C, 0x03, 0x00, + 0x06, 0x06, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"c",67*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x0F, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, + 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, + 0x01, 0xF9, 0x80, 0x06, 0x0D, 0x80, 0x0C, 0x03, 0x80, 0x08, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, + 0x01, 0x80, 0x30, 0x01, 0x80, 0x30, 0x01, 0x80, 0x30, 0x01, 0x80, 0x30, 0x01, 0x80, 0x30, 0x01, + 0x80, 0x30, 0x01, 0x80, 0x30, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x03, 0x80, 0x0C, 0x07, 0x80, + 0x06, 0x0D, 0xE0, 0x01, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"d",68*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xF8, 0x00, 0x03, 0x06, 0x00, 0x06, 0x03, 0x00, 0x04, 0x01, 0x80, 0x0C, 0x00, 0x80, 0x08, + 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x1F, 0xFF, 0xC0, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x40, 0x0C, 0x00, 0x80, 0x06, 0x01, 0x80, + 0x03, 0x83, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"e",69*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x70, 0x40, 0x00, 0xC0, 0x60, 0x00, 0xC0, 0x60, 0x01, 0x80, + 0x60, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, + 0x3F, 0xFF, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, + 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, + 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, + 0x01, 0x80, 0x00, 0x1F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"f",70*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xF8, 0xE0, 0x06, 0x0F, 0xE0, 0x0C, 0x06, 0x60, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, + 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x0C, 0x00, 0x0D, 0xF8, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x0F, 0xFE, 0x00, 0x0C, 0x7F, 0x80, + 0x18, 0x01, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x18, 0x01, 0x80, 0x0E, + 0x03, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x00, 0x00, /*"g",71*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x78, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x18, 0x7C, 0x00, 0x19, 0x87, 0x00, 0x1E, 0x03, 0x00, 0x1C, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, + 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, + 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, + 0x18, 0x01, 0x80, 0x7E, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"h",72*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x0F, 0xE0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"i",73*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0xFE, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x18, 0x0C, 0x00, 0x18, 0x0C, 0x00, 0x1C, + 0x30, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, /*"j",74*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x3C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, + 0x0C, 0x1F, 0xC0, 0x0C, 0x06, 0x00, 0x0C, 0x04, 0x00, 0x0C, 0x08, 0x00, 0x0C, 0x18, 0x00, 0x0C, + 0x30, 0x00, 0x0C, 0x60, 0x00, 0x0C, 0xE0, 0x00, 0x0D, 0xB0, 0x00, 0x0F, 0x38, 0x00, 0x0E, 0x18, + 0x00, 0x0C, 0x1C, 0x00, 0x0C, 0x0E, 0x00, 0x0C, 0x06, 0x00, 0x0C, 0x07, 0x00, 0x0C, 0x03, 0x00, + 0x0C, 0x03, 0x80, 0x3F, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"k",75*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"l",76*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x73, 0xC7, 0x80, 0x3C, 0x78, 0xC0, 0x38, 0x70, 0xC0, 0x30, 0x60, 0xC0, 0x30, 0x60, 0xC0, 0x30, + 0x60, 0xC0, 0x30, 0x60, 0xC0, 0x30, 0x60, 0xC0, 0x30, 0x60, 0xC0, 0x30, 0x60, 0xC0, 0x30, 0x60, + 0xC0, 0x30, 0x60, 0xC0, 0x30, 0x60, 0xC0, 0x30, 0x60, 0xC0, 0x30, 0x60, 0xC0, 0x30, 0x60, 0xC0, + 0x30, 0x60, 0xC0, 0xFD, 0xFB, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"m",77*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x7C, 0x00, 0x79, 0x87, 0x00, 0x1E, 0x03, 0x00, 0x1C, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, + 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, + 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, + 0x18, 0x01, 0x80, 0x7E, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"n",78*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xF8, 0x00, 0x03, 0x0E, 0x00, 0x0C, 0x03, 0x00, 0x0C, 0x01, 0x00, 0x18, 0x01, 0x80, 0x18, + 0x00, 0x80, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, 0xC0, 0x30, 0x00, + 0xC0, 0x30, 0x00, 0xC0, 0x10, 0x00, 0x80, 0x18, 0x01, 0x80, 0x08, 0x01, 0x00, 0x0C, 0x03, 0x00, + 0x07, 0x0E, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"o",79*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0xF8, 0x00, 0x7B, 0x86, 0x00, 0x1E, 0x03, 0x00, 0x1C, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, + 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, + 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x1C, 0x03, 0x00, + 0x1B, 0x0E, 0x00, 0x19, 0xF8, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, /*"p",80*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xF1, 0x00, 0x06, 0x09, 0x00, 0x0C, 0x07, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x30, + 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, + 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x10, 0x03, 0x00, 0x18, 0x03, 0x00, 0x0C, 0x07, 0x00, + 0x06, 0x1B, 0x00, 0x03, 0xF3, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, /*"q",81*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x07, 0x80, 0x3F, 0x18, 0xC0, 0x03, 0x30, 0xC0, 0x03, 0x60, 0xC0, 0x03, 0xC0, 0x00, 0x03, + 0x80, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"r",82*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xF8, 0x00, 0x03, 0x07, 0x80, 0x04, 0x03, 0x80, 0x0C, 0x01, 0x80, 0x0C, 0x00, 0x80, 0x0C, + 0x00, 0x00, 0x0E, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x0F, + 0x00, 0x00, 0x03, 0x80, 0x10, 0x01, 0x80, 0x10, 0x01, 0x80, 0x18, 0x01, 0x80, 0x1C, 0x01, 0x00, + 0x1E, 0x07, 0x00, 0x11, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"s",83*/ + + 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, 0x80, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x03, 0x80, 0x00, + 0x3F, 0xFF, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, + 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, + 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x80, 0x01, 0x80, 0x80, 0x00, 0x81, 0x00, + 0x00, 0xC2, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"t",84*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, + 0x78, 0x0F, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, + 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, + 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x03, 0x00, 0x18, 0x07, 0x00, 0x0C, 0x07, 0x00, + 0x0E, 0x1B, 0xC0, 0x03, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"u",85*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0x0F, 0xC0, 0x1C, 0x03, 0x00, 0x0C, 0x03, 0x00, 0x0C, 0x02, 0x00, 0x0E, 0x06, 0x00, 0x06, + 0x04, 0x00, 0x06, 0x04, 0x00, 0x07, 0x0C, 0x00, 0x03, 0x08, 0x00, 0x03, 0x08, 0x00, 0x03, 0x98, + 0x00, 0x01, 0x90, 0x00, 0x01, 0x90, 0x00, 0x01, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"v",86*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFD, 0xF1, 0xF0, 0x70, 0x60, 0x40, 0x30, 0x60, 0x40, 0x30, 0x60, 0x80, 0x38, 0x70, 0x80, 0x18, + 0x70, 0x80, 0x18, 0x71, 0x80, 0x18, 0xB1, 0x00, 0x1C, 0xB9, 0x00, 0x0C, 0x99, 0x00, 0x0C, 0x9B, + 0x00, 0x0D, 0x1A, 0x00, 0x0F, 0x1A, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x06, 0x0C, 0x00, + 0x06, 0x0C, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"w",87*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0x9F, 0x80, 0x0E, 0x06, 0x00, 0x06, 0x04, 0x00, 0x07, 0x0C, 0x00, 0x03, 0x88, 0x00, 0x01, + 0x90, 0x00, 0x01, 0xF0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xB0, + 0x00, 0x01, 0x38, 0x00, 0x03, 0x18, 0x00, 0x02, 0x0C, 0x00, 0x04, 0x0E, 0x00, 0x0C, 0x06, 0x00, + 0x1C, 0x07, 0x00, 0x7E, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"x",88*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0x8F, 0xE0, 0x0E, 0x03, 0x80, 0x06, 0x01, 0x00, 0x06, 0x03, 0x00, 0x07, 0x02, 0x00, 0x03, + 0x06, 0x00, 0x03, 0x06, 0x00, 0x01, 0x84, 0x00, 0x01, 0x8C, 0x00, 0x01, 0x88, 0x00, 0x00, 0xC8, + 0x00, 0x00, 0xD8, 0x00, 0x00, 0x50, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x1C, 0x80, 0x00, 0x1F, + 0x80, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, /*"y",89*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0x00, 0x1C, 0x07, 0x00, 0x18, 0x0E, 0x00, 0x18, 0x0C, 0x00, 0x10, 0x1C, 0x00, 0x10, + 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xC0, + 0x00, 0x01, 0x80, 0x00, 0x03, 0x80, 0x80, 0x07, 0x00, 0x80, 0x06, 0x01, 0x80, 0x0E, 0x01, 0x00, + 0x1C, 0x03, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"z",90*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"{",91*/ + + 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, /*"|",92*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC0, 0x00, 0x01, + 0x80, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"}",93*/ + + 0x07, 0x80, 0x00, 0x19, 0xC0, 0x00, 0x10, 0xE0, 0x20, 0x20, 0x70, 0x20, 0x20, 0x38, 0x40, 0x00, + 0x1C, 0x80, 0x00, 0x07, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"~",94*/ +}; + +const esp_painter_basic_font_t esp_painter_basic_font_40 = { + .bitmap = bitmap, + .width = 20, + .height = 40, +}; + +#endif diff --git a/components/lua_modules/esp_painter/font/basic_font_44.c b/components/lua_modules/esp_painter/font/basic_font_44.c new file mode 100644 index 0000000..b920348 --- /dev/null +++ b/components/lua_modules/esp_painter/font/basic_font_44.c @@ -0,0 +1,972 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "sdkconfig.h" + +#include "esp_painter_font.h" + +#if CONFIG_ESP_PAINTER_BASIC_FONT_44 + +static const uint8_t bitmap[] = +{ + 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, 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, + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*" ",0*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"!",1*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x80, 0x01, 0xE3, 0xC0, 0x01, + 0xE3, 0xC0, 0x03, 0xC7, 0x80, 0x03, 0x87, 0x00, 0x07, 0x8F, 0x00, 0x07, 0x0E, 0x00, 0x0E, 0x1C, + 0x00, 0x0C, 0x18, 0x00, 0x18, 0x30, 0x00, 0x10, 0x20, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*""",2*/ + + 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, 0x80, 0xC0, 0x01, 0x00, 0x80, 0x01, 0x00, + 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0x80, 0x3F, 0xFF, 0xF0, + 0x3F, 0xFF, 0xF0, 0x3F, 0xFF, 0xF0, 0x3F, 0xFF, 0xF0, 0x03, 0x01, 0x80, 0x03, 0x01, 0x80, 0x03, + 0x01, 0x80, 0x03, 0x01, 0x80, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, + 0x00, 0x3F, 0xFF, 0xF0, 0x3F, 0xFF, 0xF0, 0x3F, 0xFF, 0xF0, 0x3F, 0xFF, 0xF0, 0x06, 0x03, 0x00, + 0x06, 0x03, 0x00, 0x06, 0x03, 0x00, 0x06, 0x03, 0x00, 0x06, 0x03, 0x00, 0x06, 0x03, 0x00, 0x06, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"#",3*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xB3, 0x00, 0x03, 0x31, + 0x80, 0x06, 0x31, 0xC0, 0x0E, 0x31, 0xC0, 0x0E, 0x33, 0xC0, 0x0E, 0x33, 0xC0, 0x0E, 0x33, 0x80, + 0x0F, 0x30, 0x00, 0x07, 0x30, 0x00, 0x07, 0xB0, 0x00, 0x03, 0xF0, 0x00, 0x01, 0xF0, 0x00, 0x00, + 0xF8, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x37, 0x80, 0x00, 0x33, + 0x80, 0x00, 0x33, 0xC0, 0x00, 0x31, 0xC0, 0x0E, 0x31, 0xC0, 0x1E, 0x31, 0xC0, 0x1E, 0x31, 0xC0, + 0x1E, 0x31, 0xC0, 0x1C, 0x31, 0x80, 0x0C, 0x31, 0x80, 0x0C, 0x33, 0x00, 0x07, 0x36, 0x00, 0x01, + 0xFC, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"$",4*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x80, 0x11, 0x01, 0x80, 0x31, 0x81, + 0x00, 0x20, 0x83, 0x00, 0x60, 0xC2, 0x00, 0x60, 0xC2, 0x00, 0x60, 0xC6, 0x00, 0x60, 0xC4, 0x00, + 0x60, 0xCC, 0x00, 0x60, 0xC8, 0x00, 0x60, 0xC8, 0x00, 0x60, 0xD8, 0x00, 0x20, 0x90, 0x00, 0x31, + 0xB0, 0x00, 0x11, 0xA1, 0xC0, 0x0E, 0x22, 0x20, 0x00, 0x46, 0x30, 0x00, 0x44, 0x10, 0x00, 0xCC, + 0x18, 0x00, 0x8C, 0x18, 0x00, 0x8C, 0x18, 0x01, 0x0C, 0x18, 0x01, 0x0C, 0x18, 0x03, 0x0C, 0x18, + 0x02, 0x0C, 0x18, 0x02, 0x0C, 0x18, 0x04, 0x04, 0x10, 0x04, 0x06, 0x30, 0x0C, 0x02, 0x20, 0x08, + 0x01, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"%",5*/ + + 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, 0xF0, 0x00, 0x03, 0x38, 0x00, 0x06, 0x18, + 0x00, 0x0E, 0x1C, 0x00, 0x0E, 0x1C, 0x00, 0x0E, 0x1C, 0x00, 0x0E, 0x1C, 0x00, 0x0E, 0x1C, 0x00, + 0x0E, 0x18, 0x00, 0x0E, 0x38, 0x00, 0x0F, 0x30, 0x00, 0x07, 0x60, 0x00, 0x07, 0xC0, 0x00, 0x07, + 0x87, 0xF0, 0x0F, 0x81, 0xC0, 0x1B, 0x81, 0x80, 0x1B, 0xC1, 0x80, 0x31, 0xC1, 0x80, 0x31, 0xC1, + 0x80, 0x70, 0xE1, 0x00, 0x70, 0xE1, 0x00, 0x70, 0x73, 0x00, 0x70, 0x7A, 0x00, 0x70, 0x3A, 0x00, + 0x70, 0x3C, 0x00, 0x38, 0x1E, 0x08, 0x38, 0x1E, 0x18, 0x1E, 0x37, 0x10, 0x0F, 0xE3, 0xF0, 0x07, + 0xC1, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"&",6*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x1F, + 0x00, 0x00, 0x1F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x07, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 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, + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"'",7*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, + 0x00, 0xC0, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"(",8*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, + 0x00, 0x01, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0xC0, 0x00, + 0x00, 0xC0, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*")",9*/ + + 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, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, + 0x70, 0x70, 0x70, 0x78, 0x20, 0xF0, 0x7E, 0x23, 0xF0, 0x1F, 0x27, 0xC0, 0x03, 0xAE, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x70, 0x00, 0x03, 0xAE, 0x00, 0x1F, 0x27, 0xC0, 0x7E, 0x23, 0xF0, 0x78, 0x20, + 0xF0, 0x70, 0x70, 0x70, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, + 0x00, 0x70, 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, /*"*",10*/ + + 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, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x7F, + 0xFF, 0xF8, 0x7F, 0xFF, 0xF8, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x30, 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, /*"+",11*/ + + 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, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, /*",",12*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xF0, 0x7F, 0xFF, 0xF0, 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, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"-",13*/ + + 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, 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, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x0E, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*".",14*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0xC0, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"/",15*/ + + 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, 0xFC, 0x00, 0x01, 0x86, 0x00, 0x03, 0x03, + 0x00, 0x06, 0x01, 0x80, 0x0E, 0x01, 0xC0, 0x0C, 0x00, 0xC0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, + 0x1C, 0x00, 0x60, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, + 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, + 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x1C, 0x00, 0x60, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, + 0x0C, 0x00, 0xC0, 0x0E, 0x01, 0xC0, 0x06, 0x01, 0x80, 0x03, 0x03, 0x00, 0x01, 0x86, 0x00, 0x00, + 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"0",16*/ + + 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, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, + 0x00, 0x07, 0xF8, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x7C, 0x00, 0x07, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"1",17*/ + + 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, 0xFC, 0x00, 0x03, 0x07, 0x00, 0x04, 0x03, + 0x80, 0x08, 0x01, 0xC0, 0x08, 0x00, 0xE0, 0x18, 0x00, 0xE0, 0x18, 0x00, 0xE0, 0x1C, 0x00, 0xE0, + 0x1C, 0x00, 0xE0, 0x0C, 0x00, 0xE0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x03, 0x80, 0x00, + 0x03, 0x80, 0x00, 0x07, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x70, + 0x00, 0x00, 0xE0, 0x00, 0x01, 0xC0, 0x00, 0x03, 0x80, 0x00, 0x07, 0x00, 0x20, 0x06, 0x00, 0x20, + 0x0C, 0x00, 0x60, 0x18, 0x00, 0x60, 0x30, 0x00, 0xC0, 0x3F, 0xFF, 0xC0, 0x3F, 0xFF, 0xC0, 0x3F, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"2",18*/ + + 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, 0xFC, 0x00, 0x03, 0x0E, 0x00, 0x06, 0x03, + 0x00, 0x0C, 0x03, 0x80, 0x0C, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x06, 0x01, 0xC0, + 0x00, 0x01, 0xC0, 0x00, 0x01, 0x80, 0x00, 0x03, 0x80, 0x00, 0x07, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x03, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0xC0, 0x00, 0x00, + 0xC0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x0C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, + 0x1C, 0x00, 0xC0, 0x1C, 0x01, 0xC0, 0x08, 0x01, 0x80, 0x0C, 0x03, 0x80, 0x06, 0x0F, 0x00, 0x01, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"3",19*/ + + 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, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x0F, 0x00, 0x00, 0x17, 0x00, 0x00, 0x17, 0x00, 0x00, 0x27, 0x00, 0x00, 0x27, 0x00, + 0x00, 0x47, 0x00, 0x00, 0xC7, 0x00, 0x00, 0x87, 0x00, 0x01, 0x07, 0x00, 0x01, 0x07, 0x00, 0x02, + 0x07, 0x00, 0x06, 0x07, 0x00, 0x04, 0x07, 0x00, 0x0C, 0x07, 0x00, 0x08, 0x07, 0x00, 0x10, 0x07, + 0x00, 0x30, 0x07, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x0F, 0x80, 0x00, + 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"4",20*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x07, 0xFF, 0xE0, 0x07, 0xFF, + 0xE0, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0C, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x7C, 0x00, 0x0D, 0xFF, 0x00, 0x0B, 0x07, 0x80, 0x0A, + 0x03, 0xC0, 0x0C, 0x01, 0xC0, 0x0C, 0x01, 0xC0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, + 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x0C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, + 0x1C, 0x01, 0xC0, 0x18, 0x01, 0xC0, 0x08, 0x01, 0x80, 0x04, 0x03, 0x80, 0x02, 0x07, 0x00, 0x01, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"5",21*/ + + 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, 0x3E, 0x00, 0x00, 0xC1, 0x80, 0x03, 0x01, + 0x80, 0x06, 0x01, 0xC0, 0x06, 0x01, 0xC0, 0x0C, 0x01, 0xC0, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x7E, 0x00, 0x39, 0xFF, 0x80, 0x3B, + 0x83, 0xC0, 0x3B, 0x01, 0xE0, 0x3E, 0x00, 0xE0, 0x3C, 0x00, 0xE0, 0x38, 0x00, 0x70, 0x38, 0x00, + 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x18, 0x00, 0x70, 0x1C, 0x00, 0x70, + 0x1C, 0x00, 0x60, 0x0C, 0x00, 0xE0, 0x0E, 0x00, 0xC0, 0x07, 0x01, 0x80, 0x03, 0x83, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"6",22*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x0F, 0xFF, 0xE0, 0x0F, 0xFF, + 0xC0, 0x0C, 0x00, 0xC0, 0x08, 0x00, 0x80, 0x18, 0x01, 0x00, 0x10, 0x01, 0x00, 0x10, 0x02, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0xE0, 0x00, + 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"7",23*/ + + 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, 0xFC, 0x00, 0x03, 0x87, 0x00, 0x06, 0x01, + 0x80, 0x0E, 0x01, 0xC0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, + 0x1E, 0x00, 0xE0, 0x1E, 0x00, 0xC0, 0x0F, 0x01, 0xC0, 0x0F, 0x81, 0x80, 0x07, 0xE3, 0x00, 0x01, + 0xFE, 0x00, 0x01, 0xFC, 0x00, 0x07, 0x3F, 0x00, 0x0E, 0x0F, 0x80, 0x0C, 0x07, 0x80, 0x1C, 0x03, + 0xC0, 0x38, 0x01, 0xE0, 0x38, 0x01, 0xE0, 0x38, 0x00, 0xE0, 0x38, 0x00, 0xE0, 0x38, 0x00, 0xE0, + 0x38, 0x00, 0xE0, 0x18, 0x00, 0xC0, 0x1C, 0x01, 0xC0, 0x0E, 0x01, 0x80, 0x07, 0x07, 0x00, 0x01, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"8",24*/ + + 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, 0xFC, 0x00, 0x03, 0x07, 0x00, 0x06, 0x01, + 0x80, 0x0C, 0x00, 0xC0, 0x1C, 0x00, 0xC0, 0x18, 0x00, 0xE0, 0x38, 0x00, 0x60, 0x38, 0x00, 0x60, + 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0xF0, 0x3C, + 0x00, 0xF0, 0x1C, 0x01, 0xF0, 0x1E, 0x03, 0x70, 0x0F, 0x06, 0x70, 0x07, 0xFC, 0x70, 0x01, 0xF8, + 0x70, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xC0, + 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0x80, 0x0E, 0x03, 0x00, 0x0E, 0x07, 0x00, 0x06, 0x0C, 0x00, 0x01, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"9",25*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00, + 0x70, 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, 0x70, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*":",26*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x78, 0x00, 0x00, 0x78, 0x00, 0x00, + 0x78, 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, 0x78, 0x00, 0x00, 0x78, 0x00, 0x00, 0x78, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x00, /*";",27*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x60, 0x00, 0x00, 0xC0, 0x00, 0x01, + 0x80, 0x00, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x60, 0x00, 0x00, 0xC0, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, + 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"<",28*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x7F, 0xFF, + 0xF0, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"=",29*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0xC0, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, 0xC0, 0x00, + 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*">",30*/ + + 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, 0xFE, 0x00, 0x03, 0xFF, 0x80, 0x07, 0x03, + 0xC0, 0x0C, 0x00, 0xE0, 0x18, 0x00, 0xE0, 0x30, 0x00, 0x70, 0x30, 0x00, 0x70, 0x38, 0x00, 0x70, + 0x3C, 0x00, 0x70, 0x3C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xC0, 0x00, + 0x03, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"?",31*/ + + 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, 0x3E, 0x00, 0x00, 0xC1, 0x80, 0x03, 0x80, + 0xC0, 0x03, 0x00, 0x60, 0x06, 0x00, 0x30, 0x0C, 0x0D, 0xB0, 0x0C, 0x1B, 0xB0, 0x1C, 0x33, 0x98, + 0x1C, 0x73, 0x18, 0x18, 0x63, 0x18, 0x38, 0xE3, 0x18, 0x38, 0xE3, 0x18, 0x38, 0xC3, 0x18, 0x39, + 0xC3, 0x18, 0x39, 0xC3, 0x18, 0x39, 0xC2, 0x18, 0x39, 0xC6, 0x18, 0x39, 0xC6, 0x30, 0x39, 0xC6, + 0x30, 0x39, 0xC6, 0x30, 0x19, 0xCE, 0x60, 0x1C, 0xF7, 0xC0, 0x1C, 0x63, 0x80, 0x0C, 0x00, 0x08, + 0x0E, 0x00, 0x10, 0x07, 0x00, 0x30, 0x07, 0x00, 0x60, 0x03, 0xC1, 0xC0, 0x01, 0xFF, 0x80, 0x00, + 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"@",32*/ + + 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, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, + 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x98, 0x00, 0x00, 0x98, 0x00, 0x01, 0x9C, 0x00, + 0x01, 0x9C, 0x00, 0x01, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0x03, 0x0E, 0x00, 0x03, 0x0E, 0x00, 0x02, + 0x06, 0x00, 0x02, 0x06, 0x00, 0x06, 0x07, 0x00, 0x06, 0x07, 0x00, 0x04, 0x07, 0x00, 0x07, 0xFF, + 0x00, 0x0C, 0x03, 0x80, 0x0C, 0x03, 0x80, 0x08, 0x03, 0x80, 0x08, 0x01, 0x80, 0x18, 0x01, 0xC0, + 0x18, 0x01, 0xC0, 0x10, 0x01, 0xC0, 0x10, 0x01, 0xC0, 0x30, 0x00, 0xE0, 0x38, 0x01, 0xE0, 0xFC, + 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"A",33*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x0E, 0x07, 0x80, 0x0E, 0x01, + 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, + 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x01, 0xC0, 0x0E, 0x03, 0x80, 0x0E, 0x07, 0x00, 0x0F, + 0xFC, 0x00, 0x0E, 0x03, 0x00, 0x0E, 0x01, 0xC0, 0x0E, 0x00, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, + 0x60, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, + 0x0E, 0x00, 0x70, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x01, 0xC0, 0x0E, 0x03, 0x80, 0x7F, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"B",34*/ + + 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, 0x7E, 0x20, 0x01, 0x83, 0xE0, 0x03, 0x00, + 0xE0, 0x06, 0x00, 0x60, 0x0C, 0x00, 0x60, 0x1C, 0x00, 0x30, 0x18, 0x00, 0x30, 0x38, 0x00, 0x10, + 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, + 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x38, 0x00, 0x10, 0x38, 0x00, 0x10, 0x38, 0x00, 0x20, + 0x1C, 0x00, 0x20, 0x1C, 0x00, 0x40, 0x0E, 0x00, 0xC0, 0x07, 0x83, 0x80, 0x03, 0xFF, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"C",35*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF0, 0x00, 0x0E, 0x0C, 0x00, 0x0E, 0x03, + 0x00, 0x0E, 0x01, 0x80, 0x0E, 0x01, 0xC0, 0x0E, 0x00, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, + 0x0E, 0x00, 0x60, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, + 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, + 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x60, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, + 0x0E, 0x00, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x03, 0x80, 0x0E, 0x07, 0x00, 0x0E, 0x1C, 0x00, 0x7F, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"D",36*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x0E, 0x01, 0xE0, 0x0E, 0x00, + 0x60, 0x0E, 0x00, 0x20, 0x0E, 0x00, 0x30, 0x0E, 0x00, 0x10, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x01, 0x00, 0x0E, 0x01, 0x00, 0x0E, 0x01, 0x00, 0x0E, 0x03, 0x00, 0x0F, + 0xFF, 0x00, 0x0E, 0x03, 0x00, 0x0E, 0x03, 0x00, 0x0E, 0x01, 0x00, 0x0E, 0x01, 0x00, 0x0E, 0x01, + 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x08, + 0x0E, 0x00, 0x08, 0x0E, 0x00, 0x10, 0x0E, 0x00, 0x30, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0xF0, 0x7F, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"E",37*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x0E, 0x01, 0xE0, 0x0E, 0x00, + 0x70, 0x0E, 0x00, 0x30, 0x0E, 0x00, 0x10, 0x0E, 0x00, 0x18, 0x0E, 0x00, 0x08, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x80, 0x0E, 0x00, 0x80, 0x0E, 0x00, 0x80, 0x0E, + 0x01, 0x80, 0x0F, 0xFF, 0x80, 0x0E, 0x01, 0x80, 0x0E, 0x01, 0x80, 0x0E, 0x00, 0x80, 0x0E, 0x00, + 0x80, 0x0E, 0x00, 0x80, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x7F, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"F",38*/ + + 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, 0xF8, 0x80, 0x03, 0x87, 0x80, 0x07, 0x03, + 0x80, 0x0E, 0x01, 0x80, 0x0C, 0x00, 0x80, 0x1C, 0x00, 0xC0, 0x18, 0x00, 0x40, 0x38, 0x00, 0x40, + 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x0F, 0xF8, 0x70, 0x03, + 0xC0, 0x70, 0x01, 0xC0, 0x30, 0x01, 0xC0, 0x38, 0x01, 0xC0, 0x38, 0x01, 0xC0, 0x38, 0x01, 0xC0, + 0x1C, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x0C, 0x01, 0xC0, 0x06, 0x03, 0xC0, 0x03, 0x86, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"G",39*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x03, 0xF8, 0x1C, 0x00, 0xE0, 0x1C, 0x00, + 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, + 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, + 0x00, 0xE0, 0x1F, 0xFF, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, + 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, + 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x7F, + 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"H",40*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x38, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x0F, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"I",41*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x0E, 0x00, 0x00, 0x0E, + 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, + 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x18, 0x0E, 0x00, 0x3C, 0x0C, 0x00, 0x3C, 0x1C, 0x00, 0x3C, 0x18, 0x00, 0x1C, 0x30, + 0x00, 0x0F, 0xC0, 0x00, /*"J",42*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC7, 0xF0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, + 0x80, 0x0E, 0x03, 0x00, 0x0E, 0x02, 0x00, 0x0E, 0x06, 0x00, 0x0E, 0x04, 0x00, 0x0E, 0x08, 0x00, + 0x0E, 0x18, 0x00, 0x0E, 0x10, 0x00, 0x0E, 0x20, 0x00, 0x0E, 0x20, 0x00, 0x0E, 0x70, 0x00, 0x0E, + 0xF0, 0x00, 0x0E, 0xB8, 0x00, 0x0F, 0x38, 0x00, 0x0F, 0x1C, 0x00, 0x0E, 0x1C, 0x00, 0x0E, 0x0C, + 0x00, 0x0E, 0x0E, 0x00, 0x0E, 0x06, 0x00, 0x0E, 0x07, 0x00, 0x0E, 0x07, 0x00, 0x0E, 0x03, 0x80, + 0x0E, 0x03, 0x80, 0x0E, 0x01, 0x80, 0x0E, 0x01, 0xC0, 0x0E, 0x00, 0xC0, 0x0E, 0x00, 0xE0, 0x7F, + 0xC3, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"K",43*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, + 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x08, + 0x0E, 0x00, 0x08, 0x0E, 0x00, 0x10, 0x0E, 0x00, 0x30, 0x0E, 0x00, 0x30, 0x0E, 0x00, 0xF0, 0x7F, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"L",44*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x01, 0xF8, 0x1C, 0x01, 0xE0, 0x1C, 0x01, + 0xE0, 0x1C, 0x01, 0xE0, 0x1E, 0x01, 0xE0, 0x1E, 0x02, 0xE0, 0x1E, 0x02, 0xE0, 0x1E, 0x02, 0xE0, + 0x16, 0x02, 0xE0, 0x17, 0x06, 0xE0, 0x17, 0x04, 0xE0, 0x17, 0x04, 0xE0, 0x17, 0x04, 0xE0, 0x13, + 0x0C, 0xE0, 0x13, 0x88, 0xE0, 0x13, 0x88, 0xE0, 0x13, 0x88, 0xE0, 0x11, 0x88, 0xE0, 0x11, 0x98, + 0xE0, 0x11, 0xD0, 0xE0, 0x11, 0xD0, 0xE0, 0x11, 0xD0, 0xE0, 0x10, 0xF0, 0xE0, 0x10, 0xF0, 0xE0, + 0x10, 0xE0, 0xE0, 0x10, 0xE0, 0xE0, 0x10, 0x60, 0xE0, 0x10, 0x60, 0xE0, 0x10, 0x60, 0xE0, 0x7C, + 0x43, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"M",45*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0xFC, 0x1C, 0x00, 0x20, 0x1E, 0x00, + 0x20, 0x1E, 0x00, 0x20, 0x1F, 0x00, 0x20, 0x17, 0x00, 0x20, 0x17, 0x80, 0x20, 0x13, 0x80, 0x20, + 0x13, 0xC0, 0x20, 0x11, 0xE0, 0x20, 0x10, 0xE0, 0x20, 0x10, 0xF0, 0x20, 0x10, 0x70, 0x20, 0x10, + 0x78, 0x20, 0x10, 0x38, 0x20, 0x10, 0x3C, 0x20, 0x10, 0x1C, 0x20, 0x10, 0x1E, 0x20, 0x10, 0x0E, + 0x20, 0x10, 0x0F, 0x20, 0x10, 0x07, 0x20, 0x10, 0x07, 0xA0, 0x10, 0x03, 0xE0, 0x10, 0x01, 0xE0, + 0x10, 0x01, 0xE0, 0x10, 0x00, 0xE0, 0x10, 0x00, 0xE0, 0x10, 0x00, 0x60, 0x10, 0x00, 0x60, 0xFE, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"N",46*/ + + 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, 0x7C, 0x00, 0x01, 0x83, 0x00, 0x03, 0x01, + 0x80, 0x06, 0x00, 0xC0, 0x0E, 0x00, 0xE0, 0x0C, 0x00, 0x60, 0x1C, 0x00, 0x60, 0x1C, 0x00, 0x70, + 0x18, 0x00, 0x30, 0x18, 0x00, 0x30, 0x38, 0x00, 0x38, 0x38, 0x00, 0x38, 0x38, 0x00, 0x38, 0x38, + 0x00, 0x38, 0x38, 0x00, 0x38, 0x38, 0x00, 0x38, 0x38, 0x00, 0x38, 0x38, 0x00, 0x38, 0x38, 0x00, + 0x38, 0x38, 0x00, 0x38, 0x18, 0x00, 0x30, 0x1C, 0x00, 0x30, 0x1C, 0x00, 0x70, 0x0C, 0x00, 0x70, + 0x0C, 0x00, 0x60, 0x06, 0x00, 0xE0, 0x06, 0x00, 0xC0, 0x03, 0x01, 0x80, 0x01, 0x83, 0x00, 0x00, + 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"O",47*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x0E, 0x03, 0x80, 0x0E, 0x01, + 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x60, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, + 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, + 0x01, 0xC0, 0x0E, 0x07, 0x80, 0x0F, 0xFE, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x7F, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"P",48*/ + + 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, 0xFC, 0x00, 0x03, 0x83, 0x00, 0x06, 0x01, + 0x80, 0x0E, 0x00, 0xC0, 0x1C, 0x00, 0xE0, 0x18, 0x00, 0x60, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, + 0x38, 0x00, 0x30, 0x30, 0x00, 0x30, 0x70, 0x00, 0x38, 0x70, 0x00, 0x38, 0x70, 0x00, 0x38, 0x70, + 0x00, 0x38, 0x70, 0x00, 0x38, 0x70, 0x00, 0x38, 0x70, 0x00, 0x38, 0x70, 0x00, 0x38, 0x70, 0x00, + 0x38, 0x70, 0x00, 0x38, 0x70, 0x00, 0x38, 0x31, 0xF0, 0x30, 0x3B, 0xF8, 0x70, 0x3B, 0x1C, 0x70, + 0x1E, 0x0C, 0x60, 0x1C, 0x0E, 0x60, 0x0E, 0x0E, 0xC0, 0x06, 0x07, 0x80, 0x03, 0x87, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x07, 0x90, 0x00, 0x03, 0xF0, 0x00, 0x03, 0xE0, 0x00, 0x01, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"Q",49*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x0E, 0x07, 0x80, 0x0E, 0x03, + 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, + 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x03, 0x80, 0x0E, + 0x07, 0x00, 0x0F, 0xFC, 0x00, 0x0E, 0x18, 0x00, 0x0E, 0x1C, 0x00, 0x0E, 0x0C, 0x00, 0x0E, 0x0E, + 0x00, 0x0E, 0x0E, 0x00, 0x0E, 0x06, 0x00, 0x0E, 0x07, 0x00, 0x0E, 0x07, 0x00, 0x0E, 0x03, 0x80, + 0x0E, 0x03, 0x80, 0x0E, 0x01, 0x80, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x00, 0xE0, 0x7F, + 0xC0, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"R",50*/ + + 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, 0xFC, 0x00, 0x07, 0x07, 0x80, 0x0C, 0x03, + 0xC0, 0x1C, 0x01, 0xC0, 0x18, 0x00, 0xC0, 0x38, 0x00, 0xC0, 0x38, 0x00, 0x40, 0x38, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x0F, 0xE0, 0x00, 0x07, + 0xF8, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x07, 0xC0, 0x00, 0x03, + 0xC0, 0x00, 0x01, 0xE0, 0x00, 0x00, 0xE0, 0x20, 0x00, 0xE0, 0x20, 0x00, 0xE0, 0x30, 0x00, 0xE0, + 0x10, 0x00, 0xE0, 0x18, 0x00, 0xC0, 0x18, 0x01, 0xC0, 0x1C, 0x03, 0x80, 0x1F, 0x07, 0x00, 0x10, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"S",51*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x38, 0x70, 0xE0, 0x30, 0x70, + 0x60, 0x20, 0x70, 0x20, 0x20, 0x70, 0x30, 0x60, 0x70, 0x10, 0x40, 0x70, 0x10, 0x00, 0x70, 0x00, + 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, + 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x03, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"T",52*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x03, 0xF8, 0x1C, 0x00, 0x40, 0x1C, 0x00, + 0x40, 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x40, + 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x40, 0x1C, + 0x00, 0x40, 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x40, 0x1C, 0x00, + 0x40, 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x40, + 0x1C, 0x00, 0x40, 0x1C, 0x00, 0x80, 0x0E, 0x00, 0x80, 0x0E, 0x01, 0x00, 0x03, 0x86, 0x00, 0x00, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"U",53*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x01, 0xF8, 0x1E, 0x00, 0x60, 0x0C, 0x00, + 0x40, 0x0E, 0x00, 0x40, 0x0E, 0x00, 0xC0, 0x0E, 0x00, 0xC0, 0x0E, 0x00, 0x80, 0x07, 0x00, 0x80, + 0x07, 0x01, 0x80, 0x07, 0x01, 0x00, 0x07, 0x01, 0x00, 0x03, 0x01, 0x00, 0x03, 0x83, 0x00, 0x03, + 0x82, 0x00, 0x03, 0x82, 0x00, 0x01, 0x82, 0x00, 0x01, 0xC6, 0x00, 0x01, 0xC4, 0x00, 0x01, 0xC4, + 0x00, 0x00, 0xC4, 0x00, 0x00, 0xEC, 0x00, 0x00, 0xE8, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x68, 0x00, + 0x00, 0x78, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"V",54*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0x7C, 0x30, 0x38, 0x30, 0x30, 0x30, + 0x10, 0x30, 0x38, 0x30, 0x38, 0x38, 0x30, 0x38, 0x38, 0x20, 0x38, 0x38, 0x20, 0x18, 0x38, 0x20, + 0x18, 0x38, 0x20, 0x18, 0x38, 0x60, 0x18, 0x3C, 0x40, 0x1C, 0x3C, 0x40, 0x1C, 0x7C, 0x40, 0x1C, + 0x5C, 0x40, 0x0C, 0x4C, 0x40, 0x0C, 0x4C, 0xC0, 0x0C, 0x4C, 0x80, 0x0C, 0xCE, 0x80, 0x0E, 0x8E, + 0x80, 0x0E, 0x8E, 0x80, 0x06, 0x86, 0x80, 0x06, 0x87, 0x80, 0x07, 0x87, 0x00, 0x07, 0x07, 0x00, + 0x07, 0x07, 0x00, 0x07, 0x07, 0x00, 0x07, 0x07, 0x00, 0x03, 0x03, 0x00, 0x02, 0x02, 0x00, 0x02, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"W",55*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x87, 0xF0, 0x0E, 0x00, 0xC0, 0x0E, 0x00, + 0x80, 0x06, 0x01, 0x80, 0x07, 0x01, 0x00, 0x07, 0x03, 0x00, 0x03, 0x82, 0x00, 0x03, 0x86, 0x00, + 0x01, 0xC6, 0x00, 0x01, 0xCC, 0x00, 0x00, 0xEC, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x78, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x30, 0x00, 0x00, 0x38, 0x00, 0x00, 0x78, 0x00, 0x00, 0x5C, 0x00, 0x00, 0xDC, + 0x00, 0x00, 0x8E, 0x00, 0x01, 0x8E, 0x00, 0x01, 0x06, 0x00, 0x03, 0x07, 0x00, 0x03, 0x03, 0x00, + 0x02, 0x03, 0x80, 0x06, 0x03, 0x80, 0x04, 0x01, 0xC0, 0x0C, 0x01, 0xC0, 0x1C, 0x01, 0xE0, 0x7F, + 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"X",56*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x83, 0xF8, 0x1C, 0x00, 0xE0, 0x1C, 0x00, + 0x40, 0x0E, 0x00, 0xC0, 0x0E, 0x00, 0x80, 0x0E, 0x00, 0x80, 0x07, 0x01, 0x00, 0x07, 0x01, 0x00, + 0x03, 0x03, 0x00, 0x03, 0x82, 0x00, 0x03, 0x82, 0x00, 0x01, 0xC4, 0x00, 0x01, 0xC4, 0x00, 0x01, + 0xCC, 0x00, 0x00, 0xE8, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, + 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x03, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"Y",57*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF0, 0x0F, 0x00, 0xE0, 0x0E, 0x00, + 0xE0, 0x0C, 0x01, 0xC0, 0x18, 0x01, 0xC0, 0x10, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x07, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, + 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x07, 0x00, 0x10, + 0x07, 0x00, 0x30, 0x0E, 0x00, 0x20, 0x0E, 0x00, 0x60, 0x1C, 0x00, 0xE0, 0x1C, 0x01, 0xE0, 0x3F, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"Z",58*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x7F, 0xE0, 0x00, + 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"[",59*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, + 0x01, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, /*"\",60*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x1F, 0xF8, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x08, 0x00, 0x1F, 0xF8, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"]",61*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xFC, 0x00, 0x01, + 0xC6, 0x00, 0x03, 0x03, 0x00, 0x04, 0x00, 0x80, 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, + 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, 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, /*"^",62*/ + + 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, 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, + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xFC, /*"_",63*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xC0, 0x00, 0x01, 0xE0, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x08, 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, 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, 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, /*"`",64*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x07, 0x07, 0x00, 0x0C, 0x03, 0x80, 0x1C, + 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x0F, 0xC0, 0x00, 0xF9, + 0xC0, 0x07, 0x81, 0xC0, 0x0E, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x38, 0x01, 0xC0, + 0x38, 0x01, 0xC0, 0x38, 0x01, 0xC4, 0x38, 0x01, 0xC4, 0x1C, 0x03, 0xC4, 0x0E, 0x0D, 0xC8, 0x07, + 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"a",65*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x1F, 0x00, 0x0E, 0x61, 0x80, 0x0E, 0x80, 0xC0, 0x0F, + 0x00, 0xE0, 0x0F, 0x00, 0xE0, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, + 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, + 0x0E, 0x00, 0x60, 0x0E, 0x00, 0xE0, 0x0F, 0x00, 0xC0, 0x0F, 0x01, 0xC0, 0x0C, 0x83, 0x80, 0x08, + 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"b",66*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x01, 0xC3, 0x00, 0x03, 0x81, 0x80, 0x07, + 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x00, 0x00, 0x1C, 0x00, + 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x0E, 0x00, 0x20, 0x0E, 0x00, 0x40, 0x06, 0x00, 0x40, 0x07, 0x00, 0x80, 0x01, 0xC1, 0x00, 0x00, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"c",67*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x0F, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, + 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, + 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0xF9, 0xC0, 0x03, 0x85, 0xC0, 0x07, 0x03, 0xC0, 0x06, + 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x01, + 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x01, 0xC0, + 0x0C, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x03, 0xC0, 0x07, 0x07, 0xC0, 0x03, 0x8D, 0xF8, 0x00, + 0xF1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"d",68*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x01, 0x87, 0x00, 0x03, 0x03, 0x80, 0x06, + 0x01, 0xC0, 0x0E, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, + 0xE0, 0x1F, 0xFF, 0xE0, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x0C, 0x00, 0x40, 0x0E, 0x00, 0x40, 0x06, 0x00, 0x80, 0x07, 0x01, 0x00, 0x03, 0xC3, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"e",69*/ + + 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, 0x0F, 0xE0, 0x00, 0x18, 0x30, 0x00, 0x70, + 0x38, 0x00, 0x60, 0x38, 0x00, 0xE0, 0x38, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, + 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, + 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, + 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, + 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x0F, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"f",70*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x38, 0x03, 0x07, 0xF8, 0x06, 0x03, 0x98, 0x0E, + 0x03, 0x80, 0x1C, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x01, + 0xC0, 0x0E, 0x01, 0x80, 0x06, 0x03, 0x80, 0x03, 0x07, 0x00, 0x0E, 0xFC, 0x00, 0x1C, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x07, 0xFF, 0x80, 0x0E, 0x3F, 0xE0, 0x1C, 0x00, 0xF0, 0x38, + 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x1C, 0x00, 0xE0, 0x0F, 0x03, + 0xC0, 0x01, 0xFE, 0x00, /*"g",71*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x3E, 0x00, 0x0E, 0x43, 0x80, 0x0F, 0x81, 0x80, 0x0F, + 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, + 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, + 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x3F, + 0x87, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"h",72*/ + + 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, 0x38, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x7C, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x07, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"i",73*/ + + 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, 0x03, 0x80, 0x00, 0x07, 0xC0, 0x00, 0x07, + 0xC0, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x7F, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, + 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, + 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, + 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, + 0x03, 0x80, 0x00, 0x03, 0x80, 0x1C, 0x03, 0x00, 0x1C, 0x07, 0x00, 0x1C, 0x06, 0x00, 0x0E, 0x1C, + 0x00, 0x07, 0xF0, 0x00, /*"j",74*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x07, 0xF0, 0x0E, 0x01, 0x80, 0x0E, 0x03, 0x00, 0x0E, + 0x06, 0x00, 0x0E, 0x04, 0x00, 0x0E, 0x0C, 0x00, 0x0E, 0x18, 0x00, 0x0E, 0x30, 0x00, 0x0E, 0x78, + 0x00, 0x0E, 0xDC, 0x00, 0x0F, 0x9C, 0x00, 0x0F, 0x0E, 0x00, 0x0E, 0x06, 0x00, 0x0E, 0x07, 0x00, + 0x0E, 0x03, 0x80, 0x0E, 0x03, 0x80, 0x0E, 0x01, 0xC0, 0x0E, 0x00, 0xC0, 0x0E, 0x00, 0xE0, 0x3F, + 0x83, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"k",75*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x0F, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"l",76*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xF9, 0xF1, 0xE0, 0x3A, 0x3E, 0x30, 0x3C, 0x3C, 0x38, 0x38, + 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, + 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, + 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0xFE, + 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"m",77*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x3E, 0x3E, 0x00, 0x0E, 0x43, 0x80, 0x0E, 0x83, 0x80, 0x0F, + 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, + 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, + 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x3F, + 0x87, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"n",78*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x03, 0x87, 0x00, 0x07, 0x01, 0x80, 0x0E, + 0x01, 0xC0, 0x0C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x18, 0x00, 0x60, 0x38, 0x00, 0x70, 0x38, 0x00, + 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x18, 0x00, 0x70, + 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x0E, 0x00, 0xC0, 0x06, 0x01, 0x80, 0x03, 0x87, 0x00, 0x00, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"o",79*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3E, 0x00, 0x7E, 0x43, 0x80, 0x0E, 0x81, 0xC0, 0x0F, + 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x60, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, + 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, + 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0F, 0x00, 0xC0, 0x0F, 0x01, 0xC0, 0x0E, 0xC3, 0x80, 0x0E, + 0x3E, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, + 0x00, 0x7F, 0xC0, 0x00, /*"p",80*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF8, 0x40, 0x03, 0x04, 0xC0, 0x06, 0x03, 0xC0, 0x0C, + 0x03, 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x38, 0x01, 0xC0, 0x38, 0x01, 0xC0, 0x38, 0x01, + 0xC0, 0x38, 0x01, 0xC0, 0x38, 0x01, 0xC0, 0x38, 0x01, 0xC0, 0x38, 0x01, 0xC0, 0x38, 0x01, 0xC0, + 0x18, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x1C, 0x03, 0xC0, 0x0E, 0x03, 0xC0, 0x07, 0x0D, 0xC0, 0x01, + 0xF1, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, + 0xC0, 0x00, 0x0F, 0xF8, /*"q",81*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x7F, 0x83, 0xE0, 0x03, 0x8C, 0x70, 0x03, 0x98, 0x70, 0x03, + 0xB0, 0x70, 0x03, 0xA0, 0x70, 0x03, 0xC0, 0x00, 0x03, 0xC0, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, + 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, + 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x7F, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"r",82*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x01, 0xC3, 0xC0, 0x03, 0x81, 0xC0, 0x07, + 0x00, 0xC0, 0x07, 0x00, 0x40, 0x07, 0x00, 0x40, 0x07, 0x80, 0x00, 0x03, 0xC0, 0x00, 0x03, 0xF8, + 0x00, 0x00, 0xFE, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x0F, 0xC0, 0x00, 0x03, 0xE0, 0x08, 0x01, 0xE0, + 0x08, 0x00, 0xE0, 0x0C, 0x00, 0xE0, 0x0C, 0x00, 0xE0, 0x0E, 0x01, 0xC0, 0x0F, 0x83, 0x80, 0x08, + 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"s",83*/ + + 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, 0x20, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0xE0, 0x00, 0x03, 0xE0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, + 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, + 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, + 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x20, 0x00, 0xE0, 0x20, 0x00, 0x60, 0x40, 0x00, 0x70, 0x80, 0x00, + 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"t",84*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x7E, 0x0F, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, + 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, + 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, + 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x03, 0xC0, 0x07, 0x03, 0xC0, 0x07, 0x8D, 0xF8, 0x01, + 0xF1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"u",85*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x83, 0xF0, 0x0E, 0x00, 0xC0, 0x06, 0x00, 0x80, 0x07, + 0x00, 0x80, 0x07, 0x01, 0x80, 0x03, 0x01, 0x00, 0x03, 0x01, 0x00, 0x03, 0x83, 0x00, 0x01, 0x82, + 0x00, 0x01, 0x82, 0x00, 0x01, 0xC6, 0x00, 0x00, 0xC4, 0x00, 0x00, 0xC4, 0x00, 0x00, 0xEC, 0x00, + 0x00, 0x68, 0x00, 0x00, 0x68, 0x00, 0x00, 0x78, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"v",86*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0xFC, 0x38, 0x70, 0x30, 0x38, 0x30, 0x30, 0x38, + 0x30, 0x20, 0x18, 0x38, 0x20, 0x18, 0x38, 0x60, 0x1C, 0x38, 0x40, 0x1C, 0x78, 0x40, 0x0C, 0x5C, + 0x40, 0x0C, 0x4C, 0x40, 0x0E, 0xCC, 0x80, 0x0E, 0xCC, 0x80, 0x06, 0x8C, 0x80, 0x07, 0x8E, 0x80, + 0x07, 0x87, 0x00, 0x07, 0x87, 0x00, 0x03, 0x07, 0x00, 0x03, 0x07, 0x00, 0x03, 0x02, 0x00, 0x03, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"w",87*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC7, 0xE0, 0x07, 0x81, 0x80, 0x03, 0x81, 0x00, 0x01, + 0x83, 0x00, 0x01, 0xC2, 0x00, 0x00, 0xC4, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x78, 0x00, 0x00, 0x78, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x8E, 0x00, + 0x01, 0x86, 0x00, 0x01, 0x03, 0x00, 0x03, 0x03, 0x80, 0x06, 0x01, 0x80, 0x0E, 0x01, 0xC0, 0x3F, + 0x87, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"x",88*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x87, 0xF0, 0x0E, 0x01, 0xC0, 0x06, 0x01, 0x80, 0x06, + 0x01, 0x00, 0x07, 0x01, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00, 0x03, 0x82, 0x00, 0x01, 0x86, + 0x00, 0x01, 0x86, 0x00, 0x00, 0xC4, 0x00, 0x00, 0xCC, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x68, 0x00, + 0x00, 0x78, 0x00, 0x00, 0x78, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x00, 0x1C, 0xC0, 0x00, 0x1F, 0x80, + 0x00, 0x0F, 0x00, 0x00, /*"y",89*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xC0, 0x0E, 0x01, 0xC0, 0x18, 0x03, 0x80, 0x18, + 0x07, 0x00, 0x10, 0x07, 0x00, 0x10, 0x0E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x20, + 0x03, 0x80, 0x20, 0x07, 0x00, 0x60, 0x07, 0x00, 0x40, 0x0E, 0x00, 0xC0, 0x1C, 0x01, 0xC0, 0x1F, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"z",90*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x03, 0x80, 0x00, + 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"{",91*/ + + 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x30, 0x00, /*"|",92*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, + 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, + 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0xC0, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, + 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, + 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, + 0x80, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, /*"}",93*/ + + 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x0F, 0xE0, 0x00, 0x18, 0xF0, 0x08, 0x10, 0x78, 0x08, 0x20, + 0x3C, 0x10, 0x20, 0x1E, 0x30, 0x00, 0x0F, 0xE0, 0x00, 0x03, 0xC0, 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, 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, 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, /*"~",94*/ +}; + +const esp_painter_basic_font_t esp_painter_basic_font_44 = { + .bitmap = bitmap, + .width = 22, + .height = 44, +}; + +#endif diff --git a/components/lua_modules/esp_painter/font/basic_font_48.c b/components/lua_modules/esp_painter/font/basic_font_48.c new file mode 100644 index 0000000..9c51beb --- /dev/null +++ b/components/lua_modules/esp_painter/font/basic_font_48.c @@ -0,0 +1,972 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include "sdkconfig.h" + +#include "esp_painter_font.h" + +#if CONFIG_ESP_PAINTER_BASIC_FONT_48 + +static const uint8_t bitmap[] = +{ + 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, 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, + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*" ",0*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x7C, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"!",1*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0xF0, 0xF0, 0x01, + 0xF1, 0xF0, 0x01, 0xF1, 0xF0, 0x03, 0xE3, 0xE0, 0x03, 0xC3, 0xC0, 0x07, 0x87, 0x80, 0x07, 0x07, + 0x00, 0x0E, 0x0E, 0x00, 0x0C, 0x0C, 0x00, 0x18, 0x18, 0x00, 0x10, 0x10, 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, 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, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*""",2*/ + + 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, 0x80, 0x60, 0x01, 0x80, 0x60, 0x01, 0x80, + 0x60, 0x01, 0x00, 0x40, 0x01, 0x00, 0x40, 0x01, 0x00, 0x40, 0x01, 0x00, 0x40, 0x01, 0x00, 0x40, + 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x03, 0x00, 0xC0, 0x03, + 0x00, 0xC0, 0x03, 0x00, 0xC0, 0x03, 0x00, 0xC0, 0x03, 0x00, 0xC0, 0x03, 0x00, 0xC0, 0x03, 0x00, + 0xC0, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, + 0x3F, 0xFF, 0xFC, 0x06, 0x01, 0x80, 0x06, 0x01, 0x80, 0x06, 0x01, 0x80, 0x06, 0x01, 0x80, 0x06, + 0x01, 0x80, 0x06, 0x01, 0x80, 0x06, 0x01, 0x80, 0x06, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"#",3*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x7F, 0x00, 0x01, 0xD9, 0xC0, 0x03, 0x18, + 0xE0, 0x07, 0x18, 0x60, 0x06, 0x18, 0x70, 0x0E, 0x18, 0x70, 0x0E, 0x18, 0xF0, 0x0E, 0x18, 0xF0, + 0x0E, 0x18, 0xE0, 0x0F, 0x18, 0x00, 0x07, 0x98, 0x00, 0x07, 0xD8, 0x00, 0x03, 0xF8, 0x00, 0x01, + 0xF8, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x1F, + 0xC0, 0x00, 0x1B, 0xE0, 0x00, 0x19, 0xE0, 0x00, 0x18, 0xF0, 0x00, 0x18, 0xF0, 0x0E, 0x18, 0x70, + 0x1E, 0x18, 0x70, 0x1E, 0x18, 0x70, 0x1E, 0x18, 0x70, 0x1C, 0x18, 0x70, 0x0C, 0x18, 0x60, 0x0C, + 0x18, 0xE0, 0x06, 0x18, 0xC0, 0x03, 0x1B, 0x80, 0x00, 0xFE, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"$",4*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x20, 0x18, 0x80, 0x60, 0x30, 0xC0, + 0x40, 0x20, 0x40, 0xC0, 0x60, 0x60, 0x80, 0x60, 0x60, 0x80, 0x60, 0x61, 0x80, 0x60, 0x61, 0x00, + 0x60, 0x63, 0x00, 0x60, 0x62, 0x00, 0x60, 0x62, 0x00, 0x60, 0x66, 0x00, 0x60, 0x64, 0x00, 0x30, + 0x4C, 0x00, 0x30, 0xC8, 0x00, 0x19, 0x88, 0x00, 0x0F, 0x18, 0xF0, 0x00, 0x11, 0x98, 0x00, 0x33, + 0x0C, 0x00, 0x23, 0x0C, 0x00, 0x22, 0x04, 0x00, 0x66, 0x06, 0x00, 0x46, 0x06, 0x00, 0x46, 0x06, + 0x00, 0x86, 0x06, 0x00, 0x86, 0x06, 0x01, 0x86, 0x06, 0x01, 0x06, 0x06, 0x01, 0x06, 0x06, 0x02, + 0x02, 0x04, 0x02, 0x03, 0x0C, 0x06, 0x01, 0x98, 0x04, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"%",5*/ + + 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, 0xF0, 0x00, 0x03, 0x38, 0x00, 0x07, 0x18, + 0x00, 0x06, 0x1C, 0x00, 0x0E, 0x1C, 0x00, 0x0E, 0x1C, 0x00, 0x0E, 0x1C, 0x00, 0x0E, 0x1C, 0x00, + 0x0E, 0x1C, 0x00, 0x0E, 0x18, 0x00, 0x0E, 0x38, 0x00, 0x0F, 0x30, 0x00, 0x07, 0x70, 0x00, 0x07, + 0x60, 0x00, 0x07, 0x80, 0x00, 0x07, 0x87, 0xF8, 0x0B, 0x80, 0xE0, 0x1B, 0xC0, 0xC0, 0x39, 0xC0, + 0xC0, 0x31, 0xE0, 0xC0, 0x31, 0xE0, 0xC0, 0x70, 0xF0, 0x80, 0x70, 0xF0, 0x80, 0x70, 0x79, 0x80, + 0x70, 0x39, 0x80, 0x70, 0x3D, 0x00, 0x70, 0x1F, 0x00, 0x78, 0x0E, 0x00, 0x38, 0x0F, 0x02, 0x3C, + 0x0F, 0x86, 0x1E, 0x1B, 0xC4, 0x0F, 0xF1, 0xFC, 0x07, 0xC0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"&",6*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x1F, + 0x80, 0x00, 0x1F, 0x80, 0x00, 0x0F, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x30, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"'",7*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x60, 0x00, 0x00, 0xC0, 0x00, 0x01, 0x80, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"(",8*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0xC0, 0x00, 0x00, 0x80, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*")",9*/ + + 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, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, + 0x00, 0x38, 0x00, 0x30, 0x38, 0x38, 0x7C, 0x38, 0x7C, 0x7E, 0x10, 0xFC, 0x3F, 0x11, 0xF8, 0x0F, + 0x93, 0xE0, 0x01, 0xD7, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x01, 0xD7, 0x00, 0x0F, 0x93, + 0xE0, 0x3F, 0x11, 0xF8, 0x7E, 0x10, 0xFC, 0x7C, 0x38, 0x7C, 0x70, 0x38, 0x1C, 0x00, 0x38, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 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, /*"*",10*/ + + 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, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x18, 0x00, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x00, 0x18, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 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, /*"+",11*/ + + 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, 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, + 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, 0x0E, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x1F, + 0x80, 0x00, 0x1F, 0x80, 0x00, 0x0F, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, /*",",12*/ + + 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, 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, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 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, 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, /*"-",13*/ + + 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, 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, + 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, 0x0F, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x1F, + 0x80, 0x00, 0x1F, 0x80, 0x00, 0x1F, 0x80, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*".",14*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x0C, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, + 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"/",15*/ + + 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, 0x7E, 0x00, 0x01, 0xC3, 0x80, 0x03, 0x80, + 0xC0, 0x03, 0x00, 0xE0, 0x06, 0x00, 0x60, 0x0E, 0x00, 0x70, 0x0C, 0x00, 0x30, 0x1C, 0x00, 0x38, + 0x1C, 0x00, 0x38, 0x1C, 0x00, 0x38, 0x18, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, + 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, + 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x18, 0x00, 0x18, 0x1C, 0x00, 0x38, + 0x1C, 0x00, 0x38, 0x1C, 0x00, 0x38, 0x0C, 0x00, 0x30, 0x0E, 0x00, 0x70, 0x06, 0x00, 0x60, 0x03, + 0x00, 0xE0, 0x03, 0x80, 0xC0, 0x00, 0xC3, 0x80, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"0",16*/ + + 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, 0x04, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1C, + 0x00, 0x03, 0xFC, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, + 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, + 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, + 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x3E, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"1",17*/ + + 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, 0x7F, 0x00, 0x01, 0x83, 0xC0, 0x06, 0x00, + 0xE0, 0x0C, 0x00, 0x70, 0x0C, 0x00, 0x70, 0x1C, 0x00, 0x38, 0x1C, 0x00, 0x38, 0x1C, 0x00, 0x38, + 0x1E, 0x00, 0x38, 0x1E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, + 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xC0, 0x00, 0x03, 0x80, 0x00, 0x07, 0x00, 0x00, 0x0E, + 0x00, 0x00, 0x1C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x70, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xC0, 0x00, + 0x03, 0x80, 0x00, 0x07, 0x00, 0x08, 0x06, 0x00, 0x08, 0x0C, 0x00, 0x18, 0x1C, 0x00, 0x10, 0x38, + 0x00, 0x70, 0x3F, 0xFF, 0xF0, 0x3F, 0xFF, 0xF0, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"2",18*/ + + 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, 0x7E, 0x00, 0x01, 0x83, 0x80, 0x02, 0x01, + 0xC0, 0x04, 0x00, 0xE0, 0x0C, 0x00, 0xE0, 0x0C, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, + 0x06, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x60, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xC0, 0x00, + 0x01, 0x80, 0x00, 0x07, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x00, + 0xE0, 0x00, 0x00, 0x70, 0x00, 0x00, 0x30, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, + 0x0C, 0x00, 0x38, 0x1E, 0x00, 0x38, 0x1E, 0x00, 0x38, 0x1E, 0x00, 0x30, 0x1C, 0x00, 0x70, 0x0C, + 0x00, 0x60, 0x06, 0x00, 0xC0, 0x03, 0x03, 0x80, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"3",19*/ + + 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, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, + 0x80, 0x00, 0x07, 0x80, 0x00, 0x0F, 0x80, 0x00, 0x0B, 0x80, 0x00, 0x13, 0x80, 0x00, 0x13, 0x80, + 0x00, 0x23, 0x80, 0x00, 0x63, 0x80, 0x00, 0x43, 0x80, 0x00, 0xC3, 0x80, 0x00, 0x83, 0x80, 0x01, + 0x03, 0x80, 0x03, 0x03, 0x80, 0x02, 0x03, 0x80, 0x06, 0x03, 0x80, 0x04, 0x03, 0x80, 0x0C, 0x03, + 0x80, 0x18, 0x03, 0x80, 0x18, 0x03, 0x80, 0x30, 0x03, 0x80, 0x3F, 0xFF, 0xFC, 0x00, 0x03, 0x80, + 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, + 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x07, 0xC0, 0x00, 0x7F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"4",20*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF0, 0x07, 0xFF, 0xF0, 0x07, 0xFF, + 0xF0, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x7F, 0x00, 0x0C, + 0xFF, 0x80, 0x0D, 0x81, 0xE0, 0x0F, 0x00, 0xE0, 0x0E, 0x00, 0x70, 0x0C, 0x00, 0x70, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x0C, 0x00, 0x38, + 0x1E, 0x00, 0x38, 0x1E, 0x00, 0x38, 0x1E, 0x00, 0x30, 0x1C, 0x00, 0x70, 0x0C, 0x00, 0x70, 0x0C, + 0x00, 0xE0, 0x06, 0x00, 0xC0, 0x03, 0x83, 0x80, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"5",21*/ + + 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, 0x1F, 0x80, 0x00, 0xE0, 0x40, 0x01, 0x80, + 0x60, 0x03, 0x00, 0x70, 0x06, 0x00, 0x70, 0x06, 0x00, 0x70, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x3F, 0x00, 0x38, + 0xFF, 0xC0, 0x39, 0xC1, 0xE0, 0x3B, 0x00, 0x70, 0x3E, 0x00, 0x38, 0x3C, 0x00, 0x38, 0x3C, 0x00, + 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, + 0x18, 0x00, 0x1C, 0x1C, 0x00, 0x1C, 0x1C, 0x00, 0x18, 0x0C, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x07, + 0x00, 0x30, 0x03, 0x80, 0x60, 0x01, 0xC1, 0xC0, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"6",22*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x0F, 0xFF, 0xF8, 0x0F, 0xFF, + 0xF0, 0x0E, 0x00, 0x30, 0x0C, 0x00, 0x20, 0x18, 0x00, 0x40, 0x18, 0x00, 0xC0, 0x10, 0x00, 0x80, + 0x00, 0x01, 0x80, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, + 0x00, 0x70, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, + 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"7",23*/ + + 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, 0x7F, 0x00, 0x03, 0x81, 0xC0, 0x07, 0x00, + 0xE0, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x1C, 0x00, 0x38, 0x1C, 0x00, 0x38, 0x1C, 0x00, 0x38, + 0x1C, 0x00, 0x38, 0x1E, 0x00, 0x38, 0x1E, 0x00, 0x30, 0x0F, 0x00, 0x70, 0x07, 0xC0, 0xE0, 0x07, + 0xE1, 0xC0, 0x01, 0xFB, 0x80, 0x00, 0xFE, 0x00, 0x03, 0xBF, 0x00, 0x07, 0x0F, 0xC0, 0x0E, 0x03, + 0xE0, 0x0C, 0x01, 0xE0, 0x1C, 0x00, 0xF0, 0x1C, 0x00, 0x70, 0x38, 0x00, 0x78, 0x38, 0x00, 0x38, + 0x38, 0x00, 0x38, 0x38, 0x00, 0x38, 0x38, 0x00, 0x38, 0x18, 0x00, 0x30, 0x1C, 0x00, 0x70, 0x0C, + 0x00, 0x60, 0x06, 0x00, 0xC0, 0x03, 0x81, 0x80, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"8",24*/ + + 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, 0xFC, 0x00, 0x03, 0x83, 0x00, 0x06, 0x01, + 0x80, 0x0E, 0x00, 0xC0, 0x1C, 0x00, 0x60, 0x1C, 0x00, 0x60, 0x18, 0x00, 0x70, 0x38, 0x00, 0x30, + 0x38, 0x00, 0x30, 0x38, 0x00, 0x38, 0x38, 0x00, 0x38, 0x38, 0x00, 0x38, 0x38, 0x00, 0x38, 0x38, + 0x00, 0x38, 0x3C, 0x00, 0x78, 0x1C, 0x00, 0xF8, 0x1C, 0x00, 0xB8, 0x1E, 0x01, 0xB8, 0x0F, 0x87, + 0x38, 0x07, 0xFE, 0x38, 0x01, 0xF8, 0x38, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x70, 0x00, 0x00, 0x60, 0x00, 0x00, 0xE0, 0x0E, 0x00, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, + 0x03, 0x80, 0x0E, 0x07, 0x00, 0x06, 0x0E, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"9",25*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x7C, 0x00, 0x00, + 0x7C, 0x00, 0x00, 0x38, 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, 0x00, 0x38, 0x00, 0x00, + 0x7C, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*":",26*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, + 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C, 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, 0x00, + 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*";",27*/ + + 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, 0x10, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x70, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xC0, 0x00, 0x03, 0x80, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, 0xC0, 0x00, 0x01, 0x80, 0x00, 0x03, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0x80, 0x00, 0x01, 0xC0, 0x00, + 0x00, 0xE0, 0x00, 0x00, 0x70, 0x00, 0x00, 0x38, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"<",28*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 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, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"=",29*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x0E, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x03, 0x80, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x60, 0x00, 0x00, 0xC0, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x01, 0xC0, 0x00, 0x03, 0x80, 0x00, 0x07, + 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*">",30*/ + + 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, 0xFE, 0x00, 0x03, 0xFF, 0x80, 0x07, 0x03, + 0xC0, 0x0C, 0x01, 0xE0, 0x18, 0x00, 0xF0, 0x10, 0x00, 0x70, 0x30, 0x00, 0x78, 0x30, 0x00, 0x78, + 0x3C, 0x00, 0x78, 0x3E, 0x00, 0x78, 0x3E, 0x00, 0x78, 0x1E, 0x00, 0x78, 0x00, 0x00, 0xF0, 0x00, + 0x01, 0xF0, 0x00, 0x03, 0xE0, 0x00, 0x07, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x7C, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"?",31*/ + + 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, 0x3F, 0x00, 0x00, 0xE0, 0xC0, 0x01, 0x80, + 0x60, 0x03, 0x00, 0x10, 0x07, 0x00, 0x18, 0x06, 0x00, 0x0C, 0x0C, 0x07, 0x6C, 0x0C, 0x0C, 0xEC, + 0x1C, 0x1C, 0xE6, 0x1C, 0x18, 0xE6, 0x18, 0x38, 0xC6, 0x38, 0x30, 0xC6, 0x38, 0x70, 0xC6, 0x38, + 0x70, 0xC6, 0x38, 0x60, 0xC6, 0x38, 0x61, 0xC6, 0x38, 0xE1, 0xC6, 0x38, 0xE1, 0x86, 0x38, 0xE1, + 0x86, 0x38, 0xE1, 0x8C, 0x38, 0xE1, 0x8C, 0x38, 0xE3, 0x8C, 0x1C, 0xE3, 0x98, 0x1C, 0x65, 0x98, + 0x1C, 0x7D, 0xF0, 0x0C, 0x38, 0xE0, 0x0E, 0x00, 0x06, 0x0E, 0x00, 0x04, 0x07, 0x00, 0x0C, 0x03, + 0x80, 0x38, 0x01, 0xE0, 0xF0, 0x00, 0xFF, 0xE0, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"@",32*/ + + 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, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x7C, + 0x00, 0x00, 0x7C, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x4C, 0x00, 0x00, 0xCC, 0x00, 0x00, 0xCE, 0x00, + 0x00, 0x8E, 0x00, 0x00, 0x86, 0x00, 0x01, 0x86, 0x00, 0x01, 0x87, 0x00, 0x01, 0x07, 0x00, 0x01, + 0x03, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x80, 0x02, 0x03, 0x80, 0x02, 0x03, 0x80, 0x06, 0x01, + 0x80, 0x07, 0xFF, 0xC0, 0x04, 0x01, 0xC0, 0x04, 0x01, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xE0, + 0x08, 0x00, 0xE0, 0x08, 0x00, 0xE0, 0x18, 0x00, 0xE0, 0x18, 0x00, 0x70, 0x18, 0x00, 0x70, 0x18, + 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x78, 0xFE, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"A",33*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x0E, 0x03, 0xC0, 0x0E, 0x00, + 0xE0, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, + 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, + 0x00, 0xE0, 0x0E, 0x03, 0x80, 0x0F, 0xFE, 0x00, 0x0E, 0x01, 0xC0, 0x0E, 0x00, 0x60, 0x0E, 0x00, + 0x70, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, + 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x38, 0x0E, + 0x00, 0x38, 0x0E, 0x00, 0x70, 0x0E, 0x01, 0xC0, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"B",34*/ + + 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, 0x3F, 0x00, 0x00, 0xE0, 0xF8, 0x01, 0x80, + 0x38, 0x03, 0x00, 0x18, 0x07, 0x00, 0x18, 0x06, 0x00, 0x08, 0x0E, 0x00, 0x0C, 0x0C, 0x00, 0x04, + 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x1C, 0x00, 0x04, + 0x1C, 0x00, 0x04, 0x1C, 0x00, 0x08, 0x0E, 0x00, 0x08, 0x0E, 0x00, 0x18, 0x07, 0x00, 0x30, 0x07, + 0x80, 0x60, 0x03, 0xC0, 0xE0, 0x00, 0xFF, 0x80, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"C",35*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x0F, 0x07, 0x00, 0x0E, 0x01, + 0x80, 0x0E, 0x00, 0xC0, 0x0E, 0x00, 0x60, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x30, 0x0E, 0x00, 0x38, + 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, + 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, + 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x18, 0x0E, 0x00, 0x38, + 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x30, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0xE0, 0x0E, + 0x01, 0xC0, 0x0E, 0x03, 0x80, 0x0E, 0x0F, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"D",36*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, + 0x70, 0x0E, 0x00, 0x30, 0x0E, 0x00, 0x10, 0x0E, 0x00, 0x18, 0x0E, 0x00, 0x08, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x80, 0x0E, 0x00, 0x80, 0x0E, 0x00, 0x80, 0x0E, + 0x00, 0x80, 0x0E, 0x01, 0x80, 0x0F, 0xFF, 0x80, 0x0E, 0x03, 0x80, 0x0E, 0x01, 0x80, 0x0E, 0x00, + 0x80, 0x0E, 0x00, 0x80, 0x0E, 0x00, 0x80, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x04, 0x0E, 0x00, 0x04, 0x0E, 0x00, 0x08, 0x0E, 0x00, 0x08, 0x0E, + 0x00, 0x18, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0xF0, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"E",37*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x0E, 0x00, 0x78, 0x0E, 0x00, + 0x3C, 0x0E, 0x00, 0x0C, 0x0E, 0x00, 0x04, 0x0E, 0x00, 0x06, 0x0E, 0x00, 0x02, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x40, 0x0E, 0x00, 0x40, 0x0E, 0x00, 0x40, 0x0E, + 0x00, 0x40, 0x0E, 0x00, 0xC0, 0x0F, 0xFF, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x00, 0xC0, 0x0E, 0x00, + 0x40, 0x0E, 0x00, 0x40, 0x0E, 0x00, 0x40, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, + 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"F",38*/ + + 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, 0x7E, 0x20, 0x01, 0xC3, 0xE0, 0x03, 0x00, + 0xE0, 0x06, 0x00, 0xE0, 0x0E, 0x00, 0x60, 0x0C, 0x00, 0x20, 0x1C, 0x00, 0x30, 0x18, 0x00, 0x30, + 0x38, 0x00, 0x10, 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x03, + 0xFE, 0x70, 0x00, 0xF8, 0x70, 0x00, 0x70, 0x70, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, + 0x38, 0x00, 0x70, 0x18, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x0C, 0x00, 0x70, 0x06, + 0x00, 0x70, 0x07, 0x00, 0xF0, 0x01, 0xC1, 0x80, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"G",39*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x83, 0xFE, 0x1C, 0x00, 0x70, 0x1C, 0x00, + 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, + 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, + 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1F, 0xFF, 0xF0, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, + 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, + 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, + 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0xFF, 0x83, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"H",40*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x1C, 0x00, 0x00, 0x1C, + 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, + 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, + 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, + 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"I",41*/ + + 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, 0xFF, 0xFE, 0x00, 0x03, 0x80, 0x00, 0x03, + 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, + 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, + 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, + 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, + 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, + 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x00, 0x03, 0x80, 0x18, 0x03, 0x00, 0x3C, 0x07, + 0x00, 0x3C, 0x06, 0x00, 0x3C, 0x0C, 0x00, 0x1C, 0x18, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, /*"J",42*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC3, 0xFC, 0x0E, 0x00, 0xF0, 0x0E, 0x00, + 0xE0, 0x0E, 0x00, 0xC0, 0x0E, 0x01, 0x80, 0x0E, 0x01, 0x00, 0x0E, 0x03, 0x00, 0x0E, 0x06, 0x00, + 0x0E, 0x04, 0x00, 0x0E, 0x0C, 0x00, 0x0E, 0x08, 0x00, 0x0E, 0x10, 0x00, 0x0E, 0x30, 0x00, 0x0E, + 0x38, 0x00, 0x0E, 0x78, 0x00, 0x0E, 0xF8, 0x00, 0x0E, 0x9C, 0x00, 0x0F, 0x1C, 0x00, 0x0F, 0x0E, + 0x00, 0x0E, 0x0E, 0x00, 0x0E, 0x07, 0x00, 0x0E, 0x07, 0x00, 0x0E, 0x03, 0x80, 0x0E, 0x03, 0x80, + 0x0E, 0x03, 0x80, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, + 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x78, 0x7F, 0xC1, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"K",43*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x07, 0x00, 0x04, 0x07, 0x00, 0x04, 0x07, 0x00, 0x0C, 0x07, 0x00, 0x08, 0x07, + 0x00, 0x18, 0x07, 0x00, 0x38, 0x07, 0x00, 0x78, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"L",44*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x7E, 0x1C, 0x00, 0x78, 0x1C, 0x00, + 0x78, 0x1E, 0x00, 0x78, 0x1E, 0x00, 0xB8, 0x1E, 0x00, 0xB8, 0x1E, 0x00, 0xB8, 0x1E, 0x00, 0xB8, + 0x17, 0x01, 0xB8, 0x17, 0x01, 0x38, 0x17, 0x01, 0x38, 0x17, 0x01, 0x38, 0x13, 0x81, 0x38, 0x13, + 0x83, 0x38, 0x13, 0x82, 0x38, 0x13, 0x82, 0x38, 0x13, 0x82, 0x38, 0x11, 0xC6, 0x38, 0x11, 0xC4, + 0x38, 0x11, 0xC4, 0x38, 0x11, 0xC4, 0x38, 0x10, 0xEC, 0x38, 0x10, 0xEC, 0x38, 0x10, 0xE8, 0x38, + 0x10, 0xE8, 0x38, 0x10, 0xF8, 0x38, 0x10, 0x78, 0x38, 0x10, 0x70, 0x38, 0x10, 0x70, 0x38, 0x10, + 0x70, 0x38, 0x10, 0x30, 0x38, 0x10, 0x30, 0x38, 0x7C, 0x21, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"M",45*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0xFE, 0x0E, 0x00, 0x10, 0x0F, 0x00, + 0x10, 0x0F, 0x00, 0x10, 0x0F, 0x80, 0x10, 0x0B, 0x80, 0x10, 0x0B, 0xC0, 0x10, 0x09, 0xC0, 0x10, + 0x09, 0xE0, 0x10, 0x08, 0xE0, 0x10, 0x08, 0xE0, 0x10, 0x08, 0x70, 0x10, 0x08, 0x70, 0x10, 0x08, + 0x38, 0x10, 0x08, 0x38, 0x10, 0x08, 0x1C, 0x10, 0x08, 0x1C, 0x10, 0x08, 0x0E, 0x10, 0x08, 0x0E, + 0x10, 0x08, 0x07, 0x10, 0x08, 0x07, 0x10, 0x08, 0x03, 0x90, 0x08, 0x03, 0x90, 0x08, 0x03, 0xD0, + 0x08, 0x01, 0xD0, 0x08, 0x01, 0xF0, 0x08, 0x00, 0xF0, 0x08, 0x00, 0xF0, 0x08, 0x00, 0x70, 0x08, + 0x00, 0x70, 0x08, 0x00, 0x30, 0x08, 0x00, 0x30, 0x7F, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"N",46*/ + + 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, 0x3E, 0x00, 0x00, 0xC1, 0x80, 0x01, 0x80, + 0x40, 0x03, 0x00, 0x60, 0x06, 0x00, 0x30, 0x0E, 0x00, 0x38, 0x0C, 0x00, 0x18, 0x1C, 0x00, 0x18, + 0x1C, 0x00, 0x1C, 0x1C, 0x00, 0x1C, 0x18, 0x00, 0x0C, 0x38, 0x00, 0x0E, 0x38, 0x00, 0x0E, 0x38, + 0x00, 0x0E, 0x38, 0x00, 0x0E, 0x38, 0x00, 0x0E, 0x38, 0x00, 0x0E, 0x38, 0x00, 0x0E, 0x38, 0x00, + 0x0E, 0x38, 0x00, 0x0E, 0x38, 0x00, 0x0E, 0x38, 0x00, 0x0E, 0x18, 0x00, 0x0C, 0x1C, 0x00, 0x0C, + 0x1C, 0x00, 0x1C, 0x0C, 0x00, 0x1C, 0x0C, 0x00, 0x18, 0x0E, 0x00, 0x38, 0x06, 0x00, 0x30, 0x03, + 0x00, 0x60, 0x01, 0x80, 0xC0, 0x00, 0xC1, 0x80, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"O",47*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x0E, 0x01, 0xC0, 0x0E, 0x00, + 0x70, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, + 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x38, 0x0E, + 0x00, 0x30, 0x0E, 0x00, 0x70, 0x0E, 0x01, 0xC0, 0x0F, 0xFF, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, + 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"P",48*/ + + 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, 0x7E, 0x00, 0x01, 0xC3, 0x80, 0x03, 0x00, + 0xC0, 0x07, 0x00, 0x60, 0x06, 0x00, 0x60, 0x0E, 0x00, 0x30, 0x0C, 0x00, 0x30, 0x1C, 0x00, 0x38, + 0x1C, 0x00, 0x38, 0x18, 0x00, 0x18, 0x18, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, + 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, + 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x18, 0xF8, 0x18, + 0x1D, 0xFC, 0x18, 0x1D, 0x8E, 0x38, 0x0F, 0x0E, 0x38, 0x0F, 0x07, 0x30, 0x06, 0x07, 0x60, 0x07, + 0x07, 0x60, 0x03, 0x03, 0xC0, 0x01, 0xC3, 0x80, 0x00, 0x7F, 0x80, 0x00, 0x03, 0xC8, 0x00, 0x01, + 0xF8, 0x00, 0x01, 0xF0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Q",49*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x0E, 0x03, 0xC0, 0x0E, 0x00, + 0xE0, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x78, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, + 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, + 0x00, 0xE0, 0x0E, 0x03, 0xC0, 0x0F, 0xFF, 0x00, 0x0E, 0x0C, 0x00, 0x0E, 0x0E, 0x00, 0x0E, 0x0E, + 0x00, 0x0E, 0x07, 0x00, 0x0E, 0x07, 0x00, 0x0E, 0x07, 0x00, 0x0E, 0x03, 0x80, 0x0E, 0x03, 0x80, + 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, + 0x00, 0xF0, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x78, 0x7F, 0xC0, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"R",50*/ + + 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, 0xFE, 0x00, 0x03, 0x03, 0xE0, 0x0E, 0x00, + 0xE0, 0x0C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x38, 0x00, 0x30, 0x38, 0x00, 0x30, 0x38, 0x00, 0x10, + 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x0F, + 0xE0, 0x00, 0x03, 0xF8, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x0F, 0xC0, 0x00, 0x07, + 0xE0, 0x00, 0x01, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x78, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, + 0x20, 0x00, 0x38, 0x30, 0x00, 0x38, 0x30, 0x00, 0x38, 0x10, 0x00, 0x30, 0x18, 0x00, 0x70, 0x1C, + 0x00, 0x60, 0x1E, 0x00, 0xE0, 0x1F, 0x81, 0x80, 0x10, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"S",51*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x38, 0x38, 0x38, 0x30, 0x38, + 0x18, 0x30, 0x38, 0x08, 0x20, 0x38, 0x08, 0x60, 0x38, 0x0C, 0x40, 0x38, 0x04, 0x00, 0x38, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"T",52*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFE, 0x1C, 0x00, 0x10, 0x1C, 0x00, + 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, + 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, + 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, + 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, + 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x1C, 0x00, 0x10, 0x0C, 0x00, 0x20, 0x0E, + 0x00, 0x60, 0x07, 0x00, 0xC0, 0x03, 0x81, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"U",53*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x80, 0xFE, 0x1E, 0x00, 0x38, 0x0E, 0x00, + 0x30, 0x0E, 0x00, 0x30, 0x0E, 0x00, 0x30, 0x0F, 0x00, 0x20, 0x07, 0x00, 0x20, 0x07, 0x00, 0x60, + 0x07, 0x00, 0x60, 0x07, 0x00, 0x40, 0x03, 0x80, 0x40, 0x03, 0x80, 0xC0, 0x03, 0x80, 0x80, 0x03, + 0x80, 0x80, 0x01, 0xC0, 0x80, 0x01, 0xC1, 0x80, 0x01, 0xC1, 0x00, 0x01, 0xC1, 0x00, 0x00, 0xE1, + 0x00, 0x00, 0xE3, 0x00, 0x00, 0xE2, 0x00, 0x00, 0xE2, 0x00, 0x00, 0xF2, 0x00, 0x00, 0x76, 0x00, + 0x00, 0x74, 0x00, 0x00, 0x74, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"V",54*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x7E, 0x3F, 0x38, 0x1C, 0x0C, 0x38, 0x1C, + 0x0C, 0x38, 0x1C, 0x0C, 0x38, 0x1C, 0x08, 0x38, 0x1C, 0x08, 0x18, 0x1C, 0x08, 0x18, 0x1C, 0x08, + 0x1C, 0x1C, 0x18, 0x1C, 0x1E, 0x18, 0x1C, 0x1E, 0x10, 0x1C, 0x1E, 0x10, 0x1C, 0x3E, 0x10, 0x0C, + 0x3E, 0x10, 0x0C, 0x2E, 0x30, 0x0E, 0x26, 0x20, 0x0E, 0x27, 0x20, 0x0E, 0x67, 0x20, 0x0E, 0x67, + 0x20, 0x06, 0x47, 0x60, 0x06, 0x47, 0x60, 0x06, 0x43, 0x40, 0x07, 0xC3, 0x40, 0x07, 0xC3, 0xC0, + 0x07, 0x83, 0xC0, 0x07, 0x83, 0xC0, 0x03, 0x83, 0xC0, 0x03, 0x83, 0x80, 0x03, 0x81, 0x80, 0x03, + 0x01, 0x80, 0x03, 0x01, 0x80, 0x03, 0x01, 0x80, 0x01, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"W",55*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x81, 0xFC, 0x0E, 0x00, 0x70, 0x0E, 0x00, + 0x60, 0x07, 0x00, 0x60, 0x07, 0x00, 0xC0, 0x03, 0x80, 0xC0, 0x03, 0x81, 0x80, 0x01, 0xC1, 0x80, + 0x01, 0xC3, 0x00, 0x00, 0xE3, 0x00, 0x00, 0xE2, 0x00, 0x00, 0xF6, 0x00, 0x00, 0x74, 0x00, 0x00, + 0x7C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, + 0x00, 0x00, 0x6E, 0x00, 0x00, 0x6E, 0x00, 0x00, 0xC7, 0x00, 0x00, 0xC7, 0x00, 0x00, 0x83, 0x80, + 0x01, 0x83, 0x80, 0x01, 0x01, 0xC0, 0x03, 0x01, 0xC0, 0x02, 0x01, 0xE0, 0x06, 0x00, 0xE0, 0x06, + 0x00, 0xF0, 0x0C, 0x00, 0x70, 0x1C, 0x00, 0x78, 0x7F, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"X",56*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x81, 0xFC, 0x1E, 0x00, 0x70, 0x0E, 0x00, + 0x60, 0x0E, 0x00, 0x60, 0x0E, 0x00, 0x40, 0x07, 0x00, 0xC0, 0x07, 0x00, 0x80, 0x07, 0x00, 0x80, + 0x03, 0x81, 0x80, 0x03, 0x81, 0x00, 0x03, 0xC1, 0x00, 0x01, 0xC3, 0x00, 0x01, 0xC2, 0x00, 0x00, + 0xE2, 0x00, 0x00, 0xE2, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x74, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x78, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Y",57*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x07, 0x80, 0x38, 0x0F, 0x00, + 0x78, 0x0C, 0x00, 0x70, 0x0C, 0x00, 0xF0, 0x18, 0x00, 0xE0, 0x10, 0x01, 0xE0, 0x00, 0x01, 0xC0, + 0x00, 0x03, 0xC0, 0x00, 0x03, 0x80, 0x00, 0x07, 0x80, 0x00, 0x07, 0x00, 0x00, 0x0F, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x78, + 0x00, 0x00, 0x70, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xC0, 0x00, + 0x03, 0xC0, 0x00, 0x03, 0x80, 0x00, 0x07, 0x80, 0x04, 0x07, 0x00, 0x0C, 0x0F, 0x00, 0x08, 0x0E, + 0x00, 0x18, 0x1E, 0x00, 0x38, 0x1C, 0x00, 0xF0, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"Z",58*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x7F, 0xF8, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"[",59*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x0C, + 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, + 0x00, 0xE0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"\",60*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFC, 0x00, 0x1F, 0xFC, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x1F, 0xFC, 0x00, 0x1F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"]",61*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x77, 0x00, 0x00, + 0xE1, 0x80, 0x01, 0x80, 0xC0, 0x02, 0x00, 0x20, 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, + 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, 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, /*"^",62*/ + + 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, 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, + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, /*"_",63*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xC0, 0x00, 0x03, 0xE0, 0x00, 0x00, 0xF0, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x04, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, /*"`",64*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x03, 0x03, 0x80, 0x0C, + 0x01, 0xC0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x1C, 0x00, 0xE0, 0x00, 0x00, + 0xE0, 0x00, 0x0F, 0xE0, 0x00, 0xF0, 0xE0, 0x03, 0x80, 0xE0, 0x0E, 0x00, 0xE0, 0x1C, 0x00, 0xE0, + 0x1C, 0x00, 0xE0, 0x38, 0x00, 0xE0, 0x38, 0x00, 0xE0, 0x38, 0x00, 0xE0, 0x38, 0x00, 0xE2, 0x38, + 0x00, 0xE2, 0x1C, 0x03, 0xE2, 0x0E, 0x0E, 0xE4, 0x03, 0xF8, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"a",65*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x0E, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x1F, 0x00, 0x0E, 0x61, 0xC0, 0x0E, + 0xC0, 0xE0, 0x0F, 0x80, 0x70, 0x0F, 0x00, 0x70, 0x0F, 0x00, 0x30, 0x0E, 0x00, 0x38, 0x0E, 0x00, + 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, + 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x30, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0F, + 0x00, 0x60, 0x0F, 0x00, 0xC0, 0x0C, 0xC1, 0x80, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"b",66*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xE0, 0xC0, 0x03, + 0x80, 0x60, 0x03, 0x00, 0x70, 0x07, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x1C, 0x00, + 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x0C, 0x00, 0x08, 0x0E, 0x00, 0x08, 0x0E, 0x00, 0x10, 0x07, + 0x00, 0x30, 0x03, 0x80, 0x60, 0x01, 0xC0, 0xC0, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"c",67*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0x00, 0x03, 0xF0, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x7C, 0x70, 0x01, 0xC3, 0x70, 0x03, + 0x00, 0xF0, 0x07, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x1C, 0x00, + 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, + 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x0C, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0xF0, 0x06, + 0x00, 0xF0, 0x03, 0x01, 0x70, 0x01, 0x82, 0x7E, 0x00, 0xFC, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"d",68*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x01, 0xC1, 0x80, 0x03, + 0x80, 0xC0, 0x07, 0x00, 0x60, 0x06, 0x00, 0x70, 0x0E, 0x00, 0x30, 0x0C, 0x00, 0x38, 0x1C, 0x00, + 0x38, 0x1C, 0x00, 0x38, 0x1C, 0x00, 0x38, 0x1F, 0xFF, 0xF8, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x0E, 0x00, 0x10, 0x0E, 0x00, 0x20, 0x07, + 0x00, 0x20, 0x03, 0x80, 0x40, 0x01, 0xC1, 0x80, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"e",69*/ + + 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, 0x07, 0xF0, 0x00, 0x1C, + 0x0C, 0x00, 0x30, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, + 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0xE0, 0x00, 0x00, + 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, + 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, + 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, + 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"f",70*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x1C, 0x01, 0x83, 0xFC, 0x03, + 0x01, 0xCC, 0x07, 0x01, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, + 0xE0, 0x0E, 0x00, 0xE0, 0x07, 0x00, 0xC0, 0x03, 0x01, 0xC0, 0x01, 0x83, 0x80, 0x07, 0x7E, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x07, 0xFF, 0xC0, 0x03, + 0xFF, 0xF0, 0x0E, 0x01, 0xF0, 0x0C, 0x00, 0x78, 0x1C, 0x00, 0x38, 0x1C, 0x00, 0x38, 0x1C, 0x00, + 0x38, 0x1C, 0x00, 0x30, 0x0E, 0x00, 0x70, 0x07, 0x81, 0xC0, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, /*"g",71*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x0E, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x1F, 0x80, 0x0E, 0x61, 0xC0, 0x0E, + 0xC0, 0xE0, 0x0F, 0x80, 0x70, 0x0F, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, + 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, + 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, + 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x7F, 0xC3, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"h",72*/ + + 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, 0x1C, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x3E, + 0x00, 0x00, 0x3E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, + 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, + 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"i",73*/ + + 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, 0xE0, 0x00, 0x01, 0xF0, 0x00, 0x01, + 0xF0, 0x00, 0x01, 0xF0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0xE0, 0x00, + 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, + 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, + 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, + 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x0E, 0x00, + 0xC0, 0x0E, 0x01, 0xC0, 0x0E, 0x03, 0x80, 0x07, 0x06, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, /*"j",74*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x0E, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, + 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x07, 0xF0, 0x0E, 0x01, 0x80, 0x0E, + 0x03, 0x00, 0x0E, 0x03, 0x00, 0x0E, 0x06, 0x00, 0x0E, 0x0C, 0x00, 0x0E, 0x18, 0x00, 0x0E, 0x30, + 0x00, 0x0E, 0x38, 0x00, 0x0E, 0x78, 0x00, 0x0E, 0xDC, 0x00, 0x0F, 0x9C, 0x00, 0x0F, 0x0E, 0x00, + 0x0E, 0x07, 0x00, 0x0E, 0x07, 0x00, 0x0E, 0x03, 0x80, 0x0E, 0x03, 0x80, 0x0E, 0x01, 0xC0, 0x0E, + 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xF0, 0x7F, 0xC3, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"k",75*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x1C, + 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, + 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, + 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, + 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, + 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"l",76*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x7C, 0xF8, 0xF0, 0x1D, 0x3D, 0x38, 0x1E, + 0x1E, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"m",77*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x7E, 0x1F, 0x80, 0x0E, 0x61, 0xC0, 0x0E, + 0xC0, 0xE0, 0x0F, 0x80, 0x60, 0x0F, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, + 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, + 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, + 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x7F, 0xC3, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"n",78*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x01, 0xC3, 0x80, 0x03, + 0x00, 0xC0, 0x06, 0x00, 0x60, 0x0E, 0x00, 0x30, 0x1C, 0x00, 0x38, 0x1C, 0x00, 0x38, 0x18, 0x00, + 0x18, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, + 0x38, 0x00, 0x1C, 0x38, 0x00, 0x1C, 0x1C, 0x00, 0x38, 0x1C, 0x00, 0x38, 0x0C, 0x00, 0x30, 0x06, + 0x00, 0x60, 0x07, 0x00, 0xC0, 0x01, 0xC1, 0x80, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"o",79*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1F, 0x00, 0x7E, 0x60, 0xC0, 0x0E, + 0x80, 0x60, 0x0F, 0x00, 0x30, 0x0F, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x1C, 0x0E, 0x00, + 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, + 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0E, 0x00, 0x38, 0x0F, + 0x00, 0x70, 0x0F, 0x80, 0xE0, 0x0E, 0xC1, 0xC0, 0x0E, 0x3F, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, + 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x00, /*"p",80*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x10, 0x01, 0x83, 0x30, 0x07, + 0x01, 0xF0, 0x0E, 0x00, 0xF0, 0x0C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x38, 0x00, + 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, + 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x18, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x1C, 0x00, 0x70, 0x0C, + 0x00, 0xF0, 0x06, 0x01, 0xF0, 0x03, 0x83, 0x70, 0x00, 0xFC, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x00, /*"q",81*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x3F, 0xC0, 0xF0, 0x01, 0xC3, 0x1C, 0x01, + 0xC6, 0x1C, 0x01, 0xC8, 0x1C, 0x01, 0xD8, 0x1C, 0x01, 0xF0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xE0, + 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, + 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, + 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"r",82*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x01, 0xC1, 0xC0, 0x03, + 0x80, 0xE0, 0x07, 0x00, 0x60, 0x07, 0x00, 0x60, 0x07, 0x00, 0x20, 0x07, 0x00, 0x00, 0x07, 0x80, + 0x00, 0x03, 0xE0, 0x00, 0x01, 0xF8, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x07, 0xE0, + 0x00, 0x01, 0xE0, 0x00, 0x00, 0xF0, 0x08, 0x00, 0x70, 0x08, 0x00, 0x70, 0x0C, 0x00, 0x70, 0x0C, + 0x00, 0x60, 0x0E, 0x00, 0xE0, 0x0F, 0x81, 0xC0, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"s",83*/ + + 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, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x01, 0xF0, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x70, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, + 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x10, 0x00, 0x70, 0x10, 0x00, + 0x70, 0x20, 0x00, 0x38, 0x20, 0x00, 0x18, 0x40, 0x00, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"t",84*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x7E, 0x03, 0xF0, 0x0E, 0x00, 0x70, 0x0E, + 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, + 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, + 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0x70, 0x0E, 0x00, 0xF0, 0x06, + 0x00, 0xF0, 0x07, 0x01, 0x70, 0x03, 0x82, 0x7E, 0x01, 0xFC, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"u",85*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC1, 0xFC, 0x0F, 0x00, 0x70, 0x07, + 0x00, 0x60, 0x07, 0x00, 0x60, 0x03, 0x00, 0x40, 0x03, 0x80, 0x40, 0x03, 0x80, 0xC0, 0x01, 0x80, + 0x80, 0x01, 0xC0, 0x80, 0x01, 0xC1, 0x80, 0x00, 0xC1, 0x00, 0x00, 0xE1, 0x00, 0x00, 0xE3, 0x00, + 0x00, 0xE2, 0x00, 0x00, 0x62, 0x00, 0x00, 0x76, 0x00, 0x00, 0x74, 0x00, 0x00, 0x3C, 0x00, 0x00, + 0x3C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"v",86*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x7E, 0x3F, 0x38, 0x3C, 0x0C, 0x38, + 0x18, 0x08, 0x18, 0x18, 0x08, 0x18, 0x1C, 0x18, 0x1C, 0x1C, 0x18, 0x1C, 0x1C, 0x10, 0x1C, 0x3C, + 0x10, 0x0C, 0x2E, 0x30, 0x0E, 0x2E, 0x30, 0x0E, 0x26, 0x20, 0x0E, 0x66, 0x20, 0x06, 0x46, 0x20, + 0x07, 0x47, 0x60, 0x07, 0xC7, 0x40, 0x07, 0xC3, 0x40, 0x03, 0x83, 0x40, 0x03, 0x83, 0xC0, 0x03, + 0x83, 0x80, 0x03, 0x81, 0x80, 0x01, 0x81, 0x80, 0x01, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"w",87*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xE3, 0xF8, 0x07, 0x80, 0xE0, 0x03, + 0x80, 0xC0, 0x01, 0xC0, 0x80, 0x01, 0xC1, 0x80, 0x00, 0xE3, 0x00, 0x00, 0x72, 0x00, 0x00, 0x76, + 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x3E, 0x00, + 0x00, 0x67, 0x00, 0x00, 0x67, 0x00, 0x00, 0xC3, 0x80, 0x00, 0x83, 0x80, 0x01, 0x81, 0xC0, 0x03, + 0x00, 0xC0, 0x03, 0x00, 0xE0, 0x07, 0x00, 0xF0, 0x3F, 0x83, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"x",88*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC3, 0xFC, 0x0F, 0x00, 0xE0, 0x07, + 0x00, 0x60, 0x07, 0x00, 0x40, 0x03, 0x00, 0xC0, 0x03, 0x80, 0x80, 0x03, 0x80, 0x80, 0x01, 0x81, + 0x80, 0x01, 0xC1, 0x00, 0x01, 0xC1, 0x00, 0x00, 0xC3, 0x00, 0x00, 0xE2, 0x00, 0x00, 0x62, 0x00, + 0x00, 0x66, 0x00, 0x00, 0x74, 0x00, 0x00, 0x34, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, + 0x00, 0x0C, 0x60, 0x00, 0x1E, 0x40, 0x00, 0x1F, 0xC0, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, /*"y",89*/ + + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x0E, 0x00, 0xF0, 0x1C, + 0x00, 0xE0, 0x18, 0x01, 0xC0, 0x18, 0x03, 0xC0, 0x10, 0x03, 0x80, 0x00, 0x07, 0x00, 0x00, 0x0F, + 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x38, 0x00, 0x00, 0x78, 0x00, 0x00, 0x70, 0x00, + 0x00, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xC0, 0x08, 0x03, 0x80, 0x18, 0x07, 0x80, 0x18, 0x07, + 0x00, 0x30, 0x0E, 0x00, 0x30, 0x1E, 0x00, 0xF0, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"z",90*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xC0, 0x00, + 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x00, 0x01, + 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"{",91*/ + + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, /*"|",92*/ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, + 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, + 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, 0xC0, + 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x80, 0x00, 0x01, 0x80, + 0x00, 0x03, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"}",93*/ + + 0x03, 0xC0, 0x00, 0x0F, 0xE0, 0x00, 0x08, 0x70, 0x02, 0x10, 0x38, 0x02, 0x10, 0x1C, 0x04, 0x20, + 0x0E, 0x04, 0x20, 0x07, 0x88, 0x00, 0x03, 0xF8, 0x00, 0x01, 0xE0, 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, 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, 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, /*"~",94*/ +}; + +const esp_painter_basic_font_t esp_painter_basic_font_48 = { + .bitmap = bitmap, + .width = 24, + .height = 48, +}; + +#endif diff --git a/components/lua_modules/esp_painter/include/esp_painter.h b/components/lua_modules/esp_painter/include/esp_painter.h new file mode 100644 index 0000000..a063481 --- /dev/null +++ b/components/lua_modules/esp_painter/include/esp_painter.h @@ -0,0 +1,83 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "esp_err.h" +#include "esp_painter_font.h" +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// 颜色格式定义 +typedef enum { + ESP_PAINTER_COLOR_FORMAT_RGB565, + ESP_PAINTER_COLOR_FORMAT_RGB888, + ESP_PAINTER_COLOR_FORMAT_YUV420, + ESP_PAINTER_COLOR_FORMAT_YUV422, +} esp_painter_color_format_t; + +// 通用颜色定义 +typedef enum { + ESP_PAINTER_COLOR_BLACK, + ESP_PAINTER_COLOR_NAVY, + ESP_PAINTER_COLOR_DARKGREEN, + ESP_PAINTER_COLOR_DARKCYAN, + ESP_PAINTER_COLOR_MAROON, + ESP_PAINTER_COLOR_PURPLE, + ESP_PAINTER_COLOR_OLIVE, + ESP_PAINTER_COLOR_LIGHTGREY, + ESP_PAINTER_COLOR_DARKGREY, + ESP_PAINTER_COLOR_BLUE, + ESP_PAINTER_COLOR_GREEN, + ESP_PAINTER_COLOR_CYAN, + ESP_PAINTER_COLOR_RED, + ESP_PAINTER_COLOR_MAGENTA, + ESP_PAINTER_COLOR_YELLOW, + ESP_PAINTER_COLOR_WHITE, + ESP_PAINTER_COLOR_ORANGE, + ESP_PAINTER_COLOR_GREENYELLOW, + ESP_PAINTER_COLOR_PINK, +} esp_painter_color_t; + +// Color creation macros +#define RGB565(r,g,b) ((((r) & 0xF8) << 8) | (((g) & 0xFC) << 3) | ((b) >> 3)) +#define RGB888(r,g,b) (((r) << 16) | ((g) << 8) | (b)) + +typedef void* esp_painter_handle_t; + +typedef struct { + struct { + uint16_t width; + uint16_t height; + } canvas; + esp_painter_color_format_t color_format; + const esp_painter_basic_font_t *default_font; + bool swap_rgb565; // Whether to swap RGB565 bytes (endianness conversion) +} esp_painter_config_t; + +esp_err_t esp_painter_init(esp_painter_config_t *config, esp_painter_handle_t *handle); + +esp_err_t esp_painter_draw_string(esp_painter_handle_t handle, uint8_t *buffer, uint32_t buffer_size, + uint16_t x, uint16_t y, const esp_painter_basic_font_t *font, + esp_painter_color_t color, const char* text); + +esp_err_t esp_painter_draw_string_rgb565(esp_painter_handle_t handle, uint8_t *buffer, uint32_t buffer_size, + uint16_t x, uint16_t y, const esp_painter_basic_font_t *font, + uint16_t color565, const char *text); + +esp_err_t esp_painter_draw_string_format(esp_painter_handle_t handle, uint8_t *buffer, uint32_t buffer_size, + uint16_t x, uint16_t y, const esp_painter_basic_font_t *font, + esp_painter_color_t color, const char* fmt, ...); + +esp_err_t esp_painter_deinit(esp_painter_handle_t handle); + +#ifdef __cplusplus +} +#endif diff --git a/components/lua_modules/esp_painter/include/esp_painter_font.h b/components/lua_modules/esp_painter/include/esp_painter_font.h new file mode 100644 index 0000000..b49b58c --- /dev/null +++ b/components/lua_modules/esp_painter/include/esp_painter_font.h @@ -0,0 +1,65 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + const uint8_t *bitmap; + uint16_t width; + uint16_t height; +} esp_painter_basic_font_t; + +#define esp_painter_FONT_DECLARE(font_name) extern const esp_painter_basic_font_t font_name + +#if CONFIG_ESP_PAINTER_BASIC_FONT_12 +esp_painter_FONT_DECLARE(esp_painter_basic_font_12); +#endif + +#if CONFIG_ESP_PAINTER_BASIC_FONT_16 +esp_painter_FONT_DECLARE(esp_painter_basic_font_16); +#endif + +#if CONFIG_ESP_PAINTER_BASIC_FONT_20 +esp_painter_FONT_DECLARE(esp_painter_basic_font_20); +#endif + +#if CONFIG_ESP_PAINTER_BASIC_FONT_24 +esp_painter_FONT_DECLARE(esp_painter_basic_font_24); +#endif + +#if CONFIG_ESP_PAINTER_BASIC_FONT_28 +esp_painter_FONT_DECLARE(esp_painter_basic_font_28); +#endif + +#if CONFIG_ESP_PAINTER_BASIC_FONT_32 +esp_painter_FONT_DECLARE(esp_painter_basic_font_32); +#endif + +#if CONFIG_ESP_PAINTER_BASIC_FONT_36 +esp_painter_FONT_DECLARE(esp_painter_basic_font_36); +#endif + +#if CONFIG_ESP_PAINTER_BASIC_FONT_40 +esp_painter_FONT_DECLARE(esp_painter_basic_font_40); +#endif + +#if CONFIG_ESP_PAINTER_BASIC_FONT_44 +esp_painter_FONT_DECLARE(esp_painter_basic_font_44); +#endif + +#if CONFIG_ESP_PAINTER_BASIC_FONT_48 +esp_painter_FONT_DECLARE(esp_painter_basic_font_48); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/lua_modules/lua_module_audio/CMakeLists.txt b/components/lua_modules/lua_module_audio/CMakeLists.txt new file mode 100644 index 0000000..f610964 --- /dev/null +++ b/components/lua_modules/lua_module_audio/CMakeLists.txt @@ -0,0 +1,10 @@ +idf_component_register( + SRC_DIRS + "." + INCLUDE_DIRS + "include" + REQUIRES + cap_lua + esp_codec_dev + driver +) diff --git a/components/lua_modules/lua_module_audio/idf_component.yml b/components/lua_modules/lua_module_audio/idf_component.yml new file mode 100644 index 0000000..4b68fed --- /dev/null +++ b/components/lua_modules/lua_module_audio/idf_component.yml @@ -0,0 +1,3 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/esp_codec_dev: "*" diff --git a/components/lua_modules/lua_module_audio/include/lua_module_audio.h b/components/lua_modules/lua_module_audio/include/lua_module_audio.h new file mode 100644 index 0000000..9a55e5a --- /dev/null +++ b/components/lua_modules/lua_module_audio/include/lua_module_audio.h @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once +#include "lua.h" +#include "esp_err.h" + +int luaopen_audio(lua_State *L); +esp_err_t lua_module_audio_register(void); diff --git a/components/lua_modules/lua_module_audio/lua_module_audio.c b/components/lua_modules/lua_module_audio/lua_module_audio.c new file mode 100644 index 0000000..35e9d3a --- /dev/null +++ b/components/lua_modules/lua_module_audio/lua_module_audio.c @@ -0,0 +1,743 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "lua_module_audio.h" + +#include +#include +#include +#include +#include +#include +#include "esp_codec_dev.h" +#include "esp_err.h" +#include "esp_log.h" +#include "lauxlib.h" +#include "cap_lua.h" + +static const char *TAG = "lua_audio"; + +/* -------------------------------------------------------------------------- + * Audio constants + * -------------------------------------------------------------------------- */ +#define AUDIO_CHUNK_BYTES 512 +#define AUDIO_DEFAULT_VOL 80 +#define AUDIO_DEFAULT_GAIN_DB 30.0f +#define AUDIO_BASE_PATH "/fatfs/" +#define AUDIO_HANDLE_METATABLE "lua_audio_handle" + +typedef enum { + AUDIO_HANDLE_INPUT = 0, + AUDIO_HANDLE_OUTPUT, +} audio_handle_kind_t; + +typedef struct audio_lua_handle_t { + audio_handle_kind_t kind; + esp_codec_dev_handle_t codec_dev; + uint32_t sample_rate; + uint8_t channels; + uint8_t bits_per_sample; + uint8_t bytes_per_sample; + int out_vol; + float in_gain_db; +} audio_lua_handle_t; + +/* -------------------------------------------------------------------------- + * WAV helpers + * -------------------------------------------------------------------------- */ +typedef struct { + uint16_t audio_format; + uint16_t num_channels; + uint32_t sample_rate; + uint16_t bits_per_sample; + uint32_t data_offset; + uint32_t data_size; +} audio_wav_info_t; + +static void wav_write_u16(uint8_t *dst, uint16_t v) +{ + dst[0] = (uint8_t)(v & 0xFF); + dst[1] = (uint8_t)((v >> 8) & 0xFF); +} + +static void wav_write_u32(uint8_t *dst, uint32_t v) +{ + dst[0] = (uint8_t)(v & 0xFF); + dst[1] = (uint8_t)((v >> 8) & 0xFF); + dst[2] = (uint8_t)((v >> 16) & 0xFF); + dst[3] = (uint8_t)((v >> 24) & 0xFF); +} + +static uint16_t wav_read_u16(const uint8_t *src) +{ + return (uint16_t)src[0] | ((uint16_t)src[1] << 8); +} + +static uint32_t wav_read_u32(const uint8_t *src) +{ + return (uint32_t)src[0] | ((uint32_t)src[1] << 8) | + ((uint32_t)src[2] << 16) | ((uint32_t)src[3] << 24); +} + +static void wav_build_header(uint8_t *hdr, uint32_t data_size, + uint32_t sample_rate, uint16_t channels, + uint16_t bytes_per_sample, uint16_t bits_per_sample) +{ + uint32_t byte_rate = sample_rate * channels * bytes_per_sample; + uint16_t block_align = channels * bytes_per_sample; + + memcpy(hdr + 0, "RIFF", 4); + wav_write_u32(hdr + 4, data_size + 36); + memcpy(hdr + 8, "WAVE", 4); + memcpy(hdr + 12, "fmt ", 4); + wav_write_u32(hdr + 16, 16); + wav_write_u16(hdr + 20, 1); + wav_write_u16(hdr + 22, channels); + wav_write_u32(hdr + 24, sample_rate); + wav_write_u32(hdr + 28, byte_rate); + wav_write_u16(hdr + 32, block_align); + wav_write_u16(hdr + 34, bits_per_sample); + memcpy(hdr + 36, "data", 4); + wav_write_u32(hdr + 40, data_size); +} + +static esp_err_t wav_parse(FILE *f, audio_wav_info_t *info) +{ + uint8_t hdr[12]; + + memset(info, 0, sizeof(*info)); + if (fread(hdr, 1, sizeof(hdr), f) != sizeof(hdr)) { + return ESP_FAIL; + } + if (memcmp(hdr, "RIFF", 4) != 0 || memcmp(hdr + 8, "WAVE", 4) != 0) { + return ESP_ERR_INVALID_RESPONSE; + } + + while (1) { + uint8_t chunk_hdr[8]; + uint32_t chunk_size; + + if (fread(chunk_hdr, 1, sizeof(chunk_hdr), f) != sizeof(chunk_hdr)) { + break; + } + chunk_size = wav_read_u32(chunk_hdr + 4); + + if (memcmp(chunk_hdr, "fmt ", 4) == 0) { + uint8_t fmt[16]; + if (chunk_size < sizeof(fmt) || fread(fmt, 1, sizeof(fmt), f) != sizeof(fmt)) { + return ESP_FAIL; + } + info->audio_format = wav_read_u16(fmt + 0); + info->num_channels = wav_read_u16(fmt + 2); + info->sample_rate = wav_read_u32(fmt + 4); + info->bits_per_sample = wav_read_u16(fmt + 14); + if (chunk_size > sizeof(fmt)) { + fseek(f, (long)(chunk_size - sizeof(fmt)), SEEK_CUR); + } + } else if (memcmp(chunk_hdr, "data", 4) == 0) { + info->data_offset = (uint32_t)ftell(f); + info->data_size = chunk_size; + fseek(f, (long)chunk_size, SEEK_CUR); + } else { + fseek(f, (long)chunk_size, SEEK_CUR); + } + + if (chunk_size & 1U) { + fseek(f, 1, SEEK_CUR); + } + } + + if (info->data_offset == 0 || info->data_size == 0) { + return ESP_ERR_INVALID_SIZE; + } + return ESP_OK; +} + +/* -------------------------------------------------------------------------- + * Helpers + * -------------------------------------------------------------------------- */ +static bool audio_path_valid(const char *path, const char *ext) +{ + size_t base_len = strlen(AUDIO_BASE_PATH); + size_t ext_len = strlen(ext); + size_t len; + + if (!path || strstr(path, "..")) { + return false; + } + if (strncmp(path, AUDIO_BASE_PATH, base_len) != 0) { + return false; + } + len = strlen(path); + return len > ext_len && strcmp(path + len - ext_len, ext) == 0; +} + +static void *lua_audio_check_lightuserdata_arg(lua_State *L, int index, const char *name) +{ + void *ptr = lua_touserdata(L, index); + + luaL_argcheck(L, ptr != NULL, index, name); + return ptr; +} + +static uint32_t lua_audio_check_u32_arg(lua_State *L, int index, const char *name) +{ + lua_Integer value = luaL_checkinteger(L, index); + + if (value <= 0 || value > UINT32_MAX) { + luaL_error(L, "audio %s must be a positive integer", name); + return 0; + } + return (uint32_t)value; +} + +static uint8_t lua_audio_check_u8_arg(lua_State *L, int index, const char *name) +{ + lua_Integer value = luaL_checkinteger(L, index); + + if (value <= 0 || value > UINT8_MAX) { + luaL_error(L, "audio %s must be a positive integer", name); + return 0; + } + return (uint8_t)value; +} + +static esp_err_t audio_validate_sample_info(audio_lua_handle_t *handle) +{ + if (handle->sample_rate == 0 || handle->channels == 0 || handle->bits_per_sample == 0) { + return ESP_ERR_INVALID_ARG; + } + if ((handle->bits_per_sample % 8) != 0) { + return ESP_ERR_INVALID_ARG; + } + handle->bytes_per_sample = (uint8_t)(handle->bits_per_sample / 8); + if (handle->bytes_per_sample == 0) { + return ESP_ERR_INVALID_ARG; + } + return ESP_OK; +} + +static esp_err_t audio_validate_handle_formats(const audio_lua_handle_t *input, + const audio_lua_handle_t *output) +{ + if (input->sample_rate != output->sample_rate || + input->channels != output->channels || + input->bits_per_sample != output->bits_per_sample) { + return ESP_ERR_INVALID_ARG; + } + return ESP_OK; +} + +static esp_err_t audio_handle_activate(audio_lua_handle_t *handle) +{ + esp_codec_dev_sample_info_t fs = { + .sample_rate = handle->sample_rate, + .channel = handle->channels, + .bits_per_sample = handle->bits_per_sample, + }; + int ret; + + if (audio_validate_sample_info(handle) != ESP_OK) { + return ESP_ERR_INVALID_ARG; + } + + ret = esp_codec_dev_open(handle->codec_dev, &fs); + if (ret != ESP_CODEC_DEV_OK) { + return ESP_FAIL; + } + if (handle->kind == AUDIO_HANDLE_OUTPUT) { + ret = esp_codec_dev_set_out_vol(handle->codec_dev, handle->out_vol); + } else { + ret = esp_codec_dev_set_in_gain(handle->codec_dev, handle->in_gain_db); + } + if (ret != ESP_CODEC_DEV_OK && ret != ESP_CODEC_DEV_NOT_SUPPORT) { + esp_codec_dev_close(handle->codec_dev); + return ESP_FAIL; + } + return ESP_OK; +} + +static audio_lua_handle_t *lua_audio_check_any_handle(lua_State *L, int idx, const char *what) +{ + audio_lua_handle_t *handle = + (audio_lua_handle_t *)luaL_checkudata(L, idx, AUDIO_HANDLE_METATABLE); + + if (handle->codec_dev == NULL) { + luaL_error(L, "audio %s: invalid or closed handle", what); + return NULL; + } + return handle; +} + +static audio_lua_handle_t *lua_audio_check_handle(lua_State *L, int idx, audio_handle_kind_t kind, const char *what) +{ + audio_lua_handle_t *handle = lua_audio_check_any_handle(L, idx, what); + + if (handle->kind != kind) { + luaL_error(L, "audio %s: wrong handle type", what); + return NULL; + } + return handle; +} + +static void lua_audio_push_handle(lua_State *L, const audio_lua_handle_t *handle) +{ + audio_lua_handle_t *ud = + (audio_lua_handle_t *)lua_newuserdata(L, sizeof(*ud)); + + *ud = *handle; + luaL_getmetatable(L, AUDIO_HANDLE_METATABLE); + lua_setmetatable(L, -2); +} + +static int lua_audio_handle_gc(lua_State *L) +{ + audio_lua_handle_t *handle = + (audio_lua_handle_t *)luaL_testudata(L, 1, AUDIO_HANDLE_METATABLE); + + if (handle && handle->codec_dev != NULL) { + esp_codec_dev_close(handle->codec_dev); + handle->codec_dev = NULL; + } + return 0; +} + +/* -------------------------------------------------------------------------- + * audio.new_input(codec_dev_handle, sample_rate, channels, bits_per_sample [, gain_db]) + * -> handle | nil, errmsg + * -------------------------------------------------------------------------- */ +static int lua_audio_new_input(lua_State *L) +{ + audio_lua_handle_t handle = {0}; + + handle.kind = AUDIO_HANDLE_INPUT; + handle.codec_dev = (esp_codec_dev_handle_t)lua_audio_check_lightuserdata_arg( + L, 1, "audio codec_dev_handle lightuserdata expected"); + handle.sample_rate = lua_audio_check_u32_arg(L, 2, "sample_rate"); + handle.channels = lua_audio_check_u8_arg(L, 3, "channels"); + handle.bits_per_sample = lua_audio_check_u8_arg(L, 4, "bits_per_sample"); + handle.in_gain_db = (float)luaL_optnumber(L, 5, AUDIO_DEFAULT_GAIN_DB); + + if (audio_handle_activate(&handle) != ESP_OK) { + lua_pushnil(L); + lua_pushstring(L, "audio new_input: failed to activate input device"); + return 2; + } + lua_audio_push_handle(L, &handle); + return 1; +} + +/* -------------------------------------------------------------------------- + * audio.new_output(codec_dev_handle, sample_rate, channels, bits_per_sample [, volume]) + * -> handle | nil, errmsg + * -------------------------------------------------------------------------- */ +static int lua_audio_new_output(lua_State *L) +{ + audio_lua_handle_t handle = {0}; + + handle.kind = AUDIO_HANDLE_OUTPUT; + handle.codec_dev = (esp_codec_dev_handle_t)lua_audio_check_lightuserdata_arg( + L, 1, "audio codec_dev_handle lightuserdata expected"); + handle.sample_rate = lua_audio_check_u32_arg(L, 2, "sample_rate"); + handle.channels = lua_audio_check_u8_arg(L, 3, "channels"); + handle.bits_per_sample = lua_audio_check_u8_arg(L, 4, "bits_per_sample"); + handle.out_vol = (int)luaL_optinteger(L, 5, AUDIO_DEFAULT_VOL); + + if (handle.out_vol < 0 || handle.out_vol > 100) { + lua_pushnil(L); + lua_pushstring(L, "audio new_output: volume must be 0..100"); + return 2; + } + if (audio_handle_activate(&handle) != ESP_OK) { + lua_pushnil(L); + lua_pushstring(L, "audio new_output: failed to activate output device"); + return 2; + } + lua_audio_push_handle(L, &handle); + return 1; +} + +/* -------------------------------------------------------------------------- + * audio.close(handle) -> true | nil, errmsg + * -------------------------------------------------------------------------- */ +static int lua_audio_close(lua_State *L) +{ + audio_lua_handle_t *handle = lua_audio_check_any_handle(L, 1, "close"); + + esp_codec_dev_close(handle->codec_dev); + handle->codec_dev = NULL; + + lua_pushboolean(L, 1); + return 1; +} + +/* -------------------------------------------------------------------------- + * audio.play_wav(output_handle, path) -> nil + * -------------------------------------------------------------------------- */ +static int lua_audio_play_wav(lua_State *L) +{ + audio_lua_handle_t *dac = lua_audio_check_handle(L, 1, AUDIO_HANDLE_OUTPUT, "play_wav"); + const char *path = luaL_checkstring(L, 2); + FILE *f = NULL; + uint8_t *buf = NULL; + audio_wav_info_t info = {0}; + + if (!audio_path_valid(path, ".wav")) { + return luaL_error(L, "audio play_wav: path must be a .wav file under %s", AUDIO_BASE_PATH); + } + + f = fopen(path, "rb"); + if (!f) { + luaL_error(L, "audio play_wav: cannot open %s", path); + goto cleanup; + } + + if (wav_parse(f, &info) != ESP_OK) { + luaL_error(L, "audio play_wav: invalid WAV file"); + goto cleanup; + } + if (info.audio_format != 1 || + info.num_channels != dac->channels || + info.sample_rate != dac->sample_rate || + info.bits_per_sample != dac->bits_per_sample) { + luaL_error(L, "audio play_wav: WAV format does not match output handle configuration"); + goto cleanup; + } + + buf = malloc(AUDIO_CHUNK_BYTES); + if (!buf) { + luaL_error(L, "audio play_wav: out of memory"); + goto cleanup; + } + + fseek(f, (long)info.data_offset, SEEK_SET); + uint32_t remaining = info.data_size; + while (remaining > 0) { + size_t chunk = remaining < AUDIO_CHUNK_BYTES ? remaining : AUDIO_CHUNK_BYTES; + size_t read = fread(buf, 1, chunk, f); + if (read == 0) { + luaL_error(L, "audio play_wav: truncated data"); + goto cleanup; + } + if (esp_codec_dev_write(dac->codec_dev, buf, (int)read) != ESP_CODEC_DEV_OK) { + luaL_error(L, "audio play_wav: write failed"); + goto cleanup; + } + remaining -= (uint32_t)read; + } + +cleanup: + free(buf); + if (f) { + fclose(f); + } + return 0; +} + +/* -------------------------------------------------------------------------- + * audio.record_wav(input_handle, path, duration_ms) -> { path, duration_ms, bytes } + * -------------------------------------------------------------------------- */ +static int lua_audio_record_wav(lua_State *L) +{ + audio_lua_handle_t *adc = lua_audio_check_handle(L, 1, AUDIO_HANDLE_INPUT, "record_wav"); + const char *path = luaL_checkstring(L, 2); + uint32_t duration_ms = (uint32_t)luaL_checkinteger(L, 3); + FILE *f = NULL; + uint8_t *buf = NULL; + uint32_t total_bytes = 0; + uint8_t wav_hdr[44]; + + if (!audio_path_valid(path, ".wav")) { + return luaL_error(L, "audio record_wav: path must be a .wav file under %s", AUDIO_BASE_PATH); + } + if (duration_ms == 0) { + return luaL_error(L, "audio record_wav: duration_ms must be positive"); + } + + buf = malloc(AUDIO_CHUNK_BYTES); + if (!buf) { + luaL_error(L, "audio record_wav: out of memory"); + goto cleanup; + } + + remove(path); + f = fopen(path, "wb"); + if (!f) { + luaL_error(L, "audio record_wav: cannot open %s for writing", path); + goto cleanup; + } + memset(wav_hdr, 0, sizeof(wav_hdr)); + if (fwrite(wav_hdr, 1, sizeof(wav_hdr), f) != sizeof(wav_hdr)) { + luaL_error(L, "audio record_wav: cannot write WAV header placeholder"); + goto cleanup; + } + + uint32_t total_target_bytes = + (uint32_t)((uint64_t)adc->sample_rate * duration_ms / 1000) * + adc->channels * adc->bytes_per_sample; + + while (total_bytes < total_target_bytes) { + uint32_t chunk = total_target_bytes - total_bytes; + if (chunk > AUDIO_CHUNK_BYTES) { + chunk = AUDIO_CHUNK_BYTES; + } + if (esp_codec_dev_read(adc->codec_dev, buf, (int)chunk) != ESP_CODEC_DEV_OK) { + luaL_error(L, "audio record_wav: read failed"); + goto cleanup; + } + if (fwrite(buf, 1, chunk, f) != chunk) { + luaL_error(L, "audio record_wav: write to file failed"); + goto cleanup; + } + total_bytes += chunk; + } + + wav_build_header(wav_hdr, total_bytes, adc->sample_rate, adc->channels, + adc->bytes_per_sample, adc->bits_per_sample); + fseek(f, 0, SEEK_SET); + if (fwrite(wav_hdr, 1, sizeof(wav_hdr), f) != sizeof(wav_hdr)) { + luaL_error(L, "audio record_wav: cannot finalise WAV header"); + goto cleanup; + } + fclose(f); + f = NULL; + + free(buf); + buf = NULL; + + lua_newtable(L); + lua_pushstring(L, path); + lua_setfield(L, -2, "path"); + lua_pushinteger(L, duration_ms); + lua_setfield(L, -2, "duration_ms"); + lua_pushinteger(L, total_bytes); + lua_setfield(L, -2, "bytes"); + return 1; + +cleanup: + free(buf); + if (f) { + fclose(f); + remove(path); + } + return 0; +} + +/* -------------------------------------------------------------------------- + * audio.loopback(input_handle, output_handle [, duration_ms]) -> nil + * -------------------------------------------------------------------------- */ +static int lua_audio_loopback(lua_State *L) +{ + audio_lua_handle_t *adc = lua_audio_check_handle(L, 1, AUDIO_HANDLE_INPUT, "loopback"); + audio_lua_handle_t *dac = lua_audio_check_handle(L, 2, AUDIO_HANDLE_OUTPUT, "loopback"); + uint32_t duration_ms = (uint32_t)luaL_optinteger(L, 3, 1000); + uint8_t *buf = NULL; + + if (audio_validate_handle_formats(adc, dac) != ESP_OK) { + return luaL_error(L, "audio loopback: input/output handle formats must match"); + } + + buf = malloc(AUDIO_CHUNK_BYTES); + if (!buf) { + luaL_error(L, "audio loopback: out of memory"); + goto cleanup; + } + + uint32_t total_bytes = + (uint32_t)((uint64_t)adc->sample_rate * duration_ms / 1000) * + adc->channels * adc->bytes_per_sample; + uint32_t transferred = 0; + + ESP_LOGI(TAG, "loopback start: %" PRIu32 " ms (%" PRIu32 " bytes)", duration_ms, total_bytes); + while (transferred < total_bytes) { + uint32_t chunk = total_bytes - transferred; + if (chunk > AUDIO_CHUNK_BYTES) { + chunk = AUDIO_CHUNK_BYTES; + } + + if (esp_codec_dev_read(adc->codec_dev, buf, (int)chunk) != ESP_CODEC_DEV_OK) { + luaL_error(L, "audio loopback: input read failed"); + goto cleanup; + } + if (esp_codec_dev_write(dac->codec_dev, buf, (int)chunk) != ESP_CODEC_DEV_OK) { + luaL_error(L, "audio loopback: output write failed"); + goto cleanup; + } + transferred += chunk; + } + ESP_LOGI(TAG, "loopback done"); + +cleanup: + free(buf); + return 0; +} + +/* -------------------------------------------------------------------------- + * audio.set_volume(output_handle, pct) -> nil + * -------------------------------------------------------------------------- */ +static int lua_audio_set_volume(lua_State *L) +{ + audio_lua_handle_t *dac = lua_audio_check_handle(L, 1, AUDIO_HANDLE_OUTPUT, "set_volume"); + int vol = (int)luaL_checkinteger(L, 2); + + if (vol < 0 || vol > 100) { + return luaL_error(L, "audio set_volume: volume must be 0..100"); + } + if (esp_codec_dev_set_out_vol(dac->codec_dev, vol) != ESP_CODEC_DEV_OK) { + return luaL_error(L, "audio set_volume: set failed"); + } + dac->out_vol = vol; + return 0; +} + +/* -------------------------------------------------------------------------- + * audio.get_volume(output_handle) -> pct + * -------------------------------------------------------------------------- */ +static int lua_audio_get_volume(lua_State *L) +{ + audio_lua_handle_t *dac = lua_audio_check_handle(L, 1, AUDIO_HANDLE_OUTPUT, "get_volume"); + int vol = 0; + + if (esp_codec_dev_get_out_vol(dac->codec_dev, &vol) != ESP_CODEC_DEV_OK) { + return luaL_error(L, "audio get_volume: get failed"); + } + lua_pushinteger(L, vol); + return 1; +} + +/* -------------------------------------------------------------------------- + * audio.set_mute(output_handle, bool) -> nil + * -------------------------------------------------------------------------- */ +static int lua_audio_set_mute(lua_State *L) +{ + audio_lua_handle_t *dac = lua_audio_check_handle(L, 1, AUDIO_HANDLE_OUTPUT, "set_mute"); + bool mute = lua_toboolean(L, 2); + + if (esp_codec_dev_set_out_mute(dac->codec_dev, mute) != ESP_CODEC_DEV_OK) { + return luaL_error(L, "audio set_mute: set failed"); + } + return 0; +} + +/* -------------------------------------------------------------------------- + * audio.set_gain(input_handle, db) -> nil + * -------------------------------------------------------------------------- */ +static int lua_audio_set_gain(lua_State *L) +{ + audio_lua_handle_t *adc = lua_audio_check_handle(L, 1, AUDIO_HANDLE_INPUT, "set_gain"); + float db = (float)luaL_checknumber(L, 2); + + if (esp_codec_dev_set_in_gain(adc->codec_dev, db) != ESP_CODEC_DEV_OK) { + return luaL_error(L, "audio set_gain: set failed"); + } + adc->in_gain_db = db; + return 0; +} + +/* -------------------------------------------------------------------------- + * audio.mic_read_level(input_handle [, duration_ms]) -> { rms, peak, duration_ms } + * -------------------------------------------------------------------------- */ +static int lua_audio_mic_read_level(lua_State *L) +{ + audio_lua_handle_t *adc = lua_audio_check_handle(L, 1, AUDIO_HANDLE_INPUT, "mic_read_level"); + uint32_t duration_ms = (uint32_t)luaL_optinteger(L, 2, 100); + uint8_t *buf = NULL; + uint32_t total_bytes; + int64_t sum_sq = 0; + int32_t peak = 0; + uint32_t n_samples = 0; + + if (duration_ms == 0) { + return luaL_error(L, "audio mic_read_level: duration_ms must be positive"); + } + if (adc->bits_per_sample != 16) { + return luaL_error(L, "audio mic_read_level: only 16-bit PCM input is supported"); + } + + total_bytes = + (uint32_t)((uint64_t)adc->sample_rate * duration_ms / 1000) * + adc->channels * adc->bytes_per_sample; + + buf = malloc(AUDIO_CHUNK_BYTES); + if (!buf) { + luaL_error(L, "audio mic_read_level: out of memory"); + goto cleanup; + } + + uint32_t captured = 0; + while (captured < total_bytes) { + uint32_t chunk = total_bytes - captured; + if (chunk > AUDIO_CHUNK_BYTES) { + chunk = AUDIO_CHUNK_BYTES; + } + + if (esp_codec_dev_read(adc->codec_dev, buf, (int)chunk) != ESP_CODEC_DEV_OK) { + luaL_error(L, "audio mic_read_level: read failed"); + goto cleanup; + } + + const int16_t *samples = (const int16_t *)buf; + uint32_t n = chunk / sizeof(int16_t); + for (uint32_t i = 0; i < n; i++) { + int32_t s = samples[i]; + sum_sq += (int64_t)s * s; + if (s < 0) { + s = -s; + } + if (s > peak) { + peak = s; + } + } + n_samples += n; + captured += chunk; + } + +cleanup: + free(buf); + int32_t rms = (n_samples > 0) ? (int32_t)sqrt((double)sum_sq / n_samples) : 0; + + lua_newtable(L); + lua_pushinteger(L, rms); + lua_setfield(L, -2, "rms"); + lua_pushinteger(L, peak); + lua_setfield(L, -2, "peak"); + lua_pushinteger(L, duration_ms); + lua_setfield(L, -2, "duration_ms"); + return 1; +} + +/* -------------------------------------------------------------------------- + * Module registration + * -------------------------------------------------------------------------- */ +int luaopen_audio(lua_State *L) +{ + static const luaL_Reg funcs[] = { + {"new_input", lua_audio_new_input}, + {"new_output", lua_audio_new_output}, + {"close", lua_audio_close}, + {"play_wav", lua_audio_play_wav}, + {"record_wav", lua_audio_record_wav}, + {"loopback", lua_audio_loopback}, + {"set_volume", lua_audio_set_volume}, + {"get_volume", lua_audio_get_volume}, + {"set_mute", lua_audio_set_mute}, + {"set_gain", lua_audio_set_gain}, + {"mic_read_level", lua_audio_mic_read_level}, + {NULL, NULL}, + }; + if (luaL_newmetatable(L, AUDIO_HANDLE_METATABLE)) { + lua_pushcfunction(L, lua_audio_handle_gc); + lua_setfield(L, -2, "__gc"); + } + lua_pop(L, 1); + lua_newtable(L); + luaL_setfuncs(L, funcs, 0); + return 1; +} + +esp_err_t lua_module_audio_register(void) +{ + return cap_lua_register_module("audio", luaopen_audio); +} diff --git a/components/lua_modules/lua_module_audio/skills/lua_module_audio.md b/components/lua_modules/lua_module_audio/skills/lua_module_audio.md new file mode 100644 index 0000000..77d9e0e --- /dev/null +++ b/components/lua_modules/lua_module_audio/skills/lua_module_audio.md @@ -0,0 +1,28 @@ +# Lua Audio + +This skill describes how to correctly use audio when writing Lua scripts. + +## How to call +- Import it with `local audio = require("audio")` +- Call `audio.new_input(codec_dev_handle, sample_rate, channels, bits_per_sample [, gain_db])` to create an input handle +- Call `audio.new_output(codec_dev_handle, sample_rate, channels, bits_per_sample [, volume])` to create an output handle +- Call `audio.play_wav(output_handle, path)` to play a WAV file under `/fatfs/data/` +- Call `audio.record_wav(input_handle, path, duration_ms)` to record audio to a WAV file under `/fatfs/data/` +- Call `audio.loopback(input_handle, output_handle [, duration_ms])` to route input to output for monitoring +- Call `audio.set_volume(output_handle, pct)`, `audio.get_volume(output_handle)`, `audio.set_mute(output_handle, enabled)`, or `audio.set_gain(input_handle, db)` to adjust levels +- Call `audio.mic_read_level(input_handle [, duration_ms])` to read microphone level statistics such as `rms` and `peak` +- Call `audio.close(handle)` when a created handle is no longer needed + +## Example +```lua +local audio = require("audio") +local bm = require("board_manager") + +local output_codec, rate, channels, bits = + bm.get_audio_codec_output_params("audio_dac") +local output = audio.new_output(output_codec, rate, channels, bits) + +audio.set_volume(output, 60) +audio.play_wav(output, "/fatfs/data/test.wav") +audio.close(output) +``` diff --git a/components/lua_modules/lua_module_audio/skills/skills_list.json b/components/lua_modules/lua_module_audio/skills/skills_list.json new file mode 100644 index 0000000..938bbd9 --- /dev/null +++ b/components/lua_modules/lua_module_audio/skills/skills_list.json @@ -0,0 +1,13 @@ +{ + "skills": [ + { + "id": "lua_module_audio", + "file": "lua_module_audio.md", + "title": "lua_module_audio", + "summary": "How to create audio input/output handles and play, record, or inspect audio from Lua.", + "cap_groups": [ + "cap_lua" + ] + } + ] +} diff --git a/components/lua_modules/lua_module_board_manager/CMakeLists.txt b/components/lua_modules/lua_module_board_manager/CMakeLists.txt new file mode 100644 index 0000000..c60148f --- /dev/null +++ b/components/lua_modules/lua_module_board_manager/CMakeLists.txt @@ -0,0 +1,9 @@ +idf_component_register( + SRC_DIRS + "." + INCLUDE_DIRS + "include" + REQUIRES + cap_lua + espressif__esp_board_manager +) diff --git a/components/lua_modules/lua_module_board_manager/include/lua_module_board_manager.h b/components/lua_modules/lua_module_board_manager/include/lua_module_board_manager.h new file mode 100644 index 0000000..84316c4 --- /dev/null +++ b/components/lua_modules/lua_module_board_manager/include/lua_module_board_manager.h @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "lua.h" +#include "esp_err.h" + +int luaopen_board_manager(lua_State *L); +esp_err_t lua_module_board_manager_register(void); diff --git a/components/lua_modules/lua_module_board_manager/lua_module_board_manager.c b/components/lua_modules/lua_module_board_manager/lua_module_board_manager.c new file mode 100644 index 0000000..cfcedc0 --- /dev/null +++ b/components/lua_modules/lua_module_board_manager/lua_module_board_manager.c @@ -0,0 +1,464 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "lua_module_board_manager.h" + +#include +#include "esp_err.h" +#include "lauxlib.h" +#include "esp_board_manager_includes.h" +#include "cap_lua.h" + +/* -------------------------------------------------------------------------- + * Helpers + * -------------------------------------------------------------------------- */ + +/** Push nil + error message string, return 2. Convenience for error paths. */ +static int push_err(lua_State *L, esp_err_t err, const char *msg) +{ + lua_pushnil(L); + if (msg) { + lua_pushfstring(L, "%s: %s", msg, esp_err_to_name(err)); + } else { + lua_pushstring(L, esp_err_to_name(err)); + } + return 2; +} + +static esp_err_t lua_module_board_manager_get_camera_paths(const char **dev_path, + const char **meta_path) +{ +#if CONFIG_ESP_BOARD_DEV_CAMERA_SUPPORT + dev_camera_handle_t *camera_handle = NULL; + esp_err_t err; + + if (dev_path == NULL) { + return ESP_ERR_INVALID_ARG; + } + + *dev_path = NULL; + if (meta_path != NULL) { + *meta_path = NULL; + } + + err = esp_board_manager_get_device_handle(ESP_BOARD_DEVICE_NAME_CAMERA, + (void **)&camera_handle); + if (err != ESP_OK) { + return err; + } + if (camera_handle == NULL || camera_handle->dev_path == NULL) { + return ESP_ERR_NOT_FOUND; + } + + *dev_path = camera_handle->dev_path; + if (meta_path != NULL) { + *meta_path = camera_handle->meta_path; + } + return ESP_OK; +#else + if (dev_path != NULL) { + *dev_path = NULL; + } + if (meta_path != NULL) { + *meta_path = NULL; + } + return ESP_ERR_NOT_SUPPORTED; +#endif +} + +/* -------------------------------------------------------------------------- + * board_manager.get_board_info() -> table + * + * Returns a table: + * { name, chip, version, description, manufacturer } + * -------------------------------------------------------------------------- */ +static int lua_bm_get_board_info(lua_State *L) +{ + esp_board_info_t info = {0}; + esp_err_t err = esp_board_manager_get_board_info(&info); + if (err != ESP_OK) { + return push_err(L, err, "get_board_info"); + } + lua_newtable(L); + lua_pushstring(L, info.name ? info.name : ""); + lua_setfield(L, -2, "name"); + lua_pushstring(L, info.chip ? info.chip : ""); + lua_setfield(L, -2, "chip"); + lua_pushstring(L, info.version ? info.version : ""); + lua_setfield(L, -2, "version"); + lua_pushstring(L, info.description ? info.description : ""); + lua_setfield(L, -2, "description"); + lua_pushstring(L, info.manufacturer ? info.manufacturer : ""); + lua_setfield(L, -2, "manufacturer"); + return 1; +} + +/* -------------------------------------------------------------------------- + * board_manager.init_device(name) -> true | nil, errmsg + * -------------------------------------------------------------------------- */ +static int lua_bm_init_device(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + esp_err_t err = esp_board_manager_init_device_by_name(name); + if (err != ESP_OK) { + return push_err(L, err, name); + } + lua_pushboolean(L, 1); + return 1; +} + +/* -------------------------------------------------------------------------- + * board_manager.deinit_device(name) -> true | nil, errmsg + * -------------------------------------------------------------------------- */ +static int lua_bm_deinit_device(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + esp_err_t err = esp_board_manager_deinit_device_by_name(name); + if (err != ESP_OK) { + return push_err(L, err, name); + } + lua_pushboolean(L, 1); + return 1; +} + +/* -------------------------------------------------------------------------- + * board_manager.get_device_handle(name) -> lightuserdata | nil, errmsg + * + * Returns the raw device handle as a lightuserdata pointer. + * Useful when another C-backed Lua module needs to wrap it. + * -------------------------------------------------------------------------- */ +static int lua_bm_get_device_handle(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + void *handle = NULL; + esp_err_t err = esp_board_manager_get_device_handle(name, &handle); + if (err != ESP_OK) { + return push_err(L, err, name); + } + if (handle == NULL) { + lua_pushnil(L); + lua_pushstring(L, "device handle is NULL"); + return 2; + } + lua_pushlightuserdata(L, handle); + return 1; +} + +/* -------------------------------------------------------------------------- + * board_manager.get_device_config_handle(name) -> lightuserdata | nil, errmsg + * + * Returns the raw device config pointer as lightuserdata. + * Useful for passing board-manager-generated config structs into other modules. + * -------------------------------------------------------------------------- */ +static int lua_bm_get_device_config_handle(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + void *config = NULL; + esp_err_t err = esp_board_manager_get_device_config(name, &config); + if (err != ESP_OK) { + return push_err(L, err, name); + } + if (config == NULL) { + lua_pushnil(L); + lua_pushstring(L, "device config is NULL"); + return 2; + } + lua_pushlightuserdata(L, config); + return 1; +} + +/* -------------------------------------------------------------------------- + * board_manager.get_display_lcd_params(name) + * -> panel_handle, io_handle, lcd_width, lcd_height | nil, errmsg + * -------------------------------------------------------------------------- */ +static int lua_bm_get_display_lcd_params(lua_State *L) +{ +#ifdef CONFIG_ESP_BOARD_DEV_DISPLAY_LCD_SUPPORT + const char *name = luaL_checkstring(L, 1); + void *handle = NULL; + void *config = NULL; + esp_err_t err = esp_board_manager_get_device_handle(name, &handle); + if (err != ESP_OK) { + return push_err(L, err, name); + } + err = esp_board_manager_get_device_config(name, &config); + if (err != ESP_OK) { + return push_err(L, err, name); + } + + dev_display_lcd_handles_t *lcd_handles = (dev_display_lcd_handles_t *)handle; + dev_display_lcd_config_t *lcd_cfg = (dev_display_lcd_config_t *)config; + if (lcd_handles == NULL || lcd_cfg == NULL) { + lua_pushnil(L); + lua_pushfstring(L, "display_lcd '%s' handle/config is NULL", name); + return 2; + } + if (lcd_handles->panel_handle == NULL || lcd_handles->io_handle == NULL) { + lua_pushnil(L); + lua_pushfstring(L, "display_lcd '%s' panel/io handle is NULL", name); + return 2; + } + + lua_pushlightuserdata(L, lcd_handles->panel_handle); + lua_pushlightuserdata(L, lcd_handles->io_handle); + lua_pushinteger(L, lcd_cfg->lcd_width); + lua_pushinteger(L, lcd_cfg->lcd_height); + return 4; +#else + lua_pushnil(L); + lua_pushstring(L, "display lcd support is disabled"); + return 2; +#endif +} + +/* -------------------------------------------------------------------------- + * board_manager.get_lcd_touch_handle(name) -> lightuserdata | nil, errmsg + * + * Returns the raw esp_lcd_touch_handle_t from the board-manager wrapper handle. + * -------------------------------------------------------------------------- */ +static int lua_bm_get_lcd_touch_handle(lua_State *L) +{ +#ifdef CONFIG_ESP_BOARD_DEV_LCD_TOUCH_I2C_SUPPORT + const char *name = luaL_checkstring(L, 1); + void *handle = NULL; + esp_err_t err = esp_board_manager_get_device_handle(name, &handle); + if (err != ESP_OK) { + return push_err(L, err, name); + } + + dev_lcd_touch_i2c_handles_t *touch_handles = (dev_lcd_touch_i2c_handles_t *)handle; + if (touch_handles == NULL || touch_handles->touch_handle == NULL) { + lua_pushnil(L); + lua_pushfstring(L, "lcd_touch '%s' handle is NULL", name); + return 2; + } + + lua_pushlightuserdata(L, touch_handles->touch_handle); + return 1; +#else + lua_pushnil(L); + lua_pushstring(L, "lcd touch support is disabled"); + return 2; +#endif +} + +#ifdef CONFIG_ESP_BOARD_DEV_AUDIO_CODEC_SUPPORT +static esp_err_t lua_bm_get_i2s_audio_format(const periph_i2s_config_t *i2s_cfg, + uint32_t *sample_rate, + uint8_t *channels, + uint8_t *bits_per_sample) +{ + if (i2s_cfg == NULL || sample_rate == NULL || channels == NULL || bits_per_sample == NULL) { + return ESP_ERR_INVALID_ARG; + } + + if (i2s_cfg->mode == I2S_COMM_MODE_STD) { + *sample_rate = i2s_cfg->i2s_cfg.std.clk_cfg.sample_rate_hz; + *channels = (i2s_cfg->i2s_cfg.std.slot_cfg.slot_mode == I2S_SLOT_MODE_STEREO) ? 2 : 1; + *bits_per_sample = (uint8_t)i2s_cfg->i2s_cfg.std.slot_cfg.data_bit_width; + return ESP_OK; + } + +#if CONFIG_SOC_I2S_SUPPORTS_TDM + if (i2s_cfg->mode == I2S_COMM_MODE_TDM) { + *sample_rate = i2s_cfg->i2s_cfg.tdm.clk_cfg.sample_rate_hz; + *channels = (uint8_t)i2s_cfg->i2s_cfg.tdm.slot_cfg.total_slot; + *bits_per_sample = (uint8_t)i2s_cfg->i2s_cfg.tdm.slot_cfg.data_bit_width; + return ESP_OK; + } +#endif + +#if CONFIG_SOC_I2S_SUPPORTS_PDM_TX + if (i2s_cfg->mode == I2S_COMM_MODE_PDM && (i2s_cfg->direction & I2S_DIR_TX)) { + *sample_rate = i2s_cfg->i2s_cfg.pdm_tx.clk_cfg.sample_rate_hz; + *channels = (i2s_cfg->i2s_cfg.pdm_tx.slot_cfg.slot_mode == I2S_SLOT_MODE_STEREO) ? 2 : 1; + *bits_per_sample = (uint8_t)i2s_cfg->i2s_cfg.pdm_tx.slot_cfg.data_bit_width; + return ESP_OK; + } +#endif + +#if CONFIG_SOC_I2S_SUPPORTS_PDM_RX + if (i2s_cfg->mode == I2S_COMM_MODE_PDM && (i2s_cfg->direction & I2S_DIR_RX)) { + *sample_rate = i2s_cfg->i2s_cfg.pdm_rx.clk_cfg.sample_rate_hz; + *channels = (i2s_cfg->i2s_cfg.pdm_rx.slot_cfg.slot_mode == I2S_SLOT_MODE_STEREO) ? 2 : 1; + *bits_per_sample = (uint8_t)i2s_cfg->i2s_cfg.pdm_rx.slot_cfg.data_bit_width; + return ESP_OK; + } +#endif + + return ESP_ERR_NOT_SUPPORTED; +} + +static esp_err_t lua_bm_get_adc_audio_format(const board_codec_adc_t *adc_cfg, + uint32_t *sample_rate, + uint8_t *channels, + uint8_t *bits_per_sample) +{ + if (adc_cfg == NULL || sample_rate == NULL || channels == NULL || bits_per_sample == NULL) { + return ESP_ERR_INVALID_ARG; + } + if (adc_cfg->sample_rate_hz == 0 || adc_cfg->pattern_num == 0) { + return ESP_ERR_INVALID_ARG; + } + + *sample_rate = adc_cfg->sample_rate_hz; + *channels = adc_cfg->pattern_num; + *bits_per_sample = 16; + return ESP_OK; +} +#endif // CONFIG_ESP_BOARD_DEV_AUDIO_CODEC_SUPPORT + +static int lua_bm_get_audio_codec_common(lua_State *L, bool for_input) +{ +#ifdef CONFIG_ESP_BOARD_DEV_AUDIO_CODEC_SUPPORT + const char *name = luaL_checkstring(L, 1); + void *handle = NULL; + void *config = NULL; + void *periph_config = NULL; + esp_err_t err = esp_board_manager_get_device_handle(name, &handle); + if (err != ESP_OK) { + return push_err(L, err, name); + } + err = esp_board_manager_get_device_config(name, &config); + if (err != ESP_OK) { + return push_err(L, err, name); + } + + dev_audio_codec_handles_t *codec_handles = (dev_audio_codec_handles_t *)handle; + dev_audio_codec_config_t *codec_cfg = (dev_audio_codec_config_t *)config; + if (codec_handles == NULL || codec_cfg == NULL) { + lua_pushnil(L); + lua_pushfstring(L, "audio_codec '%s' handle/config is NULL", name); + return 2; + } + if (codec_handles->codec_dev == NULL) { + lua_pushnil(L); + lua_pushfstring(L, "audio_codec '%s' codec_dev handle is NULL", name); + return 2; + } + uint32_t sample_rate = 0; + uint8_t channels = 0; + uint8_t bits_per_sample = 0; + + if (codec_cfg->i2s_cfg.name != NULL) { + err = esp_board_manager_get_periph_config(codec_cfg->i2s_cfg.name, &periph_config); + if (err != ESP_OK) { + return push_err(L, err, codec_cfg->i2s_cfg.name); + } + + periph_i2s_config_t *i2s_cfg = (periph_i2s_config_t *)periph_config; + err = lua_bm_get_i2s_audio_format(i2s_cfg, &sample_rate, &channels, &bits_per_sample); + if (err != ESP_OK) { + return push_err(L, err, "audio codec i2s mode is not supported"); + } + } else if (for_input && codec_cfg->data_if_type == DEV_AUDIO_CODEC_DATA_IF_TYPE_ADC) { + err = lua_bm_get_adc_audio_format(&codec_cfg->adc_cfg, &sample_rate, &channels, &bits_per_sample); + if (err != ESP_OK) { + return push_err(L, err, "audio codec adc config is invalid"); + } + } else { + lua_pushnil(L); + lua_pushfstring(L, "audio_codec '%s' i2s config name is NULL", name); + return 2; + } + + if (for_input) { + if (!codec_cfg->adc_enabled) { + lua_pushnil(L); + lua_pushfstring(L, "audio_codec '%s' does not enable ADC input", name); + return 2; + } + lua_pushlightuserdata(L, codec_handles->codec_dev); + lua_pushinteger(L, (lua_Integer)sample_rate); + lua_pushinteger(L, (lua_Integer)channels); + lua_pushinteger(L, (lua_Integer)bits_per_sample); + lua_pushnumber(L, (lua_Number)codec_cfg->adc_init_gain); + return 5; + } + + if (!codec_cfg->dac_enabled) { + lua_pushnil(L); + lua_pushfstring(L, "audio_codec '%s' does not enable DAC output", name); + return 2; + } + lua_pushlightuserdata(L, codec_handles->codec_dev); + lua_pushinteger(L, (lua_Integer)sample_rate); + lua_pushinteger(L, (lua_Integer)channels); + lua_pushinteger(L, (lua_Integer)bits_per_sample); + return 4; +#else + (void)for_input; + lua_pushnil(L); + lua_pushstring(L, "audio codec support is disabled"); + return 2; +#endif +} + +/* -------------------------------------------------------------------------- + * board_manager.get_audio_codec_input_params(name) + * -> codec_dev_handle, sample_rate, channels, bits_per_sample, init_gain_db + * -------------------------------------------------------------------------- */ +static int lua_bm_get_audio_codec_input_params(lua_State *L) +{ + return lua_bm_get_audio_codec_common(L, true); +} + +/* -------------------------------------------------------------------------- + * board_manager.get_audio_codec_output_params(name) + * -> codec_dev_handle, sample_rate, channels, bits_per_sample + * -------------------------------------------------------------------------- */ +static int lua_bm_get_audio_codec_output_params(lua_State *L) +{ + return lua_bm_get_audio_codec_common(L, false); +} + +static int lua_bm_get_camera_paths(lua_State *L) +{ + const char *dev_path = NULL; + const char *meta_path = NULL; + esp_err_t err = lua_module_board_manager_get_camera_paths(&dev_path, &meta_path); + + if (err != ESP_OK) { + return push_err(L, err, "get_camera_paths"); + } + + lua_newtable(L); + lua_pushstring(L, dev_path); + lua_setfield(L, -2, "dev_path"); + if (meta_path != NULL) { + lua_pushstring(L, meta_path); + lua_setfield(L, -2, "meta_path"); + } + return 1; +} + +/* -------------------------------------------------------------------------- + * Module registration + * -------------------------------------------------------------------------- */ +int luaopen_board_manager(lua_State *L) +{ + static const luaL_Reg funcs[] = { + {"get_board_info", lua_bm_get_board_info}, + {"init_device", lua_bm_init_device}, + {"deinit_device", lua_bm_deinit_device}, + {"get_device_handle", lua_bm_get_device_handle}, + {"get_device_config_handle", lua_bm_get_device_config_handle}, + {"get_display_lcd_params", lua_bm_get_display_lcd_params}, + {"get_lcd_touch_handle", lua_bm_get_lcd_touch_handle}, + {"get_audio_codec_input_params", lua_bm_get_audio_codec_input_params}, + {"get_audio_codec_output_params", lua_bm_get_audio_codec_output_params}, + {"get_camera_paths", lua_bm_get_camera_paths}, + {NULL, NULL}, + }; + + lua_newtable(L); + luaL_setfuncs(L, funcs, 0); + return 1; +} + +esp_err_t lua_module_board_manager_register(void) +{ + return cap_lua_register_module("board_manager", luaopen_board_manager); +} diff --git a/components/lua_modules/lua_module_board_manager/skills/lua_module_board_manager.md b/components/lua_modules/lua_module_board_manager/skills/lua_module_board_manager.md new file mode 100644 index 0000000..fdb4a7c --- /dev/null +++ b/components/lua_modules/lua_module_board_manager/skills/lua_module_board_manager.md @@ -0,0 +1,30 @@ +# Lua Board Manager + +This skill describes how to correctly use board_manager when writing Lua scripts. + +## How to call +- Import it with `local board_manager = require("board_manager")` +- Call `board_manager.get_board_info()` to read board metadata such as `name`, `chip`, and `version` +- Call `board_manager.init_device(name)` before using a board-managed peripheral +- Call `board_manager.deinit_device(name)` when the peripheral is no longer needed +- Call `board_manager.get_device_handle(name)` or `board_manager.get_device_config_handle(name)` to resolve low-level handles +- Call `board_manager.get_display_lcd_params(name)` to get `panel_handle`, `io_handle`, `lcd_width`, and `lcd_height` +- Call `board_manager.get_lcd_touch_handle(name)` to get the raw LCD touch handle +- Call `board_manager.get_audio_codec_input_params(name)` or `board_manager.get_audio_codec_output_params(name)` to get codec handles and format parameters +- Call `board_manager.get_camera_paths()` to get camera device paths such as `dev_path` and `meta_path` + +## Example +```lua +local board_manager = require("board_manager") + +local info = board_manager.get_board_info() +print(info.name, info.chip) + +board_manager.init_device("display_lcd") +local panel_handle, io_handle, width, height = + board_manager.get_display_lcd_params("display_lcd") +print(width, height) + +local camera_paths = board_manager.get_camera_paths() +print(camera_paths.dev_path) +``` diff --git a/components/lua_modules/lua_module_board_manager/skills/skills_list.json b/components/lua_modules/lua_module_board_manager/skills/skills_list.json new file mode 100644 index 0000000..473ebaf --- /dev/null +++ b/components/lua_modules/lua_module_board_manager/skills/skills_list.json @@ -0,0 +1,13 @@ +{ + "skills": [ + { + "id": "lua_module_board_manager", + "file": "lua_module_board_manager.md", + "title": "lua_module_board_manager", + "summary": "How to query board information and resolve device handles and parameters from Lua.", + "cap_groups": [ + "cap_lua" + ] + } + ] +} diff --git a/components/lua_modules/lua_module_button/CMakeLists.txt b/components/lua_modules/lua_module_button/CMakeLists.txt new file mode 100644 index 0000000..fca9fb7 --- /dev/null +++ b/components/lua_modules/lua_module_button/CMakeLists.txt @@ -0,0 +1,8 @@ +idf_component_register( + SRC_DIRS + "." + INCLUDE_DIRS + "include" + REQUIRES + cap_lua +) diff --git a/components/lua_modules/lua_module_button/idf_component.yml b/components/lua_modules/lua_module_button/idf_component.yml new file mode 100644 index 0000000..e413a0e --- /dev/null +++ b/components/lua_modules/lua_module_button/idf_component.yml @@ -0,0 +1,3 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/button: "*" diff --git a/components/lua_modules/lua_module_button/include/lua_module_button.h b/components/lua_modules/lua_module_button/include/lua_module_button.h new file mode 100644 index 0000000..fa5b2c5 --- /dev/null +++ b/components/lua_modules/lua_module_button/include/lua_module_button.h @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once +#include "lua.h" +#include "esp_err.h" + +int luaopen_button(lua_State *L); +esp_err_t lua_module_button_register(void); diff --git a/components/lua_modules/lua_module_button/lua_module_button.c b/components/lua_modules/lua_module_button/lua_module_button.c new file mode 100644 index 0000000..f8b642f --- /dev/null +++ b/components/lua_modules/lua_module_button/lua_module_button.c @@ -0,0 +1,498 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "lua_module_button.h" + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "esp_err.h" +#include "esp_log.h" +#include "lauxlib.h" +#include "iot_button.h" +#include "button_gpio.h" +#include "cap_lua.h" + +static const char *TAG = "lua_button"; + +/* -------------------------------------------------------------------------- + * Constants + * -------------------------------------------------------------------------- */ +#define BTN_MAX_HANDLES 8 +#define BTN_EVENT_QUEUE_SIZE 16 +#define BTN_HANDLE_METATABLE "lua_button_handle" + +/* -------------------------------------------------------------------------- + * Internal types + * -------------------------------------------------------------------------- */ +typedef struct { + button_handle_t handle; + button_event_t event; + uint8_t repeat_count; + uint32_t pressed_time_ms; +} btn_event_item_t; + +typedef struct { + button_handle_t handle; + int lua_refs[BUTTON_EVENT_MAX]; /* LUA_NOREF if not registered */ + bool cbs_registered[BUTTON_EVENT_MAX]; +} btn_lua_reg_t; + +typedef struct { + button_handle_t handle; +} btn_lua_handle_ud_t; + +/* -------------------------------------------------------------------------- + * Module-level state + * -------------------------------------------------------------------------- */ +static btn_lua_reg_t s_regs[BTN_MAX_HANDLES]; +static int s_num_regs = 0; +static QueueHandle_t s_queue = NULL; + +/* -------------------------------------------------------------------------- + * Event name tables + * -------------------------------------------------------------------------- */ +static const char *const s_event_names[BUTTON_EVENT_MAX] = { + "press_down", + "press_up", + "press_repeat", + "press_repeat_done", + "single_click", + "double_click", + "multiple_click", + "long_press_start", + "long_press_hold", + "long_press_up", + "press_end", +}; + +static const char *btn_event_to_str(button_event_t ev) +{ + if ((unsigned)ev < BUTTON_EVENT_MAX) { + return s_event_names[ev]; + } + return "unknown"; +} + +static button_event_t btn_event_from_str(const char *s) +{ + for (int i = 0; i < BUTTON_EVENT_MAX; i++) { + if (strcmp(s, s_event_names[i]) == 0) { + return (button_event_t)i; + } + } + return BUTTON_EVENT_MAX; +} + +/* -------------------------------------------------------------------------- + * Registry helpers + * -------------------------------------------------------------------------- */ +static btn_lua_reg_t *btn_find_reg(button_handle_t handle) +{ + for (int i = 0; i < s_num_regs; i++) { + if (s_regs[i].handle == handle) { + return &s_regs[i]; + } + } + return NULL; +} + +static btn_lua_reg_t *btn_add_reg(button_handle_t handle) +{ + btn_lua_reg_t *reg = btn_find_reg(handle); + if (reg) { + return reg; + } + if (s_num_regs >= BTN_MAX_HANDLES) { + return NULL; + } + + reg = &s_regs[s_num_regs++]; + memset(reg, 0, sizeof(*reg)); + reg->handle = handle; + for (int i = 0; i < BUTTON_EVENT_MAX; i++) { + reg->lua_refs[i] = LUA_NOREF; + } + return reg; +} + +static void btn_remove_reg(lua_State *L, btn_lua_reg_t *reg) +{ + int idx = (int)(reg - s_regs); + if (idx < 0 || idx >= s_num_regs) { + return; + } + + for (int i = 0; i < BUTTON_EVENT_MAX; i++) { + if (reg->cbs_registered[i]) { + esp_err_t err = iot_button_unregister_cb(reg->handle, (button_event_t)i, NULL); + if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { + ESP_LOGW(TAG, "unregister_cb failed for event %s: %s", + btn_event_to_str((button_event_t)i), esp_err_to_name(err)); + } + } + if (reg->lua_refs[i] != LUA_NOREF) { + luaL_unref(L, LUA_REGISTRYINDEX, reg->lua_refs[i]); + } + } + + s_num_regs--; + if (idx != s_num_regs) { + s_regs[idx] = s_regs[s_num_regs]; + } + memset(&s_regs[s_num_regs], 0, sizeof(s_regs[s_num_regs])); +} + +static btn_lua_handle_ud_t *lua_btn_check_ud(lua_State *L, int idx) +{ + btn_lua_handle_ud_t *ud = + (btn_lua_handle_ud_t *)luaL_checkudata(L, idx, BTN_HANDLE_METATABLE); + + if (!ud || !ud->handle) { + luaL_error(L, "button handle expected"); + return NULL; + } + return ud; +} + +static button_handle_t lua_btn_check_handle(lua_State *L, int idx) +{ + return lua_btn_check_ud(L, idx)->handle; +} + +static int lua_btn_handle_gc(lua_State *L) +{ + btn_lua_handle_ud_t *ud = + (btn_lua_handle_ud_t *)luaL_testudata(L, 1, BTN_HANDLE_METATABLE); + btn_lua_reg_t *reg = NULL; + + if (!ud || !ud->handle) { + return 0; + } + + reg = btn_find_reg(ud->handle); + if (reg) { + btn_remove_reg(L, reg); + } + iot_button_delete(ud->handle); + ud->handle = NULL; + return 0; +} + +static void btn_c_event_cb(void *btn_handle, void *user_data) +{ + (void)user_data; + + if (!s_queue) { + return; + } + + button_handle_t handle = (button_handle_t)btn_handle; + btn_event_item_t item = { + .handle = handle, + .event = iot_button_get_event(handle), + .repeat_count = iot_button_get_repeat(handle), + .pressed_time_ms = iot_button_get_pressed_time(handle), + }; + + if (xQueueSend(s_queue, &item, 0) != pdTRUE) { + ESP_LOGW(TAG, "event queue full, dropped button event"); + } +} + +/* -------------------------------------------------------------------------- + * button.new(gpio_num [, active_level [, long_press_ms [, short_press_ms]]]) + * -> handle | nil, errmsg + * -------------------------------------------------------------------------- */ +static int lua_btn_new(lua_State *L) +{ + int gpio_num = (int)luaL_checkinteger(L, 1); + int active_level = (int)luaL_optinteger(L, 2, 0); + int long_press_ms = (int)luaL_optinteger(L, 3, 0); + int short_press_ms = (int)luaL_optinteger(L, 4, 0); + button_handle_t btn = NULL; + + if (active_level != 0 && active_level != 1) { + lua_pushnil(L); + lua_pushstring(L, "active_level must be 0 or 1"); + return 2; + } + + button_config_t btn_cfg = { + .long_press_time = (uint16_t)long_press_ms, + .short_press_time = (uint16_t)short_press_ms, + }; + button_gpio_config_t gpio_cfg = { + .gpio_num = gpio_num, + .active_level = (uint8_t)active_level, + .enable_power_save = false, + .disable_pull = false, + }; + + esp_err_t err = iot_button_new_gpio_device(&btn_cfg, &gpio_cfg, &btn); + if (err != ESP_OK || btn == NULL) { + lua_pushnil(L); + lua_pushfstring(L, "button.new failed for gpio %d: %s", + gpio_num, esp_err_to_name(err)); + return 2; + } + + if (!btn_add_reg(btn)) { + iot_button_delete(btn); + lua_pushnil(L); + lua_pushfstring(L, "too many button handles (max %d)", BTN_MAX_HANDLES); + return 2; + } + + btn_lua_handle_ud_t *ud = + (btn_lua_handle_ud_t *)lua_newuserdata(L, sizeof(*ud)); + ud->handle = btn; + luaL_getmetatable(L, BTN_HANDLE_METATABLE); + lua_setmetatable(L, -2); + return 1; +} + +/* -------------------------------------------------------------------------- + * button.close(handle) -> true | nil, errmsg + * -------------------------------------------------------------------------- */ +static int lua_btn_close(lua_State *L) +{ + btn_lua_handle_ud_t *ud = lua_btn_check_ud(L, 1); + button_handle_t handle = ud->handle; + btn_lua_reg_t *reg = btn_find_reg(handle); + esp_err_t err; + + if (!reg) { + lua_pushnil(L); + lua_pushstring(L, "invalid or closed button handle"); + return 2; + } + + btn_remove_reg(L, reg); + + err = iot_button_delete(handle); + if (err != ESP_OK) { + lua_pushnil(L); + lua_pushfstring(L, "button.close failed: %s", esp_err_to_name(err)); + return 2; + } + + ud->handle = NULL; + lua_pushboolean(L, 1); + return 1; +} + +/* -------------------------------------------------------------------------- + * button.get_key_level(handle) -> level + * -------------------------------------------------------------------------- */ +static int lua_btn_get_key_level(lua_State *L) +{ + button_handle_t handle = lua_btn_check_handle(L, 1); + btn_lua_reg_t *reg = btn_find_reg(handle); + + if (!reg) { + lua_pushnil(L); + lua_pushstring(L, "invalid or closed button handle"); + return 2; + } + + lua_pushinteger(L, iot_button_get_key_level(handle)); + return 1; +} + +/* -------------------------------------------------------------------------- + * button.on(handle, event_str, fn) -> true | nil, errmsg + * -------------------------------------------------------------------------- */ +static int lua_btn_on(lua_State *L) +{ + button_handle_t handle = lua_btn_check_handle(L, 1); + const char *event_str = luaL_checkstring(L, 2); + btn_lua_reg_t *reg = btn_find_reg(handle); + + luaL_checktype(L, 3, LUA_TFUNCTION); + + if (!reg) { + lua_pushnil(L); + lua_pushstring(L, "invalid or closed button handle"); + return 2; + } + + button_event_t ev = btn_event_from_str(event_str); + if (ev == BUTTON_EVENT_MAX) { + lua_pushnil(L); + lua_pushfstring(L, "unknown event '%s'", event_str); + return 2; + } + + if (!s_queue) { + s_queue = xQueueCreate(BTN_EVENT_QUEUE_SIZE, sizeof(btn_event_item_t)); + if (!s_queue) { + lua_pushnil(L); + lua_pushstring(L, "failed to create event queue"); + return 2; + } + } + + if (reg->lua_refs[ev] != LUA_NOREF) { + luaL_unref(L, LUA_REGISTRYINDEX, reg->lua_refs[ev]); + } + lua_pushvalue(L, 3); + reg->lua_refs[ev] = luaL_ref(L, LUA_REGISTRYINDEX); + + if (!reg->cbs_registered[ev]) { + esp_err_t err = iot_button_register_cb(handle, ev, NULL, btn_c_event_cb, NULL); + if (err != ESP_OK) { + luaL_unref(L, LUA_REGISTRYINDEX, reg->lua_refs[ev]); + reg->lua_refs[ev] = LUA_NOREF; + lua_pushnil(L); + lua_pushfstring(L, "register_cb failed for event '%s': %s", + event_str, esp_err_to_name(err)); + return 2; + } + reg->cbs_registered[ev] = true; + } + + lua_pushboolean(L, 1); + return 1; +} + +/* -------------------------------------------------------------------------- + * button.off(handle [, event_str]) -> true | nil, errmsg + * -------------------------------------------------------------------------- */ +static int lua_btn_off(lua_State *L) +{ + button_handle_t handle = lua_btn_check_handle(L, 1); + const char *event_str = luaL_optstring(L, 2, NULL); + btn_lua_reg_t *reg = btn_find_reg(handle); + + if (!reg) { + lua_pushnil(L); + lua_pushstring(L, "invalid or closed button handle"); + return 2; + } + + if (event_str) { + button_event_t ev = btn_event_from_str(event_str); + if (ev == BUTTON_EVENT_MAX) { + lua_pushnil(L); + lua_pushfstring(L, "unknown event '%s'", event_str); + return 2; + } + if (reg->lua_refs[ev] != LUA_NOREF) { + luaL_unref(L, LUA_REGISTRYINDEX, reg->lua_refs[ev]); + reg->lua_refs[ev] = LUA_NOREF; + } + if (reg->cbs_registered[ev]) { + esp_err_t err = iot_button_unregister_cb(handle, ev, NULL); + if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { + lua_pushnil(L); + lua_pushfstring(L, "unregister_cb failed for event '%s': %s", + event_str, esp_err_to_name(err)); + return 2; + } + reg->cbs_registered[ev] = false; + } + } else { + for (int i = 0; i < BUTTON_EVENT_MAX; i++) { + if (reg->lua_refs[i] != LUA_NOREF) { + luaL_unref(L, LUA_REGISTRYINDEX, reg->lua_refs[i]); + reg->lua_refs[i] = LUA_NOREF; + } + if (reg->cbs_registered[i]) { + esp_err_t err = iot_button_unregister_cb(handle, (button_event_t)i, NULL); + if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { + lua_pushnil(L); + lua_pushfstring(L, "unregister_cb failed for event '%s': %s", + btn_event_to_str((button_event_t)i), esp_err_to_name(err)); + return 2; + } + reg->cbs_registered[i] = false; + } + } + } + + lua_pushboolean(L, 1); + return 1; +} + +/* -------------------------------------------------------------------------- + * button.dispatch() -> count + * -------------------------------------------------------------------------- */ +static int lua_btn_dispatch(lua_State *L) +{ + int count = 0; + if (!s_queue) { + lua_pushinteger(L, 0); + return 1; + } + + btn_event_item_t item; + while (xQueueReceive(s_queue, &item, 0) == pdTRUE) { + btn_lua_reg_t *reg = btn_find_reg(item.handle); + if (!reg) { + continue; + } + + button_event_t ev = item.event; + if ((unsigned)ev >= BUTTON_EVENT_MAX) { + continue; + } + + int ref = reg->lua_refs[ev]; + if (ref == LUA_NOREF) { + continue; + } + + lua_rawgeti(L, LUA_REGISTRYINDEX, ref); + lua_newtable(L); + lua_pushlightuserdata(L, item.handle); + lua_setfield(L, -2, "handle"); + lua_pushstring(L, btn_event_to_str(ev)); + lua_setfield(L, -2, "event"); + lua_pushinteger(L, item.repeat_count); + lua_setfield(L, -2, "repeat_count"); + lua_pushinteger(L, item.pressed_time_ms); + lua_setfield(L, -2, "pressed_time_ms"); + + if (lua_pcall(L, 1, 0, 0) != LUA_OK) { + ESP_LOGW(TAG, "button callback error: %s", lua_tostring(L, -1)); + lua_pop(L, 1); + } + count++; + } + + lua_pushinteger(L, count); + return 1; +} + +/* -------------------------------------------------------------------------- + * Module registration + * -------------------------------------------------------------------------- */ +int luaopen_button(lua_State *L) +{ + static const luaL_Reg funcs[] = { + {"new", lua_btn_new}, + {"close", lua_btn_close}, + {"get_key_level", lua_btn_get_key_level}, + {"on", lua_btn_on}, + {"off", lua_btn_off}, + {"dispatch", lua_btn_dispatch}, + {NULL, NULL}, + }; + if (luaL_newmetatable(L, BTN_HANDLE_METATABLE)) { + lua_pushcfunction(L, lua_btn_handle_gc); + lua_setfield(L, -2, "__gc"); + } + lua_pop(L, 1); + lua_newtable(L); + luaL_setfuncs(L, funcs, 0); + return 1; +} + +esp_err_t lua_module_button_register(void) +{ + return cap_lua_register_module("button", luaopen_button); +} diff --git a/components/lua_modules/lua_module_button/skills/lua_module_button.md b/components/lua_modules/lua_module_button/skills/lua_module_button.md new file mode 100644 index 0000000..d83d955 --- /dev/null +++ b/components/lua_modules/lua_module_button/skills/lua_module_button.md @@ -0,0 +1,26 @@ +# Lua Button + +This skill describes how to correctly use button when writing Lua scripts. + +## How to call +- Import it with `local button = require("button")` +- Call `local handle = button.new(gpio_num [, active_level [, long_press_ms [, short_press_ms]]])` to create a button handle +- Call `button.on(handle, event, callback)` to subscribe to a button event +- Supported event names include `press_down`, `press_up`, `single_click`, `double_click`, `multiple_click`, `long_press_start`, `long_press_hold`, and `long_press_up` +- Call `button.off(handle [, event])` to remove a subscription or clear callbacks +- Call `button.dispatch()` to poll and dispatch pending button events +- Call `button.get_key_level(handle)` to read the current key level +- Call `button.close(handle)` when the handle is no longer needed + +## Example +```lua +local button = require("button") + +local handle = button.new(0, 0) +button.on(handle, "single_click", function(evt) + print(evt.event, evt.repeat_count) +end) + +button.dispatch() +button.close(handle) +``` diff --git a/components/lua_modules/lua_module_button/skills/skills_list.json b/components/lua_modules/lua_module_button/skills/skills_list.json new file mode 100644 index 0000000..c83409d --- /dev/null +++ b/components/lua_modules/lua_module_button/skills/skills_list.json @@ -0,0 +1,13 @@ +{ + "skills": [ + { + "id": "lua_module_button", + "file": "lua_module_button.md", + "title": "lua_module_button", + "summary": "How to create button handles, subscribe to events, and dispatch button state from Lua.", + "cap_groups": [ + "cap_lua" + ] + } + ] +} diff --git a/components/lua_modules/lua_module_camera/CMakeLists.txt b/components/lua_modules/lua_module_camera/CMakeLists.txt new file mode 100644 index 0000000..9188b1c --- /dev/null +++ b/components/lua_modules/lua_module_camera/CMakeLists.txt @@ -0,0 +1,12 @@ +idf_component_register( + SRCS + "src/lua_module_camera.c" + "src/lua_module_camera_service.c" + INCLUDE_DIRS + "include" + REQUIRES + cap_lua + esp_new_jpeg + esp_timer + freertos +) diff --git a/components/lua_modules/lua_module_camera/idf_component.yml b/components/lua_modules/lua_module_camera/idf_component.yml new file mode 100644 index 0000000..d03d96f --- /dev/null +++ b/components/lua_modules/lua_module_camera/idf_component.yml @@ -0,0 +1,4 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/esp_new_jpeg: "^1.0.0" + espressif/esp_video: "^2.0.1" diff --git a/components/lua_modules/lua_module_camera/include/lua_module_camera.h b/components/lua_modules/lua_module_camera/include/lua_module_camera.h new file mode 100644 index 0000000..7e08eca --- /dev/null +++ b/components/lua_modules/lua_module_camera/include/lua_module_camera.h @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "esp_err.h" +#include "lua.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int luaopen_camera(lua_State *L); +esp_err_t lua_module_camera_register(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/lua_modules/lua_module_camera/skills/lua_module_camera.md b/components/lua_modules/lua_module_camera/skills/lua_module_camera.md new file mode 100644 index 0000000..a7adfc0 --- /dev/null +++ b/components/lua_modules/lua_module_camera/skills/lua_module_camera.md @@ -0,0 +1,25 @@ +# Lua Camera + +This skill describes how to correctly use camera when writing Lua scripts. + +## How to call +- Import it with `local camera = require("camera")` +- Call `camera.open(dev_path)` before reading frames +- Call `camera.info()` to get stream information such as `width`, `height`, and `pixel_format` +- Call `camera.capture(save_path [, timeout_ms])` to capture a frame to a `.jpg` or `.jpeg` path under `/fatfs/data/` +- Call `camera.close()` when the camera is no longer needed + +## Example +```lua +local camera = require("camera") +local board_manager = require("board_manager") + +local camera_paths = board_manager.get_camera_paths() +camera.open(camera_paths.dev_path) +local info = camera.info() +print(info.width, info.height, info.pixel_format) + +local frame = camera.capture("/fatfs/data/capture.jpg", 3000) +print(frame.path, frame.bytes) +camera.close() +``` diff --git a/components/lua_modules/lua_module_camera/skills/skills_list.json b/components/lua_modules/lua_module_camera/skills/skills_list.json new file mode 100644 index 0000000..7c91eea --- /dev/null +++ b/components/lua_modules/lua_module_camera/skills/skills_list.json @@ -0,0 +1,13 @@ +{ + "skills": [ + { + "id": "lua_module_camera", + "file": "lua_module_camera.md", + "title": "lua_module_camera", + "summary": "How to open a camera, inspect stream info, capture frames, and close it from Lua.", + "cap_groups": [ + "cap_lua" + ] + } + ] +} diff --git a/components/lua_modules/lua_module_camera/src/lua_module_camera.c b/components/lua_modules/lua_module_camera/src/lua_module_camera.c new file mode 100644 index 0000000..7c08771 --- /dev/null +++ b/components/lua_modules/lua_module_camera/src/lua_module_camera.c @@ -0,0 +1,209 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "lua_module_camera.h" + +#include +#include +#include +#include +#include +#include + +#include "cap_lua.h" +#include "lauxlib.h" +#include "lua_module_camera_service.h" + +#define LUA_MODULE_CAMERA_NAME "camera" +#define LUA_MODULE_CAMERA_BASE_DIR "/fatfs/data" + +static bool lua_module_camera_has_suffix(const char *path, const char *suffix) +{ + size_t path_len; + size_t suffix_len; + + if (path == NULL || suffix == NULL) { + return false; + } + + path_len = strlen(path); + suffix_len = strlen(suffix); + if (path_len < suffix_len) { + return false; + } + + path += path_len - suffix_len; + for (size_t i = 0; i < suffix_len; ++i) { + if (tolower((unsigned char)path[i]) != tolower((unsigned char)suffix[i])) { + return false; + } + } + return true; +} + +static bool lua_module_camera_save_path_is_valid(const char *path) +{ + size_t base_len; + + if (path == NULL) { + return false; + } + + base_len = strlen(LUA_MODULE_CAMERA_BASE_DIR); + if (strncmp(path, LUA_MODULE_CAMERA_BASE_DIR, base_len) != 0 || path[base_len] != '/') { + return false; + } + if (strstr(path, "..") != NULL) { + return false; + } + + return lua_module_camera_has_suffix(path, ".jpg") || + lua_module_camera_has_suffix(path, ".jpeg"); +} + +/* camera.open(dev_path) + * Opens the camera device. Must be called before info() or capture(). + * Returns true on success, or raises an error. */ +static int lua_module_camera_open(lua_State *L) +{ + const char *dev_path = luaL_checkstring(L, 1); + esp_err_t err = claw_camera_open(dev_path); + + if (err != ESP_OK) { + return luaL_error(L, "camera open failed: %s", esp_err_to_name(err)); + } + + lua_pushboolean(L, 1); + return 1; +} + +/* camera.info() + * Returns a table with stream info: width, height, pixel_format, pixel_format_raw. + * Requires the camera to be opened first. */ +static int lua_module_camera_info(lua_State *L) +{ + claw_camera_stream_info_t info = {0}; + esp_err_t err = claw_camera_get_stream_info(&info); + + if (err == ESP_ERR_INVALID_STATE) { + return luaL_error(L, "camera info failed: camera not opened, call camera.open() first"); + } + if (err != ESP_OK) { + return luaL_error(L, "camera info failed: %s", esp_err_to_name(err)); + } + + lua_newtable(L); + lua_pushinteger(L, info.width); + lua_setfield(L, -2, "width"); + lua_pushinteger(L, info.height); + lua_setfield(L, -2, "height"); + lua_pushinteger(L, (lua_Integer)info.pixel_format); + lua_setfield(L, -2, "pixel_format_raw"); + lua_pushstring(L, info.pixel_format_str); + lua_setfield(L, -2, "pixel_format"); + return 1; +} + +/* camera.capture(save_path [, timeout_ms]) + * Captures a JPEG frame and writes it to save_path. + * save_path must be a .jpg/.jpeg file under /fatfs/data/. + * Returns a table with: path, bytes, width, height, pixel_format, pixel_format_raw, + * frame_bytes, timestamp_us. */ +static int lua_module_camera_capture(lua_State *L) +{ + claw_camera_frame_info_t frame_info = {0}; + const char *path = luaL_checkstring(L, 1); + int timeout_ms = (int)luaL_optinteger(L, 2, 0); + uint8_t *jpeg_data = NULL; + size_t jpeg_bytes = 0; + FILE *file = NULL; + esp_err_t err; + + if (!lua_module_camera_save_path_is_valid(path)) { + return luaL_error(L, "save path must be a .jpg/.jpeg file under %s", + LUA_MODULE_CAMERA_BASE_DIR); + } + if (timeout_ms < 0) { + return luaL_error(L, "timeout_ms must be non-negative"); + } + + err = claw_camera_capture_jpeg(timeout_ms, &jpeg_data, &jpeg_bytes, &frame_info); + if (err == ESP_ERR_INVALID_STATE) { + return luaL_error(L, "camera capture failed: camera not opened, call camera.open() first"); + } + if (err != ESP_OK) { + return luaL_error(L, "camera capture failed: %s", esp_err_to_name(err)); + } + + file = fopen(path, "wb"); + if (file == NULL) { + claw_camera_free_buffer(jpeg_data); + return luaL_error(L, "camera capture failed: cannot open %s (errno=%d)", path, errno); + } + + if (fwrite(jpeg_data, 1, jpeg_bytes, file) != jpeg_bytes) { + fclose(file); + unlink(path); + claw_camera_free_buffer(jpeg_data); + return luaL_error(L, "camera capture failed: short write to %s", path); + } + + fclose(file); + claw_camera_free_buffer(jpeg_data); + + lua_newtable(L); + lua_pushstring(L, path); + lua_setfield(L, -2, "path"); + lua_pushinteger(L, (lua_Integer)jpeg_bytes); + lua_setfield(L, -2, "bytes"); + lua_pushinteger(L, frame_info.width); + lua_setfield(L, -2, "width"); + lua_pushinteger(L, frame_info.height); + lua_setfield(L, -2, "height"); + lua_pushinteger(L, (lua_Integer)frame_info.pixel_format); + lua_setfield(L, -2, "pixel_format_raw"); + lua_pushstring(L, frame_info.pixel_format_str); + lua_setfield(L, -2, "pixel_format"); + lua_pushinteger(L, (lua_Integer)frame_info.frame_bytes); + lua_setfield(L, -2, "frame_bytes"); + lua_pushinteger(L, (lua_Integer)frame_info.timestamp_us); + lua_setfield(L, -2, "timestamp_us"); + return 1; +} + +/* camera.close() + * Closes the camera device and releases all resources. + * Returns true on success, or raises an error. */ +static int lua_module_camera_close(lua_State *L) +{ + esp_err_t err = claw_camera_close(); + + if (err != ESP_OK) { + return luaL_error(L, "camera close failed: %s", esp_err_to_name(err)); + } + + lua_pushboolean(L, 1); + return 1; +} + +int luaopen_camera(lua_State *L) +{ + static const luaL_Reg funcs[] = { + {"open", lua_module_camera_open}, + {"info", lua_module_camera_info}, + {"capture", lua_module_camera_capture}, + {"close", lua_module_camera_close}, + {NULL, NULL}, + }; + + lua_newtable(L); + luaL_setfuncs(L, funcs, 0); + return 1; +} + +esp_err_t lua_module_camera_register(void) +{ + return cap_lua_register_module(LUA_MODULE_CAMERA_NAME, luaopen_camera); +} diff --git a/components/lua_modules/lua_module_camera/src/lua_module_camera_service.c b/components/lua_modules/lua_module_camera/src/lua_module_camera_service.c new file mode 100644 index 0000000..efdf5c0 --- /dev/null +++ b/components/lua_modules/lua_module_camera/src/lua_module_camera_service.c @@ -0,0 +1,672 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "lua_module_camera_service.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "esp_jpeg_enc.h" +#include "esp_log.h" +#include "esp_timer.h" +#include "esp_video_ioctl.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "linux/videodev2.h" + +#define CLAW_CAMERA_DEFAULT_TIMEOUT_MS 5000 +#define CLAW_CAMERA_SETTLE_TIMEOUT_MS 30000 /* settle at open time, allow slow SPI sensors */ +#define CLAW_CAMERA_BUFFER_COUNT 3 +#define CLAW_CAMERA_STREAM_SETTLE_FRAMES 3 /* reduced: 3 frames enough for AE/AWB stabilize */ +#define CLAW_CAMERA_JPEG_QUALITY 80 +#define CLAW_CAMERA_MIN_JPEG_BUFFER_SIZE (64 * 1024) + +static const char *TAG = "claw_camera"; + +static esp_err_t claw_camera_settle_stream_locked(int64_t deadline_us); +static void claw_camera_fourcc_to_string(uint32_t pixel_format, char out[5]); + +typedef struct { + SemaphoreHandle_t lock; + bool opened; + bool streaming; + uint32_t settled_frames; + int fd; + uint8_t *buffers[CLAW_CAMERA_BUFFER_COUNT]; + size_t buffer_lengths[CLAW_CAMERA_BUFFER_COUNT]; + uint32_t buffer_count; + uint32_t width; + uint32_t height; + uint32_t pixel_format; + jpeg_enc_handle_t jpeg_encoder; + uint8_t *jpeg_buffer; + uint32_t jpeg_buffer_size; +} claw_camera_state_t; + +static StaticSemaphore_t s_camera_lock_buf; +static claw_camera_state_t s_camera = { + .fd = -1, +}; + +static esp_err_t claw_camera_lock(void) +{ + if (s_camera.lock == NULL) { + s_camera.lock = xSemaphoreCreateMutexStatic(&s_camera_lock_buf); + } + + if (xSemaphoreTake(s_camera.lock, pdMS_TO_TICKS(2000)) != pdTRUE) { + ESP_LOGE(TAG, "Camera mutex timeout"); + return ESP_ERR_TIMEOUT; + } + return ESP_OK; +} + +static void claw_camera_unlock(void) +{ + if (s_camera.lock != NULL) { + xSemaphoreGive(s_camera.lock); + } +} + +static int claw_camera_effective_timeout_ms(int timeout_ms) +{ + return timeout_ms > 0 ? timeout_ms : CLAW_CAMERA_DEFAULT_TIMEOUT_MS; +} + +static int claw_camera_remaining_timeout_ms(int64_t deadline_us) +{ + int64_t remaining_us = deadline_us - esp_timer_get_time(); + + if (remaining_us <= 0) { + return 0; + } + if (remaining_us > INT32_MAX * 1000LL) { + return INT32_MAX; + } + return (int)((remaining_us + 999LL) / 1000LL); +} + +static void claw_camera_fourcc_to_string(uint32_t pixel_format, char out[5]) +{ + out[0] = (char)(pixel_format & 0xff); + out[1] = (char)((pixel_format >> 8) & 0xff); + out[2] = (char)((pixel_format >> 16) & 0xff); + out[3] = (char)((pixel_format >> 24) & 0xff); + out[4] = '\0'; + + for (int i = 0; i < 4; ++i) { + if (out[i] < 32 || out[i] > 126) { + out[i] = '.'; + } + } +} + +static void claw_camera_release_encoder_locked(void) +{ + if (s_camera.jpeg_buffer != NULL) { + jpeg_free_align(s_camera.jpeg_buffer); + s_camera.jpeg_buffer = NULL; + } + if (s_camera.jpeg_encoder != NULL) { + jpeg_enc_close(s_camera.jpeg_encoder); + s_camera.jpeg_encoder = NULL; + } + s_camera.jpeg_buffer_size = 0; +} + +static void claw_camera_close_locked(void) +{ + if (s_camera.streaming && s_camera.fd >= 0) { + int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (ioctl(s_camera.fd, VIDIOC_STREAMOFF, &type) != 0) { + ESP_LOGW(TAG, "VIDIOC_STREAMOFF failed (errno=%d)", errno); + } + } + + for (uint32_t i = 0; i < s_camera.buffer_count; ++i) { + if (s_camera.buffers[i] != NULL) { + munmap(s_camera.buffers[i], s_camera.buffer_lengths[i]); + s_camera.buffers[i] = NULL; + } + s_camera.buffer_lengths[i] = 0; + } + s_camera.buffer_count = 0; + + claw_camera_release_encoder_locked(); + + if (s_camera.fd >= 0) { + close(s_camera.fd); + s_camera.fd = -1; + } + + s_camera.opened = false; + s_camera.streaming = false; + s_camera.settled_frames = 0; + s_camera.width = 0; + s_camera.height = 0; + s_camera.pixel_format = 0; +} + +static esp_err_t claw_camera_prepare_encoder_locked(void) +{ + jpeg_enc_config_t config = DEFAULT_JPEG_ENC_CONFIG(); + uint64_t input_size = 0; + int jpeg_err; + + if (s_camera.pixel_format == V4L2_PIX_FMT_JPEG) { + return ESP_OK; + } + if (s_camera.jpeg_encoder != NULL && s_camera.jpeg_buffer != NULL) { + return ESP_OK; + } + + config.width = s_camera.width; + config.height = s_camera.height; + config.quality = CLAW_CAMERA_JPEG_QUALITY; + + switch (s_camera.pixel_format) { + case V4L2_PIX_FMT_UYVY: + config.src_type = JPEG_PIXEL_FORMAT_CbYCrY; + config.subsampling = JPEG_SUBSAMPLE_422; + input_size = (uint64_t)s_camera.width * s_camera.height * 2U; + break; + case V4L2_PIX_FMT_YUYV: + config.src_type = JPEG_PIXEL_FORMAT_YCbYCr; + config.subsampling = JPEG_SUBSAMPLE_422; + input_size = (uint64_t)s_camera.width * s_camera.height * 2U; + break; + case V4L2_PIX_FMT_RGB565: + config.src_type = JPEG_PIXEL_FORMAT_RGB565_LE; + config.subsampling = JPEG_SUBSAMPLE_422; + input_size = (uint64_t)s_camera.width * s_camera.height * 2U; + break; + case V4L2_PIX_FMT_RGB565X: + config.src_type = JPEG_PIXEL_FORMAT_RGB565_BE; + config.subsampling = JPEG_SUBSAMPLE_422; + input_size = (uint64_t)s_camera.width * s_camera.height * 2U; + break; + default: + ESP_LOGE(TAG, "prepare_encoder: unsupported pixel format 0x%08" PRIx32, s_camera.pixel_format); + return ESP_ERR_NOT_SUPPORTED; + } + + if (input_size == 0 || input_size > UINT32_MAX) { + return ESP_ERR_INVALID_SIZE; + } + + jpeg_err = jpeg_enc_open(&config, &s_camera.jpeg_encoder); + if (jpeg_err != JPEG_ERR_OK) { + ESP_LOGE(TAG, "jpeg_enc_open failed: %d", jpeg_err); + s_camera.jpeg_encoder = NULL; + return ESP_FAIL; + } + + s_camera.jpeg_buffer_size = (uint32_t)(input_size * 3U / 4U); + if (s_camera.jpeg_buffer_size < CLAW_CAMERA_MIN_JPEG_BUFFER_SIZE) { + s_camera.jpeg_buffer_size = CLAW_CAMERA_MIN_JPEG_BUFFER_SIZE; + } + + s_camera.jpeg_buffer = jpeg_calloc_align(s_camera.jpeg_buffer_size, 128); + if (s_camera.jpeg_buffer == NULL) { + ESP_LOGE(TAG, "Failed to allocate JPEG output buffer"); + claw_camera_release_encoder_locked(); + return ESP_ERR_NO_MEM; + } + + return ESP_OK; +} + +static esp_err_t claw_camera_open_locked(const char *dev_path) +{ + struct v4l2_format format = {0}; + struct v4l2_requestbuffers request = {0}; + char pixel_format[5] = {0}; + esp_err_t err; + + if (s_camera.opened) { + return ESP_OK; + } + + if (dev_path == NULL) { + return ESP_ERR_INVALID_ARG; + } + + s_camera.fd = open(dev_path, O_RDWR); + if (s_camera.fd < 0) { + ESP_LOGE(TAG, "Failed to open %s (errno=%d)", dev_path, errno); + s_camera.fd = -1; + return ESP_ERR_NOT_FOUND; + } + + format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (ioctl(s_camera.fd, VIDIOC_G_FMT, &format) != 0) { + ESP_LOGE(TAG, "VIDIOC_G_FMT failed (errno=%d)", errno); + claw_camera_close_locked(); + return ESP_FAIL; + } + + s_camera.width = format.fmt.pix.width; + s_camera.height = format.fmt.pix.height; + s_camera.pixel_format = format.fmt.pix.pixelformat; + claw_camera_fourcc_to_string(s_camera.pixel_format, pixel_format); + + request.count = CLAW_CAMERA_BUFFER_COUNT; + request.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + request.memory = V4L2_MEMORY_MMAP; + if (ioctl(s_camera.fd, VIDIOC_REQBUFS, &request) != 0) { + ESP_LOGE(TAG, "VIDIOC_REQBUFS failed (errno=%d)", errno); + claw_camera_close_locked(); + return ESP_FAIL; + } + if (request.count == 0) { + ESP_LOGE(TAG, "Camera buffer request returned 0"); + claw_camera_close_locked(); + return ESP_ERR_NO_MEM; + } + + s_camera.buffer_count = request.count > CLAW_CAMERA_BUFFER_COUNT ? + CLAW_CAMERA_BUFFER_COUNT : request.count; + + for (uint32_t i = 0; i < s_camera.buffer_count; ++i) { + struct v4l2_buffer buffer = {0}; + + buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buffer.memory = V4L2_MEMORY_MMAP; + buffer.index = i; + if (ioctl(s_camera.fd, VIDIOC_QUERYBUF, &buffer) != 0) { + ESP_LOGE(TAG, "VIDIOC_QUERYBUF failed (errno=%d)", errno); + claw_camera_close_locked(); + return ESP_FAIL; + } + + s_camera.buffers[i] = mmap(NULL, buffer.length, PROT_READ | PROT_WRITE, + MAP_SHARED, s_camera.fd, buffer.m.offset); + if (s_camera.buffers[i] == MAP_FAILED) { + ESP_LOGE(TAG, "Failed to mmap camera buffer (errno=%d)", errno); + s_camera.buffers[i] = NULL; + claw_camera_close_locked(); + return ESP_ERR_NO_MEM; + } + s_camera.buffer_lengths[i] = buffer.length; + + if (ioctl(s_camera.fd, VIDIOC_QBUF, &buffer) != 0) { + ESP_LOGE(TAG, "Initial VIDIOC_QBUF failed (errno=%d)", errno); + claw_camera_close_locked(); + return ESP_FAIL; + } + } + + err = claw_camera_prepare_encoder_locked(); + if (err != ESP_OK) { + claw_camera_close_locked(); + return err; + } + + int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (ioctl(s_camera.fd, VIDIOC_STREAMON, &type) != 0) { + ESP_LOGE(TAG, "VIDIOC_STREAMON failed (errno=%d)", errno); + claw_camera_close_locked(); + return ESP_FAIL; + } + + s_camera.streaming = true; + s_camera.opened = true; + s_camera.settled_frames = 0; + + ESP_LOGI(TAG, "Camera opened: path=%s size=%ux%u format=%s", + dev_path, (unsigned)s_camera.width, (unsigned)s_camera.height, + pixel_format); + + /* Settle the stream at open time with a dedicated timeout so that capture() + * calls are not penalised by the sensor warm-up delay. */ + int64_t settle_deadline_us = + esp_timer_get_time() + ((int64_t)CLAW_CAMERA_SETTLE_TIMEOUT_MS * 1000LL); + err = claw_camera_settle_stream_locked(settle_deadline_us); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Stream settle failed during open (err=0x%x)", err); + claw_camera_close_locked(); + return err; + } + + return ESP_OK; +} + +static esp_err_t claw_camera_dequeue_buffer_locked(int timeout_ms, struct v4l2_buffer *buffer) +{ + struct timeval tv = { + .tv_sec = timeout_ms / 1000, + .tv_usec = (timeout_ms % 1000) * 1000, + }; + + if (buffer == NULL) { + return ESP_ERR_INVALID_ARG; + } + + /* esp_video VFS does not implement poll(); use VIDIOC_S_DQBUF_TIMEOUT to + * set a per-call timeout and block directly in VIDIOC_DQBUF. */ + if (ioctl(s_camera.fd, VIDIOC_S_DQBUF_TIMEOUT, &tv) != 0) { + ESP_LOGW(TAG, "VIDIOC_S_DQBUF_TIMEOUT failed (errno=%d)", errno); + return ESP_FAIL; + } + + memset(buffer, 0, sizeof(*buffer)); + buffer->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buffer->memory = V4L2_MEMORY_MMAP; + if (ioctl(s_camera.fd, VIDIOC_DQBUF, buffer) != 0) { + if (errno == ETIMEDOUT) { + ESP_LOGW(TAG, "VIDIOC_DQBUF timeout after %d ms", timeout_ms); + return ESP_ERR_TIMEOUT; + } + ESP_LOGW(TAG, "VIDIOC_DQBUF failed (errno=%d)", errno); + return ESP_FAIL; + } + + return ESP_OK; +} + +static esp_err_t claw_camera_requeue_buffer_locked(struct v4l2_buffer *buffer) +{ + if (buffer == NULL || buffer->index >= s_camera.buffer_count) { + return ESP_ERR_INVALID_ARG; + } + + if (ioctl(s_camera.fd, VIDIOC_QBUF, buffer) != 0) { + ESP_LOGW(TAG, "VIDIOC_QBUF failed (errno=%d)", errno); + return ESP_FAIL; + } + return ESP_OK; +} + +static esp_err_t claw_camera_validate_buffer_locked(const struct v4l2_buffer *buffer, + size_t *frame_bytes) +{ + if (buffer == NULL || frame_bytes == NULL) { + return ESP_ERR_INVALID_ARG; + } + if ((buffer->flags & V4L2_BUF_FLAG_DONE) == 0 || (buffer->flags & V4L2_BUF_FLAG_ERROR) != 0) { + return ESP_FAIL; + } + if (buffer->index >= s_camera.buffer_count) { + return ESP_FAIL; + } + if (s_camera.buffers[buffer->index] == NULL || s_camera.buffer_lengths[buffer->index] == 0) { + return ESP_FAIL; + } + if (buffer->bytesused > s_camera.buffer_lengths[buffer->index]) { + return ESP_ERR_INVALID_SIZE; + } + if (buffer->bytesused == 0) { + return ESP_ERR_INVALID_SIZE; + } + + *frame_bytes = buffer->bytesused; + return ESP_OK; +} + +static esp_err_t claw_camera_settle_stream_locked(int64_t deadline_us) +{ + while (s_camera.settled_frames < CLAW_CAMERA_STREAM_SETTLE_FRAMES) { + struct v4l2_buffer buffer = {0}; + size_t frame_bytes = 0; + int remaining_ms = claw_camera_remaining_timeout_ms(deadline_us); + esp_err_t err; + + if (remaining_ms <= 0) { + ESP_LOGW(TAG, "settle: timeout (settled=%" PRIu32 "/%d)", + s_camera.settled_frames, CLAW_CAMERA_STREAM_SETTLE_FRAMES); + return ESP_ERR_TIMEOUT; + } + + err = claw_camera_dequeue_buffer_locked(remaining_ms, &buffer); + if (err != ESP_OK) { + claw_camera_close_locked(); + return err; + } + + err = claw_camera_validate_buffer_locked(&buffer, &frame_bytes); + if (claw_camera_requeue_buffer_locked(&buffer) != ESP_OK) { + claw_camera_close_locked(); + return ESP_FAIL; + } + + if (err == ESP_OK && frame_bytes > 0) { + s_camera.settled_frames++; + } + } + return ESP_OK; +} + +static esp_err_t claw_camera_get_frame_locked(int timeout_ms, struct v4l2_buffer *buffer, + uint8_t **frame_data, size_t *frame_bytes, + int64_t *timestamp_us) +{ + int64_t deadline_us; + esp_err_t err; + + if (buffer == NULL || frame_data == NULL || frame_bytes == NULL) { + return ESP_ERR_INVALID_ARG; + } + + if (!s_camera.opened) { + return ESP_ERR_INVALID_STATE; + } + + deadline_us = esp_timer_get_time() + ((int64_t)claw_camera_effective_timeout_ms(timeout_ms) * 1000LL); + + err = claw_camera_settle_stream_locked(deadline_us); + if (err != ESP_OK) { + return err; + } + + while (claw_camera_remaining_timeout_ms(deadline_us) > 0) { + int remaining_ms = claw_camera_remaining_timeout_ms(deadline_us); + + err = claw_camera_dequeue_buffer_locked(remaining_ms, buffer); + if (err != ESP_OK) { + claw_camera_close_locked(); + return err; + } + + err = claw_camera_validate_buffer_locked(buffer, frame_bytes); + if (err == ESP_OK) { + *frame_data = s_camera.buffers[buffer->index]; + if (timestamp_us != NULL) { + *timestamp_us = esp_timer_get_time(); + } + return ESP_OK; + } + + if (claw_camera_requeue_buffer_locked(buffer) != ESP_OK) { + claw_camera_close_locked(); + return ESP_FAIL; + } + } + + return ESP_ERR_TIMEOUT; +} + +static esp_err_t claw_camera_copy_frame_and_requeue_locked(struct v4l2_buffer *buffer, + const uint8_t *frame_data, + size_t frame_bytes, + uint8_t **out_frame_copy) +{ + uint8_t *frame_copy; + + if (buffer == NULL || frame_data == NULL || out_frame_copy == NULL) { + return ESP_ERR_INVALID_ARG; + } + + frame_copy = malloc(frame_bytes); + if (frame_copy == NULL) { + return ESP_ERR_NO_MEM; + } + + memcpy(frame_copy, frame_data, frame_bytes); + + if (claw_camera_requeue_buffer_locked(buffer) != ESP_OK) { + free(frame_copy); + claw_camera_close_locked(); + return ESP_FAIL; + } + + *out_frame_copy = frame_copy; + return ESP_OK; +} + +esp_err_t claw_camera_open(const char *dev_path) +{ + esp_err_t err = claw_camera_lock(); + + if (err != ESP_OK) { + return err; + } + + err = claw_camera_open_locked(dev_path); + claw_camera_unlock(); + return err; +} + +esp_err_t claw_camera_get_stream_info(claw_camera_stream_info_t *out_info) +{ + esp_err_t err; + + if (out_info == NULL) { + return ESP_ERR_INVALID_ARG; + } + + memset(out_info, 0, sizeof(*out_info)); + + err = claw_camera_lock(); + if (err != ESP_OK) { + return err; + } + + if (!s_camera.opened) { + claw_camera_unlock(); + return ESP_ERR_INVALID_STATE; + } + + out_info->width = s_camera.width; + out_info->height = s_camera.height; + out_info->pixel_format = s_camera.pixel_format; + claw_camera_fourcc_to_string(s_camera.pixel_format, out_info->pixel_format_str); + + claw_camera_unlock(); + return ESP_OK; +} + +esp_err_t claw_camera_capture_jpeg(int timeout_ms, uint8_t **jpeg_data, size_t *jpeg_bytes, + claw_camera_frame_info_t *out_info) +{ + struct v4l2_buffer buffer = {0}; + uint8_t *frame_data = NULL; + uint8_t *frame_copy = NULL; + size_t frame_bytes = 0; + int64_t timestamp_us = 0; + uint8_t *copy = NULL; + size_t encoded_size = 0; + esp_err_t err; + + if (jpeg_data == NULL || jpeg_bytes == NULL) { + return ESP_ERR_INVALID_ARG; + } + + *jpeg_data = NULL; + *jpeg_bytes = 0; + if (out_info != NULL) { + memset(out_info, 0, sizeof(*out_info)); + } + + err = claw_camera_lock(); + if (err != ESP_OK) { + return err; + } + + err = claw_camera_get_frame_locked(timeout_ms, &buffer, &frame_data, &frame_bytes, ×tamp_us); + if (err != ESP_OK) { + claw_camera_unlock(); + return err; + } + + err = claw_camera_copy_frame_and_requeue_locked(&buffer, frame_data, frame_bytes, &frame_copy); + if (err != ESP_OK) { + claw_camera_unlock(); + return err; + } + + if (s_camera.pixel_format == V4L2_PIX_FMT_JPEG) { + encoded_size = frame_bytes; + copy = frame_copy; + frame_copy = NULL; + } else { + int out_len = 0; + + err = claw_camera_prepare_encoder_locked(); + if (err == ESP_OK) { + if (jpeg_enc_process(s_camera.jpeg_encoder, frame_copy, (uint32_t)frame_bytes, + s_camera.jpeg_buffer, s_camera.jpeg_buffer_size, + &out_len) != JPEG_ERR_OK) { + ESP_LOGE(TAG, "jpeg_enc_process failed"); + err = ESP_FAIL; + } else if (out_len <= 0) { + err = ESP_ERR_INVALID_SIZE; + } else { + encoded_size = (size_t)out_len; + copy = malloc(encoded_size); + if (copy == NULL) { + err = ESP_ERR_NO_MEM; + } else { + memcpy(copy, s_camera.jpeg_buffer, encoded_size); + } + } + } + } + + if (err == ESP_OK) { + *jpeg_data = copy; + *jpeg_bytes = encoded_size; + if (out_info != NULL) { + out_info->width = s_camera.width; + out_info->height = s_camera.height; + out_info->pixel_format = s_camera.pixel_format; + claw_camera_fourcc_to_string(s_camera.pixel_format, out_info->pixel_format_str); + out_info->frame_bytes = frame_bytes; + out_info->timestamp_us = timestamp_us; + } + } else if (copy != NULL) { + free(copy); + } + + free(frame_copy); + claw_camera_unlock(); + return err; +} + +esp_err_t claw_camera_close(void) +{ + esp_err_t err = claw_camera_lock(); + + if (err != ESP_OK) { + return err; + } + + claw_camera_close_locked(); + claw_camera_unlock(); + return ESP_OK; +} + +void claw_camera_free_buffer(void *buffer) +{ + free(buffer); +} diff --git a/components/lua_modules/lua_module_camera/src/lua_module_camera_service.h b/components/lua_modules/lua_module_camera/src/lua_module_camera_service.h new file mode 100644 index 0000000..308daa9 --- /dev/null +++ b/components/lua_modules/lua_module_camera/src/lua_module_camera_service.h @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint32_t width; + uint32_t height; + uint32_t pixel_format; + char pixel_format_str[5]; +} claw_camera_stream_info_t; + +typedef struct { + uint32_t width; + uint32_t height; + uint32_t pixel_format; + char pixel_format_str[5]; + size_t frame_bytes; + int64_t timestamp_us; +} claw_camera_frame_info_t; + +esp_err_t claw_camera_open(const char *dev_path); +esp_err_t claw_camera_get_stream_info(claw_camera_stream_info_t *out_info); +esp_err_t claw_camera_capture_jpeg(int timeout_ms, uint8_t **jpeg_data, size_t *jpeg_bytes, + claw_camera_frame_info_t *out_info); +esp_err_t claw_camera_close(void); +void claw_camera_free_buffer(void *buffer); + +#ifdef __cplusplus +} +#endif diff --git a/components/lua_modules/lua_module_display/CMakeLists.txt b/components/lua_modules/lua_module_display/CMakeLists.txt new file mode 100644 index 0000000..b595833 --- /dev/null +++ b/components/lua_modules/lua_module_display/CMakeLists.txt @@ -0,0 +1,12 @@ +idf_component_register( + SRCS + "src/display_hal.c" + "src/lua_module_display.c" + INCLUDE_DIRS + "include" + REQUIRES + cap_lua + esp_lcd + esp_painter + libpng +) diff --git a/components/lua_modules/lua_module_display/idf_component.yml b/components/lua_modules/lua_module_display/idf_component.yml new file mode 100644 index 0000000..34de3ad --- /dev/null +++ b/components/lua_modules/lua_module_display/idf_component.yml @@ -0,0 +1,3 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/libpng: "^1.6.55" diff --git a/components/lua_modules/lua_module_display/include/display_hal.h b/components/lua_modules/lua_module_display/include/display_hal.h new file mode 100644 index 0000000..64d2a40 --- /dev/null +++ b/components/lua_modules/lua_module_display/include/display_hal.h @@ -0,0 +1,136 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +/* Display Hardware Abstraction Layer + * + * Declares the interface that the board/application layer must implement. + * The lua_module_display component calls these functions to perform display + * operations without depending on any specific LCD driver. + */ + +#include +#include +#include "esp_err.h" +#include "esp_lcd_panel_io.h" +#include "esp_lcd_panel_ops.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + DISPLAY_HAL_TEXT_ALIGN_LEFT = 0, + DISPLAY_HAL_TEXT_ALIGN_CENTER, + DISPLAY_HAL_TEXT_ALIGN_RIGHT, +} display_hal_text_align_t; + +typedef enum { + DISPLAY_HAL_TEXT_VALIGN_TOP = 0, + DISPLAY_HAL_TEXT_VALIGN_MIDDLE, + DISPLAY_HAL_TEXT_VALIGN_BOTTOM, +} display_hal_text_valign_t; + +typedef struct { + uint8_t framebuffer_count; + bool double_buffered; + bool frame_active; + bool flush_in_flight; +} display_hal_animation_info_t; + +/* --- Lifecycle --- */ + +esp_err_t display_hal_create(esp_lcd_panel_handle_t panel_handle, + esp_lcd_panel_io_handle_t io_handle, + int lcd_width, + int lcd_height); +esp_err_t display_hal_destroy(void); + +/* --- Geometry --- */ + +int display_hal_width(void); +int display_hal_height(void); + +/* --- Frame control --- */ + +esp_err_t display_hal_begin_frame(bool clear, uint16_t color565); +esp_err_t display_hal_present(void); +esp_err_t display_hal_present_rect(int x, int y, int width, int height); +esp_err_t display_hal_end_frame(void); +bool display_hal_is_frame_active(void); +esp_err_t display_hal_get_animation_info(display_hal_animation_info_t *info); + +/* --- Drawing primitives --- */ + +esp_err_t display_hal_clear(uint16_t color565); +esp_err_t display_hal_set_clip_rect(int x, int y, int width, int height); +esp_err_t display_hal_clear_clip_rect(void); +esp_err_t display_hal_fill_rect(int x, int y, int width, int height, uint16_t color565); +esp_err_t display_hal_draw_line(int x0, int y0, int x1, int y1, uint16_t color565); +esp_err_t display_hal_draw_rect(int x, int y, int width, int height, uint16_t color565); +esp_err_t display_hal_draw_pixel(int x, int y, uint16_t color565); +esp_err_t display_hal_set_backlight(bool on); +esp_err_t display_hal_fill_circle(int cx, int cy, int r, uint16_t color565); +esp_err_t display_hal_draw_circle(int cx, int cy, int r, uint16_t color565); +esp_err_t display_hal_draw_arc(int cx, int cy, int radius, + float start_deg, float end_deg, uint16_t color565); +esp_err_t display_hal_fill_arc(int cx, int cy, int inner_radius, int outer_radius, + float start_deg, float end_deg, uint16_t color565); +esp_err_t display_hal_draw_ellipse(int cx, int cy, int radius_x, int radius_y, + uint16_t color565); +esp_err_t display_hal_fill_ellipse(int cx, int cy, int radius_x, int radius_y, + uint16_t color565); +esp_err_t display_hal_draw_round_rect(int x, int y, int width, int height, + int radius, uint16_t color565); +esp_err_t display_hal_fill_round_rect(int x, int y, int width, int height, + int radius, uint16_t color565); +esp_err_t display_hal_draw_triangle(int x1, int y1, int x2, int y2, + int x3, int y3, uint16_t color565); +esp_err_t display_hal_fill_triangle(int x1, int y1, int x2, int y2, + int x3, int y3, uint16_t color565); + +/* --- Text --- */ + +esp_err_t display_hal_measure_text(const char *text, uint8_t font_size, + uint16_t *out_width, uint16_t *out_height); +esp_err_t display_hal_draw_text(int x, int y, const char *text, uint8_t font_size, + uint16_t text_color565, bool has_bg, uint16_t bg_color565); +esp_err_t display_hal_draw_text_aligned(int x, int y, int width, int height, + const char *text, uint8_t font_size, + uint16_t text_color565, bool has_bg, uint16_t bg_color565, + display_hal_text_align_t align, + display_hal_text_valign_t valign); + +/* --- Bitmap --- */ + +/* pixels: RGB565, MSB-first byte order */ +esp_err_t display_hal_draw_bitmap(int x, int y, int w, int h, const uint16_t *pixels); +esp_err_t display_hal_draw_bitmap_crop(int x, int y, + int src_x, int src_y, + int w, int h, + int src_width, int src_height, + const uint16_t *pixels); + +/* --- JPEG --- */ + +esp_err_t display_hal_draw_jpeg(int x, int y, + const uint8_t *jpeg_data, size_t jpeg_len, + int *out_w, int *out_h); +esp_err_t display_hal_draw_jpeg_crop(int x, int y, + int src_x, int src_y, + int w, int h, + const uint8_t *jpeg_data, size_t jpeg_len, + int *out_w, int *out_h); +esp_err_t display_hal_jpeg_get_size(const uint8_t *jpeg_data, size_t jpeg_len, + int *out_w, int *out_h); +esp_err_t display_hal_draw_jpeg_scaled(int x, int y, + const uint8_t *jpeg_data, size_t jpeg_len, + int scale_w, int scale_h, + int *out_w, int *out_h); + +#ifdef __cplusplus +} +#endif diff --git a/components/lua_modules/lua_module_display/include/lua_module_display.h b/components/lua_modules/lua_module_display/include/lua_module_display.h new file mode 100644 index 0000000..80af6ed --- /dev/null +++ b/components/lua_modules/lua_module_display/include/lua_module_display.h @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "esp_err.h" +#include "lua.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Opens the "display" Lua module and pushes the table onto the stack. */ +int luaopen_display(lua_State *L); + +/* Registers the "display" module with cap_lua so Lua scripts can require it. */ +esp_err_t lua_module_display_register(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/lua_modules/lua_module_display/skills/lua_module_display.md b/components/lua_modules/lua_module_display/skills/lua_module_display.md new file mode 100644 index 0000000..3f67c72 --- /dev/null +++ b/components/lua_modules/lua_module_display/skills/lua_module_display.md @@ -0,0 +1,433 @@ +# Lua Display + +This skill describes how to correctly use `display` when writing Lua scripts. + +`display` is a low-level drawing module. It can: +- Create and destroy the LCD drawing context +- Draw text, lines, rectangles, circles, arcs, ellipses, triangles, and round rectangles +- Draw raw RGB565 bitmaps +- Draw JPEG and PNG images from memory or files +- Manage frame-based rendering and partial screen flushes + +## Typical setup + +In this project, `display` is usually used together with `board_manager`: + +```lua +local board_manager = require("board_manager") +local display = require("display") + +local panel_handle, io_handle, width, height = + board_manager.get_display_lcd_params("display_lcd") + +display.create_screen(panel_handle, io_handle, width, height) +``` + +After `display.create_screen(...)` succeeds: +- `display.width()` returns the current screen width +- `display.height()` returns the current screen height +- Most drawing APIs can be used + +When finished: + +```lua +pcall(display.end_frame) +pcall(display.destroy_screen) +``` + +## Important rules + +- All coordinates and sizes are integer arguments unless noted otherwise. +- Colors are almost always passed as three integers: `r, g, b`. +- Text drawing only supports ASCII text. +- For Chinese or other Unicode text, render an image and draw it with `draw_png_file(...)` or `draw_jpeg_file(...)`. +- Image file paths must be absolute paths like `/fatfs/data/pic.jpg`. +- Paths containing `..` are rejected. +- Supported image file extensions are `.jpg`, `.jpeg`, and `.png`. + +## Screen lifecycle + +### `display.create_screen(panel_handle, io_handle, lcd_width, lcd_height)` + +Creates the drawing context. + +- `panel_handle`: lightuserdata, usually from `board_manager.get_display_lcd_params(...)` +- `io_handle`: lightuserdata +- `lcd_width`: integer +- `lcd_height`: integer +- Returns `true` on success +- Raises a Lua error on failure + +### `display.destroy_screen()` + +Destroys the drawing context. + +- Returns `true` on success +- Raises a Lua error on failure + +### `display.width()` + +Returns the current screen width. + +### `display.height()` + +Returns the current screen height. + +## Frame rendering + +The module supports frame-based rendering. This is the preferred mode when a script draws a full screen or updates multiple primitives together. + +### `display.begin_frame([options])` + +Starts a frame. + +`options` is an optional table: +- `clear`: boolean, default `true` +- `r`: background red, default `0` +- `g`: background green, default `0` +- `b`: background blue, default `0` + +Example: + +```lua +display.begin_frame({ clear = true, r = 12, g = 18, b = 28 }) +``` + +### `display.present()` + +Flushes the full current frame to the panel. + +### `display.present_rect(x, y, width, height)` + +Flushes only a rectangular region. This is useful for partial updates such as painting apps or small widgets. + +### `display.end_frame()` + +Ends the current frame. + +### `display.frame_active()` + +Returns a boolean indicating whether a frame is currently active. + +### `display.animation_info()` + +Returns a table with runtime rendering information: +- `framebuffer_count` +- `double_buffered` +- `frame_active` +- `flush_in_flight` + +## Backlight + +### `display.backlight(on)` + +Turns the display backlight on or off. + +- `on`: boolean + +Example: + +```lua +display.backlight(true) +``` + +## Text APIs + +### `display.draw_text(x, y, text [, options])` + +Draws ASCII text at the given position. + +`options` is an optional table: +- `r`, `g`, `b`: text color, default white +- `font_size`: integer, default `24` +- `bg_r`, `bg_g`, `bg_b`: optional background color; if any background field is given, background fill is enabled + +Example: + +```lua +display.draw_text(16, 24, "hello", { + r = 255, + g = 255, + b = 255, + font_size = 24, +}) +``` + +Restrictions: +- `text` must be ASCII +- Non-ASCII text raises an error + +### `display.measure_text(text [, options])` + +Measures text without drawing it. + +`options` currently supports: +- `font_size` + +Returns: +- `width` +- `height` + +Example: + +```lua +local tw, th = display.measure_text("hello", { font_size = 24 }) +``` + +### `display.draw_text_aligned(x, y, width, height, text [, options])` + +Draws ASCII text inside a rectangle with alignment. + +`options` supports: +- `r`, `g`, `b` +- `font_size` +- `bg_r`, `bg_g`, `bg_b` +- `align`: `"left"`, `"center"`/`"centre"`, or `"right"` +- `valign`: `"top"`, `"middle"`/`"center"`, or `"bottom"` + +Example: + +```lua +display.draw_text_aligned(0, 0, display.width(), 32, "status", { + r = 255, + g = 255, + b = 255, + font_size = 16, + align = "center", + valign = "middle", +}) +``` + +## Basic drawing primitives + +### `display.clear(r, g, b)` + +Clears the screen or current frame buffer to a solid color. + +### `display.set_clip_rect(x, y, width, height)` + +Sets a clipping rectangle. Subsequent drawing is restricted to that region until cleared. + +### `display.clear_clip_rect()` + +Removes the active clipping rectangle. + +### `display.fill_rect(x, y, width, height, r, g, b)` + +Draws a filled rectangle. + +### `display.draw_rect(x, y, width, height, r, g, b)` + +Draws a rectangle outline. + +### `display.draw_pixel(x, y, r, g, b)` + +Draws one pixel. + +### `display.draw_line(x0, y0, x1, y1, r, g, b)` + +Draws a line. + +## Shape drawing + +### `display.fill_circle(cx, cy, radius, r, g, b)` + +Draws a filled circle. + +### `display.draw_circle(cx, cy, radius, r, g, b)` + +Draws a circle outline. + +### `display.draw_arc(cx, cy, radius, start_deg, end_deg, r, g, b)` + +Draws an arc. + +- `start_deg` and `end_deg` are numeric values, not limited to integers + +### `display.fill_arc(cx, cy, inner_radius, outer_radius, start_deg, end_deg, r, g, b)` + +Draws a filled ring segment. + +### `display.draw_ellipse(cx, cy, radius_x, radius_y, r, g, b)` + +Draws an ellipse outline. + +### `display.fill_ellipse(cx, cy, radius_x, radius_y, r, g, b)` + +Draws a filled ellipse. + +### `display.draw_round_rect(x, y, width, height, radius, r, g, b)` + +Draws a rounded rectangle outline. + +### `display.fill_round_rect(x, y, width, height, radius, r, g, b)` + +Draws a filled rounded rectangle. + +### `display.draw_triangle(x1, y1, x2, y2, x3, y3, r, g, b)` + +Draws a triangle outline. + +### `display.fill_triangle(x1, y1, x2, y2, x3, y3, r, g, b)` + +Draws a filled triangle. + +## Raw bitmap APIs + +These APIs draw RGB565 pixel buffers. + +### `display.draw_bitmap(x, y, w, h, data)` + +Draws a raw RGB565 bitmap. + +- `data` is a Lua string containing exactly `w * h * 2` bytes or more +- Byte order must be RGB565, MSB-first + +If the byte string is shorter than required, the API raises an error. + +### `display.draw_bitmap_le(x, y, w, h, data)` + +Same as `draw_bitmap(...)`, but input data is little-endian RGB565. + +The module swaps bytes internally before drawing. + +Use this when your pixel buffer is generated in little-endian order. + +### `display.draw_bitmap_crop(x, y, src_x, src_y, width, height, src_width, src_height, data)` + +Draws a cropped region from a larger RGB565 source image. + +Arguments: +- `x`, `y`: destination position on screen +- `src_x`, `src_y`: top-left coordinate inside the source image +- `width`, `height`: crop size to draw +- `src_width`, `src_height`: full source image size +- `data`: source RGB565 data buffer + +Notes: +- `data` must contain the full source image, not just the crop +- Required byte size is `src_width * src_height * 2` +- This API does not have a `_le` variant, so the source buffer should already match the format expected by the HAL + +## JPEG and PNG APIs + +### `display.draw_jpeg(x, y, jpeg_data)` + +Draws a JPEG from raw bytes in memory. + +- `jpeg_data` is a Lua string containing JPEG bytes +- Returns `width, height` + +### `display.draw_jpeg_file(x, y, path)` + +Draws a JPEG from a file. + +- `path` must be an absolute `.jpg` or `.jpeg` path +- Returns `width, height` + +### `display.draw_png_file(x, y, path)` + +Draws a PNG from a file. + +- `path` must be an absolute `.png` path +- Returns `width, height` + +PNG handling details: +- The PNG is decoded inside the module +- RGBA PNG input is converted to RGB565 +- Alpha is pre-multiplied against black + +This means transparent PNG pixels are blended toward black before display, not against an arbitrary background. + +### `display.draw_jpeg_crop(x, y, src_x, src_y, width, height, jpeg_data)` + +Draws a cropped region from in-memory JPEG data. + +- Returns `width, height` + +### `display.draw_jpeg_file_crop(x, y, src_x, src_y, width, height, path)` + +Draws a cropped region from a JPEG file. + +- Returns `width, height` + +### `display.draw_jpeg_file_scaled(x, y, scale_w, scale_h, path)` + +Draws a JPEG file scaled to the requested output size. + +Restrictions from the implementation: +- `scale_w` and `scale_h` must be positive +- `scale_w` and `scale_h` must both be multiples of `8` + +Returns: +- `output_w` +- `output_h` + +### `display.draw_jpeg_file_fit(x, y, max_w, max_h, path)` + +Scales a JPEG to fit within `max_w x max_h` while preserving aspect ratio. + +Behavior: +- If the original image already fits, it is drawn at full resolution +- Otherwise the module computes a scaled size automatically +- The chosen scaled size is aligned down to multiples of `8` +- Minimum output size is clamped to `8x8` +- Maximum downscale is limited to `1/8` of the original size + +Returns: +- `output_w` +- `output_h` + +## Error behavior and constraints + +- Most APIs raise Lua errors directly when arguments are invalid or the HAL returns an error +- Integer-only APIs reject non-integer Lua values +- Path-based image APIs reject invalid or unsafe paths +- `draw_bitmap(...)` and `draw_bitmap_crop(...)` reject buffers that are too short +- `draw_text(...)` and `draw_text_aligned(...)` reject non-ASCII text + +## Recommended usage pattern + +For normal screen rendering: +1. Use `board_manager.get_display_lcd_params("display_lcd")` +2. Call `display.create_screen(...)` +3. Call `display.begin_frame(...)` +4. Draw text, shapes, or images +5. Call `display.present()` or `display.present_rect(...)` +6. Call `display.end_frame()` +7. Call `display.destroy_screen()` before exit + +## Example + +```lua +local bm = require("board_manager") +local display = require("display") + +local panel_handle, io_handle, width, height = + bm.get_display_lcd_params("display_lcd") + +display.create_screen(panel_handle, io_handle, width, height) + +display.begin_frame({ clear = true, r = 12, g = 18, b = 28 }) + +display.draw_rect(12, 12, display.width() - 24, display.height() - 24, 80, 120, 160) +display.fill_rect(20, 40, 80, 36, 72, 208, 235) +display.draw_text(24, 90, "Lua Display Demo", { + r = 245, + g = 244, + b = 238, + font_size = 24, +}) +display.draw_text_aligned(0, display.height() - 24, display.width(), 20, "frame api", { + r = 210, + g = 220, + b = 228, + font_size = 16, + align = "center", + valign = "middle", +}) + +display.present() +display.end_frame() +display.destroy_screen() +``` diff --git a/components/lua_modules/lua_module_display/skills/skills_list.json b/components/lua_modules/lua_module_display/skills/skills_list.json new file mode 100644 index 0000000..7c4992b --- /dev/null +++ b/components/lua_modules/lua_module_display/skills/skills_list.json @@ -0,0 +1,13 @@ +{ + "skills": [ + { + "id": "lua_module_display", + "file": "lua_module_display.md", + "title": "lua_module_display", + "summary": "How to draw shapes, text, bitmaps, and images on the display from Lua.", + "cap_groups": [ + "cap_lua" + ] + } + ] +} diff --git a/components/lua_modules/lua_module_display/src/display_hal.c b/components/lua_modules/lua_module_display/src/display_hal.c new file mode 100644 index 0000000..e841d01 --- /dev/null +++ b/components/lua_modules/lua_module_display/src/display_hal.c @@ -0,0 +1,2142 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "display_hal.h" + +#include +#include +#include +#include "esp_attr.h" +#include "esp_check.h" +#include "esp_heap_caps.h" +#include "esp_lcd_panel_io.h" +#include "esp_lcd_panel_ops.h" +#include "esp_log.h" +#include "esp_painter.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#if CONFIG_ESP_ROM_HAS_JPEG_DECODE +#include "rom/tjpgd.h" +#endif + +static const char *TAG = "display_hal"; + +#define DISPLAY_HAL_FRAMEBUFFER_COUNT_MAX 2 +#define DISPLAY_HAL_FLUSH_TIMEOUT_MS 2000 +#define DISPLAY_HAL_TEXT_CACHE_ALIGN 32 +#define DISPLAY_HAL_PI 3.14159265358979323846f +#define DISPLAY_HAL_JPEG_WORKBUF_SIZE 3100 + +typedef struct { + SemaphoreHandle_t lock; + esp_lcd_panel_handle_t panel; + esp_lcd_panel_io_handle_t io; + esp_painter_handle_t painter; + bool display_callbacks_registered; + bool clip_enabled; + int clip_x; + int clip_y; + int clip_width; + int clip_height; + int width; + int height; + size_t framebuffer_bytes; + uint16_t *framebuffers[DISPLAY_HAL_FRAMEBUFFER_COUNT_MAX]; + uint8_t framebuffer_count; + uint8_t draw_framebuffer_index; + uint8_t visible_framebuffer_index; + int8_t pending_framebuffer_index; + bool frame_active; + bool flush_in_flight; + bool framebuffer_initialized; + SemaphoreHandle_t display_flush_done; +} display_hal_state_t; + +static display_hal_state_t s_state; + +static void display_hal_clear_clip_locked(void); +static bool display_hal_flush_done_isr(esp_lcd_panel_io_handle_t panel_io, + esp_lcd_panel_io_event_data_t *edata, + void *user_ctx); +static esp_err_t display_hal_wait_flush_done_locked(TickType_t timeout_ticks); +static bool display_hal_clip_rect_to_screen_locked(int *x, int *y, int *width, int *height); + +static inline uint16_t display_hal_rgb565_to_panel(uint16_t color565) +{ + return __builtin_bswap16(color565); +} + +static esp_err_t display_hal_lock(void) +{ + if (!s_state.lock) { + s_state.lock = xSemaphoreCreateMutex(); + } + ESP_RETURN_ON_FALSE(s_state.lock != NULL, ESP_ERR_NO_MEM, TAG, "create mutex failed"); + ESP_RETURN_ON_FALSE(xSemaphoreTake(s_state.lock, pdMS_TO_TICKS(1000)) == pdTRUE, + ESP_ERR_TIMEOUT, TAG, "mutex timeout"); + return ESP_OK; +} + +static void display_hal_unlock(void) +{ + if (s_state.lock) { + xSemaphoreGive(s_state.lock); + } +} + +static esp_err_t display_hal_require_created_locked(void) +{ + ESP_RETURN_ON_FALSE(s_state.panel != NULL && s_state.io != NULL && + s_state.width > 0 && s_state.height > 0, + ESP_ERR_INVALID_STATE, TAG, "display not created"); + return ESP_OK; +} + +static esp_err_t display_hal_ensure_display_locked(void) +{ + return display_hal_require_created_locked(); +} + +esp_err_t display_hal_create(esp_lcd_panel_handle_t panel_handle, + esp_lcd_panel_io_handle_t io_handle, + int lcd_width, + int lcd_height) +{ + esp_err_t ret = display_hal_lock(); + + if (ret != ESP_OK) { + return ret; + } + + ESP_GOTO_ON_FALSE(panel_handle != NULL && io_handle != NULL, ESP_ERR_INVALID_ARG, + fail, TAG, "panel/io handle missing"); + ESP_GOTO_ON_FALSE(lcd_width > 0 && lcd_height > 0, ESP_ERR_INVALID_ARG, + fail, TAG, "invalid lcd size"); + + s_state.panel = panel_handle; + s_state.io = io_handle; + s_state.width = lcd_width; + s_state.height = lcd_height; + s_state.framebuffer_bytes = (size_t)s_state.width * (size_t)s_state.height * sizeof(uint16_t); + s_state.framebuffer_count = 0; + s_state.draw_framebuffer_index = 0; + s_state.visible_framebuffer_index = 0; + s_state.pending_framebuffer_index = -1; + s_state.frame_active = false; + s_state.flush_in_flight = false; + s_state.framebuffer_initialized = false; + display_hal_clear_clip_locked(); + + if (!s_state.display_flush_done) { + s_state.display_flush_done = xSemaphoreCreateBinary(); + ESP_GOTO_ON_FALSE(s_state.display_flush_done != NULL, ESP_ERR_NO_MEM, fail, TAG, + "create flush semaphore failed"); + } + if (!s_state.display_callbacks_registered) { + const esp_lcd_panel_io_callbacks_t callbacks = { + .on_color_trans_done = display_hal_flush_done_isr, + }; + ESP_GOTO_ON_ERROR(esp_lcd_panel_io_register_event_callbacks(s_state.io, &callbacks, NULL), + fail, TAG, "register flush callback failed"); + s_state.display_callbacks_registered = true; + } + +fail: + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_destroy(void) +{ + esp_err_t ret = display_hal_lock(); + + if (ret != ESP_OK) { + return ret; + } + + if (s_state.flush_in_flight) { + ret = display_hal_wait_flush_done_locked(pdMS_TO_TICKS(DISPLAY_HAL_FLUSH_TIMEOUT_MS)); + if (ret != ESP_OK) { + display_hal_unlock(); + return ret; + } + } + + for (size_t i = 0; i < DISPLAY_HAL_FRAMEBUFFER_COUNT_MAX; ++i) { + heap_caps_free(s_state.framebuffers[i]); + s_state.framebuffers[i] = NULL; + } + if (s_state.painter) { + esp_painter_deinit(s_state.painter); + s_state.painter = NULL; + } + + s_state.panel = NULL; + s_state.io = NULL; + s_state.width = 0; + s_state.height = 0; + s_state.framebuffer_bytes = 0; + s_state.framebuffer_count = 0; + s_state.draw_framebuffer_index = 0; + s_state.visible_framebuffer_index = 0; + s_state.pending_framebuffer_index = -1; + s_state.frame_active = false; + s_state.flush_in_flight = false; + s_state.framebuffer_initialized = false; + s_state.clip_enabled = false; + s_state.clip_x = 0; + s_state.clip_y = 0; + s_state.clip_width = 0; + s_state.clip_height = 0; + + display_hal_unlock(); + return ESP_OK; +} + +static void display_hal_clear_clip_locked(void) +{ + s_state.clip_enabled = false; + s_state.clip_x = 0; + s_state.clip_y = 0; + s_state.clip_width = s_state.width; + s_state.clip_height = s_state.height; +} + +static uint16_t *display_hal_get_draw_framebuffer_locked(void) +{ + if (s_state.framebuffer_count == 0) { + return NULL; + } + return s_state.framebuffers[s_state.draw_framebuffer_index]; +} + +static uint16_t *display_hal_get_visible_framebuffer_locked(void) +{ + if (s_state.framebuffer_count == 0) { + return NULL; + } + return s_state.framebuffers[s_state.visible_framebuffer_index]; +} + +static esp_err_t display_hal_alloc_framebuffer_locked(size_t index) +{ + if (index >= DISPLAY_HAL_FRAMEBUFFER_COUNT_MAX) { + return ESP_ERR_INVALID_ARG; + } + if (s_state.framebuffers[index]) { + return ESP_OK; + } + + s_state.framebuffers[index] = heap_caps_aligned_alloc( + 16, s_state.framebuffer_bytes, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (!s_state.framebuffers[index]) { + s_state.framebuffers[index] = heap_caps_aligned_alloc( + 16, s_state.framebuffer_bytes, MALLOC_CAP_DEFAULT); + } + ESP_RETURN_ON_FALSE(s_state.framebuffers[index] != NULL, ESP_ERR_NO_MEM, TAG, + "framebuffer alloc failed"); + memset(s_state.framebuffers[index], 0, s_state.framebuffer_bytes); + return ESP_OK; +} + +static esp_err_t display_hal_ensure_framebuffer_locked(void) +{ + if (s_state.framebuffer_count > 0) { + return ESP_OK; + } + + ESP_RETURN_ON_ERROR(display_hal_alloc_framebuffer_locked(0), TAG, "alloc framebuffer 0 failed"); + s_state.framebuffer_count = 1; + s_state.draw_framebuffer_index = 0; + s_state.visible_framebuffer_index = 0; + s_state.pending_framebuffer_index = -1; + + if (display_hal_alloc_framebuffer_locked(1) == ESP_OK) { + s_state.framebuffer_count = 2; + } + + s_state.framebuffer_initialized = true; + return ESP_OK; +} + +static void display_hal_fill_framebuffer_locked(uint16_t *framebuffer, uint16_t panel_color) +{ + if (!framebuffer) { + return; + } + size_t pixels = (size_t)s_state.width * (size_t)s_state.height; + for (size_t i = 0; i < pixels; ++i) { + framebuffer[i] = panel_color; + } +} + +static bool display_hal_get_clip_bounds_locked(int *left, int *top, int *right, int *bottom) +{ + int clip_left = 0; + int clip_top = 0; + int clip_right = s_state.width; + int clip_bottom = s_state.height; + + if (s_state.clip_enabled) { + clip_left = s_state.clip_x; + clip_top = s_state.clip_y; + clip_right = s_state.clip_x + s_state.clip_width; + clip_bottom = s_state.clip_y + s_state.clip_height; + + if (clip_left < 0) { + clip_left = 0; + } + if (clip_top < 0) { + clip_top = 0; + } + if (clip_right > s_state.width) { + clip_right = s_state.width; + } + if (clip_bottom > s_state.height) { + clip_bottom = s_state.height; + } + } + + if (left) { + *left = clip_left; + } + if (top) { + *top = clip_top; + } + if (right) { + *right = clip_right; + } + if (bottom) { + *bottom = clip_bottom; + } + return clip_right > clip_left && clip_bottom > clip_top; +} + +static bool display_hal_clip_rect_locked(int *x, int *y, int *width, int *height, + int *src_x, int *src_y) +{ + int clip_left = 0; + int clip_top = 0; + int clip_right = 0; + int clip_bottom = 0; + int dst_x = 0; + int dst_y = 0; + int dst_w = 0; + int dst_h = 0; + int dst_right = 0; + int dst_bottom = 0; + + if (!x || !y || !width || !height || *width <= 0 || *height <= 0) { + return false; + } + if (!display_hal_get_clip_bounds_locked(&clip_left, &clip_top, &clip_right, &clip_bottom)) { + return false; + } + + dst_x = *x; + dst_y = *y; + dst_w = *width; + dst_h = *height; + dst_right = dst_x + dst_w; + dst_bottom = dst_y + dst_h; + + if (dst_x < clip_left) { + int delta = clip_left - dst_x; + if (src_x) { + *src_x += delta; + } + dst_x = clip_left; + } + if (dst_y < clip_top) { + int delta = clip_top - dst_y; + if (src_y) { + *src_y += delta; + } + dst_y = clip_top; + } + if (dst_right > clip_right) { + dst_right = clip_right; + } + if (dst_bottom > clip_bottom) { + dst_bottom = clip_bottom; + } + + dst_w = dst_right - dst_x; + dst_h = dst_bottom - dst_y; + if (dst_w <= 0 || dst_h <= 0) { + return false; + } + + *x = dst_x; + *y = dst_y; + *width = dst_w; + *height = dst_h; + return true; +} + +static bool display_hal_clip_rect_to_screen_locked(int *x, int *y, int *width, int *height) +{ + int dst_x = 0; + int dst_y = 0; + int dst_right = 0; + int dst_bottom = 0; + + if (!x || !y || !width || !height || *width <= 0 || *height <= 0) { + return false; + } + + dst_x = *x; + dst_y = *y; + dst_right = dst_x + *width; + dst_bottom = dst_y + *height; + + if (dst_x < 0) { + dst_x = 0; + } + if (dst_y < 0) { + dst_y = 0; + } + if (dst_right > s_state.width) { + dst_right = s_state.width; + } + if (dst_bottom > s_state.height) { + dst_bottom = s_state.height; + } + + *x = dst_x; + *y = dst_y; + *width = dst_right - dst_x; + *height = dst_bottom - dst_y; + return *width > 0 && *height > 0; +} + +static float display_hal_normalize_degrees(float degrees) +{ + while (degrees < 0.0f) { + degrees += 360.0f; + } + while (degrees >= 360.0f) { + degrees -= 360.0f; + } + return degrees; +} + +static bool display_hal_arc_is_full_sweep(float start_deg, float end_deg) +{ + float sweep = end_deg - start_deg; + + if (fabsf(sweep) >= 359.999f) { + return true; + } + + return fabsf(display_hal_normalize_degrees(start_deg) - + display_hal_normalize_degrees(end_deg)) < 0.001f; +} + +static float display_hal_arc_sweep_degrees(float start_deg, float end_deg) +{ + float start = display_hal_normalize_degrees(start_deg); + float end = display_hal_normalize_degrees(end_deg); + float sweep = end - start; + + if (sweep < 0.0f) { + sweep += 360.0f; + } + return sweep; +} + +static float display_hal_point_angle_degrees(int dx, int dy) +{ + float degrees = atan2f((float)dy, (float)dx) * (180.0f / DISPLAY_HAL_PI); + + if (degrees < 0.0f) { + degrees += 360.0f; + } + return degrees; +} + +static bool display_hal_angle_in_arc(float angle_deg, float start_deg, float end_deg) +{ + float start = display_hal_normalize_degrees(start_deg); + float end = display_hal_normalize_degrees(end_deg); + float angle = display_hal_normalize_degrees(angle_deg); + + if (display_hal_arc_is_full_sweep(start_deg, end_deg)) { + return true; + } + if (start <= end) { + return angle >= start && angle <= end; + } + return angle >= start || angle <= end; +} + +static IRAM_ATTR bool display_hal_flush_done_isr(esp_lcd_panel_io_handle_t panel_io, + esp_lcd_panel_io_event_data_t *edata, + void *user_ctx) +{ + BaseType_t high_task_woken = pdFALSE; + + (void)panel_io; + (void)edata; + (void)user_ctx; + + if (s_state.display_flush_done) { + xSemaphoreGiveFromISR(s_state.display_flush_done, &high_task_woken); + } + + return high_task_woken == pdTRUE; +} + +static esp_err_t display_hal_wait_flush_done_locked(TickType_t timeout_ticks) +{ + if (!s_state.flush_in_flight) { + return ESP_OK; + } + ESP_RETURN_ON_FALSE(s_state.display_flush_done != NULL, ESP_ERR_INVALID_STATE, TAG, + "flush semaphore missing"); + + if (xSemaphoreTake(s_state.display_flush_done, timeout_ticks) != pdTRUE) { + return ESP_ERR_TIMEOUT; + } + + s_state.flush_in_flight = false; + if (s_state.pending_framebuffer_index >= 0) { + s_state.visible_framebuffer_index = (uint8_t)s_state.pending_framebuffer_index; + s_state.pending_framebuffer_index = -1; + } + return ESP_OK; +} + +static esp_err_t display_hal_submit_bitmap_locked(int x_start, int y_start, + int x_end, int y_end, + const uint16_t *pixels, + int pending_framebuffer_index, + bool wait_for_done) +{ + esp_err_t ret = display_hal_wait_flush_done_locked(pdMS_TO_TICKS(DISPLAY_HAL_FLUSH_TIMEOUT_MS)); + if (ret != ESP_OK) { + return ret; + } + + if (s_state.display_flush_done) { + while (xSemaphoreTake(s_state.display_flush_done, 0) == pdTRUE) { + } + } + + ret = esp_lcd_panel_draw_bitmap(s_state.panel, x_start, y_start, x_end, y_end, pixels); + if (ret != ESP_OK) { + return ret; + } + + s_state.flush_in_flight = true; + s_state.pending_framebuffer_index = (int8_t)pending_framebuffer_index; + + if (wait_for_done) { + ret = display_hal_wait_flush_done_locked(pdMS_TO_TICKS(DISPLAY_HAL_FLUSH_TIMEOUT_MS)); + } + return ret; +} + +static const esp_painter_basic_font_t *display_hal_get_font(uint8_t font_size) +{ + switch (font_size) { +#if CONFIG_ESP_PAINTER_BASIC_FONT_12 + case 12: + return &esp_painter_basic_font_12; +#endif +#if CONFIG_ESP_PAINTER_BASIC_FONT_16 + case 16: + return &esp_painter_basic_font_16; +#endif +#if CONFIG_ESP_PAINTER_BASIC_FONT_20 + case 20: + return &esp_painter_basic_font_20; +#endif +#if CONFIG_ESP_PAINTER_BASIC_FONT_24 + case 0: + case 24: + return &esp_painter_basic_font_24; +#endif +#if CONFIG_ESP_PAINTER_BASIC_FONT_28 + case 28: + return &esp_painter_basic_font_28; +#endif +#if CONFIG_ESP_PAINTER_BASIC_FONT_32 + case 32: + return &esp_painter_basic_font_32; +#endif +#if CONFIG_ESP_PAINTER_BASIC_FONT_36 + case 36: + return &esp_painter_basic_font_36; +#endif +#if CONFIG_ESP_PAINTER_BASIC_FONT_40 + case 40: + return &esp_painter_basic_font_40; +#endif +#if CONFIG_ESP_PAINTER_BASIC_FONT_44 + case 44: + return &esp_painter_basic_font_44; +#endif +#if CONFIG_ESP_PAINTER_BASIC_FONT_48 + case 48: + return &esp_painter_basic_font_48; +#endif + default: + break; + } + +#if CONFIG_ESP_PAINTER_BASIC_FONT_24 + return &esp_painter_basic_font_24; +#elif CONFIG_ESP_PAINTER_BASIC_FONT_20 + return &esp_painter_basic_font_20; +#elif CONFIG_ESP_PAINTER_BASIC_FONT_16 + return &esp_painter_basic_font_16; +#elif CONFIG_ESP_PAINTER_BASIC_FONT_12 + return &esp_painter_basic_font_12; +#else + return NULL; +#endif +} + +static void display_hal_measure_text_raw(const char *text, const esp_painter_basic_font_t *font, + uint16_t *out_width, uint16_t *out_height) +{ + uint16_t max_cols = 0; + uint16_t cols = 0; + uint16_t lines = 1; + + if (!text || !font) { + if (out_width) { + *out_width = 0; + } + if (out_height) { + *out_height = 0; + } + return; + } + + for (const char *p = text; *p; ++p) { + if (*p == '\n') { + if (cols > max_cols) { + max_cols = cols; + } + cols = 0; + lines++; + } else if (*p != '\r') { + cols++; + } + } + if (cols > max_cols) { + max_cols = cols; + } + + if (out_width) { + *out_width = (uint16_t)(max_cols * font->width); + } + if (out_height) { + *out_height = (uint16_t)(lines * font->height); + } +} + +static esp_err_t display_hal_ensure_painter_locked(void) +{ + esp_painter_config_t painter_cfg = { + .canvas = { + .width = (uint16_t)s_state.width, + .height = (uint16_t)s_state.height, + }, + .color_format = ESP_PAINTER_COLOR_FORMAT_RGB565, + .default_font = display_hal_get_font(24), + .swap_rgb565 = true, + }; + + if (s_state.painter) { + return ESP_OK; + } + ESP_RETURN_ON_FALSE(painter_cfg.default_font != NULL, ESP_ERR_NOT_SUPPORTED, TAG, + "no esp_painter font enabled"); + ESP_RETURN_ON_ERROR(esp_painter_init(&painter_cfg, &s_state.painter), TAG, "esp_painter_init failed"); + return ESP_OK; +} + +static esp_err_t display_hal_fill_rect_locked(int x, int y, int width, int height, uint16_t color565) +{ + uint16_t panel_color = display_hal_rgb565_to_panel(color565); + uint16_t *framebuffer = display_hal_get_draw_framebuffer_locked(); + + if (!display_hal_clip_rect_locked(&x, &y, &width, &height, NULL, NULL)) { + return ESP_OK; + } + + if (s_state.frame_active && framebuffer) { + if (s_state.flush_in_flight && + s_state.pending_framebuffer_index == (int8_t)s_state.draw_framebuffer_index) { + ESP_RETURN_ON_ERROR( + display_hal_wait_flush_done_locked(pdMS_TO_TICKS(DISPLAY_HAL_FLUSH_TIMEOUT_MS)), + TAG, "wait flush failed"); + } + for (int row = 0; row < height; ++row) { + uint16_t *dst = framebuffer + ((size_t)(y + row) * s_state.width) + x; + for (int col = 0; col < width; ++col) { + dst[col] = panel_color; + } + } + return ESP_OK; + } + + uint16_t *line = malloc((size_t)width * sizeof(uint16_t)); + ESP_RETURN_ON_FALSE(line != NULL, ESP_ERR_NO_MEM, TAG, "line alloc failed"); + for (int i = 0; i < width; ++i) { + line[i] = panel_color; + } + for (int row = 0; row < height; ++row) { + esp_err_t ret = display_hal_submit_bitmap_locked(x, y + row, x + width, y + row + 1, line, -1, true); + if (ret != ESP_OK) { + free(line); + return ret; + } + } + free(line); + return ESP_OK; +} + +static esp_err_t display_hal_draw_pixel_locked(int x, int y, uint16_t color565) +{ + return display_hal_fill_rect_locked(x, y, 1, 1, color565); +} + +static esp_err_t display_hal_draw_hline_locked(int x, int y, int width, uint16_t color565) +{ + return display_hal_fill_rect_locked(x, y, width, 1, color565); +} + +static esp_err_t display_hal_draw_vline_locked(int x, int y, int height, uint16_t color565) +{ + return display_hal_fill_rect_locked(x, y, 1, height, color565); +} + +static esp_err_t display_hal_draw_line_locked(int x0, int y0, int x1, int y1, uint16_t color565) +{ + if (y0 == y1) { + int x = x0 < x1 ? x0 : x1; + return display_hal_draw_hline_locked(x, y0, abs(x1 - x0) + 1, color565); + } + if (x0 == x1) { + int y = y0 < y1 ? y0 : y1; + return display_hal_draw_vline_locked(x0, y, abs(y1 - y0) + 1, color565); + } + + int dx = abs(x1 - x0); + int sx = x0 < x1 ? 1 : -1; + int dy = -abs(y1 - y0); + int sy = y0 < y1 ? 1 : -1; + int err = dx + dy; + + while (true) { + esp_err_t ret = display_hal_draw_pixel_locked(x0, y0, color565); + if (ret != ESP_OK) { + return ret; + } + if (x0 == x1 && y0 == y1) { + break; + } + int e2 = err * 2; + if (e2 >= dy) { + err += dy; + x0 += sx; + } + if (e2 <= dx) { + err += dx; + y0 += sy; + } + } + return ESP_OK; +} + +static esp_err_t display_hal_draw_rect_locked(int x, int y, int width, int height, uint16_t color565) +{ + if (width <= 0 || height <= 0) { + return ESP_OK; + } + if (width == 1) { + return display_hal_draw_vline_locked(x, y, height, color565); + } + if (height == 1) { + return display_hal_draw_hline_locked(x, y, width, color565); + } + + ESP_RETURN_ON_ERROR(display_hal_draw_hline_locked(x, y, width, color565), TAG, "draw top failed"); + ESP_RETURN_ON_ERROR(display_hal_draw_hline_locked(x, y + height - 1, width, color565), TAG, + "draw bottom failed"); + ESP_RETURN_ON_ERROR(display_hal_draw_vline_locked(x, y + 1, height - 2, color565), TAG, + "draw left failed"); + return display_hal_draw_vline_locked(x + width - 1, y + 1, height - 2, color565); +} + +static esp_err_t display_hal_draw_bitmap_crop_locked(int x, int y, + int src_x, int src_y, + int w, int h, + int src_width, int src_height, + const uint16_t *pixels) +{ + if (!pixels || src_width <= 0 || src_height <= 0 || w <= 0 || h <= 0) { + return ESP_ERR_INVALID_ARG; + } + + if (src_x < 0) { + x -= src_x; + w += src_x; + src_x = 0; + } + if (src_y < 0) { + y -= src_y; + h += src_y; + src_y = 0; + } + if (src_x + w > src_width) { + w = src_width - src_x; + } + if (src_y + h > src_height) { + h = src_height - src_y; + } + if (w <= 0 || h <= 0) { + return ESP_OK; + } + + if (!display_hal_clip_rect_locked(&x, &y, &w, &h, &src_x, &src_y)) { + return ESP_OK; + } + + uint16_t *framebuffer = display_hal_get_draw_framebuffer_locked(); + if (s_state.frame_active && framebuffer) { + if (s_state.flush_in_flight && + s_state.pending_framebuffer_index == (int8_t)s_state.draw_framebuffer_index) { + ESP_RETURN_ON_ERROR( + display_hal_wait_flush_done_locked(pdMS_TO_TICKS(DISPLAY_HAL_FLUSH_TIMEOUT_MS)), + TAG, "wait flush failed"); + } + for (int row = 0; row < h; ++row) { + const uint16_t *src = pixels + ((size_t)(src_y + row) * src_width) + src_x; + uint16_t *dst = framebuffer + ((size_t)(y + row) * s_state.width) + x; + memcpy(dst, src, (size_t)w * sizeof(uint16_t)); + } + return ESP_OK; + } + + if (src_x == 0 && w == src_width) { + const uint16_t *start = pixels + ((size_t)src_y * src_width); + return display_hal_submit_bitmap_locked(x, y, x + w, y + h, start, -1, true); + } + + for (int row = 0; row < h; ++row) { + const uint16_t *row_ptr = pixels + ((size_t)(src_y + row) * src_width) + src_x; + ESP_RETURN_ON_ERROR( + display_hal_submit_bitmap_locked(x, y + row, x + w, y + row + 1, row_ptr, -1, true), + TAG, "submit bitmap row failed"); + } + return ESP_OK; +} + +static esp_err_t display_hal_draw_bitmap_locked(int x, int y, int w, int h, const uint16_t *pixels) +{ + return display_hal_draw_bitmap_crop_locked(x, y, 0, 0, w, h, w, h, pixels); +} + +static esp_err_t display_hal_present_locked(void) +{ + uint16_t *framebuffer = display_hal_get_draw_framebuffer_locked(); + + if (!framebuffer || !s_state.frame_active) { + return ESP_ERR_INVALID_STATE; + } + + ESP_RETURN_ON_ERROR( + display_hal_submit_bitmap_locked( + 0, 0, s_state.width, s_state.height, + framebuffer, (int)s_state.draw_framebuffer_index, false), + TAG, "present failed"); + + if (s_state.framebuffer_count > 1) { + s_state.draw_framebuffer_index = (uint8_t)((s_state.draw_framebuffer_index + 1) % + s_state.framebuffer_count); + } + return ESP_OK; +} + +static esp_err_t display_hal_present_rect_locked(int x, int y, int width, int height) +{ + uint16_t *draw_fb = display_hal_get_draw_framebuffer_locked(); + uint16_t *visible_fb = display_hal_get_visible_framebuffer_locked(); + + if (!draw_fb || !s_state.frame_active) { + return ESP_ERR_INVALID_STATE; + } + if (!display_hal_clip_rect_to_screen_locked(&x, &y, &width, &height)) { + return ESP_OK; + } + if (s_state.flush_in_flight) { + ESP_RETURN_ON_ERROR( + display_hal_wait_flush_done_locked(pdMS_TO_TICKS(DISPLAY_HAL_FLUSH_TIMEOUT_MS)), + TAG, "wait flush failed"); + } + + if (width == s_state.width) { + const uint16_t *start = draw_fb + ((size_t)y * s_state.width); + ESP_RETURN_ON_ERROR( + display_hal_submit_bitmap_locked(x, y, x + width, y + height, start, -1, true), + TAG, "present rect failed"); + } else { + for (int row = 0; row < height; ++row) { + const uint16_t *row_ptr = draw_fb + ((size_t)(y + row) * s_state.width) + x; + ESP_RETURN_ON_ERROR( + display_hal_submit_bitmap_locked( + x, y + row, x + width, y + row + 1, row_ptr, -1, true), + TAG, "present rect row failed"); + } + } + + if (visible_fb && visible_fb != draw_fb) { + for (int row = 0; row < height; ++row) { + const uint16_t *src = draw_fb + ((size_t)(y + row) * s_state.width) + x; + uint16_t *dst = visible_fb + ((size_t)(y + row) * s_state.width) + x; + memcpy(dst, src, (size_t)width * sizeof(uint16_t)); + } + } + return ESP_OK; +} + +static void display_hal_sort_vertices_by_y(int *x1, int *y1, int *x2, int *y2, int *x3, int *y3) +{ + if (*y1 > *y2) { + int tx = *x1; + int ty = *y1; + *x1 = *x2; + *y1 = *y2; + *x2 = tx; + *y2 = ty; + } + if (*y2 > *y3) { + int tx = *x2; + int ty = *y2; + *x2 = *x3; + *y2 = *y3; + *x3 = tx; + *y3 = ty; + } + if (*y1 > *y2) { + int tx = *x1; + int ty = *y1; + *x1 = *x2; + *y1 = *y2; + *x2 = tx; + *y2 = ty; + } +} + +#if CONFIG_ESP_ROM_HAS_JPEG_DECODE +typedef struct { + const uint8_t *data; + size_t len; + size_t offset; + uint16_t *pixels; + int width; + int height; +} display_hal_jpeg_ctx_t; + +static esp_err_t display_hal_jpeg_result_to_err(JRESULT result) +{ + switch (result) { + case JDR_OK: + return ESP_OK; + case JDR_PAR: + return ESP_ERR_INVALID_ARG; + case JDR_MEM1: + case JDR_MEM2: + return ESP_ERR_NO_MEM; + case JDR_FMT1: + case JDR_FMT2: + case JDR_FMT3: + return ESP_ERR_NOT_SUPPORTED; + case JDR_INTR: + case JDR_INP: + default: + return ESP_FAIL; + } +} + +static UINT display_hal_jpeg_input_cb(JDEC *decoder, BYTE *buf, UINT len) +{ + display_hal_jpeg_ctx_t *ctx = (display_hal_jpeg_ctx_t *)decoder->device; + size_t remaining = ctx->len - ctx->offset; + size_t chunk = len; + + if (chunk > remaining) { + chunk = remaining; + } + if (buf) { + memcpy(buf, ctx->data + ctx->offset, chunk); + } + ctx->offset += chunk; + return (UINT)chunk; +} + +static UINT display_hal_jpeg_output_cb(JDEC *decoder, void *bitmap, JRECT *rect) +{ + display_hal_jpeg_ctx_t *ctx = (display_hal_jpeg_ctx_t *)decoder->device; + uint8_t *src = (uint8_t *)bitmap; + + for (int y = rect->top; y <= rect->bottom; ++y) { + uint16_t *dst = ctx->pixels + ((size_t)y * (size_t)ctx->width) + rect->left; + for (int x = rect->left; x <= rect->right; ++x) { + uint16_t color = + (uint16_t)(((src[0] >> 3) << 11) | ((src[1] >> 2) << 5) | (src[2] >> 3)); + *dst++ = __builtin_bswap16(color); + src += 3; + } + } + return 1; +} + +static esp_err_t display_hal_decode_jpeg_rgb565_be(const uint8_t *jpeg_data, size_t jpeg_len, + uint16_t **pixels_out, int *out_w, int *out_h) +{ + display_hal_jpeg_ctx_t ctx = { + .data = jpeg_data, + .len = jpeg_len, + }; + JDEC decoder = {0}; + void *work = NULL; + esp_err_t ret = ESP_OK; + JRESULT result; + + if (!jpeg_data || jpeg_len == 0 || !pixels_out || !out_w || !out_h) { + return ESP_ERR_INVALID_ARG; + } + + work = calloc(1, DISPLAY_HAL_JPEG_WORKBUF_SIZE); + ESP_GOTO_ON_FALSE(work != NULL, ESP_ERR_NO_MEM, cleanup, TAG, "jpeg workspace alloc failed"); + + result = jd_prepare(&decoder, display_hal_jpeg_input_cb, work, DISPLAY_HAL_JPEG_WORKBUF_SIZE, &ctx); + ret = display_hal_jpeg_result_to_err(result); + ESP_GOTO_ON_ERROR(ret, cleanup, TAG, "jpeg header parse failed (%d)", result); + + ctx.width = (int)decoder.width; + ctx.height = (int)decoder.height; + ctx.pixels = malloc((size_t)ctx.width * (size_t)ctx.height * sizeof(uint16_t)); + ESP_GOTO_ON_FALSE(ctx.pixels != NULL, ESP_ERR_NO_MEM, cleanup, TAG, "jpeg pixel buffer alloc failed"); + + result = jd_decomp(&decoder, display_hal_jpeg_output_cb, 0); + ret = display_hal_jpeg_result_to_err(result); + ESP_GOTO_ON_ERROR(ret, cleanup, TAG, "jpeg decode failed (%d)", result); + + *pixels_out = ctx.pixels; + *out_w = ctx.width; + *out_h = ctx.height; + ctx.pixels = NULL; + +cleanup: + free(ctx.pixels); + free(work); + return ret; +} + +static esp_err_t display_hal_jpeg_get_size_internal(const uint8_t *jpeg_data, size_t jpeg_len, + int *out_w, int *out_h) +{ + display_hal_jpeg_ctx_t ctx = { + .data = jpeg_data, + .len = jpeg_len, + }; + JDEC decoder = {0}; + void *work = NULL; + esp_err_t ret = ESP_OK; + JRESULT result; + + if (!jpeg_data || jpeg_len == 0 || !out_w || !out_h) { + return ESP_ERR_INVALID_ARG; + } + + work = calloc(1, DISPLAY_HAL_JPEG_WORKBUF_SIZE); + ESP_GOTO_ON_FALSE(work != NULL, ESP_ERR_NO_MEM, cleanup, TAG, "jpeg workspace alloc failed"); + + result = jd_prepare(&decoder, display_hal_jpeg_input_cb, work, DISPLAY_HAL_JPEG_WORKBUF_SIZE, &ctx); + ret = display_hal_jpeg_result_to_err(result); + ESP_GOTO_ON_ERROR(ret, cleanup, TAG, "jpeg header parse failed (%d)", result); + + *out_w = (int)decoder.width; + *out_h = (int)decoder.height; + +cleanup: + free(work); + return ret; +} +#endif + +static esp_err_t display_hal_scale_rgb565_be(const uint16_t *src, int src_w, int src_h, + int dst_w, int dst_h, uint16_t **dst_out) +{ + uint16_t *dst = NULL; + + if (!src || src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0 || !dst_out) { + return ESP_ERR_INVALID_ARG; + } + dst = malloc((size_t)dst_w * (size_t)dst_h * sizeof(uint16_t)); + ESP_RETURN_ON_FALSE(dst != NULL, ESP_ERR_NO_MEM, TAG, "scale buffer alloc failed"); + + for (int y = 0; y < dst_h; ++y) { + int src_y = (y * src_h) / dst_h; + const uint16_t *src_row = src + ((size_t)src_y * src_w); + uint16_t *dst_row = dst + ((size_t)y * dst_w); + for (int x = 0; x < dst_w; ++x) { + int src_x = (x * src_w) / dst_w; + dst_row[x] = src_row[src_x]; + } + } + + *dst_out = dst; + return ESP_OK; +} + +int display_hal_width(void) +{ + return s_state.width; +} + +int display_hal_height(void) +{ + return s_state.height; +} + +esp_err_t display_hal_begin_frame(bool clear, uint16_t color565) +{ + esp_err_t ret = display_hal_lock(); + uint16_t *draw_fb = NULL; + uint16_t *visible_fb = NULL; + + if (ret != ESP_OK) { + return ret; + } + + ret = display_hal_ensure_display_locked(); + if (ret == ESP_OK) { + ret = display_hal_ensure_framebuffer_locked(); + } + if (ret == ESP_OK && s_state.flush_in_flight && + (!clear || s_state.pending_framebuffer_index == (int8_t)s_state.draw_framebuffer_index)) { + ret = display_hal_wait_flush_done_locked(pdMS_TO_TICKS(DISPLAY_HAL_FLUSH_TIMEOUT_MS)); + } + if (ret == ESP_OK) { + s_state.frame_active = true; + display_hal_clear_clip_locked(); + draw_fb = display_hal_get_draw_framebuffer_locked(); + visible_fb = display_hal_get_visible_framebuffer_locked(); + if (clear || !s_state.framebuffer_initialized) { + display_hal_fill_framebuffer_locked(draw_fb, display_hal_rgb565_to_panel(color565)); + s_state.framebuffer_initialized = true; + } else if (draw_fb && visible_fb && draw_fb != visible_fb) { + memcpy(draw_fb, visible_fb, s_state.framebuffer_bytes); + } + } + + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_present(void) +{ + esp_err_t ret = display_hal_lock(); + + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret == ESP_OK) { + ret = display_hal_present_locked(); + } + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_present_rect(int x, int y, int width, int height) +{ + esp_err_t ret = display_hal_lock(); + + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret == ESP_OK) { + ret = display_hal_present_rect_locked(x, y, width, height); + } + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_end_frame(void) +{ + esp_err_t ret = display_hal_lock(); + + if (ret != ESP_OK) { + return ret; + } + if (s_state.flush_in_flight) { + ret = display_hal_wait_flush_done_locked(pdMS_TO_TICKS(DISPLAY_HAL_FLUSH_TIMEOUT_MS)); + } + s_state.frame_active = false; + display_hal_clear_clip_locked(); + display_hal_unlock(); + return ret; +} + +bool display_hal_is_frame_active(void) +{ + bool active = false; + + if (display_hal_lock() == ESP_OK) { + active = s_state.frame_active; + display_hal_unlock(); + } + return active; +} + +esp_err_t display_hal_get_animation_info(display_hal_animation_info_t *info) +{ + esp_err_t ret = display_hal_lock(); + + if (ret != ESP_OK) { + return ret; + } + if (!info) { + display_hal_unlock(); + return ESP_ERR_INVALID_ARG; + } + ret = display_hal_ensure_display_locked(); + if (ret == ESP_OK) { + ret = display_hal_ensure_framebuffer_locked(); + } + if (ret == ESP_OK) { + info->framebuffer_count = s_state.framebuffer_count; + info->double_buffered = s_state.framebuffer_count > 1; + info->frame_active = s_state.frame_active; + info->flush_in_flight = s_state.flush_in_flight; + } + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_clear(uint16_t color565) +{ + return display_hal_fill_rect(0, 0, display_hal_width(), display_hal_height(), color565); +} + +esp_err_t display_hal_set_clip_rect(int x, int y, int width, int height) +{ + esp_err_t ret = display_hal_lock(); + + if (ret != ESP_OK) { + return ret; + } + ret = display_hal_require_created_locked(); + if (ret != ESP_OK) { + display_hal_unlock(); + return ret; + } + if (width <= 0 || height <= 0) { + display_hal_unlock(); + return ESP_ERR_INVALID_ARG; + } + s_state.clip_enabled = true; + s_state.clip_x = x; + s_state.clip_y = y; + s_state.clip_width = width; + s_state.clip_height = height; + display_hal_unlock(); + return ESP_OK; +} + +esp_err_t display_hal_clear_clip_rect(void) +{ + esp_err_t ret = display_hal_lock(); + + if (ret != ESP_OK) { + return ret; + } + display_hal_clear_clip_locked(); + display_hal_unlock(); + return ESP_OK; +} + +esp_err_t display_hal_fill_rect(int x, int y, int width, int height, uint16_t color565) +{ + esp_err_t ret = display_hal_lock(); + + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret == ESP_OK) { + ret = display_hal_fill_rect_locked(x, y, width, height, color565); + } + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_draw_line(int x0, int y0, int x1, int y1, uint16_t color565) +{ + esp_err_t ret = display_hal_lock(); + + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret == ESP_OK) { + ret = display_hal_draw_line_locked(x0, y0, x1, y1, color565); + } + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_draw_rect(int x, int y, int width, int height, uint16_t color565) +{ + esp_err_t ret = display_hal_lock(); + + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret == ESP_OK) { + ret = display_hal_draw_rect_locked(x, y, width, height, color565); + } + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_draw_pixel(int x, int y, uint16_t color565) +{ + return display_hal_fill_rect(x, y, 1, 1, color565); +} + +esp_err_t display_hal_set_backlight(bool on) +{ + esp_err_t ret = display_hal_lock(); + + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret == ESP_OK) { + ret = esp_lcd_panel_disp_on_off(s_state.panel, on); + } + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_fill_circle(int cx, int cy, int r, uint16_t color565) +{ + if (r <= 0) { + return ESP_OK; + } + + uint16_t panel_color = display_hal_rgb565_to_panel(color565); + uint16_t *span = malloc((size_t)(r * 2 + 1) * sizeof(uint16_t)); + ESP_RETURN_ON_FALSE(span != NULL, ESP_ERR_NO_MEM, TAG, "circle span alloc failed"); + for (int i = 0; i < r * 2 + 1; ++i) { + span[i] = panel_color; + } + + esp_err_t ret = display_hal_lock(); + if (ret != ESP_OK) { + free(span); + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + for (int dy = -r; dy <= r && ret == ESP_OK; ++dy) { + int dx = (int)sqrtf((float)(r * r - dy * dy)); + ret = display_hal_draw_bitmap_locked(cx - dx, cy + dy, dx * 2 + 1, 1, span); + } + display_hal_unlock(); + free(span); + return ret; +} + +esp_err_t display_hal_draw_circle(int cx, int cy, int r, uint16_t color565) +{ + if (r <= 0) { + return display_hal_draw_pixel(cx, cy, color565); + } + + esp_err_t ret = display_hal_lock(); + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret != ESP_OK) { + display_hal_unlock(); + return ret; + } + + int x = 0; + int y = r; + int d = 1 - r; + + while (x <= y) { + const int pts[8][2] = { + {cx + x, cy + y}, {cx - x, cy + y}, + {cx + x, cy - y}, {cx - x, cy - y}, + {cx + y, cy + x}, {cx - y, cy + x}, + {cx + y, cy - x}, {cx - y, cy - x}, + }; + for (int i = 0; i < 8 && ret == ESP_OK; ++i) { + ret = display_hal_draw_pixel_locked(pts[i][0], pts[i][1], color565); + } + if (d < 0) { + d += 2 * x + 3; + } else { + d += 2 * (x - y) + 5; + y--; + } + x++; + } + + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_draw_arc(int cx, int cy, int radius, + float start_deg, float end_deg, uint16_t color565) +{ + if (radius <= 0) { + return display_hal_draw_pixel(cx, cy, color565); + } + if (display_hal_arc_is_full_sweep(start_deg, end_deg)) { + return display_hal_draw_circle(cx, cy, radius, color565); + } + + esp_err_t ret = display_hal_lock(); + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret != ESP_OK) { + display_hal_unlock(); + return ret; + } + + float start = display_hal_normalize_degrees(start_deg); + float sweep = display_hal_arc_sweep_degrees(start_deg, end_deg); + int steps = (int)ceilf(((sweep * DISPLAY_HAL_PI) / 180.0f) * (float)radius); + if (steps < 8) { + steps = 8; + } + + int prev_x = cx + (int)lroundf(cosf(start * DISPLAY_HAL_PI / 180.0f) * (float)radius); + int prev_y = cy + (int)lroundf(sinf(start * DISPLAY_HAL_PI / 180.0f) * (float)radius); + + for (int i = 1; i <= steps && ret == ESP_OK; ++i) { + float angle = start + (sweep * (float)i / (float)steps); + float rad = angle * DISPLAY_HAL_PI / 180.0f; + int x = cx + (int)lroundf(cosf(rad) * (float)radius); + int y = cy + (int)lroundf(sinf(rad) * (float)radius); + ret = display_hal_draw_line_locked(prev_x, prev_y, x, y, color565); + prev_x = x; + prev_y = y; + } + + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_fill_arc(int cx, int cy, int inner_radius, int outer_radius, + float start_deg, float end_deg, uint16_t color565) +{ + if (outer_radius < 0) { + return ESP_ERR_INVALID_ARG; + } + if (outer_radius == 0) { + return display_hal_draw_pixel(cx, cy, color565); + } + if (inner_radius < 0) { + inner_radius = 0; + } + if (inner_radius > outer_radius) { + int tmp = inner_radius; + inner_radius = outer_radius; + outer_radius = tmp; + } + if (display_hal_arc_is_full_sweep(start_deg, end_deg) && inner_radius == 0) { + return display_hal_fill_circle(cx, cy, outer_radius, color565); + } + + esp_err_t ret = display_hal_lock(); + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret != ESP_OK) { + display_hal_unlock(); + return ret; + } + + int clip_left = 0; + int clip_top = 0; + int clip_right = s_state.width; + int clip_bottom = s_state.height; + if (!display_hal_get_clip_bounds_locked(&clip_left, &clip_top, &clip_right, &clip_bottom)) { + display_hal_unlock(); + return ESP_OK; + } + + int outer_sq = outer_radius * outer_radius; + int inner_sq = inner_radius * inner_radius; + int y_start = cy - outer_radius; + int y_end = cy + outer_radius; + if (y_start < clip_top) { + y_start = clip_top; + } + if (y_end >= clip_bottom) { + y_end = clip_bottom - 1; + } + + for (int y = y_start; y <= y_end && ret == ESP_OK; ++y) { + int span_start = -1; + int x_start = cx - outer_radius; + int x_end = cx + outer_radius; + if (x_start < clip_left) { + x_start = clip_left; + } + if (x_end >= clip_right) { + x_end = clip_right - 1; + } + + for (int x = x_start; x <= x_end; ++x) { + int dx = x - cx; + int dy = y - cy; + int dist_sq = dx * dx + dy * dy; + bool inside = dist_sq <= outer_sq && dist_sq >= inner_sq; + + if (inside && !display_hal_arc_is_full_sweep(start_deg, end_deg)) { + inside = display_hal_angle_in_arc(display_hal_point_angle_degrees(dx, dy), start_deg, end_deg); + } + + if (inside) { + if (span_start < 0) { + span_start = x; + } + } else if (span_start >= 0) { + ret = display_hal_draw_hline_locked(span_start, y, x - span_start, color565); + span_start = -1; + } + } + + if (span_start >= 0 && ret == ESP_OK) { + ret = display_hal_draw_hline_locked(span_start, y, x_end - span_start + 1, color565); + } + } + + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_draw_ellipse(int cx, int cy, int radius_x, int radius_y, + uint16_t color565) +{ + if (radius_x < 0 || radius_y < 0) { + return ESP_ERR_INVALID_ARG; + } + if (radius_x == 0 && radius_y == 0) { + return display_hal_draw_pixel(cx, cy, color565); + } + if (radius_x == 0) { + return display_hal_draw_line(cx, cy - radius_y, cx, cy + radius_y, color565); + } + if (radius_y == 0) { + return display_hal_draw_line(cx - radius_x, cy, cx + radius_x, cy, color565); + } + + esp_err_t ret = display_hal_lock(); + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret != ESP_OK) { + display_hal_unlock(); + return ret; + } + + float perimeter = DISPLAY_HAL_PI * + (3.0f * (radius_x + radius_y) - + sqrtf((float)((3 * radius_x + radius_y) * (radius_x + 3 * radius_y)))); + int steps = (int)ceilf(perimeter); + if (steps < 16) { + steps = 16; + } + + int prev_x = cx + radius_x; + int prev_y = cy; + for (int i = 1; i <= steps && ret == ESP_OK; ++i) { + float angle = ((float)i / (float)steps) * 2.0f * DISPLAY_HAL_PI; + int x = cx + (int)lroundf(cosf(angle) * (float)radius_x); + int y = cy + (int)lroundf(sinf(angle) * (float)radius_y); + ret = display_hal_draw_line_locked(prev_x, prev_y, x, y, color565); + prev_x = x; + prev_y = y; + } + + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_fill_ellipse(int cx, int cy, int radius_x, int radius_y, + uint16_t color565) +{ + if (radius_x < 0 || radius_y < 0) { + return ESP_ERR_INVALID_ARG; + } + if (radius_x == 0 && radius_y == 0) { + return display_hal_draw_pixel(cx, cy, color565); + } + if (radius_x == 0) { + return display_hal_fill_rect(cx, cy - radius_y, 1, radius_y * 2 + 1, color565); + } + if (radius_y == 0) { + return display_hal_fill_rect(cx - radius_x, cy, radius_x * 2 + 1, 1, color565); + } + + esp_err_t ret = display_hal_lock(); + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret != ESP_OK) { + display_hal_unlock(); + return ret; + } + + int clip_left = 0; + int clip_top = 0; + int clip_right = s_state.width; + int clip_bottom = s_state.height; + if (!display_hal_get_clip_bounds_locked(&clip_left, &clip_top, &clip_right, &clip_bottom)) { + display_hal_unlock(); + return ESP_OK; + } + + int y_start = cy - radius_y; + int y_end = cy + radius_y; + if (y_start < clip_top) { + y_start = clip_top; + } + if (y_end >= clip_bottom) { + y_end = clip_bottom - 1; + } + + for (int y = y_start; y <= y_end && ret == ESP_OK; ++y) { + float dy = (float)(y - cy) / (float)radius_y; + float dx = (float)radius_x * sqrtf(fmaxf(0.0f, 1.0f - (dy * dy))); + int span = (int)lroundf(dx); + int x0 = cx - span; + int x1 = cx + span; + + if (x0 < clip_left) { + x0 = clip_left; + } + if (x1 >= clip_right) { + x1 = clip_right - 1; + } + if (x1 >= x0) { + ret = display_hal_draw_hline_locked(x0, y, x1 - x0 + 1, color565); + } + } + + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_draw_round_rect(int x, int y, int width, int height, + int radius, uint16_t color565) +{ + if (width <= 0 || height <= 0) { + return ESP_OK; + } + + int max_radius = (width < height ? width : height) / 2; + if (radius <= 0 || max_radius <= 0) { + return display_hal_draw_rect(x, y, width, height, color565); + } + if (radius > max_radius) { + radius = max_radius; + } + + esp_err_t ret = display_hal_lock(); + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret != ESP_OK) { + display_hal_unlock(); + return ret; + } + + ret = display_hal_draw_hline_locked(x + radius, y, width - (radius * 2), color565); + if (ret == ESP_OK) { + ret = display_hal_draw_hline_locked(x + radius, y + height - 1, width - (radius * 2), color565); + } + if (ret == ESP_OK) { + ret = display_hal_draw_vline_locked(x, y + radius, height - (radius * 2), color565); + } + if (ret == ESP_OK) { + ret = display_hal_draw_vline_locked(x + width - 1, y + radius, height - (radius * 2), color565); + } + + for (int row = 0; row < radius && ret == ESP_OK; ++row) { + int off = radius - row - 1; + int dx = (int)sqrtf((float)(radius * radius - off * off)); + int inset = radius - dx; + ret = display_hal_draw_pixel_locked(x + inset, y + row, color565); + if (ret == ESP_OK) { + ret = display_hal_draw_pixel_locked(x + width - 1 - inset, y + row, color565); + } + if (ret == ESP_OK) { + ret = display_hal_draw_pixel_locked(x + inset, y + height - 1 - row, color565); + } + if (ret == ESP_OK) { + ret = display_hal_draw_pixel_locked(x + width - 1 - inset, y + height - 1 - row, color565); + } + } + + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_fill_round_rect(int x, int y, int width, int height, + int radius, uint16_t color565) +{ + if (width <= 0 || height <= 0) { + return ESP_OK; + } + + int max_radius = (width < height ? width : height) / 2; + if (radius <= 0 || max_radius <= 0) { + return display_hal_fill_rect(x, y, width, height, color565); + } + if (radius > max_radius) { + radius = max_radius; + } + + esp_err_t ret = display_hal_lock(); + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret != ESP_OK) { + display_hal_unlock(); + return ret; + } + + ret = display_hal_fill_rect_locked(x + radius, y, width - (radius * 2), height, color565); + for (int row = 0; row < radius && ret == ESP_OK; ++row) { + int off = radius - row - 1; + int dx = (int)sqrtf((float)(radius * radius - off * off)); + int inset = radius - dx; + int span_w = width - (inset * 2); + ret = display_hal_draw_hline_locked(x + inset, y + row, span_w, color565); + if (ret == ESP_OK) { + ret = display_hal_draw_hline_locked(x + inset, y + height - 1 - row, span_w, color565); + } + } + + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_draw_triangle(int x1, int y1, int x2, int y2, + int x3, int y3, uint16_t color565) +{ + esp_err_t ret = display_hal_lock(); + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret == ESP_OK) { + ret = display_hal_draw_line_locked(x1, y1, x2, y2, color565); + } + if (ret == ESP_OK) { + ret = display_hal_draw_line_locked(x2, y2, x3, y3, color565); + } + if (ret == ESP_OK) { + ret = display_hal_draw_line_locked(x3, y3, x1, y1, color565); + } + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_fill_triangle(int x1, int y1, int x2, int y2, + int x3, int y3, uint16_t color565) +{ + display_hal_sort_vertices_by_y(&x1, &y1, &x2, &y2, &x3, &y3); + + esp_err_t ret = display_hal_lock(); + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret != ESP_OK) { + display_hal_unlock(); + return ret; + } + + if (y1 == y3) { + int min_x = x1; + int max_x = x1; + if (x2 < min_x) { + min_x = x2; + } + if (x3 < min_x) { + min_x = x3; + } + if (x2 > max_x) { + max_x = x2; + } + if (x3 > max_x) { + max_x = x3; + } + ret = display_hal_draw_hline_locked(min_x, y1, max_x - min_x + 1, color565); + display_hal_unlock(); + return ret; + } + + for (int y = y1; y <= y3 && ret == ESP_OK; ++y) { + float alpha = (y3 == y1) ? 0.0f : (float)(y - y1) / (float)(y3 - y1); + float beta = 0.0f; + int ax = x1 + (int)lroundf((x3 - x1) * alpha); + int bx = 0; + + if (y < y2) { + beta = (y2 == y1) ? 0.0f : (float)(y - y1) / (float)(y2 - y1); + bx = x1 + (int)lroundf((x2 - x1) * beta); + } else { + beta = (y3 == y2) ? 0.0f : (float)(y - y2) / (float)(y3 - y2); + bx = x2 + (int)lroundf((x3 - x2) * beta); + } + + if (ax > bx) { + int tmp = ax; + ax = bx; + bx = tmp; + } + ret = display_hal_draw_hline_locked(ax, y, bx - ax + 1, color565); + } + + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_measure_text(const char *text, uint8_t font_size, + uint16_t *out_width, uint16_t *out_height) +{ + const esp_painter_basic_font_t *font = display_hal_get_font(font_size); + + ESP_RETURN_ON_FALSE(font != NULL, ESP_ERR_NOT_SUPPORTED, TAG, "font size %u unavailable", font_size); + display_hal_measure_text_raw(text, font, out_width, out_height); + return ESP_OK; +} + +esp_err_t display_hal_draw_text(int x, int y, const char *text, uint8_t font_size, + uint16_t text_color565, bool has_bg, uint16_t bg_color565) +{ + const esp_painter_basic_font_t *font = NULL; + uint16_t text_w = 0; + uint16_t text_h = 0; + uint16_t fill_color = 0; + uint16_t *buffer = NULL; + size_t buffer_bytes = 0; + size_t aligned_buffer_bytes = 0; + esp_err_t ret = display_hal_lock(); + + if (ret != ESP_OK) { + return ret; + } + ESP_GOTO_ON_FALSE(text != NULL, ESP_ERR_INVALID_ARG, fail, TAG, "text is NULL"); + if (text[0] == '\0') { + ret = ESP_OK; + goto fail; + } + + ret = display_hal_ensure_display_locked(); + if (ret == ESP_OK) { + ret = display_hal_ensure_painter_locked(); + } + if (ret != ESP_OK) { + goto fail; + } + + font = display_hal_get_font(font_size); + ESP_GOTO_ON_FALSE(font != NULL, ESP_ERR_NOT_SUPPORTED, fail, TAG, "font size %u unavailable", font_size); + display_hal_measure_text_raw(text, font, &text_w, &text_h); + if (text_w == 0 || text_h == 0) { + ret = ESP_OK; + goto fail; + } + + buffer_bytes = (size_t)text_w * (size_t)text_h * sizeof(uint16_t); + aligned_buffer_bytes = (buffer_bytes + (DISPLAY_HAL_TEXT_CACHE_ALIGN - 1)) & + ~(size_t)(DISPLAY_HAL_TEXT_CACHE_ALIGN - 1); + buffer = heap_caps_aligned_alloc(DISPLAY_HAL_TEXT_CACHE_ALIGN, aligned_buffer_bytes, + MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (!buffer) { + buffer = heap_caps_aligned_alloc(DISPLAY_HAL_TEXT_CACHE_ALIGN, aligned_buffer_bytes, MALLOC_CAP_DEFAULT); + } + ESP_GOTO_ON_FALSE(buffer != NULL, ESP_ERR_NO_MEM, fail, TAG, "text buffer alloc failed"); + + fill_color = display_hal_rgb565_to_panel(has_bg ? bg_color565 : 0x0000); + for (size_t i = 0; i < aligned_buffer_bytes / sizeof(uint16_t); ++i) { + buffer[i] = fill_color; + } + + ret = esp_painter_draw_string_rgb565(s_state.painter, (uint8_t *)buffer, (uint32_t)aligned_buffer_bytes, + 0, 0, font, text_color565, text); + if (ret == ESP_OK) { + ret = display_hal_draw_bitmap_locked(x, y, (int)text_w, (int)text_h, buffer); + } + +fail: + heap_caps_free(buffer); + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_draw_text_aligned(int x, int y, int width, int height, + const char *text, uint8_t font_size, + uint16_t text_color565, bool has_bg, uint16_t bg_color565, + display_hal_text_align_t align, + display_hal_text_valign_t valign) +{ + uint16_t text_w = 0; + uint16_t text_h = 0; + ESP_RETURN_ON_ERROR(display_hal_measure_text(text, font_size, &text_w, &text_h), TAG, + "measure text failed"); + + int draw_x = x; + int draw_y = y; + + if (width > 0) { + if (align == DISPLAY_HAL_TEXT_ALIGN_CENTER) { + draw_x = x + (width - (int)text_w) / 2; + } else if (align == DISPLAY_HAL_TEXT_ALIGN_RIGHT) { + draw_x = x + width - (int)text_w; + } + } + if (height > 0) { + if (valign == DISPLAY_HAL_TEXT_VALIGN_MIDDLE) { + draw_y = y + (height - (int)text_h) / 2; + } else if (valign == DISPLAY_HAL_TEXT_VALIGN_BOTTOM) { + draw_y = y + height - (int)text_h; + } + } + + return display_hal_draw_text(draw_x, draw_y, text, font_size, text_color565, has_bg, bg_color565); +} + +esp_err_t display_hal_draw_bitmap(int x, int y, int w, int h, const uint16_t *pixels) +{ + esp_err_t ret = display_hal_lock(); + + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret == ESP_OK) { + ret = display_hal_draw_bitmap_locked(x, y, w, h, pixels); + } + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_draw_bitmap_crop(int x, int y, + int src_x, int src_y, + int w, int h, + int src_width, int src_height, + const uint16_t *pixels) +{ + esp_err_t ret = display_hal_lock(); + + if (ret != ESP_OK) { + return ret; + } + if (ret == ESP_OK) { + ret = display_hal_ensure_display_locked(); + } + if (ret == ESP_OK) { + ret = display_hal_draw_bitmap_crop_locked(x, y, src_x, src_y, w, h, src_width, src_height, pixels); + } + display_hal_unlock(); + return ret; +} + +esp_err_t display_hal_draw_jpeg(int x, int y, + const uint8_t *jpeg_data, size_t jpeg_len, + int *out_w, int *out_h) +{ +#if !CONFIG_ESP_ROM_HAS_JPEG_DECODE + (void)x; + (void)y; + (void)jpeg_data; + (void)jpeg_len; + (void)out_w; + (void)out_h; + return ESP_ERR_NOT_SUPPORTED; +#else + uint16_t *pixels = NULL; + int width = 0; + int height = 0; + esp_err_t ret = display_hal_decode_jpeg_rgb565_be(jpeg_data, jpeg_len, &pixels, &width, &height); + + if (ret != ESP_OK) { + return ret; + } + if (out_w) { + *out_w = width; + } + if (out_h) { + *out_h = height; + } + ret = display_hal_draw_bitmap(x, y, width, height, pixels); + free(pixels); + return ret; +#endif +} + +esp_err_t display_hal_draw_jpeg_crop(int x, int y, + int src_x, int src_y, + int w, int h, + const uint8_t *jpeg_data, size_t jpeg_len, + int *out_w, int *out_h) +{ +#if !CONFIG_ESP_ROM_HAS_JPEG_DECODE + (void)x; + (void)y; + (void)src_x; + (void)src_y; + (void)w; + (void)h; + (void)jpeg_data; + (void)jpeg_len; + (void)out_w; + (void)out_h; + return ESP_ERR_NOT_SUPPORTED; +#else + uint16_t *pixels = NULL; + int width = 0; + int height = 0; + esp_err_t ret = display_hal_decode_jpeg_rgb565_be(jpeg_data, jpeg_len, &pixels, &width, &height); + + if (ret != ESP_OK) { + return ret; + } + if (out_w) { + *out_w = width; + } + if (out_h) { + *out_h = height; + } + ret = display_hal_draw_bitmap_crop(x, y, src_x, src_y, w, h, width, height, pixels); + free(pixels); + return ret; +#endif +} + +esp_err_t display_hal_jpeg_get_size(const uint8_t *jpeg_data, size_t jpeg_len, + int *out_w, int *out_h) +{ +#if !CONFIG_ESP_ROM_HAS_JPEG_DECODE + (void)jpeg_data; + (void)jpeg_len; + (void)out_w; + (void)out_h; + return ESP_ERR_NOT_SUPPORTED; +#else + return display_hal_jpeg_get_size_internal(jpeg_data, jpeg_len, out_w, out_h); +#endif +} + +esp_err_t display_hal_draw_jpeg_scaled(int x, int y, + const uint8_t *jpeg_data, size_t jpeg_len, + int scale_w, int scale_h, + int *out_w, int *out_h) +{ +#if !CONFIG_ESP_ROM_HAS_JPEG_DECODE + (void)x; + (void)y; + (void)jpeg_data; + (void)jpeg_len; + (void)scale_w; + (void)scale_h; + (void)out_w; + (void)out_h; + return ESP_ERR_NOT_SUPPORTED; +#else + uint16_t *pixels = NULL; + uint16_t *scaled = NULL; + int width = 0; + int height = 0; + esp_err_t ret = ESP_OK; + + if (!jpeg_data || jpeg_len == 0 || scale_w <= 0 || scale_h <= 0) { + return ESP_ERR_INVALID_ARG; + } + + ret = display_hal_decode_jpeg_rgb565_be(jpeg_data, jpeg_len, &pixels, &width, &height); + if (ret != ESP_OK) { + return ret; + } + ret = display_hal_scale_rgb565_be(pixels, width, height, scale_w, scale_h, &scaled); + if (ret == ESP_OK) { + ret = display_hal_draw_bitmap(x, y, scale_w, scale_h, scaled); + } + if (out_w) { + *out_w = scale_w; + } + if (out_h) { + *out_h = scale_h; + } + free(pixels); + free(scaled); + return ret; +#endif +} diff --git a/components/lua_modules/lua_module_display/src/lua_module_display.c b/components/lua_modules/lua_module_display/src/lua_module_display.c new file mode 100644 index 0000000..58173d1 --- /dev/null +++ b/components/lua_modules/lua_module_display/src/lua_module_display.c @@ -0,0 +1,1288 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + * + * Lua "display" module. + * + * Ported from esp-claw lua_module_halo_display.c. + * HAL calls are routed through display_hal.h which the board layer must + * implement. PNG decode is done here using libpng; JPEG decode is delegated + * to the HAL. + */ +#include "lua_module_display.h" + +#include "cap_lua.h" +#include "display_hal.h" +#include "esp_err.h" +#include "lauxlib.h" +#include "png.h" + +#include +#include +#include +#include + +/* ------------------------------------------------------------------------- + * Argument helpers (mirrors the reference implementation) + * ---------------------------------------------------------------------- */ + +static int lua_display_check_integer_arg(lua_State *L, int index, const char *name) +{ + if (!lua_isinteger(L, index)) { + return luaL_error(L, "display %s must be an integer", name); + } + return (int)lua_tointeger(L, index); +} + +static float lua_display_check_number_arg(lua_State *L, int index, const char *name) +{ + if (!lua_isnumber(L, index)) { + luaL_error(L, "display %s must be a number", name); + return 0.0f; + } + return (float)lua_tonumber(L, index); +} + +static bool lua_display_is_ascii_text(const char *text) +{ + if (!text) { + return false; + } + while (*text) { + unsigned char ch = (unsigned char)*text++; + if ((ch < 32 || ch > 126) && ch != '\n' && ch != '\r' && ch != '\t') { + return false; + } + } + return true; +} + +/* Pack three consecutive integer arguments into an RGB565 colour. */ +static uint16_t lua_display_color(lua_State *L, int start_index) +{ + int red = lua_display_check_integer_arg(L, start_index, "color component"); + int green = lua_display_check_integer_arg(L, start_index + 1, "color component"); + int blue = lua_display_check_integer_arg(L, start_index + 2, "color component"); + return (uint16_t)(((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ((blue & 0xF8) >> 3)); +} + +static uint16_t lua_display_rgb888_to_rgb565(uint8_t red, uint8_t green, uint8_t blue) +{ + return (uint16_t)(((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ((blue & 0xF8) >> 3)); +} + +static void *lua_display_check_lightuserdata_arg(lua_State *L, int index, const char *name) +{ + void *ptr = lua_touserdata(L, index); + + luaL_argcheck(L, ptr != NULL, index, name); + return ptr; +} + +/* ------------------------------------------------------------------------- + * Screen lifecycle + * ---------------------------------------------------------------------- */ + +static int lua_display_create_screen(lua_State *L) +{ + esp_lcd_panel_handle_t panel_handle = + (esp_lcd_panel_handle_t)lua_display_check_lightuserdata_arg( + L, 1, "display panel_handle lightuserdata expected"); + esp_lcd_panel_io_handle_t io_handle = + (esp_lcd_panel_io_handle_t)lua_display_check_lightuserdata_arg( + L, 2, "display io_handle lightuserdata expected"); + int lcd_width = lua_display_check_integer_arg(L, 3, "lcd_width"); + int lcd_height = lua_display_check_integer_arg(L, 4, "lcd_height"); + + esp_err_t err = display_hal_create(panel_handle, io_handle, lcd_width, lcd_height); + if (err != ESP_OK) { + return luaL_error(L, "display create_screen failed: %s", esp_err_to_name(err)); + } + + lua_pushboolean(L, 1); + return 1; +} + +static int lua_display_destroy_screen(lua_State *L) +{ + (void)L; + esp_err_t err = display_hal_destroy(); + if (err != ESP_OK) { + return luaL_error(L, "display destroy_screen failed: %s", esp_err_to_name(err)); + } + + lua_pushboolean(L, 1); + return 1; +} + +/* ------------------------------------------------------------------------- + * Text option helpers + * ---------------------------------------------------------------------- */ + +static display_hal_text_align_t lua_display_parse_align(lua_State *L, int index, + display_hal_text_align_t default_align) +{ + const char *value = lua_tostring(L, index); + if (!value || strcmp(value, "left") == 0) { + return DISPLAY_HAL_TEXT_ALIGN_LEFT; + } + if (strcmp(value, "center") == 0 || strcmp(value, "centre") == 0) { + return DISPLAY_HAL_TEXT_ALIGN_CENTER; + } + if (strcmp(value, "right") == 0) { + return DISPLAY_HAL_TEXT_ALIGN_RIGHT; + } + luaL_error(L, "display align must be left, center, or right"); + return default_align; +} + +static display_hal_text_valign_t lua_display_parse_valign(lua_State *L, int index, + display_hal_text_valign_t default_valign) +{ + const char *value = lua_tostring(L, index); + if (!value || strcmp(value, "top") == 0) { + return DISPLAY_HAL_TEXT_VALIGN_TOP; + } + if (strcmp(value, "middle") == 0 || strcmp(value, "center") == 0) { + return DISPLAY_HAL_TEXT_VALIGN_MIDDLE; + } + if (strcmp(value, "bottom") == 0) { + return DISPLAY_HAL_TEXT_VALIGN_BOTTOM; + } + luaL_error(L, "display valign must be top, middle, or bottom"); + return default_valign; +} + +/* Parse an optional table at `index` for text-rendering options. + * NULL output pointers are silently skipped. */ +static void lua_display_parse_text_options(lua_State *L, int index, + uint8_t *text_r, uint8_t *text_g, uint8_t *text_b, + uint8_t *font_size, + uint8_t *bg_r, uint8_t *bg_g, uint8_t *bg_b, + bool *has_bg, + display_hal_text_align_t *align, + display_hal_text_valign_t *valign) +{ + if (lua_isnoneornil(L, index)) { + return; + } + luaL_checktype(L, index, LUA_TTABLE); + + lua_getfield(L, index, "r"); + if (!lua_isnil(L, -1) && text_r) { + *text_r = (uint8_t)lua_display_check_integer_arg(L, -1, "text color component"); + } + lua_pop(L, 1); + + lua_getfield(L, index, "g"); + if (!lua_isnil(L, -1) && text_g) { + *text_g = (uint8_t)lua_display_check_integer_arg(L, -1, "text color component"); + } + lua_pop(L, 1); + + lua_getfield(L, index, "b"); + if (!lua_isnil(L, -1) && text_b) { + *text_b = (uint8_t)lua_display_check_integer_arg(L, -1, "text color component"); + } + lua_pop(L, 1); + + lua_getfield(L, index, "font_size"); + if (!lua_isnil(L, -1) && font_size) { + *font_size = (uint8_t)lua_display_check_integer_arg(L, -1, "font_size"); + } + lua_pop(L, 1); + + lua_getfield(L, index, "bg_r"); + if (!lua_isnil(L, -1) && bg_r) { + *bg_r = (uint8_t)lua_display_check_integer_arg(L, -1, "background color component"); + if (has_bg) { *has_bg = true; } + } + lua_pop(L, 1); + + lua_getfield(L, index, "bg_g"); + if (!lua_isnil(L, -1) && bg_g) { + *bg_g = (uint8_t)lua_display_check_integer_arg(L, -1, "background color component"); + if (has_bg) { *has_bg = true; } + } + lua_pop(L, 1); + + lua_getfield(L, index, "bg_b"); + if (!lua_isnil(L, -1) && bg_b) { + *bg_b = (uint8_t)lua_display_check_integer_arg(L, -1, "background color component"); + if (has_bg) { *has_bg = true; } + } + lua_pop(L, 1); + + lua_getfield(L, index, "align"); + if (!lua_isnil(L, -1) && align) { + *align = lua_display_parse_align(L, -1, *align); + } + lua_pop(L, 1); + + lua_getfield(L, index, "valign"); + if (!lua_isnil(L, -1) && valign) { + *valign = lua_display_parse_valign(L, -1, *valign); + } + lua_pop(L, 1); +} + +/* ------------------------------------------------------------------------- + * Text drawing + * ---------------------------------------------------------------------- */ + +static int lua_display_draw_text(lua_State *L) +{ + int x = lua_display_check_integer_arg(L, 1, "x"); + int y = lua_display_check_integer_arg(L, 2, "y"); + const char *text = luaL_checkstring(L, 3); + uint8_t text_r = 255, text_g = 255, text_b = 255; + uint8_t bg_r = 0, bg_g = 0, bg_b = 0; + uint8_t font_size = 24; + bool has_bg = false; + + if (!lua_display_is_ascii_text(text)) { + return luaL_error(L, + "display draw_text only supports ASCII text; " + "use draw_png_file/draw_jpeg_file for Chinese or other Unicode text"); + } + + lua_display_parse_text_options(L, 4, + &text_r, &text_g, &text_b, &font_size, + &bg_r, &bg_g, &bg_b, &has_bg, NULL, NULL); + + esp_err_t err = display_hal_draw_text(x, y, text, font_size, + lua_display_rgb888_to_rgb565(text_r, text_g, text_b), + has_bg, + lua_display_rgb888_to_rgb565(bg_r, bg_g, bg_b)); + if (err != ESP_OK) { + return luaL_error(L, "display draw_text failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_measure_text(lua_State *L) +{ + const char *text = luaL_checkstring(L, 1); + uint8_t font_size = 24; + uint16_t width = 0, height = 0; + + lua_display_parse_text_options(L, 2, + NULL, NULL, NULL, &font_size, + NULL, NULL, NULL, NULL, NULL, NULL); + + esp_err_t err = display_hal_measure_text(text, font_size, &width, &height); + if (err != ESP_OK) { + return luaL_error(L, "display measure_text failed: %s", esp_err_to_name(err)); + } + lua_pushinteger(L, width); + lua_pushinteger(L, height); + return 2; +} + +static int lua_display_draw_text_aligned(lua_State *L) +{ + int x = lua_display_check_integer_arg(L, 1, "x"); + int y = lua_display_check_integer_arg(L, 2, "y"); + int width = lua_display_check_integer_arg(L, 3, "width"); + int height = lua_display_check_integer_arg(L, 4, "height"); + const char *text = luaL_checkstring(L, 5); + uint8_t text_r = 255, text_g = 255, text_b = 255; + uint8_t bg_r = 0, bg_g = 0, bg_b = 0; + uint8_t font_size = 24; + bool has_bg = false; + display_hal_text_align_t align = DISPLAY_HAL_TEXT_ALIGN_LEFT; + display_hal_text_valign_t valign = DISPLAY_HAL_TEXT_VALIGN_TOP; + + if (!lua_display_is_ascii_text(text)) { + return luaL_error(L, + "display draw_text_aligned only supports ASCII text; " + "use draw_png_file/draw_jpeg_file for Chinese or other Unicode text"); + } + + lua_display_parse_text_options(L, 6, + &text_r, &text_g, &text_b, &font_size, + &bg_r, &bg_g, &bg_b, &has_bg, &align, &valign); + + esp_err_t err = display_hal_draw_text_aligned( + x, y, width, height, text, font_size, + lua_display_rgb888_to_rgb565(text_r, text_g, text_b), + has_bg, + lua_display_rgb888_to_rgb565(bg_r, bg_g, bg_b), + align, valign); + if (err != ESP_OK) { + return luaL_error(L, "display draw_text_aligned failed: %s", esp_err_to_name(err)); + } + return 0; +} + +/* ------------------------------------------------------------------------- + * Basic drawing + * ---------------------------------------------------------------------- */ + +static int lua_display_clear(lua_State *L) +{ + uint16_t color = lua_display_color(L, 1); + esp_err_t err = display_hal_clear(color); + if (err != ESP_OK) { + return luaL_error(L, "display clear failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_set_clip_rect(lua_State *L) +{ + int x = lua_display_check_integer_arg(L, 1, "x"); + int y = lua_display_check_integer_arg(L, 2, "y"); + int width = lua_display_check_integer_arg(L, 3, "width"); + int height = lua_display_check_integer_arg(L, 4, "height"); + esp_err_t err = display_hal_set_clip_rect(x, y, width, height); + if (err != ESP_OK) { + return luaL_error(L, "display set_clip_rect failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_clear_clip_rect(lua_State *L) +{ + (void)L; + esp_err_t err = display_hal_clear_clip_rect(); + if (err != ESP_OK) { + return luaL_error(L, "display clear_clip_rect failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_fill_rect(lua_State *L) +{ + int x = lua_display_check_integer_arg(L, 1, "x"); + int y = lua_display_check_integer_arg(L, 2, "y"); + int width = lua_display_check_integer_arg(L, 3, "width"); + int height = lua_display_check_integer_arg(L, 4, "height"); + uint16_t color = lua_display_color(L, 5); + esp_err_t err = display_hal_fill_rect(x, y, width, height, color); + if (err != ESP_OK) { + return luaL_error(L, "display fill_rect failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_draw_pixel(lua_State *L) +{ + int x = lua_display_check_integer_arg(L, 1, "x"); + int y = lua_display_check_integer_arg(L, 2, "y"); + uint16_t color = lua_display_color(L, 3); + esp_err_t err = display_hal_draw_pixel(x, y, color); + if (err != ESP_OK) { + return luaL_error(L, "display draw_pixel failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_draw_line(lua_State *L) +{ + int x0 = lua_display_check_integer_arg(L, 1, "x0"); + int y0 = lua_display_check_integer_arg(L, 2, "y0"); + int x1 = lua_display_check_integer_arg(L, 3, "x1"); + int y1 = lua_display_check_integer_arg(L, 4, "y1"); + uint16_t color = lua_display_color(L, 5); + esp_err_t err = display_hal_draw_line(x0, y0, x1, y1, color); + if (err != ESP_OK) { + return luaL_error(L, "display draw_line failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_draw_rect(lua_State *L) +{ + int x = lua_display_check_integer_arg(L, 1, "x"); + int y = lua_display_check_integer_arg(L, 2, "y"); + int width = lua_display_check_integer_arg(L, 3, "width"); + int height = lua_display_check_integer_arg(L, 4, "height"); + uint16_t color = lua_display_color(L, 5); + esp_err_t err = display_hal_draw_rect(x, y, width, height, color); + if (err != ESP_OK) { + return luaL_error(L, "display draw_rect failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_backlight(lua_State *L) +{ + int on = lua_toboolean(L, 1); + esp_err_t err = display_hal_set_backlight(on != 0); + if (err != ESP_OK) { + return luaL_error(L, "display backlight failed: %s", esp_err_to_name(err)); + } + return 0; +} + +/* ------------------------------------------------------------------------- + * Frame management + * ---------------------------------------------------------------------- */ + +static void lua_display_parse_frame_options(lua_State *L, int index, + bool *clear, uint8_t *red, + uint8_t *green, uint8_t *blue) +{ + if (clear) { *clear = true; } + if (red) { *red = 0; } + if (green) { *green = 0; } + if (blue) { *blue = 0; } + + if (lua_isnoneornil(L, index)) { + return; + } + luaL_checktype(L, index, LUA_TTABLE); + + lua_getfield(L, index, "clear"); + if (!lua_isnil(L, -1) && clear) { + *clear = lua_toboolean(L, -1); + } + lua_pop(L, 1); + + lua_getfield(L, index, "r"); + if (!lua_isnil(L, -1) && red) { + *red = (uint8_t)lua_display_check_integer_arg(L, -1, "frame color component"); + } + lua_pop(L, 1); + + lua_getfield(L, index, "g"); + if (!lua_isnil(L, -1) && green) { + *green = (uint8_t)lua_display_check_integer_arg(L, -1, "frame color component"); + } + lua_pop(L, 1); + + lua_getfield(L, index, "b"); + if (!lua_isnil(L, -1) && blue) { + *blue = (uint8_t)lua_display_check_integer_arg(L, -1, "frame color component"); + } + lua_pop(L, 1); +} + +static int lua_display_begin_frame(lua_State *L) +{ + bool clear = true; + uint8_t red = 0, green = 0, blue = 0; + lua_display_parse_frame_options(L, 1, &clear, &red, &green, &blue); + esp_err_t err = display_hal_begin_frame( + clear, lua_display_rgb888_to_rgb565(red, green, blue)); + if (err != ESP_OK) { + return luaL_error(L, "display begin_frame failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_present(lua_State *L) +{ + (void)L; + esp_err_t err = display_hal_present(); + if (err != ESP_OK) { + return luaL_error(L, "display present failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_present_rect(lua_State *L) +{ + int x = lua_display_check_integer_arg(L, 1, "x"); + int y = lua_display_check_integer_arg(L, 2, "y"); + int width = lua_display_check_integer_arg(L, 3, "width"); + int height = lua_display_check_integer_arg(L, 4, "height"); + esp_err_t err = display_hal_present_rect(x, y, width, height); + if (err != ESP_OK) { + return luaL_error(L, "display present_rect failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_end_frame(lua_State *L) +{ + (void)L; + esp_err_t err = display_hal_end_frame(); + if (err != ESP_OK) { + return luaL_error(L, "display end_frame failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_frame_active(lua_State *L) +{ + lua_pushboolean(L, display_hal_is_frame_active()); + return 1; +} + +static int lua_display_animation_info(lua_State *L) +{ + display_hal_animation_info_t info = {0}; + esp_err_t err = display_hal_get_animation_info(&info); + if (err != ESP_OK) { + return luaL_error(L, "display animation_info failed: %s", esp_err_to_name(err)); + } + lua_newtable(L); + lua_pushinteger(L, info.framebuffer_count); + lua_setfield(L, -2, "framebuffer_count"); + lua_pushboolean(L, info.double_buffered); + lua_setfield(L, -2, "double_buffered"); + lua_pushboolean(L, info.frame_active); + lua_setfield(L, -2, "frame_active"); + lua_pushboolean(L, info.flush_in_flight); + lua_setfield(L, -2, "flush_in_flight"); + return 1; +} + +static int lua_display_width(lua_State *L) +{ + lua_pushinteger(L, display_hal_width()); + return 1; +} + +static int lua_display_height(lua_State *L) +{ + lua_pushinteger(L, display_hal_height()); + return 1; +} + +/* ------------------------------------------------------------------------- + * Bitmap + * ---------------------------------------------------------------------- */ + +static int lua_display_draw_bitmap_impl(lua_State *L, bool input_is_little_endian) +{ + int x = (int)luaL_checkinteger(L, 1); + int y = (int)luaL_checkinteger(L, 2); + int w = (int)luaL_checkinteger(L, 3); + int h = (int)luaL_checkinteger(L, 4); + size_t data_len = 0; + const uint8_t *data = (const uint8_t *)luaL_checklstring(L, 5, &data_len); + uint8_t *swapped = NULL; + const uint16_t *pixels = NULL; + + if (w <= 0 || h <= 0) { + return luaL_error(L, "draw_bitmap: invalid size (%d x %d)", w, h); + } + + size_t expected = (size_t)w * (size_t)h * 2; + if (data_len < expected) { + return luaL_error(L, "draw_bitmap: data too short (%d bytes, need %d)", + (int)data_len, (int)expected); + } + + if (input_is_little_endian) { + swapped = malloc(expected); + if (!swapped) { + return luaL_error(L, "draw_bitmap: out of memory (%d bytes)", (int)expected); + } + /* Swap each pixel from little-endian to MSB-first order */ + for (size_t i = 0; i < expected; i += 2) { + swapped[i] = data[i + 1]; + swapped[i + 1] = data[i]; + } + pixels = (const uint16_t *)swapped; + } else { + pixels = (const uint16_t *)data; + } + + esp_err_t err = display_hal_draw_bitmap(x, y, w, h, pixels); + free(swapped); + if (err != ESP_OK) { + return luaL_error(L, "display draw_bitmap failed: %s", esp_err_to_name(err)); + } + return 0; +} + +/* + * draw_bitmap(x, y, w, h, data) + * data: raw RGB565 bytes, MSB-first (red = 0xF8 0x00). + */ +static int lua_display_draw_bitmap(lua_State *L) +{ + return lua_display_draw_bitmap_impl(L, false); +} + +/* + * draw_bitmap_le(x, y, w, h, data) + * data: RGB565 little-endian; bytes are swapped to MSB-first before sending. + */ +static int lua_display_draw_bitmap_le(lua_State *L) +{ + return lua_display_draw_bitmap_impl(L, true); +} + +static int lua_display_draw_bitmap_crop(lua_State *L) +{ + int x = lua_display_check_integer_arg(L, 1, "x"); + int y = lua_display_check_integer_arg(L, 2, "y"); + int src_x = lua_display_check_integer_arg(L, 3, "src_x"); + int src_y = lua_display_check_integer_arg(L, 4, "src_y"); + int w = lua_display_check_integer_arg(L, 5, "width"); + int h = lua_display_check_integer_arg(L, 6, "height"); + int src_width = lua_display_check_integer_arg(L, 7, "src_width"); + int src_height = lua_display_check_integer_arg(L, 8, "src_height"); + size_t data_len = 0; + const uint8_t *data = (const uint8_t *)luaL_checklstring(L, 9, &data_len); + + if (src_width <= 0 || src_height <= 0) { + return luaL_error(L, "draw_bitmap_crop: invalid source size (%d x %d)", + src_width, src_height); + } + + size_t expected = (size_t)src_width * (size_t)src_height * 2; + if (data_len < expected) { + return luaL_error(L, "draw_bitmap_crop: data too short (%d bytes, need %d)", + (int)data_len, (int)expected); + } + + esp_err_t err = display_hal_draw_bitmap_crop(x, y, src_x, src_y, w, h, + src_width, src_height, + (const uint16_t *)data); + if (err != ESP_OK) { + return luaL_error(L, "display draw_bitmap_crop failed: %s", esp_err_to_name(err)); + } + return 0; +} + +/* ------------------------------------------------------------------------- + * File helpers + * ---------------------------------------------------------------------- */ + +static bool lua_display_path_is_valid(const char *path) +{ + size_t len; + + if (!path || path[0] != '/') { + return false; + } + /* Reject path traversal */ + if (strstr(path, "..")) { + return false; + } + len = strlen(path); + if (len <= 4) { + return false; + } + /* Must end with a supported image extension */ + return strcmp(path + len - 4, ".jpg") == 0 || + (len > 5 && strcmp(path + len - 5, ".jpeg") == 0) || + strcmp(path + len - 4, ".png") == 0; +} + +static esp_err_t lua_display_read_file(const char *path, uint8_t **data_out, size_t *size_out) +{ + FILE *f = NULL; + long size = 0; + uint8_t *data = NULL; + + if (!data_out || !size_out || !lua_display_path_is_valid(path)) { + return ESP_ERR_INVALID_ARG; + } + *data_out = NULL; + *size_out = 0; + + f = fopen(path, "rb"); + if (!f) { + return ESP_ERR_NOT_FOUND; + } + if (fseek(f, 0, SEEK_END) != 0) { + fclose(f); + return ESP_FAIL; + } + size = ftell(f); + if (size <= 0) { + fclose(f); + return ESP_ERR_INVALID_SIZE; + } + if (fseek(f, 0, SEEK_SET) != 0) { + fclose(f); + return ESP_FAIL; + } + + data = malloc((size_t)size); + if (!data) { + fclose(f); + return ESP_ERR_NO_MEM; + } + if (fread(data, 1, (size_t)size, f) != (size_t)size) { + fclose(f); + free(data); + return ESP_FAIL; + } + fclose(f); + + *data_out = data; + *size_out = (size_t)size; + return ESP_OK; +} + +/* ------------------------------------------------------------------------- + * PNG decode (RGBA → RGB565, alpha pre-multiplied against black) + * ---------------------------------------------------------------------- */ + +static esp_err_t lua_display_decode_png(const uint8_t *png_data, size_t png_len, + uint8_t **pixels_out, + uint32_t *width_out, uint32_t *height_out) +{ + png_image image; + png_bytep rgba = NULL; + uint8_t *rgb565 = NULL; + size_t stride = 0; + + if (!png_data || png_len == 0 || !pixels_out || !width_out || !height_out) { + return ESP_ERR_INVALID_ARG; + } + + memset(&image, 0, sizeof(image)); + image.version = PNG_IMAGE_VERSION; + if (!png_image_begin_read_from_memory(&image, png_data, png_len)) { + return ESP_FAIL; + } + + image.format = PNG_FORMAT_RGBA; + stride = PNG_IMAGE_ROW_STRIDE(image); + rgba = malloc(PNG_IMAGE_SIZE(image)); + if (!rgba) { + png_image_free(&image); + return ESP_ERR_NO_MEM; + } + + if (!png_image_finish_read(&image, NULL, rgba, (png_int_32)stride, NULL)) { + free(rgba); + png_image_free(&image); + return ESP_FAIL; + } + + rgb565 = malloc((size_t)image.width * (size_t)image.height * 2); + if (!rgb565) { + free(rgba); + png_image_free(&image); + return ESP_ERR_NO_MEM; + } + + /* Convert RGBA to RGB565, alpha pre-multiplied against black */ + for (uint32_t row = 0; row < image.height; row++) { + const uint8_t *src_row = rgba + row * stride; + uint8_t *dst_row = rgb565 + (size_t)row * image.width * 2; + for (uint32_t col = 0; col < image.width; col++) { + const uint8_t *src = src_row + col * 4; + uint8_t alpha = src[3]; + uint8_t r = (uint8_t)((src[0] * alpha + 127) / 255); + uint8_t g = (uint8_t)((src[1] * alpha + 127) / 255); + uint8_t b = (uint8_t)((src[2] * alpha + 127) / 255); + uint16_t c = lua_display_rgb888_to_rgb565(r, g, b); + dst_row[col * 2] = (uint8_t)(c >> 8); + dst_row[col * 2 + 1] = (uint8_t)(c & 0xFF); + } + } + + free(rgba); + png_image_free(&image); + + *pixels_out = rgb565; + *width_out = image.width; + *height_out = image.height; + return ESP_OK; +} + +/* ------------------------------------------------------------------------- + * JPEG drawing + * ---------------------------------------------------------------------- */ + +/* + * draw_jpeg(x, y, jpeg_data) + * jpeg_data: Lua string containing raw JPEG bytes. + * Returns: width, height + */ +static int lua_display_draw_jpeg(lua_State *L) +{ + int x = (int)luaL_checkinteger(L, 1); + int y = (int)luaL_checkinteger(L, 2); + size_t jpeg_len = 0; + const char *jpeg_data = luaL_checklstring(L, 3, &jpeg_len); + int img_w = 0, img_h = 0; + + esp_err_t err = display_hal_draw_jpeg(x, y, + (const uint8_t *)jpeg_data, jpeg_len, + &img_w, &img_h); + if (err != ESP_OK) { + return luaL_error(L, "display draw_jpeg failed: %s", esp_err_to_name(err)); + } + lua_pushinteger(L, img_w); + lua_pushinteger(L, img_h); + return 2; +} + +static int lua_display_draw_jpeg_file(lua_State *L) +{ + int x = (int)luaL_checkinteger(L, 1); + int y = (int)luaL_checkinteger(L, 2); + const char *path = luaL_checkstring(L, 3); + uint8_t *jpeg_data = NULL; + size_t jpeg_len = 0; + int img_w = 0, img_h = 0; + + esp_err_t err = lua_display_read_file(path, &jpeg_data, &jpeg_len); + if (err != ESP_OK) { + return luaL_error(L, "display draw_jpeg_file failed: %s", esp_err_to_name(err)); + } + + err = display_hal_draw_jpeg(x, y, jpeg_data, jpeg_len, &img_w, &img_h); + free(jpeg_data); + if (err != ESP_OK) { + return luaL_error(L, "display draw_jpeg_file failed: %s", esp_err_to_name(err)); + } + lua_pushinteger(L, img_w); + lua_pushinteger(L, img_h); + return 2; +} + +static int lua_display_draw_png_file(lua_State *L) +{ + int x = (int)luaL_checkinteger(L, 1); + int y = (int)luaL_checkinteger(L, 2); + const char *path = luaL_checkstring(L, 3); + uint8_t *png_data = NULL; + size_t png_len = 0; + uint8_t *rgb565 = NULL; + uint32_t img_w = 0, img_h = 0; + + esp_err_t err = lua_display_read_file(path, &png_data, &png_len); + if (err != ESP_OK) { + return luaL_error(L, "display draw_png_file failed: %s", esp_err_to_name(err)); + } + + err = lua_display_decode_png(png_data, png_len, &rgb565, &img_w, &img_h); + free(png_data); + if (err != ESP_OK) { + free(rgb565); + return luaL_error(L, "display draw_png_file failed: %s", esp_err_to_name(err)); + } + + err = display_hal_draw_bitmap(x, y, (int)img_w, (int)img_h, (const uint16_t *)rgb565); + free(rgb565); + if (err != ESP_OK) { + return luaL_error(L, "display draw_png_file failed: %s", esp_err_to_name(err)); + } + lua_pushinteger(L, (lua_Integer)img_w); + lua_pushinteger(L, (lua_Integer)img_h); + return 2; +} + +static int lua_display_draw_jpeg_crop(lua_State *L) +{ + int x = (int)luaL_checkinteger(L, 1); + int y = (int)luaL_checkinteger(L, 2); + int src_x = (int)luaL_checkinteger(L, 3); + int src_y = (int)luaL_checkinteger(L, 4); + int w = (int)luaL_checkinteger(L, 5); + int h = (int)luaL_checkinteger(L, 6); + size_t jpeg_len = 0; + const char *jpeg_data = luaL_checklstring(L, 7, &jpeg_len); + int img_w = 0, img_h = 0; + + esp_err_t err = display_hal_draw_jpeg_crop(x, y, src_x, src_y, w, h, + (const uint8_t *)jpeg_data, jpeg_len, + &img_w, &img_h); + if (err != ESP_OK) { + return luaL_error(L, "display draw_jpeg_crop failed: %s", esp_err_to_name(err)); + } + lua_pushinteger(L, img_w); + lua_pushinteger(L, img_h); + return 2; +} + +static int lua_display_draw_jpeg_file_crop(lua_State *L) +{ + int x = (int)luaL_checkinteger(L, 1); + int y = (int)luaL_checkinteger(L, 2); + int src_x = (int)luaL_checkinteger(L, 3); + int src_y = (int)luaL_checkinteger(L, 4); + int w = (int)luaL_checkinteger(L, 5); + int h = (int)luaL_checkinteger(L, 6); + const char *path = luaL_checkstring(L, 7); + uint8_t *jpeg_data = NULL; + size_t jpeg_len = 0; + int img_w = 0, img_h = 0; + + esp_err_t err = lua_display_read_file(path, &jpeg_data, &jpeg_len); + if (err != ESP_OK) { + return luaL_error(L, "display draw_jpeg_file_crop failed: %s", esp_err_to_name(err)); + } + + err = display_hal_draw_jpeg_crop(x, y, src_x, src_y, w, h, + jpeg_data, jpeg_len, &img_w, &img_h); + free(jpeg_data); + if (err != ESP_OK) { + return luaL_error(L, "display draw_jpeg_file_crop failed: %s", esp_err_to_name(err)); + } + lua_pushinteger(L, img_w); + lua_pushinteger(L, img_h); + return 2; +} + +static int lua_align_down_8(int v) { return v & ~7; } + +/* + * draw_jpeg_file_scaled(x, y, scale_w, scale_h, path) + * scale_w, scale_h must be positive multiples of 8; max downscale 1/8. + * Returns: output_w, output_h + */ +static int lua_display_draw_jpeg_file_scaled(lua_State *L) +{ + int x = (int)luaL_checkinteger(L, 1); + int y = (int)luaL_checkinteger(L, 2); + int scale_w = (int)luaL_checkinteger(L, 3); + int scale_h = (int)luaL_checkinteger(L, 4); + const char *path = luaL_checkstring(L, 5); + uint8_t *jpeg_data = NULL; + size_t jpeg_len = 0; + int out_w = 0, out_h = 0; + + if ((scale_w & 7) != 0 || (scale_h & 7) != 0 || scale_w <= 0 || scale_h <= 0) { + return luaL_error(L, + "draw_jpeg_file_scaled: scale_w and scale_h must be positive multiples of 8"); + } + + esp_err_t err = lua_display_read_file(path, &jpeg_data, &jpeg_len); + if (err != ESP_OK) { + return luaL_error(L, "display draw_jpeg_file_scaled failed: %s", esp_err_to_name(err)); + } + + err = display_hal_draw_jpeg_scaled(x, y, jpeg_data, jpeg_len, + scale_w, scale_h, &out_w, &out_h); + free(jpeg_data); + if (err != ESP_OK) { + return luaL_error(L, "display draw_jpeg_file_scaled failed: %s", esp_err_to_name(err)); + } + lua_pushinteger(L, out_w); + lua_pushinteger(L, out_h); + return 2; +} + +/* + * draw_jpeg_file_fit(x, y, max_w, max_h, path) + * Scales JPEG to fit within max_w x max_h preserving aspect ratio. + * Output size is aligned to multiples of 8 (JPEG HW decode requirement). + * Returns: output_w, output_h + */ +static int lua_display_draw_jpeg_file_fit(lua_State *L) +{ + int x = (int)luaL_checkinteger(L, 1); + int y = (int)luaL_checkinteger(L, 2); + int max_w = (int)luaL_checkinteger(L, 3); + int max_h = (int)luaL_checkinteger(L, 4); + const char *path = luaL_checkstring(L, 5); + uint8_t *jpeg_data = NULL; + size_t jpeg_len = 0; + int orig_w = 0, orig_h = 0; + int out_w = 0, out_h = 0; + + if (max_w <= 0 || max_h <= 0) { + return luaL_error(L, "draw_jpeg_file_fit: max_w and max_h must be positive"); + } + + esp_err_t err = lua_display_read_file(path, &jpeg_data, &jpeg_len); + if (err != ESP_OK) { + return luaL_error(L, "display draw_jpeg_file_fit failed: %s", esp_err_to_name(err)); + } + + err = display_hal_jpeg_get_size(jpeg_data, jpeg_len, &orig_w, &orig_h); + if (err != ESP_OK) { + free(jpeg_data); + return luaL_error(L, "display draw_jpeg_file_fit: cannot read JPEG header"); + } + + if (orig_w <= max_w && orig_h <= max_h) { + /* Image already fits: draw at full resolution */ + err = display_hal_draw_jpeg(x, y, jpeg_data, jpeg_len, &out_w, &out_h); + free(jpeg_data); + if (err != ESP_OK) { + return luaL_error(L, "display draw_jpeg_file_fit failed: %s", esp_err_to_name(err)); + } + lua_pushinteger(L, out_w); + lua_pushinteger(L, out_h); + return 2; + } + + double ratio_w = (double)max_w / orig_w; + double ratio_h = (double)max_h / orig_h; + double ratio = (ratio_w < ratio_h) ? ratio_w : ratio_h; + if (ratio < 0.125) { ratio = 0.125; } /* max downscale 1/8 */ + + int scale_w = lua_align_down_8((int)(orig_w * ratio)); + int scale_h = lua_align_down_8((int)(orig_h * ratio)); + if (scale_w < 8) { scale_w = 8; } + if (scale_h < 8) { scale_h = 8; } + + err = display_hal_draw_jpeg_scaled(x, y, jpeg_data, jpeg_len, + scale_w, scale_h, &out_w, &out_h); + free(jpeg_data); + if (err != ESP_OK) { + return luaL_error(L, "display draw_jpeg_file_fit failed: %s", esp_err_to_name(err)); + } + lua_pushinteger(L, out_w); + lua_pushinteger(L, out_h); + return 2; +} + +/* ------------------------------------------------------------------------- + * Shape drawing + * ---------------------------------------------------------------------- */ + +static int lua_display_fill_circle(lua_State *L) +{ + int cx = lua_display_check_integer_arg(L, 1, "cx"); + int cy = lua_display_check_integer_arg(L, 2, "cy"); + int r = lua_display_check_integer_arg(L, 3, "radius"); + uint16_t color = lua_display_color(L, 4); + esp_err_t err = display_hal_fill_circle(cx, cy, r, color); + if (err != ESP_OK) { + return luaL_error(L, "display fill_circle failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_draw_circle(lua_State *L) +{ + int cx = lua_display_check_integer_arg(L, 1, "cx"); + int cy = lua_display_check_integer_arg(L, 2, "cy"); + int r = lua_display_check_integer_arg(L, 3, "radius"); + uint16_t color = lua_display_color(L, 4); + esp_err_t err = display_hal_draw_circle(cx, cy, r, color); + if (err != ESP_OK) { + return luaL_error(L, "display draw_circle failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_draw_arc(lua_State *L) +{ + int cx = lua_display_check_integer_arg(L, 1, "cx"); + int cy = lua_display_check_integer_arg(L, 2, "cy"); + int radius = lua_display_check_integer_arg(L, 3, "radius"); + float start_deg = lua_display_check_number_arg(L, 4, "start_deg"); + float end_deg = lua_display_check_number_arg(L, 5, "end_deg"); + uint16_t color = lua_display_color(L, 6); + esp_err_t err = display_hal_draw_arc(cx, cy, radius, start_deg, end_deg, color); + if (err != ESP_OK) { + return luaL_error(L, "display draw_arc failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_fill_arc(lua_State *L) +{ + int cx = lua_display_check_integer_arg(L, 1, "cx"); + int cy = lua_display_check_integer_arg(L, 2, "cy"); + int inner_radius = lua_display_check_integer_arg(L, 3, "inner_radius"); + int outer_radius = lua_display_check_integer_arg(L, 4, "outer_radius"); + float start_deg = lua_display_check_number_arg(L, 5, "start_deg"); + float end_deg = lua_display_check_number_arg(L, 6, "end_deg"); + uint16_t color = lua_display_color(L, 7); + esp_err_t err = display_hal_fill_arc(cx, cy, inner_radius, outer_radius, + start_deg, end_deg, color); + if (err != ESP_OK) { + return luaL_error(L, "display fill_arc failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_draw_ellipse(lua_State *L) +{ + int cx = lua_display_check_integer_arg(L, 1, "cx"); + int cy = lua_display_check_integer_arg(L, 2, "cy"); + int radius_x = lua_display_check_integer_arg(L, 3, "radius_x"); + int radius_y = lua_display_check_integer_arg(L, 4, "radius_y"); + uint16_t color = lua_display_color(L, 5); + esp_err_t err = display_hal_draw_ellipse(cx, cy, radius_x, radius_y, color); + if (err != ESP_OK) { + return luaL_error(L, "display draw_ellipse failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_fill_ellipse(lua_State *L) +{ + int cx = lua_display_check_integer_arg(L, 1, "cx"); + int cy = lua_display_check_integer_arg(L, 2, "cy"); + int radius_x = lua_display_check_integer_arg(L, 3, "radius_x"); + int radius_y = lua_display_check_integer_arg(L, 4, "radius_y"); + uint16_t color = lua_display_color(L, 5); + esp_err_t err = display_hal_fill_ellipse(cx, cy, radius_x, radius_y, color); + if (err != ESP_OK) { + return luaL_error(L, "display fill_ellipse failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_draw_round_rect(lua_State *L) +{ + int x = lua_display_check_integer_arg(L, 1, "x"); + int y = lua_display_check_integer_arg(L, 2, "y"); + int width = lua_display_check_integer_arg(L, 3, "width"); + int height = lua_display_check_integer_arg(L, 4, "height"); + int radius = lua_display_check_integer_arg(L, 5, "radius"); + uint16_t color = lua_display_color(L, 6); + esp_err_t err = display_hal_draw_round_rect(x, y, width, height, radius, color); + if (err != ESP_OK) { + return luaL_error(L, "display draw_round_rect failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_fill_round_rect(lua_State *L) +{ + int x = lua_display_check_integer_arg(L, 1, "x"); + int y = lua_display_check_integer_arg(L, 2, "y"); + int width = lua_display_check_integer_arg(L, 3, "width"); + int height = lua_display_check_integer_arg(L, 4, "height"); + int radius = lua_display_check_integer_arg(L, 5, "radius"); + uint16_t color = lua_display_color(L, 6); + esp_err_t err = display_hal_fill_round_rect(x, y, width, height, radius, color); + if (err != ESP_OK) { + return luaL_error(L, "display fill_round_rect failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_draw_triangle(lua_State *L) +{ + int x1 = lua_display_check_integer_arg(L, 1, "x1"); + int y1 = lua_display_check_integer_arg(L, 2, "y1"); + int x2 = lua_display_check_integer_arg(L, 3, "x2"); + int y2 = lua_display_check_integer_arg(L, 4, "y2"); + int x3 = lua_display_check_integer_arg(L, 5, "x3"); + int y3 = lua_display_check_integer_arg(L, 6, "y3"); + uint16_t color = lua_display_color(L, 7); + esp_err_t err = display_hal_draw_triangle(x1, y1, x2, y2, x3, y3, color); + if (err != ESP_OK) { + return luaL_error(L, "display draw_triangle failed: %s", esp_err_to_name(err)); + } + return 0; +} + +static int lua_display_fill_triangle(lua_State *L) +{ + int x1 = lua_display_check_integer_arg(L, 1, "x1"); + int y1 = lua_display_check_integer_arg(L, 2, "y1"); + int x2 = lua_display_check_integer_arg(L, 3, "x2"); + int y2 = lua_display_check_integer_arg(L, 4, "y2"); + int x3 = lua_display_check_integer_arg(L, 5, "x3"); + int y3 = lua_display_check_integer_arg(L, 6, "y3"); + uint16_t color = lua_display_color(L, 7); + esp_err_t err = display_hal_fill_triangle(x1, y1, x2, y2, x3, y3, color); + if (err != ESP_OK) { + return luaL_error(L, "display fill_triangle failed: %s", esp_err_to_name(err)); + } + return 0; +} + +/* ------------------------------------------------------------------------- + * Module registration + * ---------------------------------------------------------------------- */ + +int luaopen_display(lua_State *L) +{ + lua_newtable(L); + + lua_pushcfunction(L, lua_display_create_screen); + lua_setfield(L, -2, "create_screen"); + lua_pushcfunction(L, lua_display_destroy_screen); + lua_setfield(L, -2, "destroy_screen"); + + lua_pushcfunction(L, lua_display_width); + lua_setfield(L, -2, "width"); + lua_pushcfunction(L, lua_display_height); + lua_setfield(L, -2, "height"); + + lua_pushcfunction(L, lua_display_clear); + lua_setfield(L, -2, "clear"); + lua_pushcfunction(L, lua_display_set_clip_rect); + lua_setfield(L, -2, "set_clip_rect"); + lua_pushcfunction(L, lua_display_clear_clip_rect); + lua_setfield(L, -2, "clear_clip_rect"); + + lua_pushcfunction(L, lua_display_fill_rect); + lua_setfield(L, -2, "fill_rect"); + lua_pushcfunction(L, lua_display_draw_rect); + lua_setfield(L, -2, "draw_rect"); + lua_pushcfunction(L, lua_display_draw_pixel); + lua_setfield(L, -2, "draw_pixel"); + lua_pushcfunction(L, lua_display_draw_line); + lua_setfield(L, -2, "draw_line"); + + lua_pushcfunction(L, lua_display_backlight); + lua_setfield(L, -2, "backlight"); + + lua_pushcfunction(L, lua_display_begin_frame); + lua_setfield(L, -2, "begin_frame"); + lua_pushcfunction(L, lua_display_present); + lua_setfield(L, -2, "present"); + lua_pushcfunction(L, lua_display_present_rect); + lua_setfield(L, -2, "present_rect"); + lua_pushcfunction(L, lua_display_end_frame); + lua_setfield(L, -2, "end_frame"); + lua_pushcfunction(L, lua_display_frame_active); + lua_setfield(L, -2, "frame_active"); + lua_pushcfunction(L, lua_display_animation_info); + lua_setfield(L, -2, "animation_info"); + + lua_pushcfunction(L, lua_display_measure_text); + lua_setfield(L, -2, "measure_text"); + lua_pushcfunction(L, lua_display_draw_text); + lua_setfield(L, -2, "draw_text"); + lua_pushcfunction(L, lua_display_draw_text_aligned); + lua_setfield(L, -2, "draw_text_aligned"); + + lua_pushcfunction(L, lua_display_draw_bitmap); + lua_setfield(L, -2, "draw_bitmap"); + lua_pushcfunction(L, lua_display_draw_bitmap_le); + lua_setfield(L, -2, "draw_bitmap_le"); + lua_pushcfunction(L, lua_display_draw_bitmap_crop); + lua_setfield(L, -2, "draw_bitmap_crop"); + + lua_pushcfunction(L, lua_display_draw_jpeg); + lua_setfield(L, -2, "draw_jpeg"); + lua_pushcfunction(L, lua_display_draw_jpeg_file); + lua_setfield(L, -2, "draw_jpeg_file"); + lua_pushcfunction(L, lua_display_draw_png_file); + lua_setfield(L, -2, "draw_png_file"); + lua_pushcfunction(L, lua_display_draw_jpeg_crop); + lua_setfield(L, -2, "draw_jpeg_crop"); + lua_pushcfunction(L, lua_display_draw_jpeg_file_crop); + lua_setfield(L, -2, "draw_jpeg_file_crop"); + lua_pushcfunction(L, lua_display_draw_jpeg_file_scaled); + lua_setfield(L, -2, "draw_jpeg_file_scaled"); + lua_pushcfunction(L, lua_display_draw_jpeg_file_fit); + lua_setfield(L, -2, "draw_jpeg_file_fit"); + + lua_pushcfunction(L, lua_display_fill_circle); + lua_setfield(L, -2, "fill_circle"); + lua_pushcfunction(L, lua_display_draw_circle); + lua_setfield(L, -2, "draw_circle"); + lua_pushcfunction(L, lua_display_draw_arc); + lua_setfield(L, -2, "draw_arc"); + lua_pushcfunction(L, lua_display_fill_arc); + lua_setfield(L, -2, "fill_arc"); + + lua_pushcfunction(L, lua_display_draw_ellipse); + lua_setfield(L, -2, "draw_ellipse"); + lua_pushcfunction(L, lua_display_fill_ellipse); + lua_setfield(L, -2, "fill_ellipse"); + + lua_pushcfunction(L, lua_display_draw_round_rect); + lua_setfield(L, -2, "draw_round_rect"); + lua_pushcfunction(L, lua_display_fill_round_rect); + lua_setfield(L, -2, "fill_round_rect"); + + lua_pushcfunction(L, lua_display_draw_triangle); + lua_setfield(L, -2, "draw_triangle"); + lua_pushcfunction(L, lua_display_fill_triangle); + lua_setfield(L, -2, "fill_triangle"); + + return 1; +} + +esp_err_t lua_module_display_register(void) +{ + return cap_lua_register_module("display", luaopen_display); +} diff --git a/components/lua_modules/lua_module_esp_heap/CMakeLists.txt b/components/lua_modules/lua_module_esp_heap/CMakeLists.txt new file mode 100644 index 0000000..2a58b06 --- /dev/null +++ b/components/lua_modules/lua_module_esp_heap/CMakeLists.txt @@ -0,0 +1,10 @@ +idf_component_register( + SRC_DIRS + "." + INCLUDE_DIRS + "include" + REQUIRES + cap_lua + freertos + heap +) diff --git a/components/lua_modules/lua_module_esp_heap/include/lua_module_esp_heap.h b/components/lua_modules/lua_module_esp_heap/include/lua_module_esp_heap.h new file mode 100644 index 0000000..f0826be --- /dev/null +++ b/components/lua_modules/lua_module_esp_heap/include/lua_module_esp_heap.h @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +esp_err_t lua_module_esp_heap_register(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/lua_modules/lua_module_esp_heap/lua_module_esp_heap.c b/components/lua_modules/lua_module_esp_heap/lua_module_esp_heap.c new file mode 100644 index 0000000..af3b39a --- /dev/null +++ b/components/lua_modules/lua_module_esp_heap/lua_module_esp_heap.c @@ -0,0 +1,191 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "lua_module_esp_heap.h" + +#include + +#include "cap_lua.h" +#include "esp_heap_caps.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "lauxlib.h" + +#if (configUSE_TRACE_FACILITY == 1) +static const char *lua_module_esp_heap_task_state_name(eTaskState state) +{ + switch (state) { + case eRunning: + return "running"; + case eReady: + return "ready"; + case eBlocked: + return "blocked"; + case eSuspended: + return "suspended"; + case eDeleted: + return "deleted"; + case eInvalid: + default: + return "invalid"; + } +} +#endif + +static void lua_module_esp_heap_push_caps_constants(lua_State *L) +{ + lua_pushinteger(L, MALLOC_CAP_DEFAULT); + lua_setfield(L, -2, "DEFAULT"); + lua_pushinteger(L, MALLOC_CAP_INTERNAL); + lua_setfield(L, -2, "INTERNAL"); + lua_pushinteger(L, MALLOC_CAP_SPIRAM); + lua_setfield(L, -2, "SPIRAM"); + lua_pushinteger(L, MALLOC_CAP_DMA); + lua_setfield(L, -2, "DMA"); + lua_pushinteger(L, MALLOC_CAP_8BIT); + lua_setfield(L, -2, "BIT8"); + lua_pushinteger(L, MALLOC_CAP_32BIT); + lua_setfield(L, -2, "BIT32"); + lua_pushinteger(L, MALLOC_CAP_EXEC); + lua_setfield(L, -2, "EXEC"); + lua_pushinteger(L, MALLOC_CAP_IRAM_8BIT); + lua_setfield(L, -2, "IRAM_8BIT"); + lua_pushinteger(L, MALLOC_CAP_RTCRAM); + lua_setfield(L, -2, "RTCRAM"); + lua_pushinteger(L, MALLOC_CAP_RETENTION); + lua_setfield(L, -2, "RETENTION"); +} + +static int lua_module_esp_heap_caps(lua_State *L) +{ + lua_newtable(L); + lua_module_esp_heap_push_caps_constants(L); + return 1; +} + +static int lua_module_esp_heap_get_info(lua_State *L) +{ + lua_Integer caps_value = luaL_optinteger(L, 1, MALLOC_CAP_DEFAULT); + multi_heap_info_t info = {0}; + uint32_t caps = (uint32_t)caps_value; + + heap_caps_get_info(&info, caps); + + lua_newtable(L); + lua_pushinteger(L, (lua_Integer)caps); + lua_setfield(L, -2, "caps"); + lua_pushinteger(L, (lua_Integer)heap_caps_get_total_size(caps)); + lua_setfield(L, -2, "total_size"); + lua_pushinteger(L, (lua_Integer)info.total_free_bytes); + lua_setfield(L, -2, "free_size"); + lua_pushinteger(L, (lua_Integer)info.total_allocated_bytes); + lua_setfield(L, -2, "allocated_size"); + lua_pushinteger(L, (lua_Integer)info.minimum_free_bytes); + lua_setfield(L, -2, "minimum_free_size"); + lua_pushinteger(L, (lua_Integer)info.largest_free_block); + lua_setfield(L, -2, "largest_free_block"); + lua_pushinteger(L, (lua_Integer)info.allocated_blocks); + lua_setfield(L, -2, "allocated_blocks"); + lua_pushinteger(L, (lua_Integer)info.free_blocks); + lua_setfield(L, -2, "free_blocks"); + lua_pushinteger(L, (lua_Integer)info.total_blocks); + lua_setfield(L, -2, "total_blocks"); + return 1; +} + +static int lua_module_esp_heap_get_task_watermarks(lua_State *L) +{ +#if (configUSE_TRACE_FACILITY == 1) + UBaseType_t task_count = uxTaskGetNumberOfTasks(); + TaskStatus_t *tasks = NULL; + UBaseType_t count = 0; + + tasks = calloc((size_t)task_count + 4, sizeof(*tasks)); + if (!tasks) { + return luaL_error(L, "esp_heap get_task_watermarks: out of memory"); + } + + count = uxTaskGetSystemState(tasks, task_count + 4, NULL); + lua_newtable(L); + for (UBaseType_t i = 0; i < count; i++) { + lua_newtable(L); + lua_pushstring(L, tasks[i].pcTaskName ? tasks[i].pcTaskName : "(unnamed)"); + lua_setfield(L, -2, "name"); + lua_pushinteger(L, (lua_Integer)tasks[i].xTaskNumber); + lua_setfield(L, -2, "task_number"); + lua_pushstring(L, lua_module_esp_heap_task_state_name(tasks[i].eCurrentState)); + lua_setfield(L, -2, "state"); + lua_pushinteger(L, (lua_Integer)tasks[i].uxCurrentPriority); + lua_setfield(L, -2, "current_priority"); + lua_pushinteger(L, (lua_Integer)tasks[i].uxBasePriority); + lua_setfield(L, -2, "base_priority"); + lua_pushinteger(L, (lua_Integer)tasks[i].usStackHighWaterMark); + lua_setfield(L, -2, "stack_high_water_mark_words"); + lua_pushinteger(L, (lua_Integer)tasks[i].usStackHighWaterMark * (lua_Integer)sizeof(StackType_t)); + lua_setfield(L, -2, "stack_high_water_mark_bytes"); + lua_rawseti(L, -2, (lua_Integer)i + 1); + } + + free(tasks); + return 1; +#else + TaskHandle_t task = xTaskGetCurrentTaskHandle(); + UBaseType_t words = uxTaskGetStackHighWaterMark(task); + + lua_newtable(L); + lua_newtable(L); + lua_pushstring(L, pcTaskGetName(task)); + lua_setfield(L, -2, "name"); + lua_pushinteger(L, (lua_Integer)uxTaskPriorityGet(task)); + lua_setfield(L, -2, "current_priority"); + lua_pushinteger(L, (lua_Integer)uxTaskPriorityGet(task)); + lua_setfield(L, -2, "base_priority"); + lua_pushstring(L, "running"); + lua_setfield(L, -2, "state"); + lua_pushinteger(L, (lua_Integer)words); + lua_setfield(L, -2, "stack_high_water_mark_words"); + lua_pushinteger(L, (lua_Integer)words * (lua_Integer)sizeof(StackType_t)); + lua_setfield(L, -2, "stack_high_water_mark_bytes"); + lua_rawseti(L, -2, 1); + lua_pushstring(L, "configUSE_TRACE_FACILITY=0, only current task watermark is available"); + lua_setfield(L, -2, "_warning"); + return 1; +#endif +} + +static int lua_module_esp_heap_get_current_task(lua_State *L) +{ + TaskHandle_t task = xTaskGetCurrentTaskHandle(); + UBaseType_t words = uxTaskGetStackHighWaterMark(task); + + lua_newtable(L); + lua_pushstring(L, pcTaskGetName(task)); + lua_setfield(L, -2, "name"); + lua_pushinteger(L, (lua_Integer)words); + lua_setfield(L, -2, "stack_high_water_mark_words"); + lua_pushinteger(L, (lua_Integer)words * (lua_Integer)sizeof(StackType_t)); + lua_setfield(L, -2, "stack_high_water_mark_bytes"); + return 1; +} + +int luaopen_esp_heap(lua_State *L) +{ + static const luaL_Reg funcs[] = { + {"caps", lua_module_esp_heap_caps}, + {"get_info", lua_module_esp_heap_get_info}, + {"get_task_watermarks", lua_module_esp_heap_get_task_watermarks}, + {"get_current_task", lua_module_esp_heap_get_current_task}, + {NULL, NULL}, + }; + + lua_newtable(L); + luaL_setfuncs(L, funcs, 0); + return 1; +} + +esp_err_t lua_module_esp_heap_register(void) +{ + return cap_lua_register_module("esp_heap", luaopen_esp_heap); +} diff --git a/components/lua_modules/lua_module_esp_heap/skills/lua_module_esp_heap.md b/components/lua_modules/lua_module_esp_heap/skills/lua_module_esp_heap.md new file mode 100644 index 0000000..127094a --- /dev/null +++ b/components/lua_modules/lua_module_esp_heap/skills/lua_module_esp_heap.md @@ -0,0 +1,22 @@ +# Lua ESP Heap + +This skill describes how to correctly use esp_heap when writing Lua scripts. + +## How to call +- Import it with `local esp_heap = require("esp_heap")` +- Call `local caps = esp_heap.caps()` to get capability flags such as `caps.DEFAULT`, `caps.INTERNAL`, and `caps.SPIRAM` +- Call `esp_heap.get_info(caps)` to read heap statistics such as `free_size`, `allocated_size`, and `largest_free_block` +- Call `esp_heap.get_task_watermarks()` to inspect stack high-water marks for tasks +- Call `esp_heap.get_current_task()` to inspect the current task state + +## Example +```lua +local esp_heap = require("esp_heap") +local caps = esp_heap.caps() + +local info = esp_heap.get_info(caps.DEFAULT) +print(info.free_size, info.largest_free_block) + +local task = esp_heap.get_current_task() +print(task.name, task.stack_high_water_mark_bytes) +``` diff --git a/components/lua_modules/lua_module_esp_heap/skills/skills_list.json b/components/lua_modules/lua_module_esp_heap/skills/skills_list.json new file mode 100644 index 0000000..3336c59 --- /dev/null +++ b/components/lua_modules/lua_module_esp_heap/skills/skills_list.json @@ -0,0 +1,13 @@ +{ + "skills": [ + { + "id": "lua_module_esp_heap", + "file": "lua_module_esp_heap.md", + "title": "lua_module_esp_heap", + "summary": "How to query heap capability flags, memory usage, and task watermarks from Lua.", + "cap_groups": [ + "cap_lua" + ] + } + ] +} diff --git a/components/lua_modules/lua_module_lcd_touch/CMakeLists.txt b/components/lua_modules/lua_module_lcd_touch/CMakeLists.txt new file mode 100644 index 0000000..16e07d9 --- /dev/null +++ b/components/lua_modules/lua_module_lcd_touch/CMakeLists.txt @@ -0,0 +1,9 @@ +idf_component_register( + SRCS + "src/lua_module_lcd_touch.c" + INCLUDE_DIRS + "include" + REQUIRES + cap_lua + esp_lcd_touch +) diff --git a/components/lua_modules/lua_module_lcd_touch/include/lua_module_lcd_touch.h b/components/lua_modules/lua_module_lcd_touch/include/lua_module_lcd_touch.h new file mode 100644 index 0000000..c362df2 --- /dev/null +++ b/components/lua_modules/lua_module_lcd_touch/include/lua_module_lcd_touch.h @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "esp_err.h" +#include "lua.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int luaopen_lcd_touch(lua_State *L); +esp_err_t lua_module_lcd_touch_register(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/lua_modules/lua_module_lcd_touch/skills/lua_module_lcd_touch.md b/components/lua_modules/lua_module_lcd_touch/skills/lua_module_lcd_touch.md new file mode 100644 index 0000000..1dea9d5 --- /dev/null +++ b/components/lua_modules/lua_module_lcd_touch/skills/lua_module_lcd_touch.md @@ -0,0 +1,23 @@ +# Lua LCD Touch + +This skill describes how to correctly use lcd_touch when writing Lua scripts. + +## How to call +- Import it with `local lcd_touch = require("lcd_touch")` +- Get a touch handle first, typically from `board_manager.get_lcd_touch_handle(...)` +- Call `lcd_touch.sync(touch_handle)` to synchronize the cached touch state +- Call `lcd_touch.read(touch_handle)` to read the current touch state +- Call `lcd_touch.poll(touch_handle)` to get edge-aware touch information such as `just_pressed`, `just_released`, `x`, `y`, `dx`, `dy`, and `held_ms` + +## Example +```lua +local board_manager = require("board_manager") +local lcd_touch = require("lcd_touch") + +local touch_handle = board_manager.get_lcd_touch_handle("lcd_touch") +lcd_touch.sync(touch_handle) +local touch = lcd_touch.poll(touch_handle) +if touch.just_pressed then + print(touch.x, touch.y) +end +``` diff --git a/components/lua_modules/lua_module_lcd_touch/skills/skills_list.json b/components/lua_modules/lua_module_lcd_touch/skills/skills_list.json new file mode 100644 index 0000000..2851dae --- /dev/null +++ b/components/lua_modules/lua_module_lcd_touch/skills/skills_list.json @@ -0,0 +1,13 @@ +{ + "skills": [ + { + "id": "lua_module_lcd_touch", + "file": "lua_module_lcd_touch.md", + "title": "lua_module_lcd_touch", + "summary": "How to sync, read, and poll LCD touch state from Lua.", + "cap_groups": [ + "cap_lua" + ] + } + ] +} diff --git a/components/lua_modules/lua_module_lcd_touch/src/lua_module_lcd_touch.c b/components/lua_modules/lua_module_lcd_touch/src/lua_module_lcd_touch.c new file mode 100644 index 0000000..06bc8b6 --- /dev/null +++ b/components/lua_modules/lua_module_lcd_touch/src/lua_module_lcd_touch.c @@ -0,0 +1,290 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "lua_module_lcd_touch.h" + +#include +#include + +#include "cap_lua.h" +#include "esp_err.h" +#include "esp_lcd_touch.h" +#include "esp_timer.h" +#include "lauxlib.h" + +static const char *LUA_LCD_TOUCH_STATE_KEY = "clawgent.lcd_touch_state"; + +static esp_lcd_touch_handle_t lua_lcd_touch_check_handle(lua_State *L, int index) +{ + void *handle = lua_touserdata(L, index); + luaL_argcheck(L, handle != NULL, index, "lcd_touch handle expected"); + return (esp_lcd_touch_handle_t)handle; +} + +static esp_err_t lua_lcd_touch_read_raw(esp_lcd_touch_handle_t touch_handle, + bool *pressed, uint16_t *x, uint16_t *y) +{ + esp_lcd_touch_point_data_t points[1]; + uint8_t point_count = 0; + esp_err_t err; + + if (touch_handle == NULL || pressed == NULL || x == NULL || y == NULL) { + return ESP_ERR_INVALID_ARG; + } + + esp_lcd_touch_read_data(touch_handle); + err = esp_lcd_touch_get_data(touch_handle, points, &point_count, 1); + if (err != ESP_OK) { + return err; + } + + *pressed = point_count > 0; + if (*pressed) { + *x = points[0].x; + *y = points[0].y; + } else { + *x = 0; + *y = 0; + } + + return ESP_OK; +} + +static void lua_lcd_touch_push_touch_table(lua_State *L, + bool pressed, + bool just_pressed, + bool just_released, + uint16_t x, + uint16_t y, + int dx, + int dy, + lua_Number held_ms) +{ + lua_newtable(L); + + lua_pushboolean(L, pressed); + lua_setfield(L, -2, "pressed"); + + lua_pushboolean(L, just_pressed); + lua_setfield(L, -2, "just_pressed"); + + lua_pushboolean(L, just_released); + lua_setfield(L, -2, "just_released"); + + lua_pushinteger(L, x); + lua_setfield(L, -2, "x"); + + lua_pushinteger(L, y); + lua_setfield(L, -2, "y"); + + lua_pushinteger(L, dx); + lua_setfield(L, -2, "dx"); + + lua_pushinteger(L, dy); + lua_setfield(L, -2, "dy"); + + lua_pushboolean(L, (dx != 0) || (dy != 0)); + lua_setfield(L, -2, "moved"); + + lua_pushnumber(L, held_ms); + lua_setfield(L, -2, "held_ms"); +} + +static void lua_lcd_touch_push_state_table(lua_State *L) +{ + lua_getfield(L, LUA_REGISTRYINDEX, LUA_LCD_TOUCH_STATE_KEY); + if (lua_istable(L, -1)) { + return; + } + + lua_pop(L, 1); + lua_newtable(L); + + lua_pushboolean(L, false); + lua_setfield(L, -2, "initialized"); + + lua_pushboolean(L, false); + lua_setfield(L, -2, "pressed"); + + lua_pushinteger(L, 0); + lua_setfield(L, -2, "x"); + + lua_pushinteger(L, 0); + lua_setfield(L, -2, "y"); + + lua_pushnumber(L, 0); + lua_setfield(L, -2, "press_start_ms"); + + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, LUA_LCD_TOUCH_STATE_KEY); +} + +static void lua_lcd_touch_update_state(lua_State *L, + bool initialized, + bool pressed, + uint16_t x, + uint16_t y, + lua_Number press_start_ms) +{ + lua_pushboolean(L, initialized); + lua_setfield(L, -2, "initialized"); + + lua_pushboolean(L, pressed); + lua_setfield(L, -2, "pressed"); + + lua_pushinteger(L, x); + lua_setfield(L, -2, "x"); + + lua_pushinteger(L, y); + lua_setfield(L, -2, "y"); + + lua_pushnumber(L, press_start_ms); + lua_setfield(L, -2, "press_start_ms"); +} + +static int lua_lcd_touch_sync(lua_State *L) +{ + esp_lcd_touch_handle_t touch_handle = lua_lcd_touch_check_handle(L, 1); + bool pressed = false; + uint16_t x = 0; + uint16_t y = 0; + lua_Number now_ms = (lua_Number)(esp_timer_get_time() / 1000); + esp_err_t err = lua_lcd_touch_read_raw(touch_handle, &pressed, &x, &y); + if (err != ESP_OK) { + return luaL_error(L, "lcd_touch sync failed: %s", esp_err_to_name(err)); + } + + lua_lcd_touch_push_state_table(L); + lua_lcd_touch_update_state(L, true, pressed, x, y, pressed ? now_ms : 0); + lua_pop(L, 1); + + lua_lcd_touch_push_touch_table(L, pressed, false, false, x, y, 0, 0, 0); + return 1; +} + +static int lua_lcd_touch_read(lua_State *L) +{ + esp_lcd_touch_handle_t touch_handle = lua_lcd_touch_check_handle(L, 1); + bool pressed = false; + uint16_t x = 0; + uint16_t y = 0; + esp_err_t err = lua_lcd_touch_read_raw(touch_handle, &pressed, &x, &y); + if (err != ESP_OK) { + return luaL_error(L, "lcd_touch read failed: %s", esp_err_to_name(err)); + } + + lua_newtable(L); + lua_pushboolean(L, pressed); + lua_setfield(L, -2, "pressed"); + if (pressed) { + lua_pushinteger(L, x); + lua_setfield(L, -2, "x"); + lua_pushinteger(L, y); + lua_setfield(L, -2, "y"); + } + return 1; +} + +static int lua_lcd_touch_poll(lua_State *L) +{ + esp_lcd_touch_handle_t touch_handle = lua_lcd_touch_check_handle(L, 1); + bool pressed = false; + bool prev_pressed = false; + bool initialized = false; + bool just_pressed = false; + bool just_released = false; + uint16_t x = 0; + uint16_t y = 0; + uint16_t prev_x = 0; + uint16_t prev_y = 0; + int dx = 0; + int dy = 0; + lua_Number press_start_ms = 0; + lua_Number held_ms = 0; + lua_Number now_ms = (lua_Number)(esp_timer_get_time() / 1000); + esp_err_t err = lua_lcd_touch_read_raw(touch_handle, &pressed, &x, &y); + if (err != ESP_OK) { + return luaL_error(L, "lcd_touch poll failed: %s", esp_err_to_name(err)); + } + + lua_lcd_touch_push_state_table(L); + + lua_getfield(L, -1, "initialized"); + initialized = lua_toboolean(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "pressed"); + prev_pressed = lua_toboolean(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "x"); + prev_x = (uint16_t)lua_tointeger(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "y"); + prev_y = (uint16_t)lua_tointeger(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "press_start_ms"); + press_start_ms = lua_tonumber(L, -1); + lua_pop(L, 1); + + if (!initialized) { + if (pressed) { + press_start_ms = now_ms; + } else { + x = 0; + y = 0; + press_start_ms = 0; + } + } else if (pressed && prev_pressed) { + dx = (int)x - (int)prev_x; + dy = (int)y - (int)prev_y; + held_ms = press_start_ms > 0 ? (now_ms - press_start_ms) : 0; + } else if (pressed && !prev_pressed) { + just_pressed = true; + press_start_ms = now_ms; + } else if (!pressed && prev_pressed) { + just_released = true; + x = prev_x; + y = prev_y; + press_start_ms = 0; + } else { + x = 0; + y = 0; + press_start_ms = 0; + } + + if (pressed && held_ms <= 0 && press_start_ms > 0) { + held_ms = now_ms - press_start_ms; + if (held_ms < 0) { + held_ms = 0; + } + } + + lua_lcd_touch_update_state(L, true, pressed, x, y, press_start_ms); + lua_pop(L, 1); + + lua_lcd_touch_push_touch_table(L, pressed, just_pressed, just_released, x, y, dx, dy, + held_ms); + return 1; +} + +int luaopen_lcd_touch(lua_State *L) +{ + lua_newtable(L); + lua_pushcfunction(L, lua_lcd_touch_read); + lua_setfield(L, -2, "read"); + lua_pushcfunction(L, lua_lcd_touch_poll); + lua_setfield(L, -2, "poll"); + lua_pushcfunction(L, lua_lcd_touch_sync); + lua_setfield(L, -2, "sync"); + return 1; +} + +esp_err_t lua_module_lcd_touch_register(void) +{ + return cap_lua_register_module("lcd_touch", luaopen_lcd_touch); +} diff --git a/components/lua_modules/lua_module_led_strip/CMakeLists.txt b/components/lua_modules/lua_module_led_strip/CMakeLists.txt index ae9c628..7c331fd 100644 --- a/components/lua_modules/lua_module_led_strip/CMakeLists.txt +++ b/components/lua_modules/lua_module_led_strip/CMakeLists.txt @@ -5,5 +5,4 @@ idf_component_register( "include" REQUIRES cap_lua - espressif__led_strip ) diff --git a/components/lua_modules/lua_module_led_strip/idf_component.yml b/components/lua_modules/lua_module_led_strip/idf_component.yml new file mode 100644 index 0000000..48d23d0 --- /dev/null +++ b/components/lua_modules/lua_module_led_strip/idf_component.yml @@ -0,0 +1,3 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/led_strip: ^3.0.3